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* );
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();
}
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;
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 )
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 );
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 )
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 )
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 )
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;
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();
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 );
+ }
}
}
}
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
MenuNode( MenuNode* p ) : parent( p ), visible( true ) { children.setAutoDelete( true ); };
int id;
+ int idx;
int group;
MenuNode* parent;
bool visible;
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 );
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* );