int idx; //!< menu node index
int group; //!< menu group ID
bool visible; //!< visibility status
+ int emptyEnabled; //!< enable empty menu flag
NodeList children; //!< children menu nodes list
};
\internal
*/
QtxActionMenuMgr::MenuNode::MenuNode()
-: parent( 0 ), id( -1 ), idx( -1 ), group( -1 ), visible( true )
+ : parent( 0 ), id( -1 ), idx( -1 ), group( -1 ), visible( true ), emptyEnabled( 0 )
{
}
const int _id,
const int _idx,
const int _group )
-: parent( p ), id( _id ), idx( _idx ), group( _group ), visible( true )
+: parent( p ), id( _id ), idx( _idx ), group( _group ), visible( true ), emptyEnabled( 0 )
{
if ( p )
p->children.append( this );
bool filled = checkWidget( mw );
- for ( NodeList::iterator it1 = node->children.begin(); it1 != node->children.end(); ++it1 )
+ // first remove all own actions and collect foreign ones
+ QMap< QAction*, QList<QAction*> > foreign;
+ QAction* a;
+ QAction* preva = 0;
+ QListIterator<QAction*> ait( mw->actions() ); ait.toBack();
+ while ( ait.hasPrevious() )
{
- QAction* a = itemAction( (*it1)->id );
- if ( !a )
- a = menuAction( (*it1)->id );
-
- mw->removeAction( a );
-// if ( a )
-// a->removeFrom( mw );
+ a = ait.previous();
+ if ( ownAction( a, node ) )
+ {
+ preva = a;
+ mw->removeAction( a ); // remove own actions
+ }
+ else
+ {
+ foreign[preva].prepend(a); // do not yet remove foreign actions
+ }
}
+ // now only foreign actions should stay in the menu, thus remove them also
+ QMap< QAction*, QList<QAction*> >::Iterator formapit;
+ for( formapit = foreign.begin(); formapit != foreign.end(); ++formapit )
+ {
+ QMutableListIterator<QAction*> foralit( formapit.value() );
+ while ( foralit.hasNext() )
+ {
+ a = foralit.next();
+ if ( !mw->actions().contains( a ) )
+ foralit.remove();
+ }
+ }
+ QList<QAction*> alist = mw->actions();
+ foreach( a, alist ) mw->removeAction( a );
+ // collect all registered menus by group id
QMap<int, NodeList> idMap;
for ( NodeList::iterator it2 = node->children.begin(); it2 != node->children.end(); ++it2 )
{
groups.removeAll( -1 );
groups.append( -1 );
+ // rebuild menu: 1. add all registered actions
for ( QIntList::const_iterator gIt = groups.begin(); gIt != groups.end(); ++gIt )
{
if ( !idMap.contains( *gIt ) )
for ( NodeList::const_iterator iter = lst.begin(); iter != lst.end(); ++iter )
{
MenuNode* node = *iter;
+ if ( !node ) continue;
if ( rec )
updateMenu( node, rec, false );
isMenu = true;
a = menuAction( node->id );
}
+ if ( !a ) continue;
- if ( !isMenu || !a->menu()->isEmpty() )
+ if ( !isMenu || !a->menu()->isEmpty() || node->emptyEnabled > 0 )
mw->addAction( a );
}
}
+ // rebuild menu: 2. insert back all foreign actions
+ for( formapit = foreign.begin(); formapit != foreign.end(); ++formapit ) {
+ preva = formapit.key();
+ foreach( a, formapit.value() )
+ mw->insertAction( preva, a );
+ }
+
+ // remove extra separators
simplifySeparators( mw );
+ // update parent menu if necessary
if ( updParent && node->parent && filled != checkWidget( mw ) )
updateMenu( node->parent, false );
}
myUpdateIds.clear();
}
+/*!
+ \brief Check if action belongs to the menu manager
+ \internal
+ \param a action being checked
+ \param node parent menu node
+ \return \c true if action belongs to the menu \a node
+*/
+bool QtxActionMenuMgr::ownAction( QAction* a, MenuNode* node ) const
+{
+ for ( NodeList::const_iterator iter = node->children.begin(); iter != node->children.end(); ++iter )
+ {
+ QAction* mya = itemAction( (*iter)->id );
+ if ( !mya ) mya = menuAction( (*iter)->id );
+ if ( mya && mya == a ) return true;
+ }
+ return false;
+}
+
/*!
\brief Check if menu widget has any actions.
\param wid widget to be checked
return m;
}
+/*!
+ \brief Get menu by the title.
+ \param title menu text
+ \param pid parent menu item ID (to start search)
+ \param rec if \c true, perform recursive update
+ \return menu pointer or 0 if menu is not found
+*/
+QMenu* QtxActionMenuMgr::findMenu( const QString& title, const int pid, const bool rec ) const
+{
+ QMenu* m = 0;
+ MenuNode* node = find( title, pid, rec );
+ if ( node )
+ {
+ QAction* a = menuAction( node->id );
+ if ( a )
+ m = a->menu();
+ }
+ return m;
+}
+
+/*!
+ \brief Check if empty menu is enabled
+ \param id menu item ID
+ \return \c true if empty menu is enabled
+*/
+bool QtxActionMenuMgr::isEmptyEnabled( const int id ) const
+{
+ MenuNode* node = find( id );
+ if ( node && menuAction( id ) )
+ return node->emptyEnabled > 0;
+
+ return false;
+}
+
+/*!
+ \brief Enable/disable empty menu
+ \param id menu item ID
+ \param enable if \c true, empty menu will be enabled, otherwise empty menu will be disabled
+*/
+void QtxActionMenuMgr::setEmptyEnabled( const int id, const bool enable )
+{
+ MenuNode* node = find( id );
+ if ( node && menuAction( id ) ) {
+ int old = node->emptyEnabled;
+ node->emptyEnabled += enable ? 1 : -1;
+ if ( old <= 0 && enable || old > 0 && !enable ) // update menu only if enabled state has been changed
+ updateMenu( node, true, true );
+ }
+}
+
/*!
\brief Perform delayed menu update.
\param id menu item ID
const QString& context,
const QString& parent,
const QString& object );
+ void activateMenus( bool );
protected:
void createToolBar ( QDomNode& parentNode );
private:
SALOME_PYQT_Module* myModule;
QDomDocument myDoc;
- QStringList myMenuItems;
+ QList<int> myMenuItems;
};
//
return false;
// activate menus, toolbars, etc
+ if ( myXmlHandler ) myXmlHandler->activateMenus( true );
setMenuShown( true );
setToolShown( true );
disconnect( getApp(), SIGNAL( preferenceChanged( const QString&, const QString&, const QString& ) ),
this, SLOT( preferenceChanged( const QString&, const QString&, const QString& ) ) );
- // deactivate menus, toolbars, etc
- setMenuShown( false );
- setToolShown( false );
-
// perform internal deactivation
// DeactivateReq: request class for internal deactivate() operation
class DeactivateReq : public PyInterp_LockRequest
// post request
PyInterp_Dispatcher::Get()->Exec( new DeactivateReq( myInterp, theStudy, this ) );
+ // deactivate menus, toolbars, etc
+ if ( myXmlHandler ) myXmlHandler->activateMenus( false );
+ setMenuShown( false );
+ setToolShown( false );
+
// call base implementation
return SalomeApp_Module::deactivateModule( theStudy );
}
// detect return status
myLastActivateStatus = PyObject_IsTrue( res1 );
}
- }
+ }
}
/*!
}
}
+/*!
+ \brief Activate menus
+ \internal
+ \param enable if \c true menus are activated, otherwise menus are deactivated
+*/
+void SALOME_PYQT_Module::XmlHandler::activateMenus( bool enable )
+{
+ if ( !myModule )
+ return;
+
+ QtxActionMenuMgr* mgr = myModule->menuMgr();
+ int id;
+ foreach( id, myMenuItems ) mgr->setEmptyEnabled( id, enable );
+}
+
/*!
\brief Create main menu item and insert actions to it.
\internal
{
if ( !myModule || parentNode.isNull() )
return;
-
+
QDomElement parentElement = parentNode.toElement();
if ( !parentElement.isNull() ) {
QString plabel = attribute( parentElement, "label-id" );
pid, // ID
group, // group ID
ppos ); // position
+ myMenuItems.append( menuId );
QDomNode node = parentNode.firstChild();
while ( !node.isNull() ) {
if ( node.isElement() ) {
SalomeApp_Application* anApp = getApplication();
if ( anApp && !myMenuName.isEmpty() ) {
QtxActionMenuMgr* mgr = anApp->desktop()->menuMgr();
- SALOME_PYQT_Module* module = getActiveModule();
- int id = -1;
- if ( module )
- id = module->createMenu( myMenuName, -1, -1, -1, -1 );
- else
- id = mgr->insert( myMenuName, -1, -1, -1, -1 );
- myResult = mgr->findMenu( id );
+ myResult = mgr->findMenu( myMenuName, -1, false ); // search only top menu
}
}
};
+
+static QString getMenuName( const QString& menuId )
+{
+ QStringList contexts;
+ contexts << "SalomeApp_Application" << "LightApp_Application" << "STD_TabDesktop" <<
+ "STD_MDIDesktop" << "STD_Application" << "SUIT_Application" << "";
+ QString menuName = menuId;
+ for ( int i = 0; i < contexts.count() && menuName == menuId; i++ )
+ menuName = QApplication::translate( contexts[i].toLatin1().data(), menuId.toLatin1().data() );
+ return menuName;
+}
+
QMenu* SalomePyQt::getPopupMenu( const MenuName menu )
{
QString menuName;
switch( menu ) {
case File:
- menuName = QApplication::translate( "", "MEN_DESK_FILE" ); break;
+ menuName = getMenuName( "MEN_DESK_FILE" ); break;
case View:
- menuName = QApplication::translate( "", "MEN_DESK_VIEW" ); break;
+ menuName = getMenuName( "MEN_DESK_VIEW" ); break;
case Edit:
- menuName = QApplication::translate( "", "MEN_DESK_EDIT" ); break;
+ menuName = getMenuName( "MEN_DESK_EDIT" ); break;
case Preferences:
- menuName = QApplication::translate( "", "MEN_DESK_PREFERENCES" ); break;
+ menuName = getMenuName( "MEN_DESK_PREFERENCES" ); break;
case Tools:
- menuName = QApplication::translate( "", "MEN_DESK_TOOLS" ); break;
+ menuName = getMenuName( "MEN_DESK_TOOLS" ); break;
case Window:
- menuName = QApplication::translate( "", "MEN_DESK_WINDOW" ); break;
+ menuName = getMenuName( "MEN_DESK_WINDOW" ); break;
case Help:
- menuName = QApplication::translate( "", "MEN_DESK_HELP" ); break;
+ menuName = getMenuName( "MEN_DESK_HELP" ); break;
}
return ProcessEvent( new TGetPopupMenuEvent( menuName ) );
}