1 // Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File: QtxActionToolMgr.cxx
23 // Author: Alexander SOLOVYOV, Sergey TELKOV
25 #include "QtxActionToolMgr.h"
27 #include "QtxAction.h"
28 #include "QtxToolBar.h"
30 #include <QMainWindow>
33 \class QtxActionToolMgr::ToolNode
34 \brief Represents a toolbutton inside toolbar structure.
39 \fn QtxActionToolMgr::ToolNode::ToolNode()
41 \brief Default constructor.
45 \fn QtxActionToolMgr::ToolNode::ToolNode( const int _id )
48 \param _id toolbar node ID
52 \class QtxActionToolMgr
53 \brief Toolbar actions manager.
55 Toolbar manager allows using of set of action for automatic generating of
56 application toolbars and dynamic update of toolbars contents.
58 Use insert(), append() and remove() methods to create toolbar and add actions to it.
59 Methods show(), hide() allow displaying/erasing of specified toolbar items.
61 Toolbar manager automatically optimizes toolbars by removing extra separators, etc.
66 \param p parent main window
68 QtxActionToolMgr::QtxActionToolMgr( QMainWindow* p )
77 QtxActionToolMgr::~QtxActionToolMgr()
82 \brief Get parent main window.
83 \return main window pointer
85 QMainWindow* QtxActionToolMgr::mainWindow() const
91 \brief Create toolbar and assign \a id to it.
93 If \a tid is less than 0, the identifier is generated automatically.
94 If toolbar with given \a tid is already registered, the toolbar will not be created.
96 \param title toolbar title
97 \param tid requested toolbar ID
98 \param mw parent main window; if it is null, the tool manager's main window is used
99 \return id of created/found toolbar
101 int QtxActionToolMgr::createToolBar( const QString& title, const int tid, QMainWindow* mw )
103 static int _toolBarId = -1;
106 for ( ToolBarMap::ConstIterator it = myToolBars.begin(); it != myToolBars.end() && tbId == -1; ++it )
108 if( it.value().toolBar->windowTitle().toLower() == title.toLower() &&
109 ( !mw || it.value().toolBar->parent()==mw ) )
116 QMainWindow* tbw = mw ? mw : mainWindow();
117 QToolBar* tb = find( title, tbw );
119 tbId = tid < 0 ? --_toolBarId : tid;
121 myToolBars.insert( tbId, ToolBarInfo() );
122 ToolBarInfo& tInfo = myToolBars[tbId];
126 tb = new QtxToolBar( true, tbw );
127 //mainWindow()->addToolBar( tb );
128 tb->setWindowTitle( title );
129 tb->setObjectName( title );
130 tb->setToolTip( title );
134 connect( tInfo.toolBar, SIGNAL( destroyed() ), this, SLOT( onToolBarDestroyed() ) );
140 \brief Search toolbar with given \a title owned by main window \mw.
141 \param title toolbar title
142 \param mw main window
143 \return toolbar or 0 if it is not found
145 QToolBar* QtxActionToolMgr::find( const QString& title, QMainWindow* mw ) const
150 QString pattern = title.toLower();
153 QList<QToolBar*> toolbars = qFindChildren<QToolBar*>( mw );
154 for ( QList<QToolBar*>::iterator it = toolbars.begin(); it != toolbars.end() && !res; ++it )
156 if ( (*it)->windowTitle().toLower() == pattern )
163 \brief Remove toolbar.
164 \param tid toolbar ID
166 void QtxActionToolMgr::removeToolBar( const int tid )
168 if ( !myToolBars.contains( tid ) )
171 delete myToolBars[tid].toolBar;
172 myToolBars.remove( tid );
176 \brief Remove toolbar.
177 \param title toolbar title
179 void QtxActionToolMgr::removeToolBar( const QString& title )
181 removeToolBar( find( title ) );
185 \brief Insert action into toolbar.
187 \param tid toolbar ID
188 \param idx action index in the toolbar (if < 0, action is appended to the end)
191 int QtxActionToolMgr::insert( const int id, const int tid, const int idx )
193 if ( !contains( id ) || !hasToolBar( tid ) )
196 if ( containsAction( id, tid ) )
201 NodeList& list = myToolBars[tid].nodes;
202 int index = idx < 0 ? list.count() : qMin( idx, (int)list.count() );
203 list.insert( index, node );
204 triggerUpdate( tid );
210 \brief Insert action into toolbar.
212 \param tid toolbar ID
213 \param idx action index in the toolbar (if < 0, action is appended to the end)
216 int QtxActionToolMgr::insert( QAction* a, const int tid, const int idx )
218 return insert( registerAction( a ), tid, idx );
222 \brief Insert action into toolbar.
224 \param title toolbar title
225 \param idx action index in the toolbar (if < 0, action is appended to the end)
228 int QtxActionToolMgr::insert( const int id, const QString& title, const int idx )
230 return insert( id, createToolBar( title ), idx );
234 \brief Insert action into toolbar.
236 \param title toolbar title
237 \param idx action index in the toolbar (if < 0, action is appended to the end)
240 int QtxActionToolMgr::insert( QAction* a, const QString& title, const int idx )
242 return insert( registerAction( a ), createToolBar( title ), idx );
246 \brief Append action to the end of toolbar.
248 \param tid toolbar ID
251 int QtxActionToolMgr::append( const int id, const int tid )
253 return insert( id, tid );
257 \brief Append action to the end of toolbar.
259 \param tid toolbar ID
262 int QtxActionToolMgr::append( QAction* a, const int tid )
264 return insert( a, tid );
268 \brief Append action to the end of toolbar.
270 \param title toolbar title
273 int QtxActionToolMgr::append( const int id, const QString& title )
275 return insert( id, title );
279 \brief Append action to the end of toolbar.
281 \param title toolbar title
284 int QtxActionToolMgr::append( QAction* a, const QString& title )
286 return insert( a, title );
290 \brief Insert action to the beginning of toolbar.
292 \param tid toolbar ID
295 int QtxActionToolMgr::prepend( const int id, const int tid )
297 return insert( id, tid, 0 );
301 \brief Insert action to the beginning of toolbar.
303 \param tid toolbar ID
306 int QtxActionToolMgr::prepend( QAction* a, const int tid )
308 return insert( a, tid, 0 );
312 \brief Insert action to the beginning of toolbar.
314 \param title toolbar title
317 int QtxActionToolMgr::prepend( const int id, const QString& title )
319 return insert( id, title, 0 );
323 \brief Insert action to the beginning of toolbar.
325 \param title toolbar title
328 int QtxActionToolMgr::prepend( QAction* a, const QString& title )
330 return insert( a, title, 0 );
334 \brief Remove action from toolbar.
336 \param tid toolbar ID
338 void QtxActionToolMgr::remove( const int id, const int tid )
340 if ( !myToolBars.contains( tid ) )
344 const NodeList& nodes = myToolBars[tid].nodes;
345 for ( NodeList::const_iterator it = nodes.begin(); it != nodes.end(); ++it )
347 if ( (*it).id != id )
348 newList.append( *it );
351 myToolBars[tid].nodes = newList;
353 triggerUpdate( tid );
357 \brief Remove action from toolbar.
359 \param title toolbar title
361 void QtxActionToolMgr::remove( const int id, const QString& title )
363 remove( id, find( title ) );
367 \brief Get toolbar by given \a tid.
368 \param tid toolbar ID
369 \return toolbar or 0 if it is not found
371 QToolBar* QtxActionToolMgr::toolBar( const int tid ) const
374 if ( myToolBars.contains( tid ) )
375 tb = myToolBars[tid].toolBar;
380 \brief Get toolbar by given \a title.
381 \param title toolbar title
382 \return toolbar or 0 if it is not found
384 QToolBar* QtxActionToolMgr::toolBar( const QString& title ) const
386 return toolBar( find( title ) );
390 \brief Check if toolbar with given \a id already registered.
391 \param tid toolbar ID
392 \return \c true if toolbar is registered in the toolbar manager
394 bool QtxActionToolMgr::hasToolBar( const int tid ) const
396 return myToolBars.contains( tid );
400 \brief Check if toolbar with given \a id already registered.
401 \param title toolbar title
402 \return \c true if toolbar is registered in the toolbar manager
404 bool QtxActionToolMgr::hasToolBar( const QString& title ) const
406 return find( title ) != -1;
410 \brief Check if toolbar contains given action.
412 \param tid toolbar ID
413 \return \c true if toolbar contains action
415 bool QtxActionToolMgr::containsAction( const int id, const int tid ) const
417 for ( ToolBarMap::ConstIterator it = myToolBars.begin(); it != myToolBars.end(); ++it )
419 if ( tid == -1 || it.key() == tid )
421 const NodeList& list = it.value().nodes;
422 for ( NodeList::const_iterator nit = list.begin(); nit != list.end(); ++nit )
423 if ( (*nit).id == id )
431 \brief Called when toolbar is destroyed.
433 Clears internal pointer to the toolbar to disable crashes.
435 void QtxActionToolMgr::onToolBarDestroyed()
437 myToolBars.remove( find( (QToolBar*)sender() ) );
441 \brief Search toolbar by given \a name.
442 \param title toolbar title
443 \return toolbar ID or -1 if it is not found
445 int QtxActionToolMgr::find( const QString& title ) const
448 for ( ToolBarMap::ConstIterator it = myToolBars.begin(); it != myToolBars.end() && id == -1; ++it )
450 if ( it.value().toolBar->windowTitle() == title )
457 \brief Get toolbar identifier.
459 \return toolbar ID or -1 if toolbar is not registered
461 int QtxActionToolMgr::find( QToolBar* tb ) const
464 for ( ToolBarMap::ConstIterator it = myToolBars.begin(); it != myToolBars.end() && id == -1; ++it )
466 if ( it.value().toolBar == tb )
473 \brief Update toolbar.
474 \param tid toolbar ID
476 void QtxActionToolMgr::updateToolBar( const int tid )
478 if ( !isUpdatesEnabled() )
481 if ( !myToolBars.contains( tid ) )
484 QToolBar* tb = myToolBars[tid].toolBar;
485 const NodeList& list = myToolBars[tid].nodes;
487 for ( NodeList::const_iterator it = list.begin(); it != list.end(); ++it )
489 QAction* a = action( (*it).id );
490 tb->removeAction( a );
492 // a->removeFrom( tb );
497 for ( NodeList::const_iterator itr = list.begin(); itr != list.end(); ++itr )
499 if ( !isVisible( (*itr).id, tid ) )
502 QAction* a = action( (*itr).id );
508 simplifySeparators( tb );
511 if ( !tb->isVisible() )
517 \brief Update all registered toolbars.
519 void QtxActionToolMgr::internalUpdate()
521 if ( !isUpdatesEnabled() )
524 for ( ToolBarMap::ConstIterator it1 = myToolBars.begin(); it1 != myToolBars.end(); ++it1 )
525 updateToolBar( it1.key() );
531 \brief Remove extra separators from the toolbar.
534 void QtxActionToolMgr::simplifySeparators( QToolBar* tb )
536 Qtx::simplifySeparators( tb );
540 \brief Show action (in all toolbars).
543 void QtxActionToolMgr::show( const int id )
545 setShown( id, true );
549 \brief Hide action (in all toolbars).
552 void QtxActionToolMgr::hide( const int id )
554 setShown( id, false );
558 \brief Set visibility status for toolbar action with given \a id.
560 \param on new visibility status
562 void QtxActionToolMgr::setShown( const int id, const bool on )
564 for ( ToolBarMap::Iterator it = myToolBars.begin(); it != myToolBars.end(); ++it )
565 setVisible( id, it.key(), on );
569 \brief Get visibility status for toolbar action with given \a id.
571 \return \c true if action is shown in all toolbars
573 bool QtxActionToolMgr::isShown( const int id ) const
575 QList<const ToolNode*> nodes;
576 for ( ToolBarMap::ConstIterator it = myToolBars.begin(); it != myToolBars.end(); ++it )
578 const NodeList& nl = it.value().nodes;
579 for ( NodeList::const_iterator itr = nl.begin(); itr != nl.end(); ++itr )
581 const ToolNode& node = *itr;
583 nodes.append( &node );
587 if ( nodes.isEmpty() )
591 for ( QList<const ToolNode*>::iterator itr = nodes.begin(); itr != nodes.end() && vis; ++itr )
592 vis = (*itr)->visible;
598 \brief Check if an action with given \a id is visible in the toolbar \a tid.
600 \param tid toolbar ID
601 \return \c true if action is shown in the toolbar
603 bool QtxActionToolMgr::isVisible( const int id, const int tid ) const
605 if ( !myToolBars.contains( tid ) )
609 const ToolBarInfo& inf = myToolBars[tid];
610 for ( NodeList::const_iterator it = inf.nodes.begin(); it != inf.nodes.end() && !vis; ++it )
612 const ToolNode& node = *it;
621 \brief Show/hide action with given \a id in the toolbar \a tid.
623 \param tid toolbar ID
624 \param on new visibility status
626 void QtxActionToolMgr::setVisible( const int id, const int tid, const bool on )
628 if ( !myToolBars.contains( tid ) )
631 bool changed = false;
632 NodeList& lst = myToolBars[tid].nodes;
633 for ( NodeList::iterator it = lst.begin(); it != lst.end(); ++it )
635 ToolNode& node = *it;
638 changed = changed || node.visible != on;
644 triggerUpdate( tid );
648 \brief Load toolbar contents from the file.
649 \param fname file name
650 \param r actions reader
651 \return \c true on success and \c false on error
653 bool QtxActionToolMgr::load( const QString& fname, QtxActionMgr::Reader& r )
655 ToolCreator cr( &r, this );
656 return r.read( fname, cr );
660 \brief Called when delayed content update is performed.
662 Customizes the content update operation.
664 void QtxActionToolMgr::updateContent()
666 if ( !isUpdatesEnabled() )
669 for ( QMap<int,int>::const_iterator it = myUpdateIds.constBegin(); it != myUpdateIds.constEnd(); ++it )
670 updateToolBar( it.key() );
675 \brief Perform delayed toolbar update.
676 \param tid toolbar ID
678 void QtxActionToolMgr::triggerUpdate( const int tid )
680 myUpdateIds.insert( tid, 0 );
681 QtxActionMgr::triggerUpdate();
686 \class QtxActionToolMgr::ToolCreator
687 \brief Toolbars creator.
689 Used by Reader to create actions by reading descriptions from the file,
690 create toolbars and fill in the toolbara with the actions.
695 \param r actions reader
696 \param mgr toolbar manager
698 QtxActionToolMgr::ToolCreator::ToolCreator( QtxActionMgr::Reader* r,
699 QtxActionToolMgr* mgr )
700 : QtxActionMgr::Creator( r ),
708 QtxActionToolMgr::ToolCreator::~ToolCreator()
713 \brief Create and append to the action manager a new toolbar or toolbar action.
714 \param tag item tag name
715 \param subMenu \c true if this item is submenu (not used)
716 \param attr attributes map
717 \param tid toolbar ID
718 \return toolbar or toolbar action ID
720 int QtxActionToolMgr::ToolCreator::append( const QString& tag, const bool /*subMenu*/,
721 const ItemAttributes& attr, const int tid )
723 if( !myMgr || !reader() )
726 QString label = reader()->option( "label", "label" ),
727 id = reader()->option( "id", "id" ),
728 pos = reader()->option( "pos", "pos" ),
729 group = reader()->option( "group", "group" ),
730 tooltip = reader()->option( "tooltip", "tooltip" ),
731 sep = reader()->option( "separator", "separator" ),
732 accel = reader()->option( "accel", "accel" ),
733 icon = reader()->option( "icon", "icon" ),
734 toggle = reader()->option( "toggle", "toggle" );
736 int res = -1, actId = intValue( attr, id, -1 );
738 res = myMgr->createToolBar( strValue( attr, label ), intValue( attr, id, -1 ) );
740 res = myMgr->insert( separator(), tid, intValue( attr, pos, -1 ) );
745 QString name = strValue( attr, icon );
746 if( !name.isEmpty() && loadPixmap( name, pix ) )
749 QtxAction* newAct = new QtxAction( strValue( attr, tooltip ), set, strValue( attr, label ),
750 QKeySequence( strValue( attr, accel ) ), myMgr );
751 QString toggleact = strValue( attr, toggle );
752 newAct->setCheckable( !toggleact.isEmpty() );
753 newAct->setChecked( toggleact.toLower() == "true" );
756 int aid = myMgr->registerAction( newAct, actId );
757 res = myMgr->insert( aid, tid, intValue( attr, pos, -1 ) );