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