Salome HOME
350dffc83b5c742a47d94b7f8387dd522c3b19d4
[modules/gui.git] / src / LightApp / LightApp_Module.cxx
1 // Copyright (C) 2007-2014  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, 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 // File:      LightApp_Module.cxx
24 // Created:   6/20/2005 16:30:56 AM
25 // Author:    OCC team
26
27 #include "LightApp_Module.h"
28
29 #include "CAM_Application.h"
30
31 #include "LightApp_Application.h"
32 #include "LightApp_DataModel.h"
33 #include "LightApp_DataObject.h"
34 #include "LightApp_Study.h"
35 #include "LightApp_Preferences.h"
36 #include "LightApp_Selection.h"
37 #include "LightApp_Operation.h"
38 #include "LightApp_SwitchOp.h"
39 #include "LightApp_UpdateFlags.h"
40 #include "LightApp_ShowHideOp.h"
41 #include "LightApp_SelectionMgr.h"
42
43 #include <SUIT_Study.h>
44 #include <SUIT_DataObject.h>
45 #include <SUIT_DataBrowser.h>
46 #include <SUIT_Operation.h>
47 #include <SUIT_ViewManager.h>
48 #include <SUIT_ResourceMgr.h>
49 #include <SUIT_ShortcutMgr.h>
50 #include <SUIT_Desktop.h>
51 #include <SUIT_TreeModel.h>
52 #include <SUIT_Session.h>
53
54 #ifndef DISABLE_SALOMEOBJECT
55 #include <SALOME_ListIO.hxx>
56 #endif
57
58 #ifndef DISABLE_VTKVIEWER
59 #ifndef DISABLE_SALOMEOBJECT
60   #include <SVTK_ViewWindow.h>
61   #include <SVTK_ViewModel.h>
62 #else
63   #include <VTKViewer_ViewWindow.h>
64 #endif
65   #include <VTKViewer_ViewModel.h>
66 #endif
67 #ifndef DISABLE_OCCVIEWER
68   #include <OCCViewer_ViewWindow.h>
69   #include <OCCViewer_ViewPort3d.h>
70 #ifndef DISABLE_SALOMEOBJECT
71   #include <SOCC_ViewModel.h>
72 #else
73   #include <OCCViewer_ViewModel.h>
74 #endif
75 #endif
76 #ifndef DISABLE_GLVIEWER
77   #include <GLViewer_ViewFrame.h>
78   #include <GLViewer_ViewPort.h>
79 #endif
80 #ifndef DISABLE_PVVIEWER
81   #include <PVViewer_ViewManager.h>
82   #include <PVViewer_ViewWindow.h>
83 #endif
84 #ifndef DISABLE_PLOT2DVIEWER
85   #include <Plot2d_ViewWindow.h>
86   #include <Plot2d_ViewFrame.h>
87 #ifndef DISABLE_SALOMEOBJECT
88   #include <SPlot2d_ViewModel.h>
89 #else
90   #include <Plot2d_ViewModel.h>
91 #endif
92 #endif
93
94 #include <QtxPopupMgr.h>
95
96 #include <QVariant>
97 #include <QString>
98 #include <QStringList>
99 #include <QAction>
100
101 #include <iostream>
102
103 /*!Constructor.*/
104 LightApp_Module::LightApp_Module( const QString& name )
105 : CAM_Module( name ),
106   myPopupMgr( 0 ),
107   mySwitchOp( 0 ),
108   myDisplay( -1 ),
109   myErase( -1 ),
110   myDisplayOnly( -1 ),
111   myEraseAll( -1 ),
112   myIsFirstActivate( true )
113 {
114 }
115
116 /*!Destructor.*/
117 LightApp_Module::~LightApp_Module()
118 {
119   if ( mySwitchOp )
120     delete mySwitchOp;
121 }
122
123 /*!Initialize module.*/
124 void LightApp_Module::initialize( CAM_Application* app )
125 {
126   CAM_Module::initialize( app );
127
128   SUIT_ResourceMgr* resMgr = app ? app->resourceMgr() : 0;
129   if ( resMgr )
130     resMgr->raiseTranslators( name() );
131 }
132
133 /*!NOT IMPLEMENTED*/
134 void LightApp_Module::windows( QMap<int, int>& ) const
135 {
136 }
137
138 /*!NOT IMPLEMENTED*/
139 void LightApp_Module::viewManagers( QStringList& ) const
140 {
141 }
142
143 /*!Context menu popup.*/
144 void LightApp_Module::contextMenuPopup( const QString& client, QMenu* menu, QString& /*title*/ )
145 {
146   LightApp_Selection* sel = createSelection();
147   sel->init( client, getApp()->selectionMgr() );
148
149   popupMgr()->setSelection( sel );
150   popupMgr()->setMenu( menu );
151   popupMgr()->updateMenu();
152 }
153
154 /*!Update object browser.
155  * For updating model or whole object browser use update() method can be used.
156 */
157 void LightApp_Module::updateObjBrowser( bool theIsUpdateDataModel, 
158                                         SUIT_DataObject* theDataObject )
159 {
160   bool upd = getApp()->objectBrowser()->autoUpdate();
161   getApp()->objectBrowser()->setAutoUpdate( false );
162
163   if( theIsUpdateDataModel ){
164     if( CAM_DataModel* aDataModel = dataModel() ){
165       if ( LightApp_DataModel* aModel = dynamic_cast<LightApp_DataModel*>( aDataModel ) ) {
166         //SUIT_DataObject* aParent = NULL;
167         //if(theDataObject && theDataObject != aDataModel->root())
168         //  aParent = theDataObject->parent();
169
170         LightApp_DataObject* anObject = dynamic_cast<LightApp_DataObject*>(theDataObject);
171         LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>(getApp()->activeStudy());
172         aModel->update( anObject, aStudy );
173       }
174     }
175   }
176
177   getApp()->objectBrowser()->setAutoUpdate( upd );
178   getApp()->objectBrowser()->updateTree( 0, false );
179 }
180
181 /*!NOT IMPLEMENTED*/
182 void LightApp_Module::selectionChanged()
183 {
184 }
185
186 /*! \brief If return false, selection will be cleared at module activation
187  */
188 bool LightApp_Module::isSelectionCompatible()
189 {
190   // return true if selected objects belong to this module
191   bool isCompatible = true;
192 #ifndef DISABLE_SALOMEOBJECT
193   SALOME_ListIO selected;
194   if ( LightApp_SelectionMgr *Sel = getApp()->selectionMgr() )
195     Sel->selectedObjects( selected );
196
197   LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>( getApp()->activeStudy() );
198   LightApp_DataObject* aRoot = dynamic_cast<LightApp_DataObject*>( dataModel()->root() );
199   if ( aStudy && aRoot ) {
200     // my data type
201     QString moduleDataType = aRoot->componentDataType();
202     // check data type of selection
203     SALOME_ListIteratorOfListIO It( selected );
204     for ( ; isCompatible && It.More(); It.Next()) {
205       Handle(SALOME_InteractiveObject) io = It.Value();
206       isCompatible = ( aStudy->componentDataType( io->getEntry() ) == moduleDataType );
207     }
208   }
209 #endif
210   return isCompatible;
211 }
212
213 /*!Activate module.*/
214 bool LightApp_Module::activateModule( SUIT_Study* study )
215 {
216   bool res = CAM_Module::activateModule( study );
217
218   if ( !isSelectionCompatible() )// PAL19290, PAL18352
219     getApp()->selectionMgr()->clearSelected();
220
221   if ( res && application() && application()->resourceMgr() )
222     application()->resourceMgr()->raiseTranslators( name() );
223
224   connect( application(), SIGNAL( viewManagerAdded( SUIT_ViewManager* ) ),
225            this, SLOT( onViewManagerAdded( SUIT_ViewManager* ) ) );
226   connect( application(), SIGNAL( viewManagerRemoved( SUIT_ViewManager* ) ),
227            this, SLOT( onViewManagerRemoved( SUIT_ViewManager* ) ) );
228
229   if ( mySwitchOp == 0 )
230     mySwitchOp = new LightApp_SwitchOp( this );
231
232   // Enable Display and Erase actions
233   if ( action(myDisplay) )
234     action(myDisplay)->setEnabled(true);
235   if ( action(myErase) )
236     action(myErase)->setEnabled(true);
237
238   application()->shortcutMgr()->setSectionEnabled( moduleName() );
239
240   /*  BUG 0020498 : The Entry column is always shown at module activation
241       The registration of column is moved into LightApp_Application
242
243   QString EntryCol = QObject::tr( "ENTRY_COLUMN" );
244   LightApp_DataModel* m = dynamic_cast<LightApp_DataModel*>( dataModel() );
245   if( m )
246   {
247     SUIT_AbstractModel* treeModel = dynamic_cast<SUIT_AbstractModel*>( getApp()->objectBrowser()->model() );
248     m->registerColumn( getApp()->objectBrowser(), EntryCol, LightApp_DataObject::EntryId );
249     treeModel->setAppropriate( EntryCol, Qtx::Toggled );
250   }*/
251
252   if ( myIsFirstActivate ) {
253     updateModuleVisibilityState();
254     myIsFirstActivate = false;
255   }
256   
257   return res;
258 }
259
260 /*!Deactivate module.*/
261 bool LightApp_Module::deactivateModule( SUIT_Study* study )
262 {
263   delete mySwitchOp;
264   mySwitchOp = 0;
265
266   disconnect( application(), SIGNAL( viewManagerAdded( SUIT_ViewManager* ) ),
267               this, SLOT( onViewManagerAdded( SUIT_ViewManager* ) ) );
268   disconnect( application(), SIGNAL( viewManagerRemoved( SUIT_ViewManager* ) ),
269               this, SLOT( onViewManagerRemoved( SUIT_ViewManager* ) ) );
270
271   // abort all operations
272   MapOfOperation::const_iterator anIt;
273   for( anIt = myOperations.begin(); anIt != myOperations.end(); anIt++ ) {
274     anIt.value()->abort();
275   }
276
277   // Disable Display and Erase action
278   if ( action(myDisplay) )
279     action(myDisplay)->setEnabled(false);
280   if ( action(myErase) )
281     action(myErase)->setEnabled(false);
282
283   application()->shortcutMgr()->setSectionEnabled( moduleName(), false );
284   
285   /*  BUG 0020498 : The Entry column is always shown at module activation
286   QString EntryCol = QObject::tr( "ENTRY_COLUMN" );
287   LightApp_DataModel* m = dynamic_cast<LightApp_DataModel*>( dataModel() );
288   if( m )
289   {
290     SUIT_AbstractModel* treeModel = dynamic_cast<SUIT_AbstractModel*>( getApp()->objectBrowser()->model() );
291
292     treeModel->setAppropriate( EntryCol, Qtx::Shown );
293     m->unregisterColumn( getApp()->objectBrowser(), EntryCol );
294   }
295   */
296   return CAM_Module::deactivateModule( study );
297 }
298
299 /*! Redefined to reset internal flags valid for study instance */
300 void LightApp_Module::studyClosed( SUIT_Study* theStudy )
301 {
302   CAM_Module::studyClosed( theStudy );
303   
304   myIsFirstActivate = true;
305   
306   LightApp_Application* app = dynamic_cast<LightApp_Application*>(application());
307   if ( app ) {
308     SUIT_DataBrowser* ob = app->objectBrowser();
309     if ( ob && ob->model() )
310       disconnect( ob->model(), SIGNAL( clicked( SUIT_DataObject*, int ) ),
311                   this, SLOT( onObjectClicked( SUIT_DataObject*, int ) ) );
312   }
313 }
314
315 /*!NOT IMPLEMENTED*/
316 void LightApp_Module::MenuItem()
317 {
318 }
319
320 /*!NOT IMPLEMENTED*/
321 void LightApp_Module::createPreferences()
322 {
323 }
324
325 /*!NOT IMPLEMENTED*/
326 void LightApp_Module::preferencesChanged( const QString&, const QString& )
327 {
328 }
329
330 /*!NOT IMPLEMENTED*/
331 void LightApp_Module::message( const QString& )
332 {
333 }
334
335 /*!Gets application.*/
336 LightApp_Application* LightApp_Module::getApp() const
337 {
338   return (LightApp_Application*)application();
339 }
340
341 /*!
342  * \brief Update something in accordance with update flags
343  * \param theFlags - update flags
344 *
345 * Update viewer or/and object browser etc. in accordance with update flags ( see
346 * LightApp_UpdateFlags enumeration ). Derived modules can redefine this method for their
347 * own purposes
348 */
349 void LightApp_Module::update( const int theFlags )
350 {
351   if ( theFlags & UF_Model )
352   {
353     if( CAM_DataModel* aDataModel = dataModel() )
354       if( LightApp_DataModel* aModel = dynamic_cast<LightApp_DataModel*>( aDataModel ) )
355         aModel->update( 0, dynamic_cast<LightApp_Study*>( getApp()->activeStudy() ) );
356   }
357
358   if ( theFlags & UF_ObjBrowser )
359     getApp()->objectBrowser()->updateTree( 0 );
360
361   if ( theFlags & UF_Controls )
362     updateControls();
363   if ( theFlags & UF_Viewer )
364   {
365     if ( SUIT_ViewManager* viewMgr = getApp()->activeViewManager() )
366       if ( SUIT_ViewWindow* viewWnd = viewMgr->getActiveView() )
367       {
368 #ifndef DISABLE_VTKVIEWER
369 #ifndef DISABLE_SALOMEOBJECT
370         if ( viewWnd->inherits( "SVTK_ViewWindow" ) )
371           ( (SVTK_ViewWindow*)viewWnd )->Repaint();
372 #else
373         if ( viewWnd->inherits( "VTKViewer_ViewWindow" ) )
374           ( (VTKViewer_ViewWindow*)viewWnd )->Repaint();
375 #endif
376 #endif
377 #ifndef DISABLE_OCCVIEWER
378         if ( viewWnd->inherits( "OCCViewer_ViewWindow" ) )
379           ( (OCCViewer_ViewWindow*)viewWnd )->getViewPort()->onUpdate();
380 #endif
381 #ifndef DISABLE_PLOT2DVIEWER
382         if ( viewWnd->inherits( "Plot2d_ViewWindow" ) )
383           ( (Plot2d_ViewWindow*)viewWnd )->getViewFrame()->Repaint();
384 #endif
385 #ifndef DISABLE_GLVIEWER
386         if ( viewWnd->inherits( "GLViewer_ViewFrame" ) )
387           ( (GLViewer_ViewFrame*)viewWnd )->getViewPort()->onUpdate();
388 #endif
389 #ifndef DISABLE_PVVIEWER
390 //        if ( viewWnd->inherits( "PVViewer_ViewWindow" ) )
391 //          ( (PVViewer_ViewWindow*)viewWnd )->getViewPort()->onUpdate();
392 #endif
393       }
394   }
395 }
396 /*!
397  * \brief Updates controls
398 *
399 * Updates (i.e. disable/enable) controls states (menus, tool bars etc.). This method is
400 * called from update( UF_Controls ). You may redefine it in concrete module.
401 */
402 void LightApp_Module::updateControls()
403 {
404 }
405
406 /*!Create new instance of data model and return it.*/
407 CAM_DataModel* LightApp_Module::createDataModel()
408 {
409   return new LightApp_DataModel( this );
410 }
411
412 /*!Create and return instance of LightApp_Selection.*/
413 LightApp_Selection* LightApp_Module::createSelection() const
414 {
415   return new LightApp_Selection();
416 }
417
418 /*!NOT IMPLEMENTED*/
419 void LightApp_Module::onModelOpened()
420 {
421 }
422
423 /*!NOT IMPLEMENTED*/
424 void LightApp_Module::onModelSaved()
425 {
426 }
427
428 /*!NOT IMPLEMENTED*/
429 void LightApp_Module::onModelClosed()
430 {
431 }
432
433 /*!Gets popup manager.(create if not exist)*/
434 QtxPopupMgr* LightApp_Module::popupMgr()
435 {
436   if ( !myPopupMgr )
437   {
438     myPopupMgr = new QtxPopupMgr( 0, this );
439
440     QPixmap p;
441     SUIT_Desktop* d = application()->desktop();
442     
443     QAction 
444       *disp = createAction( -1, tr( "TOP_SHOW" ), p, tr( "MEN_SHOW" ), tr( "STB_SHOW" ),
445                             0, d, false, this, SLOT( onShowHide() ), QString("General:Show object(s)") ),
446       *erase = createAction( -1, tr( "TOP_HIDE" ), p, tr( "MEN_HIDE" ), tr( "STB_HIDE" ),
447                              0, d, false, this, SLOT( onShowHide() ) , QString("General:Hide object(s)") ),
448       *dispOnly = createAction( -1, tr( "TOP_DISPLAY_ONLY" ), p, tr( "MEN_DISPLAY_ONLY" ), tr( "STB_DISPLAY_ONLY" ),
449                                 0, d, false, this, SLOT( onShowHide() ) ),
450       *eraseAll = createAction( -1, tr( "TOP_ERASE_ALL" ), p, tr( "MEN_ERASE_ALL" ), tr( "STB_ERASE_ALL" ),
451                                 0, d, false, this, SLOT( onShowHide() ) );
452     myDisplay     = actionId( disp );
453     myErase       = actionId( erase );
454     myDisplayOnly = actionId( dispOnly );
455     myEraseAll    = actionId( eraseAll );
456
457     myPopupMgr->insert( disp, -1, 0 ); 
458     myPopupMgr->insert( erase, -1, 0 );
459     myPopupMgr->insert( dispOnly, -1, 0 );
460     myPopupMgr->insert( eraseAll, -1, 0 );
461     myPopupMgr->insert( separator(), -1, 0 );
462
463     QString oneAndNotActive = "( count( $component ) = 1 ) and ( not( activeModule in $component ) )";
464     QString uniform = "true in $canBeDisplayed and %1 and ( activeModule = '%2' )";
465     uniform = uniform.arg( oneAndNotActive ).arg( name() );
466     myPopupMgr->setRule( disp, /*QString( "( not isVisible ) and " ) + */ uniform, QtxPopupMgr::VisibleRule );
467     myPopupMgr->setRule( erase, /*QString( "( isVisible ) and " ) + */ uniform, QtxPopupMgr::VisibleRule );
468     myPopupMgr->setRule( dispOnly, uniform, QtxPopupMgr::VisibleRule );
469
470     QStringList viewers;
471
472 #ifndef DISABLE_OCCVIEWER
473 #ifndef DISABLE_SALOMEOBJECT
474     viewers.append( SOCC_Viewer::Type() );
475 #else
476     viewers.append( OCCViewer_Viewer::Type() );
477 #endif
478 #endif
479 #ifndef DISABLE_VTKVIEWER
480 #ifndef DISABLE_SALOMEOBJECT
481     viewers.append( SVTK_Viewer::Type() );
482 #else
483     viewers.append( VTKViewer_Viewer::Type() );
484 #endif
485 #endif
486 #ifndef DISABLE_PLOT2DVIEWER
487 #ifndef DISABLE_SALOMEOBJECT
488     viewers.append( SPlot2d_Viewer::Type() );
489 #else
490     viewers.append( Plot2d_Viewer::Type() );
491 #endif
492 #endif
493
494     if( !viewers.isEmpty() )
495     {
496       QString strViewers = "{ ", temp = "'%1' ";
497       QStringList::const_iterator anIt = viewers.begin(), aLast = viewers.end();
498       for( ; anIt!=aLast; anIt++ )
499         strViewers+=temp.arg( *anIt );
500       strViewers+="}";
501       myPopupMgr->setRule( eraseAll, QString( "client in %1" ).arg( strViewers ), QtxPopupMgr::VisibleRule );
502     }
503   }
504   return myPopupMgr;
505 }
506
507 /*!Gets preferences.*/
508 LightApp_Preferences* LightApp_Module::preferences() const
509 {
510   LightApp_Preferences* pref = 0;
511   if ( getApp() )
512     pref = getApp()->preferences();
513   return pref;
514 }
515
516 /*!Add preference to preferences.*/
517 int LightApp_Module::addPreference( const QString& label )
518 {
519   LightApp_Preferences* pref = preferences();
520   if ( !pref )
521     return -1;
522
523   int catId = pref->addPreference( moduleName(), -1 );
524   if ( catId == -1 )
525     return -1;
526
527   return pref->addPreference( label, catId );
528 }
529
530 /*!Add preference to preferences.*/
531 int LightApp_Module::addPreference( const QString& label, const int pId, const int type,
532                                     const QString& section, const QString& param )
533 {
534   LightApp_Preferences* pref = preferences();
535   if ( !pref )
536     return -1;
537
538   return pref->addPreference( moduleName(), label, pId, type, section, param );
539 }
540
541 /*!Gets property of preferences.*/
542 QVariant LightApp_Module::preferenceProperty( const int id, const QString& prop ) const
543 {
544   QVariant var;
545   LightApp_Preferences* pref = preferences();
546   if ( pref )
547     var = pref->itemProperty( prop, id );
548   return var;
549 }
550
551 /*!Set property of preferences.*/
552 void LightApp_Module::setPreferenceProperty( const int id, const QString& prop, const QVariant& var )
553 {
554   LightApp_Preferences* pref = preferences();
555   if ( pref )
556     pref->setItemProperty( prop, var, id );
557 }
558
559 /*!
560  * \brief Starts operation with given identifier
561   * \param id - identifier of operation to be started
562 *
563 * Module stores operations in map. This method starts operation by id.
564 * If operation isn't in map, then it will be created by createOperation method
565 * and will be inserted to map
566 */
567 void LightApp_Module::startOperation( const int id )
568 {
569   LightApp_Operation* op = 0;
570   if( myOperations.contains( id ) && reusableOperation( id ) )
571     op = myOperations[ id ];
572   else
573   {
574     op = createOperation( id );
575     if( op )
576     {
577       myOperations.insert( id, op );
578       op->setModule( this );
579       connect( op, SIGNAL( stopped( SUIT_Operation* ) ), this, SLOT( onOperationStopped( SUIT_Operation* ) ) );
580       connect( op, SIGNAL( destroyed() ), this, SLOT( onOperationDestroyed() ) );
581     }
582   }
583
584   if( op )
585   {
586     // be sure that operation has correct study pointer
587     op->setStudy( application() ? application()->activeStudy() : 0 );
588     op->start();
589   }
590 }
591
592 /*!
593  * \brief Creates operation with given identifier
594   * \param id - identifier of operation to be started
595   * \return Pointer on created operation or NULL if operation is not created
596 *
597 * Creates operation with given id. You should not call this method, it will be called
598 * automatically from startOperation. You may redefine this method in concrete module to
599 * create operations. 
600 */
601 LightApp_Operation* LightApp_Module::createOperation( const int id ) const
602 {
603   if( id==-1 )
604     return 0;
605
606   if( id==myDisplay )
607     return new LightApp_ShowHideOp( LightApp_ShowHideOp::DISPLAY );
608   else if( id==myErase )
609     return new LightApp_ShowHideOp( LightApp_ShowHideOp::ERASE );
610   else if( id==myDisplayOnly )
611     return new LightApp_ShowHideOp( LightApp_ShowHideOp::DISPLAY_ONLY );
612   else if( id==myEraseAll )
613     return new LightApp_ShowHideOp( LightApp_ShowHideOp::ERASE_ALL );
614   else
615     return 0;
616 }
617
618 /*!
619  * \brief Virtual protected slot called when operation stopped
620  * \param theOp - stopped operation
621 *
622 * Virtual protected slot called when operation stopped. Redefine this slot if you want to
623 * perform actions after stopping operation
624 */
625 void LightApp_Module::onOperationStopped( SUIT_Operation* /*theOp*/ )
626 {
627 }
628
629 /*!
630  * \brief Virtual protected slot called when operation destroyed
631   * \param theOp - destroyed operation
632 *
633 * Virtual protected slot called when operation destroyed. Redefine this slot if you want to
634 * perform actions after destroying operation. Base implementation removes pointer on
635 * destroyed operation from the map of operations
636 */
637 void LightApp_Module::onOperationDestroyed()
638 {
639   const QObject* s = sender();
640   if( s && s->inherits( "LightApp_Operation" ) )
641   {
642     const LightApp_Operation* op = ( LightApp_Operation* )s;
643     MapOfOperation::const_iterator anIt = myOperations.begin(),
644                                    aLast = myOperations.end();
645     for( ; anIt!=aLast; anIt++ )
646       if( anIt.value()==op )
647       {
648         myOperations.remove( anIt.key() );
649         break;
650       }
651   }
652 }
653
654 /*!
655   Must be redefined in order to use standard displayer mechanism
656   \return displayer of module
657 */
658 LightApp_Displayer* LightApp_Module::displayer()
659 {
660   return 0;
661 }
662
663 /*!
664   SLOT: called on activating of standard operations show/hide
665 */
666 void LightApp_Module::onShowHide()
667 {
668   if( !sender()->inherits( "QAction" ) || !popupMgr() )
669     return;
670
671   QAction* act = ( QAction* )sender();
672   int id = actionId( act );
673   if( id!=-1 )
674     startOperation( id );
675 }
676
677 /*!
678   virtual SLOT: called on view manager adding
679 */
680 void LightApp_Module::onViewManagerAdded( SUIT_ViewManager* )
681 {
682 }
683
684 /*!
685   virtual SLOT: called on view manager removing
686 */
687 void LightApp_Module::onViewManagerRemoved( SUIT_ViewManager* )
688 {
689 }
690
691 /*!
692   \brief Returns instance of operation by its id; if there is no operation
693   corresponding to this id, null pointer is returned
694   \param id - operation id 
695   \return operation instance
696 */
697 LightApp_Operation* LightApp_Module::operation( const int id ) const
698 {
699   return myOperations.contains( id ) ? myOperations[id] : 0;
700 }
701
702 /*!
703   virtual method called to manage the same operations
704 */
705 bool LightApp_Module::reusableOperation( const int id )
706 {
707  return true;
708
709
710 /*!
711   virtual method
712   \return true if module can copy the current selection
713 */
714 bool LightApp_Module::canCopy() const
715 {
716   return false;
717 }
718
719 /*!
720   virtual method
721   \return true if module can paste previously copied data
722 */
723 bool LightApp_Module::canPaste() const
724 {
725   return false;
726 }
727
728 /*!
729   virtual method
730   \brief Copies the current selection into clipboard
731 */
732 void LightApp_Module::copy()
733 {
734 }
735
736 /*!
737   virtual method
738   \brief Pastes the current data in the clipboard
739 */
740 void LightApp_Module::paste()
741 {
742 }
743
744 /*!
745   virtual method
746   \return true if module allows dragging the given object
747 */
748 bool LightApp_Module::isDraggable( const SUIT_DataObject* /*what*/ ) const
749 {
750   return false;
751 }
752
753 /*!
754   virtual method
755   \return true if module allows dropping one or more objects (currently selected) on the object \c where
756 */
757 bool LightApp_Module::isDropAccepted( const SUIT_DataObject* /*where*/ ) const
758 {
759   return false;
760 }
761
762 /*!
763   virtual method
764   Complete drag-n-drop operation by processing objects \a what being dragged, dropped to the line \a row
765   within the object \a where. The drop action being performed is specified by \a action.
766 */
767 void LightApp_Module::dropObjects( const DataObjectList& /*what*/, SUIT_DataObject* /*where*/,
768                                    const int /*row*/, Qt::DropAction /*action*/ )
769 {
770 }
771
772 /*!
773   \brief Return \c true if object can be renamed
774 */
775 bool LightApp_Module::renameAllowed( const QString& /*entry*/ ) const
776 {
777   return false;
778 }
779
780 /*!
781   Rename object by entry.
782   \param entry entry of the object
783   \param name new name of the object
784   \brief Return \c true if rename operation finished successfully, \c false otherwise.
785 */
786 bool LightApp_Module::renameObject( const QString& /*entry*/, const QString& /*name*/ )
787 {
788   return false;
789 }
790
791 /*!
792   Update visibility state for data objects
793 */
794 void LightApp_Module::updateModuleVisibilityState()
795 {
796   // update visibility state of objects
797   LightApp_Application* app = dynamic_cast<LightApp_Application*>(SUIT_Session::session()->activeApplication());
798   if ( !app ) return;
799   
800   SUIT_DataBrowser* ob = app->objectBrowser();
801   if ( !ob || !ob->model() ) return;
802
803   // connect to click on item
804   connect( ob->model(), SIGNAL( clicked( SUIT_DataObject*, int ) ),
805            this, SLOT( onObjectClicked( SUIT_DataObject*, int ) ), Qt::UniqueConnection );
806
807   SUIT_DataObject* rootObj = ob->root();
808   if ( !rootObj ) return;
809   
810   DataObjectList listObj = rootObj->children( true );
811   
812   SUIT_ViewModel* vmod = 0;
813   if ( SUIT_ViewManager* vman = app->activeViewManager() )
814     vmod = vman->getViewModel();
815   app->updateVisibilityState( listObj, vmod );
816 }
817
818 /*!
819  * \brief Virtual public slot
820  *
821  * This method is called after the object inserted into data view to update their visibility state
822  * This is default implementation
823  */
824 void LightApp_Module::onObjectClicked( SUIT_DataObject* theObject, int theColumn )
825 {
826   if ( !isActiveModule() ) return;
827
828   // change visibility of object
829   if ( !theObject || theColumn != SUIT_DataObject::VisibilityId ) return;
830
831   LightApp_Study* study = dynamic_cast<LightApp_Study*>( SUIT_Session::session()->activeApplication()->activeStudy() );
832   if ( !study ) return;
833
834   LightApp_DataObject* lo = dynamic_cast<LightApp_DataObject*>( theObject );
835   if ( !lo ) return;
836   
837   // detect action index (from LightApp level)
838   int id = -1;
839   
840   if ( study->visibilityState( lo->entry() ) == Qtx::ShownState )
841     id = myErase;
842   else if ( study->visibilityState( lo->entry() ) == Qtx::HiddenState )
843     id = myDisplay;
844   
845   if ( id != -1 )
846     startOperation( id );
847 }