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

source code of kconfig/src/gui/kstandardshortcut.cpp