1 // Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
8 // This library is distributed in the hope that it will be useful
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/
19 // File: QtxActionMenuMgr.cxx
20 // Author: Alexander SOLOVYEV, Sergey TELKOV
22 #include "QtxActionMenuMgr.h"
24 #include "QtxAction.h"
28 #include <qpopupmenu.h>
29 #include <qwidgetlist.h>
30 #include <qobjectlist.h>
31 #include <qmainwindow.h>
34 #include <qvaluelist.h>
36 // VSR: Uncomment this #define in order to allow dynamic menus support
37 // (emit signals when popup menu is pre-activated)
38 // Currently this support is disabled.
39 //#define ENABLE_DYNAMIC_MENU
46 QValueList<int> prepareIds( const QWidget* w )
49 const QMenuData* md = 0;
50 if ( w->inherits( "QMenuBar" ) )
51 md = dynamic_cast<const QMenuData*>( w );
52 else if ( w->inherits( "QPopupMenu" ) )
53 md = dynamic_cast<const QMenuData*>( w );
55 for ( int i=0; i < md->count(); i++ )
56 l.append( md->idAt( i ) );
61 int getNewId( const QWidget* w, const QValueList<int>& l, bool retId = true )
63 const QMenuData* md = 0;
64 if ( w->inherits( "QMenuBar" ) )
65 md = dynamic_cast<const QMenuData*>( w );
66 else if ( w->inherits( "QPopupMenu" ) )
67 md = dynamic_cast<const QMenuData*>( w );
69 for ( int i=0, j=0; i < md->count() && j < l.count(); i++, j++ )
70 if ( md->idAt( i ) != l[ j ] ) return retId ? md->idAt( i ) : i;
71 if ( md->count() > l.count() ) return retId ? md->idAt( md->count()-1 ) : md->count()-1;
76 void dumpMenu( QWidget* w, bool before )
78 QMenuData* md = dynamic_cast<QMenuData*>( w );
80 printf(">>> start dump menu (%s) >>>\n", before ? "before" : "after" );
81 for( int i = 0; i < md->count(); i++ )
82 printf("%d: %d: %s\n",i,md->idAt(i),md->text(md->idAt(i)).latin1() );
83 printf("<<< end dump menu (%s) <<<\n", before ? "before" : "after" );
88 Class: QtxActionMenuMgr::MenuAction
92 class QtxActionMenuMgr::MenuAction : public QtxAction
95 MenuAction( const QString&, const QString&, QObject*, const int = -1, const bool = false );
96 virtual ~MenuAction();
98 virtual bool addTo( QWidget* );
100 virtual bool removeFrom( QWidget* );
102 QPopupMenu* popup() const;
108 QMap<QWidget*,int> myIds;
113 Constructor for menu action
114 \param text - description text
115 \param menutext - menu text
116 \param parent - parent object
117 \param id - integer identificator of action
118 \param allowEmpty - if it is true, it makes possible to add this action with empty popup to menu
121 QtxActionMenuMgr::MenuAction::MenuAction( const QString& text,
122 const QString& menuText,
125 const bool allowEmpty )
126 : QtxAction( text, menuText, 0, parent ),
129 myEmptyEnabled( allowEmpty )
131 myPopup = new QPopupMenu();
135 Destructor: deletes internal popup
137 QtxActionMenuMgr::MenuAction::~MenuAction()
143 Adds action to widget, for example, to popup menu or menu bar
145 bool QtxActionMenuMgr::MenuAction::addTo( QWidget* w )
148 return false; // bad widget
150 if ( !w->inherits( "QPopupMenu" ) && !w->inherits( "QMenuBar" ) )
151 return false; // not allowed widget type
153 if ( myIds.find( w ) != myIds.end() )
154 return false; // already added
157 return false; // bad own popup menu
159 if ( !myEmptyEnabled && !myPopup->count() )
160 return false; // not allowed empty menu
162 if ( w->inherits( "QPopupMenu" ) ) {
163 QValueList<int> l = prepareIds( w );
165 if ( QtxAction::addTo( w ) && ( idx = getNewId( w, l, false ) ) != -1 ) {
166 QPopupMenu* pm = (QPopupMenu*)w;
167 myIds[ w ] = pm->idAt( idx );
169 pm->setId( idx, myId );
170 setPopup( pm, myId != -1 ? myId : myIds[ w ], myPopup );
173 else if ( w->inherits( "QMenuBar" ) ) {
174 QValueList<int> l = prepareIds( w );
176 if ( QtxAction::addTo( w ) && ( idx = getNewId( w, l, false ) ) != -1 ) {
177 QMenuBar* mb = (QMenuBar*)w;
178 myIds[ w ] = mb->idAt( idx );
180 mb->setId( idx, myId );
181 setPopup( mb, myId != -1 ? myId : myIds[ w ], myPopup );
191 Removes action from widget, for example, from popup menu or menu bar
193 bool QtxActionMenuMgr::MenuAction::removeFrom( QWidget* w )
196 return false; // bad widget
198 if ( !w->inherits( "QPopupMenu" ) && !w->inherits( "QMenuBar" ) )
199 return false; // not allowed widget type
201 if ( myIds.find( w ) == myIds.end() )
202 return false; // not yet added
204 if ( w->inherits( "QPopupMenu" ) ) {
206 QPopupMenu* pm = (QPopupMenu*)w;
207 int idx = pm->indexOf( myId );
208 if ( idx != -1 ) pm->setId( idx, myIds[ w ] );
211 return QtxAction::removeFrom( w );;
213 else if ( w->inherits( "QMenuBar" ) )
216 QMenuBar* mb = (QMenuBar*)w;
217 int idx = mb->indexOf( myId );
218 if ( idx != -1 ) mb->setId( idx, myIds[ w ] );
221 return QtxAction::removeFrom( w );
227 \return internal popup of action
229 QPopupMenu* QtxActionMenuMgr::MenuAction::popup() const
235 Class: QtxActionMenuMgr
238 QtxActionMenuMgr::QtxActionMenuMgr( QMainWindow* p )
240 myMenu( p ? p->menuBar() : 0 )
246 connect( myMenu, SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) );
247 #ifdef ENABLE_DYNAMIC_MENU
248 if ( myMenu->inherits( "QMenuBar" ) )
249 connect( myMenu, SIGNAL( highlighted( int ) ), this, SLOT( onHighlighted( int ) ) );
257 QtxActionMenuMgr::QtxActionMenuMgr( QWidget* mw, QObject* p )
265 connect( myMenu, SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) );
271 QtxActionMenuMgr::~QtxActionMenuMgr()
273 for ( NodeListIterator it( myRoot.children ); it.current() && myMenu; ++it )
275 QAction* a = itemAction( it.current()->id );
277 a = menuAction( it.current()->id );
280 a->removeFrom( myMenu );
283 for ( MenuMap::Iterator itr = myMenus.begin(); itr != myMenus.end(); ++itr )
288 \return whether menu item corresponding to action is visible
289 \param actId - identificator of action
290 \param place - identificator of some parent action
292 bool QtxActionMenuMgr::isVisible( const int actId, const int place ) const
294 MenuNode* node = find( actId, place );
295 return node && node->visible;
299 Sets visible state of action
300 \param actId - identificator of action
301 \param place - identificator of some parent action
302 \param v - visibility state
304 void QtxActionMenuMgr::setVisible( const int actId, const int place, const bool v )
306 MenuNode* node = find( actId, place );
312 Insert action as children menu item
313 \param id - identificator of action
314 \param menus - few names of parent menu items, separated by '|'. It means sequence of menu items,
315 for example "File|Edit" means File->Edit submenu. If submenu doesn't exist, it will be created.
316 \param group - group identificator
317 \param idx - index inside Qt menu
319 int QtxActionMenuMgr::insert( const int id, const QString& menus, const int group, const int idx )
321 return insert( id, QStringList::split( "|", menus ), group, idx );
325 Insert action as children menu item
327 \param menus - few names of parent menu items, separated by '|'. It means sequence of menu items,
328 for example "File|Edit" means File->Edit submenu. If submenu doesn't exist, it will be created.
329 \param group - group identificator
330 \param idx - index inside Qt menu
332 int QtxActionMenuMgr::insert( QAction* a, const QString& menus, const int group, const int idx )
334 return insert( a, QStringList::split( "|", menus ), group, idx );
338 Insert action as children menu item
339 \param id - identificator of action
340 \param menus - list of names of parent menu items, separated by |. It means sequence of menu items,
341 for example "File|Edit" means File->Edit submenu. If submenu doesn't exist, it will be created.
342 \param group - group identificator
343 \param idx - index inside Qt menu
345 int QtxActionMenuMgr::insert( const int id, const QStringList& menus, const int group, const int idx )
347 int pId = createMenu( menus, -1 );
351 return insert( id, pId, group, idx );
355 Insert action as children menu item
357 \param menus - list of names of parent menu items. It means sequence of menu items,
358 for example "File|Edit" means File->Edit submenu. If submenu doesn't exist, it will be created.
359 \param group - group identificator
360 \param idx - index inside Qt menu
362 int QtxActionMenuMgr::insert( QAction* a, const QStringList& menus, const int group, const int idx )
364 int pId = createMenu( menus, -1 );
368 return insert( a, pId, group, idx );
372 Insert action as children menu item
373 \param id - identificator of action
374 \param pId - identificator of action corresponding to parent menu item
375 \param group - group identificator
376 \param idx - index inside Qt menu
378 int QtxActionMenuMgr::insert( const int id, const int pId, const int group, const int idx )
383 MenuNode* pNode = pId == -1 ? &myRoot : find( pId );
387 MenuNode* node = new MenuNode( pNode );
392 pNode->children.append( node );
394 updateMenu( pNode, false );
400 Insert action as children menu item
402 \param pId - identificator of action corresponding to parent menu item
403 \param group - group identificator
404 \param idx - index inside Qt menu
406 int QtxActionMenuMgr::insert( QAction* a, const int pId, const int group, const int idx )
408 return insert( registerAction( a ), pId, group, idx );
412 Create and insert action as children menu item
413 \return identificator of inserted action
414 \param title - menu text of action
415 \param pId - identificator of action corresponding to parent menu item
416 \param group - group identificator
417 \param id - identificator of new action
418 \param idx - index inside Qt menu
419 \param allowEmpty - indicates, that it is possible to add this action with empty popup menu to other menu
421 int QtxActionMenuMgr::insert( const QString& title, const int pId, const int group, const int id, const int idx, const bool allowEmpty )
423 MenuNode* pNode = pId == -1 ? &myRoot : find( pId );
427 MenuNode* eNode = id == -1 ? 0 : find( id );
430 for ( NodeListIterator it( pNode->children ); it.current() && fid == -1; ++it )
432 if ( myMenus.contains( it.current()->id ) &&
433 clearTitle( myMenus[it.current()->id]->menuText() ) == clearTitle( title ) )
434 fid = it.current()->id;
440 int gid = (id == -1 || eNode ) ? generateId() : id;
442 MenuAction* ma = new MenuAction( clearTitle( title ), title, this, gid, allowEmpty );
443 #ifdef ENABLE_DYNAMIC_MENU
444 connect( ma->popup(), SIGNAL( highlighted( int ) ), this, SLOT( onHighlighted( int ) ) );
447 MenuNode* node = new MenuNode( pNode );
450 node->id = myMenus.insert( gid, ma ).key();
452 pNode->children.append( node );
454 updateMenu( pNode, false );
460 Create and insert action as children menu item
461 \return identificator of inserted action
462 \param title - menu text of action
463 \param menus - string list of parents' menu texts, separated by |
464 \param group - group identificator
465 \param id - identificator of new action
466 \param idx - index inside Qt menu
467 \param allowEmpty - indicates, that it is possible to add this action with empty popup menu to other menu
469 int QtxActionMenuMgr::insert( const QString& title, const QString& menus, const int group, const int id, const int idx, const bool allowEmpty )
471 return insert( title, QStringList::split( "|", menus ), group, id, idx, allowEmpty );
475 Create and insert action as children menu item
476 \return identificator of inserted action
477 \param title - menu text of action
478 \param menus - list of parents menu items
479 \param group - group identificator
480 \param id - identificator of new action
481 \param idx - index inside Qt menu
482 \param allowEmpty - indicates, that it is possible to add this action with empty popup menu to other menu
484 int QtxActionMenuMgr::insert( const QString& title, const QStringList& menus, const int group, const int id, const int idx, const bool allowEmpty )
486 int pId = createMenu( menus, -1 );
487 return insert( title, pId, group, id, idx, allowEmpty );
491 Create and append action as last children
492 \return identificator of inserted action
493 \param title - menu text of action
494 \param pId - id of action corresponding to parent menu item
495 \param group - group identificator
496 \param id - identificator of new action
497 \param allowEmpty - indicates, that it is possible to add this action with empty popup menu to other menu
499 int QtxActionMenuMgr::append( const QString& title, const int pId, const int group, const int id, const bool allowEmpty )
501 return insert( title, pId, group, id, allowEmpty );
505 Create and append action as last children
506 \return identificator of inserted action
507 \param id - identificator of existing action
508 \param pId - id of action corresponding to parent menu item
509 \param group - group identificator
511 int QtxActionMenuMgr::append( const int id, const int pId, const int group )
513 return insert( id, pId, group );
517 Create and append action as last children
518 \return identificator of inserted action
520 \param pId - id of action corresponding to parent menu item
521 \param group - group identificator
523 int QtxActionMenuMgr::append( QAction* a, const int pId, const int group )
525 return insert( a, pId, group );
529 Create and insert action as first children
530 \return identificator of inserted action
531 \param title - menu text of action
532 \param pId - id of action corresponding to parent menu item
533 \param group - group identificator
534 \param id - identificator of new action
535 \param allowEmpty - indicates, that it is possible to add this action with empty popup menu to other menu
537 int QtxActionMenuMgr::prepend( const QString& title, const int pId, const int group, const int id, const bool allowEmpty )
539 return insert( title, pId, group, id, 0, allowEmpty );
543 Create and insert action as last children
544 \return identificator of inserted action
545 \param id - identificator of existing action
546 \param pId - id of action corresponding to parent menu item
547 \param group - group identificator
549 int QtxActionMenuMgr::prepend( const int id, const int pId, const int group )
551 return insert( id, pId, group, 0 );
555 Create and insert action as last children
556 \return identificator of inserted action
558 \param pId - id of action corresponding to parent menu item
559 \param group - group identificator
561 int QtxActionMenuMgr::prepend( QAction* a, const int pId, const int group )
563 return insert( a, pId, group, 0 );
567 Removes menu item corresponding to action
568 \param id - identificator of action
570 void QtxActionMenuMgr::remove( const int id )
578 \param id - identificator of action
579 \param pId - identificator of action corresponding to parent menu item
580 \param group - group identificator
582 void QtxActionMenuMgr::remove( const int id, const int pId, const int group )
584 MenuNode* pNode = pId == -1 ? &myRoot : find( pId );
589 for ( NodeListIterator it( pNode->children ); it.current(); ++it )
591 if ( it.current()->id == id && ( it.current()->group == group || group == -1 ) )
592 delNodes.append( it.current() );
595 for ( NodeListIterator itr( delNodes ); itr.current(); ++itr )
596 pNode->children.remove( itr.current() );
598 updateMenu( pNode, false );
602 Shows menu item corresponding to action
603 \param id - identificator of action
605 void QtxActionMenuMgr::show( const int id )
607 setShown( id, true );
611 Hides menu item corresponding to action
612 \param id - identificator of action
614 void QtxActionMenuMgr::hide( const int id )
616 setShown( id, false );
620 \return shown status of menu item corresponding to action
621 \param id - identificator of action
623 bool QtxActionMenuMgr::isShown( const int id ) const
626 MenuNode* node = find( id );
633 Sets shown status of menu item corresponding to action
634 \param id - identificator of action
635 \param on - new shown status
637 void QtxActionMenuMgr::setShown( const int id, const bool on )
642 QMap<MenuNode*, int> updMap;
643 for ( NodeListIterator it( aNodes ); it.current(); ++it )
645 if ( it.current()->visible != on )
647 it.current()->visible = on;
648 updMap.insert( it.current()->parent, 0 );
652 for ( QMap<MenuNode*, int>::ConstIterator itr = updMap.begin(); itr != updMap.end(); ++itr )
653 updateMenu( itr.key(), false );
657 SLOT: called when corresponding menu is destroyed, clears internal pointer to menu
659 void QtxActionMenuMgr::onDestroyed( QObject* obj )
666 SLOT: called when menu item is highlighted
668 void QtxActionMenuMgr::onHighlighted( int id )
670 const QObject* snd = sender();
672 if ( myMenu && snd == myMenu )
675 for ( MenuMap::Iterator itr = myMenus.begin(); itr != myMenus.end(); ++itr ) {
676 if ( itr.data()->popup() && itr.data()->popup() == snd )
681 realId = findId( id, pid );
682 if ( realId != -1 ) {
683 bool updatesEnabled = isUpdatesEnabled();
684 setUpdatesEnabled( false );
685 emit menuHighlighted( pid, realId );
686 setUpdatesEnabled( updatesEnabled );
687 updateMenu( find( realId ) );
693 Assignes new menu with manager
696 void QtxActionMenuMgr::setWidget( QWidget* mw )
702 disconnect( myMenu, SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) );
707 connect( myMenu, SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) );
711 \return menu node by it's place description
712 \param actId - identificator of action
713 \param pId - identificator of action corresponding to start menu item
714 \param rec - recursive search
716 QtxActionMenuMgr::MenuNode* QtxActionMenuMgr::find( const int actId, const int pId, const bool rec ) const
718 return find( actId, find( pId ), rec );
722 \return menu node by it's place description
723 \param actId - identificator of action
724 \param startNode - start menu item
725 \param rec - recursive search
727 QtxActionMenuMgr::MenuNode* QtxActionMenuMgr::find( const int id, MenuNode* startNode, const bool rec ) const
730 MenuNode* start = startNode ? startNode : (MenuNode*)&myRoot;
731 for ( NodeListIterator it( start->children ); it.current() && !node; ++it )
733 if ( it.current()->id == id )
736 node = find( id, it.current(), rec );
743 \return true if at least one node is found
744 \param id - identificator of action
745 \param lst - list to be filled with found nodes
746 \param startNode - start menu item
748 bool QtxActionMenuMgr::find( const int id, NodeList& lst, MenuNode* startNode ) const
750 MenuNode* start = startNode ? startNode : (MenuNode*)&myRoot;
751 for ( NodeListIterator it( start->children ); it.current(); ++it )
753 if ( it.current()->id == id )
754 lst.prepend( it.current() );
756 find( id, lst, it.current() );
758 return !lst.isEmpty();
764 \param title - menu text of searched node
765 \param pId - id of action corresponding to start menu item
766 \param rec - recursive searching
768 QtxActionMenuMgr::MenuNode* QtxActionMenuMgr::find( const QString& title, const int pId, const bool rec ) const
770 return find( title, find( pId ), rec );
775 \return true if at least one node is found
776 \param title - menu text of node
777 \param lst - list to be filled with found nodes
778 \param startNode - start menu item
780 bool QtxActionMenuMgr::find( const QString& title, NodeList& lst, MenuNode* startNode ) const
782 MenuNode* start = startNode ? startNode : (MenuNode*)&myRoot;
783 for ( NodeListIterator it( start->children ); it.current(); ++it )
785 QAction* a = itemAction( it.current()->id );
787 a = menuAction( it.current()->id );
788 if ( a && clearTitle( a->menuText() ) == clearTitle( title ) )
789 lst.prepend( it.current() );
791 find( title, lst, it.current() );
793 return !lst.isEmpty();
799 \param title - menu text of searched node
800 \param startNode - start menu item
801 \param rec - recursive searching
803 QtxActionMenuMgr::MenuNode* QtxActionMenuMgr::find( const QString& title, MenuNode* startNode, const bool rec ) const
806 MenuNode* start = startNode ? startNode : (MenuNode*)&myRoot;
807 for ( NodeListIterator it( start->children ); it.current() && !node; ++it )
809 QAction* a = itemAction( it.current()->id );
811 a = menuAction( it.current()->id );
812 if ( a && clearTitle( a->menuText() ) == clearTitle( title ) )
815 node = find( title, it.current(), rec );
821 Find id among children
822 \return id (>0) if on success or -1 on fail
823 \param id - id to be searched
824 \param pid - id of parent, among children of that 'id' must be searched
826 int QtxActionMenuMgr::findId( const int id, const int pid ) const
828 MenuNode* start = pid != -1 ? find( pid ) : (MenuNode*)&myRoot;
830 for ( NodeListIterator it( start->children ); it.current(); ++it ) {
831 if ( it.current()->id == id ) return id;
839 \param id - id of child to be removed
840 \param startNode - parent menu item
842 void QtxActionMenuMgr::removeMenu( const int id, MenuNode* startNode )
844 MenuNode* start = startNode ? startNode : &myRoot;
845 for ( NodeListIterator it( start->children ); it.current(); ++it )
847 if ( it.current()->id == id )
848 start->children.remove( it.current() );
850 removeMenu( id, it.current() );
855 \return menu item action by id
856 \param id - id of action
858 QAction* QtxActionMenuMgr::itemAction( const int id ) const
864 \return menu action by id
865 \param id - id of action
867 QtxActionMenuMgr::MenuAction* QtxActionMenuMgr::menuAction( const int id ) const
871 if ( myMenus.contains( id ) )
878 Updates menu ( isUpdatesEnabled() must return true )
879 \param startNode - first menu item to be updated
880 \param rec - recursive update
881 \param updParent - update also parent item (without recursion)
882 \sa isUpdatesEnabled()
884 void QtxActionMenuMgr::updateMenu( MenuNode* startNode, const bool rec, const bool updParent )
886 if ( !isUpdatesEnabled() )
889 MenuNode* node = startNode ? startNode : &myRoot;
891 QWidget* mw = menuWidget( node );
895 bool filled = checkWidget( mw );
897 for ( NodeListIterator it1( node->children ); it1.current(); ++it1 )
899 QAction* a = itemAction( it1.current()->id );
901 a = menuAction( it1.current()->id );
906 /* VSR: commented to allow direct creating of menus by calling insertItem() methods
907 if ( mw->inherits( "QMenuBar" ) )
908 ((QMenuBar*)mw)->clear();
909 else if ( mw->inherits( "QPopupMenu" ) )
910 ((QPopupMenu*)mw)->clear();
912 QMap<int, NodeList> idMap;
913 for ( NodeListIterator it2( node->children ); it2.current(); ++it2 )
915 NodeList& lst = idMap[it2.current()->group];
916 int idx = it2.current()->idx;
917 if ( idx < 0 || idx >= lst.count() )
918 lst.append( it2.current() );
920 lst.insert( idx, it2.current() );
923 QIntList groups = idMap.keys();
929 for ( QIntList::const_iterator gIt = groups.begin(); gIt != groups.end(); ++gIt )
931 if ( !idMap.contains( *gIt ) )
934 const NodeList& lst = idMap[*gIt];
935 for ( NodeListIterator iter( lst ); iter.current(); ++iter )
937 MenuNode* par = iter.current()->parent;
938 if ( !isVisible( iter.current()->id, par ? par->id : -1 ) )
942 updateMenu( iter.current(), rec, false );
944 QAction* a = itemAction( iter.current()->id );
946 a = menuAction( iter.current()->id );
952 simplifySeparators( mw );
954 if ( updParent && node->parent && filled != checkWidget( mw ) )
955 updateMenu( node->parent, false );
959 Updates menu (virtual variant). To be redefined for custom activity on menu updating
961 void QtxActionMenuMgr::internalUpdate()
963 if ( isUpdatesEnabled() )
968 \return true if widget is non-empty menu
969 \param wid - widget to be checked
971 bool QtxActionMenuMgr::checkWidget( QWidget* wid ) const
977 if ( wid->inherits( "QPopupMenu" ) )
978 md = (QPopupMenu*)wid;
979 else if ( wid->inherits( "QMenuBar" ) )
982 return md ? md->count() : false;
986 \return popup of menu item
987 \param node - menu item
989 QWidget* QtxActionMenuMgr::menuWidget( MenuNode* node) const
991 if ( !node || node == &myRoot )
994 if ( !myMenus.contains( node->id ) || !myMenus[node->id] )
997 return myMenus[node->id]->popup();
1001 Removes excess separators of menu
1002 \param wid - menu to be processed
1004 void QtxActionMenuMgr::simplifySeparators( QWidget* wid )
1006 if ( wid && wid->inherits( "QPopupMenu" ) )
1007 Qtx::simplifySeparators( (QPopupMenu*)wid, false );
1011 Removes special symbols (&) from string
1012 \param txt - string to be processed
1013 \return clear variant of string
1015 QString QtxActionMenuMgr::clearTitle( const QString& txt ) const
1019 for ( int i = 0; i < (int)res.length(); i++ )
1021 if ( res.at( i ) == '&' )
1022 res.remove( i--, 1 );
1029 Creates and inserts many menu items
1030 \param lst - list of menu texts
1031 \param pId - id of action corresponding to parent menu item
1033 int QtxActionMenuMgr::createMenu( const QStringList& lst, const int pId )
1035 if ( lst.isEmpty() )
1038 QStringList sl( lst );
1040 QString title = sl.last().stripWhiteSpace();
1041 sl.remove( sl.fromLast() );
1043 int parentId = sl.isEmpty() ? pId : createMenu( sl, pId );
1045 return insert( title, parentId, -1 );
1049 Loads actions description from file
1050 \param fname - name of file
1051 \param r - reader of file
1052 \return true on success
1054 bool QtxActionMenuMgr::load( const QString& fname, QtxActionMgr::Reader& r )
1056 MenuCreator cr( &r, this );
1057 return r.read( fname, cr );
1061 \return true if item has such child
1062 \param title - menu text of child
1063 \param pid - id of action corresponding to item
1065 bool QtxActionMenuMgr::containsMenu( const QString& title, const int pid ) const
1067 return (bool)find( title, pid, false );
1071 \return true if item has such child
1072 \param id - id of action corresponding to child
1073 \param pid - id of action corresponding to item
1075 bool QtxActionMenuMgr::containsMenu( const int id, const int pid ) const
1077 return (bool)find( id, pid, false );
1083 \param r - menu reader
1084 \param mgr - menu manager
1086 QtxActionMenuMgr::MenuCreator::MenuCreator( QtxActionMgr::Reader* r,
1087 QtxActionMenuMgr* mgr )
1088 : QtxActionMgr::Creator( r ),
1096 QtxActionMenuMgr::MenuCreator::~MenuCreator()
1101 Appends new menu items
1102 \param tag - tag of item
1103 \param subMenu - it has submenu
1104 \param attr - list of attributes
1105 \param pId - id of action corresponding to parent item
1107 int QtxActionMenuMgr::MenuCreator::append( const QString& tag, const bool subMenu,
1108 const ItemAttributes& attr, const int pId )
1110 if( !myMgr || !reader() )
1113 QString label = reader()->option( "label", "label" ),
1114 id = reader()->option( "id", "id" ),
1115 pos = reader()->option( "pos", "pos" ),
1116 group = reader()->option( "group", "group" ),
1117 tooltip = reader()->option( "tooltip", "tooltip" ),
1118 sep = reader()->option( "separator", "separator" ),
1119 accel = reader()->option( "accel", "accel" ),
1120 icon = reader()->option( "icon", "icon" ),
1121 toggle = reader()->option( "toggle", "toggle" );
1123 int res = -1, actId = intValue( attr, id, -1 );
1126 res = myMgr->insert( strValue( attr, label ), pId, intValue( attr, group, 0 ), intValue( attr, pos, -1 ) );
1128 res = myMgr->insert( separator(), pId, intValue( attr, group, 0 ), intValue( attr, pos, -1 ) );
1131 QPixmap pix; QIconSet set;
1132 QString name = strValue( attr, icon );
1133 if( !name.isEmpty() && loadPixmap( name, pix ) )
1134 set = QIconSet( pix );
1136 QtxAction* newAct = new QtxAction( strValue( attr, tooltip ), set,
1137 strValue( attr, label ),
1138 QKeySequence( strValue( attr, accel ) ),
1140 newAct->setToolTip( strValue( attr, tooltip ) );
1141 QString toggleact = strValue( attr, toggle );
1142 newAct->setToggleAction( !toggleact.isEmpty() );
1143 newAct->setOn( toggleact.lower()=="true" );
1146 int aid = myMgr->registerAction( newAct, actId );
1147 res = myMgr->insert( aid, pId, intValue( attr, group, 0 ), intValue( attr, pos, -1 ) );