File indexing completed on 2024-05-19 04:35:47
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 #include "toggleactionmenu.h" 0011 0012 #include <QActionEvent> 0013 #include <QMenu> 0014 0015 ToggleActionMenu::ToggleActionMenu(QObject *parent) 0016 : ToggleActionMenu(QIcon(), QString(), parent) 0017 { 0018 } 0019 0020 ToggleActionMenu::ToggleActionMenu(const QString &text, QObject *parent) 0021 : ToggleActionMenu(QIcon(), text, parent) 0022 { 0023 } 0024 0025 ToggleActionMenu::ToggleActionMenu(const QIcon &icon, const QString &text, QObject *parent) 0026 : KActionMenu(icon, text, parent) 0027 , m_defaultAction(nullptr) 0028 { 0029 slotMenuChanged(); 0030 } 0031 0032 QWidget *ToggleActionMenu::createWidget(QWidget *parent) 0033 { 0034 QWidget *buttonWidget = KActionMenu::createWidget(parent); 0035 QToolButton *button = qobject_cast<QToolButton *>(buttonWidget); 0036 if (!button) { 0037 // This function is used to add a button into the toolbar. 0038 // QWidgetAction::createWidget() is also called with other parents, 0039 // e. g. when this ToggleActionMenu is added to a QMenu. 0040 // Therefore, reaching this code path is a valid use case. 0041 return buttonWidget; 0042 } 0043 0044 // BEGIN QToolButton hack 0045 // Setting the default action of a QToolButton 0046 // to an action of its menu() is tricky. 0047 // Remove this menu action from the button, 0048 // so it doesn't compose a menu of this menu action and its own menu. 0049 button->removeAction(this); 0050 // The button has lost the menu now, let it use the correct menu. 0051 button->setMenu(menu()); 0052 // END QToolButton hack 0053 0054 m_buttons.append(button); 0055 m_originalToolButtonStyle[button] = button->toolButtonStyle(); 0056 0057 // Apply other properties to the button. 0058 updateButtons(); 0059 0060 return button; 0061 } 0062 0063 QAction *ToggleActionMenu::defaultAction() 0064 { 0065 return m_defaultAction ? m_defaultAction : this; 0066 } 0067 0068 void ToggleActionMenu::setDefaultAction(QAction *action) 0069 { 0070 if (action && menu()->actions().contains(action)) { 0071 m_defaultAction = action; 0072 } else { 0073 m_defaultAction = nullptr; 0074 } 0075 updateButtons(); 0076 } 0077 0078 Qt::ToolButtonStyle ToggleActionMenu::styleFor(QToolButton *button) const 0079 { 0080 Qt::ToolButtonStyle style = m_originalToolButtonStyle[button]; 0081 0082 if (style == Qt::ToolButtonTextBesideIcon && priority() < QAction::NormalPriority) { 0083 style = Qt::ToolButtonIconOnly; 0084 } 0085 0086 return style; 0087 } 0088 0089 void ToggleActionMenu::updateButtons() 0090 { 0091 for (QToolButton *button : std::as_const(m_buttons)) { 0092 if (button) { 0093 button->setDefaultAction(this->defaultAction()); 0094 // If *this action* is low priority we need to tell the button 0095 // so that it hides the text 0096 button->setToolButtonStyle(styleFor(button)); 0097 0098 button->setPopupMode(popupMode()); 0099 } 0100 } 0101 } 0102 0103 bool ToggleActionMenu::eventFilter(QObject *watched, QEvent *event) 0104 { 0105 // If the defaultAction() is removed from the menu, reset the default action. 0106 if (watched == menu() && event->type() == QEvent::ActionRemoved) { 0107 QActionEvent *actionEvent = static_cast<QActionEvent *>(event); 0108 if (actionEvent->action() == defaultAction()) { 0109 setDefaultAction(nullptr); 0110 } 0111 } 0112 0113 return KActionMenu::eventFilter(watched, event); 0114 } 0115 0116 void ToggleActionMenu::slotMenuChanged() 0117 { 0118 menu()->installEventFilter(this); 0119 // Not removing old event filter, because we would need to remember the old menu. 0120 } 0121 0122 #include "moc_toggleactionmenu.cpp"