src/gui/kernel/qkeysequence.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 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           \i (none)         \i (none)                                \i (none)
       
   286     \row    \i SelectEndOfBlock     \i (none)                           \i Alt+Shift+Down         \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     // Multimedia keys
       
   420     { Qt::Key_Back,         QT_TRANSLATE_NOOP("QShortcut", "Back") },
       
   421     { Qt::Key_Forward,      QT_TRANSLATE_NOOP("QShortcut", "Forward") },
       
   422     { Qt::Key_Stop,         QT_TRANSLATE_NOOP("QShortcut", "Stop") },
       
   423     { Qt::Key_Refresh,      QT_TRANSLATE_NOOP("QShortcut", "Refresh") },
       
   424     { Qt::Key_VolumeDown,   QT_TRANSLATE_NOOP("QShortcut", "Volume Down") },
       
   425     { Qt::Key_VolumeMute,   QT_TRANSLATE_NOOP("QShortcut", "Volume Mute") },
       
   426     { Qt::Key_VolumeUp,     QT_TRANSLATE_NOOP("QShortcut", "Volume Up") },
       
   427     { Qt::Key_BassBoost,    QT_TRANSLATE_NOOP("QShortcut", "Bass Boost") },
       
   428     { Qt::Key_BassUp,       QT_TRANSLATE_NOOP("QShortcut", "Bass Up") },
       
   429     { Qt::Key_BassDown,     QT_TRANSLATE_NOOP("QShortcut", "Bass Down") },
       
   430     { Qt::Key_TrebleUp,     QT_TRANSLATE_NOOP("QShortcut", "Treble Up") },
       
   431     { Qt::Key_TrebleDown,   QT_TRANSLATE_NOOP("QShortcut", "Treble Down") },
       
   432     { Qt::Key_MediaPlay,    QT_TRANSLATE_NOOP("QShortcut", "Media Play") },
       
   433     { Qt::Key_MediaStop,    QT_TRANSLATE_NOOP("QShortcut", "Media Stop") },
       
   434     { Qt::Key_MediaPrevious,QT_TRANSLATE_NOOP("QShortcut", "Media Previous") },
       
   435     { Qt::Key_MediaNext,    QT_TRANSLATE_NOOP("QShortcut", "Media Next") },
       
   436     { Qt::Key_MediaRecord,  QT_TRANSLATE_NOOP("QShortcut", "Media Record") },
       
   437     { Qt::Key_HomePage,     QT_TRANSLATE_NOOP("QShortcut", "Home Page") },
       
   438     { Qt::Key_Favorites,    QT_TRANSLATE_NOOP("QShortcut", "Favorites") },
       
   439     { Qt::Key_Search,       QT_TRANSLATE_NOOP("QShortcut", "Search") },
       
   440     { Qt::Key_Standby,      QT_TRANSLATE_NOOP("QShortcut", "Standby") },
       
   441     { Qt::Key_OpenUrl,      QT_TRANSLATE_NOOP("QShortcut", "Open URL") },
       
   442     { Qt::Key_LaunchMail,   QT_TRANSLATE_NOOP("QShortcut", "Launch Mail") },
       
   443     { Qt::Key_LaunchMedia,  QT_TRANSLATE_NOOP("QShortcut", "Launch Media") },
       
   444     { Qt::Key_Launch0,      QT_TRANSLATE_NOOP("QShortcut", "Launch (0)") },
       
   445     { Qt::Key_Launch1,      QT_TRANSLATE_NOOP("QShortcut", "Launch (1)") },
       
   446     { Qt::Key_Launch2,      QT_TRANSLATE_NOOP("QShortcut", "Launch (2)") },
       
   447     { Qt::Key_Launch3,      QT_TRANSLATE_NOOP("QShortcut", "Launch (3)") },
       
   448     { Qt::Key_Launch4,      QT_TRANSLATE_NOOP("QShortcut", "Launch (4)") },
       
   449     { Qt::Key_Launch5,      QT_TRANSLATE_NOOP("QShortcut", "Launch (5)") },
       
   450     { Qt::Key_Launch6,      QT_TRANSLATE_NOOP("QShortcut", "Launch (6)") },
       
   451     { Qt::Key_Launch7,      QT_TRANSLATE_NOOP("QShortcut", "Launch (7)") },
       
   452     { Qt::Key_Launch8,      QT_TRANSLATE_NOOP("QShortcut", "Launch (8)") },
       
   453     { Qt::Key_Launch9,      QT_TRANSLATE_NOOP("QShortcut", "Launch (9)") },
       
   454     { Qt::Key_LaunchA,      QT_TRANSLATE_NOOP("QShortcut", "Launch (A)") },
       
   455     { Qt::Key_LaunchB,      QT_TRANSLATE_NOOP("QShortcut", "Launch (B)") },
       
   456     { Qt::Key_LaunchC,      QT_TRANSLATE_NOOP("QShortcut", "Launch (C)") },
       
   457     { Qt::Key_LaunchD,      QT_TRANSLATE_NOOP("QShortcut", "Launch (D)") },
       
   458     { Qt::Key_LaunchE,      QT_TRANSLATE_NOOP("QShortcut", "Launch (E)") },
       
   459     { Qt::Key_LaunchF,      QT_TRANSLATE_NOOP("QShortcut", "Launch (F)") },
       
   460 
       
   461     // --------------------------------------------------------------
       
   462     // More consistent namings
       
   463     { Qt::Key_Print,        QT_TRANSLATE_NOOP("QShortcut", "Print Screen") },
       
   464     { Qt::Key_PageUp,       QT_TRANSLATE_NOOP("QShortcut", "Page Up") },
       
   465     { Qt::Key_PageDown,     QT_TRANSLATE_NOOP("QShortcut", "Page Down") },
       
   466     { Qt::Key_CapsLock,     QT_TRANSLATE_NOOP("QShortcut", "Caps Lock") },
       
   467     { Qt::Key_NumLock,      QT_TRANSLATE_NOOP("QShortcut", "Num Lock") },
       
   468     { Qt::Key_NumLock,      QT_TRANSLATE_NOOP("QShortcut", "Number Lock") },
       
   469     { Qt::Key_ScrollLock,   QT_TRANSLATE_NOOP("QShortcut", "Scroll Lock") },
       
   470     { Qt::Key_Insert,       QT_TRANSLATE_NOOP("QShortcut", "Insert") },
       
   471     { Qt::Key_Delete,       QT_TRANSLATE_NOOP("QShortcut", "Delete") },
       
   472     { Qt::Key_Escape,       QT_TRANSLATE_NOOP("QShortcut", "Escape") },
       
   473     { Qt::Key_SysReq,       QT_TRANSLATE_NOOP("QShortcut", "System Request") },
       
   474 
       
   475     // --------------------------------------------------------------
       
   476     // Keypad navigation keys
       
   477     { Qt::Key_Select,       QT_TRANSLATE_NOOP("QShortcut", "Select") },
       
   478     { Qt::Key_Yes,          QT_TRANSLATE_NOOP("QShortcut", "Yes") },
       
   479     { Qt::Key_No,           QT_TRANSLATE_NOOP("QShortcut", "No") },
       
   480 
       
   481     // --------------------------------------------------------------
       
   482     // Device keys
       
   483     { Qt::Key_Context1,     QT_TRANSLATE_NOOP("QShortcut", "Context1") },
       
   484     { Qt::Key_Context2,     QT_TRANSLATE_NOOP("QShortcut", "Context2") },
       
   485     { Qt::Key_Context3,     QT_TRANSLATE_NOOP("QShortcut", "Context3") },
       
   486     { Qt::Key_Context4,     QT_TRANSLATE_NOOP("QShortcut", "Context4") },
       
   487     { Qt::Key_Call,         QT_TRANSLATE_NOOP("QShortcut", "Call") },
       
   488     { Qt::Key_Hangup,       QT_TRANSLATE_NOOP("QShortcut", "Hangup") },
       
   489     { Qt::Key_Flip,         QT_TRANSLATE_NOOP("QShortcut", "Flip") },
       
   490 
       
   491 
       
   492     { 0, 0 }
       
   493 };
       
   494 
       
   495 //Table of key bindings. It must be sorted on key sequence.
       
   496 //A priority of 1 indicates that this is the primary key binding when multiple are defined.
       
   497 
       
   498 const QKeyBinding QKeySequencePrivate::keyBindings[] = {
       
   499 //   StandardKey                            Priority    Key Sequence                            Platforms
       
   500     {QKeySequence::Back,                    0,          Qt::Key_Backspace,                      QApplicationPrivate::KB_Win},
       
   501     {QKeySequence::InsertParagraphSeparator,0,          Qt::Key_Return,                         QApplicationPrivate::KB_All},
       
   502     {QKeySequence::InsertParagraphSeparator,0,          Qt::Key_Enter,                          QApplicationPrivate::KB_All},
       
   503     {QKeySequence::Delete,                  1,          Qt::Key_Delete,                         QApplicationPrivate::KB_All},
       
   504     {QKeySequence::MoveToStartOfLine,       0,          Qt::Key_Home,                           QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11 | QApplicationPrivate::KB_S60},
       
   505     {QKeySequence::MoveToStartOfDocument,   0,          Qt::Key_Home,                           QApplicationPrivate::KB_Mac},
       
   506     {QKeySequence::MoveToEndOfLine,         0,          Qt::Key_End,                            QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11 | QApplicationPrivate::KB_S60},
       
   507     {QKeySequence::MoveToEndOfDocument,     0,          Qt::Key_End,                            QApplicationPrivate::KB_Mac},
       
   508     {QKeySequence::MoveToPreviousChar,      0,          Qt::Key_Left,                           QApplicationPrivate::KB_All},
       
   509     {QKeySequence::MoveToPreviousLine,      0,          Qt::Key_Up,                             QApplicationPrivate::KB_All},
       
   510     {QKeySequence::MoveToNextChar,          0,          Qt::Key_Right,                          QApplicationPrivate::KB_All},
       
   511     {QKeySequence::MoveToNextLine,          0,          Qt::Key_Down,                           QApplicationPrivate::KB_All},
       
   512     {QKeySequence::MoveToPreviousPage,      1,          Qt::Key_PageUp,                         QApplicationPrivate::KB_All},
       
   513     {QKeySequence::MoveToNextPage,          1,          Qt::Key_PageDown,                       QApplicationPrivate::KB_All},
       
   514     {QKeySequence::HelpContents,            0,          Qt::Key_F1,                             QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11},
       
   515     {QKeySequence::HelpContents,            0,          Qt::Key_F2,                             QApplicationPrivate::KB_S60},
       
   516     {QKeySequence::FindNext,                0,          Qt::Key_F3,                             QApplicationPrivate::KB_X11},
       
   517     {QKeySequence::FindNext,                1,          Qt::Key_F3,                             QApplicationPrivate::KB_Win},
       
   518     {QKeySequence::Refresh,                 0,          Qt::Key_F5,                             QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11},
       
   519     {QKeySequence::Undo,                    0,          Qt::Key_F14,                            QApplicationPrivate::KB_X11}, //Undo on sun keyboards
       
   520     {QKeySequence::Copy,                    0,          Qt::Key_F16,                            QApplicationPrivate::KB_X11}, //Copy on sun keyboards
       
   521     {QKeySequence::Paste,                   0,          Qt::Key_F18,                            QApplicationPrivate::KB_X11}, //Paste on sun keyboards      
       
   522     {QKeySequence::Cut,                     0,          Qt::Key_F20,                            QApplicationPrivate::KB_X11}, //Cut on sun keyboards
       
   523     {QKeySequence::PreviousChild,           0,          Qt::Key_Back,                           QApplicationPrivate::KB_All},
       
   524     {QKeySequence::NextChild,               0,          Qt::Key_Forward,                        QApplicationPrivate::KB_All}, 
       
   525     {QKeySequence::Forward,                 0,          Qt::SHIFT | Qt::Key_Backspace,          QApplicationPrivate::KB_Win},
       
   526     {QKeySequence::Delete,                  0,          Qt::SHIFT | Qt::Key_Backspace,          QApplicationPrivate::KB_S60},
       
   527     {QKeySequence::InsertLineSeparator,     0,          Qt::SHIFT | Qt::Key_Return,             QApplicationPrivate::KB_All},
       
   528     {QKeySequence::InsertLineSeparator,     0,          Qt::SHIFT | Qt::Key_Enter,              QApplicationPrivate::KB_All},
       
   529     {QKeySequence::Paste,                   0,          Qt::SHIFT | Qt::Key_Insert,             QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11}, 
       
   530     {QKeySequence::Cut,                     0,          Qt::SHIFT | Qt::Key_Delete,             QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11}, //## Check if this should work on mac
       
   531     {QKeySequence::SelectStartOfLine,       0,          Qt::SHIFT | Qt::Key_Home,               QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11 | QApplicationPrivate::KB_S60},
       
   532     {QKeySequence::SelectStartOfDocument,   0,          Qt::SHIFT | Qt::Key_Home,               QApplicationPrivate::KB_Mac},
       
   533     {QKeySequence::SelectEndOfLine,         0,          Qt::SHIFT | Qt::Key_End,                QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11 | QApplicationPrivate::KB_S60},
       
   534     {QKeySequence::SelectEndOfDocument,     0,          Qt::SHIFT | Qt::Key_End,                QApplicationPrivate::KB_Mac},
       
   535     {QKeySequence::SelectPreviousChar,      0,          Qt::SHIFT | Qt::Key_Left,               QApplicationPrivate::KB_All},
       
   536     {QKeySequence::SelectPreviousLine,      0,          Qt::SHIFT | Qt::Key_Up,                 QApplicationPrivate::KB_All},
       
   537     {QKeySequence::SelectNextChar,          0,          Qt::SHIFT | Qt::Key_Right,              QApplicationPrivate::KB_All},
       
   538     {QKeySequence::SelectNextLine,          0,          Qt::SHIFT | Qt::Key_Down,               QApplicationPrivate::KB_All},
       
   539     {QKeySequence::SelectPreviousPage,      0,          Qt::SHIFT | Qt::Key_PageUp,             QApplicationPrivate::KB_All},
       
   540     {QKeySequence::SelectNextPage,          0,          Qt::SHIFT | Qt::Key_PageDown,           QApplicationPrivate::KB_All},
       
   541     {QKeySequence::WhatsThis,               1,          Qt::SHIFT | Qt::Key_F1,                 QApplicationPrivate::KB_All},
       
   542     {QKeySequence::FindPrevious,            0,          Qt::SHIFT | Qt::Key_F3,                 QApplicationPrivate::KB_X11},
       
   543     {QKeySequence::FindPrevious,            1,          Qt::SHIFT | Qt::Key_F3,                 QApplicationPrivate::KB_Win},
       
   544     {QKeySequence::ZoomIn,                  1,          Qt::CTRL | Qt::Key_Plus,                QApplicationPrivate::KB_All},
       
   545     {QKeySequence::NextChild,               0,          Qt::CTRL | Qt::Key_Comma,               QApplicationPrivate::KB_KDE},
       
   546     {QKeySequence::Preferences,             0,          Qt::CTRL | Qt::Key_Comma,               QApplicationPrivate::KB_Mac},
       
   547     {QKeySequence::ZoomOut,                 1,          Qt::CTRL | Qt::Key_Minus,               QApplicationPrivate::KB_All},
       
   548     {QKeySequence::PreviousChild,           0,          Qt::CTRL | Qt::Key_Period,              QApplicationPrivate::KB_KDE},
       
   549     {QKeySequence::HelpContents,            1,          Qt::CTRL | Qt::Key_Question,            QApplicationPrivate::KB_Mac},
       
   550     {QKeySequence::SelectAll,               1,          Qt::CTRL | Qt::Key_A,                   QApplicationPrivate::KB_All},
       
   551     {QKeySequence::Bold,                    1,          Qt::CTRL | Qt::Key_B,                   QApplicationPrivate::KB_All},
       
   552     {QKeySequence::Copy,                    1,          Qt::CTRL | Qt::Key_C,                   QApplicationPrivate::KB_All},
       
   553     {QKeySequence::Delete,                  0,          Qt::CTRL | Qt::Key_D,                   QApplicationPrivate::KB_X11}, //emacs (line edit only)
       
   554     {QKeySequence::Find,                    0,          Qt::CTRL | Qt::Key_F,                   QApplicationPrivate::KB_All},
       
   555     {QKeySequence::FindNext,                1,          Qt::CTRL | Qt::Key_G,                   QApplicationPrivate::KB_Gnome | QApplicationPrivate::KB_Mac},
       
   556     {QKeySequence::FindNext,                0,          Qt::CTRL | Qt::Key_G,                   QApplicationPrivate::KB_Win},
       
   557     {QKeySequence::Replace,                 0,          Qt::CTRL | Qt::Key_H,                   QApplicationPrivate::KB_Win}, 
       
   558     {QKeySequence::Replace,                 0,          Qt::CTRL | Qt::Key_H,                   QApplicationPrivate::KB_Gnome}, 
       
   559     {QKeySequence::Italic,                  0,          Qt::CTRL | Qt::Key_I,                   QApplicationPrivate::KB_All}, 
       
   560     {QKeySequence::DeleteEndOfLine,         0,          Qt::CTRL | Qt::Key_K,                   QApplicationPrivate::KB_X11}, //emacs (line edit only)
       
   561     {QKeySequence::New,                     1,          Qt::CTRL | Qt::Key_N,                   QApplicationPrivate::KB_All},
       
   562     {QKeySequence::Open,                    1,          Qt::CTRL | Qt::Key_O,                   QApplicationPrivate::KB_All},
       
   563     {QKeySequence::Print,                   1,          Qt::CTRL | Qt::Key_P,                   QApplicationPrivate::KB_All},
       
   564     {QKeySequence::Quit,                    0,          Qt::CTRL | Qt::Key_Q,                   QApplicationPrivate::KB_Gnome | QApplicationPrivate::KB_KDE | QApplicationPrivate::KB_Mac},
       
   565     {QKeySequence::Refresh,                 1,          Qt::CTRL | Qt::Key_R,                   QApplicationPrivate::KB_Gnome | QApplicationPrivate::KB_Mac},
       
   566     {QKeySequence::Replace,                 0,          Qt::CTRL | Qt::Key_R,                   QApplicationPrivate::KB_KDE},
       
   567     {QKeySequence::Save,                    1,          Qt::CTRL | Qt::Key_S,                   QApplicationPrivate::KB_All},
       
   568     {QKeySequence::AddTab,                  0,          Qt::CTRL | Qt::Key_T,                   QApplicationPrivate::KB_All},
       
   569     {QKeySequence::Underline,               1,          Qt::CTRL | Qt::Key_U,                   QApplicationPrivate::KB_All}, 
       
   570     {QKeySequence::Paste,                   1,          Qt::CTRL | Qt::Key_V,                   QApplicationPrivate::KB_All},
       
   571     {QKeySequence::Close,                   0,          Qt::CTRL | Qt::Key_W,                   QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11},
       
   572     {QKeySequence::Close,                   1,          Qt::CTRL | Qt::Key_W,                   QApplicationPrivate::KB_Mac},
       
   573     {QKeySequence::Cut,                     1,          Qt::CTRL | Qt::Key_X,                   QApplicationPrivate::KB_All},
       
   574     {QKeySequence::Redo,                    1,          Qt::CTRL | Qt::Key_Y,                   QApplicationPrivate::KB_Win | QApplicationPrivate::KB_S60},
       
   575     {QKeySequence::Redo,                    0,          Qt::CTRL | Qt::Key_Y,                   QApplicationPrivate::KB_Mac},//different priority from above
       
   576     {QKeySequence::Undo,                    1,          Qt::CTRL | Qt::Key_Z,                   QApplicationPrivate::KB_All},
       
   577     {QKeySequence::Back,                    1,          Qt::CTRL | Qt::Key_BracketLeft,         QApplicationPrivate::KB_Mac},
       
   578     {QKeySequence::Forward,                 1,          Qt::CTRL | Qt::Key_BracketRight,        QApplicationPrivate::KB_Mac},
       
   579     {QKeySequence::PreviousChild,           1,          Qt::CTRL | Qt::Key_BraceLeft,           QApplicationPrivate::KB_Mac},
       
   580     {QKeySequence::NextChild,               1,          Qt::CTRL | Qt::Key_BraceRight,          QApplicationPrivate::KB_Mac},
       
   581     {QKeySequence::NextChild,               1,          Qt::CTRL | Qt::Key_Tab,                 QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11},
       
   582     {QKeySequence::NextChild,               0,          Qt::CTRL | Qt::Key_Tab,                 QApplicationPrivate::KB_Mac}, //different priority from above
       
   583     {QKeySequence::DeleteStartOfWord,       0,          Qt::CTRL | Qt::Key_Backspace,           QApplicationPrivate::KB_X11 | QApplicationPrivate::KB_Win},
       
   584     {QKeySequence::Copy,                    0,          Qt::CTRL | Qt::Key_Insert,              QApplicationPrivate::KB_X11 | QApplicationPrivate::KB_Win}, 
       
   585     {QKeySequence::DeleteEndOfWord,         0,          Qt::CTRL | Qt::Key_Delete,              QApplicationPrivate::KB_X11 | QApplicationPrivate::KB_Win},
       
   586     {QKeySequence::MoveToStartOfDocument,   0,          Qt::CTRL | Qt::Key_Home,                QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11 | QApplicationPrivate::KB_S60},
       
   587     {QKeySequence::MoveToEndOfDocument,     0,          Qt::CTRL | Qt::Key_End,                 QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11 | QApplicationPrivate::KB_S60},
       
   588     {QKeySequence::Back,                    0,          Qt::CTRL | Qt::Key_Left,                QApplicationPrivate::KB_Mac}, 
       
   589     {QKeySequence::MoveToPreviousWord,      0,          Qt::CTRL | Qt::Key_Left,                QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11 | QApplicationPrivate::KB_S60},
       
   590     {QKeySequence::MoveToStartOfLine,       0,          Qt::CTRL | Qt::Key_Left,                QApplicationPrivate::KB_Mac },
       
   591     {QKeySequence::MoveToStartOfDocument,   1,          Qt::CTRL | Qt::Key_Up,                  QApplicationPrivate::KB_Mac},
       
   592     {QKeySequence::Forward,                 0,          Qt::CTRL | Qt::Key_Right,               QApplicationPrivate::KB_Mac}, 
       
   593     {QKeySequence::MoveToEndOfLine,         0,          Qt::CTRL | Qt::Key_Right,               QApplicationPrivate::KB_Mac },
       
   594     {QKeySequence::MoveToNextWord,          0,          Qt::CTRL | Qt::Key_Right,               QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11 | QApplicationPrivate::KB_S60},
       
   595     {QKeySequence::MoveToEndOfDocument,     1,          Qt::CTRL | Qt::Key_Down,                QApplicationPrivate::KB_Mac},
       
   596     {QKeySequence::Close,                   1,          Qt::CTRL | Qt::Key_F4,                  QApplicationPrivate::KB_Win},
       
   597     {QKeySequence::Close,                   0,          Qt::CTRL | Qt::Key_F4,                  QApplicationPrivate::KB_Mac},
       
   598     {QKeySequence::NextChild,               0,          Qt::CTRL | Qt::Key_F6,                  QApplicationPrivate::KB_Win},
       
   599     {QKeySequence::FindPrevious,            1,          Qt::CTRL | Qt::SHIFT | Qt::Key_G,       QApplicationPrivate::KB_Gnome | QApplicationPrivate::KB_Mac},
       
   600     {QKeySequence::FindPrevious,            0,          Qt::CTRL | Qt::SHIFT | Qt::Key_G,       QApplicationPrivate::KB_Win},
       
   601     {QKeySequence::AddTab,                  1,          Qt::CTRL | Qt::SHIFT | Qt::Key_N,       QApplicationPrivate::KB_KDE},
       
   602     {QKeySequence::SaveAs,                  0,          Qt::CTRL | Qt::SHIFT | Qt::Key_S,       QApplicationPrivate::KB_Gnome | QApplicationPrivate::KB_Mac},
       
   603     {QKeySequence::Redo,                    0,          Qt::CTRL | Qt::SHIFT | Qt::Key_Z,       QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11 | QApplicationPrivate::KB_S60},
       
   604     {QKeySequence::Redo,                    1,          Qt::CTRL | Qt::SHIFT | Qt::Key_Z,       QApplicationPrivate::KB_Mac}, //different priority from above
       
   605     {QKeySequence::PreviousChild,           1,          Qt::CTRL | Qt::SHIFT | Qt::Key_Backtab, QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11},
       
   606     {QKeySequence::PreviousChild,           0,          Qt::CTRL | Qt::SHIFT | Qt::Key_Backtab, QApplicationPrivate::KB_Mac },//different priority from above 
       
   607     {QKeySequence::SelectStartOfDocument,   0,          Qt::CTRL | Qt::SHIFT | Qt::Key_Home,    QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11 | QApplicationPrivate::KB_S60},
       
   608     {QKeySequence::SelectEndOfDocument,     0,          Qt::CTRL | Qt::SHIFT | Qt::Key_End,     QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11 | QApplicationPrivate::KB_S60},
       
   609     {QKeySequence::SelectPreviousWord,      0,          Qt::CTRL | Qt::SHIFT | Qt::Key_Left,    QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11 | QApplicationPrivate::KB_S60},
       
   610     {QKeySequence::SelectStartOfLine,       1,          Qt::CTRL | Qt::SHIFT | Qt::Key_Left,    QApplicationPrivate::KB_Mac },
       
   611     {QKeySequence::SelectStartOfDocument,   1,          Qt::CTRL | Qt::SHIFT | Qt::Key_Up,      QApplicationPrivate::KB_Mac},
       
   612     {QKeySequence::SelectNextWord,          0,          Qt::CTRL | Qt::SHIFT | Qt::Key_Right,   QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11 | QApplicationPrivate::KB_S60},
       
   613     {QKeySequence::SelectEndOfLine,         1,          Qt::CTRL | Qt::SHIFT | Qt::Key_Right,   QApplicationPrivate::KB_Mac },
       
   614     {QKeySequence::SelectEndOfDocument,     1,          Qt::CTRL | Qt::SHIFT | Qt::Key_Down,    QApplicationPrivate::KB_Mac},
       
   615     {QKeySequence::PreviousChild,           0,          Qt::CTRL | Qt::SHIFT | Qt::Key_F6,      QApplicationPrivate::KB_Win},
       
   616     {QKeySequence::Undo,                    0,          Qt::ALT  | Qt::Key_Backspace,           QApplicationPrivate::KB_Win},
       
   617     {QKeySequence::DeleteStartOfWord,       0,          Qt::ALT  | Qt::Key_Backspace,           QApplicationPrivate::KB_Mac},
       
   618     {QKeySequence::DeleteEndOfWord,         0,          Qt::ALT  | Qt::Key_Delete,              QApplicationPrivate::KB_Mac},    
       
   619     {QKeySequence::Back,                    1,          Qt::ALT  | Qt::Key_Left,                QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11},
       
   620     {QKeySequence::MoveToPreviousWord,      0,          Qt::ALT  | Qt::Key_Left,                QApplicationPrivate::KB_Mac},
       
   621     {QKeySequence::MoveToStartOfBlock,      0,          Qt::ALT  | Qt::Key_Up,                  QApplicationPrivate::KB_Mac}, //mac only
       
   622     {QKeySequence::MoveToNextWord,          0,          Qt::ALT  | Qt::Key_Right,               QApplicationPrivate::KB_Mac},
       
   623     {QKeySequence::Forward,                 1,          Qt::ALT  | Qt::Key_Right,               QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11},
       
   624     {QKeySequence::MoveToEndOfBlock,        0,          Qt::ALT  | Qt::Key_Down,                QApplicationPrivate::KB_Mac}, //mac only
       
   625     {QKeySequence::MoveToPreviousPage,      0,          Qt::ALT  | Qt::Key_PageUp,              QApplicationPrivate::KB_Mac },
       
   626     {QKeySequence::MoveToNextPage,          0,          Qt::ALT  | Qt::Key_PageDown,            QApplicationPrivate::KB_Mac },
       
   627     {QKeySequence::Redo,                    0,          Qt::ALT  | Qt::SHIFT | Qt::Key_Backspace,QApplicationPrivate::KB_Win},
       
   628     {QKeySequence::SelectPreviousWord,      0,          Qt::ALT  | Qt::SHIFT | Qt::Key_Left,    QApplicationPrivate::KB_Mac},
       
   629     {QKeySequence::SelectStartOfBlock,      0,          Qt::ALT  | Qt::SHIFT | Qt::Key_Up,      QApplicationPrivate::KB_Mac}, //mac only
       
   630     {QKeySequence::SelectNextWord,          0,          Qt::ALT  | Qt::SHIFT | Qt::Key_Right,   QApplicationPrivate::KB_Mac},
       
   631     {QKeySequence::SelectEndOfBlock,        0,          Qt::ALT  | Qt::SHIFT | Qt::Key_Down,    QApplicationPrivate::KB_Mac}, //mac only
       
   632     {QKeySequence::MoveToStartOfBlock,      0,          Qt::META | Qt::Key_A,                   QApplicationPrivate::KB_Mac},
       
   633     {QKeySequence::Delete,                  0,          Qt::META | Qt::Key_D,                   QApplicationPrivate::KB_Mac},
       
   634     {QKeySequence::MoveToEndOfBlock,        0,          Qt::META | Qt::Key_E,                   QApplicationPrivate::KB_Mac},
       
   635     {QKeySequence::InsertLineSeparator,     0,          Qt::META | Qt::Key_Return,              QApplicationPrivate::KB_Mac},
       
   636     {QKeySequence::InsertLineSeparator,     0,          Qt::META | Qt::Key_Enter,               QApplicationPrivate::KB_Mac},
       
   637     {QKeySequence::MoveToStartOfLine,       0,          Qt::META | Qt::Key_Left,                QApplicationPrivate::KB_Mac},
       
   638     {QKeySequence::MoveToPreviousPage,      0,          Qt::META | Qt::Key_Up,                  QApplicationPrivate::KB_Mac},
       
   639     {QKeySequence::MoveToEndOfLine,         0,          Qt::META | Qt::Key_Right,               QApplicationPrivate::KB_Mac},
       
   640     {QKeySequence::MoveToNextPage,          0,          Qt::META | Qt::Key_Down,                QApplicationPrivate::KB_Mac},
       
   641     {QKeySequence::MoveToPreviousPage,      0,          Qt::META | Qt::Key_PageUp,              QApplicationPrivate::KB_Mac},
       
   642     {QKeySequence::MoveToNextPage,          0,          Qt::META | Qt::Key_PageDown,            QApplicationPrivate::KB_Mac},
       
   643     {QKeySequence::SelectStartOfLine,       0,          Qt::META | Qt::SHIFT | Qt::Key_Left,    QApplicationPrivate::KB_Mac},
       
   644     {QKeySequence::SelectEndOfLine,         0,          Qt::META | Qt::SHIFT | Qt::Key_Right,   QApplicationPrivate::KB_Mac}    
       
   645 };
       
   646 
       
   647 const uint QKeySequencePrivate::numberOfKeyBindings = sizeof(QKeySequencePrivate::keyBindings)/(sizeof(QKeyBinding));
       
   648 
       
   649 
       
   650 /*!
       
   651     \enum QKeySequence::StandardKey
       
   652     \since 4.2
       
   653 
       
   654     This enum represent standard key bindings. They can be used to
       
   655     assign platform dependent keyboard shortcuts to a QAction.
       
   656 
       
   657     Note that the key bindings are platform dependent. The currently
       
   658     bound shortcuts can be queried using keyBindings().
       
   659 
       
   660     \value AddTab           Add new tab.
       
   661     \value Back             Navigate back.
       
   662     \value Bold             Bold text.
       
   663     \value Close            Close document/tab.
       
   664     \value Copy             Copy.
       
   665     \value Cut              Cut.
       
   666     \value Delete           Delete.
       
   667     \value DeleteEndOfLine          Delete end of line.
       
   668     \value DeleteEndOfWord          Delete word from the end of the cursor.
       
   669     \value DeleteStartOfWord        Delete the beginning of a word up to the cursor.
       
   670     \value Find             Find in document.
       
   671     \value FindNext         Find next result.
       
   672     \value FindPrevious     Find previous result.
       
   673     \value Forward          Navigate forward.
       
   674     \value HelpContents     Open help contents.
       
   675     \value InsertLineSeparator      Insert a new line.
       
   676     \value InsertParagraphSeparator Insert a new paragraph.
       
   677     \value Italic           Italic text.
       
   678     \value MoveToEndOfBlock         Move cursor to end of block. This shortcut is only used on the OS X.
       
   679     \value MoveToEndOfDocument      Move cursor to end of document.
       
   680     \value MoveToEndOfLine          Move cursor to end of line.
       
   681     \value MoveToNextChar           Move cursor to next character.
       
   682     \value MoveToNextLine           Move cursor to next line.
       
   683     \value MoveToNextPage           Move cursor to next page.
       
   684     \value MoveToNextWord           Move cursor to next word.
       
   685     \value MoveToPreviousChar       Move cursor to previous character.
       
   686     \value MoveToPreviousLine       Move cursor to previous line.
       
   687     \value MoveToPreviousPage       Move cursor to previous page.
       
   688     \value MoveToPreviousWord       Move cursor to previous word.
       
   689     \value MoveToStartOfBlock       Move cursor to start of a block. This shortcut is only used on OS X.
       
   690     \value MoveToStartOfDocument    Move cursor to start of document.
       
   691     \value MoveToStartOfLine        Move cursor to start of line.
       
   692     \value New              Create new document.
       
   693     \value NextChild        Navigate to next tab or child window.
       
   694     \value Open             Open document.
       
   695     \value Paste            Paste.
       
   696     \value Preferences      Open the preferences dialog.
       
   697     \value PreviousChild    Navigate to previous tab or child window.
       
   698     \value Print            Print document.
       
   699     \value Quit             Quit the application.
       
   700     \value Redo             Redo.
       
   701     \value Refresh          Refresh or reload current document.
       
   702     \value Replace          Find and replace.
       
   703     \value SaveAs           Save document after prompting the user for a file name.
       
   704     \value Save             Save document.
       
   705     \value SelectAll        Select all text.
       
   706     \value SelectEndOfBlock         Extend selection to the end of a text block. This shortcut is only used on OS X.
       
   707     \value SelectEndOfDocument      Extend selection to end of document.
       
   708     \value SelectEndOfLine          Extend selection to end of line.
       
   709     \value SelectNextChar           Extend selection to next character.
       
   710     \value SelectNextLine           Extend selection to next line.
       
   711     \value SelectNextPage           Extend selection to next page.
       
   712     \value SelectNextWord           Extend selection to next word.
       
   713     \value SelectPreviousChar       Extend selection to previous character.
       
   714     \value SelectPreviousLine       Extend selection to previous line.
       
   715     \value SelectPreviousPage       Extend selection to previous page.
       
   716     \value SelectPreviousWord       Extend selection to previous word.
       
   717     \value SelectStartOfBlock       Extend selection to the start of a text block. This shortcut is only used on OS X.
       
   718     \value SelectStartOfDocument    Extend selection to start of document. 
       
   719     \value SelectStartOfLine        Extend selection to start of line.
       
   720     \value Underline        Underline text.
       
   721     \value Undo             Undo.
       
   722     \value UnknownKey       Unbound key.
       
   723     \value WhatsThis        Activate whats this.
       
   724     \value ZoomIn           Zoom in.
       
   725     \value ZoomOut          Zoom out.
       
   726 */
       
   727 
       
   728 /*!
       
   729     \since 4.2
       
   730 
       
   731     Constructs a QKeySequence object for the given \a key. 
       
   732     The result will depend on the currently running platform. 
       
   733 
       
   734     The resulting object will be based on the first element in the 
       
   735     list of key bindings for the \a key.
       
   736 */
       
   737 QKeySequence::QKeySequence(StandardKey key)
       
   738 {
       
   739     const QList <QKeySequence> bindings = keyBindings(key);
       
   740     //pick only the first/primary shortcut from current bindings
       
   741     if (bindings.size() > 0) {
       
   742         d = bindings.first().d; 
       
   743         d->ref.ref();
       
   744     }
       
   745     else
       
   746         d = new QKeySequencePrivate();
       
   747 }
       
   748 
       
   749 
       
   750 /*!
       
   751     Constructs an empty key sequence.
       
   752 */
       
   753 QKeySequence::QKeySequence()
       
   754 {
       
   755     static QKeySequencePrivate shared_empty;
       
   756     d = &shared_empty;
       
   757     d->ref.ref();
       
   758 }
       
   759 
       
   760 /*!
       
   761     Creates a key sequence from the \a key string. For example
       
   762     "Ctrl+O" gives CTRL+'O'. The strings "Ctrl",
       
   763     "Shift", "Alt" and "Meta" are recognized, as well as their
       
   764     translated equivalents in the "QShortcut" context (using
       
   765     QObject::tr()).
       
   766 
       
   767     Up to four key codes may be entered by separating them with
       
   768     commas, e.g. "Alt+X,Ctrl+S,Q".
       
   769 
       
   770     This constructor is typically used with \link QObject::tr() tr
       
   771     \endlink(), so that shortcut keys can be replaced in
       
   772     translations:
       
   773 
       
   774     \snippet doc/src/snippets/code/src_gui_kernel_qkeysequence.cpp 2
       
   775 
       
   776     Note the "File|Open" translator comment. It is by no means
       
   777     necessary, but it provides some context for the human translator.
       
   778 */
       
   779 QKeySequence::QKeySequence(const QString &key)
       
   780 {
       
   781     d = new QKeySequencePrivate();
       
   782     assign(key);
       
   783 }
       
   784 
       
   785 /*!
       
   786     Constructs a key sequence with up to 4 keys \a k1, \a k2,
       
   787     \a k3 and \a k4.
       
   788 
       
   789     The key codes are listed in Qt::Key and can be combined with
       
   790     modifiers (see Qt::Modifier) such as Qt::SHIFT, Qt::CTRL,
       
   791     Qt::ALT, or Qt::META.
       
   792 */
       
   793 QKeySequence::QKeySequence(int k1, int k2, int k3, int k4)
       
   794 {
       
   795     d = new QKeySequencePrivate();
       
   796     d->key[0] = k1;
       
   797     d->key[1] = k2;
       
   798     d->key[2] = k3;
       
   799     d->key[3] = k4;
       
   800 }
       
   801 
       
   802 /*!
       
   803     Copy constructor. Makes a copy of \a keysequence.
       
   804  */
       
   805 QKeySequence::QKeySequence(const QKeySequence& keysequence)
       
   806     : d(keysequence.d)
       
   807 {
       
   808     d->ref.ref();
       
   809 }
       
   810 
       
   811 #ifdef Q_WS_MAC
       
   812 static inline int maybeSwapShortcut(int shortcut)
       
   813 {
       
   814     if (qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)) {
       
   815         uint oldshortcut = shortcut;
       
   816         shortcut &= ~(Qt::CTRL | Qt::META);
       
   817         if (oldshortcut & Qt::CTRL)
       
   818             shortcut |= Qt::META;
       
   819         if (oldshortcut & Qt::META)
       
   820             shortcut |= Qt::CTRL;
       
   821     }
       
   822     return shortcut;
       
   823 }
       
   824 #endif
       
   825 
       
   826 /*!
       
   827     \since 4.2
       
   828 
       
   829     Returns a list of key bindings for the given \a key.
       
   830     The result of calling this function will vary based on the target platform. 
       
   831     The first element of the list indicates the primary shortcut for the given platform. 
       
   832     If the result contains more than one result, these can
       
   833     be considered alternative shortcuts on the same platform for the given \a key.
       
   834 */
       
   835 QList<QKeySequence> QKeySequence::keyBindings(StandardKey key)
       
   836 {
       
   837     uint platform = QApplicationPrivate::currentPlatform();
       
   838     QList <QKeySequence> list;
       
   839     for (uint i = 0; i < QKeySequencePrivate::numberOfKeyBindings ; ++i) {
       
   840         QKeyBinding keyBinding = QKeySequencePrivate::keyBindings[i];
       
   841         if (keyBinding.standardKey == key && (keyBinding.platform & platform)) {
       
   842             uint shortcut =
       
   843 #ifdef Q_WS_MAC
       
   844                     maybeSwapShortcut(QKeySequencePrivate::keyBindings[i].shortcut);
       
   845 #else
       
   846                     QKeySequencePrivate::keyBindings[i].shortcut;
       
   847 #endif
       
   848             if (keyBinding.priority > 0)
       
   849                 list.prepend(QKeySequence(shortcut));
       
   850             else
       
   851                 list.append(QKeySequence(shortcut));
       
   852         }
       
   853     }
       
   854     return list;
       
   855 }
       
   856 
       
   857 /*!
       
   858     Destroys the key sequence.
       
   859  */
       
   860 QKeySequence::~QKeySequence()
       
   861 {
       
   862     if (!d->ref.deref())
       
   863         delete d;
       
   864 }
       
   865 
       
   866 /*!
       
   867     \internal
       
   868     KeySequences should never be modified, but rather just created.
       
   869     Internally though we do need to modify to keep pace in event
       
   870     delivery.
       
   871 */
       
   872 
       
   873 void QKeySequence::setKey(int key, int index)
       
   874 {
       
   875     Q_ASSERT_X(index >= 0 && index < 4, "QKeySequence::setKey", "index out of range");
       
   876     qAtomicDetach(d);
       
   877     d->key[index] = key;
       
   878 }
       
   879 
       
   880 /*!
       
   881     Returns the number of keys in the key sequence.
       
   882     The maximum is 4.
       
   883  */
       
   884 uint QKeySequence::count() const
       
   885 {
       
   886     if (!d->key[0])
       
   887         return 0;
       
   888     if (!d->key[1])
       
   889         return 1;
       
   890     if (!d->key[2])
       
   891         return 2;
       
   892     if (!d->key[3])
       
   893         return 3;
       
   894     return 4;
       
   895 }
       
   896 
       
   897 
       
   898 /*!
       
   899     Returns true if the key sequence is empty; otherwise returns
       
   900     false.
       
   901 */
       
   902 bool QKeySequence::isEmpty() const
       
   903 {
       
   904     return !d->key[0];
       
   905 }
       
   906 
       
   907 
       
   908 /*!
       
   909     Returns the shortcut key sequence for the mnemonic in \a text,
       
   910     or an empty key sequence if no mnemonics are found.
       
   911 
       
   912     For example, mnemonic("E&xit") returns \c{Qt::ALT+Qt::Key_X},
       
   913     mnemonic("&Quit") returns \c{ALT+Key_Q}, and mnemonic("Quit")
       
   914     returns an empty QKeySequence.
       
   915 
       
   916     We provide a \l{accelerators.html}{list of common mnemonics}
       
   917     in English. At the time of writing, Microsoft and Open Group do
       
   918     not appear to have issued equivalent recommendations for other
       
   919     languages.
       
   920 
       
   921     \sa qt_set_sequence_auto_mnemonic()
       
   922 */
       
   923 QKeySequence QKeySequence::mnemonic(const QString &text)
       
   924 {
       
   925     if(qt_sequence_no_mnemonics)
       
   926 	return QKeySequence();
       
   927 
       
   928     int p = 0;
       
   929     while (p >= 0) {
       
   930         p = text.indexOf(QLatin1Char('&'), p) + 1;
       
   931         if (p <= 0 || p >= (int)text.length())
       
   932             break;
       
   933         if (text.at(p) != QLatin1Char('&')) {
       
   934             QChar c = text.at(p);
       
   935             if (c.isPrint()) {
       
   936                 c = c.toUpper();
       
   937                 return QKeySequence(c.unicode() + Qt::ALT);
       
   938             }
       
   939         }
       
   940         p++;
       
   941     }
       
   942     return QKeySequence();
       
   943 }
       
   944 
       
   945 /*!
       
   946     \fn int QKeySequence::assign(const QString &keys)
       
   947 
       
   948     Adds the given \a keys to the key sequence. \a keys may
       
   949     contain up to four key codes, provided they are separated by a
       
   950     comma; for example, "Alt+X,Ctrl+S,Z". The return value is the
       
   951     number of key codes added.
       
   952 */
       
   953 int QKeySequence::assign(const QString &ks)
       
   954 {
       
   955     QString keyseq = ks;
       
   956     QString part;
       
   957     int n = 0;
       
   958     int p = 0, diff = 0;
       
   959 
       
   960     // Run through the whole string, but stop
       
   961     // if we have 4 keys before the end.
       
   962     while (keyseq.length() && n < 4) {
       
   963         // We MUST use something to separate each sequence, and space
       
   964         // does not cut it, since some of the key names have space
       
   965         // in them.. (Let's hope no one translate with a comma in it:)
       
   966         p = keyseq.indexOf(QLatin1Char(','));
       
   967         if (-1 != p) {
       
   968             if (p == keyseq.count() - 1) { // Last comma 'Ctrl+,'
       
   969                 p = -1;
       
   970             } else {
       
   971                 if (QLatin1Char(',') == keyseq.at(p+1)) // e.g. 'Ctrl+,, Shift+,,'
       
   972                     p++;
       
   973                 if (QLatin1Char(' ') == keyseq.at(p+1)) { // Space after comma
       
   974                     diff = 1;
       
   975                     p++;
       
   976                 } else {
       
   977                     diff = 0;
       
   978                 }
       
   979             }
       
   980         }
       
   981         part = keyseq.left(-1 == p ? keyseq.length() : p - diff);
       
   982         keyseq = keyseq.right(-1 == p ? 0 : keyseq.length() - (p + 1));
       
   983         d->key[n] = decodeString(part);
       
   984         ++n;
       
   985     }
       
   986     return n;
       
   987 }
       
   988 
       
   989 struct QModifKeyName {
       
   990     QModifKeyName() { }
       
   991     QModifKeyName(int q, QChar n) : qt_key(q), name(n) { }
       
   992     QModifKeyName(int q, const QString &n) : qt_key(q), name(n) { }
       
   993     int qt_key;
       
   994     QString name;
       
   995 };
       
   996 
       
   997 Q_GLOBAL_STATIC(QList<QModifKeyName>, globalModifs)
       
   998 Q_GLOBAL_STATIC(QList<QModifKeyName>, globalPortableModifs)
       
   999 
       
  1000 /*!
       
  1001   Constructs a single key from the string \a str.
       
  1002 */
       
  1003 int QKeySequence::decodeString(const QString &str)
       
  1004 {
       
  1005     return QKeySequencePrivate::decodeString(str, NativeText);
       
  1006 }
       
  1007 
       
  1008 int QKeySequencePrivate::decodeString(const QString &str, QKeySequence::SequenceFormat format)
       
  1009 {
       
  1010     int ret = 0;
       
  1011     QString accel = str.toLower();
       
  1012     bool nativeText = (format == QKeySequence::NativeText);
       
  1013 
       
  1014     QList<QModifKeyName> *gmodifs;
       
  1015     if (nativeText) {
       
  1016         gmodifs = globalModifs();
       
  1017         if (gmodifs->isEmpty()) {
       
  1018 #ifdef Q_WS_MAC
       
  1019             const bool dontSwap = qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta);
       
  1020             if (dontSwap)
       
  1021                 *gmodifs << QModifKeyName(Qt::META, QChar(kCommandUnicode));
       
  1022             else
       
  1023                 *gmodifs << QModifKeyName(Qt::CTRL, QChar(kCommandUnicode));
       
  1024             *gmodifs << QModifKeyName(Qt::ALT, QChar(kOptionUnicode));
       
  1025             if (dontSwap)
       
  1026                 *gmodifs << QModifKeyName(Qt::CTRL, QChar(kControlUnicode));
       
  1027             else
       
  1028                 *gmodifs << QModifKeyName(Qt::META, QChar(kControlUnicode));
       
  1029             *gmodifs << QModifKeyName(Qt::SHIFT, QChar(kShiftUnicode));
       
  1030 #endif
       
  1031             *gmodifs << QModifKeyName(Qt::CTRL, QLatin1String("ctrl+"))
       
  1032                      << QModifKeyName(Qt::SHIFT, QLatin1String("shift+"))
       
  1033                      << QModifKeyName(Qt::ALT, QLatin1String("alt+"))
       
  1034                      << QModifKeyName(Qt::META, QLatin1String("meta+"));
       
  1035         }
       
  1036     } else {
       
  1037         gmodifs = globalPortableModifs();
       
  1038         if (gmodifs->isEmpty()) {
       
  1039             *gmodifs << QModifKeyName(Qt::CTRL, QLatin1String("ctrl+"))
       
  1040                      << QModifKeyName(Qt::SHIFT, QLatin1String("shift+"))
       
  1041                      << QModifKeyName(Qt::ALT, QLatin1String("alt+"))
       
  1042                      << QModifKeyName(Qt::META, QLatin1String("meta+"));
       
  1043         }
       
  1044     }
       
  1045     if (!gmodifs) return ret;
       
  1046 
       
  1047 
       
  1048     QList<QModifKeyName> modifs;
       
  1049     if (nativeText) {
       
  1050         modifs << QModifKeyName(Qt::CTRL, QShortcut::tr("Ctrl").toLower().append(QLatin1Char('+')))
       
  1051                << QModifKeyName(Qt::SHIFT, QShortcut::tr("Shift").toLower().append(QLatin1Char('+')))
       
  1052                << QModifKeyName(Qt::ALT, QShortcut::tr("Alt").toLower().append(QLatin1Char('+')))
       
  1053                << QModifKeyName(Qt::META, QShortcut::tr("Meta").toLower().append(QLatin1Char('+')));
       
  1054     }
       
  1055     modifs += *gmodifs; // Test non-translated ones last
       
  1056 
       
  1057     QString sl = accel;
       
  1058 #ifdef Q_WS_MAC
       
  1059     for (int i = 0; i < modifs.size(); ++i) {
       
  1060         const QModifKeyName &mkf = modifs.at(i);
       
  1061         if (sl.contains(mkf.name)) {
       
  1062             ret |= mkf.qt_key;
       
  1063             accel.remove(mkf.name);
       
  1064             sl = accel;
       
  1065         }
       
  1066     }
       
  1067 #else
       
  1068     int i = 0;
       
  1069     int lastI = 0;
       
  1070     while ((i = sl.indexOf(QLatin1Char('+'), i + 1)) != -1) {
       
  1071         const QString sub = sl.mid(lastI, i - lastI + 1);
       
  1072         // Just shortcut the check here if we only have one character.
       
  1073         // Rational: A modifier will contain the name AND +, so longer than 1, a length of 1 is just
       
  1074         // the remaining part of the shortcut (ei. The 'C' in "Ctrl+C"), so no need to check that.
       
  1075         if (sub.length() > 1) {
       
  1076             for (int j = 0; j < modifs.size(); ++j) {
       
  1077                 const QModifKeyName &mkf = modifs.at(j);
       
  1078                 if (sub == mkf.name) {
       
  1079                     ret |= mkf.qt_key;
       
  1080                     break; // Shortcut, since if we find an other it would/should just be a dup
       
  1081                 }
       
  1082             }
       
  1083         }
       
  1084         lastI = i + 1;
       
  1085     }
       
  1086 #endif
       
  1087 
       
  1088     int p = accel.lastIndexOf(QLatin1Char('+'), str.length() - 2); // -2 so that Ctrl++ works
       
  1089     if(p > 0)
       
  1090         accel = accel.mid(p + 1);
       
  1091 
       
  1092     int fnum = 0;
       
  1093     if (accel.length() == 1) {
       
  1094 #ifdef Q_WS_MAC
       
  1095         int qtKey = qtkeyForMacSymbol(accel[0]);
       
  1096         if (qtKey != -1) {
       
  1097             ret |= qtKey;
       
  1098         } else
       
  1099 #endif
       
  1100         {
       
  1101             ret |= accel[0].toUpper().unicode();
       
  1102         }
       
  1103     } else if (accel[0] == QLatin1Char('f') && (fnum = accel.mid(1).toInt()) && (fnum >= 1) && (fnum <= 35)) {
       
  1104         ret |= Qt::Key_F1 + fnum - 1;
       
  1105     } else {
       
  1106         // For NativeText, check the traslation table first,
       
  1107         // if we don't find anything then try it out with just the untranlated stuff.
       
  1108         // PortableText will only try the untranlated table.
       
  1109         bool found = false;
       
  1110         for (int tran = 0; tran < 2; ++tran) {
       
  1111             if (!nativeText)
       
  1112                 ++tran;
       
  1113             for (int i = 0; keyname[i].name; ++i) {
       
  1114                 QString keyName(tran == 0
       
  1115                                 ? QShortcut::tr(keyname[i].name)
       
  1116                                 : QString::fromLatin1(keyname[i].name));
       
  1117                 if (accel == keyName.toLower()) {
       
  1118                     ret |= keyname[i].key;
       
  1119                     found = true;
       
  1120                     break;
       
  1121                 }
       
  1122             }
       
  1123             if (found)
       
  1124                 break;
       
  1125         }
       
  1126     }
       
  1127     return ret;
       
  1128 }
       
  1129 
       
  1130 /*!
       
  1131     Creates a shortcut string for \a key. For example,
       
  1132     Qt::CTRL+Qt::Key_O gives "Ctrl+O". The strings, "Ctrl", "Shift", etc. are
       
  1133     translated (using QObject::tr()) in the "QShortcut" context.
       
  1134  */
       
  1135 QString QKeySequence::encodeString(int key)
       
  1136 {
       
  1137     return QKeySequencePrivate::encodeString(key, NativeText);
       
  1138 }
       
  1139 
       
  1140 static inline void addKey(QString &str, const QString &theKey, QKeySequence::SequenceFormat format)
       
  1141 {
       
  1142     if (!str.isEmpty())
       
  1143         str += (format == QKeySequence::NativeText) ? QShortcut::tr("+")
       
  1144                                                     : QString::fromLatin1("+");
       
  1145     str += theKey;
       
  1146 }
       
  1147 
       
  1148 QString QKeySequencePrivate::encodeString(int key, QKeySequence::SequenceFormat format)
       
  1149 {
       
  1150     bool nativeText = (format == QKeySequence::NativeText);
       
  1151     QString s;
       
  1152 #if defined(Q_WS_MAC)
       
  1153     if (nativeText) {
       
  1154         // On Mac OS X the order (by default) is Meta, Alt, Shift, Control.
       
  1155         // If the AA_MacDontSwapCtrlAndMeta is enabled, then the order
       
  1156         // is Ctrl, Alt, Shift, Meta. The macSymbolForQtKey does this swap
       
  1157         // for us, which means that we have to adjust our order here.
       
  1158         // The upshot is a lot more infrastructure to keep the number of
       
  1159         // if tests down and the code relatively clean.
       
  1160         static const int ModifierOrder[] = { Qt::META, Qt::ALT, Qt::SHIFT, Qt::CTRL, 0 };
       
  1161         static const int QtKeyOrder[] = { Qt::Key_Meta, Qt::Key_Alt, Qt::Key_Shift, Qt::Key_Control, 0 };
       
  1162         static const int DontSwapModifierOrder[] = { Qt::CTRL, Qt::ALT, Qt::SHIFT, Qt::META, 0 };
       
  1163         static const int DontSwapQtKeyOrder[] = { Qt::Key_Control, Qt::Key_Alt, Qt::Key_Shift, Qt::Key_Meta, 0 };
       
  1164         const int *modifierOrder;
       
  1165         const int *qtkeyOrder;
       
  1166         if (qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)) {
       
  1167             modifierOrder = DontSwapModifierOrder;
       
  1168             qtkeyOrder = DontSwapQtKeyOrder;
       
  1169         } else {
       
  1170             modifierOrder = ModifierOrder;
       
  1171             qtkeyOrder = QtKeyOrder;
       
  1172         }
       
  1173 
       
  1174         for (int i = 0; modifierOrder[i] != 0; ++i) {
       
  1175             if (key & modifierOrder[i])
       
  1176                 s += qt_macSymbolForQtKey(qtkeyOrder[i]);
       
  1177         }
       
  1178     } else
       
  1179 #endif
       
  1180     {
       
  1181         // On other systems the order is Meta, Control, Alt, Shift
       
  1182         if ((key & Qt::META) == Qt::META)
       
  1183             s = nativeText ? QShortcut::tr("Meta") : QString::fromLatin1("Meta");
       
  1184         if ((key & Qt::CTRL) == Qt::CTRL)
       
  1185             addKey(s, nativeText ? QShortcut::tr("Ctrl") : QString::fromLatin1("Ctrl"), format);
       
  1186         if ((key & Qt::ALT) == Qt::ALT)
       
  1187             addKey(s, nativeText ? QShortcut::tr("Alt") : QString::fromLatin1("Alt"), format);
       
  1188         if ((key & Qt::SHIFT) == Qt::SHIFT)
       
  1189             addKey(s, nativeText ? QShortcut::tr("Shift") : QString::fromLatin1("Shift"), format);
       
  1190     }
       
  1191 
       
  1192 
       
  1193     key &= ~(Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier);
       
  1194     QString p;
       
  1195 
       
  1196     if (key && key < Qt::Key_Escape && key != Qt::Key_Space) {
       
  1197         if (key < 0x10000) {
       
  1198             p = QChar(key & 0xffff).toUpper();
       
  1199         } else {
       
  1200             p = QChar((key-0x10000)/0x400+0xd800);
       
  1201             p += QChar((key-0x10000)%400+0xdc00);
       
  1202         }
       
  1203     } else if (key >= Qt::Key_F1 && key <= Qt::Key_F35) {
       
  1204             p = nativeText ? QShortcut::tr("F%1").arg(key - Qt::Key_F1 + 1)
       
  1205                            : QString::fromLatin1("F%1").arg(key - Qt::Key_F1 + 1);
       
  1206     } else if (key) {
       
  1207         int i=0;
       
  1208 #if defined(Q_WS_MAC)
       
  1209         if (nativeText) {
       
  1210             QChar ch = qt_macSymbolForQtKey(key);
       
  1211             if (!ch.isNull())
       
  1212                 p = ch;
       
  1213             else
       
  1214                 goto NonSymbol;
       
  1215         } else
       
  1216 #endif
       
  1217         {
       
  1218 #ifdef Q_WS_MAC
       
  1219 NonSymbol:
       
  1220 #endif
       
  1221             while (keyname[i].name) {
       
  1222                 if (key == keyname[i].key) {
       
  1223                     p = nativeText ? QShortcut::tr(keyname[i].name)
       
  1224                                    : QString::fromLatin1(keyname[i].name);
       
  1225                     break;
       
  1226                 }
       
  1227                 ++i;
       
  1228             }
       
  1229             // If we can't find the actual translatable keyname,
       
  1230             // fall back on the unicode representation of it...
       
  1231             // Or else characters like Qt::Key_aring may not get displayed
       
  1232             // (Really depends on you locale)
       
  1233             if (!keyname[i].name) {
       
  1234                 if (key < 0x10000) {
       
  1235                     p = QChar(key & 0xffff).toUpper();
       
  1236                 } else {
       
  1237                     p = QChar((key-0x10000)/0x400+0xd800);
       
  1238                     p += QChar((key-0x10000)%400+0xdc00);
       
  1239                 }
       
  1240             }
       
  1241         }
       
  1242     }
       
  1243 
       
  1244 #ifdef Q_WS_MAC
       
  1245     if (nativeText)
       
  1246         s += p;
       
  1247     else
       
  1248 #endif
       
  1249     addKey(s, p, format);
       
  1250     return s;
       
  1251 }
       
  1252 /*!
       
  1253     Matches the sequence with \a seq. Returns ExactMatch if
       
  1254     successful, PartialMatch if \a seq matches incompletely,
       
  1255     and NoMatch if the sequences have nothing in common.
       
  1256     Returns NoMatch if \a seq is shorter.
       
  1257 */
       
  1258 QKeySequence::SequenceMatch QKeySequence::matches(const QKeySequence &seq) const
       
  1259 {
       
  1260     uint userN = count(),
       
  1261           seqN = seq.count();
       
  1262 
       
  1263     if (userN > seqN)
       
  1264         return NoMatch;
       
  1265 
       
  1266     // If equal in length, we have a potential ExactMatch sequence,
       
  1267     // else we already know it can only be partial.
       
  1268     SequenceMatch match = (userN == seqN ? ExactMatch : PartialMatch);
       
  1269 
       
  1270     for (uint i = 0; i < userN; ++i) {
       
  1271         int userKey = (*this)[i],
       
  1272             sequenceKey = seq[i];
       
  1273         if (userKey != sequenceKey)
       
  1274             return NoMatch;
       
  1275     }
       
  1276     return match;
       
  1277 }
       
  1278 
       
  1279 
       
  1280 /*!
       
  1281     \obsolete
       
  1282 
       
  1283     Use toString() instead. 
       
  1284     
       
  1285     Returns the key sequence as a QString. This is equivalent to 
       
  1286     calling toString(QKeySequence::NativeText). Note that the
       
  1287     result is not platform independent.
       
  1288 */
       
  1289 QKeySequence::operator QString() const
       
  1290 {
       
  1291     return QKeySequence::toString(QKeySequence::NativeText);
       
  1292 }
       
  1293 
       
  1294 /*!
       
  1295    Returns the key sequence as a QVariant
       
  1296 */
       
  1297 QKeySequence::operator QVariant() const
       
  1298 {
       
  1299     return QVariant(QVariant::KeySequence, this);
       
  1300 }
       
  1301 
       
  1302 /*!
       
  1303     \obsolete
       
  1304     For backward compatibility: returns the first keycode
       
  1305     as integer. If the key sequence is empty, 0 is returned.
       
  1306  */
       
  1307 QKeySequence::operator int () const
       
  1308 {
       
  1309     if (1 <= count())
       
  1310         return d->key[0];
       
  1311     return 0;
       
  1312 }
       
  1313 
       
  1314 
       
  1315 /*!
       
  1316     Returns a reference to the element at position \a index in the key
       
  1317     sequence. This can only be used to read an element.
       
  1318  */
       
  1319 int QKeySequence::operator[](uint index) const
       
  1320 {
       
  1321     Q_ASSERT_X(index < 4, "QKeySequence::operator[]", "index out of range");
       
  1322     return d->key[index];
       
  1323 }
       
  1324 
       
  1325 
       
  1326 /*!
       
  1327     Assignment operator. Assigns the \a other key sequence to this
       
  1328     object.
       
  1329  */
       
  1330 QKeySequence &QKeySequence::operator=(const QKeySequence &other)
       
  1331 {
       
  1332     qAtomicAssign(d, other.d);
       
  1333     return *this;
       
  1334 }
       
  1335 
       
  1336 /*!
       
  1337     \fn bool QKeySequence::operator!=(const QKeySequence &other) const
       
  1338 
       
  1339     Returns true if this key sequence is not equal to the \a other
       
  1340     key sequence; otherwise returns false.
       
  1341 */
       
  1342 
       
  1343 
       
  1344 /*!
       
  1345     Returns true if this key sequence is equal to the \a other
       
  1346     key sequence; otherwise returns false.
       
  1347  */
       
  1348 bool QKeySequence::operator==(const QKeySequence &other) const
       
  1349 {
       
  1350     return (d->key[0] == other.d->key[0] &&
       
  1351             d->key[1] == other.d->key[1] &&
       
  1352             d->key[2] == other.d->key[2] &&
       
  1353             d->key[3] == other.d->key[3]);
       
  1354 }
       
  1355 
       
  1356 
       
  1357 /*!
       
  1358     Provides an arbitrary comparison of this key sequence and
       
  1359     \a other key sequence. All that is guaranteed is that the
       
  1360     operator returns false if both key sequences are equal and
       
  1361     that (ks1 \< ks2) == !( ks2 \< ks1) if the key sequences
       
  1362     are not equal.
       
  1363 
       
  1364     This function is useful in some circumstances, for example
       
  1365     if you want to use QKeySequence objects as keys in a QMap.
       
  1366 
       
  1367     \sa operator==() operator!=() operator>() operator<=() operator>=()
       
  1368 */
       
  1369 bool QKeySequence::operator< (const QKeySequence &other) const
       
  1370 {
       
  1371     for (int i = 0; i < 4; ++i)
       
  1372         if (d->key[i] != other.d->key[i])
       
  1373             return d->key[i] < other.d->key[i];
       
  1374     return false;
       
  1375 }
       
  1376 
       
  1377 /*!
       
  1378     \fn bool QKeySequence::operator> (const QKeySequence &other) const
       
  1379 
       
  1380     Returns true if this key sequence is larger than the \a other key
       
  1381     sequence; otherwise returns false.
       
  1382 
       
  1383     \sa operator==() operator!=() operator<() operator<=() operator>=()
       
  1384 */
       
  1385 
       
  1386 /*!
       
  1387     \fn bool QKeySequence::operator<= (const QKeySequence &other) const
       
  1388 
       
  1389     Returns true if this key sequence is smaller or equal to the
       
  1390     \a other key sequence; otherwise returns false.
       
  1391 
       
  1392     \sa operator==() operator!=() operator<() operator>() operator>=()
       
  1393 */
       
  1394 
       
  1395 /*!
       
  1396     \fn bool QKeySequence::operator>= (const QKeySequence &other) const
       
  1397 
       
  1398     Returns true if this key sequence is larger or equal to the
       
  1399     \a other key sequence; otherwise returns false.
       
  1400 
       
  1401     \sa operator==() operator!=() operator<() operator>() operator<=()
       
  1402 */
       
  1403 
       
  1404 /*!
       
  1405     \internal
       
  1406 */
       
  1407 bool QKeySequence::isDetached() const
       
  1408 {
       
  1409     return d->ref == 1;
       
  1410 }
       
  1411 
       
  1412 /*!
       
  1413     \since 4.1
       
  1414 
       
  1415     Return a string representation of the key sequence,
       
  1416     based on \a format.
       
  1417 
       
  1418     For example, the value Qt::CTRL+Qt::Key_O results in "Ctrl+O".
       
  1419     If the key sequence has multiple key codes, each is separated
       
  1420     by commas in the string returned, such as "Alt+X, Ctrl+Y, Z".
       
  1421     The strings, "Ctrl", "Shift", etc. are translated using
       
  1422     QObject::tr() in the "QShortcut" context.
       
  1423 
       
  1424     If the key sequence has no keys, an empty string is returned.
       
  1425 
       
  1426     On Mac OS X, the string returned resembles the sequence that is
       
  1427     shown in the menu bar.
       
  1428 
       
  1429     \sa fromString()
       
  1430 */
       
  1431 QString QKeySequence::toString(SequenceFormat format) const
       
  1432 {
       
  1433     QString finalString;
       
  1434     // A standard string, with no translation or anything like that. In some ways it will
       
  1435     // look like our latin case on Windows and X11
       
  1436     int end = count();
       
  1437     for (int i = 0; i < end; ++i) {
       
  1438         finalString += d->encodeString(d->key[i], format);
       
  1439         finalString += QLatin1String(", ");
       
  1440     }
       
  1441     finalString.truncate(finalString.length() - 2);
       
  1442     return finalString;
       
  1443 }
       
  1444 
       
  1445 /*!
       
  1446     \since 4.1
       
  1447 
       
  1448     Return a QKeySequence from the string \a str based on \a format.
       
  1449 
       
  1450     \sa toString()
       
  1451 */
       
  1452 QKeySequence QKeySequence::fromString(const QString &str, SequenceFormat format)
       
  1453 {
       
  1454     QStringList sl = str.split(QLatin1String(", "));
       
  1455     int keys[4] = {0, 0, 0, 0};
       
  1456     int total = qMin(sl.count(), 4);
       
  1457     for (int i = 0; i < total; ++i)
       
  1458         keys[i] = QKeySequencePrivate::decodeString(sl[i], format);
       
  1459     return QKeySequence(keys[0], keys[1], keys[2], keys[3]);
       
  1460 }
       
  1461 
       
  1462 /*****************************************************************************
       
  1463   QKeySequence stream functions
       
  1464  *****************************************************************************/
       
  1465 #if !defined(QT_NO_DATASTREAM)
       
  1466 /*!
       
  1467     \fn QDataStream &operator<<(QDataStream &stream, const QKeySequence &sequence)
       
  1468     \relates QKeySequence
       
  1469 
       
  1470     Writes the key \a sequence to the \a stream.
       
  1471 
       
  1472     \sa \link datastreamformat.html Format of the QDataStream operators \endlink
       
  1473 */
       
  1474 QDataStream &operator<<(QDataStream &s, const QKeySequence &keysequence)
       
  1475 {
       
  1476     QList<quint32> list;
       
  1477     list << keysequence.d->key[0];
       
  1478 
       
  1479     if (s.version() >= 5 && keysequence.count() > 1) {
       
  1480         list << keysequence.d->key[1];
       
  1481         list << keysequence.d->key[2];
       
  1482         list << keysequence.d->key[3];
       
  1483     }
       
  1484     s << list;
       
  1485     return s;
       
  1486 }
       
  1487 
       
  1488 
       
  1489 /*!
       
  1490     \fn QDataStream &operator>>(QDataStream &stream, QKeySequence &sequence)
       
  1491     \relates QKeySequence
       
  1492 
       
  1493     Reads a key sequence from the \a stream into the key \a sequence.
       
  1494 
       
  1495     \sa \link datastreamformat.html Format of the QDataStream operators \endlink
       
  1496 */
       
  1497 QDataStream &operator>>(QDataStream &s, QKeySequence &keysequence)
       
  1498 {
       
  1499 	qAtomicDetach(keysequence.d);
       
  1500     QList<quint32> list;
       
  1501     s >> list;
       
  1502     for (int i = 0; i < 4; ++i)
       
  1503         keysequence.d->key[i] = list.value(i);
       
  1504     return s;
       
  1505 }
       
  1506 
       
  1507 #endif //QT_NO_DATASTREAM
       
  1508 
       
  1509 #ifndef QT_NO_DEBUG_STREAM
       
  1510 QDebug operator<<(QDebug dbg, const QKeySequence &p)
       
  1511 {
       
  1512 #ifndef Q_BROKEN_DEBUG_STREAM
       
  1513     dbg.nospace() << "QKeySequence(" << p.toString() << ')';
       
  1514     return dbg.space();
       
  1515 #else
       
  1516     qWarning("This compiler doesn't support streaming QKeySequence to QDebug");
       
  1517     return dbg;
       
  1518     Q_UNUSED(p);
       
  1519 #endif
       
  1520 }
       
  1521 #endif
       
  1522 
       
  1523 #endif // QT_NO_SHORTCUT
       
  1524 
       
  1525 
       
  1526 /*!
       
  1527     \typedef QKeySequence::DataPtr
       
  1528     \internal
       
  1529 */
       
  1530 
       
  1531  /*!
       
  1532     \fn DataPtr &QKeySequence::data_ptr()
       
  1533     \internal
       
  1534 */
       
  1535 
       
  1536 QT_END_NAMESPACE