1 // Copyright (C) 2007-2014 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 \param title toolbar title
117 \param floatable if \c true, new toolbar is made floatable
118 \param dockAreas dock areas of the main window where the new toolbar can be situated
119 \param tid requested toolbar ID
120 \param mw parent main window; if it is null, the tool manager's main window is used
121 \param vis show toolbar visible immediately after creation (true by default)
122 \return id of created/found toolbar
124 int QtxActionToolMgr::createToolBar( const QString& title, bool floatable, Qt::ToolBarAreas dockAreas,
125 int tid, QMainWindow* mw, bool vis )
127 static int _toolBarId = -1;
130 for ( ToolBarMap::ConstIterator it = myToolBars.begin(); it != myToolBars.end() && tbId == -1; ++it )
132 if( it.value().toolBar->windowTitle().toLower() == title.toLower() &&
133 ( !mw || it.value().toolBar->parent()==mw ) )
140 QMainWindow* tbw = mw ? mw : mainWindow();
141 QToolBar* tb = find( title, tbw );
143 tbId = tid < 0 ? --_toolBarId : tid;
145 myToolBars.insert( tbId, ToolBarInfo() );
146 ToolBarInfo& tInfo = myToolBars[tbId];
150 tb = new QtxToolBar( true, tbw );
151 //tb->setVisible( false ); // VSR: create toolbar visible initially
152 tb->setFloatable( floatable );
153 tb->setAllowedAreas( dockAreas );
154 tb->setMovable( dockAreas & Qt::AllToolBarAreas );
155 //mainWindow()->addToolBar( tb );
156 tb->setWindowTitle( title );
157 tb->setObjectName( title );
158 tb->setToolTip( title );
160 QApplication::postEvent( tb, new QHideEvent());
164 connect( tInfo.toolBar, SIGNAL( destroyed() ), this, SLOT( onToolBarDestroyed() ) );
170 \brief Search toolbar with given \a title owned by main window \mw.
171 \param title toolbar title
172 \param mw main window
173 \return toolbar or 0 if it is not found
175 QToolBar* QtxActionToolMgr::find( const QString& title, QMainWindow* mw ) const
180 QString pattern = title.toLower();
183 QList<QToolBar*> toolbars = qFindChildren<QToolBar*>( mw );
184 for ( QList<QToolBar*>::iterator it = toolbars.begin(); it != toolbars.end() && !res; ++it )
186 if ( (*it)->windowTitle().toLower() == pattern )
193 \brief Remove toolbar.
194 \param tid toolbar ID
196 void QtxActionToolMgr::removeToolBar( const int tid )
198 if ( !myToolBars.contains( tid ) )
201 delete myToolBars[tid].toolBar;
202 myToolBars.remove( tid );
206 \brief Remove toolbar.
207 \param title toolbar title
209 void QtxActionToolMgr::removeToolBar( const QString& title )
211 removeToolBar( find( title ) );
215 \brief Insert action into toolbar.
217 \param tid toolbar ID
218 \param idx action index in the toolbar (if < 0, action is appended to the end)
221 int QtxActionToolMgr::insert( const int id, const int tid, const int idx )
223 if ( !contains( id ) || !hasToolBar( tid ) )
226 if ( containsAction( id, tid ) )
231 NodeList& list = myToolBars[tid].nodes;
232 int index = idx < 0 ? list.count() : qMin( idx, (int)list.count() );
233 list.insert( index, node );
234 triggerUpdate( tid );
240 \brief Insert action into toolbar.
242 \param tid toolbar ID
243 \param idx action index in the toolbar (if < 0, action is appended to the end)
246 int QtxActionToolMgr::insert( QAction* a, const int tid, const int idx )
248 return insert( registerAction( a ), tid, idx );
252 \brief Insert action into toolbar.
254 \param title toolbar title
255 \param idx action index in the toolbar (if < 0, action is appended to the end)
258 int QtxActionToolMgr::insert( const int id, const QString& title, const int idx )
260 return insert( id, createToolBar( title ), idx );
264 \brief Insert action into toolbar.
266 \param title toolbar title
267 \param idx action index in the toolbar (if < 0, action is appended to the end)
270 int QtxActionToolMgr::insert( QAction* a, const QString& title, const int idx )
272 return insert( registerAction( a ), createToolBar( title ), idx );
276 \brief Append action to the end of toolbar.
278 \param tid toolbar ID
281 int QtxActionToolMgr::append( const int id, const int tid )
283 return insert( id, tid );
287 \brief Append action to the end of toolbar.
289 \param tid toolbar ID
292 int QtxActionToolMgr::append( QAction* a, const int tid )
294 return insert( a, tid );
298 \brief Append action to the end of toolbar.
300 \param title toolbar title
303 int QtxActionToolMgr::append( const int id, const QString& title )
305 return insert( id, title );
309 \brief Append action to the end of toolbar.
311 \param title toolbar title
314 int QtxActionToolMgr::append( QAction* a, const QString& title )
316 return insert( a, title );
320 \brief Insert action to the beginning of toolbar.
322 \param tid toolbar ID
325 int QtxActionToolMgr::prepend( const int id, const int tid )
327 return insert( id, tid, 0 );
331 \brief Insert action to the beginning of toolbar.
333 \param tid toolbar ID
336 int QtxActionToolMgr::prepend( QAction* a, const int tid )
338 return insert( a, tid, 0 );
342 \brief Insert action to the beginning of toolbar.
344 \param title toolbar title
347 int QtxActionToolMgr::prepend( const int id, const QString& title )
349 return insert( id, title, 0 );
353 \brief Insert action to the beginning of toolbar.
355 \param title toolbar title
358 int QtxActionToolMgr::prepend( QAction* a, const QString& title )
360 return insert( a, title, 0 );
364 \brief Remove action from toolbar.
366 \param tid toolbar ID
368 void QtxActionToolMgr::remove( const int id, const int tid )
370 if ( !myToolBars.contains( tid ) )
374 const NodeList& nodes = myToolBars[tid].nodes;
375 for ( NodeList::const_iterator it = nodes.begin(); it != nodes.end(); ++it )
377 if ( (*it).id != id )
378 newList.append( *it );
381 myToolBars[tid].nodes = newList;
383 triggerUpdate( tid );
387 \brief Remove action from toolbar.
389 \param title toolbar title
391 void QtxActionToolMgr::remove( const int id, const QString& title )
393 remove( id, find( title ) );
397 \brief Get toolbar by given \a tid.
398 \param tid toolbar ID
399 \return toolbar or 0 if it is not found
401 QToolBar* QtxActionToolMgr::toolBar( const int tid ) const
404 if ( myToolBars.contains( tid ) )
405 tb = myToolBars[tid].toolBar;
410 \brief Get toolbar by given \a title.
411 \param title toolbar title
412 \return toolbar or 0 if it is not found
414 QToolBar* QtxActionToolMgr::toolBar( const QString& title ) const
416 return toolBar( find( title ) );
420 \bried Get all registered toolbars identifiers
421 \return list of toolbars ids
423 QIntList QtxActionToolMgr::toolBarsIds() const
425 return myToolBars.keys();
429 \brief Check if toolbar with given \a id already registered.
430 \param tid toolbar ID
431 \return \c true if toolbar is registered in the toolbar manager
433 bool QtxActionToolMgr::hasToolBar( const int tid ) const
435 return myToolBars.contains( tid );
439 \brief Check if toolbar with given \a id already registered.
440 \param title toolbar title
441 \return \c true if toolbar is registered in the toolbar manager
443 bool QtxActionToolMgr::hasToolBar( const QString& title ) const
445 return find( title ) != -1;
449 \brief Check if toolbar contains given action.
451 \param tid toolbar ID
452 \return \c true if toolbar contains action
454 bool QtxActionToolMgr::containsAction( const int id, const int tid ) const
456 for ( ToolBarMap::ConstIterator it = myToolBars.begin(); it != myToolBars.end(); ++it )
458 if ( tid == -1 || it.key() == tid )
460 const NodeList& list = it.value().nodes;
461 for ( NodeList::const_iterator nit = list.begin(); nit != list.end(); ++nit )
462 if ( (*nit).id == id )
470 \brief Get index of the action \a id within the toolbar \a tid
472 \param tid toolbar ID
473 \return index of the action in the toolbar or -1 if action is not contained in the toolbar
475 int QtxActionToolMgr::index( const int id, const int tid ) const
477 for ( ToolBarMap::ConstIterator it = myToolBars.begin(); it != myToolBars.end(); ++it )
479 if ( it.key() == tid )
481 const NodeList& list = it.value().nodes;
483 for ( NodeList::const_iterator nit = list.begin(); nit != list.end(); ++nit, ++idx )
484 if ( (*nit).id == id ) return idx;
491 \brief Called when toolbar is destroyed.
493 Clears internal pointer to the toolbar to disable crashes.
495 void QtxActionToolMgr::onToolBarDestroyed()
497 myToolBars.remove( find( (QToolBar*)sender() ) );
501 \brief Search toolbar by given \a name.
502 \param title toolbar title
503 \return toolbar ID or -1 if it is not found
505 int QtxActionToolMgr::find( const QString& title ) const
508 for ( ToolBarMap::ConstIterator it = myToolBars.begin(); it != myToolBars.end() && id == -1; ++it )
510 if ( it.value().toolBar->windowTitle() == title )
517 \brief Get toolbar identifier.
519 \return toolbar ID or -1 if toolbar is not registered
521 int QtxActionToolMgr::find( QToolBar* tb ) const
524 for ( ToolBarMap::ConstIterator it = myToolBars.begin(); it != myToolBars.end() && id == -1; ++it )
526 if ( it.value().toolBar == tb )
533 \brief Update toolbar.
534 \param tid toolbar ID
536 void QtxActionToolMgr::updateToolBar( const int tid )
538 if ( !isUpdatesEnabled() )
541 if ( !myToolBars.contains( tid ) )
544 QToolBar* tb = myToolBars[tid].toolBar;
545 const NodeList& list = myToolBars[tid].nodes;
547 for ( NodeList::const_iterator it = list.begin(); it != list.end(); ++it )
549 QAction* a = action( (*it).id );
550 tb->removeAction( a );
552 // a->removeFrom( tb );
557 for ( NodeList::const_iterator itr = list.begin(); itr != list.end(); ++itr )
559 if ( !isVisible( (*itr).id, tid ) )
562 QAction* a = action( (*itr).id );
568 simplifySeparators( tb );
571 if ( !tb->isVisible() )
577 \brief Update all registered toolbars.
579 void QtxActionToolMgr::internalUpdate()
581 if ( !isUpdatesEnabled() )
584 for ( ToolBarMap::ConstIterator it1 = myToolBars.begin(); it1 != myToolBars.end(); ++it1 )
585 updateToolBar( it1.key() );
591 \brief Remove extra separators from the toolbar.
594 void QtxActionToolMgr::simplifySeparators( QToolBar* tb )
596 Qtx::simplifySeparators( tb );
600 \brief Show action (in all toolbars).
603 void QtxActionToolMgr::show( const int id )
605 setShown( id, true );
609 \brief Hide action (in all toolbars).
612 void QtxActionToolMgr::hide( const int id )
614 setShown( id, false );
618 \brief Set visibility status for toolbar action with given \a id.
620 \param on new visibility status
622 void QtxActionToolMgr::setShown( const int id, const bool on )
624 for ( ToolBarMap::Iterator it = myToolBars.begin(); it != myToolBars.end(); ++it )
625 setVisible( id, it.key(), on );
629 \brief Get visibility status for toolbar action with given \a id.
631 \return \c true if action is shown in all toolbars
633 bool QtxActionToolMgr::isShown( const int id ) const
635 QList<const ToolNode*> nodes;
636 for ( ToolBarMap::ConstIterator it = myToolBars.begin(); it != myToolBars.end(); ++it )
638 const NodeList& nl = it.value().nodes;
639 for ( NodeList::const_iterator itr = nl.begin(); itr != nl.end(); ++itr )
641 const ToolNode& node = *itr;
643 nodes.append( &node );
647 if ( nodes.isEmpty() )
651 for ( QList<const ToolNode*>::iterator itr = nodes.begin(); itr != nodes.end() && vis; ++itr )
652 vis = (*itr)->visible;
658 \brief Check if an action with given \a id is visible in the toolbar \a tid.
660 \param tid toolbar ID
661 \return \c true if action is shown in the toolbar
663 bool QtxActionToolMgr::isVisible( const int id, const int tid ) const
665 if ( !myToolBars.contains( tid ) )
669 const ToolBarInfo& inf = myToolBars[tid];
670 for ( NodeList::const_iterator it = inf.nodes.begin(); it != inf.nodes.end() && !vis; ++it )
672 const ToolNode& node = *it;
681 \brief Show/hide action with given \a id in the toolbar \a tid.
683 \param tid toolbar ID
684 \param on new visibility status
686 void QtxActionToolMgr::setVisible( const int id, const int tid, const bool on )
688 if ( !myToolBars.contains( tid ) )
691 bool changed = false;
692 NodeList& lst = myToolBars[tid].nodes;
693 for ( NodeList::iterator it = lst.begin(); it != lst.end(); ++it )
695 ToolNode& node = *it;
698 changed = changed || node.visible != on;
704 triggerUpdate( tid );
708 \brief Load toolbar contents from the file.
709 \param fname file name
710 \param r actions reader
711 \return \c true on success and \c false on error
713 bool QtxActionToolMgr::load( const QString& fname, QtxActionMgr::Reader& r )
715 ToolCreator cr( &r, this );
716 return r.read( fname, cr );
720 \brief Called when delayed content update is performed.
722 Customizes the content update operation.
724 void QtxActionToolMgr::updateContent()
726 if ( !isUpdatesEnabled() )
729 for ( QMap<int,int>::const_iterator it = myUpdateIds.constBegin(); it != myUpdateIds.constEnd(); ++it )
730 updateToolBar( it.key() );
735 \brief Perform delayed toolbar update.
736 \param tid toolbar ID
738 void QtxActionToolMgr::triggerUpdate( const int tid )
740 myUpdateIds.insert( tid, 0 );
741 QtxActionMgr::triggerUpdate();
746 \class QtxActionToolMgr::ToolCreator
747 \brief Toolbars creator.
749 Used by Reader to create actions by reading descriptions from the file,
750 create toolbars and fill in the toolbara with the actions.
755 \param r actions reader
756 \param mgr toolbar manager
758 QtxActionToolMgr::ToolCreator::ToolCreator( QtxActionMgr::Reader* r,
759 QtxActionToolMgr* mgr )
760 : QtxActionMgr::Creator( r ),
768 QtxActionToolMgr::ToolCreator::~ToolCreator()
773 \brief Create and append to the action manager a new toolbar or toolbar action.
774 \param tag item tag name
775 \param subMenu \c true if this item is submenu (not used)
776 \param attr attributes map
777 \param tid toolbar ID
778 \return toolbar or toolbar action ID
780 int QtxActionToolMgr::ToolCreator::append( const QString& tag, const bool /*subMenu*/,
781 const ItemAttributes& attr, const int tid )
783 if( !myMgr || !reader() )
786 QString label = reader()->option( "label", "label" ),
787 id = reader()->option( "id", "id" ),
788 pos = reader()->option( "pos", "pos" ),
789 group = reader()->option( "group", "group" ),
790 tooltip = reader()->option( "tooltip", "tooltip" ),
791 sep = reader()->option( "separator", "separator" ),
792 accel = reader()->option( "accel", "accel" ),
793 icon = reader()->option( "icon", "icon" ),
794 toggle = reader()->option( "toggle", "toggle" );
796 int res = -1, actId = intValue( attr, id, -1 );
798 res = myMgr->createToolBar( strValue( attr, label ), intValue( attr, id, -1 ) );
800 res = myMgr->insert( separator(), tid, intValue( attr, pos, -1 ) );
805 QString name = strValue( attr, icon );
806 if( !name.isEmpty() && loadPixmap( name, pix ) )
809 QtxAction* newAct = new QtxAction( strValue( attr, tooltip ), set, strValue( attr, label ),
810 QKeySequence( strValue( attr, accel ) ), myMgr );
811 QString toggleact = strValue( attr, toggle );
812 newAct->setCheckable( !toggleact.isEmpty() );
813 newAct->setChecked( toggleact.toLower() == "true" );
816 int aid = myMgr->registerAction( newAct, actId );
817 res = myMgr->insert( aid, tid, intValue( attr, pos, -1 ) );