]> SALOME platform Git repositories - modules/gui.git/blob - src/LightApp/LightApp_ModuleAction.cxx
Salome HOME
36c6fa77bb5d7352fb3463871a3daf16b410e045
[modules/gui.git] / src / LightApp / LightApp_ModuleAction.cxx
1 //  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 //  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
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.
10 //
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.
15 //
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
19 //
20 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 // File   : LightApp_ModuleAction.cxx
23 // Author : Sergey TELKOV, Vadim SANDLER
24 //
25 #include "LightApp_ModuleAction.h"
26
27 #include <QtxComboBox.h>
28 #include <QtxActionSet.h>
29 #include <QVBoxLayout>
30
31 /*!
32   \class LightApp_ModuleAction::ActionSet
33   \brief Internal class to represent list of modules buttons.
34   \internal
35 */
36
37 class LightApp_ModuleAction::ActionSet : public QtxActionSet
38 {
39 public:
40   ActionSet( QObject* );
41   QAction* moduleAction( const QString& ) const;
42   int      moduleId( const QString& ) const;
43   int      moduleId( QAction* ) const;
44   void     setVisible( bool );
45 };
46
47 /*!
48   \brief Constructor.
49   \internal
50   \param parent parent object
51 */
52 LightApp_ModuleAction::ActionSet::ActionSet( QObject* parent )
53 : QtxActionSet( parent ) 
54 {
55 }
56
57 /*!
58   \brief Get action corresponding to the specified module.
59   \internal
60   \param name module name
61   \return module action or 0 if \a name is invalid
62 */
63 QAction* LightApp_ModuleAction::ActionSet::moduleAction( const QString& name ) const
64 {
65   QAction* a = 0;
66
67   QList<QAction*> alist = actions();
68   for ( QList<QAction*>::const_iterator it = alist.begin(); it != alist.end() && !a; ++it )
69   {
70     if ( (*it)->text() == name )
71       a = *it;
72   }
73
74   return a;
75 }
76
77 /*!
78   \brief Get module action identifier.
79   \internal
80   \param name module name
81   \return module action ID or -1 if \a name is invalid
82 */
83 int LightApp_ModuleAction::ActionSet::moduleId( const QString& name ) const
84 {
85   int id = -1;
86
87   QList<QAction*> alist = actions();
88   for ( QList<QAction*>::const_iterator it = alist.begin(); it != alist.end() && id == -1; ++it )
89   {
90     if ( (*it)->text() == name )
91       id = actionId( *it );
92   }
93
94   return id;
95 }
96
97 /*!
98   \brief Get module action identifier.
99   \internal
100   \param a module action
101   \return module action ID or -1 if \a a is null or invalid
102 */
103 int LightApp_ModuleAction::ActionSet::moduleId( QAction* a ) const
104 {
105   return actionId( a );
106 }
107
108 /*!
109   \brief Show/hide modules actions.
110   \internal
111   \param on new visibility state
112 */
113 void LightApp_ModuleAction::ActionSet::setVisible( bool on )
114 {
115   QList<QAction*> alist = actions();
116   for ( QList<QAction*>::const_iterator it = alist.begin(); it != alist.end(); ++it )
117     (*it)->setVisible( on );
118
119   QtxActionSet::setVisible( on );
120 }
121
122 /*!
123   \class LightApp_ModuleAction::ComboAction
124   \brief Internal class to represent combo box with the list of modules in the toolbar.
125   \internal
126 */
127
128 /*!
129   \brief Constructor.
130   \internal
131   \param parent parent object
132 */
133 LightApp_ModuleAction::ComboAction::ComboAction( QObject* parent )
134 : QtxAction( parent )
135 {
136 }
137
138 /*!
139   \brief Get list of associated widgets.
140   \internal
141   \return list of created widgets (QtxComboBox)
142 */
143 QList<QtxComboBox*> LightApp_ModuleAction::ComboAction::widgets() const
144 {
145   QList<QtxComboBox*> lst;
146
147   QList<QWidget*> wlist = createdWidgets();
148   for ( QList<QWidget*>::const_iterator wit = wlist.begin(); wit != wlist.end(); ++wit )
149     lst += qFindChildren<QtxComboBox *>(*wit);
150
151   return lst;
152 }
153
154 /*!
155   \brief Create combo box widget by request from the toolbar.
156   \internal
157   \param parent parent widget (should be QToolBar or its successor)
158   \return new custom widget, containing combo box
159 */
160 QWidget* LightApp_ModuleAction::ComboAction::createWidget( QWidget* parent )
161 {
162   if ( !parent->inherits( "QToolBar" ) )
163     return 0;
164
165   QWidget* dumb = new QWidget( parent );
166   QVBoxLayout* l = new QVBoxLayout( dumb );
167   l->setSpacing( 0 ); l->setMargin( 0 );
168   QtxComboBox* cb = new QtxComboBox( dumb );
169   cb->setSizeAdjustPolicy( QComboBox::AdjustToContents );
170   cb->setFocusPolicy( Qt::NoFocus );
171   l->addWidget( cb );
172   l->addSpacing( 3 );
173
174   connect( cb, SIGNAL( activatedId( int ) ), this, SIGNAL( activatedId( int ) ) );
175
176   return dumb;
177 }
178
179 /*!
180   \fn void LightApp_ModuleAction::ComboAction::activatedId( int id );
181   \internal
182   \brief Emitted when the combo box item is activated
183   \param item identifier
184 */
185
186 /*!
187   \class LightApp_ModuleAction
188   \brief An action, representing the list of modules to be inserted to the
189   toolbar.
190
191   This action is represented in the toolbar as combo box and a set of buttons 
192   for each module. In addition to the modules items, the combo box contains 
193   an item corresponding to the "neutral point" of the application 
194   (when there is no active module).
195   
196   The action can be constructed with up to two parameters, defining the text
197   and icon to be displayed for the "neutral point".
198
199   Only one module can be active at the moment. It can be set programmatically 
200   with setActiveModule() function. Use this method with empty string to turn
201   to the "neutral point". To get active module, use activeModule() function.
202
203   When user activates/deactivates any module, the signal moduleActivated() 
204   is emitted.
205
206   The action can be represented in the toolbar in different modes:
207   * as combo box only (Qtx::ComboItem)
208   * as set of modules buttons only (Qtx::Buttons)
209   * as combo box followed by the set of modules buttons (Qtx::All)
210   * as none (Qtx::None)
211   By default, both combo box and buttons set are shown. Use method 
212   setMode() to change this behavior.
213
214   An action can be also added to the popup menu, but combo box is never shown
215   in this case, only modules buttons.
216 */
217
218 /*!
219   \brief Constructor
220
221   Creates an module action with "neutral point" item described by \a text.
222
223   \param text "neutral point" item's text
224   \param parent parent object
225 */
226 LightApp_ModuleAction::LightApp_ModuleAction( const QString& text, QObject* parent )
227 : QtxAction( parent )
228 {
229   setText( text );
230   init();
231 }
232
233 /*!
234   \brief Constructor
235
236   Creates an module action with "neutral point" item described by \a text and \a ico.
237
238   \param text "neutral point" item's text
239   \param ico "neutral point" item's icon
240   \param parent parent object
241 */
242 LightApp_ModuleAction::LightApp_ModuleAction( const QString& text, const QIcon& ico, QObject* parent )
243 : QtxAction( parent )
244 {
245   setText( text );
246   setIcon( ico );
247   init();
248 }
249
250 /*!
251   \brief Destructor
252 */
253 LightApp_ModuleAction::~LightApp_ModuleAction()
254 {
255 }
256
257 /*!
258   \brief Get list of modules.
259   \return modules names list
260 */
261 QStringList LightApp_ModuleAction::modules() const
262 {
263   QStringList lst;
264
265   QList<QAction*> alist = mySet->actions();
266   for ( QList<QAction*>::const_iterator it = alist.begin(); it != alist.end(); ++it )
267     lst.append( (*it)->text() );
268
269   return lst;
270 }
271
272 /*!
273   \brief Get module icon.
274   \param name module name
275   \return module icon
276   \sa setModuleIcon()
277 */
278 QIcon LightApp_ModuleAction::moduleIcon( const QString& name ) const
279 {
280   QAction* a = mySet->moduleAction( name );
281   return a ? a->icon() : QIcon();
282 }
283
284 /*!
285   \brief Set module icon.
286   \param name module name
287   \param ico new module icon
288   \sa moduleIcon()
289 */
290 void LightApp_ModuleAction::setModuleIcon( const QString& name, const QIcon& ico )
291 {
292   QAction* a = mySet->moduleAction( name );
293   if ( !a )
294     return;
295
296   a->setIcon( ico );
297   update();
298 }
299
300 /*!
301   \brief Add module into the list.
302   \param name module name
303   \param ico module icon
304   \param idx position in the module list (if -1, the module is added to the end of list)
305   \sa removeModule()
306 */
307 void LightApp_ModuleAction::insertModule( const QString& name, const QIcon& ico,
308                                           const int idx )
309 {
310   QtxAction* a = new QtxAction( name, ico, name, 0, this, true );
311   a->setStatusTip( tr( "Activate/deactivate %1 module" ).arg( name ) );
312
313   mySet->insertAction( a, -1, idx );
314   update();
315 }
316
317 /*!
318   \brief Remove module from the list.
319   \param name module name
320   \sa insertModule()
321 */
322 void LightApp_ModuleAction::removeModule( const QString& name )
323 {
324   int id = mySet->moduleId( name );
325   if ( id == -1 )
326     return;
327
328   mySet->removeAction( id );
329   update();
330 }
331
332 /*!
333   \brief Get active module.
334
335   If there is no active module ("neutral point"), then the null string 
336   is returned.
337
338   \return active module name
339   \sa setActiveModule()
340 */
341 QString LightApp_ModuleAction::activeModule() const
342 {
343   QAction* a = active();
344   return a ? a->text() : QString();
345 }
346
347 /*!
348   \brief Set active module.
349
350   To turn to the "neutral point" (no active module), pass empty string.
351
352   \param name new active module name
353   \sa activeModule()
354 */
355 void LightApp_ModuleAction::setActiveModule( const QString& name )
356 {
357   if ( name == activeModule() )
358     return;
359
360   int id = mySet->moduleId( name );
361   if ( name.isEmpty() || id != -1 )
362     activate( id, false );
363 }
364
365 /*!
366   \brief Set action display mode.
367
368   Action can be represented in the toolbar as
369   * combo box only (Qtx::ComboItem)
370   * set of modules buttons only (Qtx::Buttons)
371   * combo box followed by the set of modules buttons (Qtx::All)
372   * none (Qtx::None)
373
374   \param mode action display mode
375   \sa mode()
376 */
377 void LightApp_ModuleAction::setMode( const int mode )
378 {
379   myMode = mode;
380   update();
381 }
382
383 /*!
384   \brief Get action display mode.
385   \param mode action display mode
386   \sa setMode()
387 */
388 int LightApp_ModuleAction::mode() const
389 {
390   return myMode;
391 }
392
393 /*!
394   \brief Called when the action is added to the widget.
395   \param w widget (not used)
396 */
397 void LightApp_ModuleAction::addedTo( QWidget* w )
398 {
399   if ( w->inherits( "QToolBar" ) )
400     w->insertAction( this, myCombo );
401   w->insertAction( this, mySet );
402   update();
403 }
404
405 /*!
406   \brief Remove action from widget.
407   \param w widget (menu or toolbar)
408   \return \c true if the action is removed successfully and \c false otherwise.
409   \sa addTo()
410 */
411 void LightApp_ModuleAction::removedFrom( QWidget* w )
412 {
413   if ( w->inherits( "QToolBar" ) )
414     w->removeAction( myCombo );
415   w->removeAction( mySet );
416 }
417
418 /*!
419   \fn void LightApp_ModuleAction::moduleActivated( const QString& name );
420   \brief Emitted when the module is activated
421   \param name module name (empty string for neutral point)
422 */
423
424 /*!
425   \brief Initialize an action,
426   \internal
427 */
428 void LightApp_ModuleAction::init()
429 {
430   setVisible( false );
431
432   myMode = All;
433   myCombo = new ComboAction( this );
434   mySet = new ActionSet( this );
435
436   connect( this,    SIGNAL( changed() ),          this, SLOT( onChanged() ) );
437   connect( mySet,   SIGNAL( triggered( int ) ),   this, SLOT( onTriggered( int ) ) );
438   connect( myCombo, SIGNAL( activatedId( int ) ), this, SLOT( onComboActivated( int ) ) );
439 }
440
441 /*!
442   \brief Update an action.
443   \internal
444 */
445 void LightApp_ModuleAction::update()
446 {
447   QList<QtxComboBox*> lst = myCombo->widgets();
448   for ( QList<QtxComboBox*>::const_iterator it = lst.begin(); it != lst.end(); ++it )
449     update( *it );
450
451   myCombo->setVisible( myMode & ComboItem );
452   mySet->setVisible( myMode & Buttons );
453 }
454
455 /*!
456   \brief Update combo box.
457   \internal
458   \param cb combo box
459 */
460 void LightApp_ModuleAction::update( QtxComboBox* cb )
461 {
462   if ( !cb )
463     return;
464
465   int curId = mySet->moduleId( active() );
466   QList<QAction*> alist = mySet->actions();
467   cb->clear();
468   
469   cb->addItem( icon(), text() );
470   cb->setId( 0, -1 );
471
472   for ( QList<QAction*>::const_iterator it = alist.begin(); it != alist.end(); ++it )
473   {
474     QAction* a = *it;
475     int id = mySet->moduleId( a );
476     cb->addItem( a->icon(), a->text() );
477     cb->setId( cb->count() - 1, id );
478   }
479
480   cb->setCurrentId( curId );
481 }
482
483 /*!
484   \brief Get an action corresponding to the active module.
485   \internal
486   \return active module action or 0 if there is no active module
487 */
488 QAction* LightApp_ModuleAction::active() const
489 {
490   QAction* a = 0;
491
492   QList<QAction*> alist = mySet->actions();
493   for ( QList<QAction*>::const_iterator it = alist.begin(); it != alist.end() && !a; ++it )
494   {
495     if ( (*it)->isChecked() )
496       a = *it;
497   }
498
499   return a;
500 }
501
502 /*!
503   \brief Activate a module item.
504   \internal
505   \param id module identifier
506   \param fromAction \c true if function is called from the module button
507 */
508 void LightApp_ModuleAction::activate( int id, bool fromAction )
509 {
510   bool checked = false;
511
512   QList<QAction*> alist = mySet->actions();
513   for ( QList<QAction*>::const_iterator it = alist.begin(); it != alist.end(); ++it )
514   {
515     if ( mySet->moduleId( *it ) != id ) {
516       (*it)->setChecked( false );
517     }
518     else {
519       if ( !fromAction )
520         (*it)->setChecked( true );
521       checked = (*it)->isChecked();
522     }
523   }
524
525   QList<QtxComboBox*> widgets = myCombo->widgets();
526   for ( QList<QtxComboBox*>::const_iterator wit = widgets.begin(); wit != widgets.end(); ++wit )
527   {
528     QtxComboBox* cb = *wit;
529     bool blocked = cb->signalsBlocked();
530     cb->blockSignals( true );
531     cb->setCurrentId( checked ? id : -1 );
532     cb->blockSignals( blocked );
533   }
534
535   emit moduleActivated( activeModule() );
536 }
537
538 /*!
539   \brief Called when module button is triggered.
540   \internal
541   \param id module identifier
542 */
543 void LightApp_ModuleAction::onTriggered( int id )
544 {
545   activate( id );
546 }
547
548 /*!
549   \brief Called when action state is changed.
550   \internal
551   
552   This slot is used to prevent making the parent action visible.
553 */
554 void LightApp_ModuleAction::onChanged()
555 {
556   if ( !isVisible() )
557     return;
558
559   bool block = signalsBlocked();
560   blockSignals( true );
561   setVisible( false );
562   blockSignals( block );
563 }
564
565 /*!
566   \brief Called when combo box item is activated.
567   \param id module identifier
568 */
569 void LightApp_ModuleAction::onComboActivated( int id )
570 {
571   activate( id, false );
572