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