File indexing completed on 2024-06-16 04:15:38

0001 /* This file is part of the KDE libraries
0002     SPDX-FileCopyrightText: 2006, 2007 Andreas Hartmetz (ahartmetz@gmail.com)
0003     SPDX-FileCopyrightText: 2008 Michael Jansen <kde@michael-jansen.biz>
0004     SPDX-FileCopyrightText: 2008 Alexander Dymo <adymo@kdevelop.org>
0005 
0006     SPDX-License-Identifier: LGPL-2.0-or-later
0007 */
0008 
0009 #ifndef KISSHORTCUTSDIALOG_P_H
0010 #define KISSHORTCUTSDIALOG_P_H
0011 
0012 #include "KisShortcutsEditor.h"
0013 #include "kkeysequencewidget.h"
0014 #include "KisShortcutsDialog.h"
0015 
0016 #include <kextendableitemdelegate.h>
0017 #include <klocalizedstring.h>
0018 #include <kmessagebox.h>
0019 
0020 #include <QKeySequence>
0021 #include <QMetaType>
0022 #include <QModelIndex>
0023 #include <QList>
0024 #include <QCollator>
0025 #include <QHBoxLayout>
0026 
0027 class QLabel;
0028 class QTreeWidget;
0029 class QTreeWidgetItem;
0030 class QRadioButton;
0031 class QAction;
0032 class KisKActionCollection;
0033 class QPushButton;
0034 class QComboBox;
0035 class KisShortcutsDialog;
0036 class KisKShortcutSchemesEditor;
0037 class QAction;
0038 
0039 
0040 enum ColumnDesignation {
0041     Name = 0,
0042     LocalPrimary,
0043     LocalAlternate,
0044     Id
0045 };
0046 
0047 // XXX: Hmm
0048 enum MyRoles {
0049     ShortcutRole = Qt::UserRole,
0050     DefaultShortcutRole,
0051     ObjectRole
0052 };
0053 
0054 
0055 /**
0056  * Type used for QTreeWidgetItems
0057  *
0058  * @internal
0059  */
0060 enum ItemTypes {
0061     NonActionItem = 0,
0062     ActionItem = 1
0063 };
0064 
0065 // Return the first item of the list, if it exists
0066 QKeySequence primarySequence(const QList<QKeySequence> &sequences);
0067 
0068 // Return the second item of the list, if it exists
0069 QKeySequence alternateSequence(const QList<QKeySequence> &sequences);
0070 
0071 
0072 
0073 class KisShortcutsDialog::KisShortcutsDialogPrivate
0074 {
0075 public:
0076     KisShortcutsDialogPrivate(KisShortcutsDialog *q);
0077     void changeShortcutScheme(const QString &scheme);
0078     void undo();
0079     void save();
0080 
0081     QHash<QString, KisKActionCollection *> m_collections;
0082     KisShortcutsDialog *q;
0083     KisShortcutsEditor *m_shortcutsEditor {0};
0084     KisKShortcutSchemesEditor *m_schemeEditor{0};
0085 };
0086 
0087 
0088 /**
0089  * Mixes the KisKShortcutWidget into the treeview used by KisShortcutsEditor. When
0090  * selecting an shortcut it changes the display from "CTRL-W" to the Widget.
0091  *
0092  * @bug That delegate uses KExtendableItemDelegate. That means a cell can be
0093  * expanded. When selected a cell is replaced by a KisShortcutsEditor. When
0094  * painting the widget KExtendableItemDelegate reparents the widget to the
0095  * viewport of the itemview it belongs to. The widget is destroyed when the user
0096  * selects another shortcut or explicitly issues a contractItem event. But when
0097  * the user clears the model the delegate misses that event and doesn't delete
0098  * the KShortcutseditor. And remains as a visible artifact in your treeview.
0099  * Additionally when closing your application you get an assertion failure from
0100  * KExtendableItemDelegate.
0101  *
0102  * @internal
0103  */
0104 class KisShortcutsEditorDelegate : public KExtendableItemDelegate
0105 {
0106     Q_OBJECT
0107 public:
0108     KisShortcutsEditorDelegate(QTreeWidget *parent, bool allowLetterShortcuts);
0109     //reimplemented to have some extra height
0110     QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override;
0111 
0112     /**
0113      * Set a list of action collections to check against for conflicting
0114      * shortcuts.
0115      *
0116      * @see KisKKeySequenceWidget::setCheckActionCollections
0117      */
0118     void setCheckActionCollections(const QList<KisKActionCollection *> checkActionCollections);
0119     bool eventFilter(QObject *, QEvent *) override;
0120 private:
0121     mutable QPersistentModelIndex m_editingIndex;
0122     bool m_allowLetterShortcuts;
0123     QWidget *m_editor;
0124 
0125     //! List of actionCollections to check for conflicts.
0126     QList<KisKActionCollection *> m_checkActionCollections;
0127 
0128 
0129 Q_SIGNALS:
0130   void shortcutChanged(QVariant, const QModelIndex &);
0131 
0132 public Q_SLOTS:
0133   void hiddenBySearchLine(QTreeWidgetItem *, bool);
0134 
0135 private Q_SLOTS:
0136     void itemActivated(QModelIndex index);
0137 
0138     /**
0139      * When the user collapses a hole subtree of shortcuts then remove eventually
0140      * extended items. Else we get that artifact bug. See above.
0141      */
0142     void itemCollapsed(QModelIndex index);
0143 
0144     /**
0145      * If the user allowed stealing a shortcut we want to be able to undo
0146      * that.
0147      */
0148     void stealShortcut(const QKeySequence &seq, QAction *action);
0149 
0150     void keySequenceChanged(const QKeySequence &);
0151 
0152 };
0153 
0154 
0155 /**
0156  * Edit a shortcut. This widget is displayed when a user clicks on a shortcut
0157  * from the list. It contains radio buttons choosing between default and custom
0158  * shortcuts, and a button to configure the custom shortcut.
0159  *
0160  * @see KisShortcutsEditorDelegate::itemActivated
0161  * @see KisShortcutWidget.cpp
0162  *
0163  * @internal
0164  */
0165 class ShortcutEditWidget : public QWidget
0166 {
0167     Q_OBJECT
0168 public:
0169     ShortcutEditWidget(QWidget *viewport, const QKeySequence &defaultSeq, const QKeySequence &activeSeq,
0170                        bool allowLetterShortcuts);
0171 
0172     //! @see KisKKeySequenceWidget::setCheckActionCollections()
0173     void setCheckActionCollections(const QList<KisKActionCollection *> checkActionCollections);
0174 
0175     //@{
0176     //! @see KisKKeySequenceWidget::checkAgainstStandardShortcuts()
0177     KisKKeySequenceWidget::ShortcutTypes checkForConflictsAgainst() const;
0178     void setCheckForConflictsAgainst(KisKKeySequenceWidget::ShortcutTypes);
0179     //@}
0180 
0181     //@{
0182     //! @see KisKKeySequenceWidget::checkAgainstStandardShortcuts()
0183     bool multiKeyShortcutsAllowed() const;
0184     void setMultiKeyShortcutsAllowed(bool);
0185     //@}
0186 
0187     //! @see KisKKeySequenceWidget::setComponentName
0188     void setComponentName(const QString componentName);
0189 
0190     void setAction(QObject *action);
0191     void paintEvent(QPaintEvent *pe) override;
0192 
0193 
0194 Q_SIGNALS:
0195     //! Emitted when the key sequence is changed.
0196     void keySequenceChanged(const QKeySequence &);
0197 
0198     //! @see KisKKeySequenceWidget::stealShortcut()
0199     void stealShortcut(const QKeySequence &seq, QAction *action);
0200 
0201 
0202 public Q_SLOTS:
0203   //! Set the displayed sequences
0204   void setKeySequence(const QKeySequence &activeSeq);
0205 
0206 private Q_SLOTS:
0207     void defaultToggled(bool);
0208     void setCustom(const QKeySequence &);
0209 
0210 
0211 
0212 private:
0213     QLabel *m_defaultLabel;
0214     QKeySequence m_defaultKeySequence;
0215     QRadioButton *m_defaultRadio;
0216     QRadioButton *m_customRadio;
0217     KisKKeySequenceWidget *m_customEditor;
0218     bool m_isUpdating;
0219     QObject *m_action;
0220 };
0221 
0222 #endif /* KISSHORTCUTSDIALOG_P_H */