1 // Copyright (C) 2007-2015 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, or (at your option) any later version.
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
23 // File: QtxActionToolMgr.cxx
24 // Author: Alexander SOLOVYOV, Sergey TELKOV
26 #include "QtxActionToolMgr.h"
28 #include "QtxAction.h"
29 #include "QtxToolBar.h"
31 #include <QApplication>
33 #include <QMainWindow>
36 \class QtxActionToolMgr::ToolNode
37 \brief Represents a toolbutton inside toolbar structure.
42 \fn QtxActionToolMgr::ToolNode::ToolNode()
44 \brief Default constructor.
48 \fn QtxActionToolMgr::ToolNode::ToolNode( const int _id )
51 \param _id toolbar node ID
55 \class QtxActionToolMgr
56 \brief Toolbar actions manager.
58 Toolbar manager allows using of set of action for automatic generating of
59 application toolbars and dynamic update of toolbars contents.
61 Use insert(), append() and remove() methods to create toolbar and add actions to it.
62 Methods show(), hide() allow displaying/erasing of specified toolbar items.
64 Toolbar manager automatically optimizes toolbars by removing extra separators, etc.
69 \param p parent main window
71 QtxActionToolMgr::QtxActionToolMgr( QMainWindow* p )
80 QtxActionToolMgr::~QtxActionToolMgr()
85 \brief Get parent main window.
86 \return main window pointer
88 QMainWindow* QtxActionToolMgr::mainWindow() const
94 \brief Create toolbar and assign \a id to it.
96 If \a tid is less than 0, the identifier is generated automatically.
97 If toolbar with given \a tid is already registered, the toolbar will not be created.
99 \param title toolbar title
100 \param tid requested toolbar ID
101 \param mw parent main window; if it is null, the tool manager's main window is used
102 \param vis show toolbar visible immediately after creation (true by default)
103 \return id of created/found toolbar
105 int QtxActionToolMgr::createToolBar( const QString& title, const int tid, QMainWindow* mw, bool vis )
107 return createToolBar( title, true, Qt::AllToolBarAreas, tid, mw, vis );
111 \brief Create toolbar and assign \a id to it.
113 If \a tid is less than 0, the identifier is generated automatically.
114 If toolbar with given \a tid is already registered, the toolbar will not be created.
116 The parameter \a name can be specified to give an unique string identifier to the toolbar.
117 This can be useful in the multi-language environment where identifier of the toolbar should
118 not be dependant on the language chosen (e.g. to store positions of toolbars of main menu
121 \param title toolbar title
122 \param name toolbar name (identifier)
123 \param tid requested toolbar ID
124 \param mw parent main window; if it is null, the tool manager's main window is used
125 \param vis show toolbar visible immediately after creation (true by default)
126 \return id of created/found toolbar
128 int QtxActionToolMgr::createToolBar( const QString& title, const QString& name, const int tid, QMainWindow* mw, bool vis )
130 return createToolBar( title, name, true, Qt::AllToolBarAreas, tid, mw, vis );
134 \brief Create toolbar and assign \a id to it.
136 If \a tid is less than 0, the identifier is generated automatically.
137 If toolbar with given \a tid is already registered, the toolbar will not be created.
139 The parameter \a name can be specified to give an unique string identifier to the toolbar.
140 This can be useful in the multi-language environment where identifier of the toolbar should
141 not be dependant on the language chosen (e.g. to store positions of toolbars of main menu
144 \param title toolbar title
145 \param name toolbar name (identifier)
146 \param floatable if \c true, new toolbar is made floatable
147 \param dockAreas dock areas of the main window where the new toolbar can be situated
148 \param tid requested toolbar ID
149 \param mw parent main window; if it is null, the tool manager's main window is used
150 \param vis show toolbar visible immediately after creation (true by default)
151 \return id of created/found toolbar
153 int QtxActionToolMgr::createToolBar( const QString& title, const QString& name, bool floatable, Qt::ToolBarAreas dockAreas,
154 int tid, QMainWindow* mw, bool vis )
156 static int _toolBarId = -1;
159 for ( ToolBarMap::ConstIterator it = myToolBars.begin(); it != myToolBars.end() && tbId == -1; ++it )
161 if( it.value().toolBar->windowTitle().toLower() == title.toLower() &&
162 ( !mw || it.value().toolBar->parent()==mw ) )
169 QMainWindow* tbw = mw ? mw : mainWindow();
170 QToolBar* tb = find( title, tbw );
172 tbId = tid < 0 ? --_toolBarId : tid;
174 myToolBars.insert( tbId, ToolBarInfo() );
175 ToolBarInfo& tInfo = myToolBars[tbId];
179 tb = new QtxToolBar( true, tbw );
180 //tb->setVisible( false ); // VSR: create toolbar visible initially
181 tb->setFloatable( floatable );
182 tb->setAllowedAreas( dockAreas );
183 tb->setMovable( dockAreas & Qt::AllToolBarAreas );
184 //mainWindow()->addToolBar( tb );
185 tb->setWindowTitle( title );
186 tb->setObjectName( name.isEmpty() ? title : name );
187 tb->setToolTip( title );
189 QApplication::postEvent( tb, new QHideEvent());
193 connect( tInfo.toolBar, SIGNAL( destroyed() ), this, SLOT( onToolBarDestroyed() ) );
199 \brief Create toolbar and assign \a id to it.
201 If \a tid is less than 0, the identifier is generated automatically.
202 If toolbar with given \a tid is already registered, the toolbar will not be created.
204 \param title toolbar title
205 \param floatable if \c true, new toolbar is made floatable
206 \param dockAreas dock areas of the main window where the new toolbar can be situated
207 \param tid requested toolbar ID
208 \param mw parent main window; if it is null, the tool manager's main window is used
209 \param vis show toolbar visible immediately after creation (true by default)
210 \return id of created/found toolbar
212 int QtxActionToolMgr::createToolBar( const QString& title, bool floatable, Qt::ToolBarAreas dockAreas,
213 int tid, QMainWindow* mw, bool vis )
215 return createToolBar( title, QString(), floatable, dockAreas, tid, mw, vis );
219 \brief Search toolbar with given \a title owned by main window \mw.
220 \param title toolbar title
221 \param mw main window
222 \return toolbar or 0 if it is not found
224 QToolBar* QtxActionToolMgr::find( const QString& title, QMainWindow* mw ) const
229 QString pattern = title.toLower();
232 QList<QToolBar*> toolbars = mw->findChildren<QToolBar*>( );
233 for ( QList<QToolBar*>::iterator it = toolbars.begin(); it != toolbars.end() && !res; ++it )
235 if ( (*it)->windowTitle().toLower() == pattern )
242 \brief Remove toolbar.
243 \param tid toolbar ID
245 void QtxActionToolMgr::removeToolBar( const int tid )
247 if ( !myToolBars.contains( tid ) )
250 delete myToolBars[tid].toolBar;
251 myToolBars.remove( tid );
255 \brief Remove toolbar.
256 \param title toolbar title
258 void QtxActionToolMgr::removeToolBar( const QString& title )
260 removeToolBar( find( title ) );
264 \brief Insert action into toolbar.
266 \param tid toolbar ID
267 \param idx action index in the toolbar (if < 0, action is appended to the end)
270 int QtxActionToolMgr::insert( const int id, const int tid, const int idx )
272 if ( !contains( id ) || !hasToolBar( tid ) )
275 if ( containsAction( id, tid ) )
280 NodeList& list = myToolBars[tid].nodes;
281 int index = idx < 0 ? list.count() : qMin( idx, (int)list.count() );
282 list.insert( index, node );
283 triggerUpdate( tid );
289 \brief Insert action into toolbar.
291 \param tid toolbar ID
292 \param idx action index in the toolbar (if < 0, action is appended to the end)
295 int QtxActionToolMgr::insert( QAction* a, const int tid, const int idx )
297 return insert( registerAction( a ), tid, idx );
301 \brief Insert action into toolbar.
303 \param title toolbar title
304 \param idx action index in the toolbar (if < 0, action is appended to the end)
307 int QtxActionToolMgr::insert( const int id, const QString& title, const int idx )
309 return insert( id, createToolBar( title ), idx );
313 \brief Insert action into toolbar.
315 \param title toolbar title
316 \param idx action index in the toolbar (if < 0, action is appended to the end)
319 int QtxActionToolMgr::insert( QAction* a, const QString& title, const int idx )
321 return insert( registerAction( a ), createToolBar( title ), idx );
325 \brief Append action to the end of toolbar.
327 \param tid toolbar ID
330 int QtxActionToolMgr::append( const int id, const int tid )
332 return insert( id, tid );
336 \brief Append action to the end of toolbar.
338 \param tid toolbar ID
341 int QtxActionToolMgr::append( QAction* a, const int tid )
343 return insert( a, tid );
347 \brief Append action to the end of toolbar.
349 \param title toolbar title
352 int QtxActionToolMgr::append( const int id, const QString& title )
354 return insert( id, title );
358 \brief Append action to the end of toolbar.
360 \param title toolbar title
363 int QtxActionToolMgr::append( QAction* a, const QString& title )
365 return insert( a, title );
369 \brief Insert action to the beginning of toolbar.
371 \param tid toolbar ID
374 int QtxActionToolMgr::prepend( const int id, const int tid )
376 return insert( id, tid, 0 );
380 \brief Insert action to the beginning of toolbar.
382 \param tid toolbar ID
385 int QtxActionToolMgr::prepend( QAction* a, const int tid )
387 return insert( a, tid, 0 );
391 \brief Insert action to the beginning of toolbar.
393 \param title toolbar title
396 int QtxActionToolMgr::prepend( const int id, const QString& title )
398 return insert( id, title, 0 );
402 \brief Insert action to the beginning of toolbar.
404 \param title toolbar title
407 int QtxActionToolMgr::prepend( QAction* a, const QString& title )
409 return insert( a, title, 0 );
413 \brief Remove action from toolbar.
415 \param tid toolbar ID
417 void QtxActionToolMgr::remove( const int id, const int tid )
419 if ( !myToolBars.contains( tid ) )
423 const NodeList& nodes = myToolBars[tid].nodes;
424 for ( NodeList::const_iterator it = nodes.begin(); it != nodes.end(); ++it )
426 if ( (*it).id != id )
427 newList.append( *it );
430 myToolBars[tid].nodes = newList;
432 triggerUpdate( tid );
436 \brief Remove action from toolbar.
438 \param title toolbar title
440 void QtxActionToolMgr::remove( const int id, const QString& title )
442 remove( id, find( title ) );
446 \brief Get toolbar by given \a tid.
447 \param tid toolbar ID
448 \return toolbar or 0 if it is not found
450 QToolBar* QtxActionToolMgr::toolBar( const int tid ) const
453 if ( myToolBars.contains( tid ) )
454 tb = myToolBars[tid].toolBar;
459 \brief Get toolbar by given \a title.
460 \param title toolbar title
461 \return toolbar or 0 if it is not found
463 QToolBar* QtxActionToolMgr::toolBar( const QString& title ) const
465 return toolBar( find( title ) );
469 \bried Get all registered toolbars identifiers
470 \return list of toolbars ids
472 QIntList QtxActionToolMgr::toolBarsIds() const
474 return myToolBars.keys();
478 \brief Check if toolbar with given \a id already registered.
479 \param tid toolbar ID
480 \return \c true if toolbar is registered in the toolbar manager
482 bool QtxActionToolMgr::hasToolBar( const int tid ) const
484 return myToolBars.contains( tid );
488 \brief Check if toolbar with given \a id already registered.
489 \param title toolbar title
490 \return \c true if toolbar is registered in the toolbar manager
492 bool QtxActionToolMgr::hasToolBar( const QString& title ) const
494 return find( title ) != -1;
498 \brief Check if toolbar contains given action.
500 \param tid toolbar ID
501 \return \c true if toolbar contains action
503 bool QtxActionToolMgr::containsAction( const int id, const int tid ) const
505 for ( ToolBarMap::ConstIterator it = myToolBars.begin(); it != myToolBars.end(); ++it )
507 if ( tid == -1 || it.key() == tid )
509 const NodeList& list = it.value().nodes;
510 for ( NodeList::const_iterator nit = list.begin(); nit != list.end(); ++nit )
511 if ( (*nit).id == id )
519 \brief Get index of the action \a id within the toolbar \a tid
521 \param tid toolbar ID
522 \return index of the action in the toolbar or -1 if action is not contained in the toolbar
524 int QtxActionToolMgr::index( const int id, const int tid ) const
526 for ( ToolBarMap::ConstIterator it = myToolBars.begin(); it != myToolBars.end(); ++it )
528 if ( it.key() == tid )
530 const NodeList& list = it.value().nodes;
532 for ( NodeList::const_iterator nit = list.begin(); nit != list.end(); ++nit, ++idx )
533 if ( (*nit).id == id ) return idx;
540 \brief Called when toolbar is destroyed.
542 Clears internal pointer to the toolbar to disable crashes.
544 void QtxActionToolMgr::onToolBarDestroyed()
546 myToolBars.remove( find( (QToolBar*)sender() ) );
550 \brief Search toolbar by given \a name.
551 \param title toolbar title
552 \return toolbar ID or -1 if it is not found
554 int QtxActionToolMgr::find( const QString& title ) const
557 for ( ToolBarMap::ConstIterator it = myToolBars.begin(); it != myToolBars.end() && id == -1; ++it )
559 if ( it.value().toolBar->windowTitle() == title )
566 \brief Get toolbar identifier.
568 \return toolbar ID or -1 if toolbar is not registered
570 int QtxActionToolMgr::find( QToolBar* tb ) const
573 for ( ToolBarMap::ConstIterator it = myToolBars.begin(); it != myToolBars.end() && id == -1; ++it )
575 if ( it.value().toolBar == tb )
582 \brief Update toolbar.
583 \param tid toolbar ID
585 void QtxActionToolMgr::updateToolBar( const int tid )
587 if ( !isUpdatesEnabled() )
590 if ( !myToolBars.contains( tid ) )
593 QToolBar* tb = myToolBars[tid].toolBar;
594 const NodeList& list = myToolBars[tid].nodes;
596 for ( NodeList::const_iterator it = list.begin(); it != list.end(); ++it )
598 QAction* a = action( (*it).id );
599 tb->removeAction( a );
601 // a->removeFrom( tb );
606 for ( NodeList::const_iterator itr = list.begin(); itr != list.end(); ++itr )
608 if ( !isVisible( (*itr).id, tid ) )
611 QAction* a = action( (*itr).id );
617 simplifySeparators( tb );
620 if ( !tb->isVisible() )
626 \brief Update all registered toolbars.
628 void QtxActionToolMgr::internalUpdate()
630 if ( !isUpdatesEnabled() )
633 for ( ToolBarMap::ConstIterator it1 = myToolBars.begin(); it1 != myToolBars.end(); ++it1 )
634 updateToolBar( it1.key() );
640 \brief Remove extra separators from the toolbar.
643 void QtxActionToolMgr::simplifySeparators( QToolBar* tb )
645 Qtx::simplifySeparators( tb );
649 \brief Show action (in all toolbars).
652 void QtxActionToolMgr::show( const int id )
654 setShown( id, true );
658 \brief Hide action (in all toolbars).
661 void QtxActionToolMgr::hide( const int id )
663 setShown( id, false );
667 \brief Set visibility status for toolbar action with given \a id.
669 \param on new visibility status
671 void QtxActionToolMgr::setShown( const int id, const bool on )
673 for ( ToolBarMap::Iterator it = myToolBars.begin(); it != myToolBars.end(); ++it )
674 setVisible( id, it.key(), on );
678 \brief Get visibility status for toolbar action with given \a id.
680 \return \c true if action is shown in all toolbars
682 bool QtxActionToolMgr::isShown( const int id ) const
684 QList<const ToolNode*> nodes;
685 for ( ToolBarMap::ConstIterator it = myToolBars.begin(); it != myToolBars.end(); ++it )
687 const NodeList& nl = it.value().nodes;
688 for ( NodeList::const_iterator itr = nl.begin(); itr != nl.end(); ++itr )
690 const ToolNode& node = *itr;
692 nodes.append( &node );
696 if ( nodes.isEmpty() )
700 for ( QList<const ToolNode*>::iterator itr = nodes.begin(); itr != nodes.end() && vis; ++itr )
701 vis = (*itr)->visible;
707 \brief Check if an action with given \a id is visible in the toolbar \a tid.
709 \param tid toolbar ID
710 \return \c true if action is shown in the toolbar
712 bool QtxActionToolMgr::isVisible( const int id, const int tid ) const
714 if ( !myToolBars.contains( tid ) )
718 const ToolBarInfo& inf = myToolBars[tid];
719 for ( NodeList::const_iterator it = inf.nodes.begin(); it != inf.nodes.end() && !vis; ++it )
721 const ToolNode& node = *it;
730 \brief Show/hide action with given \a id in the toolbar \a tid.
732 \param tid toolbar ID
733 \param on new visibility status
735 void QtxActionToolMgr::setVisible( const int id, const int tid, const bool on )
737 if ( !myToolBars.contains( tid ) )
740 bool changed = false;
741 NodeList& lst = myToolBars[tid].nodes;
742 for ( NodeList::iterator it = lst.begin(); it != lst.end(); ++it )
744 ToolNode& node = *it;
747 changed = changed || node.visible != on;
753 triggerUpdate( tid );
759 \brief Load toolbar contents from the file.
760 \param fname file name
761 \param r actions reader
762 \return \c true on success and \c false on error
764 bool QtxActionToolMgr::load( const QString& fname, QtxActionMgr::Reader& r )
766 ToolCreator cr( &r, this );
767 return r.read( fname, cr );
771 \brief Called when delayed content update is performed.
773 Customizes the content update operation.
775 void QtxActionToolMgr::updateContent()
777 if ( !isUpdatesEnabled() )
780 for ( QMap<int,int>::const_iterator it = myUpdateIds.constBegin(); it != myUpdateIds.constEnd(); ++it )
781 updateToolBar( it.key() );
786 \brief Perform delayed toolbar update.
787 \param tid toolbar ID
789 void QtxActionToolMgr::triggerUpdate( const int tid )
791 myUpdateIds.insert( tid, 0 );
792 QtxActionMgr::triggerUpdate();
797 \class QtxActionToolMgr::ToolCreator
798 \brief Toolbars creator.
800 Used by Reader to create actions by reading descriptions from the file,
801 create toolbars and fill in the toolbara with the actions.
806 \param r actions reader
807 \param mgr toolbar manager
809 QtxActionToolMgr::ToolCreator::ToolCreator( QtxActionMgr::Reader* r,
810 QtxActionToolMgr* mgr )
811 : QtxActionMgr::Creator( r ),
819 QtxActionToolMgr::ToolCreator::~ToolCreator()
824 \brief Create and append to the action manager a new toolbar or toolbar action.
825 \param tag item tag name
826 \param subMenu \c true if this item is submenu (not used)
827 \param attr attributes map
828 \param tid toolbar ID
829 \return toolbar or toolbar action ID
831 int QtxActionToolMgr::ToolCreator::append( const QString& tag, const bool /*subMenu*/,
832 const ItemAttributes& attr, const int tid )
834 if( !myMgr || !reader() )
837 QString label = reader()->option( "label", "label" ),
838 id = reader()->option( "id", "id" ),
839 pos = reader()->option( "pos", "pos" ),
840 group = reader()->option( "group", "group" ),
841 tooltip = reader()->option( "tooltip", "tooltip" ),
842 sep = reader()->option( "separator", "separator" ),
843 accel = reader()->option( "accel", "accel" ),
844 icon = reader()->option( "icon", "icon" ),
845 toggle = reader()->option( "toggle", "toggle" );
847 int res = -1, actId = intValue( attr, id, -1 );
849 res = myMgr->createToolBar( strValue( attr, label ), intValue( attr, id, -1 ) );
851 res = myMgr->insert( separator(), tid, intValue( attr, pos, -1 ) );
856 QString name = strValue( attr, icon );
857 if( !name.isEmpty() && loadPixmap( name, pix ) )
860 QtxAction* newAct = new QtxAction( strValue( attr, tooltip ), set, strValue( attr, label ),
861 QKeySequence( strValue( attr, accel ) ), myMgr );
862 QString toggleact = strValue( attr, toggle );
863 newAct->setCheckable( !toggleact.isEmpty() );
864 newAct->setChecked( toggleact.toLower() == "true" );
867 int aid = myMgr->registerAction( newAct, actId );
868 res = myMgr->insert( aid, tid, intValue( attr, pos, -1 ) );