/*************************************************************************** * Copyright (C) 2019 by David Hurka * * * * Inspired by and replacing toolaction.h by: * * Copyright (C) 2004-2006 by Albert Astals Cid * * * * 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. * ***************************************************************************/ #include "toggleactionmenu.h" #include #include ToggleActionMenu::ToggleActionMenu( QObject * parent ) : ToggleActionMenu( QIcon(), QString(), parent ) { } ToggleActionMenu::ToggleActionMenu( const QString &text, QObject * parent ) : ToggleActionMenu( QIcon(), text, parent ) { } ToggleActionMenu::ToggleActionMenu( const QIcon &icon, const QString &text, QObject * parent, PopupMode popupMode, MenuLogic logic ) : KActionMenu( icon, text, parent ), m_defaultAction( nullptr ), m_suggestedDefaultAction( nullptr ), m_menuLogic( logic ) { connect( this, &QAction::changed, this, &ToggleActionMenu::updateButtons ); if ( popupMode == DelayedPopup ) { setDelayed( true ); } else { setDelayed( false ); } setStickyMenu( false ); if ( logic & ImplicitDefaultAction ) { connect( menu(), &QMenu::triggered, this, &ToggleActionMenu::setDefaultAction ); } } QWidget * ToggleActionMenu::createWidget( QWidget * parent ) { QToolButton * button = qobject_cast< QToolButton * >( KActionMenu::createWidget( parent ) ); if ( !button ) { // This function is used to add a button into the toolbar. // KActionMenu will plug itself as QToolButton. // So, if no QToolButton was returned, this was not called the intended way. return button; } // Remove this menu action from the button, // so it doesn't compose a menu of this menu action and its own menu. button->removeAction( this ); // The button has lost the menu now, let it use the correct menu. button->setMenu( menu() ); m_buttons.append( QPointer< QToolButton >( button ) ); // Apply other properties to the button. updateButtons(); return button; } void ToggleActionMenu::setDefaultAction( QAction *action ) { m_defaultAction = action; updateButtons(); } void ToggleActionMenu::suggestDefaultAction( QAction *action ) { m_suggestedDefaultAction = action; } QAction * ToggleActionMenu::checkedAction( QMenu *menu ) const { // Look at each action a in the menu whether it is checked. // If a is a menu, recursively call checkedAction(). const QList actions = menu->actions(); for ( QAction * a : actions ) { if ( a->isChecked() ) { return a; } else if ( a->menu() ) { QAction * b = checkedAction( a->menu() ); if ( b ) { return b; } } } return nullptr; } void ToggleActionMenu::updateButtons() { for ( const QPointer< QToolButton > &button : qAsConst( m_buttons ) ) { if ( button ) { button->setDefaultAction( defaultAction() ); // Override some properties of the default action, // where the property of this menu makes more sense. button->setEnabled( isEnabled() ); if ( delayed() ) { button->setPopupMode( QToolButton::DelayedPopup ); } else if ( stickyMenu() ) { button->setPopupMode( QToolButton::InstantPopup ); } else { button->setPopupMode( QToolButton::MenuButtonPopup ); } } } } QAction * ToggleActionMenu::defaultAction() { if ( ( m_menuLogic & ImplicitDefaultAction ) && !m_defaultAction ) { m_defaultAction = checkedAction( menu() ); } if ( !m_defaultAction ) { m_defaultAction = m_suggestedDefaultAction; } return m_defaultAction; }