/**************************************************************************** | |
** | |
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). | |
** All rights reserved. | |
** Contact: Nokia Corporation (qt-info@nokia.com) | |
** | |
** This file is part of the QtGui module of the Qt Toolkit. | |
** | |
** $QT_BEGIN_LICENSE:LGPL$ | |
** GNU Lesser General Public License Usage | |
** This file may be used under the terms of the GNU Lesser General Public | |
** License version 2.1 as published by the Free Software Foundation and | |
** appearing in the file LICENSE.LGPL included in the packaging of this | |
** file. Please review the following information to ensure the GNU Lesser | |
** General Public License version 2.1 requirements will be met: | |
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. | |
** | |
** In addition, as a special exception, Nokia gives you certain additional | |
** rights. These rights are described in the Nokia Qt LGPL Exception | |
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. | |
** | |
** GNU General Public License Usage | |
** Alternatively, this file may be used under the terms of the GNU General | |
** Public License version 3.0 as published by the Free Software Foundation | |
** and appearing in the file LICENSE.GPL included in the packaging of this | |
** file. Please review the following information to ensure the GNU General | |
** Public License version 3.0 requirements will be met: | |
** http://www.gnu.org/copyleft/gpl.html. | |
** | |
** Other Usage | |
** Alternatively, this file may be used in accordance with the terms and | |
** conditions contained in a signed written agreement between you and Nokia. | |
** | |
** | |
** | |
** | |
** | |
** $QT_END_LICENSE$ | |
** | |
****************************************************************************/ | |
#include "qshortcut.h" | |
#include "private/qwidget_p.h" | |
#ifndef QT_NO_SHORTCUT | |
#include <qevent.h> | |
#include <qwhatsthis.h> | |
#include <qmenu.h> | |
#include <qapplication.h> | |
#include <private/qapplication_p.h> | |
#include <private/qshortcutmap_p.h> | |
QT_BEGIN_NAMESPACE | |
#define QAPP_CHECK(functionName) \ | |
if (!qApp) { \ | |
qWarning("QShortcut: Initialize QApplication before calling '" functionName "'."); \ | |
return; \ | |
} | |
/*! | |
\class QShortcut | |
\brief The QShortcut class is used to create keyboard shortcuts. | |
\ingroup events | |
The QShortcut class provides a way of connecting keyboard | |
shortcuts to Qt's \l{signals and slots} mechanism, so that | |
objects can be informed when a shortcut is executed. The shortcut | |
can be set up to contain all the key presses necessary to | |
describe a keyboard shortcut, including the states of modifier | |
keys such as \gui Shift, \gui Ctrl, and \gui Alt. | |
\target mnemonic | |
On certain widgets, using '&' in front of a character will | |
automatically create a mnemonic (a shortcut) for that character, | |
e.g. "E&xit" will create the shortcut \gui Alt+X (use '&&' to | |
display an actual ampersand). The widget might consume and perform | |
an action on a given shortcut. On X11 the ampersand will not be | |
shown and the character will be underlined. On Windows, shortcuts | |
are normally not displayed until the user presses the \gui Alt | |
key, but this is a setting the user can change. On Mac, shortcuts | |
are disabled by default. Call qt_set_sequence_auto_mnemonic() to | |
enable them. However, because mnemonic shortcuts do not fit in | |
with Aqua's guidelines, Qt will not show the shortcut character | |
underlined. | |
For applications that use menus, it may be more convenient to | |
use the convenience functions provided in the QMenu class to | |
assign keyboard shortcuts to menu items as they are created. | |
Alternatively, shortcuts may be associated with other types of | |
actions in the QAction class. | |
The simplest way to create a shortcut for a particular widget is | |
to construct the shortcut with a key sequence. For example: | |
\snippet doc/src/snippets/code/src_gui_kernel_qshortcut.cpp 0 | |
When the user types the \l{QKeySequence}{key sequence} | |
for a given shortcut, the shortcut's activated() signal is | |
emitted. (In the case of ambiguity, the activatedAmbiguously() | |
signal is emitted.) A shortcut is "listened for" by Qt's event | |
loop when the shortcut's parent widget is receiving events. | |
A shortcut's key sequence can be set with setKey() and retrieved | |
with key(). A shortcut can be enabled or disabled with | |
setEnabled(), and can have "What's This?" help text set with | |
setWhatsThis(). | |
\sa QShortcutEvent, QKeySequence, QAction | |
*/ | |
/*! | |
\fn QWidget *QShortcut::parentWidget() const | |
Returns the shortcut's parent widget. | |
*/ | |
/*! | |
\fn void QShortcut::activated() | |
This signal is emitted when the user types the shortcut's key | |
sequence. | |
\sa activatedAmbiguously() | |
*/ | |
/*! | |
\fn void QShortcut::activatedAmbiguously() | |
When a key sequence is being typed at the keyboard, it is said to | |
be ambiguous as long as it matches the start of more than one | |
shortcut. | |
When a shortcut's key sequence is completed, | |
activatedAmbiguously() is emitted if the key sequence is still | |
ambiguous (i.e., it is the start of one or more other shortcuts). | |
The activated() signal is not emitted in this case. | |
\sa activated() | |
*/ | |
/* | |
\internal | |
Private data accessed through d-pointer. | |
*/ | |
class QShortcutPrivate : public QObjectPrivate | |
{ | |
Q_DECLARE_PUBLIC(QShortcut) | |
public: | |
QShortcutPrivate() : sc_context(Qt::WindowShortcut), sc_enabled(true), sc_autorepeat(true), sc_id(0) {} | |
QKeySequence sc_sequence; | |
Qt::ShortcutContext sc_context; | |
bool sc_enabled; | |
bool sc_autorepeat; | |
int sc_id; | |
QString sc_whatsthis; | |
void redoGrab(QShortcutMap &map); | |
}; | |
void QShortcutPrivate::redoGrab(QShortcutMap &map) | |
{ | |
Q_Q(QShortcut); | |
if (!parent) { | |
qWarning("QShortcut: No widget parent defined"); | |
return; | |
} | |
if (sc_id) | |
map.removeShortcut(sc_id, q); | |
if (sc_sequence.isEmpty()) | |
return; | |
sc_id = map.addShortcut(q, sc_sequence, sc_context); | |
if (!sc_enabled) | |
map.setShortcutEnabled(false, sc_id, q); | |
if (!sc_autorepeat) | |
map.setShortcutAutoRepeat(false, sc_id, q); | |
} | |
/*! | |
Constructs a QShortcut object for the \a parent widget. Since no | |
shortcut key sequence is specified, the shortcut will not emit any | |
signals. | |
\sa setKey() | |
*/ | |
QShortcut::QShortcut(QWidget *parent) | |
: QObject(*new QShortcutPrivate, parent) | |
{ | |
Q_ASSERT(parent != 0); | |
} | |
/*! | |
Constructs a QShortcut object for the \a parent widget. The shortcut | |
operates on its parent, listening for \l{QShortcutEvent}s that | |
match the \a key sequence. Depending on the ambiguity of the | |
event, the shortcut will call the \a member function, or the \a | |
ambiguousMember function, if the key press was in the shortcut's | |
\a context. | |
*/ | |
QShortcut::QShortcut(const QKeySequence &key, QWidget *parent, | |
const char *member, const char *ambiguousMember, | |
Qt::ShortcutContext context) | |
: QObject(*new QShortcutPrivate, parent) | |
{ | |
QAPP_CHECK("QShortcut"); | |
Q_D(QShortcut); | |
Q_ASSERT(parent != 0); | |
d->sc_context = context; | |
d->sc_sequence = key; | |
d->redoGrab(qApp->d_func()->shortcutMap); | |
if (member) | |
connect(this, SIGNAL(activated()), parent, member); | |
if (ambiguousMember) | |
connect(this, SIGNAL(activatedAmbiguously()), parent, ambiguousMember); | |
} | |
/*! | |
Destroys the shortcut. | |
*/ | |
QShortcut::~QShortcut() | |
{ | |
Q_D(QShortcut); | |
if (qApp) | |
qApp->d_func()->shortcutMap.removeShortcut(d->sc_id, this); | |
} | |
/*! | |
\property QShortcut::key | |
\brief the shortcut's key sequence | |
This is a key sequence with an optional combination of Shift, Ctrl, | |
and Alt. The key sequence may be supplied in a number of ways: | |
\snippet doc/src/snippets/code/src_gui_kernel_qshortcut.cpp 1 | |
By default, this property contains an empty key sequence. | |
*/ | |
void QShortcut::setKey(const QKeySequence &key) | |
{ | |
Q_D(QShortcut); | |
if (d->sc_sequence == key) | |
return; | |
QAPP_CHECK("setKey"); | |
d->sc_sequence = key; | |
d->redoGrab(qApp->d_func()->shortcutMap); | |
} | |
QKeySequence QShortcut::key() const | |
{ | |
Q_D(const QShortcut); | |
return d->sc_sequence; | |
} | |
/*! | |
\property QShortcut::enabled | |
\brief whether the shortcut is enabled | |
An enabled shortcut emits the activated() or activatedAmbiguously() | |
signal when a QShortcutEvent occurs that matches the shortcut's | |
key() sequence. | |
If the application is in \c WhatsThis mode the shortcut will not emit | |
the signals, but will show the "What's This?" text instead. | |
By default, this property is true. | |
\sa whatsThis | |
*/ | |
void QShortcut::setEnabled(bool enable) | |
{ | |
Q_D(QShortcut); | |
if (d->sc_enabled == enable) | |
return; | |
QAPP_CHECK("setEnabled"); | |
d->sc_enabled = enable; | |
qApp->d_func()->shortcutMap.setShortcutEnabled(enable, d->sc_id, this); | |
} | |
bool QShortcut::isEnabled() const | |
{ | |
Q_D(const QShortcut); | |
return d->sc_enabled; | |
} | |
/*! | |
\property QShortcut::context | |
\brief the context in which the shortcut is valid | |
A shortcut's context decides in which circumstances a shortcut is | |
allowed to be triggered. The normal context is Qt::WindowShortcut, | |
which allows the shortcut to trigger if the parent (the widget | |
containing the shortcut) is a subwidget of the active top-level | |
window. | |
By default, this property is set to Qt::WindowShortcut. | |
*/ | |
void QShortcut::setContext(Qt::ShortcutContext context) | |
{ | |
Q_D(QShortcut); | |
if(d->sc_context == context) | |
return; | |
QAPP_CHECK("setContext"); | |
d->sc_context = context; | |
d->redoGrab(qApp->d_func()->shortcutMap); | |
} | |
Qt::ShortcutContext QShortcut::context() | |
{ | |
Q_D(QShortcut); | |
return d->sc_context; | |
} | |
/*! | |
\property QShortcut::whatsThis | |
\brief the shortcut's "What's This?" help text | |
The text will be shown when the application is in "What's | |
This?" mode and the user types the shortcut key() sequence. | |
To set "What's This?" help on a menu item (with or without a | |
shortcut key), set the help on the item's action. | |
By default, this property contains an empty string. | |
\sa QWhatsThis::inWhatsThisMode(), QAction::setWhatsThis() | |
*/ | |
void QShortcut::setWhatsThis(const QString &text) | |
{ | |
Q_D(QShortcut); | |
d->sc_whatsthis = text; | |
} | |
QString QShortcut::whatsThis() const | |
{ | |
Q_D(const QShortcut); | |
return d->sc_whatsthis; | |
} | |
/*! | |
\property QShortcut::autoRepeat | |
\brief whether the shortcut can auto repeat | |
\since 4.2 | |
If true, the shortcut will auto repeat when the keyboard shortcut | |
combination is held down, provided that keyboard auto repeat is | |
enabled on the system. | |
The default value is true. | |
*/ | |
void QShortcut::setAutoRepeat(bool on) | |
{ | |
Q_D(QShortcut); | |
if (d->sc_autorepeat == on) | |
return; | |
QAPP_CHECK("setAutoRepeat"); | |
d->sc_autorepeat = on; | |
qApp->d_func()->shortcutMap.setShortcutAutoRepeat(on, d->sc_id, this); | |
} | |
bool QShortcut::autoRepeat() const | |
{ | |
Q_D(const QShortcut); | |
return d->sc_autorepeat; | |
} | |
/*! | |
Returns the shortcut's ID. | |
\sa QShortcutEvent::shortcutId() | |
*/ | |
int QShortcut::id() const | |
{ | |
Q_D(const QShortcut); | |
return d->sc_id; | |
} | |
/*! | |
\internal | |
*/ | |
bool QShortcut::event(QEvent *e) | |
{ | |
Q_D(QShortcut); | |
bool handled = false; | |
if (d->sc_enabled && e->type() == QEvent::Shortcut) { | |
QShortcutEvent *se = static_cast<QShortcutEvent *>(e); | |
if (se->shortcutId() == d->sc_id && se->key() == d->sc_sequence){ | |
#ifndef QT_NO_WHATSTHIS | |
if (QWhatsThis::inWhatsThisMode()) { | |
QWhatsThis::showText(QCursor::pos(), d->sc_whatsthis); | |
handled = true; | |
} else | |
#endif | |
if (se->isAmbiguous()) | |
emit activatedAmbiguously(); | |
else | |
emit activated(); | |
handled = true; | |
} | |
} | |
return handled; | |
} | |
#endif // QT_NO_SHORTCUT | |
QT_END_NAMESPACE |