1 | /****************************************************************************
|
---|
2 | ** $Id: qaccel.cpp 2 2005-11-16 15:49:26Z dmik $
|
---|
3 | **
|
---|
4 | ** Implementation of QAccel class
|
---|
5 | **
|
---|
6 | ** Created : 950419
|
---|
7 | **
|
---|
8 | ** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
|
---|
9 | **
|
---|
10 | ** This file is part of the kernel module of the Qt GUI Toolkit.
|
---|
11 | **
|
---|
12 | ** This file may be distributed under the terms of the Q Public License
|
---|
13 | ** as defined by Trolltech AS of Norway and appearing in the file
|
---|
14 | ** LICENSE.QPL included in the packaging of this file.
|
---|
15 | **
|
---|
16 | ** This file may be distributed and/or modified under the terms of the
|
---|
17 | ** GNU General Public License version 2 as published by the Free Software
|
---|
18 | ** Foundation and appearing in the file LICENSE.GPL included in the
|
---|
19 | ** packaging of this file.
|
---|
20 | **
|
---|
21 | ** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
|
---|
22 | ** licenses may use this file in accordance with the Qt Commercial License
|
---|
23 | ** Agreement provided with the Software.
|
---|
24 | **
|
---|
25 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
---|
26 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
---|
27 | **
|
---|
28 | ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
|
---|
29 | ** information about Qt Commercial License Agreements.
|
---|
30 | ** See http://www.trolltech.com/qpl/ for QPL licensing information.
|
---|
31 | ** See http://www.trolltech.com/gpl/ for GPL licensing information.
|
---|
32 | **
|
---|
33 | ** Contact info@trolltech.com if any conditions of this licensing are
|
---|
34 | ** not clear to you.
|
---|
35 | **
|
---|
36 | **********************************************************************/
|
---|
37 |
|
---|
38 | #include "qaccel.h"
|
---|
39 |
|
---|
40 | #ifndef QT_NO_ACCEL
|
---|
41 |
|
---|
42 | #include "qsignal.h"
|
---|
43 | #include "qapplication.h"
|
---|
44 | #include "qwidget.h"
|
---|
45 | #include "qptrlist.h"
|
---|
46 | #include "qwhatsthis.h"
|
---|
47 | #include "qguardedptr.h"
|
---|
48 | #include "qstatusbar.h"
|
---|
49 | #include "qdockwindow.h"
|
---|
50 | #include "qsignalslotimp.h"
|
---|
51 | /*!
|
---|
52 | \class QAccel qaccel.h
|
---|
53 | \brief The QAccel class handles keyboard accelerator and shortcut keys.
|
---|
54 |
|
---|
55 | \ingroup misc
|
---|
56 |
|
---|
57 | A keyboard accelerator triggers an action when a certain key
|
---|
58 | combination is pressed. The accelerator handles all keyboard
|
---|
59 | activity for all the children of one top-level widget, so it is
|
---|
60 | not affected by the keyboard focus.
|
---|
61 |
|
---|
62 | In most cases, you will not need to use this class directly. Use
|
---|
63 | the QAction class to create actions with accelerators that can be
|
---|
64 | used in both menus and toolbars. If you're only interested in
|
---|
65 | menus use QMenuData::insertItem() or QMenuData::setAccel() to make
|
---|
66 | accelerators for operations that are also available on menus. Many
|
---|
67 | widgets automatically generate accelerators, such as QButton,
|
---|
68 | QGroupBox, QLabel (with QLabel::setBuddy()), QMenuBar and QTabBar.
|
---|
69 | Example:
|
---|
70 | \code
|
---|
71 | QPushButton p( "&Exit", parent ); // automatic shortcut ALT+Key_E
|
---|
72 | QPopupMenu *fileMenu = new fileMenu( parent );
|
---|
73 | fileMenu->insertItem( "Undo", parent, SLOT(undo()), CTRL+Key_Z );
|
---|
74 | \endcode
|
---|
75 |
|
---|
76 | A QAccel contains a list of accelerator items that can be
|
---|
77 | manipulated using insertItem(), removeItem(), clear(), key() and
|
---|
78 | findKey().
|
---|
79 |
|
---|
80 | Each accelerator item consists of an identifier and a \l
|
---|
81 | QKeySequence. A single key sequence consists of a keyboard code
|
---|
82 | combined with modifiers (\c SHIFT, \c CTRL, \c ALT or \c
|
---|
83 | UNICODE_ACCEL). For example, \c{CTRL + Key_P} could be a shortcut
|
---|
84 | for printing a document. The key codes are listed in \c
|
---|
85 | qnamespace.h. As an alternative, use \c UNICODE_ACCEL with the
|
---|
86 | unicode code point of the character. For example, \c{UNICODE_ACCEL
|
---|
87 | + 'A'} gives the same accelerator as \c Key_A.
|
---|
88 |
|
---|
89 | When an accelerator key is pressed, the accelerator sends out the
|
---|
90 | signal activated() with a number that identifies this particular
|
---|
91 | accelerator item. Accelerator items can also be individually
|
---|
92 | connected, so that two different keys will activate two different
|
---|
93 | slots (see connectItem() and disconnectItem()).
|
---|
94 |
|
---|
95 | The activated() signal is \e not emitted when two or more
|
---|
96 | accelerators match the same key. Instead, the first matching
|
---|
97 | accelerator sends out the activatedAmbiguously() signal. By
|
---|
98 | pressing the key multiple times, users can navigate between all
|
---|
99 | matching accelerators. Some standard controls like QPushButton and
|
---|
100 | QCheckBox connect the activatedAmbiguously() signal to the
|
---|
101 | harmless setFocus() slot, whereas activated() is connected to a
|
---|
102 | slot invoking the button's action. Most controls, like QLabel and
|
---|
103 | QTabBar, treat activated() and activatedAmbiguously() as
|
---|
104 | equivalent.
|
---|
105 |
|
---|
106 | Use setEnabled() to enable or disable all the items in an
|
---|
107 | accelerator, or setItemEnabled() to enable or disable individual
|
---|
108 | items. An item is active only when both the QAccel and the item
|
---|
109 | itself are enabled.
|
---|
110 |
|
---|
111 | The function setWhatsThis() specifies a help text that appears
|
---|
112 | when the user presses an accelerator key in What's This mode.
|
---|
113 |
|
---|
114 | The accelerator will be deleted when \e parent is deleted,
|
---|
115 | and will consume relevant key events until then.
|
---|
116 |
|
---|
117 | Please note that the accelerator
|
---|
118 | \code
|
---|
119 | accelerator->insertItem( QKeySequence("M") );
|
---|
120 | \endcode
|
---|
121 | can be triggered with both the 'M' key, and with Shift+M,
|
---|
122 | unless a second accelerator is defined for the Shift+M
|
---|
123 | combination.
|
---|
124 |
|
---|
125 |
|
---|
126 | Example:
|
---|
127 | \code
|
---|
128 | QAccel *a = new QAccel( myWindow ); // create accels for myWindow
|
---|
129 | a->connectItem( a->insertItem(Key_P+CTRL), // adds Ctrl+P accelerator
|
---|
130 | myWindow, // connected to myWindow's
|
---|
131 | SLOT(printDoc()) ); // printDoc() slot
|
---|
132 | \endcode
|
---|
133 |
|
---|
134 | \sa QKeyEvent QWidget::keyPressEvent() QMenuData::setAccel()
|
---|
135 | QButton::setAccel() QLabel::setBuddy() QKeySequence
|
---|
136 | \link guibooks.html#fowler GUI Design Handbook: Keyboard Shortcuts \endlink.
|
---|
137 | */
|
---|
138 |
|
---|
139 |
|
---|
140 | struct QAccelItem { // internal accelerator item
|
---|
141 | QAccelItem( const QKeySequence &k, int i )
|
---|
142 | { key=k; id=i; enabled=TRUE; signal=0; }
|
---|
143 | ~QAccelItem() { delete signal; }
|
---|
144 | int id;
|
---|
145 | QKeySequence key;
|
---|
146 | bool enabled;
|
---|
147 | QSignal *signal;
|
---|
148 | QString whatsthis;
|
---|
149 | };
|
---|
150 |
|
---|
151 |
|
---|
152 | typedef QPtrList<QAccelItem> QAccelList; // internal accelerator list
|
---|
153 |
|
---|
154 | class QAccelPrivate : public Qt {
|
---|
155 | public:
|
---|
156 | QAccelPrivate( QAccel* p );
|
---|
157 | ~QAccelPrivate();
|
---|
158 | QAccelList aitems;
|
---|
159 | bool enabled;
|
---|
160 | QGuardedPtr<QWidget> watch;
|
---|
161 | bool ignorewhatsthis;
|
---|
162 | QAccel* parent;
|
---|
163 |
|
---|
164 | void activate( QAccelItem* item );
|
---|
165 | void activateAmbiguously( QAccelItem* item );
|
---|
166 | };
|
---|
167 |
|
---|
168 | class QAccelManager : public Qt {
|
---|
169 | public:
|
---|
170 | static QAccelManager* self() { return self_ptr ? self_ptr : new QAccelManager; }
|
---|
171 | void registerAccel( QAccelPrivate* a ) { accels.append( a ); }
|
---|
172 | void unregisterAccel( QAccelPrivate* a ) { accels.removeRef( a ); if ( accels.isEmpty() ) delete this; }
|
---|
173 | bool tryAccelEvent( QWidget* w, QKeyEvent* e );
|
---|
174 | bool dispatchAccelEvent( QWidget* w, QKeyEvent* e );
|
---|
175 | bool tryComposeUnicode( QWidget* w, QKeyEvent* e );
|
---|
176 |
|
---|
177 | private:
|
---|
178 | QAccelManager():currentState(Qt::NoMatch), clash(-1) { self_ptr = this; }
|
---|
179 | ~QAccelManager() { self_ptr = 0; }
|
---|
180 |
|
---|
181 | bool correctSubWindow( QWidget *w, QAccelPrivate* d );
|
---|
182 | SequenceMatch match( QKeyEvent* e, QAccelItem* item, QKeySequence& temp );
|
---|
183 | int translateModifiers( ButtonState state );
|
---|
184 |
|
---|
185 | QPtrList<QAccelPrivate> accels;
|
---|
186 | static QAccelManager* self_ptr;
|
---|
187 | Qt::SequenceMatch currentState;
|
---|
188 | QKeySequence intermediate;
|
---|
189 | int clash;
|
---|
190 | };
|
---|
191 | QAccelManager* QAccelManager::self_ptr = 0;
|
---|
192 |
|
---|
193 | bool Q_EXPORT qt_tryAccelEvent( QWidget* w, QKeyEvent* e){
|
---|
194 | return QAccelManager::self()->tryAccelEvent( w, e );
|
---|
195 | }
|
---|
196 |
|
---|
197 | bool Q_EXPORT qt_dispatchAccelEvent( QWidget* w, QKeyEvent* e){
|
---|
198 | return QAccelManager::self()->dispatchAccelEvent( w, e );
|
---|
199 | }
|
---|
200 |
|
---|
201 | bool Q_EXPORT qt_tryComposeUnicode( QWidget* w, QKeyEvent* e){
|
---|
202 | return QAccelManager::self()->tryComposeUnicode( w, e );
|
---|
203 | }
|
---|
204 |
|
---|
205 | #ifdef Q_WS_MAC
|
---|
206 | static bool qt_accel_no_shortcuts = TRUE;
|
---|
207 | #else
|
---|
208 | static bool qt_accel_no_shortcuts = FALSE;
|
---|
209 | #endif
|
---|
210 | void Q_EXPORT qt_setAccelAutoShortcuts(bool b) { qt_accel_no_shortcuts = b; }
|
---|
211 |
|
---|
212 | /*
|
---|
213 | \internal
|
---|
214 | Returns TRUE if the accel is in the current subwindow, else FALSE.
|
---|
215 | */
|
---|
216 | bool QAccelManager::correctSubWindow( QWidget* w, QAccelPrivate* d ) {
|
---|
217 | #if !defined ( Q_OS_MACX )
|
---|
218 | if ( !d->watch || !d->watch->isVisible() || !d->watch->isEnabled() )
|
---|
219 | #else
|
---|
220 | if ( !d->watch || (!d->watch->isVisible() && !d->watch->inherits( "QMenuBar" )) || !d->watch->isEnabled() )
|
---|
221 | #endif
|
---|
222 | return FALSE;
|
---|
223 | QWidget* tlw = w->topLevelWidget();
|
---|
224 | QWidget* wtlw = d->watch->topLevelWidget();
|
---|
225 |
|
---|
226 | /* if we live in a floating dock window, keep our parent's
|
---|
227 | * accelerators working */
|
---|
228 | #ifndef QT_NO_MAINWINDOW
|
---|
229 | if ( tlw->isDialog() && tlw->parentWidget() && ::qt_cast<QDockWindow*>(tlw) )
|
---|
230 | return tlw->parentWidget()->topLevelWidget() == wtlw;
|
---|
231 |
|
---|
232 | if ( wtlw != tlw )
|
---|
233 | return FALSE;
|
---|
234 | #endif
|
---|
235 | /* if we live in a MDI subwindow, ignore the event if we are
|
---|
236 | not the active document window */
|
---|
237 | QWidget* sw = d->watch;
|
---|
238 | while ( sw && !sw->testWFlags( WSubWindow ) )
|
---|
239 | sw = sw->parentWidget( TRUE );
|
---|
240 | if ( sw ) { // we are in a subwindow indeed
|
---|
241 | QWidget* fw = w;
|
---|
242 | while ( fw && fw != sw )
|
---|
243 | fw = fw->parentWidget( TRUE );
|
---|
244 | if ( fw != sw ) // focus widget not in our subwindow
|
---|
245 | return FALSE;
|
---|
246 | }
|
---|
247 | return TRUE;
|
---|
248 | }
|
---|
249 |
|
---|
250 | inline int QAccelManager::translateModifiers( ButtonState state )
|
---|
251 | {
|
---|
252 | int result = 0;
|
---|
253 | if ( state & ShiftButton )
|
---|
254 | result |= SHIFT;
|
---|
255 | if ( state & ControlButton )
|
---|
256 | result |= CTRL;
|
---|
257 | if ( state & MetaButton )
|
---|
258 | result |= META;
|
---|
259 | if ( state & AltButton )
|
---|
260 | result |= ALT;
|
---|
261 | return result;
|
---|
262 | }
|
---|
263 |
|
---|
264 | /*
|
---|
265 | \internal
|
---|
266 | Matches the current intermediate key sequence + the latest
|
---|
267 | keyevent, with and AccelItem. Returns Identical,
|
---|
268 | PartialMatch or NoMatch, and fills \a temp with the
|
---|
269 | resulting key sequence.
|
---|
270 | */
|
---|
271 | Qt::SequenceMatch QAccelManager::match( QKeyEvent *e, QAccelItem* item, QKeySequence& temp )
|
---|
272 | {
|
---|
273 | SequenceMatch result = Qt::NoMatch;
|
---|
274 | int index = intermediate.count();
|
---|
275 | temp = intermediate;
|
---|
276 |
|
---|
277 | int modifier = translateModifiers( e->state() );
|
---|
278 |
|
---|
279 | if ( e->key() && e->key() != Key_unknown) {
|
---|
280 | int key = e->key() | modifier;
|
---|
281 | if ( e->key() == Key_BackTab ) {
|
---|
282 | /*
|
---|
283 | In QApplication, we map shift+tab to shift+backtab.
|
---|
284 | This code here reverts the mapping in a way that keeps
|
---|
285 | backtab and shift+tab accelerators working, in that
|
---|
286 | order, meaning backtab has priority.*/
|
---|
287 | key &= ~SHIFT;
|
---|
288 |
|
---|
289 | temp.setKey( key, index );
|
---|
290 | if ( Qt::NoMatch != (result = temp.matches( item->key )) )
|
---|
291 | return result;
|
---|
292 | if ( e->state() & ShiftButton )
|
---|
293 | key |= SHIFT;
|
---|
294 | key = Key_Tab | ( key & MODIFIER_MASK );
|
---|
295 | temp.setKey( key, index );
|
---|
296 | if ( Qt::NoMatch != (result = temp.matches( item->key )) )
|
---|
297 | return result;
|
---|
298 | } else {
|
---|
299 | temp.setKey( key, index );
|
---|
300 | if ( Qt::NoMatch != (result = temp.matches( item->key )) )
|
---|
301 | return result;
|
---|
302 | }
|
---|
303 |
|
---|
304 | if ( key == Key_BackTab ) {
|
---|
305 | if ( e->state() & ShiftButton )
|
---|
306 | key |= SHIFT;
|
---|
307 | temp.setKey( key, index );
|
---|
308 | if ( Qt::NoMatch != (result = temp.matches( item->key )) )
|
---|
309 | return result;
|
---|
310 | }
|
---|
311 | }
|
---|
312 | if ( !e->text().isEmpty() ) {
|
---|
313 | temp.setKey( (int)e->text()[0].unicode() | UNICODE_ACCEL | modifier, index );
|
---|
314 | result = temp.matches( item->key );
|
---|
315 | }
|
---|
316 | return result;
|
---|
317 | }
|
---|
318 |
|
---|
319 | bool QAccelManager::tryAccelEvent( QWidget* w, QKeyEvent* e )
|
---|
320 | {
|
---|
321 | if ( Qt::NoMatch == currentState ) {
|
---|
322 | e->t = QEvent::AccelOverride;
|
---|
323 | e->ignore();
|
---|
324 | QApplication::sendSpontaneousEvent( w, e );
|
---|
325 | if ( e->isAccepted() )
|
---|
326 | return FALSE;
|
---|
327 | }
|
---|
328 | e->t = QEvent::Accel;
|
---|
329 | e->ignore();
|
---|
330 | QApplication::sendSpontaneousEvent( w, e );
|
---|
331 | return e->isAccepted();
|
---|
332 | }
|
---|
333 |
|
---|
334 | bool QAccelManager::tryComposeUnicode( QWidget* w, QKeyEvent* e )
|
---|
335 | {
|
---|
336 | if ( QApplication::metaComposeUnicode ) {
|
---|
337 | int value = e->key() - Key_0;
|
---|
338 | // Ignore acceloverrides so we don't trigger
|
---|
339 | // accels on keypad when Meta compose is on
|
---|
340 | if ( (e->type() == QEvent::AccelOverride) &&
|
---|
341 | (e->state() == Qt::Keypad + Qt::MetaButton) ) {
|
---|
342 | e->accept();
|
---|
343 | // Meta compose start/continue
|
---|
344 | } else if ( (e->type() == QEvent::KeyPress) &&
|
---|
345 | (e->state() == Qt::Keypad + Qt::MetaButton) ) {
|
---|
346 | if ( value >= 0 && value <= 9 ) {
|
---|
347 | QApplication::composedUnicode *= 10;
|
---|
348 | QApplication::composedUnicode += value;
|
---|
349 | return TRUE;
|
---|
350 | } else {
|
---|
351 | // Composing interrupted, dispatch!
|
---|
352 | if ( QApplication::composedUnicode ) {
|
---|
353 | QChar ch( QApplication::composedUnicode );
|
---|
354 | QString s( ch );
|
---|
355 | QKeyEvent kep( QEvent::KeyPress, 0, ch.row() ? 0 : ch.cell(), 0, s );
|
---|
356 | QKeyEvent ker( QEvent::KeyRelease, 0, ch.row() ? 0 : ch.cell(), 0, s );
|
---|
357 | QApplication::sendEvent( w, &kep );
|
---|
358 | QApplication::sendEvent( w, &ker );
|
---|
359 | }
|
---|
360 | QApplication::composedUnicode = 0;
|
---|
361 | return TRUE;
|
---|
362 | }
|
---|
363 | // Meta compose end, dispatch
|
---|
364 | } else if ( (e->type() == QEvent::KeyRelease) &&
|
---|
365 | (e->key() == Key_Meta) &&
|
---|
366 | (QApplication::composedUnicode != 0) ) {
|
---|
367 | if ( (QApplication::composedUnicode > 0) &&
|
---|
368 | (QApplication::composedUnicode < 0xFFFE) ) {
|
---|
369 | QChar ch( QApplication::composedUnicode );
|
---|
370 | QString s( ch );
|
---|
371 | QKeyEvent kep( QEvent::KeyPress, 0, ch.row() ? 0 : ch.cell(), 0, s );
|
---|
372 | QKeyEvent ker( QEvent::KeyRelease, 0, ch.row() ? 0 : ch.cell(), 0, s );
|
---|
373 | QApplication::sendEvent( w, &kep );
|
---|
374 | QApplication::sendEvent( w, &ker );
|
---|
375 | }
|
---|
376 | QApplication::composedUnicode = 0;
|
---|
377 | return TRUE;
|
---|
378 | }
|
---|
379 | }
|
---|
380 | return FALSE;
|
---|
381 | }
|
---|
382 |
|
---|
383 | /*
|
---|
384 | \internal
|
---|
385 | Checks for possible accelerators, if no widget
|
---|
386 | ate the keypres, or we are in the middle of a
|
---|
387 | partial key sequence.
|
---|
388 | */
|
---|
389 | bool QAccelManager::dispatchAccelEvent( QWidget* w, QKeyEvent* e )
|
---|
390 | {
|
---|
391 | #ifndef QT_NO_STATUSBAR
|
---|
392 | // Needs to be declared and used here because of "goto doclash"
|
---|
393 | QStatusBar* mainStatusBar = 0;
|
---|
394 | #endif
|
---|
395 |
|
---|
396 | // Modifiers can NOT be accelerators...
|
---|
397 | if ( e->key() >= Key_Shift &&
|
---|
398 | e->key() <= Key_Alt )
|
---|
399 | return FALSE;
|
---|
400 |
|
---|
401 | SequenceMatch result = Qt::NoMatch;
|
---|
402 | QKeySequence tocheck, partial;
|
---|
403 | QAccelPrivate* accel = 0;
|
---|
404 | QAccelItem* item = 0;
|
---|
405 | QAccelPrivate* firstaccel = 0;
|
---|
406 | QAccelItem* firstitem = 0;
|
---|
407 | QAccelPrivate* lastaccel = 0;
|
---|
408 | QAccelItem* lastitem = 0;
|
---|
409 |
|
---|
410 | QKeyEvent pe = *e;
|
---|
411 | int n = -1;
|
---|
412 | int hasShift = (e->state()&Qt::ShiftButton)?1:0;
|
---|
413 | bool identicalDisabled = FALSE;
|
---|
414 | bool matchFound = FALSE;
|
---|
415 | do {
|
---|
416 | accel = accels.first();
|
---|
417 | matchFound = FALSE;
|
---|
418 | while ( accel ) {
|
---|
419 | if ( correctSubWindow( w, accel ) ) {
|
---|
420 | if ( accel->enabled ) {
|
---|
421 | item = accel->aitems.last();
|
---|
422 | while( item ) {
|
---|
423 | if ( Qt::Identical == (result = match( &pe, item, tocheck )) ) {
|
---|
424 | if ( item->enabled ) {
|
---|
425 | if ( !firstaccel ) {
|
---|
426 | firstaccel = accel;
|
---|
427 | firstitem = item;
|
---|
428 | }
|
---|
429 | lastaccel = accel;
|
---|
430 | lastitem = item;
|
---|
431 | n++;
|
---|
432 | matchFound = TRUE;
|
---|
433 | if ( n > QMAX(clash,0) )
|
---|
434 | goto doclash;
|
---|
435 | } else {
|
---|
436 | identicalDisabled = TRUE;
|
---|
437 | }
|
---|
438 | }
|
---|
439 | if ( item->enabled && Qt::PartialMatch == result ) {
|
---|
440 | partial = tocheck;
|
---|
441 | matchFound = TRUE;
|
---|
442 | }
|
---|
443 | item = accel->aitems.prev();
|
---|
444 | }
|
---|
445 | } else {
|
---|
446 | item = accel->aitems.last();
|
---|
447 | while( item ) {
|
---|
448 | if ( Qt::Identical == match( &pe, item, tocheck ) )
|
---|
449 | identicalDisabled = TRUE;
|
---|
450 | item = accel->aitems.prev();
|
---|
451 | }
|
---|
452 | }
|
---|
453 | }
|
---|
454 | accel = accels.next();
|
---|
455 | }
|
---|
456 | pe = QKeyEvent( QEvent::Accel, pe.key(), pe.ascii(), pe.state()&~Qt::ShiftButton, pe.text() );
|
---|
457 | } while ( hasShift-- && !matchFound && !identicalDisabled );
|
---|
458 |
|
---|
459 | #ifndef QT_NO_STATUSBAR
|
---|
460 | mainStatusBar = (QStatusBar*) w->topLevelWidget()->child( 0, "QStatusBar" );
|
---|
461 | #endif
|
---|
462 | if ( n < 0 ) { // no match found
|
---|
463 | currentState = partial.count() ? PartialMatch : NoMatch;
|
---|
464 | #ifndef QT_NO_STATUSBAR
|
---|
465 | // Only display message if we are, or were, in a partial match
|
---|
466 | if ( mainStatusBar && (PartialMatch == currentState || intermediate.count() ) ) {
|
---|
467 | if ( currentState == Qt::PartialMatch ) {
|
---|
468 | mainStatusBar->message( (QString)partial + ", ...", 0 );
|
---|
469 | } else if (!identicalDisabled) {
|
---|
470 | QString message = QAccel::tr("%1, %2 not defined").
|
---|
471 | arg( (QString)intermediate ).
|
---|
472 | arg( QKeySequence::encodeString( e->key() | translateModifiers(e->state()) ) );
|
---|
473 | mainStatusBar->message( message, 2000 );
|
---|
474 | // Since we're a NoMatch, reset the clash count
|
---|
475 | clash = -1;
|
---|
476 | } else {
|
---|
477 | mainStatusBar->clear();
|
---|
478 | }
|
---|
479 | }
|
---|
480 | #endif
|
---|
481 |
|
---|
482 | bool eatKey = (PartialMatch == currentState || intermediate.count() );
|
---|
483 | intermediate = partial;
|
---|
484 | if ( eatKey )
|
---|
485 | e->accept();
|
---|
486 | return eatKey;
|
---|
487 | } else if ( n == 0 ) { // found exactly one match
|
---|
488 | clash = -1; // reset
|
---|
489 | #ifndef QT_NO_STATUSBAR
|
---|
490 | if ( currentState == Qt::PartialMatch && mainStatusBar )
|
---|
491 | mainStatusBar->clear();
|
---|
492 | #endif
|
---|
493 | currentState = Qt::NoMatch; // Free sequence keylock
|
---|
494 | intermediate = QKeySequence();
|
---|
495 | lastaccel->activate( lastitem );
|
---|
496 | e->accept();
|
---|
497 | return TRUE;
|
---|
498 | }
|
---|
499 |
|
---|
500 | doclash: // found more than one match
|
---|
501 | #ifndef QT_NO_STATUSBAR
|
---|
502 | if ( !mainStatusBar ) // if "goto doclash", we need to get statusbar again.
|
---|
503 | mainStatusBar = (QStatusBar*) w->topLevelWidget()->child( 0, "QStatusBar" );
|
---|
504 | #endif
|
---|
505 |
|
---|
506 | QString message = QAccel::tr( "Ambiguous \"%1\" not handled" ).arg( (QString)tocheck );
|
---|
507 | if ( clash >= 0 && n > clash ) { // pick next match
|
---|
508 | intermediate = QKeySequence();
|
---|
509 | currentState = Qt::NoMatch; // Free sequence keylock
|
---|
510 | clash++;
|
---|
511 | #ifndef QT_NO_STATUSBAR
|
---|
512 | if ( mainStatusBar &&
|
---|
513 | !lastitem->signal &&
|
---|
514 | !(lastaccel->parent->receivers( "activatedAmbiguously(int)" )) )
|
---|
515 | mainStatusBar->message( message, 2000 );
|
---|
516 | #endif
|
---|
517 | lastaccel->activateAmbiguously( lastitem );
|
---|
518 | } else { // start (or wrap) with the first matching
|
---|
519 | intermediate = QKeySequence();
|
---|
520 | currentState = Qt::NoMatch; // Free sequence keylock
|
---|
521 | clash = 0;
|
---|
522 | #ifndef QT_NO_STATUSBAR
|
---|
523 | if ( mainStatusBar &&
|
---|
524 | !firstitem->signal &&
|
---|
525 | !(firstaccel->parent->receivers( "activatedAmbiguously(int)" )) )
|
---|
526 | mainStatusBar->message( message, 2000 );
|
---|
527 | #endif
|
---|
528 | firstaccel->activateAmbiguously( firstitem );
|
---|
529 | }
|
---|
530 | e->accept();
|
---|
531 | return TRUE;
|
---|
532 | }
|
---|
533 |
|
---|
534 | QAccelPrivate::QAccelPrivate( QAccel* p )
|
---|
535 | : parent( p )
|
---|
536 | {
|
---|
537 | QAccelManager::self()->registerAccel( this );
|
---|
538 | aitems.setAutoDelete( TRUE );
|
---|
539 | ignorewhatsthis = FALSE;
|
---|
540 | }
|
---|
541 |
|
---|
542 | QAccelPrivate::~QAccelPrivate()
|
---|
543 | {
|
---|
544 | QAccelManager::self()->unregisterAccel( this );
|
---|
545 | }
|
---|
546 |
|
---|
547 | static QAccelItem *find_id( QAccelList &list, int id )
|
---|
548 | {
|
---|
549 | register QAccelItem *item = list.first();
|
---|
550 | while ( item && item->id != id )
|
---|
551 | item = list.next();
|
---|
552 | return item;
|
---|
553 | }
|
---|
554 |
|
---|
555 | static QAccelItem *find_key( QAccelList &list, const QKeySequence &key )
|
---|
556 | {
|
---|
557 | register QAccelItem *item = list.first();
|
---|
558 | while ( item && !( item->key == key ) )
|
---|
559 | item = list.next();
|
---|
560 | return item;
|
---|
561 | }
|
---|
562 |
|
---|
563 | /*!
|
---|
564 | Constructs a QAccel object called \a name, with parent \a parent.
|
---|
565 | The accelerator operates on \a parent.
|
---|
566 | */
|
---|
567 |
|
---|
568 | QAccel::QAccel( QWidget *parent, const char *name )
|
---|
569 | : QObject( parent, name )
|
---|
570 | {
|
---|
571 | d = new QAccelPrivate( this );
|
---|
572 | d->enabled = TRUE;
|
---|
573 | d->watch = parent;
|
---|
574 | #if defined(QT_CHECK_NULL)
|
---|
575 | if ( !d->watch )
|
---|
576 | qWarning( "QAccel: An accelerator must have a parent or a watch widget" );
|
---|
577 | #endif
|
---|
578 | }
|
---|
579 |
|
---|
580 | /*!
|
---|
581 | Constructs a QAccel object called \a name, that operates on \a
|
---|
582 | watch, and is a child of \a parent.
|
---|
583 |
|
---|
584 | This constructor is not needed for normal application programming.
|
---|
585 | */
|
---|
586 | QAccel::QAccel( QWidget* watch, QObject *parent, const char *name )
|
---|
587 | : QObject( parent, name )
|
---|
588 | {
|
---|
589 | d = new QAccelPrivate( this );
|
---|
590 | d->enabled = TRUE;
|
---|
591 | d->watch = watch;
|
---|
592 | #if defined(QT_CHECK_NULL)
|
---|
593 | if ( !d->watch )
|
---|
594 | qWarning( "QAccel: An accelerator must have a parent or a watch widget" );
|
---|
595 | #endif
|
---|
596 | }
|
---|
597 |
|
---|
598 | /*!
|
---|
599 | Destroys the accelerator object and frees all allocated resources.
|
---|
600 | */
|
---|
601 |
|
---|
602 | QAccel::~QAccel()
|
---|
603 | {
|
---|
604 | delete d;
|
---|
605 | }
|
---|
606 |
|
---|
607 |
|
---|
608 | /*!
|
---|
609 | \fn void QAccel::activated( int id )
|
---|
610 |
|
---|
611 | This signal is emitted when an accelerator key is pressed. \a id
|
---|
612 | is a number that identifies this particular accelerator item.
|
---|
613 |
|
---|
614 | \sa activatedAmbiguously()
|
---|
615 | */
|
---|
616 |
|
---|
617 | /*!
|
---|
618 | \fn void QAccel::activatedAmbiguously( int id )
|
---|
619 |
|
---|
620 | This signal is emitted when an accelerator key is pressed. \a id
|
---|
621 | is a number that identifies this particular accelerator item.
|
---|
622 |
|
---|
623 | \sa activated()
|
---|
624 | */
|
---|
625 |
|
---|
626 |
|
---|
627 | /*!
|
---|
628 | Returns TRUE if the accelerator is enabled; otherwise returns
|
---|
629 | FALSE.
|
---|
630 |
|
---|
631 | \sa setEnabled(), isItemEnabled()
|
---|
632 | */
|
---|
633 |
|
---|
634 | bool QAccel::isEnabled() const
|
---|
635 | {
|
---|
636 | return d->enabled;
|
---|
637 | }
|
---|
638 |
|
---|
639 |
|
---|
640 | /*!
|
---|
641 | Enables the accelerator if \a enable is TRUE, or disables it if \a
|
---|
642 | enable is FALSE.
|
---|
643 |
|
---|
644 | Individual keys can also be enabled or disabled using
|
---|
645 | setItemEnabled(). To work, a key must be an enabled item in an
|
---|
646 | enabled QAccel.
|
---|
647 |
|
---|
648 | \sa isEnabled(), setItemEnabled()
|
---|
649 | */
|
---|
650 |
|
---|
651 | void QAccel::setEnabled( bool enable )
|
---|
652 | {
|
---|
653 | d->enabled = enable;
|
---|
654 | }
|
---|
655 |
|
---|
656 |
|
---|
657 | /*!
|
---|
658 | Returns the number of accelerator items in this accelerator.
|
---|
659 | */
|
---|
660 |
|
---|
661 | uint QAccel::count() const
|
---|
662 | {
|
---|
663 | return d->aitems.count();
|
---|
664 | }
|
---|
665 |
|
---|
666 |
|
---|
667 | static int get_seq_id()
|
---|
668 | {
|
---|
669 | static int seq_no = -2; // -1 is used as return value in findKey()
|
---|
670 | return seq_no--;
|
---|
671 | }
|
---|
672 |
|
---|
673 | /*!
|
---|
674 | Inserts an accelerator item and returns the item's identifier.
|
---|
675 |
|
---|
676 | \a key is a key code and an optional combination of SHIFT, CTRL
|
---|
677 | and ALT. \a id is the accelerator item id.
|
---|
678 |
|
---|
679 | If \a id is negative, then the item will be assigned a unique
|
---|
680 | negative identifier less than -1.
|
---|
681 |
|
---|
682 | \code
|
---|
683 | QAccel *a = new QAccel( myWindow ); // create accels for myWindow
|
---|
684 | a->insertItem( CTRL + Key_P, 200 ); // Ctrl+P, e.g. to print document
|
---|
685 | a->insertItem( ALT + Key_X, 201 ); // Alt+X, e.g. to quit
|
---|
686 | a->insertItem( UNICODE_ACCEL + 'q', 202 ); // Unicode 'q', e.g. to quit
|
---|
687 | a->insertItem( Key_D ); // gets a unique negative id < -1
|
---|
688 | a->insertItem( CTRL + SHIFT + Key_P ); // gets a unique negative id < -1
|
---|
689 | \endcode
|
---|
690 | */
|
---|
691 |
|
---|
692 | int QAccel::insertItem( const QKeySequence& key, int id )
|
---|
693 | {
|
---|
694 | if ( id == -1 )
|
---|
695 | id = get_seq_id();
|
---|
696 | d->aitems.insert( 0, new QAccelItem(key,id) );
|
---|
697 | return id;
|
---|
698 | }
|
---|
699 |
|
---|
700 | /*!
|
---|
701 | Removes the accelerator item with the identifier \a id.
|
---|
702 | */
|
---|
703 |
|
---|
704 | void QAccel::removeItem( int id )
|
---|
705 | {
|
---|
706 | if ( find_id( d->aitems, id) )
|
---|
707 | d->aitems.remove();
|
---|
708 | }
|
---|
709 |
|
---|
710 |
|
---|
711 | /*!
|
---|
712 | Removes all accelerator items.
|
---|
713 | */
|
---|
714 |
|
---|
715 | void QAccel::clear()
|
---|
716 | {
|
---|
717 | d->aitems.clear();
|
---|
718 | }
|
---|
719 |
|
---|
720 |
|
---|
721 | /*!
|
---|
722 | Returns the key sequence of the accelerator item with identifier
|
---|
723 | \a id, or an invalid key sequence (0) if the id cannot be found.
|
---|
724 | */
|
---|
725 |
|
---|
726 | QKeySequence QAccel::key( int id )
|
---|
727 | {
|
---|
728 | QAccelItem *item = find_id( d->aitems, id);
|
---|
729 | return item ? item->key : QKeySequence( 0 );
|
---|
730 | }
|
---|
731 |
|
---|
732 |
|
---|
733 | /*!
|
---|
734 | Returns the identifier of the accelerator item with the key code
|
---|
735 | \a key, or -1 if the item cannot be found.
|
---|
736 | */
|
---|
737 |
|
---|
738 | int QAccel::findKey( const QKeySequence& key ) const
|
---|
739 | {
|
---|
740 | QAccelItem *item = find_key( d->aitems, key );
|
---|
741 | return item ? item->id : -1;
|
---|
742 | }
|
---|
743 |
|
---|
744 |
|
---|
745 | /*!
|
---|
746 | Returns TRUE if the accelerator item with the identifier \a id is
|
---|
747 | enabled. Returns FALSE if the item is disabled or cannot be found.
|
---|
748 |
|
---|
749 | \sa setItemEnabled(), isEnabled()
|
---|
750 | */
|
---|
751 |
|
---|
752 | bool QAccel::isItemEnabled( int id ) const
|
---|
753 | {
|
---|
754 | QAccelItem *item = find_id( d->aitems, id);
|
---|
755 | return item ? item->enabled : FALSE;
|
---|
756 | }
|
---|
757 |
|
---|
758 |
|
---|
759 | /*!
|
---|
760 | Enables the accelerator item with the identifier \a id if \a
|
---|
761 | enable is TRUE, and disables item \a id if \a enable is FALSE.
|
---|
762 |
|
---|
763 | To work, an item must be enabled and be in an enabled QAccel.
|
---|
764 |
|
---|
765 | \sa isItemEnabled(), isEnabled()
|
---|
766 | */
|
---|
767 |
|
---|
768 | void QAccel::setItemEnabled( int id, bool enable )
|
---|
769 | {
|
---|
770 | QAccelItem *item = find_id( d->aitems, id);
|
---|
771 | if ( item )
|
---|
772 | item->enabled = enable;
|
---|
773 | }
|
---|
774 |
|
---|
775 |
|
---|
776 | /*!
|
---|
777 | Connects the accelerator item \a id to the slot \a member of \a
|
---|
778 | receiver.
|
---|
779 |
|
---|
780 | \code
|
---|
781 | a->connectItem( 201, mainView, SLOT(quit()) );
|
---|
782 | \endcode
|
---|
783 |
|
---|
784 | Of course, you can also send a signal as \a member.
|
---|
785 |
|
---|
786 | Normally accelerators are connected to slots which then receive
|
---|
787 | the \c activated(int id) signal with the id of the accelerator
|
---|
788 | item that was activated. If you choose to connect a specific
|
---|
789 | accelerator item using this function, the \c activated() signal is
|
---|
790 | emitted if the associated key sequence is pressed but no \c
|
---|
791 | activated(int id) signal is emitted.
|
---|
792 |
|
---|
793 | \sa disconnectItem()
|
---|
794 | */
|
---|
795 |
|
---|
796 | bool QAccel::connectItem( int id, const QObject *receiver, const char *member )
|
---|
797 | {
|
---|
798 | QAccelItem *item = find_id( d->aitems, id);
|
---|
799 | if ( item ) {
|
---|
800 | if ( !item->signal ) {
|
---|
801 | item->signal = new QSignal;
|
---|
802 | Q_CHECK_PTR( item->signal );
|
---|
803 | }
|
---|
804 | return item->signal->connect( receiver, member );
|
---|
805 | }
|
---|
806 | return FALSE;
|
---|
807 | }
|
---|
808 |
|
---|
809 | /*!
|
---|
810 | Disconnects an accelerator item with id \a id from the function
|
---|
811 | called \a member in the \a receiver object.
|
---|
812 |
|
---|
813 | \sa connectItem()
|
---|
814 | */
|
---|
815 |
|
---|
816 | bool QAccel::disconnectItem( int id, const QObject *receiver,
|
---|
817 | const char *member )
|
---|
818 | {
|
---|
819 | QAccelItem *item = find_id( d->aitems, id);
|
---|
820 | if ( item && item->signal )
|
---|
821 | return item->signal->disconnect( receiver, member );
|
---|
822 | return FALSE;
|
---|
823 | }
|
---|
824 |
|
---|
825 | void QAccelPrivate::activate( QAccelItem* item )
|
---|
826 | {
|
---|
827 | #ifndef QT_NO_WHATSTHIS
|
---|
828 | if ( QWhatsThis::inWhatsThisMode() && !ignorewhatsthis ) {
|
---|
829 | QWhatsThis::leaveWhatsThisMode( item->whatsthis );
|
---|
830 | return;
|
---|
831 | }
|
---|
832 | #endif
|
---|
833 | if ( item->signal )
|
---|
834 | item->signal->activate();
|
---|
835 | else
|
---|
836 | emit parent->activated( item->id );
|
---|
837 | }
|
---|
838 |
|
---|
839 | void QAccelPrivate::activateAmbiguously( QAccelItem* item )
|
---|
840 | {
|
---|
841 | if ( item->signal )
|
---|
842 | item->signal->activate();
|
---|
843 | else
|
---|
844 | emit parent->activatedAmbiguously( item->id );
|
---|
845 | }
|
---|
846 |
|
---|
847 |
|
---|
848 | /*!
|
---|
849 | Returns the shortcut key sequence for \a str, or an invalid key
|
---|
850 | sequence (0) if \a str has no shortcut sequence.
|
---|
851 |
|
---|
852 | For example, shortcutKey("E&xit") returns ALT+Key_X,
|
---|
853 | shortcutKey("&Quit") returns ALT+Key_Q and shortcutKey("Quit")
|
---|
854 | returns 0. (In code that does not inherit the Qt namespace class,
|
---|
855 | you must write e.g. Qt::ALT+Qt::Key_Q.)
|
---|
856 |
|
---|
857 | We provide a \link accelerators.html list of common accelerators
|
---|
858 | \endlink in English. At the time of writing, Microsoft and Open
|
---|
859 | Group do not appear to have issued equivalent recommendations for
|
---|
860 | other languages.
|
---|
861 | */
|
---|
862 |
|
---|
863 | QKeySequence QAccel::shortcutKey( const QString &str )
|
---|
864 | {
|
---|
865 | if(qt_accel_no_shortcuts)
|
---|
866 | return QKeySequence();
|
---|
867 |
|
---|
868 | int p = 0;
|
---|
869 | while ( p >= 0 ) {
|
---|
870 | p = str.find( '&', p ) + 1;
|
---|
871 | if ( p <= 0 || p >= (int)str.length() )
|
---|
872 | return 0;
|
---|
873 | if ( str[p] != '&' ) {
|
---|
874 | QChar c = str[p];
|
---|
875 | if ( c.isPrint() ) {
|
---|
876 | c = c.upper();
|
---|
877 | return QKeySequence( c.unicode() + ALT + UNICODE_ACCEL );
|
---|
878 | }
|
---|
879 | }
|
---|
880 | p++;
|
---|
881 | }
|
---|
882 | return QKeySequence();
|
---|
883 | }
|
---|
884 |
|
---|
885 | /*! \obsolete
|
---|
886 |
|
---|
887 | Creates an accelerator string for the key \a k.
|
---|
888 | For instance CTRL+Key_O gives "Ctrl+O". The "Ctrl" etc.
|
---|
889 | are translated (using QObject::tr()) in the "QAccel" context.
|
---|
890 |
|
---|
891 | The function is superfluous. Cast the QKeySequence \a k to a
|
---|
892 | QString for the same effect.
|
---|
893 | */
|
---|
894 | QString QAccel::keyToString( QKeySequence k )
|
---|
895 | {
|
---|
896 | return (QString) k;
|
---|
897 | }
|
---|
898 |
|
---|
899 | /*!\obsolete
|
---|
900 |
|
---|
901 | Returns an accelerator code for the string \a s. For example
|
---|
902 | "Ctrl+O" gives CTRL+UNICODE_ACCEL+'O'. The strings "Ctrl",
|
---|
903 | "Shift", "Alt" are recognized, as well as their translated
|
---|
904 | equivalents in the "QAccel" context (using QObject::tr()). Returns 0
|
---|
905 | if \a s is not recognized.
|
---|
906 |
|
---|
907 | This function is typically used with \link QObject::tr() tr
|
---|
908 | \endlink(), so that accelerator keys can be replaced in
|
---|
909 | translations:
|
---|
910 |
|
---|
911 | \code
|
---|
912 | QPopupMenu *file = new QPopupMenu( this );
|
---|
913 | file->insertItem( p1, tr("&Open..."), this, SLOT(open()),
|
---|
914 | QAccel::stringToKey(tr("Ctrl+O", "File|Open")) );
|
---|
915 | \endcode
|
---|
916 |
|
---|
917 | Notice the \c "File|Open" translator comment. It is by no means
|
---|
918 | necessary, but it provides some context for the human translator.
|
---|
919 |
|
---|
920 |
|
---|
921 | The function is superfluous. Construct a QKeySequence from the
|
---|
922 | string \a s for the same effect.
|
---|
923 |
|
---|
924 | \sa QObject::tr()
|
---|
925 | \link i18n.html Internationalization with Qt \endlink
|
---|
926 | */
|
---|
927 | QKeySequence QAccel::stringToKey( const QString & s )
|
---|
928 | {
|
---|
929 | return QKeySequence( s );
|
---|
930 | }
|
---|
931 |
|
---|
932 |
|
---|
933 | /*!
|
---|
934 | Sets a What's This help text for the accelerator item \a id to \a
|
---|
935 | text.
|
---|
936 |
|
---|
937 | The text will be shown when the application is in What's This mode
|
---|
938 | and the user hits the accelerator key.
|
---|
939 |
|
---|
940 | To set What's This help on a menu item (with or without an
|
---|
941 | accelerator key), use QMenuData::setWhatsThis().
|
---|
942 |
|
---|
943 | \sa whatsThis(), QWhatsThis::inWhatsThisMode(),
|
---|
944 | QMenuData::setWhatsThis(), QAction::setWhatsThis()
|
---|
945 | */
|
---|
946 | void QAccel::setWhatsThis( int id, const QString& text )
|
---|
947 | {
|
---|
948 |
|
---|
949 | QAccelItem *item = find_id( d->aitems, id);
|
---|
950 | if ( item )
|
---|
951 | item->whatsthis = text;
|
---|
952 | }
|
---|
953 |
|
---|
954 | /*!
|
---|
955 | Returns the What's This help text for the specified item \a id or
|
---|
956 | QString::null if no text has been specified.
|
---|
957 |
|
---|
958 | \sa setWhatsThis()
|
---|
959 | */
|
---|
960 | QString QAccel::whatsThis( int id ) const
|
---|
961 | {
|
---|
962 |
|
---|
963 | QAccelItem *item = find_id( d->aitems, id);
|
---|
964 | return item? item->whatsthis : QString::null;
|
---|
965 | }
|
---|
966 |
|
---|
967 | /*!\internal */
|
---|
968 | void QAccel::setIgnoreWhatsThis( bool b)
|
---|
969 | {
|
---|
970 | d->ignorewhatsthis = b;
|
---|
971 | }
|
---|
972 |
|
---|
973 | /*!\internal */
|
---|
974 | bool QAccel::ignoreWhatsThis() const
|
---|
975 | {
|
---|
976 | return d->ignorewhatsthis;
|
---|
977 | }
|
---|
978 |
|
---|
979 |
|
---|
980 | /*!
|
---|
981 |
|
---|
982 | \page accelerators.html
|
---|
983 |
|
---|
984 | \title Standard Accelerator Keys
|
---|
985 |
|
---|
986 | Applications invariably need to define accelerator keys for actions.
|
---|
987 | Qt fully supports accelerators, for example with \l QAccel::shortcutKey().
|
---|
988 |
|
---|
989 | Here are Microsoft's recommendations for accelerator keys, with
|
---|
990 | comments about the Open Group's recommendations where they exist
|
---|
991 | and differ. For most commands, the Open Group either has no advice or
|
---|
992 | agrees with Microsoft.
|
---|
993 |
|
---|
994 | The emboldened letter plus Alt is Microsoft's recommended choice, and
|
---|
995 | we recommend supporting it. For an Apply button, for example, we
|
---|
996 | recommend QButton::setText( \link QWidget::tr() tr \endlink("&Apply") );
|
---|
997 |
|
---|
998 | If you have conflicting commands (e.g. About and Apply buttons in the
|
---|
999 | same dialog), you must decide for yourself.
|
---|
1000 |
|
---|
1001 | \list
|
---|
1002 | \i <b><u>A</u></b>bout
|
---|
1003 | \i Always on <b><u>T</u></b>op
|
---|
1004 | \i <b><u>A</u></b>pply
|
---|
1005 | \i <b><u>B</u></b>ack
|
---|
1006 | \i <b><u>B</u></b>rowse
|
---|
1007 | \i <b><u>C</u></b>lose (CDE: Alt+F4; Alt+F4 is "close window" in Windows)
|
---|
1008 | \i <b><u>C</u></b>opy (CDE: Ctrl+C, Ctrl+Insert)
|
---|
1009 | \i <b><u>C</u></b>opy Here
|
---|
1010 | \i Create <b><u>S</u></b>hortcut
|
---|
1011 | \i Create <b><u>S</u></b>hortcut Here
|
---|
1012 | \i Cu<b><u>t</u></b>
|
---|
1013 | \i <b><u>D</u></b>elete
|
---|
1014 | \i <b><u>E</u></b>dit
|
---|
1015 | \i <b><u>E</u></b>xit (CDE: E<b><u>x</u></b>it)
|
---|
1016 | \i <b><u>E</u></b>xplore
|
---|
1017 | \i <b><u>F</u></b>ile
|
---|
1018 | \i <b><u>F</u></b>ind
|
---|
1019 | \i <b><u>H</u></b>elp
|
---|
1020 | \i Help <b><u>T</u></b>opics
|
---|
1021 | \i <b><u>H</u></b>ide
|
---|
1022 | \i <b><u>I</u></b>nsert
|
---|
1023 | \i Insert <b><u>O</u></b>bject
|
---|
1024 | \i <b><u>L</u></b>ink Here
|
---|
1025 | \i Ma<b><u>x</u></b>imize
|
---|
1026 | \i Mi<b><u>n</u></b>imize
|
---|
1027 | \i <b><u>M</u></b>ove
|
---|
1028 | \i <b><u>M</u></b>ove Here
|
---|
1029 | \i <b><u>N</u></b>ew
|
---|
1030 | \i <b><u>N</u></b>ext
|
---|
1031 | \i <b><u>N</u></b>o
|
---|
1032 | \i <b><u>O</u></b>pen
|
---|
1033 | \i Open <b><u>W</u></b>ith
|
---|
1034 | \i Page Set<b><u>u</u></b>p
|
---|
1035 | \i <b><u>P</u></b>aste
|
---|
1036 | \i Paste <b><u>L</u></b>ink
|
---|
1037 | \i Paste <b><u>S</u></b>hortcut
|
---|
1038 | \i Paste <b><u>S</u></b>pecial
|
---|
1039 | \i <b><u>P</u></b>ause
|
---|
1040 | \i <b><u>P</u></b>lay
|
---|
1041 | \i <b><u>P</u></b>rint
|
---|
1042 | \i <b><u>P</u></b>rint Here
|
---|
1043 | \i P<b><u>r</u></b>operties
|
---|
1044 | \i <b><u>Q</u></b>uick View
|
---|
1045 | \i <b><u>R</u></b>edo (CDE: Ctrl+Y, Shift+Alt+Backspace)
|
---|
1046 | \i <b><u>R</u></b>epeat
|
---|
1047 | \i <b><u>R</u></b>estore
|
---|
1048 | \i <b><u>R</u></b>esume
|
---|
1049 | \i <b><u>R</u></b>etry
|
---|
1050 | \i <b><u>R</u></b>un
|
---|
1051 | \i <b><u>S</u></b>ave
|
---|
1052 | \i Save <b><u>A</u></b>s
|
---|
1053 | \i Select <b><u>A</u></b>ll
|
---|
1054 | \i Se<b><u>n</u></b>d To
|
---|
1055 | \i <b><u>S</u></b>how
|
---|
1056 | \i <b><u>S</u></b>ize
|
---|
1057 | \i S<b><u>p</u></b>lit
|
---|
1058 | \i <b><u>S</u></b>top
|
---|
1059 | \i <b><u>U</u></b>ndo (CDE: Ctrl+Z or Alt+Backspace)
|
---|
1060 | \i <b><u>V</u></b>iew
|
---|
1061 | \i <b><u>W</u></b>hat's This?
|
---|
1062 | \i <b><u>W</u></b>indow
|
---|
1063 | \i <b><u>Y</u></b>es
|
---|
1064 | \endlist
|
---|
1065 |
|
---|
1066 | There are also a lot of other keys and actions (that use other
|
---|
1067 | modifier keys than Alt). See the Microsoft and The Open Group
|
---|
1068 | documentation for details.
|
---|
1069 |
|
---|
1070 | The \link http://www.amazon.com/exec/obidos/ASIN/0735605661/trolltech/t
|
---|
1071 | Microsoft book \endlink has ISBN 0735605661. The corresponding Open Group
|
---|
1072 | book is very hard to find, rather expensive and we cannot recommend
|
---|
1073 | it. However, if you really want it, OGPubs@opengroup.org might be able
|
---|
1074 | to help. Ask them for ISBN 1859121047.
|
---|
1075 |
|
---|
1076 | */
|
---|
1077 |
|
---|
1078 | /*! \obsolete serves no purpose anymore */
|
---|
1079 | void QAccel::repairEventFilter() {}
|
---|
1080 | /*! \obsolete serves no purpose anymore */
|
---|
1081 | bool QAccel::eventFilter( QObject *, QEvent * ) { return FALSE; }
|
---|
1082 | #endif // QT_NO_ACCEL
|
---|