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
26namespace 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
41enum 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
178class KeyError: public BaseError {
179public:
180 explicit KeyError(const QString& reason);
181};
182
183class EditKeyStroke
184{
185public:
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
204private:
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
213using PEditKeyStroke = std::shared_ptr<EditKeyStroke>;
214using EditKeyStrokeList = QList<PEditKeyStroke>;
215
216class EditKeyStrokes {
217public:
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 setExtraKeyStrokes();
227private:
228 EditKeyStrokeList mList;
229};
230
231}
232
233#endif // SYNEDITKEYSTROKE_H
234