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