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