Salome HOME
d3dde1a21557299bf381095074cfa5612bcc0aa7
[modules/gui.git] / src / CAM / CAM_Module.cxx
1 //  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 //  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 //  This library is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU Lesser General Public
8 //  License as published by the Free Software Foundation; either
9 //  version 2.1 of the License.
10 //
11 //  This library is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 //  Lesser General Public License for more details.
15 //
16 //  You should have received a copy of the GNU Lesser General Public
17 //  License along with this library; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 #include "CAM_Module.h"
23
24 #include "CAM_DataModel.h"
25 #include "CAM_Application.h"
26 #include "CAM_Study.h"
27
28 #include <QtxAction.h>
29 #include <QtxActionMenuMgr.h>
30 #include <QtxActionToolMgr.h>
31
32 #include <SUIT_Desktop.h>
33 #include <SUIT_Session.h>
34 #include <SUIT_ResourceMgr.h>
35
36 /*!
37   \class CAM_Module
38   \brief Base implementation of the module in the CAM application architecture.
39
40   Provides support of menu/toolbars management.
41 */
42
43 /*!
44   \brief Default constructor.
45
46   Creates unnamed module.
47 */
48 CAM_Module::CAM_Module()
49 : QObject(),
50   myApp( 0 ),
51   myDataModel( 0 )
52 {
53 }
54
55 /*!
56   \brief Constructor.
57
58   Creates module with the specified \a name.
59
60   \param name module name
61 */
62 CAM_Module::CAM_Module( const QString& name )
63 : QObject(),
64   myApp( 0 ),
65   myName( name ),
66   myDataModel( 0 )
67 {
68 }
69
70 /*!
71   \brief Destructor.
72
73   Destroy data model.
74 */
75 CAM_Module::~CAM_Module()
76 {
77   delete myDataModel;
78   myDataModel = 0;
79 }
80
81 /*!
82   \brief Initialize module.
83
84   This method is usually called when the module is created (for example,
85   on the module library loading).
86   Successor classes can use this method to create menu/toolbar actions
87   and perform other module initialization.
88
89   \param app parent application object
90   \sa activateModule(), deactivateModule()
91 */
92 void CAM_Module::initialize( CAM_Application* app )
93 {
94   myApp = app;
95   if ( myApp )
96   {
97     SUIT_Session* aSession = SUIT_Session::session();
98     connect( aSession, SIGNAL( applicationClosed( SUIT_Application* ) ),
99              this, SLOT( onApplicationClosed( SUIT_Application* ) ) );
100
101     connect( myApp, SIGNAL( infoChanged( QString ) ), this, SLOT( onInfoChanged( QString ) ) );
102   }
103 }
104
105 /*!
106   \brief Get module icon.
107   \return module icon pixmap
108   \sa iconName()
109 */
110 QPixmap CAM_Module::moduleIcon() const
111 {
112   if ( myIcon.isNull() ) {
113     QString iname = iconName();
114     if ( !iname.isEmpty() ) {
115       CAM_Module* that = (CAM_Module*)this;
116       that->myIcon = application()->resourceMgr()->loadPixmap( name(), iname, false );
117     }
118   }
119   return myIcon;
120 }
121
122 /*!
123   \brief Get module icon's name.
124
125   This function is used to get module icon's file name.
126   Default implementation returns empty string.
127
128   \return module icon's name.
129   \sa moduleIcon()
130 */
131 QString CAM_Module::iconName() const
132 {
133   return application()->moduleIcon( name() );
134 }
135
136 /*!
137   \brief Get module (internal) name
138   \return module name
139   \sa setName(), moduleName(), setModuleName()
140 */
141 QString CAM_Module::name() const
142 {
143   return objectName();
144 }
145
146 /*!
147   \brief Get module title (user name)
148   \return module title
149   \sa setModuleName(), name(), setName()
150 */
151 QString CAM_Module::moduleName() const
152 {
153   return myName;
154 }
155
156 /*!
157   \brief Get data model.
158
159   Creates data model, if it is not yet created.
160
161   \return data model pointer
162   \sa createDataModel()
163 */
164 CAM_DataModel* CAM_Module::dataModel() const
165 {
166   if ( !myDataModel )
167   {
168     CAM_Module* that = (CAM_Module*)this;
169     that->myDataModel = that->createDataModel();
170     that->myDataModel->initialize();
171   }
172   return myDataModel;
173 }
174
175 /*!
176   \brief Get application.
177   \return application pointer
178 */
179 CAM_Application* CAM_Module::application() const
180 {
181   return myApp;
182 }
183
184 /*!
185   \brief If return false, selection will be cleared at module activation
186 */
187 bool CAM_Module::isSelectionCompatible()
188 {
189   return false;
190 }
191
192 /*!
193   \brief Activate module.
194
195   This method is called when the user activates module.
196   Successor classes can use this method to customize module activation process,
197   for example, to show own menus, toolbars, etc.
198
199   Default implementation always returns \c true.
200
201   \return \c true if module is activated successfully.
202   \sa initialize(), deactivateModule()
203  */
204 bool CAM_Module::activateModule( SUIT_Study* /*study*/ )
205 {
206   return true;
207 }
208
209 /*!
210   \brief Deactivate module.
211
212   This method is called when the user deactivates module.
213   Successor classes can use this method to customize module deactivation process,
214   for example, to hide own menus, toolbars, etc.
215
216   Default implementation always returns \c true.
217
218   \return \c true if module is deactivated successfully.
219   \sa initialize(), activateModule()
220  */
221 bool CAM_Module::deactivateModule( SUIT_Study* )
222 {
223   return true;
224 }
225
226 /*!
227   \brief Called when study is closed.
228
229   Removes data model from the \a study.
230
231   \param study study being closed
232 */
233 void CAM_Module::studyClosed( SUIT_Study* study )
234 {
235   CAM_Study* camDoc = dynamic_cast<CAM_Study*>( study );
236   if ( !camDoc )
237     return;
238
239   CAM_DataModel* dm = dataModel();
240   if ( dm && camDoc->containsDataModel( dm ) ) {
241     dm->close();
242     camDoc->removeDataModel( dm );
243   }
244 }
245
246 /*!
247   \brief Called when study is changed (obsolete).
248
249   Default implementation does nothing.
250
251   \param oldStudy old study
252   \param newStudy new study
253 */
254 void CAM_Module::studyChanged( SUIT_Study* /*oldStudy*/, SUIT_Study* /*newStudy*/ )
255 {
256 }
257
258 /*!
259   \brief Check if the module is active.
260   \return \c true if module is active.
261 */
262 bool CAM_Module::isActiveModule() const
263 {
264   return application() ? application()->activeModule() == this : false;
265 }
266
267 /*!
268   \brief Put the text message into the status bar of the application main window.
269
270   If \a msec > 0, the message will be shown \a msec milliseconds.
271   If \a msec < 0, the message will be constantly displayed until module is active.
272
273   \param msg text message
274   \param msec message displaying duration in milliseconds
275 */
276 void CAM_Module::putInfo( const QString& msg, const int msec )
277 {
278   if ( application() )
279     application()->putInfo( msg, msec );
280
281   if ( msec < 0 )
282     myInfo = msg;
283 }
284
285 /*!
286   \brief Restore message info.
287
288   Restores constant text message when previous information status message is removed.
289
290   \param txt previous message (being removed)
291   \sa putInfo()
292 */
293 void CAM_Module::onInfoChanged( QString txt )
294 {
295   if ( txt.isEmpty() && isActiveModule() && !myInfo.isEmpty() && application() )
296     application()->putInfo( myInfo );
297 }
298
299 /*!
300   \brief Called when application is closed.
301
302   Nullify application pointer if the application is being closed.
303
304   \param theApp application
305 */
306 void CAM_Module::onApplicationClosed( SUIT_Application* theApp )
307 {
308   if (myApp == theApp)
309     myApp = NULL;
310 }
311
312 /*!
313   \brief Create data model.
314   \return created data model object or 0 if it could not be created
315 */
316 CAM_DataModel* CAM_Module::createDataModel()
317 {
318   return new CAM_DataModel( this );
319 }
320
321 /*!
322   \brief Set module (internal) name
323   \param name new module name
324   \sa name(), moduleName(), setModuleName()
325  */
326 void CAM_Module::setName( const QString& name )
327 {
328   setObjectName( name );
329 }
330
331 /*!
332   \brief Set module title (user name)
333   \param name new module title
334   \sa moduleName(), name(), setName()
335  */
336 void CAM_Module::setModuleName( const QString& name )
337 {
338   myName = name;
339 }
340
341 /*!
342   \brief Get menu manager.
343   \return menu manager pointer
344 */
345 QtxActionMenuMgr* CAM_Module::menuMgr() const
346 {
347   QtxActionMenuMgr* mgr = 0;
348   if ( application() && application()->desktop() )
349     mgr = application()->desktop()->menuMgr();
350   return mgr;
351 }
352
353 /*!
354   \brief Get toolbar manager.
355   \return toolbar manager pointer
356 */
357 QtxActionToolMgr* CAM_Module::toolMgr() const
358 {
359   QtxActionToolMgr* mgr = 0;
360   if ( application() && application()->desktop() )
361     mgr = application()->desktop()->toolMgr();
362   return mgr;
363 }
364
365 /*!
366   \brief Create toolbar with speicifed \a name.
367
368   If the toolbar has been already created, its ID is just returned.
369
370   \param name toolbar name
371   \return toolbar ID or -1 if toolbar could not be created
372 */
373 int CAM_Module::createTool( const QString& name )
374 {
375   if ( !toolMgr() )
376     return -1;
377
378   return toolMgr()->createToolBar( name );
379 }
380
381 /*!
382   \brief Add toolbar item.
383
384   Insert action \a to the toolbar manager and register it with specified \a id.
385   Resulting action ID may differ from the requested one. This can happen if
386   requested ID is already in use.
387
388   If action has been already added previously, its ID is just returned.
389
390   If \a id < 0, the action ID is generated automatically.
391
392   If \a idx < 0, the action is added to the end of the toolbar.
393
394   \param a action
395   \param tBar toolbar ID
396   \param id requested action ID
397   \param idx action index (desired position in the toolbar)
398   \return action ID or -1 if toolbar item could not be added
399 */
400 int CAM_Module::createTool( QAction* a, const int tBar, const int id, const int idx )
401 {
402   if ( !toolMgr() )
403     return -1;
404
405   int regId = registerAction( id, a );
406   int intId = toolMgr()->insert( a, tBar, idx );
407   return intId != -1 ? regId : -1;
408 }
409
410 /*!
411   \brief Add toolbar item.
412
413   Insert action \a to the toolbar manager and register it with specified \a id.
414   Resulting action ID may differ from the requested one. This can happen if
415   requested ID is already in use.
416
417   If action has been already added previously, its ID is just returned.
418
419   If \a id < 0, the action ID is generated automatically.
420
421   If \a idx < 0, the action is added to the end of the toolbar.
422
423   \param a action
424   \param tBar toolbar name
425   \param id requested action ID
426   \param idx action index (desired position in the toolbar)
427   \return action ID or -1 if toolbar item could not be added
428 */
429 int CAM_Module::createTool( QAction* a, const QString& tBar, const int id, const int idx )
430 {
431   if ( !toolMgr() )
432     return -1;
433
434   int regId = registerAction( id, a );
435   int intId = toolMgr()->insert( a, tBar, idx );
436   return intId != -1 ? regId : -1;
437 }
438
439 /*!
440   \brief Add toolbar item.
441
442   Insert action with \a id identifier to the toolbar manager.
443   It is assumed that action has been already registered.
444
445   Resulting action ID may differ from the requested one. This can happen if
446   requested ID is already in use.
447
448   If action has been already added previously, its ID is just returned.
449
450   If \a idx < 0, the action is added to the end of the toolbar.
451
452   \param id action ID
453   \param tBar toolbar ID
454   \param idx action index (desired position in the toolbar)
455   \return action ID or -1 if toolbar item could not be added
456 */
457 int CAM_Module::createTool( const int id, const int tBar, const int idx )
458 {
459   if ( !toolMgr() )
460     return -1;
461
462   int intId = toolMgr()->insert( action( id ), tBar, idx );
463   return intId != -1 ? id : -1;
464 }
465
466 /*!
467   \brief Add toolbar item.
468
469   Insert action with \a id identifier to the toolbar manager.
470   It is assumed that action has been already registered.
471
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 idx < 0, the action is added to the end of the toolbar.
478
479   \param id action ID
480   \param tBar toolbar name
481   \param idx action index (desired position in the toolbar)
482   \return action ID or -1 if toolbar item could not be added
483 */
484 int CAM_Module::createTool( const int id, const QString& tBar, const int idx )
485 {
486   if ( !toolMgr() )
487     return -1;
488
489   int intId = toolMgr()->insert( action( id ), tBar, idx );
490   return intId != -1 ? id : -1;
491 }
492
493 /*!
494   \brief Create menu or submenu.
495
496   Create main menu or popup submenu and register it with specified \a id.
497   Resulting action ID may differ from the requested one. This can happen if
498   requested ID is already in use.
499
500   If \a id < 0, the menu ID is generated automatically.
501   If menu has been already created previously, its ID is just returned.
502
503   The \a menu parameter represents the menu name - it could be a sequence
504   of strings, separated by '|' symbol. For example, "File|Edit" means
505   File->Edit submenu. If menu doesn't exist, it is created automatically.
506
507   Parameter \a idx defines the index of the menu item in the menu group which
508   is defined by the \a group. If \a idx < 0, the menu/submenu is added to the
509   end of the menu group.
510
511   \param subMenu subMenu name
512   \param menu parent menu ID
513   \param id requested menu ID
514   \param group menu group ID
515   \param idx menu item index (desired position in the menu group)
516   \return menu item ID or -1 if menu item could not be added
517 */
518 int CAM_Module::createMenu( const QString& subMenu, const int menu,
519                             const int id, const int group, const int idx )
520 {
521   if ( !menuMgr() )
522     return -1;
523
524   return menuMgr()->insert( subMenu, menu, group, id, idx );
525 }
526
527 /*!
528   \brief Create menu or submenu.
529
530   Create main menu or popup submenu and register it with specified \a id.
531   Resulting action ID may differ from the requested one. This can happen if
532   requested ID is already in use.
533
534   If \a id < 0, the menu ID is generated automatically.
535   If menu has been already created previously, its ID is just returned.
536
537   The \a menu parameter represents the menu name - it could be a sequence
538   of strings, separated by '|' symbol. For example, "File|Edit" means
539   File->Edit submenu. If menu doesn't exist, it is created automatically.
540
541   Parameter \a idx defines the index of the menu item in the menu group which
542   is defined by the \a group. If \a idx < 0, the menu/submenu is added to the
543   end of the menu group.
544
545   \param subMenu subMenu name
546   \param menu parent menu name(s)
547   \param id requested menu ID
548   \param group menu group ID
549   \param idx menu item index (desired position in the menu group)
550   \return menu item ID or -1 if menu item could not be added
551 */
552 int CAM_Module::createMenu( const QString& subMenu, const QString& menu,
553                             const int id, const int group, const int idx )
554 {
555   if ( !menuMgr() )
556     return -1;
557
558   return menuMgr()->insert( subMenu, menu, group, id, idx );
559 }
560
561 /*!
562   \brief Add menu item.
563
564   Insert action \a to the menu manager and register it with specified \a id.
565   Resulting action ID may differ from the requested one. This can happen if
566   requested ID is already in use.
567
568   If \a id < 0, the action ID is generated automatically.
569
570   If action has been already added previously, its ID is just returned.
571
572   Parameter \a idx defines the index of the menu item in the menu group which
573   is defined by the \a group. If \a idx < 0, the action is added to the
574   end of the menu group.
575
576   \param a action
577   \param menu menu ID
578   \param id requested action ID
579   \param group menu group ID
580   \param idx action index (desired position in the menu group)
581   \return action ID or -1 if menu item could not be added
582 */
583 int CAM_Module::createMenu( QAction* a, const int menu, const int id, const int group, const int idx )
584 {
585   if ( !a || !menuMgr() )
586     return -1;
587
588   int regId = registerAction( id, a );
589   int intId = menuMgr()->insert( a, menu, group, idx );
590   return intId != -1 ? regId : -1;
591 }
592
593 /*!
594   \brief Add menu item.
595
596   Insert action \a to the menu manager and register it with specified \a id.
597   Resulting action ID may differ from the requested one. This can happen if
598   requested ID is already in use.
599
600   If \a id < 0, the action ID is generated automatically.
601
602   If action has been already added previously, its ID is just returned.
603
604   The \a menu parameter represents the menu name - it could be a sequence
605   of strings, separated by '|' symbol. For example, "File|Edit" means
606   File->Edit submenu. If menu doesn't exist, it is created automatically.
607
608   Parameter \a idx defines the index of the menu item in the menu group which
609   is defined by the \a group. If \a idx < 0, the action is added to the
610   end of the menu group.
611
612   \param a action
613   \param menu menu name(s)
614   \param id requested action ID
615   \param group menu group ID
616   \param idx action index (desired position in the menu group)
617   \return action ID or -1 if menu item could not be added
618 */
619 int CAM_Module::createMenu( QAction* a, const QString& menu, const int id, const int group, const int idx )
620 {
621   if ( !a || !menuMgr() )
622     return -1;
623
624   int regId = registerAction( id, a );
625   int intId = menuMgr()->insert( a, menu, group, idx );
626   return intId != -1 ? regId : -1;
627 }
628
629 /*!
630   \brief Add menu item.
631
632   Insert action with \a id identifier to the menu manager.
633   It is assumed that action has been already registered.
634
635   Resulting action ID may differ from the requested one. This can happen if
636   requested ID is already in use.
637
638   If action has been already added previously, its ID is just returned.
639
640   Parameter \a idx defines the index of the menu item in the menu group which
641   is defined by the \a group. If \a idx < 0, the action is added to the
642   end of the menu group.
643
644   \param id action ID
645   \param menu menu ID
646   \param group menu group ID
647   \param idx action index (desired position in the menu group)
648   \return action ID or -1 if menu item could not be added
649 */
650 int CAM_Module::createMenu( const int id, const int menu, const int group, const int idx )
651 {
652   if ( !menuMgr() )
653     return -1;
654
655   int intId = menuMgr()->insert( action( id ), menu, group, idx );
656   return intId != -1 ? id : -1;
657 }
658
659 /*!
660   \brief Add menu item.
661
662   Insert action with \a id identifier to the menu manager.
663   It is assumed that action has been already registered.
664
665   Resulting action ID may differ from the requested one. This can happen if
666   requested ID is already in use.
667
668   If action has been already added previously, its ID is just returned.
669
670   The \a menu parameter represents the menu name - it could be a sequence
671   of strings, separated by '|' symbol. For example, "File|Edit" means
672   File->Edit submenu. If menu doesn't exist, it is created automatically.
673
674   Parameter \a idx defines the index of the menu item in the menu group which
675   is defined by the \a group. If \a idx < 0, the action is added to the
676   end of the menu group.
677
678   \param id action ID
679   \param menu menu name(s)
680   \param group menu group ID
681   \param idx action index (desired position in the menu group)
682   \return action ID or -1 if menu item could not be added
683 */
684 int CAM_Module::createMenu( const int id, const QString& menu, const int group, const int idx )
685 {
686   if ( !menuMgr() )
687     return -1;
688
689   int intId = menuMgr()->insert( action( id ), menu, group, idx );
690   return intId != -1 ? id : -1;
691 }
692
693 /*!
694   \brief Show/hide all module's menus.
695   \param on if \c true, show menus, otherwise, hide all menus
696   \sa setToolShown()
697 */
698 void CAM_Module::setMenuShown( const bool on )
699 {
700   QtxActionMenuMgr* mMgr = menuMgr();
701   if ( !mMgr )
702     return;
703
704   bool upd = mMgr->isUpdatesEnabled();
705   mMgr->setUpdatesEnabled( false );
706
707   QAction* sep = separator();
708   for ( QMap<int, QAction*>::Iterator it = myActionMap.begin(); it != myActionMap.end(); ++it )
709   {
710     if ( it.value() != sep )
711       mMgr->setShown( mMgr->actionId( it.value() ), on );
712   }
713
714   mMgr->setUpdatesEnabled( upd );
715   if ( upd )
716     mMgr->update();
717 }
718
719 /*!
720   \brief Show/hide specified menu item.
721   \param a action
722   \param on if \c true, show menu item, otherwise, hide it
723 */
724 void CAM_Module::setMenuShown( QAction* a, const bool on )
725 {
726   if ( menuMgr() )
727     menuMgr()->setShown( menuMgr()->actionId( a ), on );
728 }
729
730 /*!
731   \brief Show/hide specified menu item.
732   \param id menu item ID
733   \param on if \c true, show menu item, otherwise, hide it
734 */
735 void CAM_Module::setMenuShown( const int id, const bool on )
736 {
737   setMenuShown( action( id ), on );
738 }
739
740 /*!
741   \brief Show/hide all module's toolbars.
742   \param on if \c true, show toolbars, otherwise, hide all toolbars
743   \sa setMenuShown()
744 */
745 void CAM_Module::setToolShown( const bool on )
746 {
747   QtxActionToolMgr* tMgr = toolMgr();
748   if ( !tMgr )
749     return;
750
751   bool upd = tMgr->isUpdatesEnabled();
752   tMgr->setUpdatesEnabled( false );
753
754   QAction* sep = separator();
755   for ( QMap<int, QAction*>::Iterator it = myActionMap.begin(); it != myActionMap.end(); ++it )
756   {
757     if ( it.value() != sep )
758       tMgr->setShown( tMgr->actionId( it.value() ), on );
759   }
760
761   tMgr->setUpdatesEnabled( upd );
762   if ( upd )
763     tMgr->update();
764 }
765
766 /*!
767   \brief Show/hide specified toolbar item.
768   \param a action
769   \param on if \c true, show toolbar item, otherwise, hide it
770 */
771 void CAM_Module::setToolShown( QAction* a, const bool on )
772 {
773   if ( toolMgr() )
774     toolMgr()->setShown( toolMgr()->actionId( a ), on );
775 }
776
777 /*!
778   \brief Show/hide specified toolbar item.
779   \param id toolbar item ID
780   \param on if \c true, show toolbar item, otherwise, hide it
781 */
782 void CAM_Module::setToolShown( const int id, const bool on )
783 {
784   setToolShown( action( id ), on );
785 }
786
787 /*!
788   \brief Get action by specified \a id.
789   \param id action ID
790   \return action or 0 if not found
791 */
792 QAction* CAM_Module::action( const int id ) const
793 {
794   QAction* a = 0;
795   if ( myActionMap.contains( id ) )
796     a = myActionMap[id];
797   return a;
798 }
799
800 /*!
801   \brief Get action ID.
802   \param a action
803   \return action ID or -1 if not found
804 */
805 int CAM_Module::actionId( const QAction* a ) const
806 {
807   int id = -1;
808   for ( QMap<int, QAction*>::ConstIterator it = myActionMap.begin(); it != myActionMap.end() && id == -1; ++it )
809   {
810     if ( it.value() == a )
811       id = it.key();
812   }
813   return id;
814 }
815
816 /*!
817   \brief Create new instance of QtxAction and register action with specified \a id.
818
819   Resulting action ID may differ from the requested one. This can happen if
820   requested ID is already in use.
821
822   If \a id < 0, the action ID is generated automatically.
823
824   \param id required action ID
825   \param text tooltip text
826   \param icon action icon
827   \param menu menu text
828   \param tip status bar tip
829   \param key keyboard accelerator
830   \param parent parent object
831   \param toggle if \c true, the action will be toggled
832   \param reciever action activation signal receiver object
833   \param member action activation signal receiver slot
834 */
835 QAction* CAM_Module::createAction( const int id, const QString& text, const QIcon& icon,
836                                    const QString& menu, const QString& tip, const int key,
837                                    QObject* parent, const bool toggle, QObject* reciever, const char* member )
838 {
839   QtxAction* a = new QtxAction( text, icon, menu, key, parent, toggle );
840   a->setStatusTip( tip );
841
842   if ( reciever && member )
843     connect( a, SIGNAL( triggered( bool ) ), reciever, member );
844
845   registerAction( id, a );
846
847   return a;
848 }
849
850 /*!
851   \brief Register action in the internal action map.
852
853   If action has been already added previously, its ID is just returned.
854   If \a id < 0, the action ID is generated automatically.
855
856   \param id action required ID
857   \param a action
858   \return action ID
859 */
860 int CAM_Module::registerAction( const int id, QAction* a )
861 {
862   int ident = -1;
863   for ( QMap<int, QAction*>::ConstIterator it = myActionMap.begin(); it != myActionMap.end() && ident == -1; ++it )
864     if ( it.value() == a )
865       ident = it.key();
866
867   if ( ident != -1 )
868     return ident;
869
870   static int generatedId = -1;
871   ident = id < 0 ? --generatedId : id;
872
873   myActionMap.insert( ident, a );
874
875   if ( menuMgr() )
876     menuMgr()->registerAction( a );
877
878   if ( toolMgr() )
879     toolMgr()->registerAction( a );
880
881   if ( application() && application()->desktop() )
882     application()->desktop()->addAction( a );
883
884   return ident;
885 }
886
887 /*!
888   \brief Unregister action from the internal action map.
889
890   \param id action ID
891   \return \c true on success or \c false if action is in use
892 */
893 bool CAM_Module::unregisterAction( const int id )
894 {
895   return unregisterAction( action( id ) );
896 }
897
898 /*!
899   \brief Unregister action from the internal action map.
900
901   \param a action
902   \return \c true on success or \c false if action is in use
903 */
904 bool CAM_Module::unregisterAction( QAction* a )
905 {
906   if ( !a )
907     return false;
908   if ( menuMgr() ) {
909     int id = menuMgr()->actionId( a );
910     if ( id != -1 && menuMgr()->containsMenu( id, -1 ) )
911       return false;
912   }
913   if ( toolMgr() ) {
914     int id = toolMgr()->actionId( a );
915     if ( id != -1 && toolMgr()->containsAction( id ) )
916       return false;
917   }
918   if ( menuMgr() )
919     menuMgr()->unRegisterAction( menuMgr()->actionId( a ) );
920   if ( toolMgr() )
921     toolMgr()->unRegisterAction( toolMgr()->actionId( a ) );
922   return true;
923 }
924
925 /*!
926   \brief Create separator action.
927
928   Separator action can be used in menus or toolbars.
929
930   \return new separator action
931 */
932 QAction* CAM_Module::separator()
933 {
934   return QtxActionMgr::separator();
935 }
936
937 /*!
938   \brief Connect data model of the module to the active study
939   \param camStudy CAM study object
940 */
941 void CAM_Module::connectToStudy( CAM_Study* camStudy )
942 {
943   CAM_Application* app = camStudy ? dynamic_cast<CAM_Application*>( camStudy->application() ) : 0;
944   if( !app )
945     return;
946
947   CAM_DataModel* prev = 0;
948   CAM_Application::ModuleList mods = app->modules();
949   for( QList<CAM_Module*>::const_iterator it = mods.begin(); it != mods.end(); ++it )
950   {
951     CAM_DataModel* dm = (*it)->dataModel();
952     if( (*it) == this && !camStudy->containsDataModel( dm ) )
953     {
954       if ( prev )
955         camStudy->insertDataModel( (*it)->dataModel(), prev );
956       else
957         camStudy->insertDataModel( (*it)->dataModel(), 0 );
958     }
959     prev = dm;
960   }
961 }
962
963 /*!
964   \fn void CAM_Module::contextMenuPopup( const QString& type, QMenu* menu, QString& title );
965   \brief Create context popup menu.
966   \param type popup menu context
967   \param menu popup menu
968   \param title popup menu title, which can be set by the module if required
969 */
970
971 /*!
972   \fn void CAM_Module::updateCommandsStatus();
973   \brief Update menu/toolbar actions.
974 */