From 4f5b98a8a61beaf29c01e45b864c639e5dd1a726 Mon Sep 17 00:00:00 2001 From: vsr Date: Thu, 10 May 2007 06:29:15 +0000 Subject: [PATCH] Porting to Qt4 --- src/Qtx/Makefile.am | 238 ++++---- src/Qtx/QtxActionMenuMgr.cxx | 1115 +++++++++++++++++----------------- src/Qtx/QtxActionMenuMgr.h | 88 +-- src/Qtx/QtxActionMgr.h | 18 +- src/Qtx/QtxActionToolMgr.cxx | 511 +++++++++------- src/Qtx/QtxActionToolMgr.h | 44 +- 6 files changed, 1051 insertions(+), 963 deletions(-) diff --git a/src/Qtx/Makefile.am b/src/Qtx/Makefile.am index b71936b9a..40e5cb324 100755 --- a/src/Qtx/Makefile.am +++ b/src/Qtx/Makefile.am @@ -25,124 +25,138 @@ include $(top_srcdir)/adm_local/unix/make_common_starter.am # header files -salomeinclude_HEADERS= Qtx.h \ - QtxAction.h \ - QtxColorScale.h \ - QtxComboBox.h \ - QtxDblSpinBox.h \ - QtxDialog.h \ - QtxDockAction.h \ - QtxDockWindow.h \ - QtxGroupBox.h \ - QtxIntSpinBox.h \ - QtxListAction.h \ - QtxListBox.h \ - QtxListOfOperations.h \ - QtxLogoMgr.h \ - QtxMenuButton.h \ - QtxMRUAction.h \ - QtxOperations.h \ - QtxPathDialog.h \ - QtxPopupMgr.h \ - QtxResourceMgr.h \ - QtxStdOperations.h \ - QtxTable.h \ - QtxToolBar.h \ - QtxToolTip.h \ - QtxParser.h \ - QtxPopupMenu.h \ - QtxActionMgr.h \ - QtxActionMenuMgr.h \ - QtxActionToolMgr.h \ - QtxMainWindow.h \ - QtxWorkspaceAction.h \ - QtxWorkstackAction.h \ - QtxListResourceEdit.h \ - QtxWorkstack.h \ - QtxResourceEdit.h \ - QtxListView.h \ - QtxDirListEditor.h \ - QtxDblValidator.h \ - QtxSplash.h +#VSR: already migrated to Qt4 files +salomeinclude_HEADERS= \ + Qtx.h \ + QtxAction.h \ + QtxActionMenuMgr.h \ + QtxActionMgr.h \ + QtxActionToolMgr.h \ + QtxColorScale.h \ + QtxComboBox.h \ + QtxDialog.h \ + QtxDockAction.h \ + QtxDockWidget.h \ + QtxMainWindow.h \ + QtxResourceMgr.h \ + QtxToolBar.h \ + QtxWorkstack.h + +#VSR: not yet migrated to Qt4 files +# \ + QtxDblSpinBox.h \ + QtxDblValidator.h \ + QtxDirListEditor.h \ + QtxGroupBox.h \ + QtxIntSpinBox.h \ + QtxListAction.h \ + QtxListBox.h \ + QtxListOfOperations.h \ + QtxListResourceEdit.h \ + QtxListView.h \ + QtxLogoMgr.h \ + QtxMRUAction.h \ + QtxMenuButton.h \ + QtxOperations.h \ + QtxParser.h \ + QtxPathDialog.h \ + QtxPopupMenu.h \ + QtxPopupMgr.h \ + QtxResourceEdit.h \ + QtxSplash.h \ + QtxStdOperations.h \ + QtxTable.h \ + QtxToolTip.h \ + QtxWorkspaceAction.h \ + QtxWorkstackAction.h # Libraries targets lib_LTLIBRARIES= libqtx.la -dist_libqtx_la_SOURCES= \ - Qtx.cxx \ - QtxAction.cxx \ - QtxColorScale.cxx \ - QtxComboBox.cxx \ - QtxDblSpinBox.cxx \ - QtxDialog.cxx \ - QtxDockAction.cxx \ - QtxDockWindow.cxx \ - QtxGroupBox.cxx \ - QtxIntSpinBox.cxx \ - QtxListAction.cxx \ - QtxListBox.cxx \ - QtxListOfOperations.cxx \ - QtxLogoMgr.cxx \ - QtxMenuButton.cxx \ - QtxMRUAction.cxx \ - QtxPathDialog.cxx \ - QtxPopupMgr.cxx \ - QtxResourceMgr.cxx \ - QtxStdOperations.cxx \ - QtxTable.cxx \ - QtxToolBar.cxx \ - QtxToolTip.cxx \ - QtxOperations.cxx \ - QtxParser.cxx \ - QtxPopupMenu.cxx \ - QtxActionMgr.cxx \ - QtxActionMenuMgr.cxx \ - QtxActionToolMgr.cxx \ - QtxMainWindow.cxx \ - QtxWorkspaceAction.cxx \ - QtxWorkstackAction.cxx \ - QtxListResourceEdit.cxx \ - QtxResourceEdit.cxx \ - QtxWorkstack.cxx \ - QtxListView.cxx \ - QtxDirListEditor.cxx \ - QtxDblValidator.cxx \ - QtxSplash.cxx +#VSR: already migrated to Qt4 files +dist_libqtx_la_SOURCES= \ + Qtx.cxx \ + QtxAction.cxx \ + QtxActionMenuMgr.cxx \ + QtxActionMgr.cxx \ + QtxActionToolMgr.cxx \ + QtxColorScale.cxx \ + QtxComboBox.cxx \ + QtxDialog.cxx \ + QtxDockAction.cxx \ + QtxDockWidget.cxx \ + QtxMainWindow.cxx \ + QtxResourceMgr.cxx \ + QtxToolBar.cxx \ + QtxWorkstack.cxx + +#VSR: not yet migrated to Qt4 files +# \ + QtxDblSpinBox.cxx \ + QtxDblValidator.cxx \ + QtxDirListEditor.cxx \ + QtxGroupBox.cxx \ + QtxIntSpinBox.cxx \ + QtxListAction.cxx \ + QtxListBox.cxx \ + QtxListOfOperations.cxx \ + QtxListResourceEdit.cxx \ + QtxListView.cxx \ + QtxLogoMgr.cxx \ + QtxMRUAction.cxx \ + QtxMenuButton.cxx \ + QtxOperations.cxx \ + QtxParser.cxx \ + QtxPathDialog.cxx \ + QtxPopupMenu.cxx \ + QtxPopupMgr.cxx \ + QtxResourceEdit.cxx \ + QtxSplash.cxx \ + QtxStdOperations.cxx \ + QtxTable.cxx \ + QtxToolTip.cxx \ + QtxWorkspaceAction.cxx \ + QtxWorkstackAction.cxx + +#VSR: already migrated to Qt4 files +MOC_FILES= \ + QtxAction_moc.cxx \ + QtxActionMenuMgr_moc.cxx \ + QtxActionMgr_moc.cxx \ + QtxActionToolMgr_moc.cxx \ + QtxColorScale_moc.cxx \ + QtxComboBox_moc.cxx \ + QtxDialog_moc.cxx \ + QtxDockAction_moc.cxx \ + QtxDockWidget_moc.cxx \ + QtxMainWindow_moc.cxx \ + QtxToolBar_moc.cxx \ + QtxWorkstack_moc.cxx + +#VSR: not yet migrated to Qt4 files +# \ + QtxDblSpinBox_moc.cxx \ + QtxDblValidator_moc.cxx \ + QtxDirListEditor_moc.cxx \ + QtxGroupBox_moc.cxx \ + QtxIntSpinBox_moc.cxx \ + QtxListAction_moc.cxx \ + QtxListBox_moc.cxx \ + QtxListResourceEdit_moc.cxx \ + QtxListView_moc.cxx \ + QtxLogoMgr_moc.cxx \ + QtxMRUAction_moc.cxx \ + QtxMenuButton_moc.cxx \ + QtxPathDialog_moc.cxx \ + QtxPopupMenu_moc.cxx \ + QtxPopupMgr_moc.cxx \ + QtxSplash_moc.cxx \ + QtxTable_moc.cxx \ + QtxToolTip_moc.cxx \ + QtxWorkspaceAction_moc.cxx \ + QtxWorkstackAction_moc.cxx -MOC_FILES= \ - QtxAction_moc.cxx \ - QtxColorScale_moc.cxx \ - QtxComboBox_moc.cxx \ - QtxDblSpinBox_moc.cxx \ - QtxDialog_moc.cxx \ - QtxDockAction_moc.cxx \ - QtxDockWindow_moc.cxx \ - QtxGroupBox_moc.cxx \ - QtxIntSpinBox_moc.cxx \ - QtxListAction_moc.cxx \ - QtxListBox_moc.cxx \ - QtxLogoMgr_moc.cxx \ - QtxMenuButton_moc.cxx \ - QtxMRUAction_moc.cxx \ - QtxPathDialog_moc.cxx \ - QtxPopupMgr_moc.cxx \ - QtxPopupMenu_moc.cxx \ - QtxTable_moc.cxx \ - QtxToolBar_moc.cxx \ - QtxToolTip_moc.cxx \ - QtxActionMgr_moc.cxx \ - QtxActionMenuMgr_moc.cxx \ - QtxActionToolMgr_moc.cxx \ - QtxMainWindow_moc.cxx \ - QtxWorkspaceAction_moc.cxx \ - QtxWorkstackAction_moc.cxx \ - QtxWorkstack_moc.cxx \ - QtxListView_moc.cxx \ - QtxListResourceEdit_moc.cxx \ - QtxDirListEditor_moc.cxx \ - QtxDblValidator_moc.cxx \ - QtxSplash_moc.cxx nodist_libqtx_la_SOURCES= $(MOC_FILES) libqtx_la_CPPFLAGS=$(QT_INCLUDES) diff --git a/src/Qtx/QtxActionMenuMgr.cxx b/src/Qtx/QtxActionMenuMgr.cxx index 94f7050a0..d1159e580 100644 --- a/src/Qtx/QtxActionMenuMgr.cxx +++ b/src/Qtx/QtxActionMenuMgr.cxx @@ -1,17 +1,17 @@ // Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D -// +// // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either +// License as published by the Free Software Foundation; either // version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// +// This library is distributed in the hope that it will be useful +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com @@ -23,238 +23,102 @@ #include "QtxAction.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include + +#include +#include +#include +#include + +#include // VSR: Uncomment this #define in order to allow dynamic menus support // (emit signals when popup menu is pre-activated) // Currently this support is disabled. //#define ENABLE_DYNAMIC_MENU - -/*! - Service functions - Level: Internal -*/ -namespace { - QValueList prepareIds( const QWidget* w ) - { - QValueList l; - const QMenuData* md = 0; - if ( w->inherits( "QMenuBar" ) ) - md = ::qt_cast( w ); - else if ( w->inherits( "QPopupMenu" ) ) - md = ::qt_cast( w ); - if ( md ) { - for ( uint i = 0; i < md->count(); i++ ) - l.append( md->idAt( i ) ); - } - return l; - } - int getNewId( const QWidget* w, const QValueList& l, bool retId = true ) - { - const QMenuData* md = 0; - if ( w->inherits( "QMenuBar" ) ) - md = ::qt_cast( w ); - else if ( w->inherits( "QPopupMenu" ) ) - md = ::qt_cast( w ); - if ( md ) - { - for ( uint i = 0, j = 0; i < md->count() && j < l.count(); i++, j++ ) - if ( md->idAt( i ) != l[ j ] ) - return retId ? md->idAt( i ) : i; - if ( md->count() > l.count() ) - return retId ? md->idAt( md->count()-1 ) : md->count() - 1; - } - return -1; - } - - void dumpMenu( QWidget* w, bool before ) - { - if ( !w ) - return; - - QMenuData* md = 0; - if ( w->inherits( "QMenuBar" ) ) - md = ::qt_cast( w ); - else if ( w->inherits( "QPopupMenu" ) ) - md = ::qt_cast( w ); - - if ( !md ) - return; - - printf( ">>> start dump menu (%s) >>>\n", before ? "before" : "after" ); - for ( uint i = 0; i < md->count(); i++ ) - printf( "%d: %d: %s\n", i, md->idAt( i ), md->text( md->idAt( i ) ).latin1() ); - printf( "<<< end dump menu (%s) <<<\n", before ? "before" : "after" ); - } -}; /*! - Class: QtxActionMenuMgr::MenuAction - Level: Internal + \class QtxActionMenuMgr::MenuNode + \internal + \brief Represents a menu item inside main menu structure. */ -class QtxActionMenuMgr::MenuAction : public QtxAction -{ +class QtxActionMenuMgr::MenuNode { public: - MenuAction( const QString&, const QString&, QObject*, const int = -1, const bool = false ); - virtual ~MenuAction(); - - virtual bool addTo( QWidget* ); - - virtual bool removeFrom( QWidget* ); - - QPopupMenu* popup() const; - -private: - int myId; - QPopupMenu* myPopup; - bool myEmptyEnabled; - QMap myIds; + MenuNode(); + MenuNode( MenuNode*, const int, const int, const int ); + ~MenuNode(); + + MenuNode* parent; //!< parent menu node + int id; //!< menu nodeID + int idx; //!< menu node index + int group; //!< menu group ID + bool visible; //!< visibility status + NodeList children; //!< children menu nodes list }; - /*! - Constructor for menu action - \param text - description text - \param menutext - menu text - \param parent - parent object - \param id - integer identificator of action - \param allowEmpty - if it is true, it makes possible to add this action with empty popup to menu + \brief Default constructor. */ - -QtxActionMenuMgr::MenuAction::MenuAction( const QString& text, - const QString& menuText, - QObject* parent, - const int id, - const bool allowEmpty ) -: QtxAction( text, menuText, 0, parent ), - myId( id ), - myPopup( 0 ), - myEmptyEnabled( allowEmpty ) +QtxActionMenuMgr::MenuNode::MenuNode() +: parent( 0 ), id( -1 ), idx( -1 ), group( -1 ), visible( true ) { - myPopup = new QPopupMenu(); } /*! - Destructor: deletes internal popup + \brief Constructor. + \param p parent menu node + \param _id menu node ID + \param _idx menu node index + \param _group menu node group ID */ -QtxActionMenuMgr::MenuAction::~MenuAction() +QtxActionMenuMgr::MenuNode::MenuNode( MenuNode* p, + const int _id, + const int _idx, + const int _group ) +: parent( p ), id( _id ), idx( _idx ), group( _group ), visible( true ) { - delete myPopup; + if ( p ) + p->children.append( this ); } /*! - Adds action to widget, for example, to popup menu or menu bar + \brief Destructor. */ -bool QtxActionMenuMgr::MenuAction::addTo( QWidget* w ) +QtxActionMenuMgr::MenuNode::~MenuNode() { - if ( !w ) - return false; // bad widget - - if ( !w->inherits( "QPopupMenu" ) && !w->inherits( "QMenuBar" ) ) - return false; // not allowed widget type - - if ( myIds.find( w ) != myIds.end() ) - return false; // already added - - if ( !myPopup ) - return false; // bad own popup menu - - if ( !myEmptyEnabled && !myPopup->count() ) - return false; // not allowed empty menu - - if ( w->inherits( "QPopupMenu" ) ) { - QValueList l = prepareIds( w ); - int idx; - if ( QtxAction::addTo( w ) && ( idx = getNewId( w, l, false ) ) != -1 ) { - QPopupMenu* pm = (QPopupMenu*)w; - myIds[ w ] = pm->idAt( idx ); - if ( myId != -1 ) - pm->setId( idx, myId ); - setPopup( pm, myId != -1 ? myId : myIds[ w ], myPopup ); - } - } - else if ( w->inherits( "QMenuBar" ) ) { - QValueList l = prepareIds( w ); - int idx; - if ( QtxAction::addTo( w ) && ( idx = getNewId( w, l, false ) ) != -1 ) { - QMenuBar* mb = (QMenuBar*)w; - myIds[ w ] = mb->idAt( idx ); - if ( myId != -1 ) - mb->setId( idx, myId ); - setPopup( mb, myId != -1 ? myId : myIds[ w ], myPopup ); - } - } - else - return false; - - return true; + for ( NodeList::iterator it = children.begin(); it != children.end(); ++it ) + delete *it; } /*! - Removes action from widget, for example, from popup menu or menu bar -*/ -bool QtxActionMenuMgr::MenuAction::removeFrom( QWidget* w ) -{ - if ( !w ) - return false; // bad widget + \class QtxActionMenuMgr + \brief Main menu actions manager. - if ( !w->inherits( "QPopupMenu" ) && !w->inherits( "QMenuBar" ) ) - return false; // not allowed widget type + Menu manager allows using of set of action for automatic generating of + application main menu and dynamic update of its contents. - if ( myIds.find( w ) == myIds.end() ) - return false; // not yet added + Use insert(), append() and remove() methods to create main menu. + Methods show(), hide() allow displaying/erasing of specified menu items. - if ( w->inherits( "QPopupMenu" ) ) { - if ( myId != -1 ) { - QPopupMenu* pm = (QPopupMenu*)w; - int idx = pm->indexOf( myId ); - if ( idx != -1 ) pm->setId( idx, myIds[ w ] ); - } - myIds.remove( w ); - return QtxAction::removeFrom( w );; - } - else if ( w->inherits( "QMenuBar" ) ) - { - if ( myId != -1 ) { - QMenuBar* mb = (QMenuBar*)w; - int idx = mb->indexOf( myId ); - if ( idx != -1 ) mb->setId( idx, myIds[ w ] ); - } - myIds.remove( w ); - return QtxAction::removeFrom( w ); - } - return false; -} + Actions can be grouped with help of group identificator. Inside the popup + or main menu bar menu items are ordered by the group ID (ascending). -/*! - \return internal popup of action + Menu manager automatically optimizes the menu by removing extra separators, + hiding empty popup menus etc. */ -QPopupMenu* QtxActionMenuMgr::MenuAction::popup() const -{ - return myPopup; -} /*! - Class: QtxActionMenuMgr - Level: Public + \brief Constructor. + \param p parent main window */ QtxActionMenuMgr::QtxActionMenuMgr( QMainWindow* p ) -: QtxActionMgr( p ), +: QtxActionMgr( p ), + myRoot( new MenuNode() ), myMenu( p ? p->menuBar() : 0 ) { - myRoot.id = -1; - myRoot.group = -1; - if ( myMenu ) { connect( myMenu, SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) ); #ifdef ENABLE_DYNAMIC_MENU @@ -265,42 +129,51 @@ QtxActionMenuMgr::QtxActionMenuMgr( QMainWindow* p ) } /*! - Constructor + \brief Constructor. + \param mw menu widget + \param p parent object */ QtxActionMenuMgr::QtxActionMenuMgr( QWidget* mw, QObject* p ) -: QtxActionMgr( p ), +: QtxActionMgr( p ), + myRoot( new MenuNode() ), myMenu( mw ) { - myRoot.id = -1; - myRoot.group = -1; - - if ( myMenu ) + if ( myMenu ) { connect( myMenu, SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) ); +#ifdef ENABLE_DYNAMIC_MENU + if ( myMenu->inherits( "QMenuBar" ) ) + connect( myMenu, SIGNAL( highlighted( int ) ), this, SLOT( onHighlighted( int ) ) ); +#endif + } } /*! - Destructor + \brief Destructor. */ QtxActionMenuMgr::~QtxActionMenuMgr() { - for ( NodeListIterator it( myRoot.children ); it.current() && myMenu; ++it ) + for ( NodeList::iterator it = myRoot->children.begin(); it != myRoot->children.end() && myMenu; ++it ) { - QAction* a = itemAction( it.current()->id ); + QAction* a = itemAction( (*it)->id ); if ( !a ) - a = menuAction( it.current()->id ); + a = menuAction( (*it)->id ); - if ( a ) - a->removeFrom( myMenu ); +// if ( a ) +// a->removeFrom( myMenu ); } for ( MenuMap::Iterator itr = myMenus.begin(); itr != myMenus.end(); ++itr ) - delete itr.data(); + delete itr.value(); + + delete myRoot; } /*! - \return whether menu item corresponding to action is visible - \param actId - identificator of action - \param place - identificator of some parent action + \brief Check if an action with given ID \a actId is visible to + the parent action with given ID \a place. + \param actId action ID + \param place some parent action ID + \return \c true if an action is visible */ bool QtxActionMenuMgr::isVisible( const int actId, const int place ) const { @@ -309,10 +182,10 @@ bool QtxActionMenuMgr::isVisible( const int actId, const int place ) const } /*! - Sets visible state of action - \param actId - identificator of action - \param place - identificator of some parent action - \param v - visibility state + \brief Set action visibility flag. + \param actId action ID + \param place some parent action ID + \param on visibility state */ void QtxActionMenuMgr::setVisible( const int actId, const int place, const bool v ) { @@ -322,38 +195,57 @@ void QtxActionMenuMgr::setVisible( const int actId, const int place, const bool } /*! - Insert action as children menu item - \param id - identificator of action - \param menus - few names of parent menu items, separated by '|'. It means sequence of menu items, - for example "File|Edit" means File->Edit submenu. If submenu doesn't exist, it will be created. - \param group - group identificator - \param idx - index inside Qt menu + \brief Insert action to the menu. + + Insert an action to the named menu. The \a menus parameter represents + the menu name: it is a sequence of strings, separated by '|' symbol. + For example, "File|Edit" means File->Edit submenu. + If submenu doesn't exist, it will be created. + + \param id action ID + \param menus menu name + \param group group ID + \param idx menu index inside the menu group + \return action ID */ int QtxActionMenuMgr::insert( const int id, const QString& menus, const int group, const int idx ) { - return insert( id, QStringList::split( "|", menus ), group, idx ); + return insert( id, menus.split( "|", QString::SkipEmptyParts ), group, idx ); } /*! - Insert action as children menu item - \param a - action - \param menus - few names of parent menu items, separated by '|'. It means sequence of menu items, - for example "File|Edit" means File->Edit submenu. If submenu doesn't exist, it will be created. - \param group - group identificator - \param idx - index inside Qt menu + \brief Insert action to the menu. + + Insert an action to the named menu. The \a menus parameter represents + the menu name: it is a sequence of strings, separated by '|' symbol. + For example, "File|Edit" means File->Edit submenu. + If submenu doesn't exist, it will be created. + + \param a action + \param menus menu name + \param group group ID + \param idx menu index inside the menu group + \return action ID */ int QtxActionMenuMgr::insert( QAction* a, const QString& menus, const int group, const int idx ) { - return insert( a, QStringList::split( "|", menus ), group, idx ); + return insert( a, menus.split( "|", QString::SkipEmptyParts ), group, idx ); } /*! - Insert action as children menu item - \param id - identificator of action - \param menus - list of names of parent menu items, separated by |. It means sequence of menu items, - for example "File|Edit" means File->Edit submenu. If submenu doesn't exist, it will be created. - \param group - group identificator - \param idx - index inside Qt menu + \brief Insert action to the menu. + + Insert an action to the named menu. The \a menus parameter represents + the menu names list. + For example, string list consisting from two items "File" and "Edit" + means File->Edit submenu. + If submenu doesn't exist, it will be created. + + \param id action ID + \param menus menu names list + \param group group ID + \param idx menu index inside the menu group + \return action ID */ int QtxActionMenuMgr::insert( const int id, const QStringList& menus, const int group, const int idx ) { @@ -365,12 +257,19 @@ int QtxActionMenuMgr::insert( const int id, const QStringList& menus, const int } /*! - Insert action as children menu item - \param a - action - \param menus - list of names of parent menu items. It means sequence of menu items, - for example "File|Edit" means File->Edit submenu. If submenu doesn't exist, it will be created. - \param group - group identificator - \param idx - index inside Qt menu + \brief Insert action to the menu. + + Insert an action to the named menu. The \a menus parameter represents + the menu names list. + For example, string list consisting from two items "File" and "Edit" + means File->Edit submenu. + If submenu doesn't exist, it will be created. + + \param a action + \param menus menu names list + \param group group ID + \param idx menu index inside the menu group + \return action ID */ int QtxActionMenuMgr::insert( QAction* a, const QStringList& menus, const int group, const int idx ) { @@ -382,39 +281,36 @@ int QtxActionMenuMgr::insert( QAction* a, const QStringList& menus, const int gr } /*! - Insert action as children menu item - \param id - identificator of action - \param pId - identificator of action corresponding to parent menu item - \param group - group identificator - \param idx - index inside Qt menu + \brief Insert action to the menu. + \param id action ID + \param pId parent menu action ID + \param group group ID + \param idx menu index inside the menu group + \return action ID */ int QtxActionMenuMgr::insert( const int id, const int pId, const int group, const int idx ) { if ( id == -1 ) return -1; - MenuNode* pNode = pId == -1 ? &myRoot : find( pId ); + MenuNode* pNode = pId == -1 ? myRoot : find( pId ); if ( !pNode ) return -1; - MenuNode* node = new MenuNode( pNode ); - node->id = id; - node->idx = idx; - node->group = group; - - pNode->children.append( node ); + MenuNode* node = new MenuNode( pNode, id, idx, group ); - updateMenu( pNode, false ); + triggerUpdate( pNode->id, false ); return node->id; } /*! - Insert action as children menu item - \param a - action - \param pId - identificator of action corresponding to parent menu item - \param group - group identificator - \param idx - index inside Qt menu + \brief Insert action to the menu. + \param a action + \param pId parent menu action ID + \param group group ID + \param idx menu index inside the menu group + \return action ID */ int QtxActionMenuMgr::insert( QAction* a, const int pId, const int group, const int idx ) { @@ -422,29 +318,28 @@ int QtxActionMenuMgr::insert( QAction* a, const int pId, const int group, const } /*! - Create and insert action as children menu item - \return identificator of inserted action - \param title - menu text of action - \param pId - identificator of action corresponding to parent menu item - \param group - group identificator - \param id - identificator of new action - \param idx - index inside Qt menu - \param allowEmpty - indicates, that it is possible to add this action with empty popup menu to other menu + \brief Create and insert menu item action to the menu. + \param title menu text + \param pId parent menu action ID + \param group group ID + \param id action ID + \param idx menu index inside the menu group + \return action ID */ -int QtxActionMenuMgr::insert( const QString& title, const int pId, const int group, const int id, const int idx, const bool allowEmpty ) +int QtxActionMenuMgr::insert( const QString& title, const int pId, const int group, const int id, const int idx ) { - MenuNode* pNode = pId == -1 ? &myRoot : find( pId ); + MenuNode* pNode = pId == -1 ? myRoot : find( pId ); if ( !pNode ) return -1; MenuNode* eNode = id == -1 ? 0 : find( id ); int fid = -1; - for ( NodeListIterator it( pNode->children ); it.current() && fid == -1; ++it ) + for ( NodeList::iterator it = pNode->children.begin(); it != pNode->children.end() && fid == -1; ++it ) { - if ( myMenus.contains( it.current()->id ) && - clearTitle( myMenus[it.current()->id]->menuText() ) == clearTitle( title ) ) - fid = it.current()->id; + if ( myMenus.contains( (*it)->id ) && + clearTitle( myMenus[(*it)->id]->text() ) == clearTitle( title ) ) + fid = (*it)->id; } if ( fid != -1 ) @@ -452,74 +347,83 @@ int QtxActionMenuMgr::insert( const QString& title, const int pId, const int gro int gid = (id == -1 || eNode ) ? generateId() : id; - MenuAction* ma = new MenuAction( clearTitle( title ), title, this, gid, allowEmpty ); + QAction* ma = new QAction( title, this ); + ma->setMenu( new QMenu( myMenu ) ); + + connect( ma->menu(), SIGNAL( aboutToShow() ), this, SLOT( onAboutToShow() ) ); + connect( ma->menu(), SIGNAL( aboutToHide() ), this, SLOT( onAboutToHide() ) ); #ifdef ENABLE_DYNAMIC_MENU - connect( ma->popup(), SIGNAL( highlighted( int ) ), this, SLOT( onHighlighted( int ) ) ); + connect( ma->menu(), SIGNAL( highlighted( int ) ), this, SLOT( onHighlighted( int ) ) ); #endif - MenuNode* node = new MenuNode( pNode ); - node->group = group; - node->idx = idx; - node->id = myMenus.insert( gid, ma ).key(); - - pNode->children.append( node ); + MenuNode* node = new MenuNode( pNode, myMenus.insert( gid, ma ).key(), idx, group ); - updateMenu( pNode, false ); + triggerUpdate( pNode->id, false ); return node->id; } /*! - Create and insert action as children menu item - \return identificator of inserted action - \param title - menu text of action - \param menus - string list of parents' menu texts, separated by | - \param group - group identificator - \param id - identificator of new action - \param idx - index inside Qt menu - \param allowEmpty - indicates, that it is possible to add this action with empty popup menu to other menu + \brief Create and insert menu item action to the menu. + + Insert an action to the named menu. The \a menus parameter represents + the menu name: it is a sequence of strings, separated by '|' symbol. + For example, "File|Edit" means File->Edit submenu. + If submenu doesn't exist, it will be created. + + \param title menu text + \param menus menu name + \param group group ID + \param id action ID + \param idx menu index inside the menu group + \return action ID */ -int QtxActionMenuMgr::insert( const QString& title, const QString& menus, const int group, const int id, const int idx, const bool allowEmpty ) +int QtxActionMenuMgr::insert( const QString& title, const QString& menus, const int group, const int id, const int idx ) { - return insert( title, QStringList::split( "|", menus ), group, id, idx, allowEmpty ); + return insert( title, menus.split( "|", QString::SkipEmptyParts ), group, id, idx ); } /*! - Create and insert action as children menu item - \return identificator of inserted action - \param title - menu text of action - \param menus - list of parents menu items - \param group - group identificator - \param id - identificator of new action - \param idx - index inside Qt menu - \param allowEmpty - indicates, that it is possible to add this action with empty popup menu to other menu + \brief Create and insert menu item action to the menu. + + Insert an action to the named menu. The \a menus parameter represents + the menu names list. + For example, string list consisting from two items "File" and "Edit" + means File->Edit submenu. + If submenu doesn't exist, it will be created. + + \param title menu text + \param menus menu names list + \param group group ID + \param id action ID + \param idx menu index inside the menu group + \return action ID */ -int QtxActionMenuMgr::insert( const QString& title, const QStringList& menus, const int group, const int id, const int idx, const bool allowEmpty ) +int QtxActionMenuMgr::insert( const QString& title, const QStringList& menus, const int group, const int id, const int idx ) { int pId = createMenu( menus, -1 ); - return insert( title, pId, group, id, idx, allowEmpty ); + return insert( title, pId, group, id, idx ); } /*! - Create and append action as last children - \return identificator of inserted action - \param title - menu text of action - \param pId - id of action corresponding to parent menu item - \param group - group identificator - \param id - identificator of new action - \param allowEmpty - indicates, that it is possible to add this action with empty popup menu to other menu + \brief Create and add menu item action to the end of menu. + \param title menu text + \param pId parent menu action ID + \param group group ID + \param id action ID + \return action ID */ -int QtxActionMenuMgr::append( const QString& title, const int pId, const int group, const int id, const bool allowEmpty ) +int QtxActionMenuMgr::append( const QString& title, const int pId, const int group, const int id ) { - return insert( title, pId, group, id, allowEmpty ); + return insert( title, pId, group, id ); } /*! - Create and append action as last children - \return identificator of inserted action - \param id - identificator of existing action - \param pId - id of action corresponding to parent menu item - \param group - group identificator + \brief Create and add menu item action to the end of menu. + \param id action ID + \param pId parent menu action ID + \param group group ID + \return action ID */ int QtxActionMenuMgr::append( const int id, const int pId, const int group ) { @@ -527,11 +431,11 @@ int QtxActionMenuMgr::append( const int id, const int pId, const int group ) } /*! - Create and append action as last children - \return identificator of inserted action - \param a - action - \param pId - id of action corresponding to parent menu item - \param group - group identificator + \brief Create and add menu item action to the end of menu. + \param a action + \param pId parent menu action ID + \param group group ID + \return action ID */ int QtxActionMenuMgr::append( QAction* a, const int pId, const int group ) { @@ -539,25 +443,24 @@ int QtxActionMenuMgr::append( QAction* a, const int pId, const int group ) } /*! - Create and insert action as first children - \return identificator of inserted action - \param title - menu text of action - \param pId - id of action corresponding to parent menu item - \param group - group identificator - \param id - identificator of new action - \param allowEmpty - indicates, that it is possible to add this action with empty popup menu to other menu + \brief Create and add menu item action to the beginning of menu. + \param title menu text + \param pId parent menu action ID + \param group group ID + \param id action ID + \return action ID */ -int QtxActionMenuMgr::prepend( const QString& title, const int pId, const int group, const int id, const bool allowEmpty ) +int QtxActionMenuMgr::prepend( const QString& title, const int pId, const int group, const int id ) { - return insert( title, pId, group, id, 0, allowEmpty ); + return insert( title, pId, group, id, 0 ); } /*! - Create and insert action as last children - \return identificator of inserted action - \param id - identificator of existing action - \param pId - id of action corresponding to parent menu item - \param group - group identificator + \brief Create and add menu item action to the beginning of menu. + \param id action ID + \param pId parent menu action ID + \param group group ID + \return action ID */ int QtxActionMenuMgr::prepend( const int id, const int pId, const int group ) { @@ -565,11 +468,11 @@ int QtxActionMenuMgr::prepend( const int id, const int pId, const int group ) } /*! - Create and insert action as last children - \return identificator of inserted action - \param a - action - \param pId - id of action corresponding to parent menu item - \param group - group identificator + \brief Create and add menu item action to the beginning of menu. + \param a action + \param pId parent menu action ID + \param group group ID + \return action ID */ int QtxActionMenuMgr::prepend( QAction* a, const int pId, const int group ) { @@ -577,8 +480,8 @@ int QtxActionMenuMgr::prepend( QAction* a, const int pId, const int group ) } /*! - Removes menu item corresponding to action - \param id - identificator of action + \brief Remove menu item with given \a id. + \param id menu action ID */ void QtxActionMenuMgr::remove( const int id ) { @@ -587,33 +490,33 @@ void QtxActionMenuMgr::remove( const int id ) } /*! - Removes menu item - \param id - identificator of action - \param pId - identificator of action corresponding to parent menu item - \param group - group identificator + \brief Remove menu item with given \a id. + \param id menu action ID + \param pId parent menu action ID + \param group group ID */ void QtxActionMenuMgr::remove( const int id, const int pId, const int group ) { - MenuNode* pNode = pId == -1 ? &myRoot : find( pId ); + MenuNode* pNode = pId == -1 ? myRoot : find( pId ); if ( !pNode ) return; NodeList delNodes; - for ( NodeListIterator it( pNode->children ); it.current(); ++it ) + for ( NodeList::iterator it = pNode->children.begin(); it != pNode->children.end(); ++it ) { - if ( it.current()->id == id && ( it.current()->group == group || group == -1 ) ) - delNodes.append( it.current() ); + if ( (*it)->id == id && ( (*it)->group == group || group == -1 ) ) + delNodes.append( *it ); } - for ( NodeListIterator itr( delNodes ); itr.current(); ++itr ) - pNode->children.remove( itr.current() ); + for ( NodeList::iterator itr = delNodes.begin(); itr != delNodes.end(); ++itr ) + pNode->children.removeAll( *itr ); - updateMenu( pNode, false ); + triggerUpdate( pNode->id, false ); } /*! - Shows menu item corresponding to action - \param id - identificator of action + \brief Show menu item with given \a id. + \param id menu action ID */ void QtxActionMenuMgr::show( const int id ) { @@ -621,8 +524,8 @@ void QtxActionMenuMgr::show( const int id ) } /*! - Hides menu item corresponding to action - \param id - identificator of action + \brief Hide menu item with given \a id. + \param id menu action ID */ void QtxActionMenuMgr::hide( const int id ) { @@ -630,8 +533,9 @@ void QtxActionMenuMgr::hide( const int id ) } /*! - \return shown status of menu item corresponding to action - \param id - identificator of action + \brief Get visibility status for menu item with given \a id. + \param id menu action ID + \return \c true if an item is shown */ bool QtxActionMenuMgr::isShown( const int id ) const { @@ -643,31 +547,67 @@ bool QtxActionMenuMgr::isShown( const int id ) const } /*! - Sets shown status of menu item corresponding to action - \param id - identificator of action - \param on - new shown status + \brief Set visibility status for menu item with given \a id. + \param id menu action ID + \param on new visibility status */ void QtxActionMenuMgr::setShown( const int id, const bool on ) { NodeList aNodes; find( id, aNodes ); - QMap updMap; - for ( NodeListIterator it( aNodes ); it.current(); ++it ) + for ( NodeList::iterator it = aNodes.begin(); it != aNodes.end(); ++it ) { - if ( it.current()->visible != on ) + if ( (*it)->visible != on ) { - it.current()->visible = on; - updMap.insert( it.current()->parent, 0 ); + (*it)->visible = on; + triggerUpdate( (*it)->parent ? (*it)->parent->id : myRoot->id, false ); } } +} + +/*! + \brief Change menu title fot the action with given \a id. + \param id menu action ID + \param title new menu title +*/ +void QtxActionMenuMgr::change( const int id, const QString& title ) +{ + QAction* a = menuAction( id ); + if ( a ) + a->setText( title ); +} - for ( QMap::ConstIterator itr = updMap.begin(); itr != updMap.end(); ++itr ) - updateMenu( itr.key(), false ); +/*! + \brief Called when the submenu is about to show. + + Emits the signal menuAboutToShow(QMenu*). +*/ +void QtxActionMenuMgr::onAboutToShow() +{ + QMenu* m = ::qobject_cast( sender() ); + if ( m ) + emit menuAboutToShow( m ); } /*! - SLOT: called when corresponding menu is destroyed, clears internal pointer to menu + \brief Called when the submenu is about to hide. + + Emits the signal menuAboutToHide(QMenu*). +*/ +void QtxActionMenuMgr::onAboutToHide() +{ + QMenu* m = ::qobject_cast( sender() ); + if ( m ) + emit menuAboutToHide( m ); +} + +/*! + \brief Called when the corresponding menu object is destroyed. + + Clears internal pointer to menu to disable crashes. + + \param obj (menu) object being destroyed */ void QtxActionMenuMgr::onDestroyed( QObject* obj ) { @@ -676,7 +616,8 @@ void QtxActionMenuMgr::onDestroyed( QObject* obj ) } /*! - SLOT: called when menu item is highlighted + \brief Called when menu item is highlighted. + \param id menu item being highlighted ID */ void QtxActionMenuMgr::onHighlighted( int id ) { @@ -684,27 +625,28 @@ void QtxActionMenuMgr::onHighlighted( int id ) int pid = 0, realId; if ( myMenu && snd == myMenu ) pid = -1; - else { - for ( MenuMap::Iterator itr = myMenus.begin(); itr != myMenus.end(); ++itr ) { - if ( itr.data()->popup() && itr.data()->popup() == snd ) - pid = itr.key(); + else + { + for ( MenuMap::Iterator itr = myMenus.begin(); itr != myMenus.end(); ++itr ) + { + if ( itr.value()->menu() && itr.value()->menu() == snd ) + pid = itr.key(); } } - if ( pid ) { + if ( pid ) + { realId = findId( id, pid ); - if ( realId != -1 ) { - bool updatesEnabled = isUpdatesEnabled(); - setUpdatesEnabled( false ); + if ( realId != -1 ) + { emit menuHighlighted( pid, realId ); - setUpdatesEnabled( updatesEnabled ); - updateMenu( find( realId ) ); + triggerUpdate( realId ); } } } /*! - Assignes new menu with manager - \param mw - new menu + \brief Assign new menu widget to the menu manager. + \param mw new menu widget */ void QtxActionMenuMgr::setWidget( QWidget* mw ) { @@ -721,62 +663,65 @@ void QtxActionMenuMgr::setWidget( QWidget* mw ) } /*! - \return menu node by it's place description - \param actId - identificator of action - \param pId - identificator of action corresponding to start menu item - \param rec - recursive search + \brief Search menu node. + \param id menu action ID + \param pId parent menu item ID + \param rec if \c true perform recursive search + \return menu node or 0 if not found */ -QtxActionMenuMgr::MenuNode* QtxActionMenuMgr::find( const int actId, const int pId, const bool rec ) const +QtxActionMenuMgr::MenuNode* QtxActionMenuMgr::find( const int id, const int pId, const bool rec ) const { - return find( actId, find( pId ), rec ); + return find( id, find( pId ), rec ); } /*! - \return menu node by it's place description - \param actId - identificator of action - \param startNode - start menu item - \param rec - recursive search + \brief Search menu node. + \param id menu action ID + \param startNode start menu node (if 0, search from root node) + \param rec if \c true perform recursive search + \return menu node or 0 if not found */ QtxActionMenuMgr::MenuNode* QtxActionMenuMgr::find( const int id, MenuNode* startNode, const bool rec ) const { MenuNode* node = 0; - MenuNode* start = startNode ? startNode : (MenuNode*)&myRoot; - for ( NodeListIterator it( start->children ); it.current() && !node; ++it ) + MenuNode* start = startNode ? startNode : myRoot; + for ( NodeList::iterator it = start->children.begin(); it != start->children.end() && !node; ++it ) { - if ( it.current()->id == id ) - node = it.current(); + if ( (*it)->id == id ) + node = *it; else if ( rec ) - node = find( id, it.current(), rec ); + node = find( id, *it, rec ); } return node; } /*! - Finds menu node - \return true if at least one node is found - \param id - identificator of action - \param lst - list to be filled with found nodes - \param startNode - start menu item + \brief Search recursively all menu nodes with given \a id. + \param id menu action ID + \param NodeList resulting list of menu nodes + \param startNode start menu node (if 0, search from root node) + \return \c true if at least one node is found */ bool QtxActionMenuMgr::find( const int id, NodeList& lst, MenuNode* startNode ) const { - MenuNode* start = startNode ? startNode : (MenuNode*)&myRoot; - for ( NodeListIterator it( start->children ); it.current(); ++it ) + MenuNode* start = startNode ? startNode : myRoot; + for ( NodeList::iterator it = start->children.begin(); it != start->children.end(); ++it ) { - if ( it.current()->id == id ) - lst.prepend( it.current() ); + MenuNode* node = *it; + if ( node->id == id ) + lst.prepend( node ); - find( id, lst, it.current() ); + find( id, lst, node ); } return !lst.isEmpty(); } /*! - Finds menu node - \return menu node - \param title - menu text of searched node - \param pId - id of action corresponding to start menu item - \param rec - recursive searching + \brief Search menu node. + \param title menu item title + \param pId parent menu item ID + \param rec if \c true perform recursive search + \return menu node or 0 if not found */ QtxActionMenuMgr::MenuNode* QtxActionMenuMgr::find( const QString& title, const int pId, const bool rec ) const { @@ -784,89 +729,93 @@ QtxActionMenuMgr::MenuNode* QtxActionMenuMgr::find( const QString& title, const } /*! - Finds menu node - \return true if at least one node is found - \param title - menu text of node - \param lst - list to be filled with found nodes - \param startNode - start menu item + \brief Search recursively all menu nodes with given \a title. + \param title menu item title + \param NodeList resulting list of menu nodes + \param startNode start menu node (if 0, search from root node) + \return \c true if at least one node is found */ bool QtxActionMenuMgr::find( const QString& title, NodeList& lst, MenuNode* startNode ) const { - MenuNode* start = startNode ? startNode : (MenuNode*)&myRoot; - for ( NodeListIterator it( start->children ); it.current(); ++it ) + MenuNode* start = startNode ? startNode : myRoot; + for ( NodeList::iterator it = start->children.begin(); it != start->children.end(); ++it ) { - QAction* a = itemAction( it.current()->id ); + QAction* a = itemAction( (*it)->id ); if ( !a ) - a = menuAction( it.current()->id ); - if ( a && clearTitle( a->menuText() ) == clearTitle( title ) ) - lst.prepend( it.current() ); + a = menuAction( (*it)->id ); + if ( a && clearTitle( a->text() ) == clearTitle( title ) ) + lst.prepend( *it ); - find( title, lst, it.current() ); + find( title, lst, *it ); } return !lst.isEmpty(); } /*! - Finds menu node - \return menu node - \param title - menu text of searched node - \param startNode - start menu item - \param rec - recursive searching + \brief Search menu node. + \param title menu item title + \param startNode start menu node (if 0, search from root node) + \param rec if \c true perform recursive search + \return menu node or 0 if not found */ QtxActionMenuMgr::MenuNode* QtxActionMenuMgr::find( const QString& title, MenuNode* startNode, const bool rec ) const { MenuNode* node = 0; - MenuNode* start = startNode ? startNode : (MenuNode*)&myRoot; - for ( NodeListIterator it( start->children ); it.current() && !node; ++it ) + MenuNode* start = startNode ? startNode : myRoot; + for ( NodeList::iterator it = start->children.begin(); it != start->children.end() && !node; ++it ) { - QAction* a = itemAction( it.current()->id ); + QAction* a = itemAction( (*it)->id ); if ( !a ) - a = menuAction( it.current()->id ); - if ( a && clearTitle( a->menuText() ) == clearTitle( title ) ) - node = it.current(); + a = menuAction( (*it)->id ); + if ( a && clearTitle( a->text() ) == clearTitle( title ) ) + node = *it; if ( !node && rec ) - node = find( title, it.current(), rec ); + node = find( title, *it, rec ); } return node; } /*! - Find id among children - \return id (>0) if on success or -1 on fail - \param id - id to be searched - \param pid - id of parent, among children of that 'id' must be searched + \brief Find menu item by given ID (one-level only). + \param id menu action ID + \param pid parent meun item ID + \return id (>0) on success or -1 if menu item is not found */ int QtxActionMenuMgr::findId( const int id, const int pid ) const { - MenuNode* start = pid != -1 ? find( pid ) : (MenuNode*)&myRoot; - if ( start ) { - for ( NodeListIterator it( start->children ); it.current(); ++it ) { - if ( it.current()->id == id ) return id; + MenuNode* start = pid != -1 ? find( pid ) : myRoot; + if ( start ) + { + for ( NodeList::iterator it = start->children.begin(); it != start->children.end(); ++it ) + { + if ( (*it)->id == id ) + return id; } } return -1; } /*! - Removes child - \param id - id of child to be removed - \param startNode - parent menu item + \brief Removes menu node (with all its children). + \param id menu action ID + \param startNode parent menu node which search starts from (if 0, search starts from root) */ void QtxActionMenuMgr::removeMenu( const int id, MenuNode* startNode ) { - MenuNode* start = startNode ? startNode : &myRoot; - for ( NodeListIterator it( start->children ); it.current(); ++it ) + MenuNode* start = startNode ? startNode : myRoot; + for ( NodeList::iterator it = start->children.begin(); it != start->children.end(); ++it ) { - if ( it.current()->id == id ) - start->children.remove( it.current() ); + if ( (*it)->id == id ) + start->children.removeAll( *it ); else - removeMenu( id, it.current() ); + removeMenu( id, *it ); } } /*! - \return menu item action by id - \param id - id of action + \brief Get action by \a id. + \param id action ID + \return action or 0 if not found */ QAction* QtxActionMenuMgr::itemAction( const int id ) const { @@ -874,12 +823,13 @@ QAction* QtxActionMenuMgr::itemAction( const int id ) const } /*! - \return menu action by id - \param id - id of action + \brief Get submenu action by \a id. + \param id submenu ID + \return submenu action or 0 if not found */ -QtxActionMenuMgr::MenuAction* QtxActionMenuMgr::menuAction( const int id ) const +QAction* QtxActionMenuMgr::menuAction( const int id ) const { - MenuAction* a = 0; + QAction* a = 0; if ( myMenus.contains( id ) ) a = myMenus[id]; @@ -888,18 +838,22 @@ QtxActionMenuMgr::MenuAction* QtxActionMenuMgr::menuAction( const int id ) const } /*! - Updates menu ( isUpdatesEnabled() must return true ) - \param startNode - first menu item to be updated - \param rec - recursive update - \param updParent - update also parent item (without recursion) - \sa isUpdatesEnabled() + \brief Update menu. + + Does nothing if update is disabled. + + \param startNode start menu item to be updated + \param rec if \c true, perform recursive update + \param updParent if \c true update also parent item (without recursion) + + \sa isUpdatesEnabled() and setUpdatesEnabled() */ void QtxActionMenuMgr::updateMenu( MenuNode* startNode, const bool rec, const bool updParent ) { if ( !isUpdatesEnabled() ) return; - MenuNode* node = startNode ? startNode : &myRoot; + MenuNode* node = startNode ? startNode : myRoot; QWidget* mw = menuWidget( node ); if ( !mw ) @@ -907,36 +861,32 @@ void QtxActionMenuMgr::updateMenu( MenuNode* startNode, const bool rec, const bo bool filled = checkWidget( mw ); - for ( NodeListIterator it1( node->children ); it1.current(); ++it1 ) + for ( NodeList::iterator it1 = node->children.begin(); it1 != node->children.end(); ++it1 ) { - QAction* a = itemAction( it1.current()->id ); + QAction* a = itemAction( (*it1)->id ); if ( !a ) - a = menuAction( it1.current()->id ); + a = menuAction( (*it1)->id ); - if ( a ) - a->removeFrom( mw ); + mw->removeAction( a ); +// if ( a ) +// a->removeFrom( mw ); } - /* VSR: commented to allow direct creating of menus by calling insertItem() methods - if ( mw->inherits( "QMenuBar" ) ) - ((QMenuBar*)mw)->clear(); - else if ( mw->inherits( "QPopupMenu" ) ) - ((QPopupMenu*)mw)->clear(); - */ + QMap idMap; - for ( NodeListIterator it2( node->children ); it2.current(); ++it2 ) + for ( NodeList::iterator it2 = node->children.begin(); it2 != node->children.end(); ++it2 ) { - NodeList& lst = idMap[it2.current()->group]; - int idx = it2.current()->idx; + NodeList& lst = idMap[(*it2)->group]; + int idx = (*it2)->idx; if ( idx < 0 || idx >= (int)lst.count() ) - lst.append( it2.current() ); + lst.append( *it2 ); else - lst.insert( idx, it2.current() ); + lst.insert( idx, *it2 ); } QIntList groups = idMap.keys(); - qHeapSort( groups ); + qSort( groups ); - groups.remove( -1 ); + groups.removeAll( -1 ); groups.append( -1 ); for ( QIntList::const_iterator gIt = groups.begin(); gIt != groups.end(); ++gIt ) @@ -945,20 +895,27 @@ void QtxActionMenuMgr::updateMenu( MenuNode* startNode, const bool rec, const bo continue; const NodeList& lst = idMap[*gIt]; - for ( NodeListIterator iter( lst ); iter.current(); ++iter ) + for ( NodeList::const_iterator iter = lst.begin(); iter != lst.end(); ++iter ) { - MenuNode* par = iter.current()->parent; - if ( !isVisible( iter.current()->id, par ? par->id : -1 ) ) - continue; + MenuNode* node = *iter; if ( rec ) - updateMenu( iter.current(), rec, false ); + updateMenu( node, rec, false ); + + MenuNode* par = node->parent; + if ( !isVisible( node->id, par ? par->id : -1 ) ) + continue; - QAction* a = itemAction( iter.current()->id ); + bool isMenu = false; + QAction* a = itemAction( node->id ); if ( !a ) - a = menuAction( iter.current()->id ); - if ( a ) - a->addTo( mw ); + { + isMenu = true; + a = menuAction( node->id ); + } + + if ( !isMenu || !a->menu()->isEmpty() ) + mw->addAction( a ); } } @@ -969,61 +926,61 @@ void QtxActionMenuMgr::updateMenu( MenuNode* startNode, const bool rec, const bo } /*! - Updates menu (virtual variant). To be redefined for custom activity on menu updating + \brief Internal update. + + Customizes the menu update processing. */ void QtxActionMenuMgr::internalUpdate() { - if ( isUpdatesEnabled() ) - updateMenu(); + if ( !isUpdatesEnabled() ) + return; + + updateMenu(); + myUpdateIds.clear(); } /*! - \return true if widget is non-empty menu - \param wid - widget to be checked + \brief Check if menu widget has any actions. + \param wid widget to be checked + \return \c true if widget contains action(s) */ bool QtxActionMenuMgr::checkWidget( QWidget* wid ) const { if ( !wid ) return false; - QMenuData* md = 0; - if ( wid->inherits( "QPopupMenu" ) ) - md = (QPopupMenu*)wid; - else if ( wid->inherits( "QMenuBar" ) ) - md = (QMenuBar*)wid; - - return md ? md->count() : false; + return !wid->actions().isEmpty(); } /*! - \return popup of menu item - \param node - menu item + \brief Get menu widget for the given \a node. + \param node menu node + \return popup menu or main menu corresponding to the menu node (or 0 if not found) */ QWidget* QtxActionMenuMgr::menuWidget( MenuNode* node) const { - if ( !node || node == &myRoot ) + if ( !node || node == myRoot ) return myMenu; if ( !myMenus.contains( node->id ) || !myMenus[node->id] ) return 0; - return myMenus[node->id]->popup(); + return myMenus[node->id]->menu(); } /*! - Removes excess separators of menu - \param wid - menu to be processed + \brief Remove extra separators from menu widget. + \param wid menu widget to be processed */ void QtxActionMenuMgr::simplifySeparators( QWidget* wid ) { - if ( wid && wid->inherits( "QPopupMenu" ) ) - Qtx::simplifySeparators( (QPopupMenu*)wid, false ); + Qtx::simplifySeparators( wid, false ); } /*! - Removes special symbols (&) from string - \param txt - string to be processed - \return clear variant of string + \brief Remove special symbols (&) from string to get clear menu title. + \param txt string to be processed + \return clear title */ QString QtxActionMenuMgr::clearTitle( const QString& txt ) const { @@ -1039,9 +996,10 @@ QString QtxActionMenuMgr::clearTitle( const QString& txt ) const } /*! - Creates and inserts many menu items - \param lst - list of menu texts - \param pId - id of action corresponding to parent menu item + \brief Create and inserts menu item recursively. + \param lst list of menu names + \param pId parent menu item ID + \return created menu item ID (last in the chain) */ int QtxActionMenuMgr::createMenu( const QStringList& lst, const int pId ) { @@ -1050,8 +1008,8 @@ int QtxActionMenuMgr::createMenu( const QStringList& lst, const int pId ) QStringList sl( lst ); - QString title = sl.last().stripWhiteSpace(); - sl.remove( sl.fromLast() ); + QString title = sl.last().trimmed(); + sl.removeLast(); int parentId = sl.isEmpty() ? pId : createMenu( sl, pId ); @@ -1059,10 +1017,10 @@ int QtxActionMenuMgr::createMenu( const QStringList& lst, const int pId ) } /*! - Loads actions description from file - \param fname - name of file - \param r - reader of file - \return true on success + \brief Load actions description from the file. + \param fname file name + \param r action reader + \return \c true on success and \c false on error */ bool QtxActionMenuMgr::load( const QString& fname, QtxActionMgr::Reader& r ) { @@ -1071,9 +1029,10 @@ bool QtxActionMenuMgr::load( const QString& fname, QtxActionMgr::Reader& r ) } /*! - \return true if item has such child - \param title - menu text of child - \param pid - id of action corresponding to item + \brief Check if the parent menu contains menu item with given \a title. + \param title menu title + \param pid parent menu item ID + \return \c true if parent menu item contains such child item */ bool QtxActionMenuMgr::containsMenu( const QString& title, const int pid ) const { @@ -1081,41 +1040,90 @@ bool QtxActionMenuMgr::containsMenu( const QString& title, const int pid ) const } /*! - \return true if item has such child - \param id - id of action corresponding to child - \param pid - id of action corresponding to item + \brief Check if the parent menu contains menu item with given \a id. + \param id menu item ID + \param pid parent menu item ID + \return \c true if parent menu item contains such child item */ bool QtxActionMenuMgr::containsMenu( const int id, const int pid ) const { return (bool)find( id, pid, false ); } +/*! + \brief Perform delayed menu update. + \param id menu item ID + \param rec if \c true, perform recursive update +*/ +void QtxActionMenuMgr::triggerUpdate( const int id, const bool rec ) +{ + bool isRec = rec; + if ( myUpdateIds.contains( id ) ) + isRec = isRec || myUpdateIds[ id ]; + myUpdateIds.insert( id, isRec ); + + QtxActionMgr::triggerUpdate(); +} + +/*! + \brief Called when delayed content update is performed. + + Customizes the content update operation. +*/ +void QtxActionMenuMgr::updateContent() +{ + // Warning: For correct updating it is necessary to update the most enclosed submenu in first turn + // because not updated empty submenu will be skipped. Now the submenus are iterated in + // ascending order according to their identifiers. For a submenus with automatically generated + // identifiers this will work correctly since the uppermost submenus have the biggest number + // (identifiers are generated by decrementing 1 starting from -1). In general, if any submenu + // have positive identifiers this method might not work correctly. In this case it would be + // necessary to improve this method and to add preliminary sorting a submenus by depth of an + // enclosure. + for ( QMap::const_iterator it = myUpdateIds.constBegin(); it != myUpdateIds.constEnd(); ++it ) + { + MenuNode* node = it.key() == -1 ? myRoot : find( it.key() ); + if ( node ) + updateMenu( node, it.value() ); + } + myUpdateIds.clear(); +} /*! - Constructor - \param r - menu reader - \param mgr - menu manager + \class QtxActionMenuMgr::MenuCreator + \brief Menu actions creator. + + Used by Reader to create actions by reading descriptions from the file + and fill in the action manager with the actions. +*/ + +/*! + \brief Constructor. + \param r menu actions reader + \param mgr menu manager */ -QtxActionMenuMgr::MenuCreator::MenuCreator( QtxActionMgr::Reader* r, - QtxActionMenuMgr* mgr ) +QtxActionMenuMgr::MenuCreator::MenuCreator( QtxActionMgr::Reader* r, QtxActionMenuMgr* mgr ) : QtxActionMgr::Creator( r ), - myMgr( mgr ) +myMgr( mgr ) { } /*! - Destructor + \brief Creator destructor. + + Does nothing for the moment. */ QtxActionMenuMgr::MenuCreator::~MenuCreator() { } /*! - Appends new menu items - \param tag - tag of item - \param subMenu - it has submenu - \param attr - list of attributes - \param pId - id of action corresponding to parent item + \brief Create and append to the action manager a new action. + \param tag item tag name + \param subMenu \c true if this item is submenu + \param attr attributes map + \param pId parent action ID + \return menu action ID */ int QtxActionMenuMgr::MenuCreator::append( const QString& tag, const bool subMenu, const ItemAttributes& attr, const int pId ) @@ -1141,20 +1149,21 @@ int QtxActionMenuMgr::MenuCreator::append( const QString& tag, const bool subMen res = myMgr->insert( separator(), pId, intValue( attr, group, 0 ), intValue( attr, pos, -1 ) ); else { - QPixmap pix; QIconSet set; + QIcon set; + QPixmap pix; QString name = strValue( attr, icon ); if( !name.isEmpty() && loadPixmap( name, pix ) ) - set = QIconSet( pix ); + set = QIcon( pix ); QtxAction* newAct = new QtxAction( strValue( attr, tooltip ), set, - strValue( attr, label ), + strValue( attr, label ), QKeySequence( strValue( attr, accel ) ), myMgr ); newAct->setToolTip( strValue( attr, tooltip ) ); QString toggleact = strValue( attr, toggle ); - newAct->setToggleAction( !toggleact.isEmpty() ); - newAct->setOn( toggleact.lower()=="true" ); - + newAct->setCheckable( !toggleact.isEmpty() ); + newAct->setChecked( toggleact.toLower() == "true" ); + connect( newAct ); int aid = myMgr->registerAction( newAct, actId ); res = myMgr->insert( aid, pId, intValue( attr, group, 0 ), intValue( attr, pos, -1 ) ); diff --git a/src/Qtx/QtxActionMenuMgr.h b/src/Qtx/QtxActionMenuMgr.h index bdbe139a4..f9066d939 100644 --- a/src/Qtx/QtxActionMenuMgr.h +++ b/src/Qtx/QtxActionMenuMgr.h @@ -25,57 +25,23 @@ #include "Qtx.h" #include "QtxActionMgr.h" -#include -#include +#include +#include -class QPopupMenu; +class QMenu; class QMainWindow; #ifdef WIN32 #pragma warning( disable:4251 ) #endif -/*! - \class QtxActionMenuMgr - Allows to use set of action to automatically build main menu. - With help of methods insert/append/remove it is possible to - describe whole structure of menu. Method hide allows - to temporary remove some items from menu, method show allows to - recreate them. - Actions can be grouped with help of group identifictor. - Inside popup or menu bar items have order by increasing group id. - This manager is able to attune menu: to remove excess separators, - to remove empty popup menu etc. -*/ class QTX_EXPORT QtxActionMenuMgr : public QtxActionMgr { Q_OBJECT class MenuNode; - typedef QPtrList NodeList; - typedef QPtrListIterator NodeListIterator; - - /*! - \class MenuNode - Represents a menu item inside main menu structure. - For internal purposes only - */ - class MenuNode - { - public: - MenuNode() : parent( 0 ), visible( true ) { children.setAutoDelete( true ); }; - MenuNode( MenuNode* p ) : parent( p ), visible( true ) { children.setAutoDelete( true ); }; - - int id; - int idx; - int group; - MenuNode* parent; - bool visible; - NodeList children; - }; - - class MenuAction; + typedef QList NodeList; //!< menu nodes list protected: class MenuCreator; @@ -97,17 +63,17 @@ public: virtual int insert( const int, const int, const int, const int = -1 ); int insert( QAction*, const int, const int, const int = -1 ); - int insert( const QString&, const QString&, const int, const int = -1, const int = -1, const bool = false ); - int insert( const QString&, const QStringList&, const int, const int = -1, const int = -1, const bool = false ); - virtual int insert( const QString&, const int, const int, const int = -1, const int = -1, const bool = false ); + int insert( const QString&, const QString&, const int, const int = -1, const int = -1 ); + int insert( const QString&, const QStringList&, const int, const int = -1, const int = -1 ); + virtual int insert( const QString&, const int, const int, const int = -1, const int = -1 ); int append( const int, const int, const int ); int append( QAction*, const int, const int ); - int append( const QString&, const int, const int, const int = -1, const bool = false ); + int append( const QString&, const int, const int, const int = -1 ); int prepend( const int, const int, const int ); int prepend( QAction*, const int, const int ); - int prepend( const QString&, const int, const int, const int = -1, const bool = false ); + int prepend( const QString&, const int, const int, const int = -1 ); void remove( const int ); void remove( const int, const int, const int = -1 ); @@ -118,17 +84,23 @@ public: bool isShown( const int ) const; void setShown( const int, const bool ); + virtual void change( const int, const QString& ); + virtual bool load( const QString&, QtxActionMgr::Reader& ); bool containsMenu( const QString&, const int ) const; bool containsMenu( const int, const int ) const; - -private slots: - void onDestroyed( QObject* ); +private Q_SLOTS: + void onAboutToShow(); + void onAboutToHide(); void onHighlighted( int ); + void onDestroyed( QObject* ); + +Q_SIGNALS: + void menuAboutToShow( QMenu* ); + void menuAboutToHide( QMenu* ); -signals: void menuHighlighted( int, int ); protected: @@ -144,10 +116,11 @@ protected: void removeMenu( const int, MenuNode* ); QAction* itemAction( const int ) const; - MenuAction* menuAction( const int ) const; + QAction* menuAction( const int ) const; void updateMenu( MenuNode* = 0, const bool = true, const bool = true ); virtual void internalUpdate(); + virtual void updateContent(); private: bool checkWidget( QWidget* ) const; @@ -156,19 +129,18 @@ private: QString clearTitle( const QString& ) const; int createMenu( const QStringList&, const int ); -private: - typedef QMap MenuMap; + void triggerUpdate( const int, const bool rec = true ); private: - MenuNode myRoot; - QWidget* myMenu; - MenuMap myMenus; + typedef QMap MenuMap; //!< actions map + +private: + MenuNode* myRoot; //!< root menu node + QWidget* myMenu; //!< menu widget + MenuMap myMenus; //!< actions map + QMap myUpdateIds; //!< list of actions ID being updated }; -/*! - \class QtxActionMenuMgr::MenuCreator - Allows to create automatically main menu by data read from file -*/ class QtxActionMenuMgr::MenuCreator : public QtxActionMgr::Creator { public: @@ -179,7 +151,7 @@ public: const ItemAttributes&, const int ); private: - QtxActionMenuMgr* myMgr; + QtxActionMenuMgr* myMgr; //!< menu manager }; diff --git a/src/Qtx/QtxActionMgr.h b/src/Qtx/QtxActionMgr.h index f3b265a20..f1b5778f3 100644 --- a/src/Qtx/QtxActionMgr.h +++ b/src/Qtx/QtxActionMgr.h @@ -85,21 +85,21 @@ protected: void triggerUpdate(); virtual void updateContent(); -private slots: +private Q_SLOTS: void onUpdateContent(); private: - typedef QPointer ActionPtr; - typedef QMap ActionMap; + typedef QPointer ActionPtr; //!< Action guarded pointer + typedef QMap ActionMap; //!< Actions map private: - bool myUpdate; - ActionMap myActions; - QTimer* myUpdTimer; + bool myUpdate; //!< update flag + ActionMap myActions; //!< actions map + QTimer* myUpdTimer; //!< update timer }; -QTX_EXPORT typedef QMap ItemAttributes; +QTX_EXPORT typedef QMap ItemAttributes; //!< attributes map class QtxActionMgr::Creator { @@ -120,7 +120,7 @@ protected: static QString strValue( const ItemAttributes&, const QString&, const QString& = QString::null ); private: - QtxActionMgr::Reader* myReader; + QtxActionMgr::Reader* myReader; //!< actions reader }; class QtxActionMgr::Reader @@ -136,7 +136,7 @@ public: QTX_EXPORT virtual bool read( const QString&, Creator& ) const = 0; private: - QMap< QString, QString > myOptions; + QMap< QString, QString > myOptions; //!< options map }; class QtxActionMgr::XMLReader : public Reader diff --git a/src/Qtx/QtxActionToolMgr.cxx b/src/Qtx/QtxActionToolMgr.cxx index 9ce569613..ded6a5f1b 100644 --- a/src/Qtx/QtxActionToolMgr.cxx +++ b/src/Qtx/QtxActionToolMgr.cxx @@ -24,27 +24,59 @@ #include "QtxAction.h" #include "QtxToolBar.h" -#include -#include +#include /*! - Constructor + \class ToolNode + \internal + \brief Represents a toolbutton inside toolbar structure. +*/ + +/*! + \fn QtxActionToolMgr::ToolNode::ToolNode() + \brief Default constructor. +*/ + +/*! + \fn QtxActionToolMgr::ToolNode::ToolNode( const int _id ) + \brief Constructor. + \param _id toolbar node ID +*/ + + +/*! + \class QtxActionToolMgr + \brief Toolbar actions manager. + + Toolbar manager allows using of set of action for automatic generating of + application toolbars and dynamic update of toolbars contents. + + Use insert(), append() and remove() methods to create toolbar and add actions to it. + Methods show(), hide() allow displaying/erasing of specified toolbar items. + + Toolbar manager automatically optimizes toolbars by removing extra separators, etc. +*/ + +/*! + \brief Constructor. + \param p parent main window */ QtxActionToolMgr::QtxActionToolMgr( QMainWindow* p ) : QtxActionMgr( p ), -myMainWindow( p ) + myMainWindow( p ) { } /*! - Destructor + \brief Destructor. */ QtxActionToolMgr::~QtxActionToolMgr() { } /*! - \return desktop + \brief Get parent main window. + \return main window pointer */ QMainWindow* QtxActionToolMgr::mainWindow() const { @@ -52,26 +84,30 @@ QMainWindow* QtxActionToolMgr::mainWindow() const } /*! - Creates toolbar - \return id of just created toolbar - \param name - name of toolbar - \param tid - proposed id (if such id is used already, then it will be returned without creation) + \brief Create toolbar and assign \a id to it. + + If \a tid is less than 0, the ID is generated automatically. + If toolbar with given \a tid is already registered, the toolbar will not be created. + + \param title toolbar title + \param tid requested toolbar ID + \return id of created/found toolbar */ -int QtxActionToolMgr::createToolBar( const QString& name, const int tid ) +int QtxActionToolMgr::createToolBar( const QString& title, const int tid ) { static int _toolBarId = -1; int tbId = -1; for ( ToolBarMap::ConstIterator it = myToolBars.begin(); it != myToolBars.end() && tbId == -1; ++it ) { - if ( it.data().toolBar->label().lower() == name.lower() ) + if ( it.value().toolBar->windowTitle().toLower() == title.toLower() ) tbId = it.key(); } if ( tbId != -1 ) return tbId; - QToolBar* tb = find( name, mainWindow() ); + QToolBar* tb = find( title, mainWindow() ); tbId = tid < 0 ? --_toolBarId : tid; @@ -81,7 +117,8 @@ int QtxActionToolMgr::createToolBar( const QString& name, const int tid ) if ( !tb ) { tb = new QtxToolBar( true, mainWindow() ); - tb->setLabel( name ); + mainWindow()->addToolBar( tb ); + tb->setWindowTitle( title ); } tInfo.toolBar = tb; @@ -91,34 +128,31 @@ int QtxActionToolMgr::createToolBar( const QString& name, const int tid ) } /*! - \return toolbar by title - \param label - toolbar title - \param mw - desktop + \brief Search toolbar with given \a title owned by main window \mw. + \param title toolbar title + \param mw main window + \return toolbar or 0 if not found */ -QToolBar* QtxActionToolMgr::find( const QString& label, QMainWindow* mw ) const +QToolBar* QtxActionToolMgr::find( const QString& title, QMainWindow* mw ) const { if ( !mw ) return 0; - QString pattern = label.lower(); + QString pattern = title.toLower(); QToolBar* res = 0; - QPtrList lst = mw->dockWindows(); - for ( QPtrListIterator it( lst ); it.current() && !res; ++it ) + QList toolbars = qFindChildren( mw ); + for ( QList::iterator it = toolbars.begin(); it != toolbars.end() && !res; ++it ) { - if ( !it.current()->inherits( "QToolBar" ) ) - continue; - - QToolBar* cur = (QToolBar*)it.current(); - if ( cur->label().lower() == pattern ) - res = cur; + if ( (*it)->windowTitle().toLower() == pattern ) + res = *it; } return res; } /*! - Removes toolbar - \param tid - toolbar id + \brief Remove toolbar. + \param tid toolbar ID */ void QtxActionToolMgr::removeToolBar( const int tid ) { @@ -130,76 +164,80 @@ void QtxActionToolMgr::removeToolBar( const int tid ) } /*! - Removes toolbar - \param tname - toolbar name + \brief Remove toolbar. + \param title toolbar title */ -void QtxActionToolMgr::removeToolBar( const QString& tname ) +void QtxActionToolMgr::removeToolBar( const QString& title ) { - removeToolBar( find( tname ) ); + removeToolBar( find( title ) ); } /*! - Insert action into toolbar - \param id - identificator of action - \param tId - identificator of toolbar - \param idx - position inside toolbar + \brief Insert action into toolbar. + \param id action ID + \param tid toolbar ID + \param idx action index in the toolbar (if < 0, action is appended to the end) + \return action ID */ int QtxActionToolMgr::insert( const int id, const int tid, const int idx ) { if ( !contains( id ) || !hasToolBar( tid ) ) return -1; - +/* if ( containsAction( id, tid ) ) remove( id, tid ); - - ToolNode node; - node.id = id; +*/ + ToolNode node( id ); NodeList& list = myToolBars[tid].nodes; - int index = idx < 0 ? list.count() : QMIN( idx, (int)list.count() ); - list.insert( list.at( index ), node ); - updateToolBar( tid ); + int index = idx < 0 ? list.count() : qMin( idx, (int)list.count() ); + list.insert( index, node ); + triggerUpdate( tid ); return id; } /*! - Insert action into toolbar - \param act - action - \param tId - identificator of toolbar - \param pos - position inside toolbar + \brief Insert action into toolbar. + \param a action + \param tid toolbar ID + \param idx action index in the toolbar (if < 0, action is appended to the end) + \return action ID */ -int QtxActionToolMgr::insert( QAction* act, const int tid, const int pos ) +int QtxActionToolMgr::insert( QAction* a, const int tid, const int idx ) { - return insert( registerAction( act ), tid, pos ); + return insert( registerAction( a ), tid, idx ); } /*! - Insert action into toolbar - \param id - identificator of action - \param tname - name of toolbar - \param pos - position inside toolbar + \brief Insert action into toolbar. + \param id action ID + \param title toolbar title + \param idx action index in the toolbar (if < 0, action is appended to the end) + \return action ID */ -int QtxActionToolMgr::insert( const int id, const QString& tname, const int pos ) +int QtxActionToolMgr::insert( const int id, const QString& title, const int idx ) { - return insert( id, createToolBar( tname ), pos ); + return insert( id, createToolBar( title ), idx ); } /*! - Insert action into toolbar - \param act - action - \param tname - name of toolbar - \param pos - position inside toolbar + \brief Insert action into toolbar. + \param a action + \param title toolbar title + \param idx action index in the toolbar (if < 0, action is appended to the end) + \return action ID */ -int QtxActionToolMgr::insert( QAction* act, const QString& tname, const int pos ) +int QtxActionToolMgr::insert( QAction* a, const QString& title, const int idx ) { - return insert( registerAction( act ), createToolBar( tname ), pos ); + return insert( registerAction( a ), createToolBar( title ), idx ); } /*! - Append action into toolbar as last toolbutton - \param id - identificator of action - \param tId - identificator of toolbar + \brief Append action to the end of toolbar. + \param id action ID + \param tid toolbar ID + \return action ID */ int QtxActionToolMgr::append( const int id, const int tid ) { @@ -207,39 +245,43 @@ int QtxActionToolMgr::append( const int id, const int tid ) } /*! - Append action into toolbar as last toolbutton - \param act - action - \param tId - identificator of toolbar + \brief Append action to the end of toolbar. + \param a action + \param tid toolbar ID + \return action ID */ -int QtxActionToolMgr::append( QAction* act, const int tid ) +int QtxActionToolMgr::append( QAction* a, const int tid ) { - return insert( act, tid ); + return insert( a, tid ); } /*! - Append action into toolbar as last toolbutton - \param id - identificator of action - \param tname - toolbar name + \brief Append action to the end of toolbar. + \param id action ID + \param title toolbar title + \return action ID */ -int QtxActionToolMgr::append( const int id, const QString& tname ) +int QtxActionToolMgr::append( const int id, const QString& title ) { - return insert( id, tname ); + return insert( id, title ); } /*! - Append action into toolbar as last toolbutton - \param act - action - \param tname - toolbar name + \brief Append action to the end of toolbar. + \param a action + \param title toolbar title + \return action ID */ -int QtxActionToolMgr::append( QAction* act, const QString& tname ) +int QtxActionToolMgr::append( QAction* a, const QString& title ) { - return insert( act, tname ); + return insert( a, title ); } /*! - Append action into toolbar as first toolbutton - \param id - identificator of action - \param tId - identificator of toolbar + \brief Insert action to the beginning of toolbar. + \param id action ID + \param tid toolbar ID + \return action ID */ int QtxActionToolMgr::prepend( const int id, const int tid ) { @@ -247,39 +289,42 @@ int QtxActionToolMgr::prepend( const int id, const int tid ) } /*! - Append action into toolbar as first toolbutton - \param act - action - \param tId - identificator of toolbar + \brief Insert action to the beginning of toolbar. + \param a action + \param tid toolbar ID + \return action ID */ -int QtxActionToolMgr::prepend( QAction* act, const int tid ) +int QtxActionToolMgr::prepend( QAction* a, const int tid ) { - return insert( act, tid, 0 ); + return insert( a, tid, 0 ); } /*! - Append action into toolbar as first toolbutton - \param id - identificator of action - \param tname - toolbar name + \brief Insert action to the beginning of toolbar. + \param id action ID + \param title toolbar title + \return action ID */ -int QtxActionToolMgr::prepend( const int id, const QString& tname ) +int QtxActionToolMgr::prepend( const int id, const QString& title ) { - return insert( id, tname, 0 ); + return insert( id, title, 0 ); } /*! - Append action into toolbar as first toolbutton - \param act - action - \param tname - toolbar name + \brief Insert action to the beginning of toolbar. + \param a action ID + \param title toolbar title + \return action ID */ -int QtxActionToolMgr::prepend( QAction* act, const QString& tname ) +int QtxActionToolMgr::prepend( QAction* a, const QString& tname ) { - return insert( act, tname, 0 ); + return insert( a, tname, 0 ); } /*! - Remove action from toolbar - \param id - identificator of action - \param tId - identificator of toolbar + \brief Remove action from toolbar. + \param id action ID + \param tid toolbar ID */ void QtxActionToolMgr::remove( const int id, const int tid ) { @@ -296,22 +341,23 @@ void QtxActionToolMgr::remove( const int id, const int tid ) myToolBars[tid].nodes = newList; - updateToolBar( tid ); + triggerUpdate( tid ); } /*! - Remove action from toolbar - \param id - identificator of action - \param tname - name of toolbar + \brief Remove action from toolbar. + \param id action ID + \param title toolbar title */ -void QtxActionToolMgr::remove( const int id, const QString& tname ) +void QtxActionToolMgr::remove( const int id, const QString& title ) { - remove( id, find( tname ) ); + remove( id, find( title ) ); } /*! - \return toolbar by it's id - \param tId - identificator of toolbar + \brief Get toolbar by given \a tid. + \param tid toolbar ID + \return toolbar or 0 if not found */ QToolBar* QtxActionToolMgr::toolBar( const int tid ) const { @@ -322,17 +368,19 @@ QToolBar* QtxActionToolMgr::toolBar( const int tid ) const } /*! - \return toolbar by it's name - \param tname - name of toolbar + \brief Get toolbar by given \a title. + \param title toolbar title + \return toolbar or 0 if not found */ -QToolBar* QtxActionToolMgr::toolBar( const QString& tname ) const +QToolBar* QtxActionToolMgr::toolBar( const QString& title ) const { - return toolBar( find( tname ) ); + return toolBar( find( title ) ); } /*! - \return true if manager contains toolbar with such id - \param tId - identificator of toolbar + \brief Check if toolbar with given \a id already registered. + \param tid toolbar ID + \return \c true if toolbar is registered in the toolbar manager */ bool QtxActionToolMgr::hasToolBar( const int tid ) const { @@ -340,25 +388,28 @@ bool QtxActionToolMgr::hasToolBar( const int tid ) const } /*! - \return true if manager contains toolbar with such name - \param tname - name of toolbar + \brief Check if toolbar with given \a id already registered. + \param title toolbar title + \return \c true if toolbar is registered in the toolbar manager */ -bool QtxActionToolMgr::hasToolBar( const QString& tname ) const +bool QtxActionToolMgr::hasToolBar( const QString& title ) const { - return find( tname ) != -1; + return find( title ) != -1; } /*! - \return true if toolbar contains action - \param id - identificator of action - \param tId - identificator of toolbar + \brief Check if toolbar contains given action. + \param id action ID + \param tid toolbar ID + \return \c true if toolbar contains action */ bool QtxActionToolMgr::containsAction( const int id, const int tid ) const { for ( ToolBarMap::ConstIterator it = myToolBars.begin(); it != myToolBars.end(); ++it ) { - if ( tid == -1 || it.key() == tid ) { - const NodeList& list = it.data().nodes; + if ( tid == -1 || it.key() == tid ) + { + const NodeList& list = it.value().nodes; for ( NodeList::const_iterator nit = list.begin(); nit != list.end(); ++nit ) if ( (*nit).id == id ) return true; @@ -368,7 +419,9 @@ bool QtxActionToolMgr::containsAction( const int id, const int tid ) const } /*! - SLOT: called when toolbar is destroyed, removes just destroyed toolbar from map + \brief Called when toolbar is destroyed. + + Clears internal pointer to the toolbar to disable crashes. */ void QtxActionToolMgr::onToolBarDestroyed() { @@ -376,112 +429,121 @@ void QtxActionToolMgr::onToolBarDestroyed() } /*! - \return id of toolbar by it's name - \param tname - name of toolbar + \brief Search toolbar by given \a name. + \param title toolbar title + \return toolbar ID or -1 if not found */ -int QtxActionToolMgr::find( const QString& tname ) const +int QtxActionToolMgr::find( const QString& title ) const { int id = -1; for ( ToolBarMap::ConstIterator it = myToolBars.begin(); it != myToolBars.end() && id == -1; ++it ) { - if ( it.data().toolBar->label() == tname ) + if ( it.value().toolBar->windowTitle() == title ) id = it.key(); } return id; } /*! - \return id of toolbar - \param t - toolbar + \brief Get toolbar ID. + \param tb toolbar + \return toolbar ID or -1 if toolbar is not registered */ -int QtxActionToolMgr::find( QToolBar* t ) const +int QtxActionToolMgr::find( QToolBar* tb ) const { int id = -1; for ( ToolBarMap::ConstIterator it = myToolBars.begin(); it != myToolBars.end() && id == -1; ++it ) { - if ( it.data().toolBar == t ) + if ( it.value().toolBar == tb ) id = it.key(); } return id; } /*! - Updates toolbar - \param tId - toolbar id + \brief Update toolbar. + \param tid toolbar ID */ -void QtxActionToolMgr::updateToolBar( const int tId ) +void QtxActionToolMgr::updateToolBar( const int tid ) { if ( !isUpdatesEnabled() ) return; - if ( !myToolBars.contains( tId ) ) + if ( !myToolBars.contains( tid ) ) return; - QToolBar* tb = myToolBars[tId].toolBar; - const NodeList& list = myToolBars[tId].nodes; + QToolBar* tb = myToolBars[tid].toolBar; + const NodeList& list = myToolBars[tid].nodes; for ( NodeList::const_iterator it = list.begin(); it != list.end(); ++it ) { QAction* a = action( (*it).id ); - if ( a ) - a->removeFrom( tb ); + tb->removeAction( a ); +// if ( a ) +// a->removeFrom( tb ); } tb->clear(); for ( NodeList::const_iterator itr = list.begin(); itr != list.end(); ++itr ) { - if ( !isVisible( (*itr).id, tId ) ) + if ( !isVisible( (*itr).id, tid ) ) continue; QAction* a = action( (*itr).id ); - if ( a ) - a->addTo( tb ); + tb->addAction( a ); +// if ( a ) +// a->addTo( tb ); } simplifySeparators( tb ); } /*! - Updates all toolbars + \brief Update all registered toolbars. */ void QtxActionToolMgr::internalUpdate() { + if ( !isUpdatesEnabled() ) + return; + for ( ToolBarMap::ConstIterator it1 = myToolBars.begin(); it1 != myToolBars.end(); ++it1 ) updateToolBar( it1.key() ); + + myUpdateIds.clear(); } /*! - Removes excess separators from toolbar + \brief Remove extra separators from toolbar. + \param tb toolbar */ -void QtxActionToolMgr::simplifySeparators( QToolBar* t ) +void QtxActionToolMgr::simplifySeparators( QToolBar* tb ) { - if ( t ) - Qtx::simplifySeparators( t ); + Qtx::simplifySeparators( tb ); } /*! - Shows action in all toolbars - \param actId - action id + \brief Show action (in all toolbars) + \param id action ID */ -void QtxActionToolMgr::show( const int actId ) +void QtxActionToolMgr::show( const int id ) { - setShown( actId, true ); + setShown( id, true ); } /*! - Hides action in all toolbars - \param actId - action id + \brief Hide action (in all toolbars) + \param id action ID */ -void QtxActionToolMgr::hide( const int actId ) +void QtxActionToolMgr::hide( const int id ) { - setShown( actId, false ); + setShown( id, false ); } /*! - Changes shown status of action in all toolbars - \param id - action id - \param on - new shown status + \brief Set visibility status for toolbar action with given \a id. + \param id action ID + \param on new visibility status */ void QtxActionToolMgr::setShown( const int id, const bool on ) { @@ -490,15 +552,16 @@ void QtxActionToolMgr::setShown( const int id, const bool on ) } /*! - \return true if action is shown in all toolbars - \param id - action id + \brief Get visibility status for toolbar action with given \a id. + \param id action ID + \return \c true if action is shown in all toolbars */ bool QtxActionToolMgr::isShown( const int id ) const { - QPtrList nodes; + QList nodes; for ( ToolBarMap::ConstIterator it = myToolBars.begin(); it != myToolBars.end(); ++it ) { - const NodeList& nl = it.data().nodes; + const NodeList& nl = it.value().nodes; for ( NodeList::const_iterator itr = nl.begin(); itr != nl.end(); ++itr ) { const ToolNode& node = *itr; @@ -511,46 +574,48 @@ bool QtxActionToolMgr::isShown( const int id ) const return false; bool vis = true; - for ( QPtrListIterator itr( nodes ); itr.current() && vis; ++itr ) - vis = itr.current()->visible; + for ( QList::iterator itr = nodes.begin(); itr != nodes.end() && vis; ++itr ) + vis = (*itr)->visible; return vis; } /*! - \return shown status of action in toolbar - \param id - action id - \param tId - toolbar id + \brief Check if an action with given \a id is visible in the toolbar \a tid. + \param id action ID + \param tid toolbar ID + \return \c true if action is shown in the toolbar */ -bool QtxActionToolMgr::isVisible( const int id, const int tId ) const +bool QtxActionToolMgr::isVisible( const int id, const int tid ) const { - if ( !myToolBars.contains( tId ) ) + if ( !myToolBars.contains( tid ) ) return false; bool vis = false; - const NodeList& lst = myToolBars[tId].nodes; + const NodeList& lst = myToolBars[tid].nodes; for ( NodeList::const_iterator it = lst.begin(); it != lst.end() && !vis; ++it ) { const ToolNode& node = *it; if ( node.id == id ) + vis = node.visible; } return vis; } /*! - Changes action shown status in certain toolbar - \param id - action id - \param tId - toolbar id - \param on - new shown status + \brief Show/hide action with given \a id in the toolbar \a tid. + \param id action ID + \param tid toolbar ID + \param on new visibility status */ -void QtxActionToolMgr::setVisible( const int id, const int tId, const bool on ) +void QtxActionToolMgr::setVisible( const int id, const int tid, const bool on ) { - if ( !myToolBars.contains( tId ) ) + if ( !myToolBars.contains( tid ) ) return; bool changed = false; - NodeList& lst = myToolBars[tId].nodes; + NodeList& lst = myToolBars[tid].nodes; for ( NodeList::iterator it = lst.begin(); it != lst.end(); ++it ) { ToolNode& node = *it; @@ -562,13 +627,14 @@ void QtxActionToolMgr::setVisible( const int id, const int tId, const bool on ) } if ( changed ) - updateToolBar( tId ); + triggerUpdate( tid ); } /*! - Loads toolbar content from file - \param fname - file name - \param r - reader + \brief Load toolbar contents from the file. + \param fname file name + \param r actions reader + \return \c true on success and \c false on error */ bool QtxActionToolMgr::load( const QString& fname, QtxActionMgr::Reader& r ) { @@ -576,9 +642,44 @@ bool QtxActionToolMgr::load( const QString& fname, QtxActionMgr::Reader& r ) return r.read( fname, cr ); } +/*! + \brief Called when delayed content update is performed. + + Customizes the content update operation. +*/ +void QtxActionToolMgr::updateContent() +{ + if ( !isUpdatesEnabled() ) + return; + + for ( QMap::const_iterator it = myUpdateIds.constBegin(); it != myUpdateIds.constEnd(); ++it ) + updateToolBar( it.key() ); + myUpdateIds.clear(); +} + +/*! + \brief Perform delayed toolbar update. + \param tid toolbar ID +*/ +void QtxActionToolMgr::triggerUpdate( const int tid ) +{ + myUpdateIds.insert( tid, 0 ); + QtxActionMgr::triggerUpdate(); +} + /*! - Constructor + \class QtxActionMenuMgr::ToolCreator + \brief Toolbars creator. + + Used by Reader to create actions by reading descriptions from the file, + create toolbars and fill in the toolbara with the actions. +*/ + +/*! + \brief Constructor. + \param r actions reader + \param mgr toolbar manager */ QtxActionToolMgr::ToolCreator::ToolCreator( QtxActionMgr::Reader* r, QtxActionToolMgr* mgr ) @@ -588,21 +689,24 @@ QtxActionToolMgr::ToolCreator::ToolCreator( QtxActionMgr::Reader* r, } /*! - Destructor + \brief Creator destructor. + + Does nothing for the moment. */ QtxActionToolMgr::ToolCreator::~ToolCreator() { } /*! - Appends new tool buttons - \param tag - tag of toolmenu - \param subMenu - it has submenu (not used here) - \param attr - list of attributes - \param pId - id of action corresponding to parent item + \brief Create and append to the action manager a new toolbar or toolbar action. + \param tag item tag name + \param subMenu \c true if this item is submenu (not used) + \param attr attributes map + \param tid toolbar ID + \return toolbar or toolbar action ID */ -int QtxActionToolMgr::ToolCreator::append( const QString& tag, const bool subMenu, - const ItemAttributes& attr, const int tId ) +int QtxActionToolMgr::ToolCreator::append( const QString& tag, const bool /*subMenu*/, + const ItemAttributes& attr, const int tid ) { if( !myMgr || !reader() ) return -1; @@ -618,31 +722,28 @@ int QtxActionToolMgr::ToolCreator::append( const QString& tag, const bool subMen toggle = reader()->option( "toggle", "toggle" ); int res = -1, actId = intValue( attr, id, -1 ); - if( tId==-1 ) + if( tid==-1 ) res = myMgr->createToolBar( strValue( attr, label ), intValue( attr, id, -1 ) ); else if( tag==sep ) - res = myMgr->insert( separator(), tId, intValue( attr, pos, -1 ) ); + res = myMgr->insert( separator(), tid, intValue( attr, pos, -1 ) ); else { - QPixmap pix; QIconSet set; + QIcon set; + QPixmap pix; QString name = strValue( attr, icon ); if( !name.isEmpty() && loadPixmap( name, pix ) ) - set = QIconSet( pix ); + set = QIcon( pix ); - QtxAction* newAct = new QtxAction( strValue( attr, tooltip ), set, - strValue( attr, label ), - QKeySequence( strValue( attr, accel ) ), - myMgr ); + QtxAction* newAct = new QtxAction( strValue( attr, tooltip ), set, strValue( attr, label ), + QKeySequence( strValue( attr, accel ) ), myMgr ); QString toggleact = strValue( attr, toggle ); - newAct->setToggleAction( !toggleact.isEmpty() ); - newAct->setOn( toggleact.lower()=="true" ); + newAct->setCheckable( !toggleact.isEmpty() ); + newAct->setChecked( toggleact.toLower() == "true" ); connect( newAct ); int aid = myMgr->registerAction( newAct, actId ); - res = myMgr->insert( aid, tId, intValue( attr, pos, -1 ) ); + res = myMgr->insert( aid, tid, intValue( attr, pos, -1 ) ); } return res; } - - diff --git a/src/Qtx/QtxActionToolMgr.h b/src/Qtx/QtxActionToolMgr.h index 9300ec22a..582798b2b 100644 --- a/src/Qtx/QtxActionToolMgr.h +++ b/src/Qtx/QtxActionToolMgr.h @@ -24,7 +24,10 @@ #include "Qtx.h" -#include +#include +#include + +#include #include "QtxActionMgr.h" @@ -35,32 +38,21 @@ class QMainWindow; #pragma warning( disable:4251 ) #endif -/*! - \class QtxActionToolMgr - Allows to use set of action to automatically build set of toolbars. - With help of methods insert/append/remove it is possible to - describe toolbars and its internal structure. - This manager is able to attune toolbar by removing excess separators -*/ class QTX_EXPORT QtxActionToolMgr : public QtxActionMgr { Q_OBJECT - /*! - \class ToolNode - Represents a toolbutton inside toolbar - For internal purposes only - */ class ToolNode { public: ToolNode() : id( -1 ), visible( true ) {}; + ToolNode( const int _id ) : id( _id ), visible( true ) {}; - int id; - bool visible; + int id; //!< tool node ID + bool visible; //!< visibility status }; - typedef QValueList NodeList; + typedef QList NodeList; //!< toolbar nodes list protected: class ToolCreator; @@ -111,7 +103,7 @@ public: virtual bool load( const QString&, QtxActionMgr::Reader& ); -protected slots: +protected Q_SLOTS: void onToolBarDestroyed(); protected: @@ -122,22 +114,22 @@ protected: virtual void internalUpdate(); void updateToolBar( const int ); + virtual void updateContent(); + private: void simplifySeparators( QToolBar* ); + void triggerUpdate( const int ); private: - typedef struct { NodeList nodes; QToolBar* toolBar; } ToolBarInfo; - typedef QMap ToolBarMap; + typedef struct { NodeList nodes; QToolBar* toolBar; } ToolBarInfo; //!< toolbar info + typedef QMap ToolBarMap; //!< toolbars map private: - ToolBarMap myToolBars; - QMainWindow* myMainWindow; + ToolBarMap myToolBars; //!< toobars map + QMainWindow* myMainWindow; //!< parent main window + QMap myUpdateIds; //!< list of actions ID being updated }; -/*! - \class QtxActionToolMgr::ToolCreator - Allows to create automatically toolbar by data read from file -*/ class QtxActionToolMgr::ToolCreator : public QtxActionMgr::Creator { public: @@ -148,7 +140,7 @@ public: const ItemAttributes&, const int ); private: - QtxActionToolMgr* myMgr; + QtxActionToolMgr* myMgr; //!< toolbar manager }; #endif -- 2.39.2