]> SALOME platform Git repositories - modules/gui.git/commitdiff
Salome HOME
Dynamic menus in Python:
authorvsr <vsr@opencascade.com>
Mon, 27 Feb 2006 13:38:44 +0000 (13:38 +0000)
committervsr <vsr@opencascade.com>
Mon, 27 Feb 2006 13:38:44 +0000 (13:38 +0000)
* enable empty menus
* watch for the menu highlighting
* set real id to menus

src/Qtx/QtxActionMenuMgr.cxx
src/Qtx/QtxActionMenuMgr.h

index 7782a7b57ccb9c64074a8e2df405c0ddf163afe7..58604de7bb90f5b8a34a726357eb03e75936f62e 100644 (file)
@@ -40,7 +40,7 @@
 class QtxActionMenuMgr::MenuAction : public QtxAction
 {
 public:
-  MenuAction( const QString&, const QString&, QObject* );
+  MenuAction( const QString&, const QString&, QObject*, const bool = false );
   virtual ~MenuAction();
 
   virtual bool addTo( QWidget* );
@@ -52,12 +52,17 @@ public:
 private:
   int          myId;
   QPopupMenu*  myPopup;
+  bool         myEmptyEnabled;
 };
 
-QtxActionMenuMgr::MenuAction::MenuAction( const QString& text, const QString& menuText, QObject* parent )
+QtxActionMenuMgr::MenuAction::MenuAction( const QString& text,
+                                         const QString& menuText,
+                                         QObject*       parent,
+                                         const bool     allowEmpty )
 : QtxAction( text, menuText, 0, parent ),
-myId( -1 ),
-myPopup( 0 )
+  myId( -1 ),
+  myPopup( 0 ),
+  myEmptyEnabled( allowEmpty )
 {
   myPopup = new QPopupMenu();
 }
@@ -75,6 +80,12 @@ bool QtxActionMenuMgr::MenuAction::addTo( QWidget* w )
   if ( !w->inherits( "QPopupMenu" ) && !w->inherits( "QMenuBar" ) )
     return false;
 
+  if ( !myPopup )
+    return false;
+
+  if ( !myEmptyEnabled && !myPopup->count() )
+    return false;
+
   if ( w->inherits( "QPopupMenu" ) && QAction::addTo( w ) )
   {
     QPopupMenu* pm = (QPopupMenu*)w;
@@ -126,8 +137,11 @@ myMenu( p ? p->menuBar() : 0 )
   myRoot.id = -1;
   myRoot.group = -1;
 
-  if ( myMenu )
+  if ( myMenu ) {
     connect( myMenu, SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) );
+    if ( myMenu->inherits( "QMenuBar" ) )
+      connect( myMenu, SIGNAL( highlighted( int ) ), this, SLOT( onHighlighted( int ) ) );
+  }
 }
 
 QtxActionMenuMgr::QtxActionMenuMgr( QWidget* mw, QObject* p )
@@ -209,12 +223,10 @@ int QtxActionMenuMgr::insert( const int id, const int pId, const int group, cons
 
   MenuNode* node = new MenuNode( pNode );
   node->id = id;
+  node->idx = idx;
   node->group = group;
 
-  if ( idx < 0 || idx >= (int)pNode->children.count() )
-    pNode->children.append( node );
-  else
-    pNode->children.insert( idx, node );
+  pNode->children.append( node );
 
   updateMenu( pNode, false );
 
@@ -226,53 +238,54 @@ int QtxActionMenuMgr::insert( QAction* a, const int pId, const int group, const
   return insert( registerAction( a ), pId, group, idx );
 }
 
-int QtxActionMenuMgr::insert( const QString& title, const int pId, const int group, const int idx )
+int QtxActionMenuMgr::insert( const QString& title, const int pId, const int group, const int id, const int idx, const bool allowEmpty )
 {
   MenuNode* pNode = pId == -1 ? &myRoot : find( pId );
   if ( !pNode )
     return -1;
 
-  int id = -1;
-  for ( NodeListIterator it( pNode->children ); it.current() && id == -1; ++it )
+  MenuNode* eNode = id == -1 ? 0 : find( id );
+
+  int fid = -1;
+  for ( NodeListIterator it( pNode->children ); it.current() && fid == -1; ++it )
   {
     if ( myMenus.contains( it.current()->id ) &&
          clearTitle( myMenus[it.current()->id]->menuText() ) == clearTitle( title ) )
-      id = it.current()->id;
+      fid = it.current()->id;
   }
 
-  if ( id != -1 )
-    return id;
+  if ( fid != -1 )
+    return fid;
 
-  MenuAction* ma = new MenuAction( clearTitle( title ), title, this );
+  MenuAction* ma = new MenuAction( clearTitle( title ), title, this, allowEmpty );
+  connect( ma->popup(), SIGNAL( highlighted( int ) ), this, SLOT( onHighlighted( int ) ) );
 
   MenuNode* node = new MenuNode( pNode );
   node->group = group;
-  node->id = myMenus.insert( generateId(), ma ).key();
+  node->idx = idx;
+  node->id = myMenus.insert( (id == -1 || eNode ) ? generateId() : id, ma ).key();
 
-  if ( idx < 0 || idx >= (int)pNode->children.count() )
-    pNode->children.append( node );
-  else
-    pNode->children.insert( idx, node );
+  pNode->children.append( node );
 
   updateMenu( pNode, false );
 
   return node->id;
 }
 
-int QtxActionMenuMgr::insert( const QString& title, const QString& menus, const int group, const int idx )
+int QtxActionMenuMgr::insert( const QString& title, const QString& menus, const int group, const int id, const int idx, const bool allowEmpty )
 {
-  return insert( title, QStringList::split( "|", menus ), group, idx );
+  return insert( title, QStringList::split( "|", menus ), group, id, idx, allowEmpty );
 }
 
-int QtxActionMenuMgr::insert( const QString& title, const QStringList& menus, const int group, const int idx )
+int QtxActionMenuMgr::insert( const QString& title, const QStringList& menus, const int group, const int id, const int idx, const bool allowEmpty )
 {
   int pId = createMenu( menus, -1 );
-  return insert( title, pId, group, idx );
+  return insert( title, pId, group, id, idx, allowEmpty );
 }
 
-int QtxActionMenuMgr::append( const QString& title, const int pId, const int group )
+int QtxActionMenuMgr::append( const QString& title, const int pId, const int group, const int id, const bool allowEmpty )
 {
-  return insert( title, pId, group );
+  return insert( title, pId, group, id, allowEmpty );
 }
 
 int QtxActionMenuMgr::append( const int id, const int pId, const int group )
@@ -285,9 +298,9 @@ int QtxActionMenuMgr::append( QAction* a, const int pId, const int group )
   return insert( a, pId, group );
 }
 
-int QtxActionMenuMgr::prepend( const QString& title, const int pId, const int group )
+int QtxActionMenuMgr::prepend( const QString& title, const int pId, const int group, const int id, const bool allowEmpty )
 {
-  return insert( title, pId, group, 0 );
+  return insert( title, pId, group, id, 0, allowEmpty );
 }
 
 int QtxActionMenuMgr::prepend( const int id, const int pId, const int group )
@@ -369,6 +382,25 @@ void QtxActionMenuMgr::onDestroyed( QObject* obj )
     myMenu = 0;
 }
 
+void QtxActionMenuMgr::onHighlighted( int id )
+{
+  const QObject* snd = sender();
+  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();
+    }
+  }
+  if ( pid ) {
+    realId = findId( id, pid );
+    if ( realId != -1 )
+      emit menuHighlighted( pid, realId );
+  }
+}
+
 void QtxActionMenuMgr::setWidget( QWidget* mw )
 {
   if ( myMenu == mw )
@@ -415,6 +447,57 @@ bool QtxActionMenuMgr::find( const int id, NodeList& lst, MenuNode* startNode )
   return !lst.isEmpty();
 }
 
+QtxActionMenuMgr::MenuNode* QtxActionMenuMgr::find( const QString& title, const int id, const int pId ) const
+{
+  return find( title, id, find( pId ) );
+}
+
+bool QtxActionMenuMgr::find( const QString& title, const int id, NodeList& lst, MenuNode* startNode ) const
+{
+  MenuNode* start = startNode ? startNode : (MenuNode*)&myRoot;
+  for ( NodeListIterator it( start->children ); it.current(); ++it )
+  {
+    QAction* a = itemAction( it.current()->id );
+    if ( !a )
+      a = menuAction( it.current()->id );
+    if ( a && clearTitle( a->text() ) == clearTitle( title ) &&
+        ( it.current()->id == id || id == -1 ) )
+      lst.prepend( it.current() );
+
+    find( title, id, lst, it.current() );
+  }
+  return !lst.isEmpty();
+}
+
+QtxActionMenuMgr::MenuNode* QtxActionMenuMgr::find( const QString& title, const int id, MenuNode* startNode ) const
+{
+  MenuNode* node = 0;
+  MenuNode* start = startNode ? startNode : (MenuNode*)&myRoot;
+  for ( NodeListIterator it( start->children ); it.current() && !node; ++it )
+  {
+    QAction* a = itemAction( it.current()->id );
+    if ( !a )
+      a = menuAction( it.current()->id );
+    if ( a && clearTitle( a->text() ) == clearTitle( title ) &&
+        ( it.current()->id == id || id == -1 ) )
+      node = it.current();
+    if ( !node )
+      node = find( title, id, it.current() );
+  }
+  return node;
+}
+
+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;
+    }
+  }
+  return -1;
+}
+
 void QtxActionMenuMgr::removeMenu( const int id, MenuNode* startNode )
 {
   MenuNode* start = startNode ? startNode : &myRoot;
@@ -465,23 +548,20 @@ void QtxActionMenuMgr::updateMenu( MenuNode* startNode, const bool rec, const bo
       a->removeFrom( mw );
   }
 
-  if ( node != &myRoot )
-  {
-    if ( mw->inherits( "QMenuBar" ) )
-      ((QMenuBar*)mw)->clear();
-    else if ( mw->inherits( "QPopupMenu" ) )
-      ((QPopupMenu*)mw)->clear();
-  }
+  if ( mw->inherits( "QMenuBar" ) )
+    ((QMenuBar*)mw)->clear();
+  else if ( mw->inherits( "QPopupMenu" ) )
+    ((QPopupMenu*)mw)->clear();
 
   QMap<int, NodeList> idMap;
   for ( NodeListIterator it2( node->children ); it2.current(); ++it2 )
   {
-    MenuNode* par = it2.current()->parent;
-    if ( isVisible( it2.current()->id, par ? par->id : -1 ) )
-    {
-      NodeList& lst = idMap[it2.current()->group];
+    NodeList& lst = idMap[it2.current()->group];
+    int idx = it2.current()->idx;
+    if ( idx < 0 || idx >= lst.count() )
       lst.append( it2.current() );
-    }
+    else
+      lst.insert( idx, it2.current() );
   }
 
   QIntList groups = idMap.keys();
@@ -498,17 +578,27 @@ void QtxActionMenuMgr::updateMenu( MenuNode* startNode, const bool rec, const bo
     const NodeList& lst = idMap[*gIt];
     for ( NodeListIterator iter( lst ); iter.current(); ++iter )
     {
+      MenuNode* par = iter.current()->parent;
+      if ( !isVisible( iter.current()->id, par ? par->id : -1 ) )
+       continue;
+
       if ( rec )
         updateMenu( iter.current(), rec, false );
 
       QAction* a = itemAction( iter.current()->id );
-      if ( a )
-        a->addTo( mw );
-      else
-      {
-        MenuAction* ma = menuAction( iter.current()->id );
-        if ( ma && ma->popup() && ma->popup()->count() )
-          ma->addTo( mw );
+      if ( !a )
+        a = menuAction( iter.current()->id );
+      if ( a ) {
+       QMenuData* md = dynamic_cast<QMenuData*>( mw );
+       int cnt = 0;
+       if ( md ) cnt = md->count();
+       a->addTo( mw );
+       if ( md && md->count() - cnt == 1 ) { //&& iter.current()->id > 0
+         int lid = md->idAt( cnt ); 
+         QMenuItem* mi = md->findItem( lid );
+         if ( mi && !mi->isSeparator() )
+           md->setId( cnt, iter.current()->id );
+       }
       }
     }
   }
@@ -590,6 +680,15 @@ bool QtxActionMenuMgr::load( const QString& fname, QtxActionMgr::Reader& r )
   return r.read( fname, cr );
 }
 
+bool QtxActionMenuMgr::contains( const QString& title, const int id, const int pid )
+{
+  return (bool)find( title, id, pid );
+}
+
+bool QtxActionMenuMgr::contains( const int id, const int pid )
+{
+  return (bool)find( id, pid );
+}
 
 /*!
        Class: QtxActionMenuMgr::MenuCreator
index 89b81aa89a8b770a44973cfe756e902656a0d99d..77470d5be4e7fe5c89325cb528b06c896d5faa77 100644 (file)
@@ -51,6 +51,7 @@ class QTX_EXPORT QtxActionMenuMgr : public QtxActionMgr
     MenuNode( MenuNode* p ) : parent( p ), visible( true ) { children.setAutoDelete( true ); };
 
     int       id;
+    int       idx;
     int       group;
     MenuNode* parent;
     bool      visible;
@@ -79,17 +80,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 );
-  int          insert( const QString&, const QStringList&, const int, const int = -1 );
-  virtual int  insert( const QString&, 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          append( const int, const int, const int );
   int          append( QAction*, const int, const int );
-  int          append( const QString&, const int, const int );
+  int          append( const QString&, const int, const int, const int = -1, const bool = false );
 
   int          prepend( const int, const int, const int );
   int          prepend( QAction*, const int, const int );
-  int          prepend( const QString&, const int, const int );
+  int          prepend( const QString&, const int, const int, const int = -1, const bool = false );
 
   void         remove( const int );
   void         remove( const int, const int, const int = -1 );
@@ -102,14 +103,26 @@ public:
 
   virtual bool load( const QString&, QtxActionMgr::Reader& );
 
+  bool         contains( const QString&, const int, const int );
+  bool         contains( const int, const int );
+
+
 private slots:
   void         onDestroyed( QObject* );
+  void         onHighlighted( int );
+
+signals:
+  void         menuHighlighted( int, int );
 
 protected:
   void         setWidget( QWidget* );
   MenuNode*    find( const int, const int ) const;
   MenuNode*    find( const int, MenuNode* = 0 ) const;
   bool         find( const int, NodeList&, MenuNode* = 0 ) const;
+  MenuNode*    find( const QString&, const int, const int ) const;
+  MenuNode*    find( const QString&, const int, MenuNode* = 0 ) const;
+  bool         find( const QString&, const int, NodeList&, MenuNode* = 0 ) const;
+  int          findId( const int, const int = -1 ) const;
 
   void         removeMenu( const int, MenuNode* );