source: trunk/src/gui/kernel/qkeysequence.cpp@ 677

Last change on this file since 677 was 651, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.2 sources.

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