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