File indexing completed on 2024-05-12 13:56:03
0001 /* 0002 This file is part of the Okteta Gui library, made within the KDE community. 0003 0004 SPDX-FileCopyrightText: 2004, 2008 Friedrich W. H. Kossebau <kossebau@kde.org> 0005 0006 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0007 */ 0008 0009 #include "keynavigator.hpp" 0010 0011 // lib 0012 #include <bytearraytableranges.hpp> 0013 #include <bytearraytablecursor.hpp> 0014 #include <abstractbytearrayview.hpp> 0015 // Okteta core 0016 #include <Okteta/TextByteArrayAnalyzer> 0017 #include <Okteta/AbstractByteArrayModel> 0018 // KF 0019 #include <KLocalizedString> 0020 // Qt 0021 #include <QKeyEvent> 0022 #include <QMenu> 0023 #include <QAction> 0024 0025 namespace Okteta { 0026 0027 KeyNavigator::KeyNavigator(AbstractByteArrayView* view, AbstractController* parent) 0028 : AbstractController(parent) 0029 , mView(view) 0030 { 0031 } 0032 0033 bool KeyNavigator::handleKeyPress(QKeyEvent* keyEvent) 0034 { 0035 bool keyUsed; 0036 0037 if (keyEvent == QKeySequence::SelectAll) { 0038 selectAll(); 0039 keyUsed = true; 0040 } else if (keyEvent->modifiers() & Qt::ALT) { 0041 // currently there is no input with the Alt modifier used, so ignore them all 0042 keyUsed = false; 0043 } else { 0044 keyUsed = true; 0045 0046 const bool shiftPressed = keyEvent->modifiers() & Qt::SHIFT; 0047 const bool controlPressed = keyEvent->modifiers() & Qt::CTRL; 0048 0049 // we only care for cursor keys and the like, won't hardcode any other keys 0050 // we also don't check whether the commands are allowed 0051 // as the commands are also available as API so the check has to be done 0052 // in each command anyway 0053 switch (keyEvent->key()) 0054 { 0055 case Qt::Key_Left: 0056 moveCursor(controlPressed ? MoveWordBackward : MoveBackward, shiftPressed); 0057 break; 0058 case Qt::Key_Right: 0059 moveCursor(controlPressed ? MoveWordForward : MoveForward, shiftPressed); 0060 break; 0061 case Qt::Key_Up: 0062 moveCursor(controlPressed ? MovePgUp : MoveUp, shiftPressed); 0063 break; 0064 case Qt::Key_Down: 0065 moveCursor(controlPressed ? MovePgDown : MoveDown, shiftPressed); 0066 break; 0067 case Qt::Key_Home: 0068 moveCursor(controlPressed ? MoveHome : MoveLineStart, shiftPressed); 0069 break; 0070 case Qt::Key_End: 0071 moveCursor(controlPressed ? MoveEnd : MoveLineEnd, shiftPressed); 0072 break; 0073 case Qt::Key_PageUp: 0074 moveCursor(MovePgUp, shiftPressed); 0075 break; 0076 case Qt::Key_PageDown: 0077 moveCursor(MovePgDown, shiftPressed); 0078 break; 0079 default: 0080 keyUsed = false; 0081 } 0082 } 0083 0084 return keyUsed ? true : AbstractController::handleKeyPress(keyEvent); 0085 } 0086 0087 void KeyNavigator::moveCursor(MoveAction action, bool select) 0088 { 0089 mView->pauseCursor(); 0090 mView->finishByteEdit(); 0091 0092 ByteArrayTableCursor* tableCursor = mView->tableCursor(); 0093 ByteArrayTableRanges* tableRanges = mView->tableRanges(); 0094 0095 if (select) { 0096 if (!tableRanges->selectionStarted()) { 0097 tableRanges->setSelectionStart(tableCursor->realIndex()); 0098 } 0099 } else { 0100 tableRanges->removeSelection(); 0101 } 0102 0103 switch (action) 0104 { 0105 case MoveBackward: tableCursor->gotoPreviousByte(); break; 0106 case MoveWordBackward: { 0107 const Okteta::TextByteArrayAnalyzer textAnalyzer(mView->byteArrayModel(), mView->charCodec()); 0108 const int newIndex = textAnalyzer.indexOfPreviousWordStart(tableCursor->realIndex()); 0109 tableCursor->gotoIndex(newIndex); 0110 break; 0111 } 0112 case MoveForward: tableCursor->gotoNextByte(); break; 0113 case MoveWordForward: { 0114 const Okteta::TextByteArrayAnalyzer textAnalyzer(mView->byteArrayModel(), mView->charCodec()); 0115 const int newIndex = textAnalyzer.indexOfNextWordStart(tableCursor->realIndex()); 0116 tableCursor->gotoCIndex(newIndex); 0117 break; 0118 } 0119 case MoveUp: tableCursor->gotoUp(); break; 0120 case MovePgUp: tableCursor->gotoPageUp(); break; 0121 case MoveDown: tableCursor->gotoDown(); break; 0122 case MovePgDown: tableCursor->gotoPageDown(); break; 0123 case MoveLineStart: tableCursor->gotoLineStart(); break; 0124 case MoveHome: tableCursor->gotoStart(); break; 0125 case MoveLineEnd: tableCursor->gotoLineEnd(); break; 0126 case MoveEnd: tableCursor->gotoEnd(); break; 0127 } 0128 0129 if (select) { 0130 tableRanges->setSelectionEnd(tableCursor->realIndex()); 0131 } 0132 0133 mView->ensureCursorVisible(); 0134 0135 mView->updateChanged(); 0136 mView->unpauseCursor(); 0137 mView->emitSelectionSignals(); 0138 } 0139 0140 int KeyNavigator::addContextMenuActions(QMenu* menu) 0141 { 0142 QAction* selectAllAction = menu->addAction(QIcon::fromTheme(QStringLiteral("edit-select-all")), 0143 i18nc("@action:inmenu", "Select &All") + QLatin1Char('\t') + QKeySequence(QKeySequence::SelectAll).toString(QKeySequence::NativeText), 0144 mView, [this] { selectAll(); }); 0145 selectAllAction->setEnabled(mView->byteArrayModel()->size() > 0); 0146 0147 selectAllAction->setObjectName(QStringLiteral("select-all")); 0148 0149 return 1; 0150 } 0151 0152 void KeyNavigator::selectAll() 0153 { 0154 mView->selectAll(true); 0155 } 0156 0157 }