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

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

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

File size: 12.0 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 "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 \mainclass
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 QWidget *parent = q->parentWidget();
167 if (!parent) {
168 qWarning("QShortcut: No widget parent defined");
169 return;
170 }
171
172 if (sc_id)
173 map.removeShortcut(sc_id, q);
174 if (sc_sequence.isEmpty())
175 return;
176 sc_id = map.addShortcut(q, sc_sequence, sc_context);
177 if (!sc_enabled)
178 map.setShortcutEnabled(false, sc_id, q);
179 if (!sc_autorepeat)
180 map.setShortcutAutoRepeat(false, sc_id, q);
181}
182
183/*!
184 Constructs a QShortcut object for the \a parent widget. Since no
185 shortcut key sequence is specified, the shortcut will not emit any
186 signals.
187
188 \sa setKey()
189*/
190QShortcut::QShortcut(QWidget *parent)
191 : QObject(*new QShortcutPrivate, parent)
192{
193 Q_ASSERT(parent != 0);
194}
195
196/*!
197 Constructs a QShortcut object for the \a parent widget. The shortcut
198 operates on its parent, listening for \l{QShortcutEvent}s that
199 match the \a key sequence. Depending on the ambiguity of the
200 event, the shortcut will call the \a member function, or the \a
201 ambiguousMember function, if the key press was in the shortcut's
202 \a context.
203*/
204QShortcut::QShortcut(const QKeySequence &key, QWidget *parent,
205 const char *member, const char *ambiguousMember,
206 Qt::ShortcutContext context)
207 : QObject(*new QShortcutPrivate, parent)
208{
209 QAPP_CHECK("QShortcut");
210
211 Q_D(QShortcut);
212 Q_ASSERT(parent != 0);
213 d->sc_context = context;
214 d->sc_sequence = key;
215 d->redoGrab(qApp->d_func()->shortcutMap);
216 if (member)
217 connect(this, SIGNAL(activated()), parent, member);
218 if (ambiguousMember)
219 connect(this, SIGNAL(activatedAmbiguously()), parent, ambiguousMember);
220}
221
222/*!
223 Destroys the shortcut.
224*/
225QShortcut::~QShortcut()
226{
227 Q_D(QShortcut);
228 if (qApp)
229 qApp->d_func()->shortcutMap.removeShortcut(d->sc_id, this);
230}
231
232/*!
233 \property QShortcut::key
234 \brief the shortcut's key sequence
235
236 This is a key sequence with an optional combination of Shift, Ctrl,
237 and Alt. The key sequence may be supplied in a number of ways:
238
239 \snippet doc/src/snippets/code/src_gui_kernel_qshortcut.cpp 1
240
241 By default, this property contains an empty key sequence.
242*/
243void QShortcut::setKey(const QKeySequence &key)
244{
245 Q_D(QShortcut);
246 if (d->sc_sequence == key)
247 return;
248 QAPP_CHECK("setKey");
249 d->sc_sequence = key;
250 d->redoGrab(qApp->d_func()->shortcutMap);
251}
252
253QKeySequence QShortcut::key() const
254{
255 Q_D(const QShortcut);
256 return d->sc_sequence;
257}
258
259/*!
260 \property QShortcut::enabled
261 \brief whether the shortcut is enabled
262
263 An enabled shortcut emits the activated() or activatedAmbiguously()
264 signal when a QShortcutEvent occurs that matches the shortcut's
265 key() sequence.
266
267 If the application is in \c WhatsThis mode the shortcut will not emit
268 the signals, but will show the "What's This?" text instead.
269
270 By default, this property is true.
271
272 \sa whatsThis
273*/
274void QShortcut::setEnabled(bool enable)
275{
276 Q_D(QShortcut);
277 if (d->sc_enabled == enable)
278 return;
279 QAPP_CHECK("setEnabled");
280 d->sc_enabled = enable;
281 qApp->d_func()->shortcutMap.setShortcutEnabled(enable, d->sc_id, this);
282}
283
284bool QShortcut::isEnabled() const
285{
286 Q_D(const QShortcut);
287 return d->sc_enabled;
288}
289
290/*!
291 \property QShortcut::context
292 \brief the context in which the shortcut is valid
293
294 A shortcut's context decides in which circumstances a shortcut is
295 allowed to be triggered. The normal context is Qt::WindowShortcut,
296 which allows the shortcut to trigger if the parent (the widget
297 containing the shortcut) is a subwidget of the active top-level
298 window.
299
300 By default, this property is set to Qt::WindowShortcut.
301*/
302void QShortcut::setContext(Qt::ShortcutContext context)
303{
304 Q_D(QShortcut);
305 if(d->sc_context == context)
306 return;
307 QAPP_CHECK("setContext");
308 d->sc_context = context;
309 d->redoGrab(qApp->d_func()->shortcutMap);
310}
311
312Qt::ShortcutContext QShortcut::context()
313{
314 Q_D(QShortcut);
315 return d->sc_context;
316}
317
318/*!
319 \property QShortcut::whatsThis
320 \brief the shortcut's "What's This?" help text
321
322 The text will be shown when the application is in "What's
323 This?" mode and the user types the shortcut key() sequence.
324
325 To set "What's This?" help on a menu item (with or without a
326 shortcut key), set the help on the item's action.
327
328 By default, this property contains an empty string.
329
330 \sa QWhatsThis::inWhatsThisMode(), QAction::setWhatsThis()
331*/
332void QShortcut::setWhatsThis(const QString &text)
333{
334 Q_D(QShortcut);
335 d->sc_whatsthis = text;
336}
337
338QString QShortcut::whatsThis() const
339{
340 Q_D(const QShortcut);
341 return d->sc_whatsthis;
342}
343
344/*!
345 \property QShortcut::autoRepeat
346 \brief whether the shortcut can auto repeat
347 \since 4.2
348
349 If true, the shortcut will auto repeat when the keyboard shortcut
350 combination is held down, provided that keyboard auto repeat is
351 enabled on the system.
352 The default value is true.
353*/
354void QShortcut::setAutoRepeat(bool on)
355{
356 Q_D(QShortcut);
357 if (d->sc_autorepeat == on)
358 return;
359 QAPP_CHECK("setAutoRepeat");
360 d->sc_autorepeat = on;
361 qApp->d_func()->shortcutMap.setShortcutAutoRepeat(on, d->sc_id, this);
362}
363
364bool QShortcut::autoRepeat() const
365{
366 Q_D(const QShortcut);
367 return d->sc_autorepeat;
368}
369
370/*!
371 Returns the shortcut's ID.
372
373 \sa QShortcutEvent::shortcutId()
374*/
375int QShortcut::id() const
376{
377 Q_D(const QShortcut);
378 return d->sc_id;
379}
380
381/*!
382 \internal
383*/
384bool QShortcut::event(QEvent *e)
385{
386 Q_D(QShortcut);
387 bool handled = false;
388 if (d->sc_enabled && e->type() == QEvent::Shortcut) {
389 QShortcutEvent *se = static_cast<QShortcutEvent *>(e);
390 if (se->shortcutId() == d->sc_id && se->key() == d->sc_sequence){
391#ifndef QT_NO_WHATSTHIS
392 if (QWhatsThis::inWhatsThisMode()) {
393 QWhatsThis::showText(QCursor::pos(), d->sc_whatsthis);
394 handled = true;
395 } else
396#endif
397 if (se->isAmbiguous())
398 emit activatedAmbiguously();
399 else
400 emit activated();
401 handled = true;
402 }
403 }
404 return handled;
405}
406#endif // QT_NO_SHORTCUT
407
408QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.