| 1 | /* |
| 2 | * Copyright (C) 2020-2022 Roy Qu (royqh1979@gmail.com) |
| 3 | * |
| 4 | * This program is free software: you can redistribute it and/or modify |
| 5 | * it under the terms of the GNU General Public License as published by |
| 6 | * the Free Software Foundation, either version 3 of the License, or |
| 7 | * (at your option) any later version. |
| 8 | * |
| 9 | * This program is distributed in the hope that it will be useful, |
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 12 | * GNU General Public License for more details. |
| 13 | * |
| 14 | * You should have received a copy of the GNU General Public License |
| 15 | * along with this program. If not, see <https://www.gnu.org/licenses/>. |
| 16 | */ |
| 17 | #ifndef SYNEDITKEYSTROKE_H |
| 18 | #define SYNEDITKEYSTROKE_H |
| 19 | |
| 20 | #include <QKeySequence> |
| 21 | #include <QList> |
| 22 | #include <memory> |
| 23 | #include "MiscClasses.h" |
| 24 | #include "qt_utils/utils.h" |
| 25 | |
| 26 | namespace QSynedit { |
| 27 | //**************************************************************************** |
| 28 | // NOTE! If you add an editor command, you must also update the |
| 29 | // EditorCommandStrs constant array in implementation section below, or the |
| 30 | // command will not show up in the IDE. |
| 31 | //**************************************************************************** |
| 32 | |
| 33 | // "Editor Commands". Key strokes are translated from a table into these |
| 34 | // I used constants instead of a set so that additional commands could be |
| 35 | // added in descendants (you can't extend a set) |
| 36 | |
| 37 | // There are two ranges of editor commands: the ecViewXXX commands are always |
| 38 | // valid, while the ecEditXXX commands are ignored when the editor is in |
| 39 | // read-only mode |
| 40 | |
| 41 | enum class EditCommand { |
| 42 | ecNone = 0, // Nothing. Useful for user event to handle command |
| 43 | ecViewCommandFirst = 0, |
| 44 | ecViewCommandLast = 500, |
| 45 | ecEditCommandFirst = 501, |
| 46 | ecEditCommandLast = 1000, |
| 47 | |
| 48 | ecLeft = 1, // Move cursor left one char |
| 49 | ecRight = 2, // Move cursor right one char |
| 50 | ecUp = 3, // Move cursor up one line |
| 51 | ecDown = 4, // Move cursor down one line |
| 52 | ecWordLeft = 5, // Move cursor left one word |
| 53 | ecWordRight = 6, // Move cursor right one word |
| 54 | ecLineStart = 7, // Move cursor to beginning of line |
| 55 | ecLineEnd = 8, // Move cursor to end of line |
| 56 | ecPageUp = 9, // Move cursor up one page |
| 57 | ecPageDown = 10, // Move cursor down one page |
| 58 | ecPageLeft = 11, // Move cursor right one page |
| 59 | ecPageRight = 12, // Move cursor left one page |
| 60 | ecPageTop = 13, // Move cursor to top of page |
| 61 | ecPageBottom = 14, // Move cursor to bottom of page |
| 62 | ecEditorStart = 15, // Move cursor to absolute beginning |
| 63 | ecEditorEnd = 16, // Move cursor to absolute end |
| 64 | ecGotoXY = 17, // Move cursor to specific coordinates, Data = PPoint |
| 65 | |
| 66 | //****************************************************************************** |
| 67 | // Maybe the command processor should just take a boolean that signifies if |
| 68 | // selection is affected or not? |
| 69 | //****************************************************************************** |
| 70 | |
| 71 | ecSelection = 100, // Add this to ecXXX command to get equivalent |
| 72 | // command, but with selection enabled. This is not |
| 73 | // a command itself. |
| 74 | // Same as commands above, except they affect selection, too |
| 75 | ecSelLeft = ecLeft + ecSelection, |
| 76 | ecSelRight = ecRight + ecSelection, |
| 77 | ecSelUp = ecUp + ecSelection, |
| 78 | ecSelDown = ecDown + ecSelection, |
| 79 | ecSelWordLeft = ecWordLeft + ecSelection, |
| 80 | ecSelWordRight = ecWordRight + ecSelection, |
| 81 | ecSelLineStart = ecLineStart + ecSelection, |
| 82 | ecSelLineEnd = ecLineEnd + ecSelection, |
| 83 | ecSelPageUp = ecPageUp + ecSelection, |
| 84 | ecSelPageDown = ecPageDown + ecSelection, |
| 85 | ecSelPageLeft = ecPageLeft + ecSelection, |
| 86 | ecSelPageRight = ecPageRight + ecSelection, |
| 87 | ecSelPageTop = ecPageTop + ecSelection, |
| 88 | ecSelPageBottom = ecPageBottom + ecSelection, |
| 89 | ecSelEditorStart = ecEditorStart + ecSelection, |
| 90 | ecSelEditorEnd = ecEditorEnd + ecSelection, |
| 91 | ecSelGotoXY = ecGotoXY + ecSelection, // Data = PPoint |
| 92 | |
| 93 | |
| 94 | ecCopy = 201, // Copy selection to clipboard |
| 95 | ecSelWord = 202, |
| 96 | ecSelectAll = 203, // Select entire contents of editor, cursor to end |
| 97 | ecExpandSelection = 204, // expand selection |
| 98 | ecShrinkSelection = 205, // shrink selection |
| 99 | |
| 100 | ecScrollUp = 211, // Scroll up one line leaving cursor position unchanged. |
| 101 | ecScrollDown = 212, // Scroll down one line leaving cursor position unchanged. |
| 102 | ecScrollLeft = 213, // Scroll left one char leaving cursor position unchanged. |
| 103 | ecScrollRight = 214, // Scroll right one char leaving cursor position unchanged. |
| 104 | |
| 105 | ecInsertMode = 221, // Set insert mode |
| 106 | ecOverwriteMode = 222, // Set overwrite mode |
| 107 | ecToggleMode = 223, // Toggle ins/ovr mode |
| 108 | |
| 109 | ecNormalSelect = 231, // Normal selection mode |
| 110 | ecColumnSelect = 232, // Column selection mode |
| 111 | ecLineSelect = 233, // Line selection mode |
| 112 | |
| 113 | ecMatchBracket = 250, // Go to matching bracket |
| 114 | |
| 115 | ecContextHelp = 490, // Help on Word, Data = Word |
| 116 | |
| 117 | ecDeleteLastChar = 501, // Delete last char (i.e. backspace key) |
| 118 | ecDeleteChar = 502, // Delete char at cursor (i.e. delete key) |
| 119 | ecDeleteWordEnd = 503, // Delete from cursor to end of word |
| 120 | ecDeleteWordStart = 504, // Delete from cursor to start of word |
| 121 | ecDeleteBOL = 505, // Delete from cursor to beginning of line |
| 122 | ecDeleteEOL = 506, // Delete from cursor to end of line |
| 123 | ecDeleteLine = 507, // Delete current line |
| 124 | ecClearAll = 508, // Delete everything |
| 125 | ecLineBreak = 509, // Break line at current position, move caret to new line |
| 126 | ecInsertLine = 510, // Break line at current position, leave caret |
| 127 | ecChar = 511, // Insert a character at current position |
| 128 | ecDuplicateLine = 512, // Duplicate current line |
| 129 | ecMoveSelUp = 513, // Move selection up |
| 130 | ecMoveSelDown = 514, // Move selection down |
| 131 | ecImeStr = 550, // Insert character(s) from IME |
| 132 | ecDeleteWord = 551, // Delete current Word |
| 133 | |
| 134 | ecUndo = 601, // Perform undo if available |
| 135 | ecRedo = 602, // Perform redo if available |
| 136 | ecCut = 603, // Cut selection to clipboard |
| 137 | ecPaste = 604, // Paste clipboard to current position |
| 138 | |
| 139 | ecBlockIndent = 610, // Indent selection |
| 140 | ecBlockUnindent = 611, // Unindent selection |
| 141 | ecTab = 612, // Tab key |
| 142 | ecShiftTab = 613, // Shift+Tab key |
| 143 | ecComment = 614, |
| 144 | ecUncomment = 615, |
| 145 | ecToggleComment = 616, |
| 146 | ecToggleBlockComment = 617, |
| 147 | |
| 148 | ecUpperCase = 620, // apply to the current or previous word |
| 149 | ecLowerCase = 621, |
| 150 | ecToggleCase = 622, |
| 151 | ecTitleCase = 623, |
| 152 | ecUpperCaseBlock = 625, // apply to current selection, or current char if no selection |
| 153 | ecLowerCaseBlock = 626, |
| 154 | ecToggleCaseBlock = 627, |
| 155 | |
| 156 | ecString = 630, //Insert a whole string |
| 157 | ecZoomOut = 631, //Increase Font Size |
| 158 | ecZoomIn = 632, //Decrease Font Size |
| 159 | |
| 160 | ecLineBreakAtBegin = 651, //add a line break at the begin of the line |
| 161 | ecLineBreakAtEnd = 652, |
| 162 | |
| 163 | //### Code Folding ### |
| 164 | ecCollapse = 700, |
| 165 | ecUncollapse = 701, |
| 166 | ecCollapseLevel = 702, |
| 167 | ecUncollapseLevel = 703, |
| 168 | ecCollapseAll = 704, |
| 169 | ecUncollapseAll = 705, |
| 170 | //### End Code Folding ### |
| 171 | |
| 172 | ecUserFirst = 1001, // Start of user-defined commands |
| 173 | |
| 174 | |
| 175 | |
| 176 | }; |
| 177 | |
| 178 | class KeyError: public BaseError { |
| 179 | public: |
| 180 | explicit KeyError(const QString& reason); |
| 181 | }; |
| 182 | |
| 183 | class EditKeyStroke |
| 184 | { |
| 185 | public: |
| 186 | explicit EditKeyStroke(); |
| 187 | QKeySequence keySequence() const; |
| 188 | void setKeySequence(QKeySequence& keySequence); |
| 189 | int key() const; |
| 190 | void setKey(int key); |
| 191 | |
| 192 | Qt::KeyboardModifiers keyModifiers() const; |
| 193 | void setKeyModifiers(const Qt::KeyboardModifiers &keyModifiers); |
| 194 | |
| 195 | int key2() const; |
| 196 | void setKey2(int key2); |
| 197 | |
| 198 | Qt::KeyboardModifiers keyModifiers2() const; |
| 199 | void setKeyModifiers2(const Qt::KeyboardModifiers &keyModifiers2); |
| 200 | |
| 201 | EditCommand command() const; |
| 202 | void setCommand(const EditCommand &command); |
| 203 | |
| 204 | private: |
| 205 | int mKey; // Virtual keycode, i.e. VK_xxx |
| 206 | Qt::KeyboardModifiers mKeyModifiers; |
| 207 | int mKey2; |
| 208 | Qt::KeyboardModifiers mKeyModifiers2; |
| 209 | EditCommand mCommand; |
| 210 | |
| 211 | }; |
| 212 | |
| 213 | using PEditKeyStroke = std::shared_ptr<EditKeyStroke>; |
| 214 | using EditKeyStrokeList = QList<PEditKeyStroke>; |
| 215 | |
| 216 | class EditKeyStrokes { |
| 217 | public: |
| 218 | PEditKeyStroke add(EditCommand command, int key, Qt::KeyboardModifiers modifiers); |
| 219 | PEditKeyStroke findCommand(EditCommand command); |
| 220 | PEditKeyStroke findKeycode(int key, Qt::KeyboardModifiers modifiers); |
| 221 | PEditKeyStroke findKeycode2(int key, Qt::KeyboardModifiers modifiers, |
| 222 | int key2, Qt::KeyboardModifiers modifiers2); |
| 223 | PEditKeyStroke findKeySequence(const QKeySequence& keySeq); |
| 224 | void clear(); |
| 225 | void resetDefaults(); |
| 226 | void (); |
| 227 | private: |
| 228 | EditKeyStrokeList mList; |
| 229 | }; |
| 230 | |
| 231 | } |
| 232 | |
| 233 | #endif // SYNEDITKEYSTROKE_H |
| 234 | |