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