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

Last change on this file since 67 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

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