File indexing completed on 2024-04-28 15:52:00

0001 /*
0002     SPDX-FileCopyrightText: 2019-2021 David Hurka <david.hurka@mailbox.org>
0003 
0004     Inspired by and replacing toolaction.h by:
0005     SPDX-FileCopyrightText: 2004-2006 Albert Astals Cid <aacid@kde.org>
0006 
0007     SPDX-License-Identifier: GPL-2.0-or-later
0008 */
0009 
0010 #ifndef TOGGLEACTIONMENU_H
0011 #define TOGGLEACTIONMENU_H
0012 
0013 #include <KActionMenu>
0014 #include <QPointer>
0015 #include <QSet>
0016 #include <QToolButton>
0017 
0018 /**
0019  * @brief A KActionMenu, which allows to set the default action of its toolbar buttons.
0020  *
0021  * This behaves like a KActionMenu, with the addition of setDefaultAction().
0022  *
0023  * @par Intention
0024  * Setting the default action of toolbar buttons has the advantage that the user
0025  * can trigger a frequently used action directly without opening the menu.
0026  * Additionally, the state of the default action is visible in the toolbar.
0027  *
0028  * @par Example
0029  * You can make the toolbar button show the last used action with only one connection.
0030  * You may want to initialize the default action.
0031  * \code
0032  * if (myToggleActionMenu->defaultAction() == myToggleActionMenu) {
0033  *     myToggleActionMenu->setDefaultAction(myFirstAction);
0034  * }
0035  * connect(myToggleActionMenu->menu(), &QMenu::triggered,
0036  *         myToggleActionMenu, &ToggleActionMenu::setDefaultAction);
0037  * \endcode
0038  */
0039 class ToggleActionMenu : public KActionMenu
0040 {
0041     Q_OBJECT
0042 
0043 public:
0044     explicit ToggleActionMenu(QObject *parent);
0045     ToggleActionMenu(const QString &text, QObject *parent);
0046     /**
0047      * Constructs an empty ToggleActionMenu.
0048      *
0049      * @param icon The icon of this menu, when plugged into another menu.
0050      * @param text The name of this menu, when plugged into another menu.
0051      * @param parent Parent @c QOject.
0052      */
0053     ToggleActionMenu(const QIcon &icon, const QString &text, QObject *parent);
0054 
0055     QWidget *createWidget(QWidget *parent) override;
0056 
0057     /**
0058      * Returns the current default action of the toolbar buttons.
0059      * May be @c this.
0060      *
0061      * This action is set by setDefaultAction().
0062      */
0063     QAction *defaultAction();
0064 
0065 public Q_SLOTS:
0066     /**
0067      * Sets the default action of the toolbar buttons.
0068      *
0069      * Toolbar buttons are updated immediately.
0070      *
0071      * Calling setDefaultAction(nullptr) will reset the default action
0072      * to this menu itself.
0073      *
0074      * @note
0075      * @p action must be present in the menu as direct child action.
0076      * The default action will be reset to this menu itself
0077      * when @p action is removed from the menu.
0078      *
0079      * @note
0080      * @p action will define all properties of the toolbar buttons.
0081      * When you disable @p action, the toolbar button will become disabled too.
0082      * Then the menu can no longer be accessed.
0083      */
0084     void setDefaultAction(QAction *action);
0085 
0086 protected:
0087     /** Can store @c nullptr, which means this menu itself will be the default action. */
0088     QPointer<QAction> m_defaultAction;
0089     QList<QPointer<QToolButton>> m_buttons;
0090 
0091     QHash<const QToolButton *, Qt::ToolButtonStyle> m_originalToolButtonStyle;
0092 
0093     /**
0094      * Returns the aproppriate style for @p button.
0095      * Respects both toolbar settings and settings for this menu action.
0096      */
0097     Qt::ToolButtonStyle styleFor(QToolButton *button) const;
0098 
0099     /**
0100      * Updates the toolbar buttons by setting the current defaultAction() on them.
0101      *
0102      * (If the current defaultAction() is invalid, `this` is used instead.)
0103      */
0104     void updateButtons();
0105 
0106     /**
0107      * Updates the event filter, which listens to QMenu’s QActionEvent.
0108      *
0109      * This is connected to QAction::changed().
0110      * That signal is emmited when the menu changes, but that’s not documented.
0111      */
0112     void slotMenuChanged();
0113 
0114     bool eventFilter(QObject *watched, QEvent *event) override;
0115 };
0116 
0117 #endif // TOGGLEACTIONMENU_H