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
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!
67static 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*/
433static 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
448static 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*/
465void 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
493void 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
524QString name(StandardShortcut id)
525{
526 return QString::fromLatin1(ba: guardedStandardShortcutInfo(id)->name);
527}
528
529QString 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
536QString 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
545const 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
556StandardShortcut 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
574StandardShortcut 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
584QList<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
604Category category(StandardShortcut id)
605{
606 return guardedStandardShortcutInfo(id)->category;
607}
608
609const QList<QKeySequence> &open()
610{
611 return shortcut(id: Open);
612}
613const QList<QKeySequence> &openNew()
614{
615 return shortcut(id: New);
616}
617const QList<QKeySequence> &close()
618{
619 return shortcut(id: Close);
620}
621const QList<QKeySequence> &save()
622{
623 return shortcut(id: Save);
624}
625const QList<QKeySequence> &print()
626{
627 return shortcut(id: Print);
628}
629const QList<QKeySequence> &quit()
630{
631 return shortcut(id: Quit);
632}
633const QList<QKeySequence> &cut()
634{
635 return shortcut(id: Cut);
636}
637const QList<QKeySequence> &copy()
638{
639 return shortcut(id: Copy);
640}
641const QList<QKeySequence> &paste()
642{
643 return shortcut(id: Paste);
644}
645const QList<QKeySequence> &pasteSelection()
646{
647 return shortcut(id: PasteSelection);
648}
649const QList<QKeySequence> &deleteWordBack()
650{
651 return shortcut(id: DeleteWordBack);
652}
653const QList<QKeySequence> &deleteWordForward()
654{
655 return shortcut(id: DeleteWordForward);
656}
657const QList<QKeySequence> &undo()
658{
659 return shortcut(id: Undo);
660}
661const QList<QKeySequence> &redo()
662{
663 return shortcut(id: Redo);
664}
665const QList<QKeySequence> &find()
666{
667 return shortcut(id: Find);
668}
669const QList<QKeySequence> &findNext()
670{
671 return shortcut(id: FindNext);
672}
673const QList<QKeySequence> &findPrev()
674{
675 return shortcut(id: FindPrev);
676}
677const QList<QKeySequence> &replace()
678{
679 return shortcut(id: Replace);
680}
681const QList<QKeySequence> &home()
682{
683 return shortcut(id: Home);
684}
685const QList<QKeySequence> &begin()
686{
687 return shortcut(id: Begin);
688}
689const QList<QKeySequence> &end()
690{
691 return shortcut(id: End);
692}
693const QList<QKeySequence> &beginningOfLine()
694{
695 return shortcut(id: BeginningOfLine);
696}
697const QList<QKeySequence> &endOfLine()
698{
699 return shortcut(id: EndOfLine);
700}
701const QList<QKeySequence> &prior()
702{
703 return shortcut(id: Prior);
704}
705const QList<QKeySequence> &next()
706{
707 return shortcut(id: Next);
708}
709const QList<QKeySequence> &backwardWord()
710{
711 return shortcut(id: BackwardWord);
712}
713const QList<QKeySequence> &forwardWord()
714{
715 return shortcut(id: ForwardWord);
716}
717const QList<QKeySequence> &gotoLine()
718{
719 return shortcut(id: GotoLine);
720}
721const QList<QKeySequence> &addBookmark()
722{
723 return shortcut(id: AddBookmark);
724}
725const QList<QKeySequence> &tabNext()
726{
727 return shortcut(id: TabNext);
728}
729const QList<QKeySequence> &tabPrev()
730{
731 return shortcut(id: TabPrev);
732}
733const QList<QKeySequence> &fullScreen()
734{
735 return shortcut(id: FullScreen);
736}
737const QList<QKeySequence> &zoomIn()
738{
739 return shortcut(id: ZoomIn);
740}
741const QList<QKeySequence> &zoomOut()
742{
743 return shortcut(id: ZoomOut);
744}
745const QList<QKeySequence> &help()
746{
747 return shortcut(id: Help);
748}
749const QList<QKeySequence> &completion()
750{
751 return shortcut(id: TextCompletion);
752}
753const QList<QKeySequence> &prevCompletion()
754{
755 return shortcut(id: PrevCompletion);
756}
757const QList<QKeySequence> &nextCompletion()
758{
759 return shortcut(id: NextCompletion);
760}
761const QList<QKeySequence> &rotateUp()
762{
763 return shortcut(id: RotateUp);
764}
765const QList<QKeySequence> &rotateDown()
766{
767 return shortcut(id: RotateDown);
768}
769const QList<QKeySequence> &substringCompletion()
770{
771 return shortcut(id: SubstringCompletion);
772}
773const QList<QKeySequence> &whatsThis()
774{
775 return shortcut(id: WhatsThis);
776}
777const QList<QKeySequence> &reload()
778{
779 return shortcut(id: Reload);
780}
781const QList<QKeySequence> &selectAll()
782{
783 return shortcut(id: SelectAll);
784}
785const QList<QKeySequence> &up()
786{
787 return shortcut(id: Up);
788}
789const QList<QKeySequence> &back()
790{
791 return shortcut(id: Back);
792}
793const QList<QKeySequence> &forward()
794{
795 return shortcut(id: Forward);
796}
797const QList<QKeySequence> &showMenubar()
798{
799 return shortcut(id: ShowMenubar);
800}
801const QList<QKeySequence> &deleteFile()
802{
803 return shortcut(id: DeleteFile);
804}
805const QList<QKeySequence> &renameFile()
806{
807 return shortcut(id: RenameFile);
808}
809const QList<QKeySequence> &createFolder()
810{
811 return shortcut(id: CreateFolder);
812}
813const QList<QKeySequence> &moveToTrash()
814{
815 return shortcut(id: MoveToTrash);
816}
817const QList<QKeySequence> &preferences()
818{
819 return shortcut(id: Preferences);
820}
821const QList<QKeySequence> &showHideHiddenFiles()
822{
823 return shortcut(id: ShowHideHiddenFiles);
824}
825const QList<QKeySequence> &openMainMenu()
826{
827 return shortcut(id: OpenMainMenu);
828}
829const QList<QKeySequence> &openContextMenu()
830{
831 return shortcut(id: OpenContextMenu);
832}
833}
834

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