File indexing completed on 2024-04-21 14:55:58

0001 /*  This file is part of the KDE libraries
0002     Copyright (C) 2001,2002 Ellis Whitehead <ellis@kde.org>
0003     Copyright (C) 2006 Hamish Rodda <rodda@kde.org>
0004     Copyright (C) 2006 Andreas Hartmetz <ahartmetz@gmail.com>
0005 
0006     This library is free software; you can redistribute it and/or
0007     modify it under the terms of the GNU Library General Public
0008     License as published by the Free Software Foundation; either
0009     version 2 of the License, or (at your option) any later version.
0010 
0011     This library is distributed in the hope that it will be useful,
0012     but WITHOUT ANY WARRANTY; without even the implied warranty of
0013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0014     Library General Public License for more details.
0015 
0016     You should have received a copy of the GNU Library General Public License
0017     along with this library; see the file COPYING.LIB.  If not, write to
0018     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0019     Boston, MA 02110-1301, USA.
0020 */
0021 
0022 /**
0023  * @file kshortcut.h
0024  * Defines platform-independent classes for keyboard shortcut handling.
0025  */
0026 
0027 #ifndef KSHORTCUT_H
0028 #define KSHORTCUT_H
0029 
0030 #include <kdelibs4support_export.h>
0031 
0032 #include <QList>
0033 #include <QHash>
0034 #include <QMetaType>
0035 #include <QKeySequence>
0036 
0037 class KShortcutPrivate;
0038 
0039 /**
0040 * @short Represents a keyboard shortcut
0041 *
0042 * The KShortcut class is used to represent a keyboard shortcut to an action.
0043 * A shortcut is normally a single key with modifiers, such as Ctrl+V.
0044 * A KShortcut object may also contain an alternate key sequence which will also
0045 * activate the action it's associated with, as long as no other actions have
0046 * defined that key as their primary key. Ex: Ctrl+V;Shift+Insert.
0047 *
0048 * This can be used to add additional accelerators to a KAction. For example,
0049 * the below code binds the escape key to the close action.
0050 *
0051 * \code
0052 *  KAction *closeAction = KStandardAction::close(this, SLOT( close() ), actionCollection());
0053 *  KShortcut closeShortcut = closeAction->shortcut();
0054 *  closeShortcut.setAlternate(Qt::Key_Escape);
0055 *  closeAction->setShortcut(closeShortcut);
0056 * \endcode
0057 */
0058 class KDELIBS4SUPPORT_DEPRECATED_EXPORT KShortcut
0059 {
0060 public:
0061     /**
0062      * An enum about the behavior of operations that treat a KShortcut like a list of QKeySequences.
0063      */
0064     enum EmptyHandling {
0065         ///if a shortcut is or becomes empty, let it stay as a placeholder
0066         KeepEmpty = 0,
0067         ///remove empty QKeySequences, possibly changing the positions of QKeySequences due to the ensuing reshuffling.
0068         RemoveEmpty
0069     };
0070 
0071     /**
0072      * Creates a new empty shortcut.
0073      * @see isEmpty()
0074      * @see clear()
0075      */
0076     KShortcut();
0077 
0078     /**
0079      * Creates a new shortcut that contains the given Qt key
0080      * sequence as primary shortcut.
0081      * @param primary Qt key sequence to add
0082      */
0083     KDELIBS4SUPPORT_DEPRECATED explicit KShortcut(const QKeySequence &primary);
0084 
0085     /**
0086      * Creates a new shortcut with the given Qt key sequences
0087      * as primary and secondary shortcuts.
0088      * @param primary Qt keycode of primary shortcut
0089      * @param alternate Qt keycode of alternate shortcut
0090      * @see Qt::Key
0091      */
0092     // TODO KDE5 move to QShortcut
0093     KShortcut(const QKeySequence &primary, const QKeySequence &alternate);
0094 
0095     /**
0096      * Creates a new shortcut with the given Qt key codes
0097      * as primary and secondary shortcuts.
0098      * You can only assign single-key shortcuts this way.
0099      * @param keyQtPri Qt keycode of primary shortcut
0100      * @param keyQtAlt Qt keycode of alternate shortcut
0101      * @see Qt::Key
0102      */
0103     // TODO KDE5 move to QShortcut
0104     KDELIBS4SUPPORT_DEPRECATED explicit KShortcut(int keyQtPri, int keyQtAlt = 0);
0105 
0106     /**
0107      * Copy constructor.
0108      */
0109     KShortcut(const KShortcut &other);
0110 
0111     /**
0112      * Creates a new shortcut that contains the key sequences described
0113      * in @p description. The format of description is the same as
0114      * used in QKeySequence::fromString(const QString&).
0115      * Up to two key sequences separated by a semicolon followed by a
0116      * space "; " may be given.
0117      * @param description the description of key sequence(s)
0118      * @see QKeySequence::fromString(const QString&, SequenceFormat)
0119      */
0120     // TODO KDE5 move to QShortcut
0121     KDELIBS4SUPPORT_DEPRECATED explicit KShortcut(const QString &description);
0122 
0123     /**
0124      * Creates a new shortcut with the given Qt key sequences.
0125      * The first sequence in the list is considered to be the primary
0126      * sequence, the second one the alternate.
0127      * @param seqs List of key sequeces.
0128      */
0129     // TODO KDE5 move to QShortcut
0130     KShortcut(const QList<QKeySequence> &seqs);
0131 
0132     /**
0133      * Destructor.
0134      */
0135     ~KShortcut();
0136 
0137     /** @name Query methods */
0138     /** @{ */
0139 
0140     /**
0141      * Returns the primary key sequence of this shortcut.
0142      * @return primary key sequence
0143      */
0144     QKeySequence primary() const;
0145 
0146     /**
0147      * Returns the alternate key sequence of this shortcut.
0148      * @return alternate key sequence
0149      */
0150     QKeySequence alternate() const;
0151 
0152     /**
0153      * Returns whether this shortcut contains any nonempty key sequences.
0154      * @return whether this shortcut is empty
0155      */
0156     bool isEmpty() const;
0157 
0158     /**
0159      * Returns whether at least one of the key sequences is equal to @p needle.
0160      * @return whether this shortcut contains @p needle
0161      */
0162     bool contains(const QKeySequence &needle) const;
0163 
0164     /**
0165      * Returns whether at least one of the key sequences conflicts witho @p needle.
0166      * @return whether this shortcut conflicts with @p needle
0167      */
0168     bool conflictsWith(const QKeySequence &needle) const;
0169 
0170     /**
0171       * Returns a description of the shortcut as a semicolon-separated
0172       * list of key sequences, as returned by QKeySequence::toString().
0173       * @return the string represenation of this shortcut
0174       * @see QKeySequence::toString()
0175       * @see KShortcut(const QString &description)
0176       */
0177     QString toString() const;
0178 
0179     /**
0180      * Returns a description of the shortcut as a semicolon-separated
0181      * list of key sequences, as returned by QKeySequence::toString().
0182      * @return the string represenation of this shortcut
0183      * @see QKeySequence::toString()
0184      * @see KShortcut(const QString &description)
0185      * @since KDE 4.2
0186      */
0187     QString toString(QKeySequence::SequenceFormat format) const;
0188 
0189     bool operator==(const KShortcut &other) const;
0190 
0191     bool operator!=(const KShortcut &other) const;
0192 
0193     /**
0194      * Returns shortcut as QList\<QKeySequence\>, and is equivalent to toList(RemoveEmpty).
0195      * Be aware that empty shortcuts will not be included in the list;
0196      * due to this, conversion operations like
0197      * KShortcut b = (QList\<QKeySequence\>)KShortcut a
0198      * will not always result in b == a.
0199      * @return the shortcut converted to a QList\<QKeySequence\>
0200      */
0201     operator QList<QKeySequence>() const;
0202 
0203     /**
0204      * The same as operator QList\<QKeySequence\>()
0205      * If @p handleEmpty equals RemoveEmpty, empty key sequences will be left out of the result.
0206      * Otherwise, empy key sequences will be included; you can be sure that
0207      * shortcut.alternate() == shortcut.toList(KeepEmpty).at(1).
0208      * @return the shortcut converted to a QList\<QKeySequence\>
0209      */
0210     QList<QKeySequence> toList(enum EmptyHandling handleEmpty = RemoveEmpty) const;
0211 
0212     /**
0213      * Returns shortcut as QVariant.
0214      */
0215     operator QVariant() const;
0216 
0217     /** @} */
0218     /** @name Mutator methods */
0219     /** @{ */
0220 
0221     /**
0222      * Set the primary key sequence of this shortcut to the given key sequence.
0223      * @param keySeq set primary key sequence to this
0224      */
0225     void setPrimary(const QKeySequence &keySeq);
0226 
0227     /**
0228      * Set the alternate key sequence of this shortcut to the given key sequence.
0229      * @param keySeq set alternate key sequence to this
0230      */
0231     void setAlternate(const QKeySequence &keySeq);
0232 
0233     /**
0234      * Remove @p keySeq from this shortcut.
0235      * If @p handleEmpty equals RemoveEmpty, following key sequences will move up to take the place of
0236      * @p keySeq. Otherwise, key sequences equal to @p keySeq will be set to empty.
0237      * @param keySeq remove this key sequence from the shortcut
0238      */
0239     void remove(const QKeySequence &keySeq, enum EmptyHandling handleEmpty = RemoveEmpty);
0240 
0241     /**
0242      * Assignment operator.
0243      */
0244     KShortcut &operator=(const KShortcut &other);
0245 
0246 private:
0247     class KShortcutPrivate *const d;
0248 };
0249 
0250 inline uint qHash(const KShortcut &key)
0251 {
0252     return qHash(key.primary()[0]) + qHash(key.primary()[1]);
0253 }
0254 
0255 inline uint qHash(const QKeySequence &key)
0256 {
0257     uint hash = 0;
0258     for (int i = 0; i < static_cast<int>(key.count()); i++) {
0259         hash += qHash(key[uint(i)]);
0260     }
0261     return hash;
0262 }
0263 
0264 Q_DECLARE_METATYPE(KShortcut)
0265 
0266 #endif // KSHORTCUT_H