1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 or version 3 as published by the Free
20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22 ** following information to ensure the GNU Lesser General Public License
23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 **
26 ** As a special exception, The Qt Company gives you certain additional
27 ** rights. These rights are described in The Qt Company LGPL Exception
28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 **
30 ** GNU General Public License Usage
31 ** Alternatively, this file may be used under the terms of the GNU
32 ** General Public License version 3.0 as published by the Free Software
33 ** Foundation and appearing in the file LICENSE.GPL included in the
34 ** packaging of this file.  Please review the following information to
35 ** ensure the GNU General Public License version 3.0 requirements will be
36 ** met: http://www.gnu.org/copyleft/gpl.html.
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "qkeysequence.h"
43 #include "qkeysequence_p.h"
44 #include "private/qapplication_p.h"
45 
46 #ifndef QT_NO_SHORTCUT
47 
48 #include "qshortcut.h"
49 #include "qdebug.h"
50 #ifndef QT_NO_REGEXP
51 # include "qregexp.h"
52 #endif
53 #ifndef QT_NO_DATASTREAM
54 # include "qdatastream.h"
55 #endif
56 #include "qvariant.h"
57 
58 #ifdef Q_WS_MAC
59 # include <private/qt_mac_p.h>
60 
61 #endif
62 
63 QT_BEGIN_NAMESPACE
64 
65 #ifdef Q_WS_MAC
66 static bool qt_sequence_no_mnemonics = true;
67 struct MacSpecialKey {
68     int key;
69     ushort macSymbol;
70 };
71 
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 },
94 };
95 
operator <(const MacSpecialKey & entry,int key)96 static bool operator<(const MacSpecialKey &entry, int key)
97 {
98     return entry.key < key;
99 }
100 
operator <(int key,const MacSpecialKey & entry)101 static bool operator<(int key, const MacSpecialKey &entry)
102 {
103     return key < entry.key;
104 }
105 
106 static const MacSpecialKey * const MacSpecialKeyEntriesEnd = entries + NumEntries;
107 
qt_macSymbolForQtKey(int key)108 QChar qt_macSymbolForQtKey(int key)
109 {
110     const MacSpecialKey *i = qBinaryFind(entries, MacSpecialKeyEntriesEnd, key);
111     if (i == MacSpecialKeyEntriesEnd)
112         return QChar();
113     ushort macSymbol = i->macSymbol;
114     if (qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)
115             && (macSymbol == kControlUnicode || macSymbol == kCommandUnicode)) {
116         if (macSymbol == kControlUnicode)
117             macSymbol = kCommandUnicode;
118         else
119             macSymbol = kControlUnicode;
120     }
121 
122     return QChar(macSymbol);
123 }
124 
qtkeyForMacSymbol(const QChar ch)125 static int qtkeyForMacSymbol(const QChar ch)
126 {
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) {
131             int key = entry.key;
132             if (qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)
133                     && (unicode == kControlUnicode || unicode == kCommandUnicode)) {
134                 if (unicode == kControlUnicode)
135                     key = Qt::Key_Control;
136                 else
137                     key = Qt::Key_Meta;
138             }
139             return key;
140         }
141     }
142     return -1;
143 }
144 
145 #else
146 static bool qt_sequence_no_mnemonics = false;
147 #endif
qt_set_sequence_auto_mnemonic(bool b)148 void Q_GUI_EXPORT qt_set_sequence_auto_mnemonic(bool b) { qt_sequence_no_mnemonics = !b; }
149 
150 /*!
151     \class QKeySequence
152     \brief The QKeySequence class encapsulates a key sequence as used
153     by shortcuts.
154 
155     \ingroup shared
156 
157 
158     In its most common form, a key sequence describes a combination of
159     keys that must be used together to perform some action. Key sequences
160     are used with QAction objects to specify which keyboard shortcuts can
161     be used to trigger actions.
162 
163     Key sequences can be constructed for use as keyboard shortcuts in
164     three different ways:
165 
166     \list
167     \o For standard shortcuts, a \l{QKeySequence::StandardKey}{standard key}
168        can be used to request the platform-specific key sequence associated
169        with each shortcut.
170     \o For custom shortcuts, human-readable strings such as "Ctrl+X" can
171        be used, and these can be translated into the appropriate shortcuts
172        for users of different languages. Translations are made in the
173        "QShortcut" context.
174     \o For hard-coded shortcuts, integer key codes can be specified with
175        a combination of values defined by the Qt::Key and Qt::Modifier enum
176        values. Each key code consists of a single Qt::Key value and zero or
177        more modifiers, such as Qt::SHIFT, Qt::CTRL, Qt::ALT and Qt::META.
178     \endlist
179 
180     For example, \gui{Ctrl P} might be a sequence used as a shortcut for
181     printing a document, and can be specified in any of the following
182     ways:
183 
184     \snippet doc/src/snippets/code/src_gui_kernel_qkeysequence.cpp 0
185 
186     Note that, for letters, the case used in the specification string
187     does not matter. In the above examples, the user does not need to
188     hold down the \key{Shift} key to activate a shortcut specified
189     with "Ctrl+P". However, for other keys, the use of \key{Shift} as
190     an unspecified extra modifier key can lead to confusion for users
191     of an application whose keyboards have different layouts to those
192     used by the developers. See the \l{Keyboard Layout Issues} section
193     below for more details.
194 
195     It is preferable to use standard shortcuts where possible.
196     When creating key sequences for non-standard shortcuts, you should use
197     human-readable strings in preference to hard-coded integer values.
198 
199     QKeySequence objects can be cast to a QString to obtain a human-readable
200     translated version of the sequence. Similarly, the toString() function
201     produces human-readable strings for use in menus. On Mac OS X, the
202     appropriate symbols are used to describe keyboard shortcuts using special
203     keys on the Macintosh keyboard.
204 
205     An alternative way to specify hard-coded key codes is to use the Unicode
206     code point of the character; for example, 'A' gives the same key sequence
207     as Qt::Key_A.
208 
209     \bold{Note:} On Mac OS X, references to "Ctrl", Qt::CTRL, Qt::Control
210     and Qt::ControlModifier correspond to the \key Command keys on the
211     Macintosh keyboard, and references to "Meta", Qt::META, Qt::Meta and
212     Qt::MetaModifier correspond to the \key Control keys. Developers on
213     Mac OS X can use the same shortcut descriptions across all platforms,
214     and their applications will automatically work as expected on Mac OS X.
215 
216     \section1 Standard Shortcuts
217 
218     QKeySequence defines many \l{QKeySequence::StandardKey} {standard
219     keyboard shortcuts} to reduce the amount of effort required when
220     setting up actions in a typical application. The table below shows
221     some common key sequences that are often used for these standard
222     shortcuts by applications on four widely-used platforms.  Note
223     that on Mac OS X, the \key Ctrl value corresponds to the \key
224     Command keys on the Macintosh keyboard, and the \key Meta value
225     corresponds to the \key Control keys.
226 
227     \table
228     \header \i StandardKey      \i Windows                              \i Mac OS X                 \i KDE          \i GNOME                                 \i S60
229     \row    \i HelpContents     \i F1                                   \i Ctrl+?                   \i F1           \i F1                                    \i F2
230     \row    \i WhatsThis        \i Shift+F1                             \i Shift+F1                 \i Shift+F1     \i Shift+F1                              \i Shift+F1
231     \row    \i Open             \i Ctrl+O                               \i Ctrl+O                   \i Ctrl+O       \i Ctrl+O                                \i (none)
232     \row    \i Close            \i Ctrl+F4, Ctrl+W                      \i Ctrl+W, Ctrl+F4          \i Ctrl+W       \i Ctrl+W                                \i (none)
233     \row    \i Save             \i Ctrl+S                               \i Ctrl+S                   \i Ctrl+S       \i Ctrl+S                                \i (none)
234     \row    \i Quit             \i                                      \i Ctrl+Q                   \i Qtrl+Q       \i Qtrl+Q                                \i (none)
235     \row    \i SaveAs           \i                                      \i Ctrl+Shift+S             \i              \i Ctrl+Shift+S                          \i (none)
236     \row    \i New              \i Ctrl+N                               \i Ctrl+N                   \i Ctrl+N       \i Ctrl+N                                \i (none)
237     \row    \i Delete           \i Del                                  \i Del, Meta+D              \i Del, Ctrl+D  \i Del, Ctrl+D                           \i Del
238     \row    \i Cut              \i Ctrl+X, Shift+Del                    \i Ctrl+X                   \i Ctrl+X, F20, Shift+Del \i Ctrl+X, F20, Shift+Del      \i Ctrl+X
239     \row    \i Copy             \i Ctrl+C, Ctrl+Ins                     \i Ctrl+C                   \i Ctrl+C, F16, Ctrl+Ins  \i Ctrl+C, F16, Ctrl+Ins       \i Ctrl+C
240     \row    \i Paste            \i Ctrl+V, Shift+Ins                    \i Ctrl+V                   \i Ctrl+V, F18, Shift+Ins \i Ctrl+V, F18, Shift+Ins      \i Ctrl+V
241     \row    \i Preferences      \i                                      \i Ctrl+,                   \i              \i                                       \i (none)
242     \row    \i Undo             \i Ctrl+Z, Alt+Backspace                \i Ctrl+Z                   \i Ctrl+Z, F14  \i Ctrl+Z, F14                           \i Ctrl+Z
243     \row    \i Redo             \i Ctrl+Y, Shift+Ctrl+Z, Alt+Shift+Backspace \i Ctrl+Shift+Z        \i Ctrl+Shift+Z \i Ctrl+Shift+Z                     \i (none)
244     \row    \i Back             \i Alt+Left, Backspace                  \i Ctrl+[                   \i Alt+Left     \i Alt+Left                              \i (none)
245     \row    \i Forward          \i Alt+Right, Shift+Backspace           \i Ctrl+]                   \i Alt+Right    \i Alt+Right                             \i (none)
246     \row    \i Refresh          \i F5                                   \i F5                       \i F5           \i Ctrl+R, F5                            \i (none)
247     \row    \i ZoomIn           \i Ctrl+Plus                            \i Ctrl+Plus                \i Ctrl+Plus    \i Ctrl+Plus                             \i (none)
248     \row    \i ZoomOut          \i Ctrl+Minus                           \i Ctrl+Minus               \i Ctrl+Minus   \i Ctrl+Minus                            \i (none)
249     \row    \i Print            \i Ctrl+P                               \i Ctrl+P                   \i Ctrl+P       \i Ctrl+P                                \i (none)
250     \row    \i AddTab           \i Ctrl+T                               \i Ctrl+T                   \i Ctrl+Shift+N, Ctrl+T \i Ctrl+T                        \i (none)
251     \row    \i NextChild        \i Ctrl+Tab, Forward, Ctrl+F6           \i Ctrl+}, Forward, Ctrl+Tab \i Ctrl+Tab, Forward, Ctrl+Comma \i Ctrl+Tab, Forward   \i (none)
252     \row    \i PreviousChild    \i Ctrl+Shift+Tab, Back, Ctrl+Shift+F6  \i Ctrl+{, Back, Ctrl+Shift+Tab \i Ctrl+Shift+Tab, Back, Ctrl+Period \i Ctrl+Shift+Tab, Back \i (none)
253     \row    \i Find             \i Ctrl+F                               \i Ctrl+F                   \i Ctrl+F         \i Ctrl+F                              \i (none)
254     \row    \i FindNext         \i F3, Ctrl+G                           \i Ctrl+G                   \i F3             \i Ctrl+G, F3                          \i (none)
255     \row    \i FindPrevious     \i Shift+F3, Ctrl+Shift+G               \i Ctrl+Shift+G             \i Shift+F3       \i Ctrl+Shift+G, Shift+F3              \i (none)
256     \row    \i Replace          \i Ctrl+H                               \i (none)                   \i Ctrl+R         \i Ctrl+H                              \i (none)
257     \row    \i SelectAll        \i Ctrl+A                               \i Ctrl+A                   \i Ctrl+A         \i Ctrl+A                              \i (none)
258     \row    \i Bold             \i Ctrl+B                               \i Ctrl+B                   \i Ctrl+B         \i Ctrl+B                              \i (none)
259     \row    \i Italic           \i Ctrl+I                               \i Ctrl+I                   \i Ctrl+I         \i Ctrl+I                              \i (none)
260     \row    \i Underline        \i Ctrl+U                               \i Ctrl+U                   \i Ctrl+U         \i Ctrl+U                              \i (none)
261     \row    \i MoveToNextChar       \i Right                            \i Right                    \i Right          \i Right                               \i Right
262     \row    \i MoveToPreviousChar   \i Left                             \i Left                     \i Left           \i Left                                \i Left
263     \row    \i MoveToNextWord       \i Ctrl+Right                       \i Alt+Right                \i Ctrl+Right     \i Ctrl+Right                          \i Ctrl+Right
264     \row    \i MoveToPreviousWord   \i Ctrl+Left                        \i Alt+Left                 \i Ctrl+Left      \i Ctrl+Left                           \i Ctrl+Left
265     \row    \i MoveToNextLine       \i Down                             \i Down                     \i Down           \i Down                                \i Down
266     \row    \i MoveToPreviousLine   \i Up                               \i Up                       \i Up             \i Up                                  \i Up
267     \row    \i MoveToNextPage       \i PgDown                           \i PgDown, Alt+PgDown, Meta+Down, Meta+PgDown\i PgDown \i PgDown                     \i PgDown
268     \row    \i MoveToPreviousPage   \i PgUp                             \i PgUp, Alt+PgUp, Meta+Up, Meta+PgUp        \i PgUp   \i PgUp                       \i PgUp
269     \row    \i MoveToStartOfLine    \i Home                             \i Ctrl+Left, Meta+Left   \i Home            \i Home                                 \i Home
270     \row    \i MoveToEndOfLine      \i End                              \i Ctrl+Right, Meta+Right \i End             \i End                                  \i End
271     \row    \i MoveToStartOfBlock   \i (none)                           \i Alt+Up, Meta+A         \i (none)          \i (none)                               \i (none)
272     \row    \i MoveToEndOfBlock     \i (none)                           \i Alt+Down, Meta+E       \i (none)          \i (none)                               \i (none)
273     \row    \i MoveToStartOfDocument\i Ctrl+Home                        \i Ctrl+Up, Home          \i Ctrl+Home       \i Ctrl+Home                            \i Ctrl+Home
274     \row    \i MoveToEndOfDocument  \i Ctrl+End                         \i Ctrl+Down, End         \i Ctrl+End        \i Ctrl+End                             \i Ctrl+End
275     \row    \i SelectNextChar       \i Shift+Right                      \i Shift+Right            \i Shift+Right     \i Shift+Right                          \i Shift+Right
276     \row    \i SelectPreviousChar   \i Shift+Left                       \i Shift+Left             \i Shift+Left      \i Shift+Left                           \i Shift+Left
277     \row    \i SelectNextWord       \i Ctrl+Shift+Right                 \i Alt+Shift+Right        \i Ctrl+Shift+Right \i Ctrl+Shift+Right                    \i Ctrl+Shift+Right
278     \row    \i SelectPreviousWord   \i Ctrl+Shift+Left                  \i Alt+Shift+Left         \i Ctrl+Shift+Left \i Ctrl+Shift+Left                      \i Ctrl+Shift+Left
279     \row    \i SelectNextLine       \i Shift+Down                       \i Shift+Down             \i Shift+Down     \i Shift+Down                            \i Shift+Down
280     \row    \i SelectPreviousLine   \i Shift+Up                         \i Shift+Up               \i Shift+Up       \i Shift+Up                              \i Shift+Up
281     \row    \i SelectNextPage       \i Shift+PgDown                     \i Shift+PgDown           \i Shift+PgDown   \i Shift+PgDown                          \i Shift+PgDown
282     \row    \i SelectPreviousPage   \i Shift+PgUp                       \i Shift+PgUp             \i Shift+PgUp     \i Shift+PgUp                            \i Shift+PgUp
283     \row    \i SelectStartOfLine    \i Shift+Home                       \i Ctrl+Shift+Left        \i Shift+Home     \i Shift+Home                            \i Shift+Home
284     \row    \i SelectEndOfLine      \i Shift+End                        \i Ctrl+Shift+Right       \i Shift+End      \i Shift+End                             \i Shift+End
285     \row    \i SelectStartOfBlock   \i (none)                           \i Alt+Shift+Up, Meta+Shift+A \i (none)     \i (none)                                \i (none)
286     \row    \i SelectEndOfBlock     \i (none)                           \i Alt+Shift+Down, Meta+Shift+E \i (none)   \i (none)                                \i (none)
287     \row    \i SelectStartOfDocument\i Ctrl+Shift+Home                  \i Ctrl+Shift+Up, Shift+Home          \i Ctrl+Shift+Home\i Ctrl+Shift+Home           \i Ctrl+Shift+Home
288     \row    \i SelectEndOfDocument  \i Ctrl+Shift+End                   \i Ctrl+Shift+Down, Shift+End        \i Ctrl+Shift+End \i Ctrl+Shift+End             \i Ctrl+Shift+End
289     \row    \i DeleteStartOfWord    \i Ctrl+Backspace                   \i Alt+Backspace          \i Ctrl+Backspace \i Ctrl+Backspace                        \i (none)
290     \row    \i DeleteEndOfWord      \i Ctrl+Del                         \i (none)                 \i Ctrl+Del       \i Ctrl+Del                              \i (none)
291     \row    \i DeleteEndOfLine      \i (none)                           \i (none)                 \i Ctrl+K         \i Ctrl+K                                \i (none)
292     \row    \i InsertParagraphSeparator     \i Enter                    \i Enter                  \i Enter          \i Enter                                 \i (none)
293     \row    \i InsertLineSeparator          \i Shift+Enter              \i Meta+Enter             \i Shift+Enter    \i Shift+Enter                           \i (none)
294     \endtable
295 
296     Note that, since the key sequences used for the standard shortcuts differ
297     between platforms, you still need to test your shortcuts on each platform
298     to ensure that you do not unintentionally assign the same key sequence to
299     many actions.
300 
301     \section1 Keyboard Layout Issues
302 
303     Many key sequence specifications are chosen by developers based on the
304     layout of certain types of keyboard, rather than choosing keys that
305     represent the first letter of an action's name, such as \key{Ctrl S}
306     ("Ctrl+S") or \key{Ctrl C} ("Ctrl+C").
307     Additionally, because certain symbols can only be entered with the
308     help of modifier keys on certain keyboard layouts, key sequences intended
309     for use with one keyboard layout may map to a different key, map to no
310     keys at all, or require an additional modifier key to be used on
311     different keyboard layouts.
312 
313     For example, the shortcuts, \key{Ctrl plus} and \key{Ctrl minus}, are often
314     used as shortcuts for zoom operations in graphics applications, and these
315     may be specified as "Ctrl++" and "Ctrl+-" respectively. However, the way
316     these shortcuts are specified and interpreted depends on the keyboard layout.
317     Users of Norwegian keyboards will note that the \key{+} and \key{-} keys
318     are not adjacent on the keyboard, but will still be able to activate both
319     shortcuts without needing to press the \key{Shift} key. However, users
320     with British keyboards will need to hold down the \key{Shift} key
321     to enter the \key{+} symbol, making the shortcut effectively the same as
322     "Ctrl+Shift+=".
323 
324     Although some developers might resort to fully specifying all the modifiers
325     they use on their keyboards to activate a shortcut, this will also result
326     in unexpected behavior for users of different keyboard layouts.
327 
328     For example, a developer using a British keyboard may decide to specify
329     "Ctrl+Shift+=" as the key sequence in order to create a shortcut that
330     coincidentally behaves in the same way as \key{Ctrl plus}. However, the
331     \key{=} key needs to be accessed using the \key{Shift} key on Norwegian
332     keyboard, making the required shortcut effectively \key{Ctrl Shift Shift =}
333     (an impossible key combination).
334 
335     As a result, both human-readable strings and hard-coded key codes
336     can both be problematic to use when specifying a key sequence that
337     can be used on a variety of different keyboard layouts. Only the
338     use of \l{QKeySequence::StandardKey} {standard shortcuts}
339     guarantees that the user will be able to use the shortcuts that
340     the developer intended.
341 
342     Despite this, we can address this issue by ensuring that human-readable
343     strings are used, making it possible for translations of key sequences to
344     be made for users of different languages. This approach will be successful
345     for users whose keyboards have the most typical layout for the language
346     they are using.
347 
348     \section1 GNU Emacs Style Key Sequences
349 
350     Key sequences similar to those used in \l{GNU Emacs}, allowing up to four
351     key codes, can be created by using the multiple argument constructor,
352     or by passing a human-readable string of comma-separated key sequences.
353 
354     For example, the key sequence, \key{Ctrl X} followed by \key{Ctrl C}, can
355     be specified using either of the following ways:
356 
357     \snippet doc/src/snippets/code/src_gui_kernel_qkeysequence.cpp 1
358 
359     \warning A QApplication instance must have been constructed before a
360              QKeySequence is created; otherwise, your application may crash.
361 
362     \sa QShortcut
363 */
364 
365 /*!
366     \enum QKeySequence::SequenceMatch
367 
368     \value NoMatch The key sequences are different; not even partially
369     matching.
370     \value PartialMatch The key sequences match partially, but are not
371     the same.
372     \value ExactMatch The key sequences are the same.
373     \omitvalue Identical
374 */
375 
376 /*!
377     \enum QKeySequence::SequenceFormat
378 
379     \value NativeText The key sequence as a platform specific string.
380     This means that it will be shown translated and on the Mac it will
381     resemble a key sequence from the menu bar. This enum is best used when you
382     want to display the string to the user.
383 
384     \value PortableText The key sequence is given in a "portable" format,
385     suitable for reading and writing to a file. In many cases, it will look
386     similar to the native text on Windows and X11.
387 */
388 
389 static const struct {
390     int key;
391     const char* name;
392 } keyname[] = {
393     //: This and all following "incomprehensible" strings in QShortcut context
394     //: are key names. Please use the localized names appearing on actual
395     //: keyboards or whatever is commonly used.
396     { Qt::Key_Space,        QT_TRANSLATE_NOOP("QShortcut", "Space") },
397     { Qt::Key_Escape,       QT_TRANSLATE_NOOP("QShortcut", "Esc") },
398     { Qt::Key_Tab,          QT_TRANSLATE_NOOP("QShortcut", "Tab") },
399     { Qt::Key_Backtab,      QT_TRANSLATE_NOOP("QShortcut", "Backtab") },
400     { Qt::Key_Backspace,    QT_TRANSLATE_NOOP("QShortcut", "Backspace") },
401     { Qt::Key_Return,       QT_TRANSLATE_NOOP("QShortcut", "Return") },
402     { Qt::Key_Enter,        QT_TRANSLATE_NOOP("QShortcut", "Enter") },
403     { Qt::Key_Insert,       QT_TRANSLATE_NOOP("QShortcut", "Ins") },
404     { Qt::Key_Delete,       QT_TRANSLATE_NOOP("QShortcut", "Del") },
405     { Qt::Key_Pause,        QT_TRANSLATE_NOOP("QShortcut", "Pause") },
406     { Qt::Key_Print,        QT_TRANSLATE_NOOP("QShortcut", "Print") },
407     { Qt::Key_SysReq,       QT_TRANSLATE_NOOP("QShortcut", "SysReq") },
408     { Qt::Key_Home,         QT_TRANSLATE_NOOP("QShortcut", "Home") },
409     { Qt::Key_End,          QT_TRANSLATE_NOOP("QShortcut", "End") },
410     { Qt::Key_Left,         QT_TRANSLATE_NOOP("QShortcut", "Left") },
411     { Qt::Key_Up,           QT_TRANSLATE_NOOP("QShortcut", "Up") },
412     { Qt::Key_Right,        QT_TRANSLATE_NOOP("QShortcut", "Right") },
413     { Qt::Key_Down,         QT_TRANSLATE_NOOP("QShortcut", "Down") },
414     { Qt::Key_PageUp,       QT_TRANSLATE_NOOP("QShortcut", "PgUp") },
415     { Qt::Key_PageDown,     QT_TRANSLATE_NOOP("QShortcut", "PgDown") },
416     { Qt::Key_CapsLock,     QT_TRANSLATE_NOOP("QShortcut", "CapsLock") },
417     { Qt::Key_NumLock,      QT_TRANSLATE_NOOP("QShortcut", "NumLock") },
418     { Qt::Key_ScrollLock,   QT_TRANSLATE_NOOP("QShortcut", "ScrollLock") },
419     { Qt::Key_Menu,         QT_TRANSLATE_NOOP("QShortcut", "Menu") },
420     { Qt::Key_Help,         QT_TRANSLATE_NOOP("QShortcut", "Help") },
421 
422     // Special keys
423     // Includes multimedia, launcher, lan keys ( bluetooth, wireless )
424     // window navigation
425     { Qt::Key_Back,                       QT_TRANSLATE_NOOP("QShortcut", "Back") },
426     { Qt::Key_Forward,                    QT_TRANSLATE_NOOP("QShortcut", "Forward") },
427     { Qt::Key_Stop,                       QT_TRANSLATE_NOOP("QShortcut", "Stop") },
428     { Qt::Key_Refresh,                    QT_TRANSLATE_NOOP("QShortcut", "Refresh") },
429     { Qt::Key_VolumeDown,                 QT_TRANSLATE_NOOP("QShortcut", "Volume Down") },
430     { Qt::Key_VolumeMute,                 QT_TRANSLATE_NOOP("QShortcut", "Volume Mute") },
431     { Qt::Key_VolumeUp,                   QT_TRANSLATE_NOOP("QShortcut", "Volume Up") },
432     { Qt::Key_BassBoost,                  QT_TRANSLATE_NOOP("QShortcut", "Bass Boost") },
433     { Qt::Key_BassUp,                     QT_TRANSLATE_NOOP("QShortcut", "Bass Up") },
434     { Qt::Key_BassDown,                   QT_TRANSLATE_NOOP("QShortcut", "Bass Down") },
435     { Qt::Key_TrebleUp,                   QT_TRANSLATE_NOOP("QShortcut", "Treble Up") },
436     { Qt::Key_TrebleDown,                 QT_TRANSLATE_NOOP("QShortcut", "Treble Down") },
437     { Qt::Key_MediaPlay,                  QT_TRANSLATE_NOOP("QShortcut", "Media Play") },
438     { Qt::Key_MediaStop,                  QT_TRANSLATE_NOOP("QShortcut", "Media Stop") },
439     { Qt::Key_MediaPrevious,              QT_TRANSLATE_NOOP("QShortcut", "Media Previous") },
440     { Qt::Key_MediaNext,                  QT_TRANSLATE_NOOP("QShortcut", "Media Next") },
441     { Qt::Key_MediaRecord,                QT_TRANSLATE_NOOP("QShortcut", "Media Record") },
442     //: Media player pause button
443     { Qt::Key_MediaPause,                 QT_TRANSLATE_NOOP("QShortcut", "Media Pause") },
444     //: Media player button to toggle between playing and paused
445     { Qt::Key_MediaTogglePlayPause,       QT_TRANSLATE_NOOP("QShortcut", "Toggle Media Play/Pause") },
446     { Qt::Key_HomePage,                   QT_TRANSLATE_NOOP("QShortcut", "Home Page") },
447     { Qt::Key_Favorites,                  QT_TRANSLATE_NOOP("QShortcut", "Favorites") },
448     { Qt::Key_Search,                     QT_TRANSLATE_NOOP("QShortcut", "Search") },
449     { Qt::Key_Standby,                    QT_TRANSLATE_NOOP("QShortcut", "Standby") },
450     { Qt::Key_OpenUrl,                    QT_TRANSLATE_NOOP("QShortcut", "Open URL") },
451     { Qt::Key_LaunchMail,                 QT_TRANSLATE_NOOP("QShortcut", "Launch Mail") },
452     { Qt::Key_LaunchMedia,                QT_TRANSLATE_NOOP("QShortcut", "Launch Media") },
453     { Qt::Key_Launch0,                    QT_TRANSLATE_NOOP("QShortcut", "Launch (0)") },
454     { Qt::Key_Launch1,                    QT_TRANSLATE_NOOP("QShortcut", "Launch (1)") },
455     { Qt::Key_Launch2,                    QT_TRANSLATE_NOOP("QShortcut", "Launch (2)") },
456     { Qt::Key_Launch3,                    QT_TRANSLATE_NOOP("QShortcut", "Launch (3)") },
457     { Qt::Key_Launch4,                    QT_TRANSLATE_NOOP("QShortcut", "Launch (4)") },
458     { Qt::Key_Launch5,                    QT_TRANSLATE_NOOP("QShortcut", "Launch (5)") },
459     { Qt::Key_Launch6,                    QT_TRANSLATE_NOOP("QShortcut", "Launch (6)") },
460     { Qt::Key_Launch7,                    QT_TRANSLATE_NOOP("QShortcut", "Launch (7)") },
461     { Qt::Key_Launch8,                    QT_TRANSLATE_NOOP("QShortcut", "Launch (8)") },
462     { Qt::Key_Launch9,                    QT_TRANSLATE_NOOP("QShortcut", "Launch (9)") },
463     { Qt::Key_LaunchA,                    QT_TRANSLATE_NOOP("QShortcut", "Launch (A)") },
464     { Qt::Key_LaunchB,                    QT_TRANSLATE_NOOP("QShortcut", "Launch (B)") },
465     { Qt::Key_LaunchC,                    QT_TRANSLATE_NOOP("QShortcut", "Launch (C)") },
466     { Qt::Key_LaunchD,                    QT_TRANSLATE_NOOP("QShortcut", "Launch (D)") },
467     { Qt::Key_LaunchE,                    QT_TRANSLATE_NOOP("QShortcut", "Launch (E)") },
468     { Qt::Key_LaunchF,                    QT_TRANSLATE_NOOP("QShortcut", "Launch (F)") },
469     { Qt::Key_MonBrightnessUp,            QT_TRANSLATE_NOOP("QShortcut", "Monitor Brightness Up") },
470     { Qt::Key_MonBrightnessDown,          QT_TRANSLATE_NOOP("QShortcut", "Monitor Brightness Down") },
471     { Qt::Key_KeyboardLightOnOff,         QT_TRANSLATE_NOOP("QShortcut", "Keyboard Light On/Off") },
472     { Qt::Key_KeyboardBrightnessUp,       QT_TRANSLATE_NOOP("QShortcut", "Keyboard Brightness Up") },
473     { Qt::Key_KeyboardBrightnessDown,     QT_TRANSLATE_NOOP("QShortcut", "Keyboard Brightness Down") },
474     { Qt::Key_PowerOff,                   QT_TRANSLATE_NOOP("QShortcut", "Power Off") },
475     { Qt::Key_WakeUp,                     QT_TRANSLATE_NOOP("QShortcut", "Wake Up") },
476     { Qt::Key_Eject,                      QT_TRANSLATE_NOOP("QShortcut", "Eject") },
477     { Qt::Key_ScreenSaver,                QT_TRANSLATE_NOOP("QShortcut", "Screensaver") },
478     { Qt::Key_WWW,                        QT_TRANSLATE_NOOP("QShortcut", "WWW") },
479     { Qt::Key_Sleep,                      QT_TRANSLATE_NOOP("QShortcut", "Sleep") },
480     { Qt::Key_LightBulb,                  QT_TRANSLATE_NOOP("QShortcut", "LightBulb") },
481     { Qt::Key_Shop,                       QT_TRANSLATE_NOOP("QShortcut", "Shop") },
482     { Qt::Key_History,                    QT_TRANSLATE_NOOP("QShortcut", "History") },
483     { Qt::Key_AddFavorite,                QT_TRANSLATE_NOOP("QShortcut", "Add Favorite") },
484     { Qt::Key_HotLinks,                   QT_TRANSLATE_NOOP("QShortcut", "Hot Links") },
485     { Qt::Key_BrightnessAdjust,           QT_TRANSLATE_NOOP("QShortcut", "Adjust Brightness") },
486     { Qt::Key_Finance,                    QT_TRANSLATE_NOOP("QShortcut", "Finance") },
487     { Qt::Key_Community,                  QT_TRANSLATE_NOOP("QShortcut", "Community") },
488     { Qt::Key_AudioRewind,                QT_TRANSLATE_NOOP("QShortcut", "Audio Rewind") },
489     { Qt::Key_BackForward,                QT_TRANSLATE_NOOP("QShortcut", "Back Forward") },
490     { Qt::Key_ApplicationLeft,            QT_TRANSLATE_NOOP("QShortcut", "Application Left") },
491     { Qt::Key_ApplicationRight,           QT_TRANSLATE_NOOP("QShortcut", "Application Right") },
492     { Qt::Key_Book,                       QT_TRANSLATE_NOOP("QShortcut", "Book") },
493     { Qt::Key_CD,                         QT_TRANSLATE_NOOP("QShortcut", "CD") },
494     { Qt::Key_Calculator,                 QT_TRANSLATE_NOOP("QShortcut", "Calculator") },
495     { Qt::Key_Clear,                      QT_TRANSLATE_NOOP("QShortcut", "Clear") },
496     { Qt::Key_ClearGrab,                  QT_TRANSLATE_NOOP("QShortcut", "Clear Grab") },
497     { Qt::Key_Close,                      QT_TRANSLATE_NOOP("QShortcut", "Close") },
498     { Qt::Key_Copy,                       QT_TRANSLATE_NOOP("QShortcut", "Copy") },
499     { Qt::Key_Cut,                        QT_TRANSLATE_NOOP("QShortcut", "Cut") },
500     { Qt::Key_Display,                    QT_TRANSLATE_NOOP("QShortcut", "Display") },
501     { Qt::Key_DOS,                        QT_TRANSLATE_NOOP("QShortcut", "DOS") },
502     { Qt::Key_Documents,                  QT_TRANSLATE_NOOP("QShortcut", "Documents") },
503     { Qt::Key_Excel,                      QT_TRANSLATE_NOOP("QShortcut", "Spreadsheet") },
504     { Qt::Key_Explorer,                   QT_TRANSLATE_NOOP("QShortcut", "Browser") },
505     { Qt::Key_Game,                       QT_TRANSLATE_NOOP("QShortcut", "Game") },
506     { Qt::Key_Go,                         QT_TRANSLATE_NOOP("QShortcut", "Go") },
507     { Qt::Key_iTouch,                     QT_TRANSLATE_NOOP("QShortcut", "iTouch") },
508     { Qt::Key_LogOff,                     QT_TRANSLATE_NOOP("QShortcut", "Logoff") },
509     { Qt::Key_Market,                     QT_TRANSLATE_NOOP("QShortcut", "Market") },
510     { Qt::Key_Meeting,                    QT_TRANSLATE_NOOP("QShortcut", "Meeting") },
511     { Qt::Key_MenuKB,                     QT_TRANSLATE_NOOP("QShortcut", "Keyboard Menu") },
512     { Qt::Key_MenuPB,                     QT_TRANSLATE_NOOP("QShortcut", "Menu PB") },
513     { Qt::Key_MySites,                    QT_TRANSLATE_NOOP("QShortcut", "My Sites") },
514     { Qt::Key_News,                       QT_TRANSLATE_NOOP("QShortcut", "News") },
515     { Qt::Key_OfficeHome,                 QT_TRANSLATE_NOOP("QShortcut", "Home Office") },
516     { Qt::Key_Option,                     QT_TRANSLATE_NOOP("QShortcut", "Option") },
517     { Qt::Key_Paste,                      QT_TRANSLATE_NOOP("QShortcut", "Paste") },
518     { Qt::Key_Phone,                      QT_TRANSLATE_NOOP("QShortcut", "Phone") },
519     { Qt::Key_Reply,                      QT_TRANSLATE_NOOP("QShortcut", "Reply") },
520     { Qt::Key_Reload,                     QT_TRANSLATE_NOOP("QShortcut", "Reload") },
521     { Qt::Key_RotateWindows,              QT_TRANSLATE_NOOP("QShortcut", "Rotate Windows") },
522     { Qt::Key_RotationPB,                 QT_TRANSLATE_NOOP("QShortcut", "Rotation PB") },
523     { Qt::Key_RotationKB,                 QT_TRANSLATE_NOOP("QShortcut", "Rotation KB") },
524     { Qt::Key_Save,                       QT_TRANSLATE_NOOP("QShortcut", "Save") },
525     { Qt::Key_Send,                       QT_TRANSLATE_NOOP("QShortcut", "Send") },
526     { Qt::Key_Spell,                      QT_TRANSLATE_NOOP("QShortcut", "Spellchecker") },
527     { Qt::Key_SplitScreen,                QT_TRANSLATE_NOOP("QShortcut", "Split Screen") },
528     { Qt::Key_Support,                    QT_TRANSLATE_NOOP("QShortcut", "Support") },
529     { Qt::Key_TaskPane,                   QT_TRANSLATE_NOOP("QShortcut", "Task Panel") },
530     { Qt::Key_Terminal,                   QT_TRANSLATE_NOOP("QShortcut", "Terminal") },
531     { Qt::Key_Tools,                      QT_TRANSLATE_NOOP("QShortcut", "Tools") },
532     { Qt::Key_Travel,                     QT_TRANSLATE_NOOP("QShortcut", "Travel") },
533     { Qt::Key_Video,                      QT_TRANSLATE_NOOP("QShortcut", "Video") },
534     { Qt::Key_Word,                       QT_TRANSLATE_NOOP("QShortcut", "Word Processor") },
535     { Qt::Key_Xfer,                       QT_TRANSLATE_NOOP("QShortcut", "XFer") },
536     { Qt::Key_ZoomIn,                     QT_TRANSLATE_NOOP("QShortcut", "Zoom In") },
537     { Qt::Key_ZoomOut,                    QT_TRANSLATE_NOOP("QShortcut", "Zoom Out") },
538     { Qt::Key_Away,                       QT_TRANSLATE_NOOP("QShortcut", "Away") },
539     { Qt::Key_Messenger,                  QT_TRANSLATE_NOOP("QShortcut", "Messenger") },
540     { Qt::Key_WebCam,                     QT_TRANSLATE_NOOP("QShortcut", "WebCam") },
541     { Qt::Key_MailForward,                QT_TRANSLATE_NOOP("QShortcut", "Mail Forward") },
542     { Qt::Key_Pictures,                   QT_TRANSLATE_NOOP("QShortcut", "Pictures") },
543     { Qt::Key_Music,                      QT_TRANSLATE_NOOP("QShortcut", "Music") },
544     { Qt::Key_Battery,                    QT_TRANSLATE_NOOP("QShortcut", "Battery") },
545     { Qt::Key_Bluetooth,                  QT_TRANSLATE_NOOP("QShortcut", "Bluetooth") },
546     { Qt::Key_WLAN,                       QT_TRANSLATE_NOOP("QShortcut", "Wireless") },
547     { Qt::Key_UWB,                        QT_TRANSLATE_NOOP("QShortcut", "Ultra Wide Band") },
548     { Qt::Key_AudioForward,               QT_TRANSLATE_NOOP("QShortcut", "Audio Forward") },
549     { Qt::Key_AudioRepeat,                QT_TRANSLATE_NOOP("QShortcut", "Audio Repeat") },
550     { Qt::Key_AudioRandomPlay,            QT_TRANSLATE_NOOP("QShortcut", "Audio Random Play") },
551     { Qt::Key_Subtitle,                   QT_TRANSLATE_NOOP("QShortcut", "Subtitle") },
552     { Qt::Key_AudioCycleTrack,            QT_TRANSLATE_NOOP("QShortcut", "Audio Cycle Track") },
553     { Qt::Key_Time,                       QT_TRANSLATE_NOOP("QShortcut", "Time") },
554     { Qt::Key_Select,                     QT_TRANSLATE_NOOP("QShortcut", "Select") },
555     { Qt::Key_View,                       QT_TRANSLATE_NOOP("QShortcut", "View") },
556     { Qt::Key_TopMenu,                    QT_TRANSLATE_NOOP("QShortcut", "Top Menu") },
557     { Qt::Key_Suspend,                    QT_TRANSLATE_NOOP("QShortcut", "Suspend") },
558     { Qt::Key_Hibernate,                  QT_TRANSLATE_NOOP("QShortcut", "Hibernate") },
559 
560     // --------------------------------------------------------------
561     // More consistent namings
562     { Qt::Key_Print,        QT_TRANSLATE_NOOP("QShortcut", "Print Screen") },
563     { Qt::Key_PageUp,       QT_TRANSLATE_NOOP("QShortcut", "Page Up") },
564     { Qt::Key_PageDown,     QT_TRANSLATE_NOOP("QShortcut", "Page Down") },
565     { Qt::Key_CapsLock,     QT_TRANSLATE_NOOP("QShortcut", "Caps Lock") },
566     { Qt::Key_NumLock,      QT_TRANSLATE_NOOP("QShortcut", "Num Lock") },
567     { Qt::Key_NumLock,      QT_TRANSLATE_NOOP("QShortcut", "Number Lock") },
568     { Qt::Key_ScrollLock,   QT_TRANSLATE_NOOP("QShortcut", "Scroll Lock") },
569     { Qt::Key_Insert,       QT_TRANSLATE_NOOP("QShortcut", "Insert") },
570     { Qt::Key_Delete,       QT_TRANSLATE_NOOP("QShortcut", "Delete") },
571     { Qt::Key_Escape,       QT_TRANSLATE_NOOP("QShortcut", "Escape") },
572     { Qt::Key_SysReq,       QT_TRANSLATE_NOOP("QShortcut", "System Request") },
573 
574     // --------------------------------------------------------------
575     // Keypad navigation keys
576     { Qt::Key_Select,       QT_TRANSLATE_NOOP("QShortcut", "Select") },
577     { Qt::Key_Yes,          QT_TRANSLATE_NOOP("QShortcut", "Yes") },
578     { Qt::Key_No,           QT_TRANSLATE_NOOP("QShortcut", "No") },
579 
580     // --------------------------------------------------------------
581     // Device keys
582     { Qt::Key_Context1,         QT_TRANSLATE_NOOP("QShortcut", "Context1") },
583     { Qt::Key_Context2,         QT_TRANSLATE_NOOP("QShortcut", "Context2") },
584     { Qt::Key_Context3,         QT_TRANSLATE_NOOP("QShortcut", "Context3") },
585     { Qt::Key_Context4,         QT_TRANSLATE_NOOP("QShortcut", "Context4") },
586     //: Button to start a call (note: a separate button is used to end the call)
587     { Qt::Key_Call,             QT_TRANSLATE_NOOP("QShortcut", "Call") },
588     //: Button to end a call (note: a separate button is used to start the call)
589     { Qt::Key_Hangup,           QT_TRANSLATE_NOOP("QShortcut", "Hangup") },
590     //: Button that will hang up if we're in call, or make a call if we're not.
591     { Qt::Key_ToggleCallHangup, QT_TRANSLATE_NOOP("QShortcut", "Toggle Call/Hangup") },
592     { Qt::Key_Flip,             QT_TRANSLATE_NOOP("QShortcut", "Flip") },
593     //: Button to trigger voice dialing
594     { Qt::Key_VoiceDial,        QT_TRANSLATE_NOOP("QShortcut", "Voice Dial") },
595     //: Button to redial the last number called
596     { Qt::Key_LastNumberRedial, QT_TRANSLATE_NOOP("QShortcut", "Last Number Redial") },
597     //: Button to trigger the camera shutter (take a picture)
598     { Qt::Key_Camera,           QT_TRANSLATE_NOOP("QShortcut", "Camera Shutter") },
599     //: Button to focus the camera
600     { Qt::Key_CameraFocus,      QT_TRANSLATE_NOOP("QShortcut", "Camera Focus") },
601 
602     // --------------------------------------------------------------
603     // Japanese keyboard support
604     { Qt::Key_Kanji,            QT_TRANSLATE_NOOP("QShortcut", "Kanji") },
605     { Qt::Key_Muhenkan,         QT_TRANSLATE_NOOP("QShortcut", "Muhenkan") },
606     { Qt::Key_Henkan,           QT_TRANSLATE_NOOP("QShortcut", "Henkan") },
607     { Qt::Key_Romaji,           QT_TRANSLATE_NOOP("QShortcut", "Romaji") },
608     { Qt::Key_Hiragana,         QT_TRANSLATE_NOOP("QShortcut", "Hiragana") },
609     { Qt::Key_Katakana,         QT_TRANSLATE_NOOP("QShortcut", "Katakana") },
610     { Qt::Key_Hiragana_Katakana,QT_TRANSLATE_NOOP("QShortcut", "Hiragana Katakana") },
611     { Qt::Key_Zenkaku,          QT_TRANSLATE_NOOP("QShortcut", "Zenkaku") },
612     { Qt::Key_Hankaku,          QT_TRANSLATE_NOOP("QShortcut", "Hankaku") },
613     { Qt::Key_Zenkaku_Hankaku,  QT_TRANSLATE_NOOP("QShortcut", "Zenkaku Hankaku") },
614     { Qt::Key_Touroku,          QT_TRANSLATE_NOOP("QShortcut", "Touroku") },
615     { Qt::Key_Massyo,           QT_TRANSLATE_NOOP("QShortcut", "Massyo") },
616     { Qt::Key_Kana_Lock,        QT_TRANSLATE_NOOP("QShortcut", "Kana Lock") },
617     { Qt::Key_Kana_Shift,       QT_TRANSLATE_NOOP("QShortcut", "Kana Shift") },
618     { Qt::Key_Eisu_Shift,       QT_TRANSLATE_NOOP("QShortcut", "Eisu Shift") },
619     { Qt::Key_Eisu_toggle,      QT_TRANSLATE_NOOP("QShortcut", "Eisu toggle") },
620     { Qt::Key_Codeinput,        QT_TRANSLATE_NOOP("QShortcut", "Code input") },
621     { Qt::Key_MultipleCandidate,QT_TRANSLATE_NOOP("QShortcut", "Multiple Candidate") },
622     { Qt::Key_PreviousCandidate,QT_TRANSLATE_NOOP("QShortcut", "Previous Candidate") },
623 
624     // --------------------------------------------------------------
625     // Korean keyboard support
626     { Qt::Key_Hangul,          QT_TRANSLATE_NOOP("QShortcut", "Hangul") },
627     { Qt::Key_Hangul_Start,    QT_TRANSLATE_NOOP("QShortcut", "Hangul Start") },
628     { Qt::Key_Hangul_End,      QT_TRANSLATE_NOOP("QShortcut", "Hangul End") },
629     { Qt::Key_Hangul_Hanja,    QT_TRANSLATE_NOOP("QShortcut", "Hangul Hanja") },
630     { Qt::Key_Hangul_Jamo,     QT_TRANSLATE_NOOP("QShortcut", "Hangul Jamo") },
631     { Qt::Key_Hangul_Romaja,   QT_TRANSLATE_NOOP("QShortcut", "Hangul Romaja") },
632     { Qt::Key_Hangul_Jeonja,   QT_TRANSLATE_NOOP("QShortcut", "Hangul Jeonja") },
633     { Qt::Key_Hangul_Banja,    QT_TRANSLATE_NOOP("QShortcut", "Hangul Banja") },
634     { Qt::Key_Hangul_PreHanja, QT_TRANSLATE_NOOP("QShortcut", "Hangul PreHanja") },
635     { Qt::Key_Hangul_PostHanja,QT_TRANSLATE_NOOP("QShortcut", "Hangul PostHanja") },
636     { Qt::Key_Hangul_Special,  QT_TRANSLATE_NOOP("QShortcut", "Hangul Special") },
637 
638     { 0, 0 }
639 };
640 
641 //Table of key bindings. It must be sorted on key sequence.
642 //A priority of 1 indicates that this is the primary key binding when multiple are defined.
643 
644 const QKeyBinding QKeySequencePrivate::keyBindings[] = {
645 //   StandardKey                            Priority    Key Sequence                            Platforms
646     {QKeySequence::Back,                    0,          Qt::Key_Backspace,                      QApplicationPrivate::KB_Win},
647     {QKeySequence::InsertParagraphSeparator,0,          Qt::Key_Return,                         QApplicationPrivate::KB_All},
648     {QKeySequence::InsertParagraphSeparator,0,          Qt::Key_Enter,                          QApplicationPrivate::KB_All},
649     {QKeySequence::Delete,                  1,          Qt::Key_Delete,                         QApplicationPrivate::KB_All},
650     {QKeySequence::MoveToStartOfLine,       0,          Qt::Key_Home,                           QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11 | QApplicationPrivate::KB_S60},
651     {QKeySequence::MoveToStartOfDocument,   0,          Qt::Key_Home,                           QApplicationPrivate::KB_Mac},
652     {QKeySequence::MoveToEndOfLine,         0,          Qt::Key_End,                            QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11 | QApplicationPrivate::KB_S60},
653     {QKeySequence::MoveToEndOfDocument,     0,          Qt::Key_End,                            QApplicationPrivate::KB_Mac},
654     {QKeySequence::MoveToPreviousChar,      0,          Qt::Key_Left,                           QApplicationPrivate::KB_All},
655     {QKeySequence::MoveToPreviousLine,      0,          Qt::Key_Up,                             QApplicationPrivate::KB_All},
656     {QKeySequence::MoveToNextChar,          0,          Qt::Key_Right,                          QApplicationPrivate::KB_All},
657     {QKeySequence::MoveToNextLine,          0,          Qt::Key_Down,                           QApplicationPrivate::KB_All},
658     {QKeySequence::MoveToPreviousPage,      1,          Qt::Key_PageUp,                         QApplicationPrivate::KB_All},
659     {QKeySequence::MoveToNextPage,          1,          Qt::Key_PageDown,                       QApplicationPrivate::KB_All},
660     {QKeySequence::HelpContents,            0,          Qt::Key_F1,                             QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11},
661     {QKeySequence::HelpContents,            0,          Qt::Key_F2,                             QApplicationPrivate::KB_S60},
662     {QKeySequence::FindNext,                0,          Qt::Key_F3,                             QApplicationPrivate::KB_X11},
663     {QKeySequence::FindNext,                1,          Qt::Key_F3,                             QApplicationPrivate::KB_Win},
664     {QKeySequence::Refresh,                 0,          Qt::Key_F5,                             QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11},
665     {QKeySequence::Undo,                    0,          Qt::Key_F14,                            QApplicationPrivate::KB_X11}, //Undo on sun keyboards
666     {QKeySequence::Copy,                    0,          Qt::Key_F16,                            QApplicationPrivate::KB_X11}, //Copy on sun keyboards
667     {QKeySequence::Paste,                   0,          Qt::Key_F18,                            QApplicationPrivate::KB_X11}, //Paste on sun keyboards
668     {QKeySequence::Cut,                     0,          Qt::Key_F20,                            QApplicationPrivate::KB_X11}, //Cut on sun keyboards
669     {QKeySequence::PreviousChild,           0,          Qt::Key_Back,                           QApplicationPrivate::KB_All},
670     {QKeySequence::NextChild,               0,          Qt::Key_Forward,                        QApplicationPrivate::KB_All},
671     {QKeySequence::Forward,                 0,          Qt::SHIFT | Qt::Key_Backspace,          QApplicationPrivate::KB_Win},
672     {QKeySequence::Delete,                  0,          Qt::SHIFT | Qt::Key_Backspace,          QApplicationPrivate::KB_S60},
673     {QKeySequence::InsertLineSeparator,     0,          Qt::SHIFT | Qt::Key_Return,             QApplicationPrivate::KB_All},
674     {QKeySequence::InsertLineSeparator,     0,          Qt::SHIFT | Qt::Key_Enter,              QApplicationPrivate::KB_All},
675     {QKeySequence::Paste,                   0,          Qt::SHIFT | Qt::Key_Insert,             QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11},
676     {QKeySequence::Cut,                     0,          Qt::SHIFT | Qt::Key_Delete,             QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11}, //## Check if this should work on mac
677     {QKeySequence::SelectStartOfLine,       0,          Qt::SHIFT | Qt::Key_Home,               QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11 | QApplicationPrivate::KB_S60},
678     {QKeySequence::SelectStartOfDocument,   0,          Qt::SHIFT | Qt::Key_Home,               QApplicationPrivate::KB_Mac},
679     {QKeySequence::SelectEndOfLine,         0,          Qt::SHIFT | Qt::Key_End,                QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11 | QApplicationPrivate::KB_S60},
680     {QKeySequence::SelectEndOfDocument,     0,          Qt::SHIFT | Qt::Key_End,                QApplicationPrivate::KB_Mac},
681     {QKeySequence::SelectPreviousChar,      0,          Qt::SHIFT | Qt::Key_Left,               QApplicationPrivate::KB_All},
682     {QKeySequence::SelectPreviousLine,      0,          Qt::SHIFT | Qt::Key_Up,                 QApplicationPrivate::KB_All},
683     {QKeySequence::SelectNextChar,          0,          Qt::SHIFT | Qt::Key_Right,              QApplicationPrivate::KB_All},
684     {QKeySequence::SelectNextLine,          0,          Qt::SHIFT | Qt::Key_Down,               QApplicationPrivate::KB_All},
685     {QKeySequence::SelectPreviousPage,      0,          Qt::SHIFT | Qt::Key_PageUp,             QApplicationPrivate::KB_All},
686     {QKeySequence::SelectNextPage,          0,          Qt::SHIFT | Qt::Key_PageDown,           QApplicationPrivate::KB_All},
687     {QKeySequence::WhatsThis,               1,          Qt::SHIFT | Qt::Key_F1,                 QApplicationPrivate::KB_All},
688     {QKeySequence::FindPrevious,            0,          Qt::SHIFT | Qt::Key_F3,                 QApplicationPrivate::KB_X11},
689     {QKeySequence::FindPrevious,            1,          Qt::SHIFT | Qt::Key_F3,                 QApplicationPrivate::KB_Win},
690     {QKeySequence::ZoomIn,                  1,          Qt::CTRL | Qt::Key_Plus,                QApplicationPrivate::KB_All},
691     {QKeySequence::NextChild,               0,          Qt::CTRL | Qt::Key_Comma,               QApplicationPrivate::KB_KDE},
692     {QKeySequence::Preferences,             0,          Qt::CTRL | Qt::Key_Comma,               QApplicationPrivate::KB_Mac},
693     {QKeySequence::ZoomOut,                 1,          Qt::CTRL | Qt::Key_Minus,               QApplicationPrivate::KB_All},
694     {QKeySequence::PreviousChild,           0,          Qt::CTRL | Qt::Key_Period,              QApplicationPrivate::KB_KDE},
695     {QKeySequence::HelpContents,            1,          Qt::CTRL | Qt::Key_Question,            QApplicationPrivate::KB_Mac},
696     {QKeySequence::SelectAll,               1,          Qt::CTRL | Qt::Key_A,                   QApplicationPrivate::KB_All},
697     {QKeySequence::Bold,                    1,          Qt::CTRL | Qt::Key_B,                   QApplicationPrivate::KB_All},
698     {QKeySequence::Copy,                    1,          Qt::CTRL | Qt::Key_C,                   QApplicationPrivate::KB_All},
699     {QKeySequence::Delete,                  0,          Qt::CTRL | Qt::Key_D,                   QApplicationPrivate::KB_X11}, //emacs (line edit only)
700     {QKeySequence::Find,                    0,          Qt::CTRL | Qt::Key_F,                   QApplicationPrivate::KB_All},
701     {QKeySequence::FindNext,                1,          Qt::CTRL | Qt::Key_G,                   QApplicationPrivate::KB_Gnome | QApplicationPrivate::KB_Mac},
702     {QKeySequence::FindNext,                0,          Qt::CTRL | Qt::Key_G,                   QApplicationPrivate::KB_Win},
703     {QKeySequence::Replace,                 0,          Qt::CTRL | Qt::Key_H,                   QApplicationPrivate::KB_Win},
704     {QKeySequence::Replace,                 0,          Qt::CTRL | Qt::Key_H,                   QApplicationPrivate::KB_Gnome},
705     {QKeySequence::Italic,                  0,          Qt::CTRL | Qt::Key_I,                   QApplicationPrivate::KB_All},
706     {QKeySequence::DeleteEndOfLine,         0,          Qt::CTRL | Qt::Key_K,                   QApplicationPrivate::KB_X11}, //emacs (line edit only)
707     {QKeySequence::New,                     1,          Qt::CTRL | Qt::Key_N,                   QApplicationPrivate::KB_All},
708     {QKeySequence::Open,                    1,          Qt::CTRL | Qt::Key_O,                   QApplicationPrivate::KB_All},
709     {QKeySequence::Print,                   1,          Qt::CTRL | Qt::Key_P,                   QApplicationPrivate::KB_All},
710     {QKeySequence::Quit,                    0,          Qt::CTRL | Qt::Key_Q,                   QApplicationPrivate::KB_Gnome | QApplicationPrivate::KB_KDE | QApplicationPrivate::KB_Mac},
711     {QKeySequence::Refresh,                 1,          Qt::CTRL | Qt::Key_R,                   QApplicationPrivate::KB_Gnome | QApplicationPrivate::KB_Mac},
712     {QKeySequence::Replace,                 0,          Qt::CTRL | Qt::Key_R,                   QApplicationPrivate::KB_KDE},
713     {QKeySequence::Save,                    1,          Qt::CTRL | Qt::Key_S,                   QApplicationPrivate::KB_All},
714     {QKeySequence::AddTab,                  0,          Qt::CTRL | Qt::Key_T,                   QApplicationPrivate::KB_All},
715     {QKeySequence::Underline,               1,          Qt::CTRL | Qt::Key_U,                   QApplicationPrivate::KB_All},
716     {QKeySequence::Paste,                   1,          Qt::CTRL | Qt::Key_V,                   QApplicationPrivate::KB_All},
717     {QKeySequence::Close,                   0,          Qt::CTRL | Qt::Key_W,                   QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11},
718     {QKeySequence::Close,                   1,          Qt::CTRL | Qt::Key_W,                   QApplicationPrivate::KB_Mac},
719     {QKeySequence::Cut,                     1,          Qt::CTRL | Qt::Key_X,                   QApplicationPrivate::KB_All},
720     {QKeySequence::Redo,                    1,          Qt::CTRL | Qt::Key_Y,                   QApplicationPrivate::KB_Win | QApplicationPrivate::KB_S60},
721     {QKeySequence::Undo,                    1,          Qt::CTRL | Qt::Key_Z,                   QApplicationPrivate::KB_All},
722     {QKeySequence::Back,                    1,          Qt::CTRL | Qt::Key_BracketLeft,         QApplicationPrivate::KB_Mac},
723     {QKeySequence::Forward,                 1,          Qt::CTRL | Qt::Key_BracketRight,        QApplicationPrivate::KB_Mac},
724     {QKeySequence::PreviousChild,           1,          Qt::CTRL | Qt::Key_BraceLeft,           QApplicationPrivate::KB_Mac},
725     {QKeySequence::NextChild,               1,          Qt::CTRL | Qt::Key_BraceRight,          QApplicationPrivate::KB_Mac},
726     {QKeySequence::NextChild,               1,          Qt::CTRL | Qt::Key_Tab,                 QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11},
727     {QKeySequence::NextChild,               0,          Qt::CTRL | Qt::Key_Tab,                 QApplicationPrivate::KB_Mac}, //different priority from above
728     {QKeySequence::DeleteStartOfWord,       0,          Qt::CTRL | Qt::Key_Backspace,           QApplicationPrivate::KB_X11 | QApplicationPrivate::KB_Win},
729     {QKeySequence::Copy,                    0,          Qt::CTRL | Qt::Key_Insert,              QApplicationPrivate::KB_X11 | QApplicationPrivate::KB_Win},
730     {QKeySequence::DeleteEndOfWord,         0,          Qt::CTRL | Qt::Key_Delete,              QApplicationPrivate::KB_X11 | QApplicationPrivate::KB_Win},
731     {QKeySequence::MoveToStartOfDocument,   0,          Qt::CTRL | Qt::Key_Home,                QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11 | QApplicationPrivate::KB_S60},
732     {QKeySequence::MoveToEndOfDocument,     0,          Qt::CTRL | Qt::Key_End,                 QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11 | QApplicationPrivate::KB_S60},
733     {QKeySequence::Back,                    0,          Qt::CTRL | Qt::Key_Left,                QApplicationPrivate::KB_Mac},
734     {QKeySequence::MoveToPreviousWord,      0,          Qt::CTRL | Qt::Key_Left,                QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11 | QApplicationPrivate::KB_S60},
735     {QKeySequence::MoveToStartOfLine,       0,          Qt::CTRL | Qt::Key_Left,                QApplicationPrivate::KB_Mac },
736     {QKeySequence::MoveToStartOfDocument,   1,          Qt::CTRL | Qt::Key_Up,                  QApplicationPrivate::KB_Mac},
737     {QKeySequence::Forward,                 0,          Qt::CTRL | Qt::Key_Right,               QApplicationPrivate::KB_Mac},
738     {QKeySequence::MoveToEndOfLine,         0,          Qt::CTRL | Qt::Key_Right,               QApplicationPrivate::KB_Mac },
739     {QKeySequence::MoveToNextWord,          0,          Qt::CTRL | Qt::Key_Right,               QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11 | QApplicationPrivate::KB_S60},
740     {QKeySequence::MoveToEndOfDocument,     1,          Qt::CTRL | Qt::Key_Down,                QApplicationPrivate::KB_Mac},
741     {QKeySequence::Close,                   1,          Qt::CTRL | Qt::Key_F4,                  QApplicationPrivate::KB_Win},
742     {QKeySequence::Close,                   0,          Qt::CTRL | Qt::Key_F4,                  QApplicationPrivate::KB_Mac},
743     {QKeySequence::NextChild,               0,          Qt::CTRL | Qt::Key_F6,                  QApplicationPrivate::KB_Win},
744     {QKeySequence::FindPrevious,            1,          Qt::CTRL | Qt::SHIFT | Qt::Key_G,       QApplicationPrivate::KB_Gnome | QApplicationPrivate::KB_Mac},
745     {QKeySequence::FindPrevious,            0,          Qt::CTRL | Qt::SHIFT | Qt::Key_G,       QApplicationPrivate::KB_Win},
746     {QKeySequence::AddTab,                  1,          Qt::CTRL | Qt::SHIFT | Qt::Key_N,       QApplicationPrivate::KB_KDE},
747     {QKeySequence::SaveAs,                  0,          Qt::CTRL | Qt::SHIFT | Qt::Key_S,       QApplicationPrivate::KB_Gnome | QApplicationPrivate::KB_Mac},
748     {QKeySequence::Redo,                    0,          Qt::CTRL | Qt::SHIFT | Qt::Key_Z,       QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11 | QApplicationPrivate::KB_S60},
749     {QKeySequence::Redo,                    0,          Qt::CTRL | Qt::SHIFT | Qt::Key_Z,       QApplicationPrivate::KB_Mac},
750     {QKeySequence::PreviousChild,           1,          Qt::CTRL | Qt::SHIFT | Qt::Key_Backtab, QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11},
751     {QKeySequence::PreviousChild,           0,          Qt::CTRL | Qt::SHIFT | Qt::Key_Backtab, QApplicationPrivate::KB_Mac },//different priority from above
752     {QKeySequence::Paste,                   0,          Qt::CTRL | Qt::SHIFT | Qt::Key_Insert,  QApplicationPrivate::KB_X11},
753     {QKeySequence::SelectStartOfDocument,   0,          Qt::CTRL | Qt::SHIFT | Qt::Key_Home,    QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11 | QApplicationPrivate::KB_S60},
754     {QKeySequence::SelectEndOfDocument,     0,          Qt::CTRL | Qt::SHIFT | Qt::Key_End,     QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11 | QApplicationPrivate::KB_S60},
755     {QKeySequence::SelectPreviousWord,      0,          Qt::CTRL | Qt::SHIFT | Qt::Key_Left,    QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11 | QApplicationPrivate::KB_S60},
756     {QKeySequence::SelectStartOfLine,       1,          Qt::CTRL | Qt::SHIFT | Qt::Key_Left,    QApplicationPrivate::KB_Mac },
757     {QKeySequence::SelectStartOfDocument,   1,          Qt::CTRL | Qt::SHIFT | Qt::Key_Up,      QApplicationPrivate::KB_Mac},
758     {QKeySequence::SelectNextWord,          0,          Qt::CTRL | Qt::SHIFT | Qt::Key_Right,   QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11 | QApplicationPrivate::KB_S60},
759     {QKeySequence::SelectEndOfLine,         1,          Qt::CTRL | Qt::SHIFT | Qt::Key_Right,   QApplicationPrivate::KB_Mac },
760     {QKeySequence::SelectEndOfDocument,     1,          Qt::CTRL | Qt::SHIFT | Qt::Key_Down,    QApplicationPrivate::KB_Mac},
761     {QKeySequence::PreviousChild,           0,          Qt::CTRL | Qt::SHIFT | Qt::Key_F6,      QApplicationPrivate::KB_Win},
762     {QKeySequence::Undo,                    0,          Qt::ALT  | Qt::Key_Backspace,           QApplicationPrivate::KB_Win},
763     {QKeySequence::DeleteStartOfWord,       0,          Qt::ALT  | Qt::Key_Backspace,           QApplicationPrivate::KB_Mac},
764     {QKeySequence::DeleteEndOfWord,         0,          Qt::ALT  | Qt::Key_Delete,              QApplicationPrivate::KB_Mac},
765     {QKeySequence::Back,                    1,          Qt::ALT  | Qt::Key_Left,                QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11},
766     {QKeySequence::MoveToPreviousWord,      0,          Qt::ALT  | Qt::Key_Left,                QApplicationPrivate::KB_Mac},
767     {QKeySequence::MoveToStartOfBlock,      0,          Qt::ALT  | Qt::Key_Up,                  QApplicationPrivate::KB_Mac}, //mac only
768     {QKeySequence::MoveToNextWord,          0,          Qt::ALT  | Qt::Key_Right,               QApplicationPrivate::KB_Mac},
769     {QKeySequence::Forward,                 1,          Qt::ALT  | Qt::Key_Right,               QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11},
770     {QKeySequence::MoveToEndOfBlock,        0,          Qt::ALT  | Qt::Key_Down,                QApplicationPrivate::KB_Mac}, //mac only
771     {QKeySequence::MoveToPreviousPage,      0,          Qt::ALT  | Qt::Key_PageUp,              QApplicationPrivate::KB_Mac },
772     {QKeySequence::MoveToNextPage,          0,          Qt::ALT  | Qt::Key_PageDown,            QApplicationPrivate::KB_Mac },
773     {QKeySequence::Redo,                    0,          Qt::ALT  | Qt::SHIFT | Qt::Key_Backspace,QApplicationPrivate::KB_Win},
774     {QKeySequence::SelectPreviousWord,      0,          Qt::ALT  | Qt::SHIFT | Qt::Key_Left,    QApplicationPrivate::KB_Mac},
775     {QKeySequence::SelectStartOfBlock,      0,          Qt::ALT  | Qt::SHIFT | Qt::Key_Up,      QApplicationPrivate::KB_Mac}, //mac only
776     {QKeySequence::SelectNextWord,          0,          Qt::ALT  | Qt::SHIFT | Qt::Key_Right,   QApplicationPrivate::KB_Mac},
777     {QKeySequence::SelectEndOfBlock,        0,          Qt::ALT  | Qt::SHIFT | Qt::Key_Down,    QApplicationPrivate::KB_Mac}, //mac only
778     {QKeySequence::MoveToStartOfBlock,      0,          Qt::META | Qt::Key_A,                   QApplicationPrivate::KB_Mac},
779     {QKeySequence::Delete,                  0,          Qt::META | Qt::Key_D,                   QApplicationPrivate::KB_Mac},
780     {QKeySequence::MoveToEndOfBlock,        0,          Qt::META | Qt::Key_E,                   QApplicationPrivate::KB_Mac},
781     {QKeySequence::InsertLineSeparator,     0,          Qt::META | Qt::Key_Return,              QApplicationPrivate::KB_Mac},
782     {QKeySequence::InsertLineSeparator,     0,          Qt::META | Qt::Key_Enter,               QApplicationPrivate::KB_Mac},
783     {QKeySequence::MoveToStartOfLine,       0,          Qt::META | Qt::Key_Left,                QApplicationPrivate::KB_Mac},
784     {QKeySequence::MoveToPreviousPage,      0,          Qt::META | Qt::Key_Up,                  QApplicationPrivate::KB_Mac},
785     {QKeySequence::MoveToEndOfLine,         0,          Qt::META | Qt::Key_Right,               QApplicationPrivate::KB_Mac},
786     {QKeySequence::MoveToNextPage,          0,          Qt::META | Qt::Key_Down,                QApplicationPrivate::KB_Mac},
787     {QKeySequence::MoveToPreviousPage,      0,          Qt::META | Qt::Key_PageUp,              QApplicationPrivate::KB_Mac},
788     {QKeySequence::MoveToNextPage,          0,          Qt::META | Qt::Key_PageDown,            QApplicationPrivate::KB_Mac},
789     {QKeySequence::SelectStartOfBlock,      0,          Qt::META | Qt::SHIFT | Qt::Key_A,       QApplicationPrivate::KB_Mac},
790     {QKeySequence::SelectEndOfBlock,        0,          Qt::META | Qt::SHIFT | Qt::Key_E,       QApplicationPrivate::KB_Mac},
791     {QKeySequence::SelectStartOfLine,       0,          Qt::META | Qt::SHIFT | Qt::Key_Left,    QApplicationPrivate::KB_Mac},
792     {QKeySequence::SelectEndOfLine,         0,          Qt::META | Qt::SHIFT | Qt::Key_Right,   QApplicationPrivate::KB_Mac}
793 };
794 
795 const uint QKeySequencePrivate::numberOfKeyBindings = sizeof(QKeySequencePrivate::keyBindings)/(sizeof(QKeyBinding));
796 
797 
798 /*!
799     \enum QKeySequence::StandardKey
800     \since 4.2
801 
802     This enum represent standard key bindings. They can be used to
803     assign platform dependent keyboard shortcuts to a QAction.
804 
805     Note that the key bindings are platform dependent. The currently
806     bound shortcuts can be queried using keyBindings().
807 
808     \value AddTab           Add new tab.
809     \value Back             Navigate back.
810     \value Bold             Bold text.
811     \value Close            Close document/tab.
812     \value Copy             Copy.
813     \value Cut              Cut.
814     \value Delete           Delete.
815     \value DeleteEndOfLine          Delete end of line.
816     \value DeleteEndOfWord          Delete word from the end of the cursor.
817     \value DeleteStartOfWord        Delete the beginning of a word up to the cursor.
818     \value Find             Find in document.
819     \value FindNext         Find next result.
820     \value FindPrevious     Find previous result.
821     \value Forward          Navigate forward.
822     \value HelpContents     Open help contents.
823     \value InsertLineSeparator      Insert a new line.
824     \value InsertParagraphSeparator Insert a new paragraph.
825     \value Italic           Italic text.
826     \value MoveToEndOfBlock         Move cursor to end of block. This shortcut is only used on the OS X.
827     \value MoveToEndOfDocument      Move cursor to end of document.
828     \value MoveToEndOfLine          Move cursor to end of line.
829     \value MoveToNextChar           Move cursor to next character.
830     \value MoveToNextLine           Move cursor to next line.
831     \value MoveToNextPage           Move cursor to next page.
832     \value MoveToNextWord           Move cursor to next word.
833     \value MoveToPreviousChar       Move cursor to previous character.
834     \value MoveToPreviousLine       Move cursor to previous line.
835     \value MoveToPreviousPage       Move cursor to previous page.
836     \value MoveToPreviousWord       Move cursor to previous word.
837     \value MoveToStartOfBlock       Move cursor to start of a block. This shortcut is only used on OS X.
838     \value MoveToStartOfDocument    Move cursor to start of document.
839     \value MoveToStartOfLine        Move cursor to start of line.
840     \value New              Create new document.
841     \value NextChild        Navigate to next tab or child window.
842     \value Open             Open document.
843     \value Paste            Paste.
844     \value Preferences      Open the preferences dialog.
845     \value PreviousChild    Navigate to previous tab or child window.
846     \value Print            Print document.
847     \value Quit             Quit the application.
848     \value Redo             Redo.
849     \value Refresh          Refresh or reload current document.
850     \value Replace          Find and replace.
851     \value SaveAs           Save document after prompting the user for a file name.
852     \value Save             Save document.
853     \value SelectAll        Select all text.
854     \value SelectEndOfBlock         Extend selection to the end of a text block. This shortcut is only used on OS X.
855     \value SelectEndOfDocument      Extend selection to end of document.
856     \value SelectEndOfLine          Extend selection to end of line.
857     \value SelectNextChar           Extend selection to next character.
858     \value SelectNextLine           Extend selection to next line.
859     \value SelectNextPage           Extend selection to next page.
860     \value SelectNextWord           Extend selection to next word.
861     \value SelectPreviousChar       Extend selection to previous character.
862     \value SelectPreviousLine       Extend selection to previous line.
863     \value SelectPreviousPage       Extend selection to previous page.
864     \value SelectPreviousWord       Extend selection to previous word.
865     \value SelectStartOfBlock       Extend selection to the start of a text block. This shortcut is only used on OS X.
866     \value SelectStartOfDocument    Extend selection to start of document.
867     \value SelectStartOfLine        Extend selection to start of line.
868     \value Underline        Underline text.
869     \value Undo             Undo.
870     \value UnknownKey       Unbound key.
871     \value WhatsThis        Activate whats this.
872     \value ZoomIn           Zoom in.
873     \value ZoomOut          Zoom out.
874 */
875 
876 /*!
877     \since 4.2
878 
879     Constructs a QKeySequence object for the given \a key.
880     The result will depend on the currently running platform.
881 
882     The resulting object will be based on the first element in the
883     list of key bindings for the \a key.
884 */
QKeySequence(StandardKey key)885 QKeySequence::QKeySequence(StandardKey key)
886 {
887     const QList <QKeySequence> bindings = keyBindings(key);
888     //pick only the first/primary shortcut from current bindings
889     if (bindings.size() > 0) {
890         d = bindings.first().d;
891         d->ref.ref();
892     }
893     else
894         d = new QKeySequencePrivate();
895 }
896 
897 
898 /*!
899     Constructs an empty key sequence.
900 */
QKeySequence()901 QKeySequence::QKeySequence()
902 {
903     static QKeySequencePrivate shared_empty;
904     d = &shared_empty;
905     d->ref.ref();
906 }
907 
908 /*!
909     Creates a key sequence from the \a key string. For example
910     "Ctrl+O" gives CTRL+'O'. The strings "Ctrl",
911     "Shift", "Alt" and "Meta" are recognized, as well as their
912     translated equivalents in the "QShortcut" context (using
913     QObject::tr()).
914 
915     Up to four key codes may be entered by separating them with
916     commas, e.g. "Alt+X,Ctrl+S,Q".
917 
918     \a key should be in NativeText format.
919 
920     This constructor is typically used with \link QObject::tr() tr
921     \endlink(), so that shortcut keys can be replaced in
922     translations:
923 
924     \snippet doc/src/snippets/code/src_gui_kernel_qkeysequence.cpp 2
925 
926     Note the "File|Open" translator comment. It is by no means
927     necessary, but it provides some context for the human translator.
928 */
QKeySequence(const QString & key)929 QKeySequence::QKeySequence(const QString &key)
930 {
931     d = new QKeySequencePrivate();
932     assign(key);
933 }
934 
935 /*!
936     \since 4.7
937     Creates a key sequence from the \a key string based on \a format.
938 */
QKeySequence(const QString & key,QKeySequence::SequenceFormat format)939 QKeySequence::QKeySequence(const QString &key, QKeySequence::SequenceFormat format)
940 {
941     d = new QKeySequencePrivate();
942     assign(key, format);
943 }
944 
945 /*!
946     Constructs a key sequence with up to 4 keys \a k1, \a k2,
947     \a k3 and \a k4.
948 
949     The key codes are listed in Qt::Key and can be combined with
950     modifiers (see Qt::Modifier) such as Qt::SHIFT, Qt::CTRL,
951     Qt::ALT, or Qt::META.
952 */
QKeySequence(int k1,int k2,int k3,int k4)953 QKeySequence::QKeySequence(int k1, int k2, int k3, int k4)
954 {
955     d = new QKeySequencePrivate();
956     d->key[0] = k1;
957     d->key[1] = k2;
958     d->key[2] = k3;
959     d->key[3] = k4;
960 }
961 
962 /*!
963     Copy constructor. Makes a copy of \a keysequence.
964  */
QKeySequence(const QKeySequence & keysequence)965 QKeySequence::QKeySequence(const QKeySequence& keysequence)
966     : d(keysequence.d)
967 {
968     d->ref.ref();
969 }
970 
971 #ifdef Q_WS_MAC
maybeSwapShortcut(int shortcut)972 static inline int maybeSwapShortcut(int shortcut)
973 {
974     if (qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)) {
975         uint oldshortcut = shortcut;
976         shortcut &= ~(Qt::CTRL | Qt::META);
977         if (oldshortcut & Qt::CTRL)
978             shortcut |= Qt::META;
979         if (oldshortcut & Qt::META)
980             shortcut |= Qt::CTRL;
981     }
982     return shortcut;
983 }
984 #endif
985 
986 /*!
987     \since 4.2
988 
989     Returns a list of key bindings for the given \a key.
990     The result of calling this function will vary based on the target platform.
991     The first element of the list indicates the primary shortcut for the given platform.
992     If the result contains more than one result, these can
993     be considered alternative shortcuts on the same platform for the given \a key.
994 */
keyBindings(StandardKey key)995 QList<QKeySequence> QKeySequence::keyBindings(StandardKey key)
996 {
997     uint platform = QApplicationPrivate::currentPlatform();
998     QList <QKeySequence> list;
999     for (uint i = 0; i < QKeySequencePrivate::numberOfKeyBindings ; ++i) {
1000         QKeyBinding keyBinding = QKeySequencePrivate::keyBindings[i];
1001         if (keyBinding.standardKey == key && (keyBinding.platform & platform)) {
1002             uint shortcut =
1003 #ifdef Q_WS_MAC
1004                     maybeSwapShortcut(QKeySequencePrivate::keyBindings[i].shortcut);
1005 #else
1006                     QKeySequencePrivate::keyBindings[i].shortcut;
1007 #endif
1008             if (keyBinding.priority > 0)
1009                 list.prepend(QKeySequence(shortcut));
1010             else
1011                 list.append(QKeySequence(shortcut));
1012         }
1013     }
1014     return list;
1015 }
1016 
1017 /*!
1018     Destroys the key sequence.
1019  */
~QKeySequence()1020 QKeySequence::~QKeySequence()
1021 {
1022     if (!d->ref.deref())
1023         delete d;
1024 }
1025 
1026 /*!
1027     \internal
1028     KeySequences should never be modified, but rather just created.
1029     Internally though we do need to modify to keep pace in event
1030     delivery.
1031 */
1032 
setKey(int key,int index)1033 void QKeySequence::setKey(int key, int index)
1034 {
1035     Q_ASSERT_X(index >= 0 && index < 4, "QKeySequence::setKey", "index out of range");
1036     qAtomicDetach(d);
1037     d->key[index] = key;
1038 }
1039 
1040 /*!
1041     Returns the number of keys in the key sequence.
1042     The maximum is 4.
1043  */
count() const1044 uint QKeySequence::count() const
1045 {
1046     if (!d->key[0])
1047         return 0;
1048     if (!d->key[1])
1049         return 1;
1050     if (!d->key[2])
1051         return 2;
1052     if (!d->key[3])
1053         return 3;
1054     return 4;
1055 }
1056 
1057 
1058 /*!
1059     Returns true if the key sequence is empty; otherwise returns
1060     false.
1061 */
isEmpty() const1062 bool QKeySequence::isEmpty() const
1063 {
1064     return !d->key[0];
1065 }
1066 
1067 
1068 /*!
1069     Returns the shortcut key sequence for the mnemonic in \a text,
1070     or an empty key sequence if no mnemonics are found.
1071 
1072     For example, mnemonic("E&xit") returns \c{Qt::ALT+Qt::Key_X},
1073     mnemonic("&Quit") returns \c{ALT+Key_Q}, and mnemonic("Quit")
1074     returns an empty QKeySequence.
1075 
1076     We provide a \l{accelerators.html}{list of common mnemonics}
1077     in English. At the time of writing, Microsoft and Open Group do
1078     not appear to have issued equivalent recommendations for other
1079     languages.
1080 
1081     \sa qt_set_sequence_auto_mnemonic()
1082 */
mnemonic(const QString & text)1083 QKeySequence QKeySequence::mnemonic(const QString &text)
1084 {
1085     QKeySequence ret;
1086 
1087     if(qt_sequence_no_mnemonics)
1088         return ret;
1089 
1090     bool found = false;
1091     int p = 0;
1092     while (p >= 0) {
1093         p = text.indexOf(QLatin1Char('&'), p) + 1;
1094         if (p <= 0 || p >= (int)text.length())
1095             break;
1096         if (text.at(p) != QLatin1Char('&')) {
1097             QChar c = text.at(p);
1098             if (c.isPrint()) {
1099                 if (!found) {
1100                     c = c.toUpper();
1101                     ret = QKeySequence(c.unicode() + Qt::ALT);
1102 #ifdef QT_NO_DEBUG
1103                     return ret;
1104 #else
1105                     found = true;
1106                 } else {
1107                     qWarning("QKeySequence::mnemonic: \"%s\" contains multiple occurrences of '&'", qPrintable(text));
1108 #endif
1109                 }
1110             }
1111         }
1112         p++;
1113     }
1114     return ret;
1115 }
1116 
1117 /*!
1118     \fn int QKeySequence::assign(const QString &keys)
1119 
1120     Adds the given \a keys to the key sequence. \a keys may
1121     contain up to four key codes, provided they are separated by a
1122     comma; for example, "Alt+X,Ctrl+S,Z". The return value is the
1123     number of key codes added.
1124     \a keys should be in NativeText format.
1125 */
assign(const QString & ks)1126 int QKeySequence::assign(const QString &ks)
1127 {
1128     return assign(ks, NativeText);
1129 }
1130 
1131 /*!
1132     \fn int QKeySequence::assign(const QString &keys, QKeySequence::SequenceFormat format)
1133     \since 4.7
1134 
1135     Adds the given \a keys to the key sequence (based on \a format).
1136     \a keys may contain up to four key codes, provided they are
1137     separated by a comma; for example, "Alt+X,Ctrl+S,Z". The return
1138     value is the number of key codes added.
1139 */
assign(const QString & ks,QKeySequence::SequenceFormat format)1140 int QKeySequence::assign(const QString &ks, QKeySequence::SequenceFormat format)
1141 {
1142     QString keyseq = ks;
1143     QString part;
1144     int n = 0;
1145     int p = 0, diff = 0;
1146 
1147     // Run through the whole string, but stop
1148     // if we have 4 keys before the end.
1149     while (keyseq.length() && n < 4) {
1150         // We MUST use something to separate each sequence, and space
1151         // does not cut it, since some of the key names have space
1152         // in them.. (Let's hope no one translate with a comma in it:)
1153         p = keyseq.indexOf(QLatin1Char(','));
1154         if (-1 != p) {
1155             if (p == keyseq.count() - 1) { // Last comma 'Ctrl+,'
1156                 p = -1;
1157             } else {
1158                 if (QLatin1Char(',') == keyseq.at(p+1)) // e.g. 'Ctrl+,, Shift+,,'
1159                     p++;
1160                 if (QLatin1Char(' ') == keyseq.at(p+1)) { // Space after comma
1161                     diff = 1;
1162                     p++;
1163                 } else {
1164                     diff = 0;
1165                 }
1166             }
1167         }
1168         part = keyseq.left(-1 == p ? keyseq.length() : p - diff);
1169         keyseq = keyseq.right(-1 == p ? 0 : keyseq.length() - (p + 1));
1170         d->key[n] = QKeySequencePrivate::decodeString(part, format);
1171         ++n;
1172     }
1173     return n;
1174 }
1175 
1176 struct QModifKeyName {
QModifKeyNameQModifKeyName1177     QModifKeyName() { }
QModifKeyNameQModifKeyName1178     QModifKeyName(int q, QChar n) : qt_key(q), name(n) { }
QModifKeyNameQModifKeyName1179     QModifKeyName(int q, const QString &n) : qt_key(q), name(n) { }
1180     int qt_key;
1181     QString name;
1182 };
1183 
Q_GLOBAL_STATIC(QList<QModifKeyName>,globalModifs)1184 Q_GLOBAL_STATIC(QList<QModifKeyName>, globalModifs)
1185 Q_GLOBAL_STATIC(QList<QModifKeyName>, globalPortableModifs)
1186 
1187 /*!
1188   Constructs a single key from the string \a str.
1189 */
1190 int QKeySequence::decodeString(const QString &str)
1191 {
1192     return QKeySequencePrivate::decodeString(str, NativeText);
1193 }
1194 
decodeString(const QString & str,QKeySequence::SequenceFormat format)1195 int QKeySequencePrivate::decodeString(const QString &str, QKeySequence::SequenceFormat format)
1196 {
1197     int ret = 0;
1198     QString accel = str.toLower();
1199     bool nativeText = (format == QKeySequence::NativeText);
1200 
1201     QList<QModifKeyName> *gmodifs;
1202     if (nativeText) {
1203         gmodifs = globalModifs();
1204         if (gmodifs->isEmpty()) {
1205 #ifdef Q_WS_MAC
1206             const bool dontSwap = qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta);
1207             if (dontSwap)
1208                 *gmodifs << QModifKeyName(Qt::META, QChar(kCommandUnicode));
1209             else
1210                 *gmodifs << QModifKeyName(Qt::CTRL, QChar(kCommandUnicode));
1211             *gmodifs << QModifKeyName(Qt::ALT, QChar(kOptionUnicode));
1212             if (dontSwap)
1213                 *gmodifs << QModifKeyName(Qt::CTRL, QChar(kControlUnicode));
1214             else
1215                 *gmodifs << QModifKeyName(Qt::META, QChar(kControlUnicode));
1216             *gmodifs << QModifKeyName(Qt::SHIFT, QChar(kShiftUnicode));
1217 #endif
1218             *gmodifs << QModifKeyName(Qt::CTRL, QLatin1String("ctrl+"))
1219                      << QModifKeyName(Qt::SHIFT, QLatin1String("shift+"))
1220                      << QModifKeyName(Qt::ALT, QLatin1String("alt+"))
1221                      << QModifKeyName(Qt::META, QLatin1String("meta+"));
1222         }
1223     } else {
1224         gmodifs = globalPortableModifs();
1225         if (gmodifs->isEmpty()) {
1226             *gmodifs << QModifKeyName(Qt::CTRL, QLatin1String("ctrl+"))
1227                      << QModifKeyName(Qt::SHIFT, QLatin1String("shift+"))
1228                      << QModifKeyName(Qt::ALT, QLatin1String("alt+"))
1229                      << QModifKeyName(Qt::META, QLatin1String("meta+"));
1230         }
1231     }
1232     if (!gmodifs) return ret;
1233 
1234 
1235     QList<QModifKeyName> modifs;
1236     if (nativeText) {
1237         modifs << QModifKeyName(Qt::CTRL, QShortcut::tr("Ctrl").toLower().append(QLatin1Char('+')))
1238                << QModifKeyName(Qt::SHIFT, QShortcut::tr("Shift").toLower().append(QLatin1Char('+')))
1239                << QModifKeyName(Qt::ALT, QShortcut::tr("Alt").toLower().append(QLatin1Char('+')))
1240                << QModifKeyName(Qt::META, QShortcut::tr("Meta").toLower().append(QLatin1Char('+')));
1241     }
1242     modifs += *gmodifs; // Test non-translated ones last
1243 
1244     QString sl = accel;
1245 #ifdef Q_WS_MAC
1246     for (int i = 0; i < modifs.size(); ++i) {
1247         const QModifKeyName &mkf = modifs.at(i);
1248         if (sl.contains(mkf.name)) {
1249             ret |= mkf.qt_key;
1250             accel.remove(mkf.name);
1251             sl = accel;
1252         }
1253     }
1254 #else
1255     int i = 0;
1256     int lastI = 0;
1257     while ((i = sl.indexOf(QLatin1Char('+'), i + 1)) != -1) {
1258         const QString sub = sl.mid(lastI, i - lastI + 1);
1259         // Just shortcut the check here if we only have one character.
1260         // Rational: A modifier will contain the name AND +, so longer than 1, a length of 1 is just
1261         // the remaining part of the shortcut (ei. The 'C' in "Ctrl+C"), so no need to check that.
1262         if (sub.length() > 1) {
1263             for (int j = 0; j < modifs.size(); ++j) {
1264                 const QModifKeyName &mkf = modifs.at(j);
1265                 if (sub == mkf.name) {
1266                     ret |= mkf.qt_key;
1267                     break; // Shortcut, since if we find an other it would/should just be a dup
1268                 }
1269             }
1270         }
1271         lastI = i + 1;
1272     }
1273 #endif
1274 
1275     int p = accel.lastIndexOf(QLatin1Char('+'), str.length() - 2); // -2 so that Ctrl++ works
1276     if(p > 0)
1277         accel = accel.mid(p + 1);
1278 
1279     int fnum = 0;
1280     if (accel.length() == 1) {
1281 #ifdef Q_WS_MAC
1282         int qtKey = qtkeyForMacSymbol(accel[0]);
1283         if (qtKey != -1) {
1284             ret |= qtKey;
1285         } else
1286 #endif
1287         {
1288             ret |= accel[0].toUpper().unicode();
1289         }
1290     } else if (accel[0] == QLatin1Char('f') && (fnum = accel.mid(1).toInt()) && (fnum >= 1) && (fnum <= 35)) {
1291         ret |= Qt::Key_F1 + fnum - 1;
1292     } else {
1293         // For NativeText, check the traslation table first,
1294         // if we don't find anything then try it out with just the untranlated stuff.
1295         // PortableText will only try the untranlated table.
1296         bool found = false;
1297         for (int tran = 0; tran < 2; ++tran) {
1298             if (!nativeText)
1299                 ++tran;
1300             for (int i = 0; keyname[i].name; ++i) {
1301                 QString keyName(tran == 0
1302                                 ? QShortcut::tr(keyname[i].name)
1303                                 : QString::fromLatin1(keyname[i].name));
1304                 if (accel == keyName.toLower()) {
1305                     ret |= keyname[i].key;
1306                     found = true;
1307                     break;
1308                 }
1309             }
1310             if (found)
1311                 break;
1312         }
1313     }
1314     return ret;
1315 }
1316 
1317 /*!
1318     Creates a shortcut string for \a key. For example,
1319     Qt::CTRL+Qt::Key_O gives "Ctrl+O". The strings, "Ctrl", "Shift", etc. are
1320     translated (using QObject::tr()) in the "QShortcut" context.
1321  */
encodeString(int key)1322 QString QKeySequence::encodeString(int key)
1323 {
1324     return QKeySequencePrivate::encodeString(key, NativeText);
1325 }
1326 
addKey(QString & str,const QString & theKey,QKeySequence::SequenceFormat format)1327 static inline void addKey(QString &str, const QString &theKey, QKeySequence::SequenceFormat format)
1328 {
1329     if (!str.isEmpty())
1330         str += (format == QKeySequence::NativeText) ? QShortcut::tr("+")
1331                                                     : QString::fromLatin1("+");
1332     str += theKey;
1333 }
1334 
encodeString(int key,QKeySequence::SequenceFormat format)1335 QString QKeySequencePrivate::encodeString(int key, QKeySequence::SequenceFormat format)
1336 {
1337     bool nativeText = (format == QKeySequence::NativeText);
1338     QString s;
1339 #if defined(Q_WS_MAC)
1340     if (nativeText) {
1341         // On Mac OS X the order (by default) is Meta, Alt, Shift, Control.
1342         // If the AA_MacDontSwapCtrlAndMeta is enabled, then the order
1343         // is Ctrl, Alt, Shift, Meta. The macSymbolForQtKey does this swap
1344         // for us, which means that we have to adjust our order here.
1345         // The upshot is a lot more infrastructure to keep the number of
1346         // if tests down and the code relatively clean.
1347         static const int ModifierOrder[] = { Qt::META, Qt::ALT, Qt::SHIFT, Qt::CTRL, 0 };
1348         static const int QtKeyOrder[] = { Qt::Key_Meta, Qt::Key_Alt, Qt::Key_Shift, Qt::Key_Control, 0 };
1349         static const int DontSwapModifierOrder[] = { Qt::CTRL, Qt::ALT, Qt::SHIFT, Qt::META, 0 };
1350         static const int DontSwapQtKeyOrder[] = { Qt::Key_Control, Qt::Key_Alt, Qt::Key_Shift, Qt::Key_Meta, 0 };
1351         const int *modifierOrder;
1352         const int *qtkeyOrder;
1353         if (qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)) {
1354             modifierOrder = DontSwapModifierOrder;
1355             qtkeyOrder = DontSwapQtKeyOrder;
1356         } else {
1357             modifierOrder = ModifierOrder;
1358             qtkeyOrder = QtKeyOrder;
1359         }
1360 
1361         for (int i = 0; modifierOrder[i] != 0; ++i) {
1362             if (key & modifierOrder[i])
1363                 s += qt_macSymbolForQtKey(qtkeyOrder[i]);
1364         }
1365     } else
1366 #endif
1367     {
1368         // On other systems the order is Meta, Control, Alt, Shift
1369         if ((key & Qt::META) == Qt::META)
1370             s = nativeText ? QShortcut::tr("Meta") : QString::fromLatin1("Meta");
1371         if ((key & Qt::CTRL) == Qt::CTRL)
1372             addKey(s, nativeText ? QShortcut::tr("Ctrl") : QString::fromLatin1("Ctrl"), format);
1373         if ((key & Qt::ALT) == Qt::ALT)
1374             addKey(s, nativeText ? QShortcut::tr("Alt") : QString::fromLatin1("Alt"), format);
1375         if ((key & Qt::SHIFT) == Qt::SHIFT)
1376             addKey(s, nativeText ? QShortcut::tr("Shift") : QString::fromLatin1("Shift"), format);
1377     }
1378 
1379 
1380     key &= ~(Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier);
1381     QString p;
1382 
1383     if (key && key < Qt::Key_Escape && key != Qt::Key_Space) {
1384         if (!QChar::requiresSurrogates(key)) {
1385             p = QChar(ushort(key)).toUpper();
1386         } else {
1387             p += QChar(QChar::highSurrogate(key));
1388             p += QChar(QChar::lowSurrogate(key));
1389         }
1390     } else if (key >= Qt::Key_F1 && key <= Qt::Key_F35) {
1391             p = nativeText ? QShortcut::tr("F%1").arg(key - Qt::Key_F1 + 1)
1392                            : QString::fromLatin1("F%1").arg(key - Qt::Key_F1 + 1);
1393     } else if (key) {
1394         int i=0;
1395 #if defined(Q_WS_MAC)
1396         if (nativeText) {
1397             QChar ch = qt_macSymbolForQtKey(key);
1398             if (!ch.isNull())
1399                 p = ch;
1400             else
1401                 goto NonSymbol;
1402         } else
1403 #endif
1404         {
1405 #ifdef Q_WS_MAC
1406 NonSymbol:
1407 #endif
1408             while (keyname[i].name) {
1409                 if (key == keyname[i].key) {
1410                     p = nativeText ? QShortcut::tr(keyname[i].name)
1411                                    : QString::fromLatin1(keyname[i].name);
1412                     break;
1413                 }
1414                 ++i;
1415             }
1416             // If we can't find the actual translatable keyname,
1417             // fall back on the unicode representation of it...
1418             // Or else characters like Qt::Key_aring may not get displayed
1419             // (Really depends on you locale)
1420             if (!keyname[i].name) {
1421                 if (!QChar::requiresSurrogates(key)) {
1422                     p = QChar(ushort(key)).toUpper();
1423                 } else {
1424                     p += QChar(QChar::highSurrogate(key));
1425                     p += QChar(QChar::lowSurrogate(key));
1426                 }
1427             }
1428         }
1429     }
1430 
1431 #ifdef Q_WS_MAC
1432     if (nativeText)
1433         s += p;
1434     else
1435 #endif
1436     addKey(s, p, format);
1437     return s;
1438 }
1439 /*!
1440     Matches the sequence with \a seq. Returns ExactMatch if
1441     successful, PartialMatch if \a seq matches incompletely,
1442     and NoMatch if the sequences have nothing in common.
1443     Returns NoMatch if \a seq is shorter.
1444 */
matches(const QKeySequence & seq) const1445 QKeySequence::SequenceMatch QKeySequence::matches(const QKeySequence &seq) const
1446 {
1447     uint userN = count(),
1448           seqN = seq.count();
1449 
1450     if (userN > seqN)
1451         return NoMatch;
1452 
1453     // If equal in length, we have a potential ExactMatch sequence,
1454     // else we already know it can only be partial.
1455     SequenceMatch match = (userN == seqN ? ExactMatch : PartialMatch);
1456 
1457     for (uint i = 0; i < userN; ++i) {
1458         int userKey = (*this)[i],
1459             sequenceKey = seq[i];
1460         if (userKey != sequenceKey)
1461             return NoMatch;
1462     }
1463     return match;
1464 }
1465 
1466 
1467 /*!
1468     \obsolete
1469 
1470     Use toString() instead.
1471 
1472     Returns the key sequence as a QString. This is equivalent to
1473     calling toString(QKeySequence::NativeText). Note that the
1474     result is not platform independent.
1475 */
operator QString() const1476 QKeySequence::operator QString() const
1477 {
1478     return QKeySequence::toString(QKeySequence::NativeText);
1479 }
1480 
1481 /*!
1482    Returns the key sequence as a QVariant
1483 */
operator QVariant() const1484 QKeySequence::operator QVariant() const
1485 {
1486     return QVariant(QVariant::KeySequence, this);
1487 }
1488 
1489 /*!
1490     \obsolete
1491     For backward compatibility: returns the first keycode
1492     as integer. If the key sequence is empty, 0 is returned.
1493  */
operator int() const1494 QKeySequence::operator int () const
1495 {
1496     if (1 <= count())
1497         return d->key[0];
1498     return 0;
1499 }
1500 
1501 
1502 /*!
1503     Returns a reference to the element at position \a index in the key
1504     sequence. This can only be used to read an element.
1505  */
operator [](uint index) const1506 int QKeySequence::operator[](uint index) const
1507 {
1508     Q_ASSERT_X(index < 4, "QKeySequence::operator[]", "index out of range");
1509     return d->key[index];
1510 }
1511 
1512 
1513 /*!
1514     Assignment operator. Assigns the \a other key sequence to this
1515     object.
1516  */
operator =(const QKeySequence & other)1517 QKeySequence &QKeySequence::operator=(const QKeySequence &other)
1518 {
1519     qAtomicAssign(d, other.d);
1520     return *this;
1521 }
1522 
1523 /*!
1524     \fn void QKeySequence::swap(QKeySequence &other)
1525     \since 4.8
1526 
1527     Swaps key sequence \a other with this key sequence. This operation is very
1528     fast and never fails.
1529 */
1530 
1531 /*!
1532     \fn bool QKeySequence::operator!=(const QKeySequence &other) const
1533 
1534     Returns true if this key sequence is not equal to the \a other
1535     key sequence; otherwise returns false.
1536 */
1537 
1538 
1539 /*!
1540     Returns true if this key sequence is equal to the \a other
1541     key sequence; otherwise returns false.
1542  */
operator ==(const QKeySequence & other) const1543 bool QKeySequence::operator==(const QKeySequence &other) const
1544 {
1545     return (d->key[0] == other.d->key[0] &&
1546             d->key[1] == other.d->key[1] &&
1547             d->key[2] == other.d->key[2] &&
1548             d->key[3] == other.d->key[3]);
1549 }
1550 
1551 
1552 /*!
1553     Provides an arbitrary comparison of this key sequence and
1554     \a other key sequence. All that is guaranteed is that the
1555     operator returns false if both key sequences are equal and
1556     that (ks1 \< ks2) == !( ks2 \< ks1) if the key sequences
1557     are not equal.
1558 
1559     This function is useful in some circumstances, for example
1560     if you want to use QKeySequence objects as keys in a QMap.
1561 
1562     \sa operator==() operator!=() operator>() operator<=() operator>=()
1563 */
operator <(const QKeySequence & other) const1564 bool QKeySequence::operator< (const QKeySequence &other) const
1565 {
1566     for (int i = 0; i < 4; ++i)
1567         if (d->key[i] != other.d->key[i])
1568             return d->key[i] < other.d->key[i];
1569     return false;
1570 }
1571 
1572 /*!
1573     \fn bool QKeySequence::operator> (const QKeySequence &other) const
1574 
1575     Returns true if this key sequence is larger than the \a other key
1576     sequence; otherwise returns false.
1577 
1578     \sa operator==() operator!=() operator<() operator<=() operator>=()
1579 */
1580 
1581 /*!
1582     \fn bool QKeySequence::operator<= (const QKeySequence &other) const
1583 
1584     Returns true if this key sequence is smaller or equal to the
1585     \a other key sequence; otherwise returns false.
1586 
1587     \sa operator==() operator!=() operator<() operator>() operator>=()
1588 */
1589 
1590 /*!
1591     \fn bool QKeySequence::operator>= (const QKeySequence &other) const
1592 
1593     Returns true if this key sequence is larger or equal to the
1594     \a other key sequence; otherwise returns false.
1595 
1596     \sa operator==() operator!=() operator<() operator>() operator<=()
1597 */
1598 
1599 /*!
1600     \internal
1601 */
isDetached() const1602 bool QKeySequence::isDetached() const
1603 {
1604     return d->ref == 1;
1605 }
1606 
1607 /*!
1608     \since 4.1
1609 
1610     Return a string representation of the key sequence,
1611     based on \a format.
1612 
1613     For example, the value Qt::CTRL+Qt::Key_O results in "Ctrl+O".
1614     If the key sequence has multiple key codes, each is separated
1615     by commas in the string returned, such as "Alt+X, Ctrl+Y, Z".
1616     The strings, "Ctrl", "Shift", etc. are translated using
1617     QObject::tr() in the "QShortcut" context.
1618 
1619     If the key sequence has no keys, an empty string is returned.
1620 
1621     On Mac OS X, the string returned resembles the sequence that is
1622     shown in the menu bar.
1623 
1624     \sa fromString()
1625 */
toString(SequenceFormat format) const1626 QString QKeySequence::toString(SequenceFormat format) const
1627 {
1628     QString finalString;
1629     // A standard string, with no translation or anything like that. In some ways it will
1630     // look like our latin case on Windows and X11
1631     int end = count();
1632     for (int i = 0; i < end; ++i) {
1633         finalString += d->encodeString(d->key[i], format);
1634         finalString += QLatin1String(", ");
1635     }
1636     finalString.truncate(finalString.length() - 2);
1637     return finalString;
1638 }
1639 
1640 /*!
1641     \since 4.1
1642 
1643     Return a QKeySequence from the string \a str based on \a format.
1644 
1645     \sa toString()
1646 */
fromString(const QString & str,SequenceFormat format)1647 QKeySequence QKeySequence::fromString(const QString &str, SequenceFormat format)
1648 {
1649     return QKeySequence(str, format);
1650 }
1651 
1652 /*****************************************************************************
1653   QKeySequence stream functions
1654  *****************************************************************************/
1655 #if !defined(QT_NO_DATASTREAM)
1656 /*!
1657     \fn QDataStream &operator<<(QDataStream &stream, const QKeySequence &sequence)
1658     \relates QKeySequence
1659 
1660     Writes the key \a sequence to the \a stream.
1661 
1662     \sa \link datastreamformat.html Format of the QDataStream operators \endlink
1663 */
operator <<(QDataStream & s,const QKeySequence & keysequence)1664 QDataStream &operator<<(QDataStream &s, const QKeySequence &keysequence)
1665 {
1666     QList<quint32> list;
1667     list << keysequence.d->key[0];
1668 
1669     if (s.version() >= 5 && keysequence.count() > 1) {
1670         list << keysequence.d->key[1];
1671         list << keysequence.d->key[2];
1672         list << keysequence.d->key[3];
1673     }
1674     s << list;
1675     return s;
1676 }
1677 
1678 
1679 /*!
1680     \fn QDataStream &operator>>(QDataStream &stream, QKeySequence &sequence)
1681     \relates QKeySequence
1682 
1683     Reads a key sequence from the \a stream into the key \a sequence.
1684 
1685     \sa \link datastreamformat.html Format of the QDataStream operators \endlink
1686 */
operator >>(QDataStream & s,QKeySequence & keysequence)1687 QDataStream &operator>>(QDataStream &s, QKeySequence &keysequence)
1688 {
1689 	qAtomicDetach(keysequence.d);
1690     QList<quint32> list;
1691     s >> list;
1692     for (int i = 0; i < 4; ++i)
1693         keysequence.d->key[i] = list.value(i);
1694     return s;
1695 }
1696 
1697 #endif //QT_NO_DATASTREAM
1698 
1699 #ifndef QT_NO_DEBUG_STREAM
operator <<(QDebug dbg,const QKeySequence & p)1700 QDebug operator<<(QDebug dbg, const QKeySequence &p)
1701 {
1702 #ifndef Q_BROKEN_DEBUG_STREAM
1703     dbg.nospace() << "QKeySequence(" << p.toString() << ')';
1704     return dbg.space();
1705 #else
1706     qWarning("This compiler doesn't support streaming QKeySequence to QDebug");
1707     return dbg;
1708     Q_UNUSED(p);
1709 #endif
1710 }
1711 #endif
1712 
1713 #endif // QT_NO_SHORTCUT
1714 
1715 
1716 /*!
1717     \typedef QKeySequence::DataPtr
1718     \internal
1719 */
1720 
1721  /*!
1722     \fn DataPtr &QKeySequence::data_ptr()
1723     \internal
1724 */
1725 
1726 QT_END_NAMESPACE
1727