1 | /* |
2 | This file is part of the KDE libraries |
3 | SPDX-FileCopyrightText: 1997 Stefan Taferner <taferner@alpin.or.at> |
4 | SPDX-FileCopyrightText: 2000 Nicolas Hadacek <haadcek@kde.org> |
5 | SPDX-FileCopyrightText: 2001, 2002 Ellis Whitehead <ellis@kde.org> |
6 | |
7 | SPDX-License-Identifier: LGPL-2.0-or-later |
8 | */ |
9 | |
10 | #include "kstandardshortcut.h" |
11 | #include "kstandardshortcutwatcher.h" |
12 | |
13 | #include "kconfig.h" |
14 | #include "kconfigwatcher.h" |
15 | #include "ksharedconfig.h" |
16 | #include <kconfiggroup.h> |
17 | |
18 | #include <QCoreApplication> |
19 | #include <QDebug> |
20 | #include <QKeySequence> |
21 | |
22 | namespace KStandardShortcut |
23 | { |
24 | struct KStandardShortcutInfo { |
25 | //! The standard shortcut id. @see StandardShortcut |
26 | StandardShortcut id; |
27 | |
28 | /** |
29 | * Unique name for the given accel. The name is used to save the user |
30 | * settings. It's not representable. Use description for that. |
31 | * @warning NEVER EVER CHANGE IT OR TRANSLATE IT! |
32 | */ |
33 | const char *name; |
34 | |
35 | //! Localized label for user-visible display, including translation context. |
36 | struct { |
37 | const char *text; |
38 | const char *context; |
39 | } description; |
40 | |
41 | //! The keys for this shortcut |
42 | int cutDefault, cutDefault2; |
43 | |
44 | //! A shortcut that is created with @a cutDefault and @cutDefault2 |
45 | QList<QKeySequence> cut; |
46 | |
47 | //! If this struct is initialized. If not initialized @cut is not valid |
48 | bool isInitialized; |
49 | |
50 | // Category of this Shortcut |
51 | Category category; |
52 | }; |
53 | |
54 | #define CTRL(x) QKeyCombination(Qt::CTRL | Qt::Key_##x).toCombined() |
55 | #define SHIFT(x) QKeyCombination(Qt::SHIFT | Qt::Key_##x).toCombined() |
56 | #define CTRLALT(x) QKeyCombination(Qt::CTRL | Qt::ALT | Qt::Key_##x).toCombined() |
57 | #define CTRLSHIFT(x) QKeyCombination(Qt::CTRL | Qt::SHIFT | Qt::Key_##x).toCombined() |
58 | #define ALT(x) QKeyCombination(Qt::ALT | Qt::Key_##x).toCombined() |
59 | #define ALTSHIFT(x) QKeyCombination(Qt::ALT | Qt::SHIFT | Qt::Key_##x).toCombined() |
60 | |
61 | /** Array of predefined KStandardShortcutInfo objects, which cover all |
62 | the "standard" accelerators. Each enum value from StandardShortcut |
63 | should appear in this table. |
64 | */ |
65 | // STUFF WILL BREAK IF YOU DON'T READ THIS!!! |
66 | // Read the comments of the big enum in kstandardshortcut.h before you change anything! |
67 | static KStandardShortcutInfo g_infoStandardShortcut[] = { |
68 | // Group File, |
69 | {.id: AccelNone, .name: nullptr, .description: {.text: nullptr, .context: nullptr}, .cutDefault: 0, .cutDefault2: 0, .cut: QList<QKeySequence>(), .isInitialized: false, .category: Category::InvalidCategory}, |
70 | {.id: Open, .name: "Open" , QT_TRANSLATE_NOOP3("KStandardShortcut" , "Open" , "@action" ), CTRL(O), .cutDefault2: 0, .cut: QList<QKeySequence>(), .isInitialized: false, .category: Category::File}, |
71 | {.id: New, .name: "New" , QT_TRANSLATE_NOOP3("KStandardShortcut" , "New" , "@action" ), CTRL(N), .cutDefault2: 0, .cut: QList<QKeySequence>(), .isInitialized: false, .category: Category::File}, |
72 | {.id: Close, .name: "Close" , QT_TRANSLATE_NOOP3("KStandardShortcut" , "Close" , "@action" ), CTRL(W), CTRL(Escape), .cut: QList<QKeySequence>(), .isInitialized: false, .category: Category::File}, |
73 | {.id: Save, .name: "Save" , QT_TRANSLATE_NOOP3("KStandardShortcut" , "Save" , "@action" ), CTRL(S), .cutDefault2: 0, .cut: QList<QKeySequence>(), .isInitialized: false, .category: Category::File}, |
74 | {.id: Print, .name: "Print" , QT_TRANSLATE_NOOP3("KStandardShortcut" , "Print" , "@action" ), CTRL(P), .cutDefault2: 0, .cut: QList<QKeySequence>(), .isInitialized: false, .category: Category::File}, |
75 | {.id: Quit, .name: "Quit" , QT_TRANSLATE_NOOP3("KStandardShortcut" , "Quit" , "@action" ), CTRL(Q), .cutDefault2: 0, .cut: QList<QKeySequence>(), .isInitialized: false, .category: Category::Navigation}, |
76 | |
77 | // Group Edit |
78 | {.id: Undo, .name: "Undo" , QT_TRANSLATE_NOOP3("KStandardShortcut" , "Undo" , "@action" ), CTRL(Z), .cutDefault2: 0, .cut: QList<QKeySequence>(), .isInitialized: false, .category: Category::Edit}, |
79 | {.id: Redo, .name: "Redo" , QT_TRANSLATE_NOOP3("KStandardShortcut" , "Redo" , "@action" ), CTRLSHIFT(Z), .cutDefault2: 0, .cut: QList<QKeySequence>(), .isInitialized: false, .category: Category::Edit}, |
80 | // Both "Cut" and "Delete" use Shift+Delete, but this is okay; see |
81 | // https://commits.kde.org/kxmlgui/8eabbf6725386e716b7536c71a9181dfe5d959f0 |
82 | {.id: Cut, .name: "Cut" , QT_TRANSLATE_NOOP3("KStandardShortcut" , "Cut" , "@action" ), CTRL(X), SHIFT(Delete), .cut: QList<QKeySequence>(), .isInitialized: false, .category: Category::Edit}, |
83 | {.id: Copy, .name: "Copy" , QT_TRANSLATE_NOOP3("KStandardShortcut" , "Copy" , "@action" ), CTRL(C), CTRL(Insert), .cut: QList<QKeySequence>(), .isInitialized: false, .category: Category::Edit}, |
84 | {.id: Paste, .name: "Paste" , QT_TRANSLATE_NOOP3("KStandardShortcut" , "Paste" , "@action" ), CTRL(V), SHIFT(Insert), .cut: QList<QKeySequence>(), .isInitialized: false, .category: Category::Edit}, |
85 | {.id: PasteSelection, |
86 | .name: "Paste Selection" , |
87 | QT_TRANSLATE_NOOP3("KStandardShortcut" , "Paste Selection" , "@action" ), |
88 | CTRLSHIFT(Insert), |
89 | .cutDefault2: 0, |
90 | .cut: QList<QKeySequence>(), |
91 | .isInitialized: false, |
92 | .category: Category::Edit}, |
93 | |
94 | {.id: SelectAll, .name: "SelectAll" , QT_TRANSLATE_NOOP3("KStandardShortcut" , "Select All" , "@action" ), CTRL(A), .cutDefault2: 0, .cut: QList<QKeySequence>(), .isInitialized: false, .category: Category::Edit}, |
95 | {.id: Deselect, .name: "Deselect" , QT_TRANSLATE_NOOP3("KStandardShortcut" , "Deselect" , "@action" ), CTRLSHIFT(A), .cutDefault2: 0, .cut: QList<QKeySequence>(), .isInitialized: false, .category: Category::Edit}, |
96 | {.id: DeleteWordBack, |
97 | .name: "DeleteWordBack" , |
98 | QT_TRANSLATE_NOOP3("KStandardShortcut" , "Delete Word Backwards" , "@action" ), |
99 | CTRL(Backspace), |
100 | .cutDefault2: 0, |
101 | .cut: QList<QKeySequence>(), |
102 | .isInitialized: false, |
103 | .category: Category::Edit}, |
104 | {.id: DeleteWordForward, |
105 | .name: "DeleteWordForward" , |
106 | QT_TRANSLATE_NOOP3("KStandardShortcut" , "Delete Word Forward" , "@action" ), |
107 | CTRL(Delete), |
108 | .cutDefault2: 0, |
109 | .cut: QList<QKeySequence>(), |
110 | .isInitialized: false, |
111 | .category: Category::Edit}, |
112 | |
113 | {.id: Find, .name: "Find" , QT_TRANSLATE_NOOP3("KStandardShortcut" , "Find" , "@action" ), CTRL(F), .cutDefault2: 0, .cut: QList<QKeySequence>(), .isInitialized: false, .category: Category::Edit}, |
114 | {.id: FindNext, .name: "FindNext" , QT_TRANSLATE_NOOP3("KStandardShortcut" , "Find Next" , "@action" ), .cutDefault: Qt::Key_F3, .cutDefault2: 0, .cut: QList<QKeySequence>(), .isInitialized: false, .category: Category::Edit}, |
115 | {.id: FindPrev, .name: "FindPrev" , QT_TRANSLATE_NOOP3("KStandardShortcut" , "Find Prev" , "@action" ), SHIFT(F3), .cutDefault2: 0, .cut: QList<QKeySequence>(), .isInitialized: false, .category: Category::Edit}, |
116 | {.id: Replace, .name: "Replace" , QT_TRANSLATE_NOOP3("KStandardShortcut" , "Replace" , "@action" ), CTRL(R), .cutDefault2: 0, .cut: QList<QKeySequence>(), .isInitialized: false, .category: Category::Edit}, |
117 | |
118 | // Group Navigation |
119 | {.id: Home, |
120 | .name: "Home" , |
121 | QT_TRANSLATE_NOOP3("KStandardShortcut" , "Home" , "@action Go to main page" ), |
122 | ALT(Home), |
123 | .cutDefault2: Qt::Key_HomePage, |
124 | .cut: QList<QKeySequence>(), |
125 | .isInitialized: false, |
126 | .category: Category::Navigation}, |
127 | {.id: Begin, |
128 | .name: "Begin" , |
129 | QT_TRANSLATE_NOOP3("KStandardShortcut" , "Begin" , "@action Beginning of document" ), |
130 | CTRL(Home), |
131 | .cutDefault2: 0, |
132 | .cut: QList<QKeySequence>(), |
133 | .isInitialized: false, |
134 | .category: Category::Navigation}, |
135 | {.id: End, .name: "End" , QT_TRANSLATE_NOOP3("KStandardShortcut" , "End" , "@action End of document" ), CTRL(End), .cutDefault2: 0, .cut: QList<QKeySequence>(), .isInitialized: false, .category: Category::Navigation}, |
136 | {.id: Prior, .name: "Prior" , QT_TRANSLATE_NOOP3("KStandardShortcut" , "Prior" , "@action" ), .cutDefault: Qt::Key_PageUp, .cutDefault2: 0, .cut: QList<QKeySequence>(), .isInitialized: false, .category: Category::Navigation}, |
137 | {.id: Next, |
138 | .name: "Next" , |
139 | QT_TRANSLATE_NOOP3("KStandardShortcut" , "Next" , "@action Opposite to Prior" ), |
140 | .cutDefault: Qt::Key_PageDown, |
141 | .cutDefault2: 0, |
142 | .cut: QList<QKeySequence>(), |
143 | .isInitialized: false, |
144 | .category: Category::Navigation}, |
145 | |
146 | {.id: Up, .name: "Up" , QT_TRANSLATE_NOOP3("KStandardShortcut" , "Up" , "@action" ), ALT(Up), .cutDefault2: 0, .cut: QList<QKeySequence>(), .isInitialized: false, .category: Category::Navigation}, |
147 | {.id: Back, .name: "Back" , QT_TRANSLATE_NOOP3("KStandardShortcut" , "Back" , "@action" ), ALT(Left), .cutDefault2: Qt::Key_Back, .cut: QList<QKeySequence>(), .isInitialized: false, .category: Category::Navigation}, |
148 | {.id: Forward, |
149 | .name: "Forward" , |
150 | QT_TRANSLATE_NOOP3("KStandardShortcut" , "Forward" , "@action" ), |
151 | ALT(Right), |
152 | .cutDefault2: Qt::Key_Forward, |
153 | .cut: QList<QKeySequence>(), |
154 | .isInitialized: false, |
155 | .category: Category::Navigation}, |
156 | {.id: Reload, |
157 | .name: "Reload" , |
158 | QT_TRANSLATE_NOOP3("KStandardShortcut" , "Reload" , "@action" ), |
159 | .cutDefault: Qt::Key_F5, |
160 | .cutDefault2: Qt::Key_Refresh, |
161 | .cut: QList<QKeySequence>(), |
162 | .isInitialized: false, |
163 | .category: Category::Navigation}, |
164 | |
165 | {.id: BeginningOfLine, |
166 | .name: "BeginningOfLine" , |
167 | QT_TRANSLATE_NOOP3("KStandardShortcut" , "Beginning of Line" , "@action" ), |
168 | .cutDefault: Qt::Key_Home, |
169 | .cutDefault2: 0, |
170 | .cut: QList<QKeySequence>(), |
171 | .isInitialized: false, |
172 | .category: Category::Navigation}, |
173 | {.id: EndOfLine, |
174 | .name: "EndOfLine" , |
175 | QT_TRANSLATE_NOOP3("KStandardShortcut" , "End of Line" , "@action" ), |
176 | .cutDefault: Qt::Key_End, |
177 | .cutDefault2: 0, |
178 | .cut: QList<QKeySequence>(), |
179 | .isInitialized: false, |
180 | .category: Category::Navigation}, |
181 | {.id: GotoLine, .name: "GotoLine" , QT_TRANSLATE_NOOP3("KStandardShortcut" , "Go to Line" , "@action" ), CTRL(G), .cutDefault2: 0, .cut: QList<QKeySequence>(), .isInitialized: false, .category: Category::Navigation}, |
182 | {.id: BackwardWord, |
183 | .name: "BackwardWord" , |
184 | QT_TRANSLATE_NOOP3("KStandardShortcut" , "Backward Word" , "@action" ), |
185 | CTRL(Left), |
186 | .cutDefault2: 0, |
187 | .cut: QList<QKeySequence>(), |
188 | .isInitialized: false, |
189 | .category: Category::Navigation}, |
190 | {.id: ForwardWord, |
191 | .name: "ForwardWord" , |
192 | QT_TRANSLATE_NOOP3("KStandardShortcut" , "Forward Word" , "@action" ), |
193 | CTRL(Right), |
194 | .cutDefault2: 0, |
195 | .cut: QList<QKeySequence>(), |
196 | .isInitialized: false, |
197 | .category: Category::Navigation}, |
198 | |
199 | {.id: AddBookmark, |
200 | .name: "AddBookmark" , |
201 | QT_TRANSLATE_NOOP3("KStandardShortcut" , "Add Bookmark" , "@action" ), |
202 | CTRL(B), |
203 | .cutDefault2: 0, |
204 | .cut: QList<QKeySequence>(), |
205 | .isInitialized: false, |
206 | .category: Category::Navigation}, |
207 | {.id: ZoomIn, .name: "ZoomIn" , QT_TRANSLATE_NOOP3("KStandardShortcut" , "Zoom In" , "@action" ), CTRL(Plus), CTRL(Equal), .cut: QList<QKeySequence>(), .isInitialized: false, .category: Category::View}, |
208 | {.id: ZoomOut, .name: "ZoomOut" , QT_TRANSLATE_NOOP3("KStandardShortcut" , "Zoom Out" , "@action" ), CTRL(Minus), .cutDefault2: 0, .cut: QList<QKeySequence>(), .isInitialized: false, .category: Category::View}, |
209 | {.id: FullScreen, |
210 | .name: "FullScreen" , |
211 | QT_TRANSLATE_NOOP3("KStandardShortcut" , "Full Screen Mode" , "@action" ), |
212 | CTRLSHIFT(F), |
213 | .cutDefault2: 0, |
214 | .cut: QList<QKeySequence>(), |
215 | .isInitialized: false, |
216 | .category: Category::View}, |
217 | |
218 | {.id: ShowMenubar, .name: "ShowMenubar" , QT_TRANSLATE_NOOP3("KStandardShortcut" , "Show Menu Bar" , "@action" ), CTRL(M), .cutDefault2: 0, .cut: QList<QKeySequence>(), .isInitialized: false, .category: Category::View}, |
219 | {.id: TabNext, |
220 | .name: "Activate Next Tab" , |
221 | QT_TRANSLATE_NOOP3("KStandardShortcut" , "Activate Next Tab" , "@action" ), |
222 | CTRL(PageDown), |
223 | CTRL(BracketRight), |
224 | .cut: QList<QKeySequence>(), |
225 | .isInitialized: false, |
226 | .category: Category::Navigation}, |
227 | {.id: TabPrev, |
228 | .name: "Activate Previous Tab" , |
229 | QT_TRANSLATE_NOOP3("KStandardShortcut" , "Activate Previous Tab" , "@action" ), |
230 | CTRL(PageUp), |
231 | CTRL(BracketLeft), |
232 | .cut: QList<QKeySequence>(), |
233 | .isInitialized: false, |
234 | .category: Category::Navigation}, |
235 | |
236 | // Group Help |
237 | {.id: Help, .name: "Help" , QT_TRANSLATE_NOOP3("KStandardShortcut" , "Help" , "@action" ), .cutDefault: Qt::Key_F1, .cutDefault2: 0, .cut: QList<QKeySequence>(), .isInitialized: false, .category: Category::Help}, |
238 | {.id: WhatsThis, .name: "WhatsThis" , QT_TRANSLATE_NOOP3("KStandardShortcut" , "What's This" , "@action" ), SHIFT(F1), .cutDefault2: 0, .cut: QList<QKeySequence>(), .isInitialized: false, .category: Category::Help}, |
239 | |
240 | // Group TextCompletion |
241 | {.id: TextCompletion, |
242 | .name: "TextCompletion" , |
243 | QT_TRANSLATE_NOOP3("KStandardShortcut" , "Text Completion" , "@action" ), |
244 | CTRL(E), |
245 | .cutDefault2: 0, |
246 | .cut: QList<QKeySequence>(), |
247 | .isInitialized: false, |
248 | .category: Category::Edit}, |
249 | {.id: PrevCompletion, |
250 | .name: "PrevCompletion" , |
251 | QT_TRANSLATE_NOOP3("KStandardShortcut" , "Previous Completion Match" , "@action" ), |
252 | CTRL(Up), |
253 | .cutDefault2: 0, |
254 | .cut: QList<QKeySequence>(), |
255 | .isInitialized: false, |
256 | .category: Category::Edit}, |
257 | {.id: NextCompletion, |
258 | .name: "NextCompletion" , |
259 | QT_TRANSLATE_NOOP3("KStandardShortcut" , "Next Completion Match" , "@action" ), |
260 | CTRL(Down), |
261 | .cutDefault2: 0, |
262 | .cut: QList<QKeySequence>(), |
263 | .isInitialized: false, |
264 | .category: Category::Edit}, |
265 | {.id: SubstringCompletion, |
266 | .name: "SubstringCompletion" , |
267 | QT_TRANSLATE_NOOP3("KStandardShortcut" , "Substring Completion" , "@action" ), |
268 | CTRL(T), |
269 | .cutDefault2: 0, |
270 | .cut: QList<QKeySequence>(), |
271 | .isInitialized: false, |
272 | .category: Category::Edit}, |
273 | |
274 | {.id: RotateUp, |
275 | .name: "RotateUp" , |
276 | QT_TRANSLATE_NOOP3("KStandardShortcut" , "Previous Item in List" , "@action" ), |
277 | .cutDefault: Qt::Key_Up, |
278 | .cutDefault2: 0, |
279 | .cut: QList<QKeySequence>(), |
280 | .isInitialized: false, |
281 | .category: Category::Navigation}, |
282 | {.id: RotateDown, |
283 | .name: "RotateDown" , |
284 | QT_TRANSLATE_NOOP3("KStandardShortcut" , "Next Item in List" , "@action" ), |
285 | .cutDefault: Qt::Key_Down, |
286 | .cutDefault2: 0, |
287 | .cut: QList<QKeySequence>(), |
288 | .isInitialized: false, |
289 | .category: Category::Navigation}, |
290 | |
291 | {.id: OpenRecent, .name: "OpenRecent" , QT_TRANSLATE_NOOP3("KStandardShortcut" , "Open Recent" , "@action" ), .cutDefault: 0, .cutDefault2: 0, .cut: QList<QKeySequence>(), .isInitialized: false, .category: Category::File}, |
292 | {.id: SaveAs, .name: "SaveAs" , QT_TRANSLATE_NOOP3("KStandardShortcut" , "Save As" , "@action" ), CTRLSHIFT(S), .cutDefault2: 0, .cut: QList<QKeySequence>(), .isInitialized: false, .category: Category::File}, |
293 | {.id: Revert, .name: "Revert" , QT_TRANSLATE_NOOP3("KStandardShortcut" , "Revert" , "@action" ), .cutDefault: 0, .cutDefault2: 0, .cut: QList<QKeySequence>(), .isInitialized: false, .category: Category::Edit}, |
294 | {.id: PrintPreview, .name: "PrintPreview" , QT_TRANSLATE_NOOP3("KStandardShortcut" , "Print Preview" , "@action" ), .cutDefault: 0, .cutDefault2: 0, .cut: QList<QKeySequence>(), .isInitialized: false, .category: Category::File}, |
295 | {.id: Mail, .name: "Mail" , QT_TRANSLATE_NOOP3("KStandardShortcut" , "Mail" , "@action" ), .cutDefault: 0, .cutDefault2: 0, .cut: QList<QKeySequence>(), .isInitialized: false, .category: Category::Help}, |
296 | {.id: Clear, .name: "Clear" , QT_TRANSLATE_NOOP3("KStandardShortcut" , "Clear" , "@action" ), .cutDefault: 0, .cutDefault2: 0, .cut: QList<QKeySequence>(), .isInitialized: false, .category: Category::Edit}, |
297 | {.id: ActualSize, |
298 | .name: "ActualSize" , |
299 | QT_TRANSLATE_NOOP3("KStandardShortcut" , "Zoom to Actual Size" , "@action" ), |
300 | CTRL(0), |
301 | .cutDefault2: 0, |
302 | .cut: QList<QKeySequence>(), |
303 | .isInitialized: false, |
304 | .category: Category::View}, |
305 | {.id: FitToPage, .name: "FitToPage" , QT_TRANSLATE_NOOP3("KStandardShortcut" , "Fit To Page" , "@action" ), .cutDefault: 0, .cutDefault2: 0, .cut: QList<QKeySequence>(), .isInitialized: false, .category: Category::View}, |
306 | {.id: FitToWidth, .name: "FitToWidth" , QT_TRANSLATE_NOOP3("KStandardShortcut" , "Fit To Width" , "@action" ), .cutDefault: 0, .cutDefault2: 0, .cut: QList<QKeySequence>(), .isInitialized: false, .category: Category::View}, |
307 | {.id: FitToHeight, .name: "FitToHeight" , QT_TRANSLATE_NOOP3("KStandardShortcut" , "Fit To Height" , "@action" ), .cutDefault: 0, .cutDefault2: 0, .cut: QList<QKeySequence>(), .isInitialized: false, .category: Category::View}, |
308 | {.id: Zoom, .name: "Zoom" , QT_TRANSLATE_NOOP3("KStandardShortcut" , "Zoom" , "@action" ), .cutDefault: 0, .cutDefault2: 0, .cut: QList<QKeySequence>(), .isInitialized: false, .category: Category::View}, |
309 | {.id: Goto, .name: "Goto" , QT_TRANSLATE_NOOP3("KStandardShortcut" , "Goto" , "@action" ), .cutDefault: 0, .cutDefault2: 0, .cut: QList<QKeySequence>(), .isInitialized: false, .category: Category::Navigation}, |
310 | {.id: GotoPage, .name: "GotoPage" , QT_TRANSLATE_NOOP3("KStandardShortcut" , "Goto Page" , "@action" ), .cutDefault: 0, .cutDefault2: 0, .cut: QList<QKeySequence>(), .isInitialized: false, .category: Category::Navigation}, |
311 | {.id: DocumentBack, |
312 | .name: "DocumentBack" , |
313 | QT_TRANSLATE_NOOP3("KStandardShortcut" , "Document Back" , "@action" ), |
314 | ALTSHIFT(Left), |
315 | .cutDefault2: 0, |
316 | .cut: QList<QKeySequence>(), |
317 | .isInitialized: false, |
318 | .category: Category::Navigation}, |
319 | {.id: DocumentForward, |
320 | .name: "DocumentForward" , |
321 | QT_TRANSLATE_NOOP3("KStandardShortcut" , "Document Forward" , "@action" ), |
322 | ALTSHIFT(Right), |
323 | .cutDefault2: 0, |
324 | .cut: QList<QKeySequence>(), |
325 | .isInitialized: false, |
326 | .category: Category::Navigation}, |
327 | {.id: EditBookmarks, |
328 | .name: "EditBookmarks" , |
329 | QT_TRANSLATE_NOOP3("KStandardShortcut" , "Edit Bookmarks" , "@action" ), |
330 | .cutDefault: 0, |
331 | .cutDefault2: 0, |
332 | .cut: QList<QKeySequence>(), |
333 | .isInitialized: false, |
334 | .category: Category::Navigation}, |
335 | {.id: Spelling, .name: "Spelling" , QT_TRANSLATE_NOOP3("KStandardShortcut" , "Spelling" , "@action" ), .cutDefault: 0, .cutDefault2: 0, .cut: QList<QKeySequence>(), .isInitialized: false, .category: Category::Edit}, |
336 | {.id: ShowToolbar, .name: "ShowToolbar" , QT_TRANSLATE_NOOP3("KStandardShortcut" , "Show Toolbar" , "@action" ), .cutDefault: 0, .cutDefault2: 0, .cut: QList<QKeySequence>(), .isInitialized: false, .category: Category::View}, |
337 | {.id: ShowStatusbar, .name: "ShowStatusbar" , QT_TRANSLATE_NOOP3("KStandardShortcut" , "Show Statusbar" , "@action" ), .cutDefault: 0, .cutDefault2: 0, .cut: QList<QKeySequence>(), .isInitialized: false, .category: Category::View}, |
338 | {.id: KeyBindings, |
339 | .name: "KeyBindings" , |
340 | QT_TRANSLATE_NOOP3("KStandardShortcut" , "Key Bindings" , "@action" ), |
341 | CTRLALT(Comma), |
342 | .cutDefault2: 0, |
343 | .cut: QList<QKeySequence>(), |
344 | .isInitialized: false, |
345 | .category: Category::Settings}, |
346 | {.id: Preferences, |
347 | .name: "Preferences" , |
348 | QT_TRANSLATE_NOOP3("KStandardShortcut" , "Configure Application" , "@action" ), |
349 | CTRLSHIFT(Comma), |
350 | .cutDefault2: 0, |
351 | .cut: QList<QKeySequence>(), |
352 | .isInitialized: false, |
353 | .category: Category::Settings}, |
354 | {.id: ConfigureToolbars, |
355 | .name: "ConfigureToolbars" , |
356 | QT_TRANSLATE_NOOP3("KStandardShortcut" , "Configure Toolbars" , "@action" ), |
357 | .cutDefault: 0, |
358 | .cutDefault2: 0, |
359 | .cut: QList<QKeySequence>(), |
360 | .isInitialized: false, |
361 | .category: Category::Settings}, |
362 | {.id: ConfigureNotifications, |
363 | .name: "ConfigureNotifications" , |
364 | QT_TRANSLATE_NOOP3("KStandardShortcut" , "Configure Notifications" , "@action" ), |
365 | .cutDefault: 0, |
366 | .cutDefault2: 0, |
367 | .cut: QList<QKeySequence>(), |
368 | .isInitialized: false, |
369 | .category: Category::Settings}, |
370 | {.id: ReportBug, .name: "ReportBug" , QT_TRANSLATE_NOOP3("KStandardShortcut" , "Report Bug" , "@action" ), .cutDefault: 0, .cutDefault2: 0, .cut: QList<QKeySequence>(), .isInitialized: false, .category: Category::Help}, |
371 | {.id: SwitchApplicationLanguage, |
372 | .name: "SwitchApplicationLanguage" , |
373 | QT_TRANSLATE_NOOP3("KStandardShortcut" , "Configure Language..." , "@action" ), |
374 | .cutDefault: 0, |
375 | .cutDefault2: 0, |
376 | .cut: QList<QKeySequence>(), |
377 | .isInitialized: false, |
378 | .category: Category::Settings}, |
379 | {.id: AboutApp, .name: "AboutApp" , QT_TRANSLATE_NOOP3("KStandardShortcut" , "About Application" , "@action" ), .cutDefault: 0, .cutDefault2: 0, .cut: QList<QKeySequence>(), .isInitialized: false, .category: Category::Help}, |
380 | {.id: AboutKDE, .name: "AboutKDE" , QT_TRANSLATE_NOOP3("KStandardShortcut" , "About KDE" , "@action" ), .cutDefault: 0, .cutDefault2: 0, .cut: QList<QKeySequence>(), .isInitialized: false, .category: Category::Help}, |
381 | // Both "Cut" and "Delete" use Shift+Delete, but this is okay; see |
382 | // https://commits.kde.org/kxmlgui/8eabbf6725386e716b7536c71a9181dfe5d959f0 |
383 | {.id: DeleteFile, .name: "DeleteFile" , QT_TRANSLATE_NOOP3("KStandardShortcut" , "Delete" , "@action" ), SHIFT(Delete), .cutDefault2: 0, .cut: QList<QKeySequence>(), .isInitialized: false, .category: Category::File}, |
384 | {.id: RenameFile, .name: "RenameFile" , QT_TRANSLATE_NOOP3("KStandardShortcut" , "Rename" , "@action" ), .cutDefault: Qt::Key_F2, .cutDefault2: 0, .cut: QList<QKeySequence>(), .isInitialized: false, .category: Category::File}, |
385 | {.id: MoveToTrash, |
386 | .name: "MoveToTrash" , |
387 | QT_TRANSLATE_NOOP3("KStandardShortcut" , "Move to Trash" , "@action" ), |
388 | .cutDefault: Qt::Key_Delete, |
389 | .cutDefault2: 0, |
390 | .cut: QList<QKeySequence>(), |
391 | .isInitialized: false, |
392 | .category: Category::File}, |
393 | {.id: Donate, .name: "Donate" , QT_TRANSLATE_NOOP3("KStandardShortcut" , "Donate" , "@action" ), .cutDefault: 0, .cutDefault2: 0, .cut: QList<QKeySequence>(), .isInitialized: false, .category: Category::Help}, |
394 | {.id: ShowHideHiddenFiles, |
395 | .name: "ShowHideHiddenFiles" , |
396 | QT_TRANSLATE_NOOP3("KStandardShortcut" , "Show/Hide Hidden Files" , "@action" ), |
397 | CTRL(H), |
398 | ALT(Period), |
399 | .cut: QList<QKeySequence>(), |
400 | .isInitialized: false, |
401 | .category: Category::View}, |
402 | {.id: CreateFolder, |
403 | .name: "CreateFolder" , |
404 | QT_TRANSLATE_NOOP3("KStandardShortcut" , "Create Folder" , "@action" ), |
405 | CTRLSHIFT(N), |
406 | .cutDefault2: 0, |
407 | .cut: QList<QKeySequence>(), |
408 | .isInitialized: false, |
409 | .category: Category::File}, |
410 | {.id: OpenMainMenu, |
411 | .name: "OpenMainMenu" , |
412 | QT_TRANSLATE_NOOP3("KStandardShortcut" , "Open Main Menu" , "@action referring to the menu bar or a hamburger menu" ), |
413 | .cutDefault: Qt::Key_F10, |
414 | .cutDefault2: 0, |
415 | .cut: QList<QKeySequence>(), |
416 | .isInitialized: false, |
417 | .category: Category::View}, |
418 | {.id: OpenContextMenu, |
419 | .name: "OpenContextMenu" , |
420 | QT_TRANSLATE_NOOP3("KStandardShortcut" , "Open Context Menu" , "@action" ), |
421 | .cutDefault: Qt::Key_Menu, |
422 | SHIFT(F10), |
423 | .cut: QList<QKeySequence>(), |
424 | .isInitialized: false, |
425 | .category: Category::View}, |
426 | |
427 | // dummy entry to catch simple off-by-one errors. Insert new entries before this line. |
428 | {.id: AccelNone, .name: nullptr, .description: {.text: nullptr, .context: nullptr}, .cutDefault: 0, .cutDefault2: 0, .cut: QList<QKeySequence>(), .isInitialized: false, .category: Category::InvalidCategory}}; |
429 | |
430 | /** Search for the KStandardShortcutInfo object associated with the given @p id. |
431 | Return a dummy entry with no name and an empty shortcut if @p id is invalid. |
432 | */ |
433 | static KStandardShortcutInfo *guardedStandardShortcutInfo(StandardShortcut id) |
434 | { |
435 | if (id >= static_cast<int>(sizeof(g_infoStandardShortcut) / sizeof(KStandardShortcutInfo)) || id < 0) { |
436 | qWarning() << "KStandardShortcut: id not found!" ; |
437 | return &g_infoStandardShortcut[AccelNone]; |
438 | } else { |
439 | return &g_infoStandardShortcut[id]; |
440 | } |
441 | } |
442 | |
443 | // Sanitize the list for duplicates. For some reason some |
444 | // people have kdeglobals entries like |
445 | // Close=Ctrl+W; Ctrl+Esc; Ctrl+W; Ctrl+Esc; |
446 | // having the same shortcut more than once in the shortcut |
447 | // declaration is clearly bogus so fix it |
448 | static void sanitizeShortcutList(QList<QKeySequence> *list) |
449 | { |
450 | for (int i = 0; i < list->size(); ++i) { |
451 | const QKeySequence &ks = list->at(i); |
452 | int other = list->indexOf(t: ks, from: i + 1); |
453 | while (other != -1) { |
454 | list->removeAt(i: other); |
455 | other = list->indexOf(t: ks, from: other); |
456 | } |
457 | } |
458 | } |
459 | |
460 | /** Initialize the accelerator @p id by checking if it is overridden |
461 | in the configuration file (and if it isn't, use the default). |
462 | On X11, if QApplication was initialized with GUI disabled, |
463 | the default will always be used. |
464 | */ |
465 | void initialize(StandardShortcut id) |
466 | { |
467 | KStandardShortcutInfo *info = guardedStandardShortcutInfo(id); |
468 | |
469 | // All three are needed. |
470 | if (info->id != AccelNone) { |
471 | Q_ASSERT(info->description.text); |
472 | Q_ASSERT(info->description.context); |
473 | Q_ASSERT(info->name); |
474 | } |
475 | |
476 | KConfigGroup cg(KSharedConfig::openConfig(), QStringLiteral("Shortcuts" )); |
477 | |
478 | if (cg.hasKey(key: info->name)) { |
479 | QString s = cg.readEntry(key: info->name); |
480 | if (s != QLatin1String("none" )) { |
481 | info->cut = QKeySequence::listFromString(str: s); |
482 | sanitizeShortcutList(list: &info->cut); |
483 | } else { |
484 | info->cut = QList<QKeySequence>(); |
485 | } |
486 | } else { |
487 | info->cut = hardcodedDefaultShortcut(id); |
488 | } |
489 | |
490 | info->isInitialized = true; |
491 | } |
492 | |
493 | void saveShortcut(StandardShortcut id, const QList<QKeySequence> &newShortcut) |
494 | { |
495 | KStandardShortcutInfo *info = guardedStandardShortcutInfo(id); |
496 | // If the action has no standard shortcut associated there is nothing to |
497 | // save |
498 | if (info->id == AccelNone) { |
499 | return; |
500 | } |
501 | |
502 | KConfigGroup cg(KSharedConfig::openConfig(), QStringLiteral("Shortcuts" )); |
503 | |
504 | info->cut = newShortcut; |
505 | bool sameAsDefault = (newShortcut == hardcodedDefaultShortcut(id)); |
506 | |
507 | if (sameAsDefault) { |
508 | // If the shortcut is the equal to the hardcoded one we remove it from |
509 | // kdeglobal if necessary and return. |
510 | if (cg.hasKey(key: info->name)) { |
511 | cg.deleteEntry(key: info->name, pFlags: KConfig::Global | KConfig::Persistent | KConfig::Notify); |
512 | cg.sync(); |
513 | } |
514 | |
515 | return; |
516 | } |
517 | |
518 | // Write the changed shortcut to kdeglobals |
519 | sanitizeShortcutList(list: &info->cut); |
520 | cg.writeEntry(key: info->name, value: QKeySequence::listToString(list: info->cut), pFlags: KConfig::Global | KConfig::Persistent | KConfig::Notify); |
521 | cg.sync(); |
522 | } |
523 | |
524 | QString name(StandardShortcut id) |
525 | { |
526 | return QString::fromLatin1(ba: guardedStandardShortcutInfo(id)->name); |
527 | } |
528 | |
529 | QString label(StandardShortcut id) |
530 | { |
531 | KStandardShortcutInfo *info = guardedStandardShortcutInfo(id); |
532 | return QCoreApplication::translate(context: "KStandardShortcut" , key: info->description.text, disambiguation: info->description.context); |
533 | } |
534 | |
535 | // TODO: Add psWhatsThis entry to KStandardShortcutInfo |
536 | QString whatsThis(StandardShortcut /*id*/) |
537 | { |
538 | // KStandardShortcutInfo* info = guardedStandardShortcutInfo( id ); |
539 | // if( info && info->whatsThis ) |
540 | // return i18n(info->whatsThis); |
541 | // else |
542 | return QString(); |
543 | } |
544 | |
545 | const QList<QKeySequence> &shortcut(StandardShortcut id) |
546 | { |
547 | KStandardShortcutInfo *info = guardedStandardShortcutInfo(id); |
548 | |
549 | if (!info->isInitialized) { |
550 | initialize(id); |
551 | } |
552 | |
553 | return info->cut; |
554 | } |
555 | |
556 | StandardShortcut find(const QKeySequence &seq) |
557 | { |
558 | if (!seq.isEmpty()) { |
559 | for (const KStandardShortcutInfo &shortcutInfo : g_infoStandardShortcut) { |
560 | const StandardShortcut id = shortcutInfo.id; |
561 | if (id != AccelNone) { |
562 | if (!shortcutInfo.isInitialized) { |
563 | initialize(id); |
564 | } |
565 | if (shortcutInfo.cut.contains(t: seq)) { |
566 | return id; |
567 | } |
568 | } |
569 | } |
570 | } |
571 | return AccelNone; |
572 | } |
573 | |
574 | StandardShortcut findByName(const QString &name) |
575 | { |
576 | for (const KStandardShortcutInfo &shortcutInfo : g_infoStandardShortcut) { |
577 | if (QLatin1StringView(shortcutInfo.name) == name) { |
578 | return shortcutInfo.id; |
579 | } |
580 | } |
581 | return AccelNone; |
582 | } |
583 | |
584 | QList<QKeySequence> hardcodedDefaultShortcut(StandardShortcut id) |
585 | { |
586 | QList<QKeySequence> cut; |
587 | KStandardShortcutInfo *info = guardedStandardShortcutInfo(id); |
588 | |
589 | if (info->cutDefault != 0) { |
590 | cut << info->cutDefault; |
591 | } |
592 | |
593 | if (info->cutDefault2 != 0) { |
594 | if (cut.isEmpty()) { |
595 | cut << QKeySequence(); |
596 | } |
597 | |
598 | cut << info->cutDefault2; |
599 | } |
600 | |
601 | return cut; |
602 | } |
603 | |
604 | Category category(StandardShortcut id) |
605 | { |
606 | return guardedStandardShortcutInfo(id)->category; |
607 | } |
608 | |
609 | const QList<QKeySequence> &open() |
610 | { |
611 | return shortcut(id: Open); |
612 | } |
613 | const QList<QKeySequence> &openNew() |
614 | { |
615 | return shortcut(id: New); |
616 | } |
617 | const QList<QKeySequence> &close() |
618 | { |
619 | return shortcut(id: Close); |
620 | } |
621 | const QList<QKeySequence> &save() |
622 | { |
623 | return shortcut(id: Save); |
624 | } |
625 | const QList<QKeySequence> &print() |
626 | { |
627 | return shortcut(id: Print); |
628 | } |
629 | const QList<QKeySequence> &quit() |
630 | { |
631 | return shortcut(id: Quit); |
632 | } |
633 | const QList<QKeySequence> &cut() |
634 | { |
635 | return shortcut(id: Cut); |
636 | } |
637 | const QList<QKeySequence> ©() |
638 | { |
639 | return shortcut(id: Copy); |
640 | } |
641 | const QList<QKeySequence> &paste() |
642 | { |
643 | return shortcut(id: Paste); |
644 | } |
645 | const QList<QKeySequence> &pasteSelection() |
646 | { |
647 | return shortcut(id: PasteSelection); |
648 | } |
649 | const QList<QKeySequence> &deleteWordBack() |
650 | { |
651 | return shortcut(id: DeleteWordBack); |
652 | } |
653 | const QList<QKeySequence> &deleteWordForward() |
654 | { |
655 | return shortcut(id: DeleteWordForward); |
656 | } |
657 | const QList<QKeySequence> &undo() |
658 | { |
659 | return shortcut(id: Undo); |
660 | } |
661 | const QList<QKeySequence> &redo() |
662 | { |
663 | return shortcut(id: Redo); |
664 | } |
665 | const QList<QKeySequence> &find() |
666 | { |
667 | return shortcut(id: Find); |
668 | } |
669 | const QList<QKeySequence> &findNext() |
670 | { |
671 | return shortcut(id: FindNext); |
672 | } |
673 | const QList<QKeySequence> &findPrev() |
674 | { |
675 | return shortcut(id: FindPrev); |
676 | } |
677 | const QList<QKeySequence> &replace() |
678 | { |
679 | return shortcut(id: Replace); |
680 | } |
681 | const QList<QKeySequence> &home() |
682 | { |
683 | return shortcut(id: Home); |
684 | } |
685 | const QList<QKeySequence> &begin() |
686 | { |
687 | return shortcut(id: Begin); |
688 | } |
689 | const QList<QKeySequence> &end() |
690 | { |
691 | return shortcut(id: End); |
692 | } |
693 | const QList<QKeySequence> &beginningOfLine() |
694 | { |
695 | return shortcut(id: BeginningOfLine); |
696 | } |
697 | const QList<QKeySequence> &endOfLine() |
698 | { |
699 | return shortcut(id: EndOfLine); |
700 | } |
701 | const QList<QKeySequence> &prior() |
702 | { |
703 | return shortcut(id: Prior); |
704 | } |
705 | const QList<QKeySequence> &next() |
706 | { |
707 | return shortcut(id: Next); |
708 | } |
709 | const QList<QKeySequence> &backwardWord() |
710 | { |
711 | return shortcut(id: BackwardWord); |
712 | } |
713 | const QList<QKeySequence> &forwardWord() |
714 | { |
715 | return shortcut(id: ForwardWord); |
716 | } |
717 | const QList<QKeySequence> &gotoLine() |
718 | { |
719 | return shortcut(id: GotoLine); |
720 | } |
721 | const QList<QKeySequence> &addBookmark() |
722 | { |
723 | return shortcut(id: AddBookmark); |
724 | } |
725 | const QList<QKeySequence> &tabNext() |
726 | { |
727 | return shortcut(id: TabNext); |
728 | } |
729 | const QList<QKeySequence> &tabPrev() |
730 | { |
731 | return shortcut(id: TabPrev); |
732 | } |
733 | const QList<QKeySequence> &fullScreen() |
734 | { |
735 | return shortcut(id: FullScreen); |
736 | } |
737 | const QList<QKeySequence> &zoomIn() |
738 | { |
739 | return shortcut(id: ZoomIn); |
740 | } |
741 | const QList<QKeySequence> &zoomOut() |
742 | { |
743 | return shortcut(id: ZoomOut); |
744 | } |
745 | const QList<QKeySequence> &help() |
746 | { |
747 | return shortcut(id: Help); |
748 | } |
749 | const QList<QKeySequence> &completion() |
750 | { |
751 | return shortcut(id: TextCompletion); |
752 | } |
753 | const QList<QKeySequence> &prevCompletion() |
754 | { |
755 | return shortcut(id: PrevCompletion); |
756 | } |
757 | const QList<QKeySequence> &nextCompletion() |
758 | { |
759 | return shortcut(id: NextCompletion); |
760 | } |
761 | const QList<QKeySequence> &rotateUp() |
762 | { |
763 | return shortcut(id: RotateUp); |
764 | } |
765 | const QList<QKeySequence> &rotateDown() |
766 | { |
767 | return shortcut(id: RotateDown); |
768 | } |
769 | const QList<QKeySequence> &substringCompletion() |
770 | { |
771 | return shortcut(id: SubstringCompletion); |
772 | } |
773 | const QList<QKeySequence> &whatsThis() |
774 | { |
775 | return shortcut(id: WhatsThis); |
776 | } |
777 | const QList<QKeySequence> &reload() |
778 | { |
779 | return shortcut(id: Reload); |
780 | } |
781 | const QList<QKeySequence> &selectAll() |
782 | { |
783 | return shortcut(id: SelectAll); |
784 | } |
785 | const QList<QKeySequence> &up() |
786 | { |
787 | return shortcut(id: Up); |
788 | } |
789 | const QList<QKeySequence> &back() |
790 | { |
791 | return shortcut(id: Back); |
792 | } |
793 | const QList<QKeySequence> &forward() |
794 | { |
795 | return shortcut(id: Forward); |
796 | } |
797 | const QList<QKeySequence> &showMenubar() |
798 | { |
799 | return shortcut(id: ShowMenubar); |
800 | } |
801 | const QList<QKeySequence> &deleteFile() |
802 | { |
803 | return shortcut(id: DeleteFile); |
804 | } |
805 | const QList<QKeySequence> &renameFile() |
806 | { |
807 | return shortcut(id: RenameFile); |
808 | } |
809 | const QList<QKeySequence> &createFolder() |
810 | { |
811 | return shortcut(id: CreateFolder); |
812 | } |
813 | const QList<QKeySequence> &moveToTrash() |
814 | { |
815 | return shortcut(id: MoveToTrash); |
816 | } |
817 | const QList<QKeySequence> &preferences() |
818 | { |
819 | return shortcut(id: Preferences); |
820 | } |
821 | const QList<QKeySequence> &showHideHiddenFiles() |
822 | { |
823 | return shortcut(id: ShowHideHiddenFiles); |
824 | } |
825 | const QList<QKeySequence> &openMainMenu() |
826 | { |
827 | return shortcut(id: OpenMainMenu); |
828 | } |
829 | const QList<QKeySequence> &openContextMenu() |
830 | { |
831 | return shortcut(id: OpenContextMenu); |
832 | } |
833 | } |
834 | |