1
/****************************************************************************
3
** Copyright (C) 1992-2005 Trolltech AS. All rights reserved.
5
** This file is part of the Qt 3 compatibility classes of the Qt Toolkit.
7
** This file may be distributed under the terms of the Q Public License
8
** as defined by Trolltech AS of Norway and appearing in the file
9
** LICENSE.QPL included in the packaging of this file.
11
** This file may be distributed and/or modified under the terms of the
12
** GNU General Public License version 2 as published by the Free Software
13
** Foundation and appearing in the file LICENSE.GPL included in the
14
** packaging of this file.
16
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
17
** information about Qt Commercial License Agreements.
18
** See http://www.trolltech.com/qpl/ for QPL licensing information.
19
** See http://www.trolltech.com/gpl/ for GPL licensing information.
21
** Contact info@trolltech.com if any conditions of this licensing are
24
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
25
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27
****************************************************************************/
32
#include "qapplication.h"
34
#include "q3ptrlist.h"
35
#include "qwhatsthis.h"
37
#include "qstatusbar.h"
38
#include "qdockwidget.h"
40
#include "qkeysequence.h"
41
#include "private/qapplication_p.h"
46
\brief The Q3Accel class handles keyboard accelerator and shortcut keys.
50
A keyboard accelerator triggers an action when a certain key
51
combination is pressed. The accelerator handles all keyboard
52
activity for all the children of one top-level widget, so it is
53
not affected by the keyboard focus.
55
In most cases, you will not need to use this class directly. Use
56
the QAction class to create actions with accelerators that can be
57
used in both menus and toolbars. If you're only interested in
58
menus use Q3MenuData::insertItem() or Q3MenuData::setAccel() to make
59
accelerators for operations that are also available on menus. Many
60
widgets automatically generate accelerators, such as QAbstractButton,
61
QGroupBox, QLabel (with QLabel::setBuddy()), QMenuBar, and QTabBar.
64
QPushButton p("&Exit", parent); // automatic shortcut ALT+Key_E
65
Q3PopupMenu *fileMenu = new fileMenu(parent);
66
fileMenu->insertItem("Undo", parent, SLOT(undo()), CTRL+Key_Z);
69
A Q3Accel contains a list of accelerator items that can be
70
manipulated using insertItem(), removeItem(), clear(), key() and
73
Each accelerator item consists of an identifier and a \l
74
QKeySequence. A single key sequence consists of a keyboard code
75
combined with modifiers (\c SHIFT, \c CTRL, \c ALT or \c
76
UNICODE_ACCEL). For example, \c{CTRL + Key_P} could be a shortcut
77
for printing a document. The key codes are listed in \c
78
qnamespace.h. As an alternative, use \c UNICODE_ACCEL with the
79
unicode code point of the character. For example, \c{UNICODE_ACCEL
80
+ 'A'} gives the same accelerator as \c Key_A.
82
When an accelerator key is pressed, the accelerator sends out the
83
signal activated() with a number that identifies this particular
84
accelerator item. Accelerator items can also be individually
85
connected, so that two different keys will activate two different
86
slots (see connectItem() and disconnectItem()).
88
The activated() signal is \e not emitted when two or more
89
accelerators match the same key. Instead, the first matching
90
accelerator sends out the activatedAmbiguously() signal. By
91
pressing the key multiple times, users can navigate between all
92
matching accelerators. Some standard controls like QPushButton and
93
QCheckBox connect the activatedAmbiguously() signal to the
94
harmless setFocus() slot, whereas activated() is connected to a
95
slot invoking the button's action. Most controls, like QLabel and
96
QTabBar, treat activated() and activatedAmbiguously() as
99
Use setEnabled() to enable or disable all the items in an
100
accelerator, or setItemEnabled() to enable or disable individual
101
items. An item is active only when both the Q3Accel and the item
104
The function setWhatsThis() specifies a help text that appears
105
when the user presses an accelerator key in What's This mode.
107
The accelerator will be deleted when \e parent is deleted,
108
and will consume relevant key events until then.
110
Please note that the accelerator
112
accelerator->insertItem(QKeySequence("M"));
114
can be triggered with both the 'M' key, and with Shift+M,
115
unless a second accelerator is defined for the Shift+M
121
Q3Accel *a = new Q3Accel(myWindow); // create accels for myWindow
122
a->connectItem(a->insertItem(Key_P+CTRL), // adds Ctrl+P accelerator
123
myWindow, // connected to myWindow's
124
SLOT(printDoc())); // printDoc() slot
127
\sa QKeyEvent QWidget::keyPressEvent()
128
QAbstractButton::setAccel() QLabel::setBuddy() QKeySequence
132
struct Q3AccelItem { // internal accelerator item
133
Q3AccelItem(const QKeySequence &k, int i)
134
{ key=k; id=i; enabled=true; signal=0; }
135
~Q3AccelItem() { delete signal; }
144
typedef Q3PtrList<Q3AccelItem> Q3AccelList; // internal accelerator list
146
class Q3AccelPrivate {
148
Q3AccelPrivate(Q3Accel* p);
152
QPointer<QWidget> watch;
153
bool ignorewhatsthis;
156
void activate(Q3AccelItem* item);
157
void activateAmbiguously(Q3AccelItem* item);
160
class Q3AccelManager {
162
static Q3AccelManager* self() { return self_ptr ? self_ptr : new Q3AccelManager; }
163
void registerAccel(Q3AccelPrivate* a) { accels.append(a); }
164
void unregisterAccel(Q3AccelPrivate* a) { accels.removeRef(a); if (accels.isEmpty()) delete this; }
165
bool tryAccelEvent(QWidget* w, QKeyEvent* e);
166
bool dispatchAccelEvent(QWidget* w, QKeyEvent* e);
167
bool tryComposeUnicode(QWidget* w, QKeyEvent* e);
171
: currentState(QKeySequence::NoMatch), clash(-1), metaComposeUnicode(false),composedUnicode(0)
172
{ setFuncPtr(); self_ptr = this; }
173
~Q3AccelManager() { self_ptr = 0; }
176
bool correctSubWindow(QWidget *w, Q3AccelPrivate* d);
177
QKeySequence::SequenceMatch match(QKeyEvent* e, Q3AccelItem* item, QKeySequence& temp);
178
int translateModifiers(ButtonState state);
180
Q3PtrList<Q3AccelPrivate> accels;
181
static Q3AccelManager* self_ptr;
182
QKeySequence::SequenceMatch currentState;
183
QKeySequence intermediate;
185
bool metaComposeUnicode;
188
Q3AccelManager* Q3AccelManager::self_ptr = 0;
190
bool Q_COMPAT_EXPORT qt_tryAccelEvent(QWidget* w, QKeyEvent* e){
191
return Q3AccelManager::self()->tryAccelEvent(w, e);
194
bool Q_COMPAT_EXPORT qt_dispatchAccelEvent(QWidget* w, QKeyEvent* e){
195
return Q3AccelManager::self()->dispatchAccelEvent(w, e);
198
bool Q_COMPAT_EXPORT qt_tryComposeUnicode(QWidget* w, QKeyEvent* e){
199
return Q3AccelManager::self()->tryComposeUnicode(w, e);
202
void Q3AccelManager::setFuncPtr() {
203
if (qApp->d_func()->qt_compat_used)
205
QApplicationPrivate *data = static_cast<QApplicationPrivate*>(qApp->d_ptr);
206
data->qt_tryAccelEvent = qt_tryAccelEvent;
207
data->qt_tryComposeUnicode = qt_tryComposeUnicode;
208
data->qt_dispatchAccelEvent = qt_dispatchAccelEvent;
209
data->qt_compat_used = true;
213
static bool qt_accel_no_shortcuts = true;
215
static bool qt_accel_no_shortcuts = false;
217
void Q_COMPAT_EXPORT qt_set_accel_auto_shortcuts(bool b) { qt_accel_no_shortcuts = b; }
221
Returns true if the accel is in the current subwindow, else false.
223
bool Q3AccelManager::correctSubWindow(QWidget* w, Q3AccelPrivate* d) {
224
#if !defined (Q_OS_MACX)
225
if (!d->watch || !d->watch->isVisible() || !d->watch->isEnabled())
227
if (!d->watch || (!d->watch->isVisible() && !d->watch->inherits("QMenuBar")) || !d->watch->isEnabled())
230
QWidget* tlw = w->window();
231
QWidget* wtlw = d->watch->window();
233
/* if we live in a floating dock window, keep our parent's
234
* accelerators working */
235
#ifndef QT_NO_MAINWINDOW
236
if ((tlw->windowType() == Qt::Dialog) && tlw->parentWidget() && ::qobject_cast<QDockWidget*>(tlw))
237
return tlw->parentWidget()->window() == wtlw;
242
/* if we live in a MDI subwindow, ignore the event if we are
243
not the active document window */
244
QWidget* sw = d->watch;
245
while (sw && sw->windowType() != Qt::SubWindow)
246
sw = sw->parentWidget(true);
247
if (sw) { // we are in a subwindow indeed
249
while (fw && fw != sw)
250
fw = fw->parentWidget(true);
251
if (fw != sw) // focus widget not in our subwindow
257
inline int Q3AccelManager::translateModifiers(ButtonState state)
260
if (state & ShiftButton)
262
if (state & ControlButton)
264
if (state & MetaButton)
266
if (state & AltButton)
273
Matches the current intermediate key sequence + the latest
274
keyevent, with and AccelItem. Returns Identical,
275
PartialMatch or NoMatch, and fills \a temp with the
276
resulting key sequence.
278
QKeySequence::SequenceMatch Q3AccelManager::match(QKeyEvent *e, Q3AccelItem* item, QKeySequence& temp)
280
QKeySequence::SequenceMatch result = QKeySequence::NoMatch;
281
int index = intermediate.count();
284
int modifier = translateModifiers(e->state());
286
if (e->key() && e->key() != Key_unknown) {
287
int key = e->key() | modifier;
288
if (e->key() == Key_BackTab) {
290
In QApplication, we map shift+tab to shift+backtab.
291
This code here reverts the mapping in a way that keeps
292
backtab and shift+tab accelerators working, in that
293
order, meaning backtab has priority.*/
296
temp.setKey(key, index);
297
if (QKeySequence::NoMatch != (result = temp.matches(item->key)))
299
if (e->state() & ShiftButton)
301
key = Key_Tab | (key & MODIFIER_MASK);
302
temp.setKey(key, index);
303
if (QKeySequence::NoMatch != (result = temp.matches(item->key)))
306
temp.setKey(key, index);
307
if (QKeySequence::NoMatch != (result = temp.matches(item->key)))
311
if (key == Key_BackTab) {
312
if (e->state() & ShiftButton)
314
temp.setKey(key, index);
315
if (QKeySequence::NoMatch != (result = temp.matches(item->key)))
319
if (!e->text().isEmpty()) {
320
temp.setKey((int)e->text()[0].unicode() | UNICODE_ACCEL | modifier, index);
321
result = temp.matches(item->key);
326
bool Q3AccelManager::tryAccelEvent(QWidget* w, QKeyEvent* e)
328
if (QKeySequence::NoMatch == currentState) {
329
e->t = QEvent::AccelOverride;
331
QApplication::sendSpontaneousEvent(w, e);
335
e->t = QEvent::Accel;
337
QApplication::sendSpontaneousEvent(w, e);
338
return e->isAccepted();
341
bool Q3AccelManager::tryComposeUnicode(QWidget* w, QKeyEvent* e)
343
if (metaComposeUnicode) {
344
int value = e->key() - Key_0;
345
// Ignore acceloverrides so we don't trigger
346
// accels on keypad when Meta compose is on
347
if ((e->type() == QEvent::AccelOverride) &&
348
(e->state() == Qt::Keypad + Qt::MetaButton)) {
350
// Meta compose start/continue
351
} else if ((e->type() == QEvent::KeyPress) &&
352
(e->state() == Qt::Keypad + Qt::MetaButton)) {
353
if (value >= 0 && value <= 9) {
354
composedUnicode *= 10;
355
composedUnicode += value;
358
// Composing interrupted, dispatch!
359
if (composedUnicode) {
360
QChar ch(composedUnicode);
362
QKeyEvent kep(QEvent::KeyPress, 0, ch.row() ? 0 : ch.cell(), 0, s);
363
QKeyEvent ker(QEvent::KeyRelease, 0, ch.row() ? 0 : ch.cell(), 0, s);
364
QApplication::sendEvent(w, &kep);
365
QApplication::sendEvent(w, &ker);
370
// Meta compose end, dispatch
371
} else if ((e->type() == QEvent::KeyRelease) &&
372
(e->key() == Key_Meta) &&
373
(composedUnicode != 0)) {
374
if ((composedUnicode > 0) &&
375
(composedUnicode < 0xFFFE)) {
376
QChar ch(composedUnicode);
378
QKeyEvent kep(QEvent::KeyPress, 0, ch.row() ? 0 : ch.cell(), 0, s);
379
QKeyEvent ker(QEvent::KeyRelease, 0, ch.row() ? 0 : ch.cell(), 0, s);
380
QApplication::sendEvent(w, &kep);
381
QApplication::sendEvent(w, &ker);
392
Checks for possible accelerators, if no widget
393
ate the keypres, or we are in the middle of a
394
partial key sequence.
396
bool Q3AccelManager::dispatchAccelEvent(QWidget* w, QKeyEvent* e)
398
#ifndef QT_NO_STATUSBAR
399
// Needs to be declared and used here because of "goto doclash"
400
QStatusBar* mainStatusBar = 0;
403
// Modifiers can NOT be accelerators...
404
if (e->key() >= Key_Shift &&
408
QKeySequence::SequenceMatch result = QKeySequence::NoMatch;
409
QKeySequence tocheck, partial;
410
Q3AccelPrivate* accel = 0;
411
Q3AccelItem* item = 0;
412
Q3AccelPrivate* firstaccel = 0;
413
Q3AccelItem* firstitem = 0;
414
Q3AccelPrivate* lastaccel = 0;
415
Q3AccelItem* lastitem = 0;
419
int hasShift = (e->state()&Qt::ShiftButton)?1:0;
420
bool identicalDisabled = false;
421
bool matchFound = false;
423
accel = accels.first();
426
if (correctSubWindow(w, accel)) {
427
if (accel->enabled) {
428
item = accel->aitems.last();
430
if (QKeySequence::Identical == (result = match(&pe, item, tocheck))) {
440
if (n > QMAX(clash,0))
443
identicalDisabled = true;
446
if (item->enabled && QKeySequence::PartialMatch == result) {
450
item = accel->aitems.prev();
453
item = accel->aitems.last();
455
if (QKeySequence::Identical == match(&pe, item, tocheck))
456
identicalDisabled = true;
457
item = accel->aitems.prev();
461
accel = accels.next();
463
pe = QKeyEvent(QEvent::Accel, pe.key(), pe.ascii(), pe.state()&~Qt::ShiftButton, pe.text());
464
} while (hasShift-- && !matchFound && !identicalDisabled);
466
#ifndef QT_NO_STATUSBAR
467
mainStatusBar = (QStatusBar*) w->window()->child(0, "QStatusBar");
469
if (n < 0) { // no match found
470
currentState = partial.count() ? QKeySequence::PartialMatch : QKeySequence::NoMatch;
471
#ifndef QT_NO_STATUSBAR
472
// Only display message if we are, or were, in a partial match
473
if (mainStatusBar && (QKeySequence::PartialMatch == currentState || intermediate.count())) {
474
if (currentState == QKeySequence::PartialMatch) {
475
mainStatusBar->showMessage((QString)partial + ", ...");
476
} else if (!identicalDisabled) {
477
QString message = Q3Accel::tr("%1, %2 not defined").
478
arg((QString)intermediate).
479
arg(QKeySequence::encodeString(e->key() | translateModifiers(e->state())));
480
mainStatusBar->showMessage(message, 2000);
481
// Since we're a NoMatch, reset the clash count
484
mainStatusBar->clearMessage();
489
bool eatKey = (QKeySequence::PartialMatch == currentState || intermediate.count());
490
intermediate = partial;
494
} else if (n == 0) { // found exactly one match
496
#ifndef QT_NO_STATUSBAR
497
if (currentState == QKeySequence::PartialMatch && mainStatusBar)
498
mainStatusBar->clearMessage();
500
currentState = QKeySequence::NoMatch; // Free sequence keylock
501
intermediate = QKeySequence();
502
lastaccel->activate(lastitem);
507
doclash: // found more than one match
508
#ifndef QT_NO_STATUSBAR
509
if (!mainStatusBar) // if "goto doclash", we need to get statusbar again.
510
mainStatusBar = (QStatusBar*) w->window()->child(0, "QStatusBar");
513
QString message = Q3Accel::tr("Ambiguous \"%1\" not handled").arg((QString)tocheck);
514
if (clash >= 0 && n > clash) { // pick next match
515
intermediate = QKeySequence();
516
currentState = QKeySequence::NoMatch; // Free sequence keylock
518
#ifndef QT_NO_STATUSBAR
521
!(lastaccel->parent->receivers(SIGNAL(activatedAmbiguously(int)))))
522
mainStatusBar->showMessage(message, 2000);
524
lastaccel->activateAmbiguously(lastitem);
525
} else { // start (or wrap) with the first matching
526
intermediate = QKeySequence();
527
currentState = QKeySequence::NoMatch; // Free sequence keylock
529
#ifndef QT_NO_STATUSBAR
531
!firstitem->signal &&
532
!(firstaccel->parent->receivers(SIGNAL(activatedAmbiguously(int)))))
533
mainStatusBar->showMessage(message, 2000);
535
firstaccel->activateAmbiguously(firstitem);
541
Q3AccelPrivate::Q3AccelPrivate(Q3Accel* p)
544
Q3AccelManager::self()->registerAccel(this);
545
aitems.setAutoDelete(true);
546
ignorewhatsthis = false;
549
Q3AccelPrivate::~Q3AccelPrivate()
551
Q3AccelManager::self()->unregisterAccel(this);
554
static Q3AccelItem *find_id(Q3AccelList &list, int id)
556
register Q3AccelItem *item = list.first();
557
while (item && item->id != id)
562
static Q3AccelItem *find_key(Q3AccelList &list, const QKeySequence &key)
564
register Q3AccelItem *item = list.first();
565
while (item && !(item->key == key))
571
Constructs a Q3Accel object called \a name, with parent \a parent.
572
The accelerator operates on \a parent.
575
Q3Accel::Q3Accel(QWidget *parent, const char *name)
576
: QObject(parent, name)
578
d = new Q3AccelPrivate(this);
581
#if defined(QT_CHECK_NULL)
583
qWarning("Q3Accel: An accelerator must have a parent or a watch widget");
588
Constructs a Q3Accel object called \a name, that operates on \a
589
watch, and is a child of \a parent.
591
This constructor is not needed for normal application programming.
593
Q3Accel::Q3Accel(QWidget* watch, QObject *parent, const char *name)
594
: QObject(parent, name)
596
d = new Q3AccelPrivate(this);
599
#if defined(QT_CHECK_NULL)
601
qWarning("Q3Accel: An accelerator must have a parent or a watch widget");
606
Destroys the accelerator object and frees all allocated resources.
616
\fn void Q3Accel::activated(int id)
618
This signal is emitted when an accelerator key is pressed. \a id
619
is a number that identifies this particular accelerator item.
621
\sa activatedAmbiguously()
625
\fn void Q3Accel::activatedAmbiguously(int id)
627
This signal is emitted when an accelerator key is pressed. \a id
628
is a number that identifies this particular accelerator item.
635
Returns true if the accelerator is enabled; otherwise returns
638
\sa setEnabled(), isItemEnabled()
641
bool Q3Accel::isEnabled() const
648
Enables the accelerator if \a enable is true, or disables it if \a
651
Individual keys can also be enabled or disabled using
652
setItemEnabled(). To work, a key must be an enabled item in an
655
\sa isEnabled(), setItemEnabled()
658
void Q3Accel::setEnabled(bool enable)
665
Returns the number of accelerator items in this accelerator.
668
uint Q3Accel::count() const
670
return d->aitems.count();
674
static int get_seq_id()
676
static int seq_no = -2; // -1 is used as return value in findKey()
681
Inserts an accelerator item and returns the item's identifier.
683
\a key is a key code and an optional combination of SHIFT, CTRL
684
and ALT. \a id is the accelerator item id.
686
If \a id is negative, then the item will be assigned a unique
687
negative identifier less than -1.
690
Q3Accel *a = new Q3Accel(myWindow); // create accels for myWindow
691
a->insertItem(CTRL + Key_P, 200); // Ctrl+P, e.g. to print document
692
a->insertItem(ALT + Key_X, 201); // Alt+X, e.g. to quit
693
a->insertItem(UNICODE_ACCEL + 'q', 202); // Unicode 'q', e.g. to quit
694
a->insertItem(Key_D); // gets a unique negative id < -1
695
a->insertItem(CTRL + SHIFT + Key_P); // gets a unique negative id < -1
699
int Q3Accel::insertItem(const QKeySequence& key, int id)
703
d->aitems.insert(0, new Q3AccelItem(key,id));
708
Removes the accelerator item with the identifier \a id.
711
void Q3Accel::removeItem(int id)
713
if (find_id(d->aitems, id))
719
Removes all accelerator items.
722
void Q3Accel::clear()
729
Returns the key sequence of the accelerator item with identifier
730
\a id, or an invalid key sequence (0) if the id cannot be found.
733
QKeySequence Q3Accel::key(int id)
735
Q3AccelItem *item = find_id(d->aitems, id);
736
return item ? item->key : QKeySequence(0);
741
Returns the identifier of the accelerator item with the key code
742
\a key, or -1 if the item cannot be found.
745
int Q3Accel::findKey(const QKeySequence& key) const
747
Q3AccelItem *item = find_key(d->aitems, key);
748
return item ? item->id : -1;
753
Returns true if the accelerator item with the identifier \a id is
754
enabled. Returns false if the item is disabled or cannot be found.
756
\sa setItemEnabled(), isEnabled()
759
bool Q3Accel::isItemEnabled(int id) const
761
Q3AccelItem *item = find_id(d->aitems, id);
762
return item ? item->enabled : false;
767
Enables the accelerator item with the identifier \a id if \a
768
enable is true, and disables item \a id if \a enable is false.
770
To work, an item must be enabled and be in an enabled Q3Accel.
772
\sa isItemEnabled(), isEnabled()
775
void Q3Accel::setItemEnabled(int id, bool enable)
777
Q3AccelItem *item = find_id(d->aitems, id);
779
item->enabled = enable;
784
Connects the accelerator item \a id to the slot \a member of \a
788
a->connectItem(201, mainView, SLOT(quit()));
791
Of course, you can also send a signal as \a member.
793
Normally accelerators are connected to slots which then receive
794
the \c activated(int id) signal with the id of the accelerator
795
item that was activated. If you choose to connect a specific
796
accelerator item using this function, the \c activated() signal is
797
emitted if the associated key sequence is pressed but no \c
798
activated(int id) signal is emitted.
803
bool Q3Accel::connectItem(int id, const QObject *receiver, const char *member)
805
Q3AccelItem *item = find_id(d->aitems, id);
808
item->signal = new Q3Signal;
809
Q_CHECK_PTR(item->signal);
811
return item->signal->connect(receiver, member);
817
Disconnects an accelerator item with id \a id from the function
818
called \a member in the \a receiver object.
823
bool Q3Accel::disconnectItem(int id, const QObject *receiver,
826
Q3AccelItem *item = find_id(d->aitems, id);
827
if (item && item->signal)
828
return item->signal->disconnect(receiver, member);
832
void Q3AccelPrivate::activate(Q3AccelItem* item)
834
#ifndef QT_NO_WHATSTHIS
835
if (QWhatsThis::inWhatsThisMode() && !ignorewhatsthis) {
836
QWhatsThis::showText(QCursor::pos(), item->whatsthis);
841
item->signal->activate();
843
emit parent->activated(item->id);
846
void Q3AccelPrivate::activateAmbiguously(Q3AccelItem* item)
849
item->signal->activate();
851
emit parent->activatedAmbiguously(item->id);
856
Returns the shortcut key sequence for \a str, or an invalid key
857
sequence (0) if \a str has no shortcut sequence.
859
For example, shortcutKey("E&xit") returns ALT+Key_X,
860
shortcutKey("&Quit") returns ALT+Key_Q and shortcutKey("Quit")
861
returns 0. (In code that does not inherit the Qt namespace class,
862
you must write e.g. Qt::ALT+Qt::Key_Q.)
864
We provide a \link accelerators.html list of common accelerators
865
\endlink in English. At the time of writing, Microsoft and Open
866
Group do not appear to have issued equivalent recommendations for
870
QKeySequence Q3Accel::shortcutKey(const QString &str)
872
if(qt_accel_no_shortcuts)
873
return QKeySequence();
877
p = str.find('&', p) + 1;
878
if (p <= 0 || p >= (int)str.length())
883
char ltr = c.upper().latin1();
884
if (ltr >= (char)Key_A && ltr <= (char)Key_Z)
888
return QKeySequence(c.unicode() + ALT + UNICODE_ACCEL);
893
return QKeySequence();
898
Creates an accelerator string for the key \a k.
899
For instance CTRL+Key_O gives "Ctrl+O". The "Ctrl" etc.
900
are translated (using QObject::tr()) in the "Q3Accel" context.
902
The function is superfluous. Cast the QKeySequence \a k to a
903
QString for the same effect.
905
QString Q3Accel::keyToString(QKeySequence k)
912
Returns an accelerator code for the string \a s. For example
913
"Ctrl+O" gives CTRL+UNICODE_ACCEL+'O'. The strings "Ctrl",
914
"Shift", "Alt" are recognized, as well as their translated
915
equivalents in the "Q3Accel" context (using QObject::tr()). Returns 0
916
if \a s is not recognized.
918
This function is typically used with \link QObject::tr() tr
919
\endlink(), so that accelerator keys can be replaced in
923
Q3PopupMenu *file = new Q3PopupMenu(this);
924
file->insertItem(p1, tr("&Open..."), this, SLOT(open()),
925
Q3Accel::stringToKey(tr("Ctrl+O", "File|Open")));
928
Notice the \c "File|Open" translator comment. It is by no means
929
necessary, but it provides some context for the human translator.
931
The function is superfluous. Construct a QKeySequence from the
932
string \a s for the same effect.
934
\sa QObject::tr(), {Internationalization with Qt}
936
QKeySequence Q3Accel::stringToKey(const QString & s)
938
return QKeySequence(s);
943
Sets a What's This help text for the accelerator item \a id to \a
946
The text will be shown when the application is in What's This mode
947
and the user hits the accelerator key.
949
To set What's This help on a menu item (with or without an
950
accelerator key), use Q3MenuData::setWhatsThis().
952
\sa whatsThis(), QWhatsThis::inWhatsThisMode(), QAction::setWhatsThis()
954
void Q3Accel::setWhatsThis(int id, const QString& text)
956
Q3AccelItem *item = find_id(d->aitems, id);
958
item->whatsthis = text;
962
Returns the What's This help text for the specified item \a id or
963
an empty string if no text has been specified.
967
QString Q3Accel::whatsThis(int id) const
970
Q3AccelItem *item = find_id(d->aitems, id);
971
return item? item->whatsthis : QString();
975
void Q3Accel::setIgnoreWhatsThis(bool b)
977
d->ignorewhatsthis = b;
981
bool Q3Accel::ignoreWhatsThis() const
983
return d->ignorewhatsthis;
987
\fn void Q3Accel::repairEventFilter()