Salome HOME
dc442427df162fb62d44a58f1e6edb0f5ac38065
[modules/gui.git] / src / CAM / CAM_Module.cxx
1 // Copyright (C) 2007-2023  CEA, EDF, 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, or (at your option) any later version.
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
23 #include "CAM_Module.h"
24
25 #include "CAM_DataModel.h"
26 #include "CAM_Application.h"
27 #include "CAM_Study.h"
28
29 #include <QtxAction.h>
30 #include <QtxActionGroup.h>
31 #include <QtxActionMenuMgr.h>
32 #include <QtxActionToolMgr.h>
33
34 #include <SUIT_Desktop.h>
35 #include <SUIT_Session.h>
36 #include <SUIT_ResourceMgr.h>
37
38 #include <QMenu>
39
40 /*!
41   \class CAM_Module
42   \brief Base implementation of the module in the CAM application architecture.
43
44   Provides support of menu/toolbars management.
45 */
46
47 class ActionMgrLocker
48 {
49 public:
50   ActionMgrLocker( QtxActionMgr* m, bool use ) : myMgr( m ), myUseLock( use )
51   {
52     if ( myUseLock ) {
53       myUpdEnabled = myMgr->isUpdatesEnabled();
54       myMgr->setUpdatesEnabled( false );
55     }
56   }
57   ~ActionMgrLocker()
58   {
59     if ( myUseLock ) {
60       myMgr->setUpdatesEnabled( myUpdEnabled );
61       //myMgr->update();
62     }
63   }
64
65   QtxActionMgr* myMgr;
66   bool          myUseLock;
67   bool          myUpdEnabled;
68 };
69
70 /*!
71   \brief Default constructor.
72
73   Creates unnamed module.
74 */
75 CAM_Module::CAM_Module()
76 : QObject(),
77   myApp( 0 ),
78   myDataModel( 0 )
79 {
80 }
81
82 /*!
83   \brief Constructor.
84
85   Creates module with the specified \a name.
86
87   \param name module name
88 */
89 CAM_Module::CAM_Module( const QString& name )
90 : QObject(),
91   myApp( 0 ),
92   myName( name ),
93   myDataModel( 0 ),
94   myMenuShown( false ),
95   myToolShown( false ),
96   myActionLoggingEnabled( false )
97 {
98 }
99
100 /*!
101   \brief Destructor.
102
103   Destroy data model.
104 */
105 CAM_Module::~CAM_Module()
106 {
107   delete myDataModel;
108   myDataModel = 0;
109 }
110
111 /*!
112   \brief Initialize module.
113
114   This method is usually called when the module is created (for example,
115   on the module library loading).
116   Successor classes can use this method to create menu/toolbar actions
117   and perform other module initialization.
118
119   \param app parent application object
120   \sa activateModule(), deactivateModule()
121 */
122 void CAM_Module::initialize( CAM_Application* app )
123 {
124   myApp = app;
125   if ( myApp )
126   {
127     SUIT_Session* aSession = SUIT_Session::session();
128     connect( aSession, SIGNAL( applicationClosed( SUIT_Application* ) ),
129              this, SLOT( onApplicationClosed( SUIT_Application* ) ) );
130
131     connect( myApp, SIGNAL( infoChanged( QString ) ), this, SLOT( onInfoChanged( QString ) ) );
132   }
133 }
134
135 /*!
136   \brief Get module icon.
137   \return module icon pixmap
138   \sa iconName()
139 */
140 QPixmap CAM_Module::moduleIcon() const
141 {
142   if ( myIcon.isNull() ) {
143     QString iname = iconName();
144     if ( !iname.isEmpty() ) {
145       CAM_Module* that = (CAM_Module*)this;
146       that->myIcon = application()->resourceMgr()->loadPixmap( name(), iname, false );
147     }
148   }
149   return myIcon;
150 }
151
152 /*!
153   \brief Get module icon's name.
154
155   This function is used to get module icon's file name.
156   Default implementation returns empty string.
157
158   \return module icon's name.
159   \sa moduleIcon()
160 */
161 QString CAM_Module::iconName() const
162 {
163   return application()->moduleIcon( name() );
164 }
165
166 /*!
167   \brief Get module (internal) name
168   \return module name
169   \sa setName(), moduleName(), setModuleName()
170 */
171 QString CAM_Module::name() const
172 {
173   return objectName();
174 }
175
176 /*!
177   \brief Get module title (user name)
178   \return module title
179   \sa setModuleName(), name(), setName()
180 */
181 QString CAM_Module::moduleName() const
182 {
183   return myName;
184 }
185
186 /*!
187   \brief Get data model.
188
189   Creates data model, if it is not yet created.
190
191   \return data model pointer
192   \sa createDataModel()
193 */
194 CAM_DataModel* CAM_Module::dataModel() const
195 {
196   if ( !myDataModel )
197   {
198     CAM_Module* that = (CAM_Module*)this;
199     that->myDataModel = that->createDataModel();
200     that->myDataModel->initialize();
201   }
202   return myDataModel;
203 }
204
205 /*!
206   \brief Get application.
207   \return application pointer
208 */
209 CAM_Application* CAM_Module::application() const
210 {
211   return myApp;
212 }
213
214 /*!
215   \brief If return false, selection will be cleared at module activation
216 */
217 bool CAM_Module::isSelectionCompatible()
218 {
219   return false;
220 }
221
222 /*!
223   \brief Activate module.
224
225   This method is called when the user activates module.
226   Successor classes can use this method to customize module activation process,
227   for example, to show own menus, toolbars, etc.
228
229   Default implementation always returns \c true.
230
231   \return \c true if module is activated successfully.
232   \sa initialize(), deactivateModule()
233  */
234 bool CAM_Module::activateModule( SUIT_Study* /*study*/ )
235 {
236   // IMN 05/03/2015: we copied myActionMap for reset/unset actions accelerator keys
237   // after activate/deactivate modules
238   for ( QMap<QAction*, QKeySequence>::Iterator it = myActionShortcutMap.begin(); it != myActionShortcutMap.end(); ++it )
239   {
240     // Reset actions accelerator keys
241     it.key()->setShortcut( it.value() );
242   }
243   myActionShortcutMap.clear();
244   return true;
245 }
246
247 /*!
248   \brief Deactivate module.
249
250   This method is called when the user deactivates module.
251   Successor classes can use this method to customize module deactivation process,
252   for example, to hide own menus, toolbars, etc.
253
254   Default implementation always returns \c true.
255
256   \return \c true if module is deactivated successfully.
257   \sa initialize(), activateModule()
258  */
259 bool CAM_Module::deactivateModule( SUIT_Study* )
260 {
261   // IMN 05/03/2015: we copied myActionMap for reset/unset actions accelerator keys
262   // after activate/deactivate modules
263   myActionShortcutMap.clear();
264   for ( QMap<int, QAction*>::Iterator it = myActionMap.begin(); it != myActionMap.end(); ++it )
265   {
266     myActionShortcutMap.insert( it.value(), it.value()->shortcut() );
267     it.value()->setShortcut( QKeySequence() );
268   }
269   return true;
270 }
271
272 /*!
273   \brief Called when study is closed.
274
275   Removes data model from the \a study.
276
277   \param study study being closed
278 */
279 void CAM_Module::studyClosed( SUIT_Study* study )
280 {
281   CAM_Study* camDoc = dynamic_cast<CAM_Study*>( study );
282   if ( !camDoc )
283     return;
284
285   CAM_DataModel* dm = dataModel();
286   if ( dm && camDoc->containsDataModel( dm ) ) {
287     dm->close();
288     camDoc->removeDataModel( dm );
289   }
290 }
291
292 /*!
293   \brief Called when study is changed (obsolete).
294
295   Default implementation does nothing.
296
297   \param oldStudy old study
298   \param newStudy new study
299 */
300 void CAM_Module::studyChanged( SUIT_Study* /*oldStudy*/, SUIT_Study* /*newStudy*/ )
301 {
302 }
303
304 /*!
305   \brief Check if the module is active.
306   \return \c true if module is active.
307 */
308 bool CAM_Module::isActiveModule() const
309 {
310   return application() ? application()->activeModule() == this : false;
311 }
312
313 /*!
314   \brief Put the text message into the status bar of the application main window.
315
316   If \a msec > 0, the message will be shown \a msec milliseconds.
317   If \a msec < 0, the message will be constantly displayed until module is active.
318
319   \param msg text message
320   \param msec message displaying duration in milliseconds
321 */
322 void CAM_Module::putInfo( const QString& msg, const int msec )
323 {
324   if ( application() )
325     application()->putInfo( msg, msec );
326
327   if ( msec < 0 )
328     myInfo = msg;
329 }
330
331 /*!
332     \brief Shows the notifications with spectified text, title and automatic close timeout.
333     Notification will be automatically closed after specified timeout in msec. If
334     timeout is zero then automatic closing doesn't performed.
335     \param text - Notification text
336     \param title - Notification title
337     \param timeout - Notification close timeout in msec
338     \return notification identifier
339 */
340 int CAM_Module::showNotification( const QString& message, const QString& title, int timeout )
341 {
342   int res = -1;
343   if ( application() )
344     res = application()->showNotification( message, title, timeout );
345   return res;
346 }
347
348 /*!
349     \brief Closes the notifications with spectified text.
350     \param text - Notification text
351 */
352 void CAM_Module::hideNotification( const QString& message )
353 {
354   if ( application() )
355     application()->hideNotification( message );
356 }
357
358 /*!
359     \brief Closes the notifications with spectified identifier.
360     \param text - Notification text
361 */
362 void CAM_Module::hideNotification( int id )
363 {
364   if ( application() )
365     application()->hideNotification( id );
366 }
367
368 /*!
369   \brief Restore message info.
370
371   Restores constant text message when previous information status message is removed.
372
373   \param txt previous message (being removed)
374   \sa putInfo()
375 */
376 void CAM_Module::onInfoChanged( QString txt )
377 {
378   if ( txt.isEmpty() && isActiveModule() && !myInfo.isEmpty() && application() )
379     application()->putInfo( myInfo );
380 }
381
382 /*!
383   \brief Called when application is closed.
384
385   Nullify application pointer if the application is being closed.
386
387   \param theApp application
388 */
389 void CAM_Module::onApplicationClosed( SUIT_Application* theApp )
390 {
391   if (myApp == theApp)
392     myApp = NULL;
393 }
394
395 /*!
396   \brief Create data model.
397   \return created data model object or 0 if it could not be created
398 */
399 CAM_DataModel* CAM_Module::createDataModel()
400 {
401   return new CAM_DataModel( this );
402 }
403
404 /*!
405   \brief Set module (internal) name
406   \param name new module name
407   \sa name(), moduleName(), setModuleName()
408  */
409 void CAM_Module::setName( const QString& name )
410 {
411   setObjectName( name );
412 }
413
414 /*!
415   \brief Set module title (user name)
416   \param name new module title
417   \sa moduleName(), name(), setName()
418  */
419 void CAM_Module::setModuleName( const QString& name )
420 {
421   myName = name;
422 }
423
424 /*!
425   \brief Get menu manager.
426   \return menu manager pointer
427 */
428 QtxActionMenuMgr* CAM_Module::menuMgr() const
429 {
430   QtxActionMenuMgr* mgr = 0;
431   if ( application() && application()->desktop() )
432     mgr = application()->desktop()->menuMgr();
433   return mgr;
434 }
435
436 /*!
437   \brief Get toolbar manager.
438   \return toolbar manager pointer
439 */
440 QtxActionToolMgr* CAM_Module::toolMgr() const
441 {
442   QtxActionToolMgr* mgr = 0;
443   if ( application() && application()->desktop() )
444     mgr = application()->desktop()->toolMgr();
445   return mgr;
446 }
447
448 /*!
449   \brief Create toolbar with speicifed \a name.
450
451   If the toolbar has been already created, its ID is just returned.
452
453   \param title toolbar title
454   \param name toolbar name (identifier)
455   \return toolbar ID or -1 if toolbar could not be created
456 */
457 int CAM_Module::createTool( const QString& title, const QString& name )
458 {
459   if ( !toolMgr() )
460     return -1;
461
462   ActionMgrLocker lock( toolMgr(), !myToolShown );
463
464   return toolMgr()->createToolBar( title, name );
465 }
466
467 /*!
468   \brief Add toolbar item.
469
470   Insert action \a to the toolbar manager and register it with specified \a id.
471   Resulting action ID may differ from the requested one. This can happen if
472   requested ID is already in use.
473
474   If action has been already added previously, its ID is just returned.
475
476   If \a id < 0, the action ID is generated automatically.
477
478   If \a idx < 0, the action is added to the end of the toolbar.
479
480   \param a action
481   \param tBar toolbar ID
482   \param id requested action ID
483   \param idx action index (desired position in the toolbar)
484   \return action ID or -1 if toolbar item could not be added
485 */
486 int CAM_Module::createTool( QAction* a, const int tBar, const int id, const int idx )
487 {
488   if ( !toolMgr() )
489     return -1;
490
491   ActionMgrLocker lock( toolMgr(), !myToolShown );
492
493   int regId = registerAction( id, a );
494   int intId = toolMgr()->insert( a, tBar, idx );
495
496   if ( !myToolShown )
497     setToolShown( a, false );
498
499   return intId != -1 ? regId : -1;
500 }
501
502 /*!
503   \brief Add toolbar item.
504
505   Insert action \a to the toolbar manager and register it with specified \a id.
506   Resulting action ID may differ from the requested one. This can happen if
507   requested ID is already in use.
508
509   If action has been already added previously, its ID is just returned.
510
511   If \a id < 0, the action ID is generated automatically.
512
513   If \a idx < 0, the action is added to the end of the toolbar.
514
515   \param a action
516   \param tBar toolbar name
517   \param id requested action ID
518   \param idx action index (desired position in the toolbar)
519   \return action ID or -1 if toolbar item could not be added
520 */
521 int CAM_Module::createTool( QAction* a, const QString& tBar, const int id, const int idx )
522 {
523   if ( !toolMgr() )
524     return -1;
525
526   ActionMgrLocker lock( toolMgr(), !myToolShown );
527
528   int regId = registerAction( id, a );
529   int intId = toolMgr()->insert( a, tBar, idx );
530
531   if ( !myToolShown )
532     setToolShown( a, false );
533
534   return intId != -1 ? regId : -1;
535 }
536
537 /*!
538   \brief Add toolbar item.
539
540   Insert action with \a id identifier to the toolbar manager.
541   It is assumed that action has been already registered.
542
543   Resulting action ID may differ from the requested one. This can happen if
544   requested ID is already in use.
545
546   If action has been already added previously, its ID is just returned.
547
548   If \a idx < 0, the action is added to the end of the toolbar.
549
550   \param id action ID
551   \param tBar toolbar ID
552   \param idx action index (desired position in the toolbar)
553   \return action ID or -1 if toolbar item could not be added
554 */
555 int CAM_Module::createTool( const int id, const int tBar, const int idx )
556 {
557   if ( !toolMgr() )
558     return -1;
559
560   ActionMgrLocker lock( toolMgr(), !myToolShown );
561
562   int intId = toolMgr()->insert( action( id ), tBar, idx );
563
564   if ( !myToolShown )
565     setToolShown( action( id ), false );
566
567   return intId != -1 ? id : -1;
568 }
569
570 /*!
571   \brief Add toolbar item.
572
573   Insert action with \a id identifier to the toolbar manager.
574   It is assumed that action has been already registered.
575
576   Resulting action ID may differ from the requested one. This can happen if
577   requested ID is already in use.
578
579   If action has been already added previously, its ID is just returned.
580
581   If \a idx < 0, the action is added to the end of the toolbar.
582
583   \param id action ID
584   \param tBar toolbar name
585   \param idx action index (desired position in the toolbar)
586   \return action ID or -1 if toolbar item could not be added
587 */
588 int CAM_Module::createTool( const int id, const QString& tBar, const int idx )
589 {
590   if ( !toolMgr() )
591     return -1;
592
593   ActionMgrLocker lock( toolMgr(), !myToolShown );
594
595   int intId = toolMgr()->insert( action( id ), tBar, idx );
596
597   if ( !myToolShown )
598     setToolShown( action( id ), false );
599
600   return intId != -1 ? id : -1;
601 }
602
603 /*!
604   Clears given toolbar.
605   \param title - title of toolbar
606 */
607 void CAM_Module::clearTool( const QString& title )
608 {
609   if ( toolMgr() )
610     toolMgr()->clear( title );
611 }
612
613 /*!
614   \brief Create menu or submenu.
615
616   Create main menu or popup submenu and register it with specified \a id.
617   Resulting action ID may differ from the requested one. This can happen if
618   requested ID is already in use.
619
620   If \a id < 0, the menu ID is generated automatically.
621   If menu has been already created previously, its ID is just returned.
622
623   The \a menu parameter represents the menu name - it could be a sequence
624   of strings, separated by '|' symbol. For example, "File|Edit" means
625   File->Edit submenu. If menu doesn't exist, it is created automatically.
626
627   Parameter \a idx defines the index of the menu item in the menu group which
628   is defined by the \a group. If \a idx < 0, the menu/submenu is added to the
629   end of the menu group.
630
631   \param subMenu subMenu name
632   \param menu parent menu ID
633   \param id requested menu ID
634   \param group menu group ID
635   \param idx menu item index (desired position in the menu group)
636   \return menu item ID or -1 if menu item could not be added
637 */
638 int CAM_Module::createMenu( const QString& subMenu, const int menu,
639                             const int id, const int group, const int idx, QMenu * menuObj )
640 {
641   if ( !menuMgr() )
642     return -1;
643   
644   return menuMgr()->insert( subMenu, menu, group, id, idx, menuObj );
645 }
646
647 /*!
648   \brief Create menu or submenu.
649
650   Create main menu or popup submenu and register it with specified \a id.
651   Resulting action ID may differ from the requested one. This can happen if
652   requested ID is already in use.
653
654   If \a id < 0, the menu ID is generated automatically.
655   If menu has been already created previously, its ID is just returned.
656
657   The \a menu parameter represents the menu name - it could be a sequence
658   of strings, separated by '|' symbol. For example, "File|Edit" means
659   File->Edit submenu. If menu doesn't exist, it is created automatically.
660
661   Parameter \a idx defines the index of the menu item in the menu group which
662   is defined by the \a group. If \a idx < 0, the menu/submenu is added to the
663   end of the menu group.
664
665   \param subMenu subMenu name
666   \param menu parent menu name(s)
667   \param id requested menu ID
668   \param group menu group ID
669   \param idx menu item index (desired position in the menu group)
670   \return menu item ID or -1 if menu item could not be added
671 */
672 int CAM_Module::createMenu( const QString& subMenu, const QString& menu,
673                             const int id, const int group, const int idx )
674 {
675   if ( !menuMgr() )
676     return -1;
677
678   return menuMgr()->insert( subMenu, menu, group, id, idx );
679 }
680
681 /*!
682   \brief Add menu item.
683
684   Insert action \a to the menu manager and register it with specified \a id.
685   Resulting action ID may differ from the requested one. This can happen if
686   requested ID is already in use.
687
688   If \a id < 0, the action ID is generated automatically.
689
690   If action has been already added previously, its ID is just returned.
691
692   Parameter \a idx defines the index of the menu item in the menu group which
693   is defined by the \a group. If \a idx < 0, the action is added to the
694   end of the menu group.
695
696   \param a action
697   \param menu menu ID
698   \param id requested action ID
699   \param group menu group ID
700   \param idx action index (desired position in the menu group)
701   \return action ID or -1 if menu item could not be added
702 */
703 int CAM_Module::createMenu( QAction* a, const int menu, const int id, const int group, const int idx )
704 {
705   if ( !a || !menuMgr() )
706     return -1;
707   
708   ActionMgrLocker lock( menuMgr(), !myMenuShown );
709
710   int regId = registerAction( id, a );
711   int intId = menuMgr()->insert( a, menu, group, idx );
712
713   if ( !myMenuShown )
714     setMenuShown( a, false );
715
716   return intId != -1 ? regId : -1;
717 }
718
719 /*!
720   \brief Add menu item.
721
722   Insert action \a to the menu manager and register it with specified \a id.
723   Resulting action ID may differ from the requested one. This can happen if
724   requested ID is already in use.
725
726   If \a id < 0, the action ID is generated automatically.
727
728   If action has been already added previously, its ID is just returned.
729
730   The \a menu parameter represents the menu name - it could be a sequence
731   of strings, separated by '|' symbol. For example, "File|Edit" means
732   File->Edit submenu. If menu doesn't exist, it is created automatically.
733
734   Parameter \a idx defines the index of the menu item in the menu group which
735   is defined by the \a group. If \a idx < 0, the action is added to the
736   end of the menu group.
737
738   \param a action
739   \param menu menu name(s)
740   \param id requested action ID
741   \param group menu group ID
742   \param idx action index (desired position in the menu group)
743   \return action ID or -1 if menu item could not be added
744 */
745 int CAM_Module::createMenu( QAction* a, const QString& menu, const int id, const int group, const int idx )
746 {
747   if ( !a || !menuMgr() )
748     return -1;
749
750   ActionMgrLocker lock( menuMgr(), !myMenuShown );
751
752   int regId = registerAction( id, a );
753   int intId = menuMgr()->insert( a, menu, group, idx );
754
755   if ( !myMenuShown )
756     setMenuShown( a, false );
757   
758   return intId != -1 ? regId : -1;
759 }
760
761 /*!
762   \brief Add menu item.
763
764   Insert action with \a id identifier to the menu manager.
765   It is assumed that action has been already registered.
766
767   Resulting action ID may differ from the requested one. This can happen if
768   requested ID is already in use.
769
770   If action has been already added previously, its ID is just returned.
771
772   Parameter \a idx defines the index of the menu item in the menu group which
773   is defined by the \a group. If \a idx < 0, the action is added to the
774   end of the menu group.
775
776   \param id action ID
777   \param menu menu ID
778   \param group menu group ID
779   \param idx action index (desired position in the menu group)
780   \return action ID or -1 if menu item could not be added
781 */
782 int CAM_Module::createMenu( const int id, const int menu, const int group, const int idx )
783 {
784   if ( !menuMgr() )
785     return -1;
786
787   ActionMgrLocker lock( menuMgr(), !myMenuShown );
788
789   int intId = menuMgr()->insert( action( id ), menu, group, idx );
790
791   if ( !myMenuShown )
792     setMenuShown( action( id ), false );
793
794   return intId != -1 ? id : -1;
795 }
796
797 /*!
798   \brief Add menu item.
799
800   Insert action with \a id identifier to the menu manager.
801   It is assumed that action has been already registered.
802
803   Resulting action ID may differ from the requested one. This can happen if
804   requested ID is already in use.
805
806   If action has been already added previously, its ID is just returned.
807
808   The \a menu parameter represents the menu name - it could be a sequence
809   of strings, separated by '|' symbol. For example, "File|Edit" means
810   File->Edit submenu. If menu doesn't exist, it is created automatically.
811
812   Parameter \a idx defines the index of the menu item in the menu group which
813   is defined by the \a group. If \a idx < 0, the action is added to the
814   end of the menu group.
815
816   \param id action ID
817   \param menu menu name(s)
818   \param group menu group ID
819   \param idx action index (desired position in the menu group)
820   \return action ID or -1 if menu item could not be added
821 */
822 int CAM_Module::createMenu( const int id, const QString& menu, const int group, const int idx )
823 {
824   if ( !menuMgr() )
825     return -1;
826
827   ActionMgrLocker lock( menuMgr(), !myMenuShown );
828
829   int intId = menuMgr()->insert( action( id ), menu, group, idx );
830
831   if ( !myMenuShown )
832     setMenuShown( action( id ), false );
833
834   return intId != -1 ? id : -1;
835 }
836
837 /*!
838   \brief Show/hide all module's menus.
839   \param on if \c true, show menus, otherwise, hide all menus
840   \sa setToolShown()
841 */
842 void CAM_Module::setMenuShown( const bool on )
843 {
844   myMenuShown = on;
845
846   QtxActionMenuMgr* mMgr = menuMgr();
847   if ( !mMgr )
848     return;
849
850   bool upd = mMgr->isUpdatesEnabled();
851   mMgr->setUpdatesEnabled( false );
852
853   QAction* sep = separator();
854   for ( QMap<int, QAction*>::Iterator it = myActionMap.begin(); it != myActionMap.end(); ++it )
855   {
856     if ( it.value() != sep )
857       mMgr->setShown( mMgr->actionId( it.value() ), on );
858   }
859
860   mMgr->setUpdatesEnabled( upd );
861   if ( upd )
862     mMgr->update();
863 }
864
865 /*!
866   \brief Show/hide specified menu item.
867   \param a action
868   \param on if \c true, show menu item, otherwise, hide it
869 */
870 void CAM_Module::setMenuShown( QAction* a, const bool on )
871 {
872   if ( menuMgr() )
873     menuMgr()->setShown( menuMgr()->actionId( a ), on );
874 }
875
876 /*!
877   \brief Show/hide specified menu item.
878   \param id menu item ID
879   \param on if \c true, show menu item, otherwise, hide it
880 */
881 void CAM_Module::setMenuShown( const int id, const bool on )
882 {
883   setMenuShown( action( id ), on );
884 }
885
886 /*!
887   \brief Show/hide all module's toolbars.
888   \param on if \c true, show toolbars, otherwise, hide all toolbars
889   \sa setMenuShown()
890 */
891 void CAM_Module::setToolShown( const bool on )
892 {
893   myToolShown = on;
894
895   QtxActionToolMgr* tMgr = toolMgr();
896   if ( !tMgr )
897     return;
898
899   bool upd = tMgr->isUpdatesEnabled();
900   tMgr->setUpdatesEnabled( false );
901
902   QAction* sep = separator();
903   for ( QMap<int, QAction*>::Iterator it = myActionMap.begin(); it != myActionMap.end(); ++it )
904   {
905     if ( it.value() != sep )
906       tMgr->setShown( tMgr->actionId( it.value() ), on );
907   }
908
909   tMgr->setUpdatesEnabled( upd );
910   if ( upd )
911     tMgr->update();
912 }
913
914 /*!
915   \brief Show/hide specified toolbar item.
916   \param a action
917   \param on if \c true, show toolbar item, otherwise, hide it
918 */
919 void CAM_Module::setToolShown( QAction* a, const bool on )
920 {
921   if ( toolMgr() )
922     toolMgr()->setShown( toolMgr()->actionId( a ), on );
923 }
924
925 /*!
926   \brief Show/hide specified toolbar item.
927   \param id toolbar item ID
928   \param on if \c true, show toolbar item, otherwise, hide it
929 */
930 void CAM_Module::setToolShown( const int id, const bool on )
931 {
932   setToolShown( action( id ), on );
933 }
934
935 /*!
936   \brief Get action by specified \a id.
937   \param id action ID
938   \return action or 0 if not found
939 */
940 QAction* CAM_Module::action( const int id ) const
941 {
942   QAction* a = 0;
943   if ( myActionMap.contains( id ) )
944     a = myActionMap[id];
945   else if ( menuMgr() ) {
946     QMenu* m = menuMgr()->findMenu( id );
947     if ( m ) a = m->menuAction();
948   }
949   return a;
950 }
951
952 /*!
953   \brief Get action ID.
954   \param a action
955   \return action ID or -1 if not found
956 */
957 int CAM_Module::actionId( const QAction* a ) const
958 {
959   int id = -1;
960   for ( QMap<int, QAction*>::ConstIterator it = myActionMap.begin(); it != myActionMap.end() && id == -1; ++it )
961   {
962     if ( it.value() == a )
963       id = it.key();
964   }
965   return id;
966 }
967
968 /*!
969   \brief Create new instance of QtxAction and register action with specified \a id.
970
971   Resulting action ID may differ from the requested one. This can happen if
972   requested ID is already in use.
973
974   If \a id < 0, the action ID is generated automatically.
975
976   \param id required action ID
977   \param text tooltip text
978   \param icon action icon
979   \param menu menu text
980   \param tip status bar tip
981   \param key keyboard accelerator
982   \param parent parent object
983   \param toggle if \c true, the action will be toggled
984   \param reciever action activation signal receiver object
985   \param member action activation signal receiver slot
986 */
987 QAction* CAM_Module::createAction( const int id, const QString& text, const QIcon& icon,
988                                    const QString& menu, const QString& tip, const int key,
989                                    QObject* parent, const bool toggle, QObject* reciever,
990                                    const char* member, const QString& shortcutAction )
991 {
992   return createAction( id, text, icon, menu, tip, QKeySequence(key), parent, toggle, reciever, member, shortcutAction );
993 }
994
995 /*!
996   \brief Create new instance of QtxAction and register action with specified \a id.
997
998   Resulting action ID may differ from the requested one. This can happen if
999   requested ID is already in use.
1000
1001   If \a id < 0, the action ID is generated automatically.
1002
1003   \param id required action ID
1004   \param text tooltip text
1005   \param icon action icon
1006   \param menu menu text
1007   \param tip status bar tip
1008   \param key keyboard accelerator
1009   \param parent parent object
1010   \param toggle if \c true, the action will be toggled
1011   \param reciever action activation signal receiver object
1012   \param member action activation signal receiver slot
1013 */
1014 QAction* CAM_Module::createAction( const int id, const QString& text, const QIcon& icon,
1015                                    const QString& menu, const QString& tip, const QKeySequence& key,
1016                                    QObject* parent, const bool toggle, QObject* reciever,
1017                                    const char* member, const QString& shortcutAction )
1018 {
1019   QtxAction* a = new QtxAction( text, icon, menu, key, parent, toggle, shortcutAction );
1020   a->setStatusTip( tip );
1021
1022   connect( a, SIGNAL( triggered( bool ) ), this, SLOT( moduleActionActivated() ), Qt::UniqueConnection );
1023
1024   if ( reciever && member )
1025     connect( a, SIGNAL( triggered( bool ) ), reciever, member );
1026
1027   registerAction( id, a );
1028
1029   return a;
1030 }
1031
1032 /*!
1033   \brief Create new action group.
1034   \param id action group ID
1035   \param exclusive \c true for exclusive action group
1036   \return created action group
1037 */
1038 QtxActionGroup* CAM_Module::createActionGroup( const int id, const bool exclusive )
1039 {
1040   QtxActionGroup* a = qobject_cast<QtxActionGroup*>( action( id ) );
1041   if ( !a ) {
1042     a = new QtxActionGroup( this );
1043     registerAction( id, a );
1044   }
1045   a->setExclusive( exclusive );
1046   return a;
1047 }
1048
1049 /*!
1050   \brief Register action in the internal action map.
1051
1052   If action has been already added previously, its ID is just returned.
1053   If \a id < 0, the action ID is generated automatically.
1054
1055   \param id action required ID
1056   \param a action
1057   \return action ID
1058 */
1059 int CAM_Module::registerAction( const int id, QAction* a )
1060 {
1061   int ident = -1;
1062   for ( QMap<int, QAction*>::ConstIterator it = myActionMap.begin(); it != myActionMap.end() && ident == -1; ++it )
1063     if ( it.value() == a )
1064       ident = it.key();
1065
1066   if ( ident != -1 )
1067     return ident;
1068
1069   static int generatedId = -1;
1070   ident = id < 0 ? --generatedId : id;
1071
1072   myActionMap.insert( ident, a );
1073
1074   if ( menuMgr() )
1075     menuMgr()->registerAction( a );
1076
1077   if ( toolMgr() )
1078     toolMgr()->registerAction( a );
1079
1080   if ( application() && application()->desktop() &&
1081        a->shortcutContext() != Qt::WidgetShortcut &&
1082        a->shortcutContext() != Qt::WidgetWithChildrenShortcut )
1083     application()->desktop()->addAction( a );
1084
1085   return ident;
1086 }
1087
1088 /*!
1089   \brief Unregister action from the internal action map.
1090
1091   \param id action ID
1092   \return \c true on success or \c false if action is in use
1093 */
1094 bool CAM_Module::unregisterAction( const int id )
1095 {
1096   return unregisterAction( action( id ) );
1097 }
1098
1099 /*!
1100   \brief Unregister action from the internal action map.
1101
1102   \param a action
1103   \return \c true on success or \c false if action is in use
1104 */
1105 bool CAM_Module::unregisterAction( QAction* a )
1106 {
1107   if ( !a )
1108     return false;
1109   if ( menuMgr() ) {
1110     int id = menuMgr()->actionId( a );
1111     if ( id != -1 && menuMgr()->containsMenu( id, -1 ) )
1112       return false;
1113   }
1114   if ( toolMgr() ) {
1115     int id = toolMgr()->actionId( a );
1116     if ( id != -1 && toolMgr()->containsAction( id ) )
1117       return false;
1118   }
1119   if ( menuMgr() )
1120     menuMgr()->unRegisterAction( menuMgr()->actionId( a ) );
1121   if ( toolMgr() )
1122     toolMgr()->unRegisterAction( toolMgr()->actionId( a ) );
1123   return true;
1124 }
1125
1126 /*!
1127   \brief Create separator action.
1128
1129   Separator action can be used in menus or toolbars.
1130
1131   \return new separator action
1132 */
1133 QAction* CAM_Module::separator()
1134 {
1135   return QtxActionMgr::separator();
1136 }
1137
1138 /*!
1139   \brief Update visibility state of the module objects.
1140 */
1141 void CAM_Module::updateModuleVisibilityState() {
1142
1143 }
1144
1145 /*!
1146   \brief Activate GUI operation of module by its ID.
1147   This method is called from CAM_Application::startOperation().
1148   \param actionId is a numerical unique operation id.
1149 */
1150 bool CAM_Module::activateOperation( int /*actionId*/ )
1151 {
1152   return false;
1153 }
1154
1155 /*!
1156   \brief Activate GUI operation of module by its ID.
1157   This method is called from CAM_Application::startOperation().
1158   \param actionId is a string unique operation id.
1159 */
1160 bool CAM_Module::activateOperation( const QString& /*actionId*/ )
1161 {
1162   return false;
1163 }
1164
1165 /*!
1166   \brief Activate GUI operation of module by its ID and \a pluginName.
1167   This method is called from CAM_Application::startOperation().
1168   \param actionId is a string unique operation id.
1169   \param pluginName is a name of a plugin where the operation is implemented.
1170 */
1171 bool CAM_Module::activateOperation( const QString& /*actionId*/, const QString& /*pluginName*/ )
1172 {
1173   return false;
1174 }
1175
1176
1177 /*!
1178   \brief Connect data model of the module to the active study
1179   \param camStudy CAM study object
1180 */
1181 void CAM_Module::connectToStudy( CAM_Study* camStudy )
1182 {
1183   CAM_Application* app = camStudy ? dynamic_cast<CAM_Application*>( camStudy->application() ) : 0;
1184   if( !app )
1185     return;
1186
1187   CAM_DataModel* prev = 0;
1188   CAM_Application::ModuleList mods = app->modules();
1189   for( QList<CAM_Module*>::const_iterator it = mods.begin(); it != mods.end(); ++it )
1190   {
1191     CAM_DataModel* dm = (*it)->dataModel();
1192     if( (*it) == this && !camStudy->containsDataModel( dm ) )
1193     {
1194       if ( prev )
1195         camStudy->insertDataModel( (*it)->dataModel(), prev );
1196       else
1197         camStudy->insertDataModel( (*it)->dataModel(), 0 );
1198     }
1199     prev = dm;
1200   }
1201 }
1202
1203 /*!
1204   \fn void CAM_Module::contextMenuPopup( const QString& type, QMenu* menu, QString& title );
1205   \brief Create context popup menu.
1206   \param type popup menu context
1207   \param menu popup menu
1208   \param title popup menu title, which can be set by the module if required
1209 */
1210
1211 /*!
1212   \fn void CAM_Module::updateCommandsStatus();
1213   \brief Update menu/toolbar actions.
1214 */
1215
1216
1217 bool CAM_Module::abortAllOperations()
1218 {
1219   return true;
1220 }
1221
1222 /*!
1223   \brief Called when an action is triggered
1224 */
1225 void CAM_Module::moduleActionActivated()
1226 {
1227   QAction* action = qobject_cast<QAction*>( sender() );
1228   if ( action && !action->isSeparator() && isActionLoggingEnabled() )
1229     logAction( action );
1230 }
1231
1232 /*!
1233   \brief Log given action.
1234   \param action GUI action being logged.
1235
1236   Default implementation just forwards to CAM_Applicaion::logAction();
1237 */
1238 void CAM_Module::logAction( QAction* action )
1239 {
1240   CAM_Application::logAction( action, moduleName() );
1241 }
1242
1243 /*!
1244   \brief Return \c true if action logging is enabled.
1245 */
1246 bool CAM_Module::isActionLoggingEnabled() const
1247 {
1248   return myActionLoggingEnabled;
1249 }
1250
1251 /*!
1252   \brief Enable / disable action logging.
1253   \param enabled \c true to enable logging, or \c false to disable it.
1254 */
1255 void CAM_Module::setActionLoggingEnabled( bool enabled )
1256 {
1257   myActionLoggingEnabled = enabled;
1258 }