source: trunk/src/gui/kernel/qshortcut.cpp@ 858

Last change on this file since 858 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 11.9 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the QtGui module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qshortcut.h"
43#include "private/qwidget_p.h"
44
45#ifndef QT_NO_SHORTCUT
46#include <qevent.h>
47#include <qwhatsthis.h>
48#include <qmenu.h>
49#include <qapplication.h>
50#include <private/qapplication_p.h>
51#include <private/qshortcutmap_p.h>
52
53QT_BEGIN_NAMESPACE
54
55#define QAPP_CHECK(functionName) \
56 if (!qApp) { \
57 qWarning("QShortcut: Initialize QApplication before calling '" functionName "'."); \
58 return; \
59 }
60
61/*!
62 \class QShortcut
63 \brief The QShortcut class is used to create keyboard shortcuts.
64
65 \ingroup events
66
67
68 The QShortcut class provides a way of connecting keyboard
69 shortcuts to Qt's \l{signals and slots} mechanism, so that
70 objects can be informed when a shortcut is executed. The shortcut
71 can be set up to contain all the key presses necessary to
72 describe a keyboard shortcut, including the states of modifier
73 keys such as \gui Shift, \gui Ctrl, and \gui Alt.
74
75 \target mnemonic
76
77 On certain widgets, using '&' in front of a character will
78 automatically create a mnemonic (a shortcut) for that character,
79 e.g. "E&xit" will create the shortcut \gui Alt+X (use '&&' to
80 display an actual ampersand). The widget might consume and perform
81 an action on a given shortcut. On X11 the ampersand will not be
82 shown and the character will be underlined. On Windows, shortcuts
83 are normally not displayed until the user presses the \gui Alt
84 key, but this is a setting the user can change. On Mac, shortcuts
85 are disabled by default. Call qt_set_sequence_auto_mnemonic() to
86 enable them. However, because mnemonic shortcuts do not fit in
87 with Aqua's guidelines, Qt will not show the shortcut character
88 underlined.
89
90 For applications that use menus, it may be more convenient to
91 use the convenience functions provided in the QMenu class to
92 assign keyboard shortcuts to menu items as they are created.
93 Alternatively, shortcuts may be associated with other types of
94 actions in the QAction class.
95
96 The simplest way to create a shortcut for a particular widget is
97 to construct the shortcut with a key sequence. For example:
98
99 \snippet doc/src/snippets/code/src_gui_kernel_qshortcut.cpp 0
100
101 When the user types the \l{QKeySequence}{key sequence}
102 for a given shortcut, the shortcut's activated() signal is
103 emitted. (In the case of ambiguity, the activatedAmbiguously()
104 signal is emitted.) A shortcut is "listened for" by Qt's event
105 loop when the shortcut's parent widget is receiving events.
106
107 A shortcut's key sequence can be set with setKey() and retrieved
108 with key(). A shortcut can be enabled or disabled with
109 setEnabled(), and can have "What's This?" help text set with
110 setWhatsThis().
111
112 \sa QShortcutEvent, QKeySequence, QAction
113*/
114
115/*!
116 \fn QWidget *QShortcut::parentWidget() const
117
118 Returns the shortcut's parent widget.
119*/
120
121/*!
122 \fn void QShortcut::activated()
123
124 This signal is emitted when the user types the shortcut's key
125 sequence.
126
127 \sa activatedAmbiguously()
128*/
129
130/*!
131 \fn void QShortcut::activatedAmbiguously()
132
133 When a key sequence is being typed at the keyboard, it is said to
134 be ambiguous as long as it matches the start of more than one
135 shortcut.
136
137 When a shortcut's key sequence is completed,
138 activatedAmbiguously() is emitted if the key sequence is still
139 ambiguous (i.e., it is the start of one or more other shortcuts).
140 The activated() signal is not emitted in this case.
141
142 \sa activated()
143*/
144
145/*
146 \internal
147 Private data accessed through d-pointer.
148*/
149class QShortcutPrivate : public QObjectPrivate
150{
151 Q_DECLARE_PUBLIC(QShortcut)
152public:
153 QShortcutPrivate() : sc_context(Qt::WindowShortcut), sc_enabled(true), sc_autorepeat(true), sc_id(0) {}
154 QKeySequence sc_sequence;
155 Qt::ShortcutContext sc_context;
156 bool sc_enabled;
157 bool sc_autorepeat;
158 int sc_id;
159 QString sc_whatsthis;
160 void redoGrab(QShortcutMap &map);
161};
162
163void QShortcutPrivate::redoGrab(QShortcutMap &map)
164{
165 Q_Q(QShortcut);
166 if (!parent) {
167 qWarning("QShortcut: No widget parent defined");
168 return;
169 }
170
171 if (sc_id)
172 map.removeShortcut(sc_id, q);
173 if (sc_sequence.isEmpty())
174 return;
175 sc_id = map.addShortcut(q, sc_sequence, sc_context);
176 if (!sc_enabled)
177 map.setShortcutEnabled(false, sc_id, q);
178 if (!sc_autorepeat)
179 map.setShortcutAutoRepeat(false, sc_id, q);
180}
181
182/*!
183 Constructs a QShortcut object for the \a parent widget. Since no
184 shortcut key sequence is specified, the shortcut will not emit any
185 signals.
186
187 \sa setKey()
188*/
189QShortcut::QShortcut(QWidget *parent)
190 : QObject(*new QShortcutPrivate, parent)
191{
192 Q_ASSERT(parent != 0);
193}
194
195/*!
196 Constructs a QShortcut object for the \a parent widget. The shortcut
197 operates on its parent, listening for \l{QShortcutEvent}s that
198 match the \a key sequence. Depending on the ambiguity of the
199 event, the shortcut will call the \a member function, or the \a
200 ambiguousMember function, if the key press was in the shortcut's
201 \a context.
202*/
203QShortcut::QShortcut(const QKeySequence &key, QWidget *parent,
204 const char *member, const char *ambiguousMember,
205 Qt::ShortcutContext context)
206 : QObject(*new QShortcutPrivate, parent)
207{
208 QAPP_CHECK("QShortcut");
209
210 Q_D(QShortcut);
211 Q_ASSERT(parent != 0);
212 d->sc_context = context;
213 d->sc_sequence = key;
214 d->redoGrab(qApp->d_func()->shortcutMap);
215 if (member)
216 connect(this, SIGNAL(activated()), parent, member);
217 if (ambiguousMember)
218 connect(this, SIGNAL(activatedAmbiguously()), parent, ambiguousMember);
219}
220
221/*!
222 Destroys the shortcut.
223*/
224QShortcut::~QShortcut()
225{
226 Q_D(QShortcut);
227 if (qApp)
228 qApp->d_func()->shortcutMap.removeShortcut(d->sc_id, this);
229}
230
231/*!
232 \property QShortcut::key
233 \brief the shortcut's key sequence
234
235 This is a key sequence with an optional combination of Shift, Ctrl,
236 and Alt. The key sequence may be supplied in a number of ways:
237
238 \snippet doc/src/snippets/code/src_gui_kernel_qshortcut.cpp 1
239
240 By default, this property contains an empty key sequence.
241*/
242void QShortcut::setKey(const QKeySequence &key)
243{
244 Q_D(QShortcut);
245 if (d->sc_sequence == key)
246 return;
247 QAPP_CHECK("setKey");
248 d->sc_sequence = key;
249 d->redoGrab(qApp->d_func()->shortcutMap);
250}
251
252QKeySequence QShortcut::key() const
253{
254 Q_D(const QShortcut);
255 return d->sc_sequence;
256}
257
258/*!
259 \property QShortcut::enabled
260 \brief whether the shortcut is enabled
261
262 An enabled shortcut emits the activated() or activatedAmbiguously()
263 signal when a QShortcutEvent occurs that matches the shortcut's
264 key() sequence.
265
266 If the application is in \c WhatsThis mode the shortcut will not emit
267 the signals, but will show the "What's This?" text instead.
268
269 By default, this property is true.
270
271 \sa whatsThis
272*/
273void QShortcut::setEnabled(bool enable)
274{
275 Q_D(QShortcut);
276 if (d->sc_enabled == enable)
277 return;
278 QAPP_CHECK("setEnabled");
279 d->sc_enabled = enable;
280 qApp->d_func()->shortcutMap.setShortcutEnabled(enable, d->sc_id, this);
281}
282
283bool QShortcut::isEnabled() const
284{
285 Q_D(const QShortcut);
286 return d->sc_enabled;
287}
288
289/*!
290 \property QShortcut::context
291 \brief the context in which the shortcut is valid
292
293 A shortcut's context decides in which circumstances a shortcut is
294 allowed to be triggered. The normal context is Qt::WindowShortcut,
295 which allows the shortcut to trigger if the parent (the widget
296 containing the shortcut) is a subwidget of the active top-level
297 window.
298
299 By default, this property is set to Qt::WindowShortcut.
300*/
301void QShortcut::setContext(Qt::ShortcutContext context)
302{
303 Q_D(QShortcut);
304 if(d->sc_context == context)
305 return;
306 QAPP_CHECK("setContext");
307 d->sc_context = context;
308 d->redoGrab(qApp->d_func()->shortcutMap);
309}
310
311Qt::ShortcutContext QShortcut::context()
312{
313 Q_D(QShortcut);
314 return d->sc_context;
315}
316
317/*!
318 \property QShortcut::whatsThis
319 \brief the shortcut's "What's This?" help text
320
321 The text will be shown when the application is in "What's
322 This?" mode and the user types the shortcut key() sequence.
323
324 To set "What's This?" help on a menu item (with or without a
325 shortcut key), set the help on the item's action.
326
327 By default, this property contains an empty string.
328
329 \sa QWhatsThis::inWhatsThisMode(), QAction::setWhatsThis()
330*/
331void QShortcut::setWhatsThis(const QString &text)
332{
333 Q_D(QShortcut);
334 d->sc_whatsthis = text;
335}
336
337QString QShortcut::whatsThis() const
338{
339 Q_D(const QShortcut);
340 return d->sc_whatsthis;
341}
342
343/*!
344 \property QShortcut::autoRepeat
345 \brief whether the shortcut can auto repeat
346 \since 4.2
347
348 If true, the shortcut will auto repeat when the keyboard shortcut
349 combination is held down, provided that keyboard auto repeat is
350 enabled on the system.
351 The default value is true.
352*/
353void QShortcut::setAutoRepeat(bool on)
354{
355 Q_D(QShortcut);
356 if (d->sc_autorepeat == on)
357 return;
358 QAPP_CHECK("setAutoRepeat");
359 d->sc_autorepeat = on;
360 qApp->d_func()->shortcutMap.setShortcutAutoRepeat(on, d->sc_id, this);
361}
362
363bool QShortcut::autoRepeat() const
364{
365 Q_D(const QShortcut);
366 return d->sc_autorepeat;
367}
368
369/*!
370 Returns the shortcut's ID.
371
372 \sa QShortcutEvent::shortcutId()
373*/
374int QShortcut::id() const
375{
376 Q_D(const QShortcut);
377 return d->sc_id;
378}
379
380/*!
381 \internal
382*/
383bool QShortcut::event(QEvent *e)
384{
385 Q_D(QShortcut);
386 bool handled = false;
387 if (d->sc_enabled && e->type() == QEvent::Shortcut) {
388 QShortcutEvent *se = static_cast<QShortcutEvent *>(e);
389 if (se->shortcutId() == d->sc_id && se->key() == d->sc_sequence){
390#ifndef QT_NO_WHATSTHIS
391 if (QWhatsThis::inWhatsThisMode()) {
392 QWhatsThis::showText(QCursor::pos(), d->sc_whatsthis);
393 handled = true;
394 } else
395#endif
396 if (se->isAmbiguous())
397 emit activatedAmbiguously();
398 else
399 emit activated();
400 handled = true;
401 }
402 }
403 return handled;
404}
405#endif // QT_NO_SHORTCUT
406
407QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.