1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the QtGui module of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include "qkeysequence.h"
43 #include "qkeysequence_p.h"
44 #include <qpa/qplatformtheme.h>
45 #include "private/qguiapplication_p.h"
47 #ifndef QT_NO_SHORTCUT
53 #ifndef QT_NO_DATASTREAM
54 # include "qdatastream.h"
58 #if defined(Q_OS_MAC) && !defined(Q_OS_IOS)
59 #include <QtCore/private/qcore_mac_p.h>
60 #include <Carbon/Carbon.h>
65 #if defined(Q_OS_MAC) && !defined(Q_OS_IOS)
66 static bool qt_sequence_no_mnemonics = true;
67 struct MacSpecialKey {
72 static const int NumEntries = 21;
73 static const MacSpecialKey entries[NumEntries] = {
74 { Qt::Key_Escape, 0x238B },
75 { Qt::Key_Tab, 0x21E5 },
76 { Qt::Key_Backtab, 0x21E4 },
77 { Qt::Key_Backspace, 0x232B },
78 { Qt::Key_Return, 0x21B5 },
79 { Qt::Key_Enter, 0x2324 },
80 { Qt::Key_Delete, 0x2326 },
81 { Qt::Key_Home, 0x2196 },
82 { Qt::Key_End, 0x2198 },
83 { Qt::Key_Left, 0x2190 },
84 { Qt::Key_Up, 0x2191 },
85 { Qt::Key_Right, 0x2192 },
86 { Qt::Key_Down, 0x2193 },
87 { Qt::Key_PageUp, 0x21DE },
88 { Qt::Key_PageDown, 0x21DF },
89 { Qt::Key_Shift, kShiftUnicode },
90 { Qt::Key_Control, kCommandUnicode },
91 { Qt::Key_Meta, kControlUnicode },
92 { Qt::Key_Alt, kOptionUnicode },
93 { Qt::Key_CapsLock, 0x21EA },
96 static bool operator<(const MacSpecialKey &entry, int key)
98 return entry.key < key;
101 static bool operator<(int key, const MacSpecialKey &entry)
103 return key < entry.key;
106 static const MacSpecialKey * const MacSpecialKeyEntriesEnd = entries + NumEntries;
108 QChar qt_macSymbolForQtKey(int key)
110 const MacSpecialKey *i = qBinaryFind(entries, MacSpecialKeyEntriesEnd, key);
111 if (i == MacSpecialKeyEntriesEnd)
113 ushort macSymbol = i->macSymbol;
114 if (qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)
115 && (macSymbol == kControlUnicode || macSymbol == kCommandUnicode)) {
116 if (macSymbol == kControlUnicode)
117 macSymbol = kCommandUnicode;
119 macSymbol = kControlUnicode;
122 return QChar(macSymbol);
125 static int qtkeyForMacSymbol(const QChar ch)
127 const ushort unicode = ch.unicode();
128 for (int i = 0; i < NumEntries; ++i) {
129 const MacSpecialKey &entry = entries[i];
130 if (entry.macSymbol == unicode) {
132 if (qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)
133 && (unicode == kControlUnicode || unicode == kCommandUnicode)) {
134 if (unicode == kControlUnicode)
135 key = Qt::Key_Control;
146 static bool qt_sequence_no_mnemonics = false;
148 void Q_GUI_EXPORT qt_set_sequence_auto_mnemonic(bool b) { qt_sequence_no_mnemonics = !b; }
152 \brief The QKeySequence class encapsulates a key sequence as used
159 In its most common form, a key sequence describes a combination of
160 keys that must be used together to perform some action. Key sequences
161 are used with QAction objects to specify which keyboard shortcuts can
162 be used to trigger actions.
164 Key sequences can be constructed for use as keyboard shortcuts in
165 three different ways:
168 \li For standard shortcuts, a \l{QKeySequence::StandardKey}{standard key}
169 can be used to request the platform-specific key sequence associated
171 \li For custom shortcuts, human-readable strings such as "Ctrl+X" can
172 be used, and these can be translated into the appropriate shortcuts
173 for users of different languages. Translations are made in the
175 \li For hard-coded shortcuts, integer key codes can be specified with
176 a combination of values defined by the Qt::Key and Qt::Modifier enum
177 values. Each key code consists of a single Qt::Key value and zero or
178 more modifiers, such as Qt::SHIFT, Qt::CTRL, Qt::ALT and Qt::META.
181 For example, \uicontrol{Ctrl P} might be a sequence used as a shortcut for
182 printing a document, and can be specified in any of the following
185 \snippet code/src_gui_kernel_qkeysequence.cpp 0
187 Note that, for letters, the case used in the specification string
188 does not matter. In the above examples, the user does not need to
189 hold down the \uicontrol{Shift} key to activate a shortcut specified
190 with "Ctrl+P". However, for other keys, the use of \uicontrol{Shift} as
191 an unspecified extra modifier key can lead to confusion for users
192 of an application whose keyboards have different layouts to those
193 used by the developers. See the \l{Keyboard Layout Issues} section
194 below for more details.
196 It is preferable to use standard shortcuts where possible.
197 When creating key sequences for non-standard shortcuts, you should use
198 human-readable strings in preference to hard-coded integer values.
200 QKeySequence objects can be cast to a QString to obtain a human-readable
201 translated version of the sequence. Similarly, the toString() function
202 produces human-readable strings for use in menus. On Mac OS X, the
203 appropriate symbols are used to describe keyboard shortcuts using special
204 keys on the Macintosh keyboard.
206 An alternative way to specify hard-coded key codes is to use the Unicode
207 code point of the character; for example, 'A' gives the same key sequence
210 \b{Note:} On Mac OS X, references to "Ctrl", Qt::CTRL, Qt::Control
211 and Qt::ControlModifier correspond to the \uicontrol Command keys on the
212 Macintosh keyboard, and references to "Meta", Qt::META, Qt::Meta and
213 Qt::MetaModifier correspond to the \uicontrol Control keys. Developers on
214 Mac OS X can use the same shortcut descriptions across all platforms,
215 and their applications will automatically work as expected on Mac OS X.
217 \section1 Standard Shortcuts
219 QKeySequence defines many \l{QKeySequence::StandardKey} {standard
220 keyboard shortcuts} to reduce the amount of effort required when
221 setting up actions in a typical application. The table below shows
222 some common key sequences that are often used for these standard
223 shortcuts by applications on four widely-used platforms. Note
224 that on Mac OS X, the \uicontrol Ctrl value corresponds to the \uicontrol
225 Command keys on the Macintosh keyboard, and the \uicontrol Meta value
226 corresponds to the \uicontrol Control keys.
229 \header \li StandardKey \li Windows \li Mac OS X \li KDE \li GNOME
230 \row \li HelpContents \li F1 \li Ctrl+? \li F1 \li F1
231 \row \li WhatsThis \li Shift+F1 \li Shift+F1 \li Shift+F1 \li Shift+F1
232 \row \li Open \li Ctrl+O \li Ctrl+O \li Ctrl+O \li Ctrl+O
233 \row \li Close \li Ctrl+F4, Ctrl+W \li Ctrl+W, Ctrl+F4 \li Ctrl+W \li Ctrl+W
234 \row \li Save \li Ctrl+S \li Ctrl+S \li Ctrl+S \li Ctrl+S
235 \row \li Quit \li \li Ctrl+Q \li Qtrl+Q \li Qtrl+Q
236 \row \li SaveAs \li \li Ctrl+Shift+S \li \li Ctrl+Shift+S
237 \row \li New \li Ctrl+N \li Ctrl+N \li Ctrl+N \li Ctrl+N
238 \row \li Delete \li Del \li Del, Meta+D \li Del, Ctrl+D \li Del, Ctrl+D
239 \row \li Cut \li Ctrl+X, Shift+Del \li Ctrl+X \li Ctrl+X, F20, Shift+Del \li Ctrl+X, F20, Shift+Del
240 \row \li Copy \li Ctrl+C, Ctrl+Ins \li Ctrl+C \li Ctrl+C, F16, Ctrl+Ins \li Ctrl+C, F16, Ctrl+Ins
241 \row \li Paste \li Ctrl+V, Shift+Ins \li Ctrl+V \li Ctrl+V, F18, Shift+Ins \li Ctrl+V, F18, Shift+Ins
242 \row \li Preferences \li \li Ctrl+, \li \li
243 \row \li Undo \li Ctrl+Z, Alt+Backspace \li Ctrl+Z \li Ctrl+Z, F14 \li Ctrl+Z, F14
244 \row \li Redo \li Ctrl+Y, Shift+Ctrl+Z, Alt+Shift+Backspace \li Ctrl+Shift+Z \li Ctrl+Shift+Z \li Ctrl+Shift+Z
245 \row \li Back \li Alt+Left, Backspace \li Ctrl+[ \li Alt+Left \li Alt+Left
246 \row \li Forward \li Alt+Right, Shift+Backspace \li Ctrl+] \li Alt+Right \li Alt+Right
247 \row \li Refresh \li F5 \li F5 \li F5 \li Ctrl+R, F5
248 \row \li ZoomIn \li Ctrl+Plus \li Ctrl+Plus \li Ctrl+Plus \li Ctrl+Plus
249 \row \li ZoomOut \li Ctrl+Minus \li Ctrl+Minus \li Ctrl+Minus \li Ctrl+Minus
250 \row \li FullScreen \li F11, Alt+Enter \li Ctrl+Meta+F \li F11, Ctrl+Shift+F \li Ctrl+F11
251 \row \li Print \li Ctrl+P \li Ctrl+P \li Ctrl+P \li Ctrl+P
252 \row \li AddTab \li Ctrl+T \li Ctrl+T \li Ctrl+Shift+N, Ctrl+T \li Ctrl+T
253 \row \li NextChild \li Ctrl+Tab, Forward, Ctrl+F6 \li Ctrl+}, Forward, Ctrl+Tab \li Ctrl+Tab, Forward, Ctrl+Comma \li Ctrl+Tab, Forward
254 \row \li PreviousChild \li Ctrl+Shift+Tab, Back, Ctrl+Shift+F6 \li Ctrl+{, Back, Ctrl+Shift+Tab \li Ctrl+Shift+Tab, Back, Ctrl+Period \li Ctrl+Shift+Tab, Back
255 \row \li Find \li Ctrl+F \li Ctrl+F \li Ctrl+F \li Ctrl+F
256 \row \li FindNext \li F3, Ctrl+G \li Ctrl+G \li F3 \li Ctrl+G, F3
257 \row \li FindPrevious \li Shift+F3, Ctrl+Shift+G \li Ctrl+Shift+G \li Shift+F3 \li Ctrl+Shift+G, Shift+F3
258 \row \li Replace \li Ctrl+H \li (none) \li Ctrl+R \li Ctrl+H
259 \row \li SelectAll \li Ctrl+A \li Ctrl+A \li Ctrl+A \li Ctrl+A
260 \row \li Bold \li Ctrl+B \li Ctrl+B \li Ctrl+B \li Ctrl+B
261 \row \li Italic \li Ctrl+I \li Ctrl+I \li Ctrl+I \li Ctrl+I
262 \row \li Underline \li Ctrl+U \li Ctrl+U \li Ctrl+U \li Ctrl+U
263 \row \li MoveToNextChar \li Right \li Right \li Right \li Right
264 \row \li MoveToPreviousChar \li Left \li Left \li Left \li Left
265 \row \li MoveToNextWord \li Ctrl+Right \li Alt+Right \li Ctrl+Right \li Ctrl+Right
266 \row \li MoveToPreviousWord \li Ctrl+Left \li Alt+Left \li Ctrl+Left \li Ctrl+Left
267 \row \li MoveToNextLine \li Down \li Down \li Down \li Down
268 \row \li MoveToPreviousLine \li Up \li Up \li Up \li Up
269 \row \li MoveToNextPage \li PgDown \li PgDown, Alt+PgDown, Meta+Down, Meta+PgDown\li PgDown \li PgDown
270 \row \li MoveToPreviousPage \li PgUp \li PgUp, Alt+PgUp, Meta+Up, Meta+PgUp \li PgUp \li PgUp
271 \row \li MoveToStartOfLine \li Home \li Ctrl+Left, Meta+Left \li Home \li Home
272 \row \li MoveToEndOfLine \li End \li Ctrl+Right, Meta+Right \li End \li End
273 \row \li MoveToStartOfBlock \li (none) \li Alt+Up, Meta+A \li (none) \li (none)
274 \row \li MoveToEndOfBlock \li (none) \li Alt+Down, Meta+E \li (none) \li (none)
275 \row \li MoveToStartOfDocument\li Ctrl+Home \li Ctrl+Up, Home \li Ctrl+Home \li Ctrl+Home
276 \row \li MoveToEndOfDocument \li Ctrl+End \li Ctrl+Down, End \li Ctrl+End \li Ctrl+End
277 \row \li SelectNextChar \li Shift+Right \li Shift+Right \li Shift+Right \li Shift+Right
278 \row \li SelectPreviousChar \li Shift+Left \li Shift+Left \li Shift+Left \li Shift+Left
279 \row \li SelectNextWord \li Ctrl+Shift+Right \li Alt+Shift+Right \li Ctrl+Shift+Right \li Ctrl+Shift+Right
280 \row \li SelectPreviousWord \li Ctrl+Shift+Left \li Alt+Shift+Left \li Ctrl+Shift+Left \li Ctrl+Shift+Left
281 \row \li SelectNextLine \li Shift+Down \li Shift+Down \li Shift+Down \li Shift+Down
282 \row \li SelectPreviousLine \li Shift+Up \li Shift+Up \li Shift+Up \li Shift+Up
283 \row \li SelectNextPage \li Shift+PgDown \li Shift+PgDown \li Shift+PgDown \li Shift+PgDown
284 \row \li SelectPreviousPage \li Shift+PgUp \li Shift+PgUp \li Shift+PgUp \li Shift+PgUp
285 \row \li SelectStartOfLine \li Shift+Home \li Ctrl+Shift+Left \li Shift+Home \li Shift+Home
286 \row \li SelectEndOfLine \li Shift+End \li Ctrl+Shift+Right \li Shift+End \li Shift+End
287 \row \li SelectStartOfBlock \li (none) \li Alt+Shift+Up, Meta+Shift+A \li (none) \li (none)
288 \row \li SelectEndOfBlock \li (none) \li Alt+Shift+Down, Meta+Shift+E \li (none) \li (none)
289 \row \li SelectStartOfDocument\li Ctrl+Shift+Home \li Ctrl+Shift+Up, Shift+Home \li Ctrl+Shift+Home\li Ctrl+Shift+Home
290 \row \li SelectEndOfDocument \li Ctrl+Shift+End \li Ctrl+Shift+Down, Shift+End \li Ctrl+Shift+End \li Ctrl+Shift+End
291 \row \li DeleteStartOfWord \li Ctrl+Backspace \li Alt+Backspace \li Ctrl+Backspace \li Ctrl+Backspace
292 \row \li DeleteEndOfWord \li Ctrl+Del \li (none) \li Ctrl+Del \li Ctrl+Del
293 \row \li DeleteEndOfLine \li (none) \li (none) \li Ctrl+K \li Ctrl+K
294 \row \li InsertParagraphSeparator \li Enter \li Enter \li Enter \li Enter
295 \row \li InsertLineSeparator \li Shift+Enter \li Meta+Enter \li Shift+Enter \li Shift+Enter
298 Note that, since the key sequences used for the standard shortcuts differ
299 between platforms, you still need to test your shortcuts on each platform
300 to ensure that you do not unintentionally assign the same key sequence to
303 \section1 Keyboard Layout Issues
305 Many key sequence specifications are chosen by developers based on the
306 layout of certain types of keyboard, rather than choosing keys that
307 represent the first letter of an action's name, such as \uicontrol{Ctrl S}
308 ("Ctrl+S") or \uicontrol{Ctrl C} ("Ctrl+C").
309 Additionally, because certain symbols can only be entered with the
310 help of modifier keys on certain keyboard layouts, key sequences intended
311 for use with one keyboard layout may map to a different key, map to no
312 keys at all, or require an additional modifier key to be used on
313 different keyboard layouts.
315 For example, the shortcuts, \uicontrol{Ctrl plus} and \uicontrol{Ctrl minus}, are often
316 used as shortcuts for zoom operations in graphics applications, and these
317 may be specified as "Ctrl++" and "Ctrl+-" respectively. However, the way
318 these shortcuts are specified and interpreted depends on the keyboard layout.
319 Users of Norwegian keyboards will note that the \uicontrol{+} and \uicontrol{-} keys
320 are not adjacent on the keyboard, but will still be able to activate both
321 shortcuts without needing to press the \uicontrol{Shift} key. However, users
322 with British keyboards will need to hold down the \uicontrol{Shift} key
323 to enter the \uicontrol{+} symbol, making the shortcut effectively the same as
326 Although some developers might resort to fully specifying all the modifiers
327 they use on their keyboards to activate a shortcut, this will also result
328 in unexpected behavior for users of different keyboard layouts.
330 For example, a developer using a British keyboard may decide to specify
331 "Ctrl+Shift+=" as the key sequence in order to create a shortcut that
332 coincidentally behaves in the same way as \uicontrol{Ctrl plus}. However, the
333 \uicontrol{=} key needs to be accessed using the \uicontrol{Shift} key on Norwegian
334 keyboard, making the required shortcut effectively \uicontrol{Ctrl Shift Shift =}
335 (an impossible key combination).
337 As a result, both human-readable strings and hard-coded key codes
338 can both be problematic to use when specifying a key sequence that
339 can be used on a variety of different keyboard layouts. Only the
340 use of \l{QKeySequence::StandardKey} {standard shortcuts}
341 guarantees that the user will be able to use the shortcuts that
342 the developer intended.
344 Despite this, we can address this issue by ensuring that human-readable
345 strings are used, making it possible for translations of key sequences to
346 be made for users of different languages. This approach will be successful
347 for users whose keyboards have the most typical layout for the language
350 \section1 GNU Emacs Style Key Sequences
352 Key sequences similar to those used in \l{GNU Emacs}, allowing up to four
353 key codes, can be created by using the multiple argument constructor,
354 or by passing a human-readable string of comma-separated key sequences.
356 For example, the key sequence, \uicontrol{Ctrl X} followed by \uicontrol{Ctrl C}, can
357 be specified using either of the following ways:
359 \snippet code/src_gui_kernel_qkeysequence.cpp 1
361 \warning A QApplication instance must have been constructed before a
362 QKeySequence is created; otherwise, your application may crash.
368 \enum QKeySequence::SequenceMatch
370 \value NoMatch The key sequences are different; not even partially
372 \value PartialMatch The key sequences match partially, but are not
374 \value ExactMatch The key sequences are the same.
378 \enum QKeySequence::SequenceFormat
380 \value NativeText The key sequence as a platform specific string.
381 This means that it will be shown translated and on the Mac it will
382 resemble a key sequence from the menu bar. This enum is best used when you
383 want to display the string to the user.
385 \value PortableText The key sequence is given in a "portable" format,
386 suitable for reading and writing to a file. In many cases, it will look
387 similar to the native text on Windows and X11.
390 static const struct {
394 //: This and all following "incomprehensible" strings in QShortcut context
395 //: are key names. Please use the localized names appearing on actual
396 //: keyboards or whatever is commonly used.
397 { Qt::Key_Space, QT_TRANSLATE_NOOP("QShortcut", "Space") },
398 { Qt::Key_Escape, QT_TRANSLATE_NOOP("QShortcut", "Esc") },
399 { Qt::Key_Tab, QT_TRANSLATE_NOOP("QShortcut", "Tab") },
400 { Qt::Key_Backtab, QT_TRANSLATE_NOOP("QShortcut", "Backtab") },
401 { Qt::Key_Backspace, QT_TRANSLATE_NOOP("QShortcut", "Backspace") },
402 { Qt::Key_Return, QT_TRANSLATE_NOOP("QShortcut", "Return") },
403 { Qt::Key_Enter, QT_TRANSLATE_NOOP("QShortcut", "Enter") },
404 { Qt::Key_Insert, QT_TRANSLATE_NOOP("QShortcut", "Ins") },
405 { Qt::Key_Delete, QT_TRANSLATE_NOOP("QShortcut", "Del") },
406 { Qt::Key_Pause, QT_TRANSLATE_NOOP("QShortcut", "Pause") },
407 { Qt::Key_Print, QT_TRANSLATE_NOOP("QShortcut", "Print") },
408 { Qt::Key_SysReq, QT_TRANSLATE_NOOP("QShortcut", "SysReq") },
409 { Qt::Key_Home, QT_TRANSLATE_NOOP("QShortcut", "Home") },
410 { Qt::Key_End, QT_TRANSLATE_NOOP("QShortcut", "End") },
411 { Qt::Key_Left, QT_TRANSLATE_NOOP("QShortcut", "Left") },
412 { Qt::Key_Up, QT_TRANSLATE_NOOP("QShortcut", "Up") },
413 { Qt::Key_Right, QT_TRANSLATE_NOOP("QShortcut", "Right") },
414 { Qt::Key_Down, QT_TRANSLATE_NOOP("QShortcut", "Down") },
415 { Qt::Key_PageUp, QT_TRANSLATE_NOOP("QShortcut", "PgUp") },
416 { Qt::Key_PageDown, QT_TRANSLATE_NOOP("QShortcut", "PgDown") },
417 { Qt::Key_CapsLock, QT_TRANSLATE_NOOP("QShortcut", "CapsLock") },
418 { Qt::Key_NumLock, QT_TRANSLATE_NOOP("QShortcut", "NumLock") },
419 { Qt::Key_ScrollLock, QT_TRANSLATE_NOOP("QShortcut", "ScrollLock") },
420 { Qt::Key_Menu, QT_TRANSLATE_NOOP("QShortcut", "Menu") },
421 { Qt::Key_Help, QT_TRANSLATE_NOOP("QShortcut", "Help") },
424 // Includes multimedia, launcher, lan keys ( bluetooth, wireless )
426 { Qt::Key_Back, QT_TRANSLATE_NOOP("QShortcut", "Back") },
427 { Qt::Key_Forward, QT_TRANSLATE_NOOP("QShortcut", "Forward") },
428 { Qt::Key_Stop, QT_TRANSLATE_NOOP("QShortcut", "Stop") },
429 { Qt::Key_Refresh, QT_TRANSLATE_NOOP("QShortcut", "Refresh") },
430 { Qt::Key_VolumeDown, QT_TRANSLATE_NOOP("QShortcut", "Volume Down") },
431 { Qt::Key_VolumeMute, QT_TRANSLATE_NOOP("QShortcut", "Volume Mute") },
432 { Qt::Key_VolumeUp, QT_TRANSLATE_NOOP("QShortcut", "Volume Up") },
433 { Qt::Key_BassBoost, QT_TRANSLATE_NOOP("QShortcut", "Bass Boost") },
434 { Qt::Key_BassUp, QT_TRANSLATE_NOOP("QShortcut", "Bass Up") },
435 { Qt::Key_BassDown, QT_TRANSLATE_NOOP("QShortcut", "Bass Down") },
436 { Qt::Key_TrebleUp, QT_TRANSLATE_NOOP("QShortcut", "Treble Up") },
437 { Qt::Key_TrebleDown, QT_TRANSLATE_NOOP("QShortcut", "Treble Down") },
438 { Qt::Key_MediaPlay, QT_TRANSLATE_NOOP("QShortcut", "Media Play") },
439 { Qt::Key_MediaStop, QT_TRANSLATE_NOOP("QShortcut", "Media Stop") },
440 { Qt::Key_MediaPrevious, QT_TRANSLATE_NOOP("QShortcut", "Media Previous") },
441 { Qt::Key_MediaNext, QT_TRANSLATE_NOOP("QShortcut", "Media Next") },
442 { Qt::Key_MediaRecord, QT_TRANSLATE_NOOP("QShortcut", "Media Record") },
443 //: Media player pause button
444 { Qt::Key_MediaPause, QT_TRANSLATE_NOOP("QShortcut", "Media Pause") },
445 //: Media player button to toggle between playing and paused
446 { Qt::Key_MediaTogglePlayPause, QT_TRANSLATE_NOOP("QShortcut", "Toggle Media Play/Pause") },
447 { Qt::Key_HomePage, QT_TRANSLATE_NOOP("QShortcut", "Home Page") },
448 { Qt::Key_Favorites, QT_TRANSLATE_NOOP("QShortcut", "Favorites") },
449 { Qt::Key_Search, QT_TRANSLATE_NOOP("QShortcut", "Search") },
450 { Qt::Key_Standby, QT_TRANSLATE_NOOP("QShortcut", "Standby") },
451 { Qt::Key_OpenUrl, QT_TRANSLATE_NOOP("QShortcut", "Open URL") },
452 { Qt::Key_LaunchMail, QT_TRANSLATE_NOOP("QShortcut", "Launch Mail") },
453 { Qt::Key_LaunchMedia, QT_TRANSLATE_NOOP("QShortcut", "Launch Media") },
454 { Qt::Key_Launch0, QT_TRANSLATE_NOOP("QShortcut", "Launch (0)") },
455 { Qt::Key_Launch1, QT_TRANSLATE_NOOP("QShortcut", "Launch (1)") },
456 { Qt::Key_Launch2, QT_TRANSLATE_NOOP("QShortcut", "Launch (2)") },
457 { Qt::Key_Launch3, QT_TRANSLATE_NOOP("QShortcut", "Launch (3)") },
458 { Qt::Key_Launch4, QT_TRANSLATE_NOOP("QShortcut", "Launch (4)") },
459 { Qt::Key_Launch5, QT_TRANSLATE_NOOP("QShortcut", "Launch (5)") },
460 { Qt::Key_Launch6, QT_TRANSLATE_NOOP("QShortcut", "Launch (6)") },
461 { Qt::Key_Launch7, QT_TRANSLATE_NOOP("QShortcut", "Launch (7)") },
462 { Qt::Key_Launch8, QT_TRANSLATE_NOOP("QShortcut", "Launch (8)") },
463 { Qt::Key_Launch9, QT_TRANSLATE_NOOP("QShortcut", "Launch (9)") },
464 { Qt::Key_LaunchA, QT_TRANSLATE_NOOP("QShortcut", "Launch (A)") },
465 { Qt::Key_LaunchB, QT_TRANSLATE_NOOP("QShortcut", "Launch (B)") },
466 { Qt::Key_LaunchC, QT_TRANSLATE_NOOP("QShortcut", "Launch (C)") },
467 { Qt::Key_LaunchD, QT_TRANSLATE_NOOP("QShortcut", "Launch (D)") },
468 { Qt::Key_LaunchE, QT_TRANSLATE_NOOP("QShortcut", "Launch (E)") },
469 { Qt::Key_LaunchF, QT_TRANSLATE_NOOP("QShortcut", "Launch (F)") },
470 { Qt::Key_MonBrightnessUp, QT_TRANSLATE_NOOP("QShortcut", "Monitor Brightness Up") },
471 { Qt::Key_MonBrightnessDown, QT_TRANSLATE_NOOP("QShortcut", "Monitor Brightness Down") },
472 { Qt::Key_KeyboardLightOnOff, QT_TRANSLATE_NOOP("QShortcut", "Keyboard Light On/Off") },
473 { Qt::Key_KeyboardBrightnessUp, QT_TRANSLATE_NOOP("QShortcut", "Keyboard Brightness Up") },
474 { Qt::Key_KeyboardBrightnessDown, QT_TRANSLATE_NOOP("QShortcut", "Keyboard Brightness Down") },
475 { Qt::Key_PowerOff, QT_TRANSLATE_NOOP("QShortcut", "Power Off") },
476 { Qt::Key_WakeUp, QT_TRANSLATE_NOOP("QShortcut", "Wake Up") },
477 { Qt::Key_Eject, QT_TRANSLATE_NOOP("QShortcut", "Eject") },
478 { Qt::Key_ScreenSaver, QT_TRANSLATE_NOOP("QShortcut", "Screensaver") },
479 { Qt::Key_WWW, QT_TRANSLATE_NOOP("QShortcut", "WWW") },
480 { Qt::Key_Sleep, QT_TRANSLATE_NOOP("QShortcut", "Sleep") },
481 { Qt::Key_LightBulb, QT_TRANSLATE_NOOP("QShortcut", "LightBulb") },
482 { Qt::Key_Shop, QT_TRANSLATE_NOOP("QShortcut", "Shop") },
483 { Qt::Key_History, QT_TRANSLATE_NOOP("QShortcut", "History") },
484 { Qt::Key_AddFavorite, QT_TRANSLATE_NOOP("QShortcut", "Add Favorite") },
485 { Qt::Key_HotLinks, QT_TRANSLATE_NOOP("QShortcut", "Hot Links") },
486 { Qt::Key_BrightnessAdjust, QT_TRANSLATE_NOOP("QShortcut", "Adjust Brightness") },
487 { Qt::Key_Finance, QT_TRANSLATE_NOOP("QShortcut", "Finance") },
488 { Qt::Key_Community, QT_TRANSLATE_NOOP("QShortcut", "Community") },
489 { Qt::Key_AudioRewind, QT_TRANSLATE_NOOP("QShortcut", "Audio Rewind") },
490 { Qt::Key_BackForward, QT_TRANSLATE_NOOP("QShortcut", "Back Forward") },
491 { Qt::Key_ApplicationLeft, QT_TRANSLATE_NOOP("QShortcut", "Application Left") },
492 { Qt::Key_ApplicationRight, QT_TRANSLATE_NOOP("QShortcut", "Application Right") },
493 { Qt::Key_Book, QT_TRANSLATE_NOOP("QShortcut", "Book") },
494 { Qt::Key_CD, QT_TRANSLATE_NOOP("QShortcut", "CD") },
495 { Qt::Key_Calculator, QT_TRANSLATE_NOOP("QShortcut", "Calculator") },
496 { Qt::Key_Clear, QT_TRANSLATE_NOOP("QShortcut", "Clear") },
497 { Qt::Key_ClearGrab, QT_TRANSLATE_NOOP("QShortcut", "Clear Grab") },
498 { Qt::Key_Close, QT_TRANSLATE_NOOP("QShortcut", "Close") },
499 { Qt::Key_Copy, QT_TRANSLATE_NOOP("QShortcut", "Copy") },
500 { Qt::Key_Cut, QT_TRANSLATE_NOOP("QShortcut", "Cut") },
501 { Qt::Key_Display, QT_TRANSLATE_NOOP("QShortcut", "Display") },
502 { Qt::Key_DOS, QT_TRANSLATE_NOOP("QShortcut", "DOS") },
503 { Qt::Key_Documents, QT_TRANSLATE_NOOP("QShortcut", "Documents") },
504 { Qt::Key_Excel, QT_TRANSLATE_NOOP("QShortcut", "Spreadsheet") },
505 { Qt::Key_Explorer, QT_TRANSLATE_NOOP("QShortcut", "Browser") },
506 { Qt::Key_Game, QT_TRANSLATE_NOOP("QShortcut", "Game") },
507 { Qt::Key_Go, QT_TRANSLATE_NOOP("QShortcut", "Go") },
508 { Qt::Key_iTouch, QT_TRANSLATE_NOOP("QShortcut", "iTouch") },
509 { Qt::Key_LogOff, QT_TRANSLATE_NOOP("QShortcut", "Logoff") },
510 { Qt::Key_Market, QT_TRANSLATE_NOOP("QShortcut", "Market") },
511 { Qt::Key_Meeting, QT_TRANSLATE_NOOP("QShortcut", "Meeting") },
512 { Qt::Key_MenuKB, QT_TRANSLATE_NOOP("QShortcut", "Keyboard Menu") },
513 { Qt::Key_MenuPB, QT_TRANSLATE_NOOP("QShortcut", "Menu PB") },
514 { Qt::Key_MySites, QT_TRANSLATE_NOOP("QShortcut", "My Sites") },
515 { Qt::Key_News, QT_TRANSLATE_NOOP("QShortcut", "News") },
516 { Qt::Key_OfficeHome, QT_TRANSLATE_NOOP("QShortcut", "Home Office") },
517 { Qt::Key_Option, QT_TRANSLATE_NOOP("QShortcut", "Option") },
518 { Qt::Key_Paste, QT_TRANSLATE_NOOP("QShortcut", "Paste") },
519 { Qt::Key_Phone, QT_TRANSLATE_NOOP("QShortcut", "Phone") },
520 { Qt::Key_Reply, QT_TRANSLATE_NOOP("QShortcut", "Reply") },
521 { Qt::Key_Reload, QT_TRANSLATE_NOOP("QShortcut", "Reload") },
522 { Qt::Key_RotateWindows, QT_TRANSLATE_NOOP("QShortcut", "Rotate Windows") },
523 { Qt::Key_RotationPB, QT_TRANSLATE_NOOP("QShortcut", "Rotation PB") },
524 { Qt::Key_RotationKB, QT_TRANSLATE_NOOP("QShortcut", "Rotation KB") },
525 { Qt::Key_Save, QT_TRANSLATE_NOOP("QShortcut", "Save") },
526 { Qt::Key_Send, QT_TRANSLATE_NOOP("QShortcut", "Send") },
527 { Qt::Key_Spell, QT_TRANSLATE_NOOP("QShortcut", "Spellchecker") },
528 { Qt::Key_SplitScreen, QT_TRANSLATE_NOOP("QShortcut", "Split Screen") },
529 { Qt::Key_Support, QT_TRANSLATE_NOOP("QShortcut", "Support") },
530 { Qt::Key_TaskPane, QT_TRANSLATE_NOOP("QShortcut", "Task Panel") },
531 { Qt::Key_Terminal, QT_TRANSLATE_NOOP("QShortcut", "Terminal") },
532 { Qt::Key_Tools, QT_TRANSLATE_NOOP("QShortcut", "Tools") },
533 { Qt::Key_Travel, QT_TRANSLATE_NOOP("QShortcut", "Travel") },
534 { Qt::Key_Video, QT_TRANSLATE_NOOP("QShortcut", "Video") },
535 { Qt::Key_Word, QT_TRANSLATE_NOOP("QShortcut", "Word Processor") },
536 { Qt::Key_Xfer, QT_TRANSLATE_NOOP("QShortcut", "XFer") },
537 { Qt::Key_ZoomIn, QT_TRANSLATE_NOOP("QShortcut", "Zoom In") },
538 { Qt::Key_ZoomOut, QT_TRANSLATE_NOOP("QShortcut", "Zoom Out") },
539 { Qt::Key_Away, QT_TRANSLATE_NOOP("QShortcut", "Away") },
540 { Qt::Key_Messenger, QT_TRANSLATE_NOOP("QShortcut", "Messenger") },
541 { Qt::Key_WebCam, QT_TRANSLATE_NOOP("QShortcut", "WebCam") },
542 { Qt::Key_MailForward, QT_TRANSLATE_NOOP("QShortcut", "Mail Forward") },
543 { Qt::Key_Pictures, QT_TRANSLATE_NOOP("QShortcut", "Pictures") },
544 { Qt::Key_Music, QT_TRANSLATE_NOOP("QShortcut", "Music") },
545 { Qt::Key_Battery, QT_TRANSLATE_NOOP("QShortcut", "Battery") },
546 { Qt::Key_Bluetooth, QT_TRANSLATE_NOOP("QShortcut", "Bluetooth") },
547 { Qt::Key_WLAN, QT_TRANSLATE_NOOP("QShortcut", "Wireless") },
548 { Qt::Key_UWB, QT_TRANSLATE_NOOP("QShortcut", "Ultra Wide Band") },
549 { Qt::Key_AudioForward, QT_TRANSLATE_NOOP("QShortcut", "Audio Forward") },
550 { Qt::Key_AudioRepeat, QT_TRANSLATE_NOOP("QShortcut", "Audio Repeat") },
551 { Qt::Key_AudioRandomPlay, QT_TRANSLATE_NOOP("QShortcut", "Audio Random Play") },
552 { Qt::Key_Subtitle, QT_TRANSLATE_NOOP("QShortcut", "Subtitle") },
553 { Qt::Key_AudioCycleTrack, QT_TRANSLATE_NOOP("QShortcut", "Audio Cycle Track") },
554 { Qt::Key_Time, QT_TRANSLATE_NOOP("QShortcut", "Time") },
555 { Qt::Key_Select, QT_TRANSLATE_NOOP("QShortcut", "Select") },
556 { Qt::Key_View, QT_TRANSLATE_NOOP("QShortcut", "View") },
557 { Qt::Key_TopMenu, QT_TRANSLATE_NOOP("QShortcut", "Top Menu") },
558 { Qt::Key_Suspend, QT_TRANSLATE_NOOP("QShortcut", "Suspend") },
559 { Qt::Key_Hibernate, QT_TRANSLATE_NOOP("QShortcut", "Hibernate") },
561 // --------------------------------------------------------------
562 // More consistent namings
563 { Qt::Key_Print, QT_TRANSLATE_NOOP("QShortcut", "Print Screen") },
564 { Qt::Key_PageUp, QT_TRANSLATE_NOOP("QShortcut", "Page Up") },
565 { Qt::Key_PageDown, QT_TRANSLATE_NOOP("QShortcut", "Page Down") },
566 { Qt::Key_CapsLock, QT_TRANSLATE_NOOP("QShortcut", "Caps Lock") },
567 { Qt::Key_NumLock, QT_TRANSLATE_NOOP("QShortcut", "Num Lock") },
568 { Qt::Key_NumLock, QT_TRANSLATE_NOOP("QShortcut", "Number Lock") },
569 { Qt::Key_ScrollLock, QT_TRANSLATE_NOOP("QShortcut", "Scroll Lock") },
570 { Qt::Key_Insert, QT_TRANSLATE_NOOP("QShortcut", "Insert") },
571 { Qt::Key_Delete, QT_TRANSLATE_NOOP("QShortcut", "Delete") },
572 { Qt::Key_Escape, QT_TRANSLATE_NOOP("QShortcut", "Escape") },
573 { Qt::Key_SysReq, QT_TRANSLATE_NOOP("QShortcut", "System Request") },
575 // --------------------------------------------------------------
576 // Keypad navigation keys
577 { Qt::Key_Select, QT_TRANSLATE_NOOP("QShortcut", "Select") },
578 { Qt::Key_Yes, QT_TRANSLATE_NOOP("QShortcut", "Yes") },
579 { Qt::Key_No, QT_TRANSLATE_NOOP("QShortcut", "No") },
581 // --------------------------------------------------------------
583 { Qt::Key_Context1, QT_TRANSLATE_NOOP("QShortcut", "Context1") },
584 { Qt::Key_Context2, QT_TRANSLATE_NOOP("QShortcut", "Context2") },
585 { Qt::Key_Context3, QT_TRANSLATE_NOOP("QShortcut", "Context3") },
586 { Qt::Key_Context4, QT_TRANSLATE_NOOP("QShortcut", "Context4") },
587 //: Button to start a call (note: a separate button is used to end the call)
588 { Qt::Key_Call, QT_TRANSLATE_NOOP("QShortcut", "Call") },
589 //: Button to end a call (note: a separate button is used to start the call)
590 { Qt::Key_Hangup, QT_TRANSLATE_NOOP("QShortcut", "Hangup") },
591 //: Button that will hang up if we're in call, or make a call if we're not.
592 { Qt::Key_ToggleCallHangup, QT_TRANSLATE_NOOP("QShortcut", "Toggle Call/Hangup") },
593 { Qt::Key_Flip, QT_TRANSLATE_NOOP("QShortcut", "Flip") },
594 //: Button to trigger voice dialing
595 { Qt::Key_VoiceDial, QT_TRANSLATE_NOOP("QShortcut", "Voice Dial") },
596 //: Button to redial the last number called
597 { Qt::Key_LastNumberRedial, QT_TRANSLATE_NOOP("QShortcut", "Last Number Redial") },
598 //: Button to trigger the camera shutter (take a picture)
599 { Qt::Key_Camera, QT_TRANSLATE_NOOP("QShortcut", "Camera Shutter") },
600 //: Button to focus the camera
601 { Qt::Key_CameraFocus, QT_TRANSLATE_NOOP("QShortcut", "Camera Focus") },
603 // --------------------------------------------------------------
604 // Japanese keyboard support
605 { Qt::Key_Kanji, QT_TRANSLATE_NOOP("QShortcut", "Kanji") },
606 { Qt::Key_Muhenkan, QT_TRANSLATE_NOOP("QShortcut", "Muhenkan") },
607 { Qt::Key_Henkan, QT_TRANSLATE_NOOP("QShortcut", "Henkan") },
608 { Qt::Key_Romaji, QT_TRANSLATE_NOOP("QShortcut", "Romaji") },
609 { Qt::Key_Hiragana, QT_TRANSLATE_NOOP("QShortcut", "Hiragana") },
610 { Qt::Key_Katakana, QT_TRANSLATE_NOOP("QShortcut", "Katakana") },
611 { Qt::Key_Hiragana_Katakana,QT_TRANSLATE_NOOP("QShortcut", "Hiragana Katakana") },
612 { Qt::Key_Zenkaku, QT_TRANSLATE_NOOP("QShortcut", "Zenkaku") },
613 { Qt::Key_Hankaku, QT_TRANSLATE_NOOP("QShortcut", "Hankaku") },
614 { Qt::Key_Zenkaku_Hankaku, QT_TRANSLATE_NOOP("QShortcut", "Zenkaku Hankaku") },
615 { Qt::Key_Touroku, QT_TRANSLATE_NOOP("QShortcut", "Touroku") },
616 { Qt::Key_Massyo, QT_TRANSLATE_NOOP("QShortcut", "Massyo") },
617 { Qt::Key_Kana_Lock, QT_TRANSLATE_NOOP("QShortcut", "Kana Lock") },
618 { Qt::Key_Kana_Shift, QT_TRANSLATE_NOOP("QShortcut", "Kana Shift") },
619 { Qt::Key_Eisu_Shift, QT_TRANSLATE_NOOP("QShortcut", "Eisu Shift") },
620 { Qt::Key_Eisu_toggle, QT_TRANSLATE_NOOP("QShortcut", "Eisu toggle") },
621 { Qt::Key_Codeinput, QT_TRANSLATE_NOOP("QShortcut", "Code input") },
622 { Qt::Key_MultipleCandidate,QT_TRANSLATE_NOOP("QShortcut", "Multiple Candidate") },
623 { Qt::Key_PreviousCandidate,QT_TRANSLATE_NOOP("QShortcut", "Previous Candidate") },
625 // --------------------------------------------------------------
626 // Korean keyboard support
627 { Qt::Key_Hangul, QT_TRANSLATE_NOOP("QShortcut", "Hangul") },
628 { Qt::Key_Hangul_Start, QT_TRANSLATE_NOOP("QShortcut", "Hangul Start") },
629 { Qt::Key_Hangul_End, QT_TRANSLATE_NOOP("QShortcut", "Hangul End") },
630 { Qt::Key_Hangul_Hanja, QT_TRANSLATE_NOOP("QShortcut", "Hangul Hanja") },
631 { Qt::Key_Hangul_Jamo, QT_TRANSLATE_NOOP("QShortcut", "Hangul Jamo") },
632 { Qt::Key_Hangul_Romaja, QT_TRANSLATE_NOOP("QShortcut", "Hangul Romaja") },
633 { Qt::Key_Hangul_Jeonja, QT_TRANSLATE_NOOP("QShortcut", "Hangul Jeonja") },
634 { Qt::Key_Hangul_Banja, QT_TRANSLATE_NOOP("QShortcut", "Hangul Banja") },
635 { Qt::Key_Hangul_PreHanja, QT_TRANSLATE_NOOP("QShortcut", "Hangul PreHanja") },
636 { Qt::Key_Hangul_PostHanja,QT_TRANSLATE_NOOP("QShortcut", "Hangul PostHanja") },
637 { Qt::Key_Hangul_Special, QT_TRANSLATE_NOOP("QShortcut", "Hangul Special") },
642 // Table of key bindings. It must be sorted on key sequence:
643 // The integer value of VK_KEY | Modifier Keys (e.g., VK_META, and etc.)
644 // A priority of 1 indicates that this is the primary key binding when multiple are defined.
647 KB_Win = (1 << QPlatformTheme::WindowsKeyboardScheme),
648 KB_Mac = (1 << QPlatformTheme::MacKeyboardScheme),
649 KB_X11 = (1 << QPlatformTheme::X11KeyboardScheme),
650 KB_KDE = (1 << QPlatformTheme::KdeKeyboardScheme),
651 KB_Gnome = (1 << QPlatformTheme::GnomeKeyboardScheme),
652 KB_CDE = (1 << QPlatformTheme::CdeKeyboardScheme),
656 const QKeyBinding QKeySequencePrivate::keyBindings[] = {
657 // StandardKey Priority Key Sequence Platforms
658 {QKeySequence::Back, 0, Qt::Key_Backspace, KB_Win},
659 {QKeySequence::InsertParagraphSeparator,0, Qt::Key_Return, KB_All},
660 {QKeySequence::InsertParagraphSeparator,0, Qt::Key_Enter, KB_All},
661 {QKeySequence::Delete, 1, Qt::Key_Delete, KB_All},
662 {QKeySequence::MoveToStartOfLine, 0, Qt::Key_Home, KB_Win | KB_X11},
663 {QKeySequence::MoveToStartOfDocument, 0, Qt::Key_Home, KB_Mac},
664 {QKeySequence::MoveToEndOfLine, 0, Qt::Key_End, KB_Win | KB_X11},
665 {QKeySequence::MoveToEndOfDocument, 0, Qt::Key_End, KB_Mac},
666 {QKeySequence::MoveToPreviousChar, 0, Qt::Key_Left, KB_All},
667 {QKeySequence::MoveToPreviousLine, 0, Qt::Key_Up, KB_All},
668 {QKeySequence::MoveToNextChar, 0, Qt::Key_Right, KB_All},
669 {QKeySequence::MoveToNextLine, 0, Qt::Key_Down, KB_All},
670 {QKeySequence::MoveToPreviousPage, 1, Qt::Key_PageUp, KB_All},
671 {QKeySequence::MoveToNextPage, 1, Qt::Key_PageDown, KB_All},
672 {QKeySequence::HelpContents, 0, Qt::Key_F1, KB_Win | KB_X11},
673 {QKeySequence::FindNext, 0, Qt::Key_F3, KB_X11},
674 {QKeySequence::FindNext, 1, Qt::Key_F3, KB_Win},
675 {QKeySequence::Refresh, 0, Qt::Key_F5, KB_Win | KB_X11},
676 {QKeySequence::FullScreen, 1, Qt::Key_F11, KB_Win | KB_KDE},
677 {QKeySequence::Undo, 0, Qt::Key_F14, KB_X11}, //Undo on sun keyboards
678 {QKeySequence::Copy, 0, Qt::Key_F16, KB_X11}, //Copy on sun keyboards
679 {QKeySequence::Paste, 0, Qt::Key_F18, KB_X11}, //Paste on sun keyboards
680 {QKeySequence::Cut, 0, Qt::Key_F20, KB_X11}, //Cut on sun keyboards
681 {QKeySequence::PreviousChild, 0, Qt::Key_Back, KB_All},
682 {QKeySequence::NextChild, 0, Qt::Key_Forward, KB_All},
683 {QKeySequence::Forward, 0, Qt::SHIFT | Qt::Key_Backspace, KB_Win},
684 {QKeySequence::InsertLineSeparator, 0, Qt::SHIFT | Qt::Key_Return, KB_All},
685 {QKeySequence::InsertLineSeparator, 0, Qt::SHIFT | Qt::Key_Enter, KB_All},
686 {QKeySequence::Paste, 0, Qt::SHIFT | Qt::Key_Insert, KB_Win | KB_X11},
687 {QKeySequence::Cut, 0, Qt::SHIFT | Qt::Key_Delete, KB_Win | KB_X11}, //## Check if this should work on mac
688 {QKeySequence::SelectStartOfLine, 0, Qt::SHIFT | Qt::Key_Home, KB_Win | KB_X11},
689 {QKeySequence::SelectStartOfDocument, 0, Qt::SHIFT | Qt::Key_Home, KB_Mac},
690 {QKeySequence::SelectEndOfLine, 0, Qt::SHIFT | Qt::Key_End, KB_Win | KB_X11},
691 {QKeySequence::SelectEndOfDocument, 0, Qt::SHIFT | Qt::Key_End, KB_Mac},
692 {QKeySequence::SelectPreviousChar, 0, Qt::SHIFT | Qt::Key_Left, KB_All},
693 {QKeySequence::SelectPreviousLine, 0, Qt::SHIFT | Qt::Key_Up, KB_All},
694 {QKeySequence::SelectNextChar, 0, Qt::SHIFT | Qt::Key_Right, KB_All},
695 {QKeySequence::SelectNextLine, 0, Qt::SHIFT | Qt::Key_Down, KB_All},
696 {QKeySequence::SelectPreviousPage, 0, Qt::SHIFT | Qt::Key_PageUp, KB_All},
697 {QKeySequence::SelectNextPage, 0, Qt::SHIFT | Qt::Key_PageDown, KB_All},
698 {QKeySequence::WhatsThis, 1, Qt::SHIFT | Qt::Key_F1, KB_All},
699 {QKeySequence::FindPrevious, 0, Qt::SHIFT | Qt::Key_F3, KB_X11},
700 {QKeySequence::FindPrevious, 1, Qt::SHIFT | Qt::Key_F3, KB_Win},
701 {QKeySequence::ZoomIn, 1, Qt::CTRL | Qt::Key_Plus, KB_All},
702 {QKeySequence::NextChild, 0, Qt::CTRL | Qt::Key_Comma, KB_KDE},
703 {QKeySequence::Preferences, 0, Qt::CTRL | Qt::Key_Comma, KB_Mac},
704 {QKeySequence::ZoomOut, 1, Qt::CTRL | Qt::Key_Minus, KB_All},
705 {QKeySequence::PreviousChild, 0, Qt::CTRL | Qt::Key_Period, KB_KDE},
706 {QKeySequence::HelpContents, 1, Qt::CTRL | Qt::Key_Question, KB_Mac},
707 {QKeySequence::SelectAll, 1, Qt::CTRL | Qt::Key_A, KB_All},
708 {QKeySequence::Bold, 1, Qt::CTRL | Qt::Key_B, KB_All},
709 {QKeySequence::Copy, 1, Qt::CTRL | Qt::Key_C, KB_All},
710 {QKeySequence::Delete, 0, Qt::CTRL | Qt::Key_D, KB_X11}, //emacs (line edit only)
711 {QKeySequence::Find, 0, Qt::CTRL | Qt::Key_F, KB_All},
712 {QKeySequence::FindNext, 1, Qt::CTRL | Qt::Key_G, KB_Gnome | KB_Mac},
713 {QKeySequence::FindNext, 0, Qt::CTRL | Qt::Key_G, KB_Win},
714 {QKeySequence::Replace, 0, Qt::CTRL | Qt::Key_H, KB_Win},
715 {QKeySequence::Replace, 0, Qt::CTRL | Qt::Key_H, KB_Gnome},
716 {QKeySequence::Italic, 0, Qt::CTRL | Qt::Key_I, KB_All},
717 {QKeySequence::DeleteEndOfLine, 0, Qt::CTRL | Qt::Key_K, KB_X11}, //emacs (line edit only)
718 {QKeySequence::New, 1, Qt::CTRL | Qt::Key_N, KB_All},
719 {QKeySequence::Open, 1, Qt::CTRL | Qt::Key_O, KB_All},
720 {QKeySequence::Print, 1, Qt::CTRL | Qt::Key_P, KB_All},
721 {QKeySequence::Quit, 0, Qt::CTRL | Qt::Key_Q, KB_Gnome | KB_KDE | KB_Mac},
722 {QKeySequence::Refresh, 1, Qt::CTRL | Qt::Key_R, KB_Gnome | KB_Mac},
723 {QKeySequence::Replace, 0, Qt::CTRL | Qt::Key_R, KB_KDE},
724 {QKeySequence::Save, 1, Qt::CTRL | Qt::Key_S, KB_All},
725 {QKeySequence::AddTab, 0, Qt::CTRL | Qt::Key_T, KB_All},
726 {QKeySequence::Underline, 1, Qt::CTRL | Qt::Key_U, KB_All},
727 {QKeySequence::Paste, 1, Qt::CTRL | Qt::Key_V, KB_All},
728 {QKeySequence::Close, 0, Qt::CTRL | Qt::Key_W, KB_Win | KB_X11},
729 {QKeySequence::Close, 1, Qt::CTRL | Qt::Key_W, KB_Mac},
730 {QKeySequence::Cut, 1, Qt::CTRL | Qt::Key_X, KB_All},
731 {QKeySequence::Redo, 1, Qt::CTRL | Qt::Key_Y, KB_Win},
732 {QKeySequence::Undo, 1, Qt::CTRL | Qt::Key_Z, KB_All},
733 {QKeySequence::Back, 1, Qt::CTRL | Qt::Key_BracketLeft, KB_Mac},
734 {QKeySequence::Forward, 1, Qt::CTRL | Qt::Key_BracketRight, KB_Mac},
735 {QKeySequence::PreviousChild, 1, Qt::CTRL | Qt::Key_BraceLeft, KB_Mac},
736 {QKeySequence::NextChild, 1, Qt::CTRL | Qt::Key_BraceRight, KB_Mac},
737 {QKeySequence::NextChild, 1, Qt::CTRL | Qt::Key_Tab, KB_Win | KB_X11},
738 {QKeySequence::NextChild, 0, Qt::CTRL | Qt::Key_Tab, KB_Mac}, //different priority from above
739 {QKeySequence::DeleteStartOfWord, 0, Qt::CTRL | Qt::Key_Backspace, KB_X11 | KB_Win},
740 {QKeySequence::Copy, 0, Qt::CTRL | Qt::Key_Insert, KB_X11 | KB_Win},
741 {QKeySequence::DeleteEndOfWord, 0, Qt::CTRL | Qt::Key_Delete, KB_X11 | KB_Win},
742 {QKeySequence::MoveToStartOfDocument, 0, Qt::CTRL | Qt::Key_Home, KB_Win | KB_X11},
743 {QKeySequence::MoveToEndOfDocument, 0, Qt::CTRL | Qt::Key_End, KB_Win | KB_X11},
744 {QKeySequence::Back, 0, Qt::CTRL | Qt::Key_Left, KB_Mac},
745 {QKeySequence::MoveToPreviousWord, 0, Qt::CTRL | Qt::Key_Left, KB_Win | KB_X11},
746 {QKeySequence::MoveToStartOfLine, 0, Qt::CTRL | Qt::Key_Left, KB_Mac },
747 {QKeySequence::MoveToStartOfDocument, 1, Qt::CTRL | Qt::Key_Up, KB_Mac},
748 {QKeySequence::Forward, 0, Qt::CTRL | Qt::Key_Right, KB_Mac},
749 {QKeySequence::MoveToEndOfLine, 0, Qt::CTRL | Qt::Key_Right, KB_Mac },
750 {QKeySequence::MoveToNextWord, 0, Qt::CTRL | Qt::Key_Right, KB_Win | KB_X11},
751 {QKeySequence::MoveToEndOfDocument, 1, Qt::CTRL | Qt::Key_Down, KB_Mac},
752 {QKeySequence::Close, 1, Qt::CTRL | Qt::Key_F4, KB_Win},
753 {QKeySequence::Close, 0, Qt::CTRL | Qt::Key_F4, KB_Mac},
754 {QKeySequence::NextChild, 0, Qt::CTRL | Qt::Key_F6, KB_Win},
755 {QKeySequence::FullScreen, 1, Qt::CTRL | Qt::Key_F11, KB_Gnome},
756 {QKeySequence::FullScreen, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_F, KB_KDE},
757 {QKeySequence::FindPrevious, 1, Qt::CTRL | Qt::SHIFT | Qt::Key_G, KB_Gnome | KB_Mac},
758 {QKeySequence::FindPrevious, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_G, KB_Win},
759 {QKeySequence::AddTab, 1, Qt::CTRL | Qt::SHIFT | Qt::Key_N, KB_KDE},
760 {QKeySequence::SaveAs, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_S, KB_Gnome | KB_Mac},
761 {QKeySequence::Redo, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_Z, KB_Win | KB_X11},
762 {QKeySequence::Redo, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_Z, KB_Mac},
763 {QKeySequence::PreviousChild, 1, Qt::CTRL | Qt::SHIFT | Qt::Key_Backtab, KB_Win | KB_X11},
764 {QKeySequence::PreviousChild, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_Backtab, KB_Mac },//different priority from above
765 {QKeySequence::Paste, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_Insert, KB_X11},
766 {QKeySequence::SelectStartOfDocument, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_Home, KB_Win | KB_X11},
767 {QKeySequence::SelectEndOfDocument, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_End, KB_Win | KB_X11},
768 {QKeySequence::SelectPreviousWord, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_Left, KB_Win | KB_X11},
769 {QKeySequence::SelectStartOfLine, 1, Qt::CTRL | Qt::SHIFT | Qt::Key_Left, KB_Mac },
770 {QKeySequence::SelectStartOfDocument, 1, Qt::CTRL | Qt::SHIFT | Qt::Key_Up, KB_Mac},
771 {QKeySequence::SelectNextWord, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_Right, KB_Win | KB_X11},
772 {QKeySequence::SelectEndOfLine, 1, Qt::CTRL | Qt::SHIFT | Qt::Key_Right, KB_Mac },
773 {QKeySequence::SelectEndOfDocument, 1, Qt::CTRL | Qt::SHIFT | Qt::Key_Down, KB_Mac},
774 {QKeySequence::PreviousChild, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_F6, KB_Win},
775 {QKeySequence::Undo, 0, Qt::ALT | Qt::Key_Backspace, KB_Win},
776 {QKeySequence::DeleteStartOfWord, 0, Qt::ALT | Qt::Key_Backspace, KB_Mac},
777 {QKeySequence::FullScreen, 0, Qt::ALT | Qt::Key_Enter, KB_Win},
778 {QKeySequence::DeleteEndOfWord, 0, Qt::ALT | Qt::Key_Delete, KB_Mac},
779 {QKeySequence::Back, 1, Qt::ALT | Qt::Key_Left, KB_Win | KB_X11},
780 {QKeySequence::MoveToPreviousWord, 0, Qt::ALT | Qt::Key_Left, KB_Mac},
781 {QKeySequence::MoveToStartOfBlock, 0, Qt::ALT | Qt::Key_Up, KB_Mac}, //mac only
782 {QKeySequence::MoveToNextWord, 0, Qt::ALT | Qt::Key_Right, KB_Mac},
783 {QKeySequence::Forward, 1, Qt::ALT | Qt::Key_Right, KB_Win | KB_X11},
784 {QKeySequence::MoveToEndOfBlock, 0, Qt::ALT | Qt::Key_Down, KB_Mac}, //mac only
785 {QKeySequence::MoveToPreviousPage, 0, Qt::ALT | Qt::Key_PageUp, KB_Mac },
786 {QKeySequence::MoveToNextPage, 0, Qt::ALT | Qt::Key_PageDown, KB_Mac },
787 {QKeySequence::Redo, 0, Qt::ALT | Qt::SHIFT | Qt::Key_Backspace,KB_Win},
788 {QKeySequence::SelectPreviousWord, 0, Qt::ALT | Qt::SHIFT | Qt::Key_Left, KB_Mac},
789 {QKeySequence::SelectStartOfBlock, 0, Qt::ALT | Qt::SHIFT | Qt::Key_Up, KB_Mac}, //mac only
790 {QKeySequence::SelectNextWord, 0, Qt::ALT | Qt::SHIFT | Qt::Key_Right, KB_Mac},
791 {QKeySequence::SelectEndOfBlock, 0, Qt::ALT | Qt::SHIFT | Qt::Key_Down, KB_Mac}, //mac only
792 {QKeySequence::MoveToStartOfBlock, 0, Qt::META | Qt::Key_A, KB_Mac},
793 {QKeySequence::Delete, 0, Qt::META | Qt::Key_D, KB_Mac},
794 {QKeySequence::MoveToEndOfBlock, 0, Qt::META | Qt::Key_E, KB_Mac},
795 {QKeySequence::InsertLineSeparator, 0, Qt::META | Qt::Key_Return, KB_Mac},
796 {QKeySequence::InsertLineSeparator, 0, Qt::META | Qt::Key_Enter, KB_Mac},
797 {QKeySequence::MoveToStartOfLine, 0, Qt::META | Qt::Key_Left, KB_Mac},
798 {QKeySequence::MoveToPreviousPage, 0, Qt::META | Qt::Key_Up, KB_Mac},
799 {QKeySequence::MoveToEndOfLine, 0, Qt::META | Qt::Key_Right, KB_Mac},
800 {QKeySequence::MoveToNextPage, 0, Qt::META | Qt::Key_Down, KB_Mac},
801 {QKeySequence::MoveToPreviousPage, 0, Qt::META | Qt::Key_PageUp, KB_Mac},
802 {QKeySequence::MoveToNextPage, 0, Qt::META | Qt::Key_PageDown, KB_Mac},
803 {QKeySequence::SelectStartOfBlock, 0, Qt::META | Qt::SHIFT | Qt::Key_A, KB_Mac},
804 {QKeySequence::SelectEndOfBlock, 0, Qt::META | Qt::SHIFT | Qt::Key_E, KB_Mac},
805 {QKeySequence::SelectStartOfLine, 0, Qt::META | Qt::SHIFT | Qt::Key_Left, KB_Mac},
806 {QKeySequence::SelectEndOfLine, 0, Qt::META | Qt::SHIFT | Qt::Key_Right, KB_Mac},
807 {QKeySequence::FullScreen, 1, Qt::META | Qt::CTRL | Qt::Key_F, KB_Mac}
810 const uint QKeySequencePrivate::numberOfKeyBindings = sizeof(QKeySequencePrivate::keyBindings)/(sizeof(QKeyBinding));
814 \enum QKeySequence::StandardKey
817 This enum represent standard key bindings. They can be used to
818 assign platform dependent keyboard shortcuts to a QAction.
820 Note that the key bindings are platform dependent. The currently
821 bound shortcuts can be queried using keyBindings().
823 \value AddTab Add new tab.
824 \value Back Navigate back.
825 \value Bold Bold text.
826 \value Close Close document/tab.
829 \value Delete Delete.
830 \value DeleteEndOfLine Delete end of line.
831 \value DeleteEndOfWord Delete word from the end of the cursor.
832 \value DeleteStartOfWord Delete the beginning of a word up to the cursor.
833 \value Find Find in document.
834 \value FindNext Find next result.
835 \value FindPrevious Find previous result.
836 \value Forward Navigate forward.
837 \value HelpContents Open help contents.
838 \value InsertLineSeparator Insert a new line.
839 \value InsertParagraphSeparator Insert a new paragraph.
840 \value Italic Italic text.
841 \value MoveToEndOfBlock Move cursor to end of block. This shortcut is only used on the OS X.
842 \value MoveToEndOfDocument Move cursor to end of document.
843 \value MoveToEndOfLine Move cursor to end of line.
844 \value MoveToNextChar Move cursor to next character.
845 \value MoveToNextLine Move cursor to next line.
846 \value MoveToNextPage Move cursor to next page.
847 \value MoveToNextWord Move cursor to next word.
848 \value MoveToPreviousChar Move cursor to previous character.
849 \value MoveToPreviousLine Move cursor to previous line.
850 \value MoveToPreviousPage Move cursor to previous page.
851 \value MoveToPreviousWord Move cursor to previous word.
852 \value MoveToStartOfBlock Move cursor to start of a block. This shortcut is only used on OS X.
853 \value MoveToStartOfDocument Move cursor to start of document.
854 \value MoveToStartOfLine Move cursor to start of line.
855 \value New Create new document.
856 \value NextChild Navigate to next tab or child window.
857 \value Open Open document.
859 \value Preferences Open the preferences dialog.
860 \value PreviousChild Navigate to previous tab or child window.
861 \value Print Print document.
862 \value Quit Quit the application.
864 \value Refresh Refresh or reload current document.
865 \value Replace Find and replace.
866 \value SaveAs Save document after prompting the user for a file name.
867 \value Save Save document.
868 \value SelectAll Select all text.
869 \value SelectEndOfBlock Extend selection to the end of a text block. This shortcut is only used on OS X.
870 \value SelectEndOfDocument Extend selection to end of document.
871 \value SelectEndOfLine Extend selection to end of line.
872 \value SelectNextChar Extend selection to next character.
873 \value SelectNextLine Extend selection to next line.
874 \value SelectNextPage Extend selection to next page.
875 \value SelectNextWord Extend selection to next word.
876 \value SelectPreviousChar Extend selection to previous character.
877 \value SelectPreviousLine Extend selection to previous line.
878 \value SelectPreviousPage Extend selection to previous page.
879 \value SelectPreviousWord Extend selection to previous word.
880 \value SelectStartOfBlock Extend selection to the start of a text block. This shortcut is only used on OS X.
881 \value SelectStartOfDocument Extend selection to start of document.
882 \value SelectStartOfLine Extend selection to start of line.
883 \value Underline Underline text.
885 \value UnknownKey Unbound key.
886 \value WhatsThis Activate "what's this".
887 \value ZoomIn Zoom in.
888 \value ZoomOut Zoom out.
889 \value FullScreen Toggle the window state to/from full screen.
895 Constructs a QKeySequence object for the given \a key.
896 The result will depend on the currently running platform.
898 The resulting object will be based on the first element in the
899 list of key bindings for the \a key.
901 QKeySequence::QKeySequence(StandardKey key)
903 const QList <QKeySequence> bindings = keyBindings(key);
904 //pick only the first/primary shortcut from current bindings
905 if (bindings.size() > 0) {
906 d = bindings.first().d;
910 d = new QKeySequencePrivate();
915 Constructs an empty key sequence.
917 QKeySequence::QKeySequence()
919 static QKeySequencePrivate shared_empty;
925 Creates a key sequence from the \a key string, based on \a format.
927 For example "Ctrl+O" gives CTRL+'O'. The strings "Ctrl",
928 "Shift", "Alt" and "Meta" are recognized, as well as their
929 translated equivalents in the "QShortcut" context (using
932 Up to four key codes may be entered by separating them with
933 commas, e.g. "Alt+X,Ctrl+S,Q".
935 This constructor is typically used with \l{QObject::tr()}{tr}(), so
936 that shortcut keys can be replaced in translations:
938 \snippet code/src_gui_kernel_qkeysequence.cpp 2
940 Note the "File|Open" translator comment. It is by no means
941 necessary, but it provides some context for the human translator.
943 QKeySequence::QKeySequence(const QString &key, QKeySequence::SequenceFormat format)
945 d = new QKeySequencePrivate();
950 Constructs a key sequence with up to 4 keys \a k1, \a k2,
953 The key codes are listed in Qt::Key and can be combined with
954 modifiers (see Qt::Modifier) such as Qt::SHIFT, Qt::CTRL,
955 Qt::ALT, or Qt::META.
957 QKeySequence::QKeySequence(int k1, int k2, int k3, int k4)
959 d = new QKeySequencePrivate();
967 Copy constructor. Makes a copy of \a keysequence.
969 QKeySequence::QKeySequence(const QKeySequence& keysequence)
975 #if defined(Q_OS_MAC) && !defined(Q_OS_IOS)
976 static inline int maybeSwapShortcut(int shortcut)
978 if (qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)) {
979 uint oldshortcut = shortcut;
980 shortcut &= ~(Qt::CTRL | Qt::META);
981 if (oldshortcut & Qt::CTRL)
982 shortcut |= Qt::META;
983 if (oldshortcut & Qt::META)
984 shortcut |= Qt::CTRL;
993 Returns a list of key bindings for the given \a key.
994 The result of calling this function will vary based on the target platform.
995 The first element of the list indicates the primary shortcut for the given platform.
996 If the result contains more than one result, these can
997 be considered alternative shortcuts on the same platform for the given \a key.
999 QList<QKeySequence> QKeySequence::keyBindings(StandardKey key)
1001 const uint platform = QKeySequencePrivate::currentKeyPlatforms();
1002 QList <QKeySequence> list;
1003 for (uint i = 0; i < QKeySequencePrivate::numberOfKeyBindings ; ++i) {
1004 QKeyBinding keyBinding = QKeySequencePrivate::keyBindings[i];
1005 if (keyBinding.standardKey == key && (keyBinding.platform & platform)) {
1007 #if defined(Q_OS_MAC) && !defined(Q_OS_IOS)
1008 maybeSwapShortcut(QKeySequencePrivate::keyBindings[i].shortcut);
1010 QKeySequencePrivate::keyBindings[i].shortcut;
1012 if (keyBinding.priority > 0)
1013 list.prepend(QKeySequence(shortcut));
1015 list.append(QKeySequence(shortcut));
1022 Destroys the key sequence.
1024 QKeySequence::~QKeySequence()
1026 if (!d->ref.deref())
1032 KeySequences should never be modified, but rather just created.
1033 Internally though we do need to modify to keep pace in event
1037 void QKeySequence::setKey(int key, int index)
1039 Q_ASSERT_X(index >= 0 && index < 4, "QKeySequence::setKey", "index out of range");
1041 d->key[index] = key;
1045 Returns the number of keys in the key sequence.
1048 int QKeySequence::count() const
1063 Returns true if the key sequence is empty; otherwise returns
1066 bool QKeySequence::isEmpty() const
1073 Returns the shortcut key sequence for the mnemonic in \a text,
1074 or an empty key sequence if no mnemonics are found.
1076 For example, mnemonic("E&xit") returns \c{Qt::ALT+Qt::Key_X},
1077 mnemonic("&Quit") returns \c{ALT+Key_Q}, and mnemonic("Quit")
1078 returns an empty QKeySequence.
1080 We provide a \l{accelerators.html}{list of common mnemonics}
1081 in English. At the time of writing, Microsoft and Open Group do
1082 not appear to have issued equivalent recommendations for other
1085 \sa qt_set_sequence_auto_mnemonic()
1087 QKeySequence QKeySequence::mnemonic(const QString &text)
1091 if(qt_sequence_no_mnemonics)
1097 p = text.indexOf(QLatin1Char('&'), p) + 1;
1098 if (p <= 0 || p >= (int)text.length())
1100 if (text.at(p) != QLatin1Char('&')) {
1101 QChar c = text.at(p);
1105 ret = QKeySequence(c.unicode() + Qt::ALT);
1111 qWarning("QKeySequence::mnemonic: \"%s\" contains multiple occurrences of '&'", qPrintable(text));
1122 \fn int QKeySequence::assign(const QString &keys)
1124 Adds the given \a keys to the key sequence. \a keys may
1125 contain up to four key codes, provided they are separated by a
1126 comma; for example, "Alt+X,Ctrl+S,Z". The return value is the
1127 number of key codes added.
1128 \a keys should be in NativeText format.
1130 int QKeySequence::assign(const QString &ks)
1132 return assign(ks, NativeText);
1136 \fn int QKeySequence::assign(const QString &keys, QKeySequence::SequenceFormat format)
1139 Adds the given \a keys to the key sequence (based on \a format).
1140 \a keys may contain up to four key codes, provided they are
1141 separated by a comma; for example, "Alt+X,Ctrl+S,Z". The return
1142 value is the number of key codes added.
1144 int QKeySequence::assign(const QString &ks, QKeySequence::SequenceFormat format)
1146 QString keyseq = ks;
1149 int p = 0, diff = 0;
1151 // Run through the whole string, but stop
1152 // if we have 4 keys before the end.
1153 while (keyseq.length() && n < 4) {
1154 // We MUST use something to separate each sequence, and space
1155 // does not cut it, since some of the key names have space
1156 // in them.. (Let's hope no one translate with a comma in it:)
1157 p = keyseq.indexOf(QLatin1Char(','));
1159 if (p == keyseq.count() - 1) { // Last comma 'Ctrl+,'
1162 if (QLatin1Char(',') == keyseq.at(p+1)) // e.g. 'Ctrl+,, Shift+,,'
1164 if (QLatin1Char(' ') == keyseq.at(p+1)) { // Space after comma
1172 part = keyseq.left(-1 == p ? keyseq.length() : p - diff);
1173 keyseq = keyseq.right(-1 == p ? 0 : keyseq.length() - (p + 1));
1174 d->key[n] = QKeySequencePrivate::decodeString(part, format);
1180 struct QModifKeyName {
1182 QModifKeyName(int q, QChar n) : qt_key(q), name(n) { }
1183 QModifKeyName(int q, const QString &n) : qt_key(q), name(n) { }
1188 Q_GLOBAL_STATIC(QList<QModifKeyName>, globalModifs)
1189 Q_GLOBAL_STATIC(QList<QModifKeyName>, globalPortableModifs)
1192 Constructs a single key from the string \a str.
1194 int QKeySequence::decodeString(const QString &str)
1196 return QKeySequencePrivate::decodeString(str, NativeText);
1199 int QKeySequencePrivate::decodeString(const QString &str, QKeySequence::SequenceFormat format)
1202 QString accel = str.toLower();
1203 bool nativeText = (format == QKeySequence::NativeText);
1205 QList<QModifKeyName> *gmodifs;
1207 gmodifs = globalModifs();
1208 if (gmodifs->isEmpty()) {
1209 #if defined(Q_OS_MAC) && !defined(Q_OS_IOS)
1210 const bool dontSwap = qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta);
1212 *gmodifs << QModifKeyName(Qt::META, QChar(kCommandUnicode));
1214 *gmodifs << QModifKeyName(Qt::CTRL, QChar(kCommandUnicode));
1215 *gmodifs << QModifKeyName(Qt::ALT, QChar(kOptionUnicode));
1217 *gmodifs << QModifKeyName(Qt::CTRL, QChar(kControlUnicode));
1219 *gmodifs << QModifKeyName(Qt::META, QChar(kControlUnicode));
1220 *gmodifs << QModifKeyName(Qt::SHIFT, QChar(kShiftUnicode));
1222 *gmodifs << QModifKeyName(Qt::CTRL, QLatin1String("ctrl+"))
1223 << QModifKeyName(Qt::SHIFT, QLatin1String("shift+"))
1224 << QModifKeyName(Qt::ALT, QLatin1String("alt+"))
1225 << QModifKeyName(Qt::META, QLatin1String("meta+"));
1228 gmodifs = globalPortableModifs();
1229 if (gmodifs->isEmpty()) {
1230 *gmodifs << QModifKeyName(Qt::CTRL, QLatin1String("ctrl+"))
1231 << QModifKeyName(Qt::SHIFT, QLatin1String("shift+"))
1232 << QModifKeyName(Qt::ALT, QLatin1String("alt+"))
1233 << QModifKeyName(Qt::META, QLatin1String("meta+"));
1236 if (!gmodifs) return ret;
1239 QList<QModifKeyName> modifs;
1241 modifs << QModifKeyName(Qt::CTRL, QCoreApplication::translate("QShortcut", "Ctrl").toLower().append(QLatin1Char('+')))
1242 << QModifKeyName(Qt::SHIFT, QCoreApplication::translate("QShortcut", "Shift").toLower().append(QLatin1Char('+')))
1243 << QModifKeyName(Qt::ALT, QCoreApplication::translate("QShortcut", "Alt").toLower().append(QLatin1Char('+')))
1244 << QModifKeyName(Qt::META, QCoreApplication::translate("QShortcut", "Meta").toLower().append(QLatin1Char('+')));
1246 modifs += *gmodifs; // Test non-translated ones last
1249 #if defined(Q_OS_MAC) && !defined(Q_OS_IOS)
1250 for (int i = 0; i < modifs.size(); ++i) {
1251 const QModifKeyName &mkf = modifs.at(i);
1252 if (sl.contains(mkf.name)) {
1254 accel.remove(mkf.name);
1261 while ((i = sl.indexOf(QLatin1Char('+'), i + 1)) != -1) {
1262 const QString sub = sl.mid(lastI, i - lastI + 1);
1263 // If we get here the shortcuts contains at least one '+'. We break up
1264 // along the following strategy:
1265 // Meta+Ctrl++ ( "Meta+", "Ctrl+", "+" )
1266 // Super+Shift+A ( "Super+", "Shift+" )
1267 // 4+3+2=1 ( "4+", "3+" )
1268 // In other words, everything we try to handle HAS to be a modifier
1269 // except for a single '+' at the end of the string.
1271 // Only '+' can have length 1.
1272 if (sub.length() == 1) {
1273 // Make sure we only encounter a single '+' at the end of the accel
1274 if (accel.lastIndexOf(QLatin1Char('+')) != accel.length()-1)
1275 return Qt::Key_unknown;
1277 // Identify the modifier
1278 bool validModifier = false;
1279 for (int j = 0; j < modifs.size(); ++j) {
1280 const QModifKeyName &mkf = modifs.at(j);
1281 if (sub == mkf.name) {
1283 validModifier = true;
1284 break; // Shortcut, since if we find an other it would/should just be a dup
1289 return Qt::Key_unknown;
1295 int p = accel.lastIndexOf(QLatin1Char('+'), str.length() - 2); // -2 so that Ctrl++ works
1297 accel = accel.mid(p + 1);
1300 if (accel.length() == 1) {
1301 #if defined(Q_OS_MAC) && !defined(Q_OS_IOS)
1302 int qtKey = qtkeyForMacSymbol(accel[0]);
1308 ret |= accel[0].toUpper().unicode();
1310 } else if (accel[0] == QLatin1Char('f') && (fnum = accel.mid(1).toInt()) && (fnum >= 1) && (fnum <= 35)) {
1311 ret |= Qt::Key_F1 + fnum - 1;
1313 // For NativeText, check the traslation table first,
1314 // if we don't find anything then try it out with just the untranlated stuff.
1315 // PortableText will only try the untranlated table.
1317 for (int tran = 0; tran < 2; ++tran) {
1320 for (int i = 0; keyname[i].name; ++i) {
1321 QString keyName(tran == 0
1322 ? QCoreApplication::translate("QShortcut", keyname[i].name)
1323 : QString::fromLatin1(keyname[i].name));
1324 if (accel == keyName.toLower()) {
1325 ret |= keyname[i].key;
1333 // We couldn't translate the key.
1335 return Qt::Key_unknown;
1340 unsigned QKeySequencePrivate::currentKeyPlatforms()
1342 int keyboardScheme = QPlatformTheme::WindowsKeyboardScheme;
1343 if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme())
1344 keyboardScheme = theme->themeHint(QPlatformTheme::KeyboardScheme).toInt();
1345 unsigned result = 1u << keyboardScheme;
1346 if (keyboardScheme == QPlatformTheme::KdeKeyboardScheme
1347 || keyboardScheme == QPlatformTheme::GnomeKeyboardScheme
1348 || keyboardScheme == QPlatformTheme::CdeKeyboardScheme)
1354 Creates a shortcut string for \a key. For example,
1355 Qt::CTRL+Qt::Key_O gives "Ctrl+O". The strings, "Ctrl", "Shift", etc. are
1356 translated (using QObject::tr()) in the "QShortcut" context.
1358 QString QKeySequence::encodeString(int key)
1360 return QKeySequencePrivate::encodeString(key, NativeText);
1363 static inline void addKey(QString &str, const QString &theKey, QKeySequence::SequenceFormat format)
1366 str += (format == QKeySequence::NativeText) ? QCoreApplication::translate("QShortcut", "+")
1367 : QString::fromLatin1("+");
1371 QString QKeySequencePrivate::encodeString(int key, QKeySequence::SequenceFormat format)
1373 bool nativeText = (format == QKeySequence::NativeText);
1376 // Handle -1 (Invalid Key) and Qt::Key_unknown gracefully
1377 if (key == -1 || key == Qt::Key_unknown)
1380 #if defined(Q_OS_MAC) && !defined(Q_OS_IOS)
1382 // On Mac OS X the order (by default) is Meta, Alt, Shift, Control.
1383 // If the AA_MacDontSwapCtrlAndMeta is enabled, then the order
1384 // is Ctrl, Alt, Shift, Meta. The macSymbolForQtKey does this swap
1385 // for us, which means that we have to adjust our order here.
1386 // The upshot is a lot more infrastructure to keep the number of
1387 // if tests down and the code relatively clean.
1388 static const int ModifierOrder[] = { Qt::META, Qt::ALT, Qt::SHIFT, Qt::CTRL, 0 };
1389 static const int QtKeyOrder[] = { Qt::Key_Meta, Qt::Key_Alt, Qt::Key_Shift, Qt::Key_Control, 0 };
1390 static const int DontSwapModifierOrder[] = { Qt::CTRL, Qt::ALT, Qt::SHIFT, Qt::META, 0 };
1391 static const int DontSwapQtKeyOrder[] = { Qt::Key_Control, Qt::Key_Alt, Qt::Key_Shift, Qt::Key_Meta, 0 };
1392 const int *modifierOrder;
1393 const int *qtkeyOrder;
1394 if (qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)) {
1395 modifierOrder = DontSwapModifierOrder;
1396 qtkeyOrder = DontSwapQtKeyOrder;
1398 modifierOrder = ModifierOrder;
1399 qtkeyOrder = QtKeyOrder;
1402 for (int i = 0; modifierOrder[i] != 0; ++i) {
1403 if (key & modifierOrder[i])
1404 s += qt_macSymbolForQtKey(qtkeyOrder[i]);
1409 // On other systems the order is Meta, Control, Alt, Shift
1410 if ((key & Qt::META) == Qt::META)
1411 s = nativeText ? QCoreApplication::translate("QShortcut", "Meta") : QString::fromLatin1("Meta");
1412 if ((key & Qt::CTRL) == Qt::CTRL)
1413 addKey(s, nativeText ? QCoreApplication::translate("QShortcut", "Ctrl") : QString::fromLatin1("Ctrl"), format);
1414 if ((key & Qt::ALT) == Qt::ALT)
1415 addKey(s, nativeText ? QCoreApplication::translate("QShortcut", "Alt") : QString::fromLatin1("Alt"), format);
1416 if ((key & Qt::SHIFT) == Qt::SHIFT)
1417 addKey(s, nativeText ? QCoreApplication::translate("QShortcut", "Shift") : QString::fromLatin1("Shift"), format);
1421 key &= ~(Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier);
1424 if (key && key < Qt::Key_Escape && key != Qt::Key_Space) {
1425 if (!QChar::requiresSurrogates(key)) {
1426 p = QChar(ushort(key)).toUpper();
1428 p += QChar(QChar::highSurrogate(key));
1429 p += QChar(QChar::lowSurrogate(key));
1431 } else if (key >= Qt::Key_F1 && key <= Qt::Key_F35) {
1432 p = nativeText ? QCoreApplication::translate("QShortcut", "F%1").arg(key - Qt::Key_F1 + 1)
1433 : QString::fromLatin1("F%1").arg(key - Qt::Key_F1 + 1);
1436 #if defined(Q_OS_MAC) && !defined(Q_OS_IOS)
1438 QChar ch = qt_macSymbolForQtKey(key);
1446 #if defined(Q_OS_MAC) && !defined(Q_OS_IOS)
1449 while (keyname[i].name) {
1450 if (key == keyname[i].key) {
1451 p = nativeText ? QCoreApplication::translate("QShortcut", keyname[i].name)
1452 : QString::fromLatin1(keyname[i].name);
1457 // If we can't find the actual translatable keyname,
1458 // fall back on the unicode representation of it...
1459 // Or else characters like Qt::Key_aring may not get displayed
1460 // (Really depends on you locale)
1461 if (!keyname[i].name) {
1462 if (!QChar::requiresSurrogates(key)) {
1463 p = QChar(ushort(key)).toUpper();
1465 p += QChar(QChar::highSurrogate(key));
1466 p += QChar(QChar::lowSurrogate(key));
1472 #if defined(Q_OS_MAC) && !defined(Q_OS_IOS)
1477 addKey(s, p, format);
1481 Matches the sequence with \a seq. Returns ExactMatch if
1482 successful, PartialMatch if \a seq matches incompletely,
1483 and NoMatch if the sequences have nothing in common.
1484 Returns NoMatch if \a seq is shorter.
1486 QKeySequence::SequenceMatch QKeySequence::matches(const QKeySequence &seq) const
1488 uint userN = count(),
1494 // If equal in length, we have a potential ExactMatch sequence,
1495 // else we already know it can only be partial.
1496 SequenceMatch match = (userN == seqN ? ExactMatch : PartialMatch);
1498 for (uint i = 0; i < userN; ++i) {
1499 int userKey = (*this)[i],
1500 sequenceKey = seq[i];
1501 if (userKey != sequenceKey)
1508 /*! \fn QKeySequence::operator QString() const
1512 Use toString() instead.
1514 Returns the key sequence as a QString. This is equivalent to
1515 calling toString(QKeySequence::NativeText). Note that the
1516 result is not platform independent.
1520 Returns the key sequence as a QVariant
1522 QKeySequence::operator QVariant() const
1524 return QVariant(QVariant::KeySequence, this);
1527 /*! \fn QKeySequence::operator int () const
1530 For backward compatibility: returns the first keycode
1531 as integer. If the key sequence is empty, 0 is returned.
1535 Returns a reference to the element at position \a index in the key
1536 sequence. This can only be used to read an element.
1538 int QKeySequence::operator[](uint index) const
1540 Q_ASSERT_X(index < 4, "QKeySequence::operator[]", "index out of range");
1541 return d->key[index];
1546 Assignment operator. Assigns the \a other key sequence to this
1549 QKeySequence &QKeySequence::operator=(const QKeySequence &other)
1551 qAtomicAssign(d, other.d);
1556 \fn void QKeySequence::swap(QKeySequence &other)
1559 Swaps key sequence \a other with this key sequence. This operation is very
1560 fast and never fails.
1564 \fn bool QKeySequence::operator!=(const QKeySequence &other) const
1566 Returns true if this key sequence is not equal to the \a other
1567 key sequence; otherwise returns false.
1572 Returns true if this key sequence is equal to the \a other
1573 key sequence; otherwise returns false.
1575 bool QKeySequence::operator==(const QKeySequence &other) const
1577 return (d->key[0] == other.d->key[0] &&
1578 d->key[1] == other.d->key[1] &&
1579 d->key[2] == other.d->key[2] &&
1580 d->key[3] == other.d->key[3]);
1585 Provides an arbitrary comparison of this key sequence and
1586 \a other key sequence. All that is guaranteed is that the
1587 operator returns false if both key sequences are equal and
1588 that (ks1 \< ks2) == !( ks2 \< ks1) if the key sequences
1591 This function is useful in some circumstances, for example
1592 if you want to use QKeySequence objects as keys in a QMap.
1594 \sa operator==(), operator!=(), operator>(), operator<=(), operator>=()
1596 bool QKeySequence::operator< (const QKeySequence &other) const
1598 for (int i = 0; i < 4; ++i)
1599 if (d->key[i] != other.d->key[i])
1600 return d->key[i] < other.d->key[i];
1605 \fn bool QKeySequence::operator> (const QKeySequence &other) const
1607 Returns true if this key sequence is larger than the \a other key
1608 sequence; otherwise returns false.
1610 \sa operator==(), operator!=(), operator<(), operator<=(), operator>=()
1614 \fn bool QKeySequence::operator<= (const QKeySequence &other) const
1616 Returns true if this key sequence is smaller or equal to the
1617 \a other key sequence; otherwise returns false.
1619 \sa operator==(), operator!=(), operator<(), operator>(), operator>=()
1623 \fn bool QKeySequence::operator>= (const QKeySequence &other) const
1625 Returns true if this key sequence is larger or equal to the
1626 \a other key sequence; otherwise returns false.
1628 \sa operator==(), operator!=(), operator<(), operator>(), operator<=()
1634 bool QKeySequence::isDetached() const
1636 return d->ref.load() == 1;
1642 Return a string representation of the key sequence,
1645 For example, the value Qt::CTRL+Qt::Key_O results in "Ctrl+O".
1646 If the key sequence has multiple key codes, each is separated
1647 by commas in the string returned, such as "Alt+X, Ctrl+Y, Z".
1648 The strings, "Ctrl", "Shift", etc. are translated using
1649 QObject::tr() in the "QShortcut" context.
1651 If the key sequence has no keys, an empty string is returned.
1653 On Mac OS X, the string returned resembles the sequence that is
1654 shown in the menu bar.
1658 QString QKeySequence::toString(SequenceFormat format) const
1660 QString finalString;
1661 // A standard string, with no translation or anything like that. In some ways it will
1662 // look like our latin case on Windows and X11
1664 for (int i = 0; i < end; ++i) {
1665 finalString += d->encodeString(d->key[i], format);
1666 finalString += QLatin1String(", ");
1668 finalString.truncate(finalString.length() - 2);
1675 Return a QKeySequence from the string \a str based on \a format.
1679 QKeySequence QKeySequence::fromString(const QString &str, SequenceFormat format)
1681 return QKeySequence(str, format);
1684 /*****************************************************************************
1685 QKeySequence stream functions
1686 *****************************************************************************/
1687 #if !defined(QT_NO_DATASTREAM)
1689 \fn QDataStream &operator<<(QDataStream &stream, const QKeySequence &sequence)
1690 \relates QKeySequence
1692 Writes the key \a sequence to the \a stream.
1694 \sa{Serializing Qt Data Types}{Format of the QDataStream operators}
1696 QDataStream &operator<<(QDataStream &s, const QKeySequence &keysequence)
1698 QList<quint32> list;
1699 list << keysequence.d->key[0];
1701 if (s.version() >= 5 && keysequence.count() > 1) {
1702 list << keysequence.d->key[1];
1703 list << keysequence.d->key[2];
1704 list << keysequence.d->key[3];
1712 \fn QDataStream &operator>>(QDataStream &stream, QKeySequence &sequence)
1713 \relates QKeySequence
1715 Reads a key sequence from the \a stream into the key \a sequence.
1717 \sa{Serializing Qt Data Types}{Format of the QDataStream operators}
1719 QDataStream &operator>>(QDataStream &s, QKeySequence &keysequence)
1721 qAtomicDetach(keysequence.d);
1722 QList<quint32> list;
1724 for (int i = 0; i < 4; ++i)
1725 keysequence.d->key[i] = list.value(i);
1729 #endif //QT_NO_DATASTREAM
1731 #ifndef QT_NO_DEBUG_STREAM
1732 QDebug operator<<(QDebug dbg, const QKeySequence &p)
1734 dbg.nospace() << "QKeySequence(" << p.toString() << ')';
1739 #endif // QT_NO_SHORTCUT
1743 \typedef QKeySequence::DataPtr
1748 \fn DataPtr &QKeySequence::data_ptr()