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