okular/part/toggleactionmenu.h
David Hurka 5a58d3bb8e Simplify ToggleActionMenu
* Remove the ImplicitDefaultAction intelligence, so ToggleActionMenu is
  not more than a KActionMenu with setDefaultAction().
* Instead, reset the default action when it gets removed from the menu().
  This is done by filtering QActionEvent from menu().
* Add an autotest for ToggleActionMenu.

This replaces prior efforts to fix problems in ToggleActionMenu
in !245 and !254, following the discussion on the virtual meeting
at 2021-02-26.

6b26a2b4b and 1786e6c99 have already ported PageView and
AnnotationActionHandler to the simplified interface.
2021-04-23 01:54:42 +00:00

113 lines
4 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/***************************************************************************
* Copyright (C) 2019-2021 by David Hurka <david.hurka@mailbox.org> *
* *
* Inspired by and replacing toolaction.h by: *
* Copyright (C) 2004-2006 by Albert Astals Cid <aacid@kde.org> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
***************************************************************************/
#ifndef TOGGLEACTIONMENU_H
#define TOGGLEACTIONMENU_H
#include <KActionMenu>
#include <QPointer>
#include <QSet>
#include <QToolButton>
/**
* @brief A KActionMenu, which allows to set the default action of its toolbar buttons.
*
* This behaves like a KActionMenu, with the addition of setDefaultAction().
*
* @par Intention
* Setting the default action of toolbar buttons has the advantage that the user
* can trigger a frequently used action directly without opening the menu.
* Additionally, the state of the default action is visible in the toolbar.
*
* @par Example
* You can make the toolbar button show the last used action with only one connection.
* You may want to initialize the default action.
* \code
* if (myToggleActionMenu->defaultAction() == myToggleActionMenu) {
* myToggleActionMenu->setDefaultAction(myFirstAction);
* }
* connect(myToggleActionMenu->menu(), &QMenu::triggered,
* myToggleActionMenu, &ToggleActionMenu::setDefaultAction);
* \endcode
*/
class ToggleActionMenu : public KActionMenu
{
Q_OBJECT
public:
explicit ToggleActionMenu(QObject *parent);
ToggleActionMenu(const QString &text, QObject *parent);
/**
* Constructs an empty ToggleActionMenu.
*
* @param icon The icon of this menu, when plugged into another menu.
* @param text The name of this menu, when plugged into another menu.
* @param parent Parent @c QOject.
*/
ToggleActionMenu(const QIcon &icon, const QString &text, QObject *parent);
QWidget *createWidget(QWidget *parent) override;
/**
* Returns the current default action of the toolbar buttons.
* May be @c this.
*
* This action is set by setDefaultAction().
*/
QAction *defaultAction();
public Q_SLOTS:
/**
* Sets the default action of the toolbar buttons.
*
* Toolbar buttons are updated immediately.
*
* Calling setDefaultAction(nullptr) will reset the default action
* to this menu itself.
*
* @note
* @p action must be present in the menu as direct child action.
* The default action will be reset to this menu itself
* when @p action is removed from the menu.
*
* @note
* @p action will define all properties of the toolbar buttons.
* When you disable @p action, the toolbar button will become disabled too.
* Then the menu can no longer be accessed.
*/
void setDefaultAction(QAction *action);
protected:
/** Can store @c nullptr, which means this menu itself will be the default action. */
QPointer<QAction> m_defaultAction;
QList<QPointer<QToolButton>> m_buttons;
/**
* Updates the toolbar buttons by setting the current defaultAction() on them.
*
* (If the current defaultAction() is invalid, `this` is used instead.)
*/
void updateButtons();
/**
* Updates the event filter, which listens to QMenus QActionEvent.
*
* This is connected to QAction::changed().
* That signal is emmited when the menu changes, but thats not documented.
*/
void slotMenuChanged();
bool eventFilter(QObject *watched, QEvent *event) override;
};
#endif // TOGGLEACTIONMENU_H