From 044770f9b004ff364a1581a4a442bcad2e663325 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Wed, 12 Oct 2011 22:29:41 +0200 Subject: Move QShortcutMap to QtGui MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QShortcut stays in QtWidgets, what we need in QtGui is only the basic functionality of the shortcut map. QML can integrate directly with the map where required. Change-Id: Ie39e9242f24cbebf824e5c3d2926880325ea4187 Reviewed-by: Samuel Rødal --- src/gui/kernel/kernel.pri | 2 + src/gui/kernel/qshortcutmap.cpp | 697 +++++++++++++++++++++++++++++++ src/gui/kernel/qshortcutmap_p.h | 115 +++++ src/widgets/kernel/kernel.pri | 2 + src/widgets/kernel/qshortcut.cpp | 620 +++++++++++++++++++++++++++ src/widgets/kernel/qshortcut.h | 107 +++++ src/widgets/to_be_moved/qshortcut.cpp | 620 --------------------------- src/widgets/to_be_moved/qshortcut.h | 107 ----- src/widgets/to_be_moved/qshortcutmap.cpp | 697 ------------------------------- src/widgets/to_be_moved/qshortcutmap_p.h | 115 ----- src/widgets/to_be_moved/to_be_moved.pri | 7 - src/widgets/widgets.pro | 3 - 12 files changed, 1543 insertions(+), 1549 deletions(-) create mode 100644 src/gui/kernel/qshortcutmap.cpp create mode 100644 src/gui/kernel/qshortcutmap_p.h create mode 100644 src/widgets/kernel/qshortcut.cpp create mode 100644 src/widgets/kernel/qshortcut.h delete mode 100644 src/widgets/to_be_moved/qshortcut.cpp delete mode 100644 src/widgets/to_be_moved/qshortcut.h delete mode 100644 src/widgets/to_be_moved/qshortcutmap.cpp delete mode 100644 src/widgets/to_be_moved/qshortcutmap_p.h delete mode 100644 src/widgets/to_be_moved/to_be_moved.pri diff --git a/src/gui/kernel/kernel.pri b/src/gui/kernel/kernel.pri index 7bdd3079e8..318adcd9bd 100644 --- a/src/gui/kernel/kernel.pri +++ b/src/gui/kernel/kernel.pri @@ -19,6 +19,7 @@ HEADERS += \ kernel/qkeysequence_p.h \ kernel/qkeymapper_p.h \ kernel/qpalette.h \ + kernel/qshortcutmap_p.h \ kernel/qsessionmanager.h \ kernel/qwindowdefs.h \ kernel/qscreen.h \ @@ -37,6 +38,7 @@ SOURCES += \ kernel/qpalette.cpp \ kernel/qguivariant.cpp \ kernel/qscreen.cpp \ + kernel/qshortcutmap.cpp \ kernel/qstylehints.cpp qpa { diff --git a/src/gui/kernel/qshortcutmap.cpp b/src/gui/kernel/qshortcutmap.cpp new file mode 100644 index 0000000000..64b0aa1741 --- /dev/null +++ b/src/gui/kernel/qshortcutmap.cpp @@ -0,0 +1,697 @@ +/**************************************************************************** +** +** 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 "qshortcutmap_p.h" +#include "private/qobject_p.h" +#include "qkeysequence.h" +#include "qdebug.h" +#include "qevent.h" +#include "qvector.h" +#include "qcoreapplication.h" +#include + +#ifndef QT_NO_SHORTCUT + +QT_BEGIN_NAMESPACE + +// To enable verbose output uncomment below +//#define DEBUG_QSHORTCUTMAP + +/* \internal + Entry data for QShortcutMap + Contains: + Keysequence for entry + Pointer to parent owning the sequence +*/ + +struct QShortcutEntry +{ + QShortcutEntry() + : keyseq(0), context(Qt::WindowShortcut), enabled(false), autorepeat(1), id(0), owner(0), contextMatcher(0) + {} + + QShortcutEntry(const QKeySequence &k) + : keyseq(k), context(Qt::WindowShortcut), enabled(false), autorepeat(1), id(0), owner(0), contextMatcher(0) + {} + + QShortcutEntry(QObject *o, const QKeySequence &k, Qt::ShortcutContext c, int i, bool a, QShortcutMap::ContextMatcher m) + : keyseq(k), context(c), enabled(true), autorepeat(a), id(i), owner(o), contextMatcher(m) + {} + + bool correctContext() const { return contextMatcher(owner, context); } + + bool operator<(const QShortcutEntry &f) const + { return keyseq < f.keyseq; } + + QKeySequence keyseq; + Qt::ShortcutContext context; + bool enabled : 1; + bool autorepeat : 1; + signed int id; + QObject *owner; + QShortcutMap::ContextMatcher contextMatcher; +}; + +#if 0 //ndef QT_NO_DEBUG_STREAM +/*! \internal + QDebug operator<< for easy debug output of the shortcut entries. +*/ +static QDebug &operator<<(QDebug &dbg, const QShortcutEntry *se) { + if (!se) + return dbg << "QShortcutEntry(0x0)"; + dbg.nospace() + << "QShortcutEntry(" << se->keyseq + << "), id(" << se->id << "), enabled(" << se->enabled << "), autorepeat(" << se->autorepeat + << "), owner(" << se->owner << ')'; + return dbg.space(); +} +#endif // QT_NO_DEBUGSTREAM + +/* \internal + Private data for QShortcutMap +*/ +class QShortcutMapPrivate +{ + Q_DECLARE_PUBLIC(QShortcutMap) + +public: + QShortcutMapPrivate(QShortcutMap* parent) + : q_ptr(parent), currentId(0), ambigCount(0), currentState(QKeySequence::NoMatch) + { + identicals.reserve(10); + currentSequences.reserve(10); + } + QShortcutMap *q_ptr; // Private's parent + + QList sequences; // All sequences! + + int currentId; // Global shortcut ID number + int ambigCount; // Index of last enabled ambiguous dispatch + QKeySequence::SequenceMatch currentState; + QVector currentSequences; // Sequence for the current state + QVector newEntries; + QKeySequence prevSequence; // Sequence for the previous identical match + QVector identicals; // Last identical matches +}; + + +/*! \internal + QShortcutMap constructor. +*/ +QShortcutMap::QShortcutMap() + : d_ptr(new QShortcutMapPrivate(this)) +{ + resetState(); +} + +/*! \internal + QShortcutMap destructor. +*/ +QShortcutMap::~QShortcutMap() +{ +} + +/*! \internal + Adds a shortcut to the global map. + Returns the id of the newly added shortcut. +*/ +int QShortcutMap::addShortcut(QObject *owner, const QKeySequence &key, Qt::ShortcutContext context, ContextMatcher matcher) +{ + Q_ASSERT_X(owner, "QShortcutMap::addShortcut", "All shortcuts need an owner"); + Q_ASSERT_X(!key.isEmpty(), "QShortcutMap::addShortcut", "Cannot add keyless shortcuts to map"); + Q_D(QShortcutMap); + + QShortcutEntry newEntry(owner, key, context, --(d->currentId), true, matcher); + QList::iterator it = qUpperBound(d->sequences.begin(), d->sequences.end(), newEntry); + d->sequences.insert(it, newEntry); // Insert sorted +#if defined(DEBUG_QSHORTCUTMAP) + qDebug().nospace() + << "QShortcutMap::addShortcut(" << owner << ", " + << key << ", " << context << ") = " << d->currentId; +#endif + return d->currentId; +} + +/*! \internal + Removes a shortcut from the global map. + If \a owner is 0, all entries in the map with the key sequence specified + is removed. If \a key is null, all sequences for \a owner is removed from + the map. If \a id is 0, any identical \a key sequences owned by \a owner + are removed. + Returns the number of sequences removed from the map. +*/ + +int QShortcutMap::removeShortcut(int id, QObject *owner, const QKeySequence &key) +{ + Q_D(QShortcutMap); + int itemsRemoved = 0; + bool allOwners = (owner == 0); + bool allKeys = key.isEmpty(); + bool allIds = id == 0; + + // Special case, remove everything + if (allOwners && allKeys && id == 0) { + itemsRemoved = d->sequences.size(); + d->sequences.clear(); + return itemsRemoved; + } + + int i = d->sequences.size()-1; + while (i>=0) + { + const QShortcutEntry &entry = d->sequences.at(i); + int entryId = entry.id; + if ((allOwners || entry.owner == owner) + && (allIds || entry.id == id) + && (allKeys || entry.keyseq == key)) { + d->sequences.removeAt(i); + ++itemsRemoved; + } + if (id == entryId) + return itemsRemoved; + --i; + } +#if defined(DEBUG_QSHORTCUTMAP) + qDebug().nospace() + << "QShortcutMap::removeShortcut(" << id << ", " << owner << ", " + << key << ") = " << itemsRemoved; +#endif + return itemsRemoved; +} + +/*! \internal + Changes the enable state of a shortcut to \a enable. + If \a owner is 0, all entries in the map with the key sequence specified + is removed. If \a key is null, all sequences for \a owner is removed from + the map. If \a id is 0, any identical \a key sequences owned by \a owner + are changed. + Returns the number of sequences which are matched in the map. +*/ +int QShortcutMap::setShortcutEnabled(bool enable, int id, QObject *owner, const QKeySequence &key) +{ + Q_D(QShortcutMap); + int itemsChanged = 0; + bool allOwners = (owner == 0); + bool allKeys = key.isEmpty(); + bool allIds = id == 0; + + int i = d->sequences.size()-1; + while (i>=0) + { + QShortcutEntry entry = d->sequences.at(i); + if ((allOwners || entry.owner == owner) + && (allIds || entry.id == id) + && (allKeys || entry.keyseq == key)) { + d->sequences[i].enabled = enable; + ++itemsChanged; + } + if (id == entry.id) + return itemsChanged; + --i; + } +#if defined(DEBUG_QSHORTCUTMAP) + qDebug().nospace() + << "QShortcutMap::setShortcutEnabled(" << enable << ", " << id << ", " + << owner << ", " << key << ") = " << itemsChanged; +#endif + return itemsChanged; +} + +/*! \internal + Changes the auto repeat state of a shortcut to \a enable. + If \a owner is 0, all entries in the map with the key sequence specified + is removed. If \a key is null, all sequences for \a owner is removed from + the map. If \a id is 0, any identical \a key sequences owned by \a owner + are changed. + Returns the number of sequences which are matched in the map. +*/ +int QShortcutMap::setShortcutAutoRepeat(bool on, int id, QObject *owner, const QKeySequence &key) +{ + Q_D(QShortcutMap); + int itemsChanged = 0; + bool allOwners = (owner == 0); + bool allKeys = key.isEmpty(); + bool allIds = id == 0; + + int i = d->sequences.size()-1; + while (i>=0) + { + QShortcutEntry entry = d->sequences.at(i); + if ((allOwners || entry.owner == owner) + && (allIds || entry.id == id) + && (allKeys || entry.keyseq == key)) { + d->sequences[i].autorepeat = on; + ++itemsChanged; + } + if (id == entry.id) + return itemsChanged; + --i; + } +#if defined(DEBUG_QSHORTCUTMAP) + qDebug().nospace() + << "QShortcutMap::setShortcutAutoRepeat(" << on << ", " << id << ", " + << owner << ", " << key << ") = " << itemsChanged; +#endif + return itemsChanged; +} + +/*! \internal + Resets the state of the statemachine to NoMatch +*/ +void QShortcutMap::resetState() +{ + Q_D(QShortcutMap); + d->currentState = QKeySequence::NoMatch; + clearSequence(d->currentSequences); +} + +/*! \internal + Returns the current state of the statemachine +*/ +QKeySequence::SequenceMatch QShortcutMap::state() +{ + Q_D(QShortcutMap); + return d->currentState; +} + +/*! \internal + Uses ShortcutOverride event to see if any widgets want to override + the event. If not, uses nextState(QKeyEvent) to check for a grabbed + Shortcut, and dispatchEvent() is found an identical. + \sa nextState dispatchEvent +*/ +bool QShortcutMap::tryShortcutEvent(QObject *o, QKeyEvent *e) +{ + Q_D(QShortcutMap); + + bool wasAccepted = e->isAccepted(); + bool wasSpontaneous = e->spont; + if (d->currentState == QKeySequence::NoMatch) { + ushort orgType = e->t; + e->t = QEvent::ShortcutOverride; + e->ignore(); + QCoreApplication::sendEvent(o, e); + e->t = orgType; + e->spont = wasSpontaneous; + if (e->isAccepted()) { + if (!wasAccepted) + e->ignore(); + return false; + } + } + + QKeySequence::SequenceMatch result = nextState(e); + bool stateWasAccepted = e->isAccepted(); + if (wasAccepted) + e->accept(); + else + e->ignore(); + + int identicalMatches = d->identicals.count(); + + switch(result) { + case QKeySequence::NoMatch: + return stateWasAccepted; + case QKeySequence::ExactMatch: + resetState(); + dispatchEvent(e); + default: + break; + } + // If nextState is QKeySequence::ExactMatch && identicals.count == 0 + // we've only found disabled shortcuts + return identicalMatches > 0 || result == QKeySequence::PartialMatch; +} + +/*! \internal + Returns the next state of the statemachine + If return value is SequenceMatch::ExactMatch, then a call to matches() + will return a QObjects* list of all matching objects for the last matching + sequence. +*/ +QKeySequence::SequenceMatch QShortcutMap::nextState(QKeyEvent *e) +{ + Q_D(QShortcutMap); + // Modifiers can NOT be shortcuts... + if (e->key() >= Qt::Key_Shift && + e->key() <= Qt::Key_Alt) + return d->currentState; + + QKeySequence::SequenceMatch result = QKeySequence::NoMatch; + + // We start fresh each time.. + d->identicals.resize(0); + + result = find(e); + if (result == QKeySequence::NoMatch && e->modifiers() & Qt::ShiftModifier) { + // If Shift + Key_Backtab, also try Shift + Qt::Key_Tab + if (e->key() == Qt::Key_Backtab) { + QKeyEvent pe = QKeyEvent(e->type(), Qt::Key_Tab, e->modifiers(), e->text()); + result = find(&pe); + } + } + + // Should we eat this key press? + if (d->currentState == QKeySequence::PartialMatch + || (d->currentState == QKeySequence::ExactMatch && d->identicals.count())) + e->accept(); + // Does the new state require us to clean up? + if (result == QKeySequence::NoMatch) + clearSequence(d->currentSequences); + d->currentState = result; + +#if defined(DEBUG_QSHORTCUTMAP) + qDebug().nospace() << "QShortcutMap::nextState(" << e << ") = " << result; +#endif + return result; +} + + +/*! \internal + Determines if an enabled shortcut has a matcing key sequence. +*/ +bool QShortcutMap::hasShortcutForKeySequence(const QKeySequence &seq) const +{ + Q_D(const QShortcutMap); + QShortcutEntry entry(seq); // needed for searching + QList::ConstIterator itEnd = d->sequences.constEnd(); + QList::ConstIterator it = qLowerBound(d->sequences.constBegin(), itEnd, entry); + + for (;it != itEnd; ++it) { + if (matches(entry.keyseq, (*it).keyseq) == QKeySequence::ExactMatch && (*it).correctContext() && (*it).enabled) { + return true; + } + } + + //end of the loop: we didn't find anything + return false; +} + +/*! \internal + Returns the next state of the statemachine, based + on the new key event \a e. + Matches are appended to the vector of identicals, + which can be access through matches(). + \sa matches +*/ +QKeySequence::SequenceMatch QShortcutMap::find(QKeyEvent *e) +{ + Q_D(QShortcutMap); + if (!d->sequences.count()) + return QKeySequence::NoMatch; + + createNewSequences(e, d->newEntries); +#if defined(DEBUG_QSHORTCUTMAP) + qDebug() << "Possible shortcut key sequences:" << d->newEntries; +#endif + + // Should never happen + if (d->newEntries == d->currentSequences) { + Q_ASSERT_X(e->key() != Qt::Key_unknown || e->text().length(), + "QShortcutMap::find", "New sequence to find identical to previous"); + return QKeySequence::NoMatch; + } + + // Looking for new identicals, scrap old + d->identicals.resize(0); + + bool partialFound = false; + bool identicalDisabledFound = false; + QVector okEntries; + int result = QKeySequence::NoMatch; + for (int i = d->newEntries.count()-1; i >= 0 ; --i) { + QShortcutEntry entry(d->newEntries.at(i)); // needed for searching + QList::ConstIterator itEnd = d->sequences.constEnd(); + QList::ConstIterator it = + qLowerBound(d->sequences.constBegin(), itEnd, entry); + + int oneKSResult = QKeySequence::NoMatch; + int tempRes = QKeySequence::NoMatch; + do { + if (it == itEnd) + break; + tempRes = matches(entry.keyseq, (*it).keyseq); + oneKSResult = qMax(oneKSResult, tempRes); + if (tempRes != QKeySequence::NoMatch && (*it).correctContext()) { + if (tempRes == QKeySequence::ExactMatch) { + if ((*it).enabled) + d->identicals.append(&*it); + else + identicalDisabledFound = true; + } else if (tempRes == QKeySequence::PartialMatch) { + // We don't need partials, if we have identicals + if (d->identicals.size()) + break; + // We only care about enabled partials, so we don't consume + // key events when all partials are disabled! + partialFound |= (*it).enabled; + } + } + ++it; + // If we got a valid match on this run, there might still be more keys to check against, + // so we'll loop once more. If we get NoMatch, there's guaranteed no more possible + // matches in the shortcutmap. + } while (tempRes != QKeySequence::NoMatch); + + // If the type of match improves (ergo, NoMatch->Partial, or Partial->Exact), clear the + // previous list. If this match is equal or better than the last match, append to the list + if (oneKSResult > result) { + okEntries.clear(); +#if defined(DEBUG_QSHORTCUTMAP) + qDebug() << "Found better match (" << d->newEntries << "), clearing key sequence list"; +#endif + } + if (oneKSResult && oneKSResult >= result) { + okEntries << d->newEntries.at(i); +#if defined(DEBUG_QSHORTCUTMAP) + qDebug() << "Added ok key sequence" << d->newEntries; +#endif + } + } + + if (d->identicals.size()) { + result = QKeySequence::ExactMatch; + } else if (partialFound) { + result = QKeySequence::PartialMatch; + } else if (identicalDisabledFound) { + result = QKeySequence::ExactMatch; + } else { + clearSequence(d->currentSequences); + result = QKeySequence::NoMatch; + } + if (result != QKeySequence::NoMatch) + d->currentSequences = okEntries; +#if defined(DEBUG_QSHORTCUTMAP) + qDebug() << "Returning shortcut match == " << result; +#endif + return QKeySequence::SequenceMatch(result); +} + +/*! \internal + Clears \a seq to an empty QKeySequence. + Same as doing (the slower) + \snippet doc/src/snippets/code/src_gui_kernel_qshortcutmap.cpp 0 +*/ +void QShortcutMap::clearSequence(QVector &ksl) +{ + ksl.clear(); + d_func()->newEntries.clear(); +} + +/*! \internal + Alters \a seq to the new sequence state, based on the + current sequence state, and the new key event \a e. +*/ +void QShortcutMap::createNewSequences(QKeyEvent *e, QVector &ksl) +{ + Q_D(QShortcutMap); + QList possibleKeys = QKeyMapper::possibleKeys(e); + int pkTotal = possibleKeys.count(); + if (!pkTotal) + return; + + int ssActual = d->currentSequences.count(); + int ssTotal = qMax(1, ssActual); + // Resize to possible permutations of the current sequence(s). + ksl.resize(pkTotal * ssTotal); + + int index = ssActual ? d->currentSequences.at(0).count() : 0; + for (int pkNum = 0; pkNum < pkTotal; ++pkNum) { + for (int ssNum = 0; ssNum < ssTotal; ++ssNum) { + int i = (pkNum * ssTotal) + ssNum; + QKeySequence &curKsl = ksl[i]; + if (ssActual) { + const QKeySequence &curSeq = d->currentSequences.at(ssNum); + curKsl.setKey(curSeq[0], 0); + curKsl.setKey(curSeq[1], 1); + curKsl.setKey(curSeq[2], 2); + curKsl.setKey(curSeq[3], 3); + } else { + curKsl.setKey(0, 0); + curKsl.setKey(0, 1); + curKsl.setKey(0, 2); + curKsl.setKey(0, 3); + } + // Filtering keycode here with 0xdfffffff to ignore the Keypad modifier + curKsl.setKey(possibleKeys.at(pkNum) & 0xdfffffff, index); + } + } +} + +/*! \internal + Basically the same function as QKeySequence::matches(const QKeySequence &seq) const + only that is specially handles Key_hyphen as Key_Minus, as people mix these up all the time and + they conceptually the same. +*/ +QKeySequence::SequenceMatch QShortcutMap::matches(const QKeySequence &seq1, + const QKeySequence &seq2) const +{ + uint userN = seq1.count(), + seqN = seq2.count(); + + if (userN > seqN) + return QKeySequence::NoMatch; + + // If equal in length, we have a potential ExactMatch sequence, + // else we already know it can only be partial. + QKeySequence::SequenceMatch match = (userN == seqN + ? QKeySequence::ExactMatch + : QKeySequence::PartialMatch); + + for (uint i = 0; i < userN; ++i) { + int userKey = seq1[i], + sequenceKey = seq2[i]; + if ((userKey & Qt::Key_unknown) == Qt::Key_hyphen) + userKey = (userKey & Qt::KeyboardModifierMask) | Qt::Key_Minus; + if ((sequenceKey & Qt::Key_unknown) == Qt::Key_hyphen) + sequenceKey = (sequenceKey & Qt::KeyboardModifierMask) | Qt::Key_Minus; + if (userKey != sequenceKey) + return QKeySequence::NoMatch; + } + return match; +} + + +/*! \internal + Converts keyboard button states into modifier states +*/ +int QShortcutMap::translateModifiers(Qt::KeyboardModifiers modifiers) +{ + int result = 0; + if (modifiers & Qt::ShiftModifier) + result |= Qt::SHIFT; + if (modifiers & Qt::ControlModifier) + result |= Qt::CTRL; + if (modifiers & Qt::MetaModifier) + result |= Qt::META; + if (modifiers & Qt::AltModifier) + result |= Qt::ALT; + return result; +} + +/*! \internal + Returns the vector of QShortcutEntry's matching the last Identical state. +*/ +QVector QShortcutMap::matches() const +{ + Q_D(const QShortcutMap); + return d->identicals; +} + +/*! \internal + Dispatches QShortcutEvents to widgets who grabbed the matched key sequence. +*/ +void QShortcutMap::dispatchEvent(QKeyEvent *e) +{ + Q_D(QShortcutMap); + if (!d->identicals.size()) + return; + + const QKeySequence &curKey = d->identicals.at(0)->keyseq; + if (d->prevSequence != curKey) { + d->ambigCount = 0; + d->prevSequence = curKey; + } + // Find next + const QShortcutEntry *current = 0, *next = 0; + int i = 0, enabledShortcuts = 0; + while(i < d->identicals.size()) { + current = d->identicals.at(i); + if (current->enabled || !next){ + ++enabledShortcuts; + if (enabledShortcuts > d->ambigCount + 1) + break; + next = current; + } + ++i; + } + d->ambigCount = (d->identicals.size() == i ? 0 : d->ambigCount + 1); + // Don't trigger shortcut if we're autorepeating and the shortcut is + // grabbed with not accepting autorepeats. + if (!next || (e->isAutoRepeat() && !next->autorepeat)) + return; + // Dispatch next enabled +#if defined(DEBUG_QSHORTCUTMAP) + qDebug().nospace() + << "QShortcutMap::dispatchEvent(): Sending QShortcutEvent(\"" + << (QString)next->keyseq << "\", " << next->id << ", " + << (bool)(enabledShortcuts>1) << ") to object(" << next->owner << ')'; +#endif + QShortcutEvent se(next->keyseq, next->id, enabledShortcuts>1); + QCoreApplication::sendEvent(const_cast(next->owner), &se); +} + +/* \internal + QShortcutMap dump function, only available when DEBUG_QSHORTCUTMAP is + defined. +*/ +#if defined(Dump_QShortcutMap) +void QShortcutMap::dumpMap() const +{ + Q_D(const QShortcutMap); + for (int i = 0; i < d->sequences.size(); ++i) + qDebug().nospace() << &(d->sequences.at(i)); +} +#endif + +QT_END_NAMESPACE + +#endif // QT_NO_SHORTCUT diff --git a/src/gui/kernel/qshortcutmap_p.h b/src/gui/kernel/qshortcutmap_p.h new file mode 100644 index 0000000000..bfd3607e5e --- /dev/null +++ b/src/gui/kernel/qshortcutmap_p.h @@ -0,0 +1,115 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#ifndef QSHORTCUTMAP_P_H +#define QSHORTCUTMAP_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "QtGui/qkeysequence.h" +#include "QtCore/qvector.h" +#include "QtCore/qscopedpointer.h" + +QT_BEGIN_NAMESPACE + +#ifndef QT_NO_SHORTCUT + +// To enable dump output uncomment below +//#define Dump_QShortcutMap + +class QKeyEvent; +struct QShortcutEntry; +class QShortcutMapPrivate; +class QObject; + +class Q_GUI_EXPORT QShortcutMap +{ + Q_DECLARE_PRIVATE(QShortcutMap) +public: + QShortcutMap(); + ~QShortcutMap(); + + typedef bool (*ContextMatcher)(QObject *object, Qt::ShortcutContext context); + + int addShortcut(QObject *owner, const QKeySequence &key, Qt::ShortcutContext context, ContextMatcher matcher); + int removeShortcut(int id, QObject *owner, const QKeySequence &key = QKeySequence()); + int setShortcutEnabled(bool enable, int id, QObject *owner, const QKeySequence &key = QKeySequence()); + int setShortcutAutoRepeat(bool on, int id, QObject *owner, const QKeySequence &key = QKeySequence()); + + void resetState(); + QKeySequence::SequenceMatch nextState(QKeyEvent *e); + QKeySequence::SequenceMatch state(); + void dispatchEvent(QKeyEvent *e); + bool tryShortcutEvent(QObject *o, QKeyEvent *e); + +#ifdef Dump_QShortcutMap + void dumpMap() const; +#endif + + bool hasShortcutForKeySequence(const QKeySequence &seq) const; + + +private: + QScopedPointer d_ptr; + + QKeySequence::SequenceMatch find(QKeyEvent *e); + QKeySequence::SequenceMatch matches(const QKeySequence &seq1, const QKeySequence &seq2) const; + QVector matches() const; + void createNewSequences(QKeyEvent *e, QVector &ksl); + void clearSequence(QVector &ksl); + bool correctContext(const QShortcutEntry &item) const; + int translateModifiers(Qt::KeyboardModifiers modifiers); +}; + +#endif // QT_NO_SHORTCUT + +QT_END_NAMESPACE + +#endif // QSHORTCUTMAP_P_H diff --git a/src/widgets/kernel/kernel.pri b/src/widgets/kernel/kernel.pri index 8fbf968581..4f0129add0 100644 --- a/src/widgets/kernel/kernel.pri +++ b/src/widgets/kernel/kernel.pri @@ -26,6 +26,7 @@ HEADERS += \ kernel/qlayout_p.h \ kernel/qlayoutengine_p.h \ kernel/qlayoutitem.h \ + kernel/qshortcut.h \ kernel/qsizepolicy.h \ kernel/qstackedlayout.h \ kernel/qtooltip.h \ @@ -59,6 +60,7 @@ SOURCES += \ kernel/qlayout.cpp \ kernel/qlayoutengine.cpp \ kernel/qlayoutitem.cpp \ + kernel/qshortcut.cpp \ kernel/qstackedlayout.cpp \ kernel/qtooltip.cpp \ kernel/qwhatsthis.cpp \ diff --git a/src/widgets/kernel/qshortcut.cpp b/src/widgets/kernel/qshortcut.cpp new file mode 100644 index 0000000000..94f809d199 --- /dev/null +++ b/src/widgets/kernel/qshortcut.cpp @@ -0,0 +1,620 @@ +/**************************************************************************** +** +** 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 +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +#define QAPP_CHECK(functionName) \ + if (!qApp) { \ + qWarning("QShortcut: Initialize QApplication before calling '" functionName "'."); \ + return; \ + } + + +static bool correctWidgetContext(Qt::ShortcutContext context, QWidget *w, QWidget *active_window); +#ifndef QT_NO_GRAPHICSVIEW +static bool correctGraphicsWidgetContext(Qt::ShortcutContext context, QGraphicsWidget *w, QWidget *active_window); +#endif +#ifndef QT_NO_ACTION +static bool correctActionContext(Qt::ShortcutContext context, QAction *a, QWidget *active_window); +#endif + + +/*! \internal + Returns true if the widget \a w is a logical sub window of the current + top-level widget. +*/ +bool qWidgetShortcutContextMatcher(QObject *object, Qt::ShortcutContext context) +{ + Q_ASSERT_X(object, "QShortcutMap", "Shortcut has no owner. Illegal map state!"); + + QWidget *active_window = QApplication::activeWindow(); + + // popups do not become the active window, + // so we fake it here to get the correct context + // for the shortcut system. + if (QApplication::activePopupWidget()) + active_window = QApplication::activePopupWidget(); + + if (!active_window) + return false; + +#ifndef QT_NO_ACTION + if (QAction *a = qobject_cast(object)) + return correctActionContext(context, a, active_window); +#endif + +#ifndef QT_NO_GRAPHICSVIEW + if (QGraphicsWidget *gw = qobject_cast(object)) + return correctGraphicsWidgetContext(context, gw, active_window); +#endif + + QWidget *w = qobject_cast(object); + if (!w) { + QShortcut *s = qobject_cast(object); + if (s) + w = s->parentWidget(); + } + + if (!w) + return false; + + return correctWidgetContext(context, w, active_window); +} + +static bool correctWidgetContext(Qt::ShortcutContext context, QWidget *w, QWidget *active_window) +{ + bool visible = w->isVisible(); +#ifdef Q_WS_MAC + if (!qApp->testAttribute(Qt::AA_DontUseNativeMenuBar) && qobject_cast(w)) + visible = true; +#endif + + if (!visible || !w->isEnabled()) + return false; + + if (context == Qt::ApplicationShortcut) + return QApplicationPrivate::tryModalHelper(w, 0); // true, unless w is shadowed by a modal dialog + + if (context == Qt::WidgetShortcut) + return w == QApplication::focusWidget(); + + if (context == Qt::WidgetWithChildrenShortcut) { + const QWidget *tw = QApplication::focusWidget(); + while (tw && tw != w && (tw->windowType() == Qt::Widget || tw->windowType() == Qt::Popup)) + tw = tw->parentWidget(); + return tw == w; + } + + // Below is Qt::WindowShortcut context + QWidget *tlw = w->window(); +#ifndef QT_NO_GRAPHICSVIEW + if (QWExtra *topData = static_cast(QObjectPrivate::get(tlw))->extra) { + if (topData->proxyWidget) { + bool res = correctGraphicsWidgetContext(context, (QGraphicsWidget *)topData->proxyWidget, active_window); + return res; + } + } +#endif + + /* if a floating tool window is active, keep shortcuts on the + * parent working */ + if (active_window != tlw && active_window && active_window->windowType() == Qt::Tool && active_window->parentWidget()) { + active_window = active_window->parentWidget()->window(); + } + + if (active_window != tlw) + return false; + + /* if we live in a MDI subwindow, ignore the event if we are + not the active document window */ + const QWidget* sw = w; + while (sw && !(sw->windowType() == Qt::SubWindow) && !sw->isWindow()) + sw = sw->parentWidget(); + if (sw && (sw->windowType() == Qt::SubWindow)) { + QWidget *focus_widget = QApplication::focusWidget(); + while (focus_widget && focus_widget != sw) + focus_widget = focus_widget->parentWidget(); + return sw == focus_widget; + } + +#if defined(DEBUG_QSHORTCUTMAP) + qDebug().nospace() << "..true [Pass-through]"; +#endif + return true; +} + +#ifndef QT_NO_GRAPHICSVIEW +static bool correctGraphicsWidgetContext(Qt::ShortcutContext context, QGraphicsWidget *w, QWidget *active_window) +{ + bool visible = w->isVisible(); +#ifdef Q_WS_MAC + if (!qApp->testAttribute(Qt::AA_DontUseNativeMenuBar) && qobject_cast(w)) + visible = true; +#endif + + if (!visible || !w->isEnabled() || !w->scene()) + return false; + + if (context == Qt::ApplicationShortcut) { + // Applicationwide shortcuts are always reachable unless their owner + // is shadowed by modality. In QGV there's no modality concept, but we + // must still check if all views are shadowed. + QList views = w->scene()->views(); + for (int i = 0; i < views.size(); ++i) { + if (QApplicationPrivate::tryModalHelper(views.at(i), 0)) + return true; + } + return false; + } + + if (context == Qt::WidgetShortcut) + return static_cast(w) == w->scene()->focusItem(); + + if (context == Qt::WidgetWithChildrenShortcut) { + const QGraphicsItem *ti = w->scene()->focusItem(); + if (ti && ti->isWidget()) { + const QGraphicsWidget *tw = static_cast(ti); + while (tw && tw != w && (tw->windowType() == Qt::Widget || tw->windowType() == Qt::Popup)) + tw = tw->parentWidget(); + return tw == w; + } + return false; + } + + // Below is Qt::WindowShortcut context + + // Find the active view (if any). + QList views = w->scene()->views(); + QGraphicsView *activeView = 0; + for (int i = 0; i < views.size(); ++i) { + QGraphicsView *view = views.at(i); + if (view->window() == active_window) { + activeView = view; + break; + } + } + if (!activeView) + return false; + + // The shortcut is reachable if owned by a windowless widget, or if the + // widget's window is the same as the focus item's window. + QGraphicsWidget *a = w->scene()->activeWindow(); + return !w->window() || a == w->window(); +} +#endif + +#ifndef QT_NO_ACTION +static bool correctActionContext(Qt::ShortcutContext context, QAction *a, QWidget *active_window) +{ + const QList &widgets = static_cast(QObjectPrivate::get(a))->widgets; +#if defined(DEBUG_QSHORTCUTMAP) + if (widgets.isEmpty()) + qDebug() << a << "not connected to any widgets; won't trigger"; +#endif + for (int i = 0; i < widgets.size(); ++i) { + QWidget *w = widgets.at(i); +#ifndef QT_NO_MENU + if (QMenu *menu = qobject_cast(w)) { + QAction *a = menu->menuAction(); + if (correctActionContext(context, a, active_window)) + return true; + } else +#endif + if (correctWidgetContext(context, w, active_window)) + return true; + } + +#ifndef QT_NO_GRAPHICSVIEW + const QList &graphicsWidgets = static_cast(QObjectPrivate::get(a))->graphicsWidgets; +#if defined(DEBUG_QSHORTCUTMAP) + if (graphicsWidgets.isEmpty()) + qDebug() << a << "not connected to any widgets; won't trigger"; +#endif + for (int i = 0; i < graphicsWidgets.size(); ++i) { + QGraphicsWidget *w = graphicsWidgets.at(i); + if (correctGraphicsWidgetContext(context, w, active_window)) + return true; + } +#endif + return false; +} +#endif // QT_NO_ACTION + + +/*! + \class QShortcut + \brief The QShortcut class is used to create keyboard shortcuts. + + \ingroup events + \inmodule QtWidgets + + 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, qWidgetShortcutContextMatcher); + 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(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 diff --git a/src/widgets/kernel/qshortcut.h b/src/widgets/kernel/qshortcut.h new file mode 100644 index 0000000000..6e3c647852 --- /dev/null +++ b/src/widgets/kernel/qshortcut.h @@ -0,0 +1,107 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#ifndef QSHORTCUT_H +#define QSHORTCUT_H + +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Gui) + +#ifndef QT_NO_SHORTCUT + +class QShortcutPrivate; +class Q_WIDGETS_EXPORT QShortcut : public QObject +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QShortcut) + Q_PROPERTY(QKeySequence key READ key WRITE setKey) + Q_PROPERTY(QString whatsThis READ whatsThis WRITE setWhatsThis) + Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled) + Q_PROPERTY(bool autoRepeat READ autoRepeat WRITE setAutoRepeat) + Q_PROPERTY(Qt::ShortcutContext context READ context WRITE setContext) +public: + explicit QShortcut(QWidget *parent); + QShortcut(const QKeySequence& key, QWidget *parent, + const char *member = 0, const char *ambiguousMember = 0, + Qt::ShortcutContext context = Qt::WindowShortcut); + ~QShortcut(); + + void setKey(const QKeySequence& key); + QKeySequence key() const; + + void setEnabled(bool enable); + bool isEnabled() const; + + void setContext(Qt::ShortcutContext context); + Qt::ShortcutContext context(); + + void setWhatsThis(const QString &text); + QString whatsThis() const; + + void setAutoRepeat(bool on); + bool autoRepeat() const; + + int id() const; + + inline QWidget *parentWidget() const + { return static_cast(QObject::parent()); } + +Q_SIGNALS: + void activated(); + void activatedAmbiguously(); + +protected: + bool event(QEvent *e); +}; + +#endif // QT_NO_SHORTCUT + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QSHORTCUT_H diff --git a/src/widgets/to_be_moved/qshortcut.cpp b/src/widgets/to_be_moved/qshortcut.cpp deleted file mode 100644 index 94f809d199..0000000000 --- a/src/widgets/to_be_moved/qshortcut.cpp +++ /dev/null @@ -1,620 +0,0 @@ -/**************************************************************************** -** -** 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 -#include -#include -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE - -#define QAPP_CHECK(functionName) \ - if (!qApp) { \ - qWarning("QShortcut: Initialize QApplication before calling '" functionName "'."); \ - return; \ - } - - -static bool correctWidgetContext(Qt::ShortcutContext context, QWidget *w, QWidget *active_window); -#ifndef QT_NO_GRAPHICSVIEW -static bool correctGraphicsWidgetContext(Qt::ShortcutContext context, QGraphicsWidget *w, QWidget *active_window); -#endif -#ifndef QT_NO_ACTION -static bool correctActionContext(Qt::ShortcutContext context, QAction *a, QWidget *active_window); -#endif - - -/*! \internal - Returns true if the widget \a w is a logical sub window of the current - top-level widget. -*/ -bool qWidgetShortcutContextMatcher(QObject *object, Qt::ShortcutContext context) -{ - Q_ASSERT_X(object, "QShortcutMap", "Shortcut has no owner. Illegal map state!"); - - QWidget *active_window = QApplication::activeWindow(); - - // popups do not become the active window, - // so we fake it here to get the correct context - // for the shortcut system. - if (QApplication::activePopupWidget()) - active_window = QApplication::activePopupWidget(); - - if (!active_window) - return false; - -#ifndef QT_NO_ACTION - if (QAction *a = qobject_cast(object)) - return correctActionContext(context, a, active_window); -#endif - -#ifndef QT_NO_GRAPHICSVIEW - if (QGraphicsWidget *gw = qobject_cast(object)) - return correctGraphicsWidgetContext(context, gw, active_window); -#endif - - QWidget *w = qobject_cast(object); - if (!w) { - QShortcut *s = qobject_cast(object); - if (s) - w = s->parentWidget(); - } - - if (!w) - return false; - - return correctWidgetContext(context, w, active_window); -} - -static bool correctWidgetContext(Qt::ShortcutContext context, QWidget *w, QWidget *active_window) -{ - bool visible = w->isVisible(); -#ifdef Q_WS_MAC - if (!qApp->testAttribute(Qt::AA_DontUseNativeMenuBar) && qobject_cast(w)) - visible = true; -#endif - - if (!visible || !w->isEnabled()) - return false; - - if (context == Qt::ApplicationShortcut) - return QApplicationPrivate::tryModalHelper(w, 0); // true, unless w is shadowed by a modal dialog - - if (context == Qt::WidgetShortcut) - return w == QApplication::focusWidget(); - - if (context == Qt::WidgetWithChildrenShortcut) { - const QWidget *tw = QApplication::focusWidget(); - while (tw && tw != w && (tw->windowType() == Qt::Widget || tw->windowType() == Qt::Popup)) - tw = tw->parentWidget(); - return tw == w; - } - - // Below is Qt::WindowShortcut context - QWidget *tlw = w->window(); -#ifndef QT_NO_GRAPHICSVIEW - if (QWExtra *topData = static_cast(QObjectPrivate::get(tlw))->extra) { - if (topData->proxyWidget) { - bool res = correctGraphicsWidgetContext(context, (QGraphicsWidget *)topData->proxyWidget, active_window); - return res; - } - } -#endif - - /* if a floating tool window is active, keep shortcuts on the - * parent working */ - if (active_window != tlw && active_window && active_window->windowType() == Qt::Tool && active_window->parentWidget()) { - active_window = active_window->parentWidget()->window(); - } - - if (active_window != tlw) - return false; - - /* if we live in a MDI subwindow, ignore the event if we are - not the active document window */ - const QWidget* sw = w; - while (sw && !(sw->windowType() == Qt::SubWindow) && !sw->isWindow()) - sw = sw->parentWidget(); - if (sw && (sw->windowType() == Qt::SubWindow)) { - QWidget *focus_widget = QApplication::focusWidget(); - while (focus_widget && focus_widget != sw) - focus_widget = focus_widget->parentWidget(); - return sw == focus_widget; - } - -#if defined(DEBUG_QSHORTCUTMAP) - qDebug().nospace() << "..true [Pass-through]"; -#endif - return true; -} - -#ifndef QT_NO_GRAPHICSVIEW -static bool correctGraphicsWidgetContext(Qt::ShortcutContext context, QGraphicsWidget *w, QWidget *active_window) -{ - bool visible = w->isVisible(); -#ifdef Q_WS_MAC - if (!qApp->testAttribute(Qt::AA_DontUseNativeMenuBar) && qobject_cast(w)) - visible = true; -#endif - - if (!visible || !w->isEnabled() || !w->scene()) - return false; - - if (context == Qt::ApplicationShortcut) { - // Applicationwide shortcuts are always reachable unless their owner - // is shadowed by modality. In QGV there's no modality concept, but we - // must still check if all views are shadowed. - QList views = w->scene()->views(); - for (int i = 0; i < views.size(); ++i) { - if (QApplicationPrivate::tryModalHelper(views.at(i), 0)) - return true; - } - return false; - } - - if (context == Qt::WidgetShortcut) - return static_cast(w) == w->scene()->focusItem(); - - if (context == Qt::WidgetWithChildrenShortcut) { - const QGraphicsItem *ti = w->scene()->focusItem(); - if (ti && ti->isWidget()) { - const QGraphicsWidget *tw = static_cast(ti); - while (tw && tw != w && (tw->windowType() == Qt::Widget || tw->windowType() == Qt::Popup)) - tw = tw->parentWidget(); - return tw == w; - } - return false; - } - - // Below is Qt::WindowShortcut context - - // Find the active view (if any). - QList views = w->scene()->views(); - QGraphicsView *activeView = 0; - for (int i = 0; i < views.size(); ++i) { - QGraphicsView *view = views.at(i); - if (view->window() == active_window) { - activeView = view; - break; - } - } - if (!activeView) - return false; - - // The shortcut is reachable if owned by a windowless widget, or if the - // widget's window is the same as the focus item's window. - QGraphicsWidget *a = w->scene()->activeWindow(); - return !w->window() || a == w->window(); -} -#endif - -#ifndef QT_NO_ACTION -static bool correctActionContext(Qt::ShortcutContext context, QAction *a, QWidget *active_window) -{ - const QList &widgets = static_cast(QObjectPrivate::get(a))->widgets; -#if defined(DEBUG_QSHORTCUTMAP) - if (widgets.isEmpty()) - qDebug() << a << "not connected to any widgets; won't trigger"; -#endif - for (int i = 0; i < widgets.size(); ++i) { - QWidget *w = widgets.at(i); -#ifndef QT_NO_MENU - if (QMenu *menu = qobject_cast(w)) { - QAction *a = menu->menuAction(); - if (correctActionContext(context, a, active_window)) - return true; - } else -#endif - if (correctWidgetContext(context, w, active_window)) - return true; - } - -#ifndef QT_NO_GRAPHICSVIEW - const QList &graphicsWidgets = static_cast(QObjectPrivate::get(a))->graphicsWidgets; -#if defined(DEBUG_QSHORTCUTMAP) - if (graphicsWidgets.isEmpty()) - qDebug() << a << "not connected to any widgets; won't trigger"; -#endif - for (int i = 0; i < graphicsWidgets.size(); ++i) { - QGraphicsWidget *w = graphicsWidgets.at(i); - if (correctGraphicsWidgetContext(context, w, active_window)) - return true; - } -#endif - return false; -} -#endif // QT_NO_ACTION - - -/*! - \class QShortcut - \brief The QShortcut class is used to create keyboard shortcuts. - - \ingroup events - \inmodule QtWidgets - - 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, qWidgetShortcutContextMatcher); - 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(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 diff --git a/src/widgets/to_be_moved/qshortcut.h b/src/widgets/to_be_moved/qshortcut.h deleted file mode 100644 index 6e3c647852..0000000000 --- a/src/widgets/to_be_moved/qshortcut.h +++ /dev/null @@ -1,107 +0,0 @@ -/**************************************************************************** -** -** 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$ -** -****************************************************************************/ - -#ifndef QSHORTCUT_H -#define QSHORTCUT_H - -#include -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Gui) - -#ifndef QT_NO_SHORTCUT - -class QShortcutPrivate; -class Q_WIDGETS_EXPORT QShortcut : public QObject -{ - Q_OBJECT - Q_DECLARE_PRIVATE(QShortcut) - Q_PROPERTY(QKeySequence key READ key WRITE setKey) - Q_PROPERTY(QString whatsThis READ whatsThis WRITE setWhatsThis) - Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled) - Q_PROPERTY(bool autoRepeat READ autoRepeat WRITE setAutoRepeat) - Q_PROPERTY(Qt::ShortcutContext context READ context WRITE setContext) -public: - explicit QShortcut(QWidget *parent); - QShortcut(const QKeySequence& key, QWidget *parent, - const char *member = 0, const char *ambiguousMember = 0, - Qt::ShortcutContext context = Qt::WindowShortcut); - ~QShortcut(); - - void setKey(const QKeySequence& key); - QKeySequence key() const; - - void setEnabled(bool enable); - bool isEnabled() const; - - void setContext(Qt::ShortcutContext context); - Qt::ShortcutContext context(); - - void setWhatsThis(const QString &text); - QString whatsThis() const; - - void setAutoRepeat(bool on); - bool autoRepeat() const; - - int id() const; - - inline QWidget *parentWidget() const - { return static_cast(QObject::parent()); } - -Q_SIGNALS: - void activated(); - void activatedAmbiguously(); - -protected: - bool event(QEvent *e); -}; - -#endif // QT_NO_SHORTCUT - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QSHORTCUT_H diff --git a/src/widgets/to_be_moved/qshortcutmap.cpp b/src/widgets/to_be_moved/qshortcutmap.cpp deleted file mode 100644 index 64b0aa1741..0000000000 --- a/src/widgets/to_be_moved/qshortcutmap.cpp +++ /dev/null @@ -1,697 +0,0 @@ -/**************************************************************************** -** -** 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 "qshortcutmap_p.h" -#include "private/qobject_p.h" -#include "qkeysequence.h" -#include "qdebug.h" -#include "qevent.h" -#include "qvector.h" -#include "qcoreapplication.h" -#include - -#ifndef QT_NO_SHORTCUT - -QT_BEGIN_NAMESPACE - -// To enable verbose output uncomment below -//#define DEBUG_QSHORTCUTMAP - -/* \internal - Entry data for QShortcutMap - Contains: - Keysequence for entry - Pointer to parent owning the sequence -*/ - -struct QShortcutEntry -{ - QShortcutEntry() - : keyseq(0), context(Qt::WindowShortcut), enabled(false), autorepeat(1), id(0), owner(0), contextMatcher(0) - {} - - QShortcutEntry(const QKeySequence &k) - : keyseq(k), context(Qt::WindowShortcut), enabled(false), autorepeat(1), id(0), owner(0), contextMatcher(0) - {} - - QShortcutEntry(QObject *o, const QKeySequence &k, Qt::ShortcutContext c, int i, bool a, QShortcutMap::ContextMatcher m) - : keyseq(k), context(c), enabled(true), autorepeat(a), id(i), owner(o), contextMatcher(m) - {} - - bool correctContext() const { return contextMatcher(owner, context); } - - bool operator<(const QShortcutEntry &f) const - { return keyseq < f.keyseq; } - - QKeySequence keyseq; - Qt::ShortcutContext context; - bool enabled : 1; - bool autorepeat : 1; - signed int id; - QObject *owner; - QShortcutMap::ContextMatcher contextMatcher; -}; - -#if 0 //ndef QT_NO_DEBUG_STREAM -/*! \internal - QDebug operator<< for easy debug output of the shortcut entries. -*/ -static QDebug &operator<<(QDebug &dbg, const QShortcutEntry *se) { - if (!se) - return dbg << "QShortcutEntry(0x0)"; - dbg.nospace() - << "QShortcutEntry(" << se->keyseq - << "), id(" << se->id << "), enabled(" << se->enabled << "), autorepeat(" << se->autorepeat - << "), owner(" << se->owner << ')'; - return dbg.space(); -} -#endif // QT_NO_DEBUGSTREAM - -/* \internal - Private data for QShortcutMap -*/ -class QShortcutMapPrivate -{ - Q_DECLARE_PUBLIC(QShortcutMap) - -public: - QShortcutMapPrivate(QShortcutMap* parent) - : q_ptr(parent), currentId(0), ambigCount(0), currentState(QKeySequence::NoMatch) - { - identicals.reserve(10); - currentSequences.reserve(10); - } - QShortcutMap *q_ptr; // Private's parent - - QList sequences; // All sequences! - - int currentId; // Global shortcut ID number - int ambigCount; // Index of last enabled ambiguous dispatch - QKeySequence::SequenceMatch currentState; - QVector currentSequences; // Sequence for the current state - QVector newEntries; - QKeySequence prevSequence; // Sequence for the previous identical match - QVector identicals; // Last identical matches -}; - - -/*! \internal - QShortcutMap constructor. -*/ -QShortcutMap::QShortcutMap() - : d_ptr(new QShortcutMapPrivate(this)) -{ - resetState(); -} - -/*! \internal - QShortcutMap destructor. -*/ -QShortcutMap::~QShortcutMap() -{ -} - -/*! \internal - Adds a shortcut to the global map. - Returns the id of the newly added shortcut. -*/ -int QShortcutMap::addShortcut(QObject *owner, const QKeySequence &key, Qt::ShortcutContext context, ContextMatcher matcher) -{ - Q_ASSERT_X(owner, "QShortcutMap::addShortcut", "All shortcuts need an owner"); - Q_ASSERT_X(!key.isEmpty(), "QShortcutMap::addShortcut", "Cannot add keyless shortcuts to map"); - Q_D(QShortcutMap); - - QShortcutEntry newEntry(owner, key, context, --(d->currentId), true, matcher); - QList::iterator it = qUpperBound(d->sequences.begin(), d->sequences.end(), newEntry); - d->sequences.insert(it, newEntry); // Insert sorted -#if defined(DEBUG_QSHORTCUTMAP) - qDebug().nospace() - << "QShortcutMap::addShortcut(" << owner << ", " - << key << ", " << context << ") = " << d->currentId; -#endif - return d->currentId; -} - -/*! \internal - Removes a shortcut from the global map. - If \a owner is 0, all entries in the map with the key sequence specified - is removed. If \a key is null, all sequences for \a owner is removed from - the map. If \a id is 0, any identical \a key sequences owned by \a owner - are removed. - Returns the number of sequences removed from the map. -*/ - -int QShortcutMap::removeShortcut(int id, QObject *owner, const QKeySequence &key) -{ - Q_D(QShortcutMap); - int itemsRemoved = 0; - bool allOwners = (owner == 0); - bool allKeys = key.isEmpty(); - bool allIds = id == 0; - - // Special case, remove everything - if (allOwners && allKeys && id == 0) { - itemsRemoved = d->sequences.size(); - d->sequences.clear(); - return itemsRemoved; - } - - int i = d->sequences.size()-1; - while (i>=0) - { - const QShortcutEntry &entry = d->sequences.at(i); - int entryId = entry.id; - if ((allOwners || entry.owner == owner) - && (allIds || entry.id == id) - && (allKeys || entry.keyseq == key)) { - d->sequences.removeAt(i); - ++itemsRemoved; - } - if (id == entryId) - return itemsRemoved; - --i; - } -#if defined(DEBUG_QSHORTCUTMAP) - qDebug().nospace() - << "QShortcutMap::removeShortcut(" << id << ", " << owner << ", " - << key << ") = " << itemsRemoved; -#endif - return itemsRemoved; -} - -/*! \internal - Changes the enable state of a shortcut to \a enable. - If \a owner is 0, all entries in the map with the key sequence specified - is removed. If \a key is null, all sequences for \a owner is removed from - the map. If \a id is 0, any identical \a key sequences owned by \a owner - are changed. - Returns the number of sequences which are matched in the map. -*/ -int QShortcutMap::setShortcutEnabled(bool enable, int id, QObject *owner, const QKeySequence &key) -{ - Q_D(QShortcutMap); - int itemsChanged = 0; - bool allOwners = (owner == 0); - bool allKeys = key.isEmpty(); - bool allIds = id == 0; - - int i = d->sequences.size()-1; - while (i>=0) - { - QShortcutEntry entry = d->sequences.at(i); - if ((allOwners || entry.owner == owner) - && (allIds || entry.id == id) - && (allKeys || entry.keyseq == key)) { - d->sequences[i].enabled = enable; - ++itemsChanged; - } - if (id == entry.id) - return itemsChanged; - --i; - } -#if defined(DEBUG_QSHORTCUTMAP) - qDebug().nospace() - << "QShortcutMap::setShortcutEnabled(" << enable << ", " << id << ", " - << owner << ", " << key << ") = " << itemsChanged; -#endif - return itemsChanged; -} - -/*! \internal - Changes the auto repeat state of a shortcut to \a enable. - If \a owner is 0, all entries in the map with the key sequence specified - is removed. If \a key is null, all sequences for \a owner is removed from - the map. If \a id is 0, any identical \a key sequences owned by \a owner - are changed. - Returns the number of sequences which are matched in the map. -*/ -int QShortcutMap::setShortcutAutoRepeat(bool on, int id, QObject *owner, const QKeySequence &key) -{ - Q_D(QShortcutMap); - int itemsChanged = 0; - bool allOwners = (owner == 0); - bool allKeys = key.isEmpty(); - bool allIds = id == 0; - - int i = d->sequences.size()-1; - while (i>=0) - { - QShortcutEntry entry = d->sequences.at(i); - if ((allOwners || entry.owner == owner) - && (allIds || entry.id == id) - && (allKeys || entry.keyseq == key)) { - d->sequences[i].autorepeat = on; - ++itemsChanged; - } - if (id == entry.id) - return itemsChanged; - --i; - } -#if defined(DEBUG_QSHORTCUTMAP) - qDebug().nospace() - << "QShortcutMap::setShortcutAutoRepeat(" << on << ", " << id << ", " - << owner << ", " << key << ") = " << itemsChanged; -#endif - return itemsChanged; -} - -/*! \internal - Resets the state of the statemachine to NoMatch -*/ -void QShortcutMap::resetState() -{ - Q_D(QShortcutMap); - d->currentState = QKeySequence::NoMatch; - clearSequence(d->currentSequences); -} - -/*! \internal - Returns the current state of the statemachine -*/ -QKeySequence::SequenceMatch QShortcutMap::state() -{ - Q_D(QShortcutMap); - return d->currentState; -} - -/*! \internal - Uses ShortcutOverride event to see if any widgets want to override - the event. If not, uses nextState(QKeyEvent) to check for a grabbed - Shortcut, and dispatchEvent() is found an identical. - \sa nextState dispatchEvent -*/ -bool QShortcutMap::tryShortcutEvent(QObject *o, QKeyEvent *e) -{ - Q_D(QShortcutMap); - - bool wasAccepted = e->isAccepted(); - bool wasSpontaneous = e->spont; - if (d->currentState == QKeySequence::NoMatch) { - ushort orgType = e->t; - e->t = QEvent::ShortcutOverride; - e->ignore(); - QCoreApplication::sendEvent(o, e); - e->t = orgType; - e->spont = wasSpontaneous; - if (e->isAccepted()) { - if (!wasAccepted) - e->ignore(); - return false; - } - } - - QKeySequence::SequenceMatch result = nextState(e); - bool stateWasAccepted = e->isAccepted(); - if (wasAccepted) - e->accept(); - else - e->ignore(); - - int identicalMatches = d->identicals.count(); - - switch(result) { - case QKeySequence::NoMatch: - return stateWasAccepted; - case QKeySequence::ExactMatch: - resetState(); - dispatchEvent(e); - default: - break; - } - // If nextState is QKeySequence::ExactMatch && identicals.count == 0 - // we've only found disabled shortcuts - return identicalMatches > 0 || result == QKeySequence::PartialMatch; -} - -/*! \internal - Returns the next state of the statemachine - If return value is SequenceMatch::ExactMatch, then a call to matches() - will return a QObjects* list of all matching objects for the last matching - sequence. -*/ -QKeySequence::SequenceMatch QShortcutMap::nextState(QKeyEvent *e) -{ - Q_D(QShortcutMap); - // Modifiers can NOT be shortcuts... - if (e->key() >= Qt::Key_Shift && - e->key() <= Qt::Key_Alt) - return d->currentState; - - QKeySequence::SequenceMatch result = QKeySequence::NoMatch; - - // We start fresh each time.. - d->identicals.resize(0); - - result = find(e); - if (result == QKeySequence::NoMatch && e->modifiers() & Qt::ShiftModifier) { - // If Shift + Key_Backtab, also try Shift + Qt::Key_Tab - if (e->key() == Qt::Key_Backtab) { - QKeyEvent pe = QKeyEvent(e->type(), Qt::Key_Tab, e->modifiers(), e->text()); - result = find(&pe); - } - } - - // Should we eat this key press? - if (d->currentState == QKeySequence::PartialMatch - || (d->currentState == QKeySequence::ExactMatch && d->identicals.count())) - e->accept(); - // Does the new state require us to clean up? - if (result == QKeySequence::NoMatch) - clearSequence(d->currentSequences); - d->currentState = result; - -#if defined(DEBUG_QSHORTCUTMAP) - qDebug().nospace() << "QShortcutMap::nextState(" << e << ") = " << result; -#endif - return result; -} - - -/*! \internal - Determines if an enabled shortcut has a matcing key sequence. -*/ -bool QShortcutMap::hasShortcutForKeySequence(const QKeySequence &seq) const -{ - Q_D(const QShortcutMap); - QShortcutEntry entry(seq); // needed for searching - QList::ConstIterator itEnd = d->sequences.constEnd(); - QList::ConstIterator it = qLowerBound(d->sequences.constBegin(), itEnd, entry); - - for (;it != itEnd; ++it) { - if (matches(entry.keyseq, (*it).keyseq) == QKeySequence::ExactMatch && (*it).correctContext() && (*it).enabled) { - return true; - } - } - - //end of the loop: we didn't find anything - return false; -} - -/*! \internal - Returns the next state of the statemachine, based - on the new key event \a e. - Matches are appended to the vector of identicals, - which can be access through matches(). - \sa matches -*/ -QKeySequence::SequenceMatch QShortcutMap::find(QKeyEvent *e) -{ - Q_D(QShortcutMap); - if (!d->sequences.count()) - return QKeySequence::NoMatch; - - createNewSequences(e, d->newEntries); -#if defined(DEBUG_QSHORTCUTMAP) - qDebug() << "Possible shortcut key sequences:" << d->newEntries; -#endif - - // Should never happen - if (d->newEntries == d->currentSequences) { - Q_ASSERT_X(e->key() != Qt::Key_unknown || e->text().length(), - "QShortcutMap::find", "New sequence to find identical to previous"); - return QKeySequence::NoMatch; - } - - // Looking for new identicals, scrap old - d->identicals.resize(0); - - bool partialFound = false; - bool identicalDisabledFound = false; - QVector okEntries; - int result = QKeySequence::NoMatch; - for (int i = d->newEntries.count()-1; i >= 0 ; --i) { - QShortcutEntry entry(d->newEntries.at(i)); // needed for searching - QList::ConstIterator itEnd = d->sequences.constEnd(); - QList::ConstIterator it = - qLowerBound(d->sequences.constBegin(), itEnd, entry); - - int oneKSResult = QKeySequence::NoMatch; - int tempRes = QKeySequence::NoMatch; - do { - if (it == itEnd) - break; - tempRes = matches(entry.keyseq, (*it).keyseq); - oneKSResult = qMax(oneKSResult, tempRes); - if (tempRes != QKeySequence::NoMatch && (*it).correctContext()) { - if (tempRes == QKeySequence::ExactMatch) { - if ((*it).enabled) - d->identicals.append(&*it); - else - identicalDisabledFound = true; - } else if (tempRes == QKeySequence::PartialMatch) { - // We don't need partials, if we have identicals - if (d->identicals.size()) - break; - // We only care about enabled partials, so we don't consume - // key events when all partials are disabled! - partialFound |= (*it).enabled; - } - } - ++it; - // If we got a valid match on this run, there might still be more keys to check against, - // so we'll loop once more. If we get NoMatch, there's guaranteed no more possible - // matches in the shortcutmap. - } while (tempRes != QKeySequence::NoMatch); - - // If the type of match improves (ergo, NoMatch->Partial, or Partial->Exact), clear the - // previous list. If this match is equal or better than the last match, append to the list - if (oneKSResult > result) { - okEntries.clear(); -#if defined(DEBUG_QSHORTCUTMAP) - qDebug() << "Found better match (" << d->newEntries << "), clearing key sequence list"; -#endif - } - if (oneKSResult && oneKSResult >= result) { - okEntries << d->newEntries.at(i); -#if defined(DEBUG_QSHORTCUTMAP) - qDebug() << "Added ok key sequence" << d->newEntries; -#endif - } - } - - if (d->identicals.size()) { - result = QKeySequence::ExactMatch; - } else if (partialFound) { - result = QKeySequence::PartialMatch; - } else if (identicalDisabledFound) { - result = QKeySequence::ExactMatch; - } else { - clearSequence(d->currentSequences); - result = QKeySequence::NoMatch; - } - if (result != QKeySequence::NoMatch) - d->currentSequences = okEntries; -#if defined(DEBUG_QSHORTCUTMAP) - qDebug() << "Returning shortcut match == " << result; -#endif - return QKeySequence::SequenceMatch(result); -} - -/*! \internal - Clears \a seq to an empty QKeySequence. - Same as doing (the slower) - \snippet doc/src/snippets/code/src_gui_kernel_qshortcutmap.cpp 0 -*/ -void QShortcutMap::clearSequence(QVector &ksl) -{ - ksl.clear(); - d_func()->newEntries.clear(); -} - -/*! \internal - Alters \a seq to the new sequence state, based on the - current sequence state, and the new key event \a e. -*/ -void QShortcutMap::createNewSequences(QKeyEvent *e, QVector &ksl) -{ - Q_D(QShortcutMap); - QList possibleKeys = QKeyMapper::possibleKeys(e); - int pkTotal = possibleKeys.count(); - if (!pkTotal) - return; - - int ssActual = d->currentSequences.count(); - int ssTotal = qMax(1, ssActual); - // Resize to possible permutations of the current sequence(s). - ksl.resize(pkTotal * ssTotal); - - int index = ssActual ? d->currentSequences.at(0).count() : 0; - for (int pkNum = 0; pkNum < pkTotal; ++pkNum) { - for (int ssNum = 0; ssNum < ssTotal; ++ssNum) { - int i = (pkNum * ssTotal) + ssNum; - QKeySequence &curKsl = ksl[i]; - if (ssActual) { - const QKeySequence &curSeq = d->currentSequences.at(ssNum); - curKsl.setKey(curSeq[0], 0); - curKsl.setKey(curSeq[1], 1); - curKsl.setKey(curSeq[2], 2); - curKsl.setKey(curSeq[3], 3); - } else { - curKsl.setKey(0, 0); - curKsl.setKey(0, 1); - curKsl.setKey(0, 2); - curKsl.setKey(0, 3); - } - // Filtering keycode here with 0xdfffffff to ignore the Keypad modifier - curKsl.setKey(possibleKeys.at(pkNum) & 0xdfffffff, index); - } - } -} - -/*! \internal - Basically the same function as QKeySequence::matches(const QKeySequence &seq) const - only that is specially handles Key_hyphen as Key_Minus, as people mix these up all the time and - they conceptually the same. -*/ -QKeySequence::SequenceMatch QShortcutMap::matches(const QKeySequence &seq1, - const QKeySequence &seq2) const -{ - uint userN = seq1.count(), - seqN = seq2.count(); - - if (userN > seqN) - return QKeySequence::NoMatch; - - // If equal in length, we have a potential ExactMatch sequence, - // else we already know it can only be partial. - QKeySequence::SequenceMatch match = (userN == seqN - ? QKeySequence::ExactMatch - : QKeySequence::PartialMatch); - - for (uint i = 0; i < userN; ++i) { - int userKey = seq1[i], - sequenceKey = seq2[i]; - if ((userKey & Qt::Key_unknown) == Qt::Key_hyphen) - userKey = (userKey & Qt::KeyboardModifierMask) | Qt::Key_Minus; - if ((sequenceKey & Qt::Key_unknown) == Qt::Key_hyphen) - sequenceKey = (sequenceKey & Qt::KeyboardModifierMask) | Qt::Key_Minus; - if (userKey != sequenceKey) - return QKeySequence::NoMatch; - } - return match; -} - - -/*! \internal - Converts keyboard button states into modifier states -*/ -int QShortcutMap::translateModifiers(Qt::KeyboardModifiers modifiers) -{ - int result = 0; - if (modifiers & Qt::ShiftModifier) - result |= Qt::SHIFT; - if (modifiers & Qt::ControlModifier) - result |= Qt::CTRL; - if (modifiers & Qt::MetaModifier) - result |= Qt::META; - if (modifiers & Qt::AltModifier) - result |= Qt::ALT; - return result; -} - -/*! \internal - Returns the vector of QShortcutEntry's matching the last Identical state. -*/ -QVector QShortcutMap::matches() const -{ - Q_D(const QShortcutMap); - return d->identicals; -} - -/*! \internal - Dispatches QShortcutEvents to widgets who grabbed the matched key sequence. -*/ -void QShortcutMap::dispatchEvent(QKeyEvent *e) -{ - Q_D(QShortcutMap); - if (!d->identicals.size()) - return; - - const QKeySequence &curKey = d->identicals.at(0)->keyseq; - if (d->prevSequence != curKey) { - d->ambigCount = 0; - d->prevSequence = curKey; - } - // Find next - const QShortcutEntry *current = 0, *next = 0; - int i = 0, enabledShortcuts = 0; - while(i < d->identicals.size()) { - current = d->identicals.at(i); - if (current->enabled || !next){ - ++enabledShortcuts; - if (enabledShortcuts > d->ambigCount + 1) - break; - next = current; - } - ++i; - } - d->ambigCount = (d->identicals.size() == i ? 0 : d->ambigCount + 1); - // Don't trigger shortcut if we're autorepeating and the shortcut is - // grabbed with not accepting autorepeats. - if (!next || (e->isAutoRepeat() && !next->autorepeat)) - return; - // Dispatch next enabled -#if defined(DEBUG_QSHORTCUTMAP) - qDebug().nospace() - << "QShortcutMap::dispatchEvent(): Sending QShortcutEvent(\"" - << (QString)next->keyseq << "\", " << next->id << ", " - << (bool)(enabledShortcuts>1) << ") to object(" << next->owner << ')'; -#endif - QShortcutEvent se(next->keyseq, next->id, enabledShortcuts>1); - QCoreApplication::sendEvent(const_cast(next->owner), &se); -} - -/* \internal - QShortcutMap dump function, only available when DEBUG_QSHORTCUTMAP is - defined. -*/ -#if defined(Dump_QShortcutMap) -void QShortcutMap::dumpMap() const -{ - Q_D(const QShortcutMap); - for (int i = 0; i < d->sequences.size(); ++i) - qDebug().nospace() << &(d->sequences.at(i)); -} -#endif - -QT_END_NAMESPACE - -#endif // QT_NO_SHORTCUT diff --git a/src/widgets/to_be_moved/qshortcutmap_p.h b/src/widgets/to_be_moved/qshortcutmap_p.h deleted file mode 100644 index 29045eb7db..0000000000 --- a/src/widgets/to_be_moved/qshortcutmap_p.h +++ /dev/null @@ -1,115 +0,0 @@ -/**************************************************************************** -** -** 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$ -** -****************************************************************************/ - -#ifndef QSHORTCUTMAP_P_H -#define QSHORTCUTMAP_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "QtGui/qkeysequence.h" -#include "QtCore/qvector.h" -#include "QtCore/qscopedpointer.h" - -QT_BEGIN_NAMESPACE - -#ifndef QT_NO_SHORTCUT - -// To enable dump output uncomment below -//#define Dump_QShortcutMap - -class QKeyEvent; -struct QShortcutEntry; -class QShortcutMapPrivate; -class QObject; - -class QShortcutMap -{ - Q_DECLARE_PRIVATE(QShortcutMap) -public: - QShortcutMap(); - ~QShortcutMap(); - - typedef bool (*ContextMatcher)(QObject *object, Qt::ShortcutContext context); - - int addShortcut(QObject *owner, const QKeySequence &key, Qt::ShortcutContext context, ContextMatcher matcher); - int removeShortcut(int id, QObject *owner, const QKeySequence &key = QKeySequence()); - int setShortcutEnabled(bool enable, int id, QObject *owner, const QKeySequence &key = QKeySequence()); - int setShortcutAutoRepeat(bool on, int id, QObject *owner, const QKeySequence &key = QKeySequence()); - - void resetState(); - QKeySequence::SequenceMatch nextState(QKeyEvent *e); - QKeySequence::SequenceMatch state(); - void dispatchEvent(QKeyEvent *e); - bool tryShortcutEvent(QObject *o, QKeyEvent *e); - -#ifdef Dump_QShortcutMap - void dumpMap() const; -#endif - - bool hasShortcutForKeySequence(const QKeySequence &seq) const; - - -private: - QScopedPointer d_ptr; - - QKeySequence::SequenceMatch find(QKeyEvent *e); - QKeySequence::SequenceMatch matches(const QKeySequence &seq1, const QKeySequence &seq2) const; - QVector matches() const; - void createNewSequences(QKeyEvent *e, QVector &ksl); - void clearSequence(QVector &ksl); - bool correctContext(const QShortcutEntry &item) const; - int translateModifiers(Qt::KeyboardModifiers modifiers); -}; - -#endif // QT_NO_SHORTCUT - -QT_END_NAMESPACE - -#endif // QSHORTCUTMAP_P_H diff --git a/src/widgets/to_be_moved/to_be_moved.pri b/src/widgets/to_be_moved/to_be_moved.pri deleted file mode 100644 index fc570ce2d9..0000000000 --- a/src/widgets/to_be_moved/to_be_moved.pri +++ /dev/null @@ -1,7 +0,0 @@ -HEADERS += \ - to_be_moved/qshortcut.h \ - to_be_moved/qshortcutmap_p.h \ - -SOURCES += \ - to_be_moved/qshortcut.cpp \ - to_be_moved/qshortcutmap.cpp \ diff --git a/src/widgets/widgets.pro b/src/widgets/widgets.pro index bff487bf3f..74d5e9d7ed 100644 --- a/src/widgets/widgets.pro +++ b/src/widgets/widgets.pro @@ -30,9 +30,6 @@ symbian { include(s60framework/s60framework.pri) } -# to be moved into QtGui -include(to_be_moved/to_be_moved.pri) - #modules include(animation/animation.pri) include(kernel/kernel.pri) -- cgit v1.2.3