Salome HOME
f011cfe9ae6b6bbf4013079be6da1f18d03294f2
[modules/hydro.git] / src / HYDROGUI / HYDROGUI_Module.cxx
1 // Copyright (C) 2007-2013  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
23 #include "HYDROGUI_Module.h"
24
25 #include "HYDROGUI.h"
26 #include "HYDROGUI_DataModel.h"
27 #include "HYDROGUI_Displayer.h"
28 #include "HYDROGUI_GVSelector.h"
29 #include "HYDROGUI_InputPanel.h"
30 #include "HYDROGUI_ObjSelector.h"
31 #include "HYDROGUI_Operations.h"
32 #include "HYDROGUI_PrsImage.h"
33 #include "HYDROGUI_Tool.h"
34 #include "HYDROGUI_UpdateFlags.h"
35
36 #include <HYDROData_Image.h>
37
38 #include <HYDROOperations_Factory.h>
39
40 #include <GraphicsView_ViewFrame.h>
41 #include <GraphicsView_ViewManager.h>
42 #include <GraphicsView_ViewPort.h>
43 #include <GraphicsView_Viewer.h>
44
45 #include <ImageComposer_CutOperator.h>
46 #include <ImageComposer_CropOperator.h>
47 #include <ImageComposer_FuseOperator.h>
48
49 #include <LightApp_Application.h>
50 #include <LightApp_GVSelector.h>
51 #include <LightApp_SelectionMgr.h>
52 #include <LightApp_UpdateFlags.h>
53
54 #include <SALOME_Event.h>
55
56 #include <SUIT_Desktop.h>
57 #include <SUIT_Study.h>
58 #include <SUIT_ViewManager.h>
59
60 #include <QAction>
61 #include <QApplication>
62 #include <QGraphicsSceneMouseEvent>
63 #include <QMenu>
64
65 static int ViewManagerId = 0;
66
67 extern "C" HYDRO_EXPORT CAM_Module* createModule()
68 {
69   return new HYDROGUI_Module();
70 }
71
72 extern "C" HYDRO_EXPORT char* getModuleVersion()
73 {
74   return (char*)HYDRO_VERSION;
75 }
76
77 HYDROGUI_Module::HYDROGUI_Module()
78 : LightApp_Module( "HYDRO" ),
79   myDisplayer( 0 ),
80   myIsUpdateEnabled( true )
81 {
82 }
83
84 HYDROGUI_Module::~HYDROGUI_Module()
85 {
86 }
87
88 int HYDROGUI_Module::getStudyId() const
89 {
90   LightApp_Application* anApp = getApp();
91   return anApp ? anApp->activeStudy()->id() : 0;
92 }
93
94 void HYDROGUI_Module::initialize( CAM_Application* theApp )
95 {
96   LightApp_Module::initialize( theApp );
97
98   createActions();
99   createUndoRedoActions();
100   createMenus();
101   createPopups();
102   createToolbars();
103
104   setMenuShown( false );
105   setToolShown( false );
106
107   myDisplayer = new HYDROGUI_Displayer( this );
108 }
109
110 bool HYDROGUI_Module::activateModule( SUIT_Study* theStudy )
111 {
112   bool aRes = LightApp_Module::activateModule( theStudy );
113
114   LightApp_Application* anApp = getApp();
115   SUIT_Desktop* aDesktop = anApp->desktop();
116
117   setMenuShown( true );
118   setToolShown( true );
119
120 #ifndef DISABLE_PYCONSOLE
121   aDesktop->tabifyDockWidget( HYDROGUI_Tool::WindowDock( anApp->getWindow( LightApp_Application::WT_PyConsole ) ), 
122                               HYDROGUI_Tool::WindowDock( anApp->getWindow( LightApp_Application::WT_LogWindow ) ) );
123 #endif
124
125   update( UF_All );
126
127   updateCommandsStatus();
128
129   return aRes;
130 }
131
132 bool HYDROGUI_Module::deactivateModule( SUIT_Study* theStudy )
133 {
134   ViewManagerMapIterator anIter( myViewManagerMap );
135   while( anIter.hasNext() )
136     if( SUIT_ViewManager* aViewManager = anIter.next().value().first )
137       getApp()->removeViewManager( aViewManager );
138   myViewManagerMap.clear();
139
140   myObjectStateMap.clear();
141
142   setMenuShown( false );
143   setToolShown( false );
144
145   return LightApp_Module::deactivateModule( theStudy );
146 }
147
148 void HYDROGUI_Module::windows( QMap<int, int>& theMap ) const
149 {
150   theMap.clear();
151   theMap.insert( LightApp_Application::WT_LogWindow,     Qt::BottomDockWidgetArea );
152 #ifndef DISABLE_PYCONSOLE
153   theMap.insert( LightApp_Application::WT_PyConsole,     Qt::BottomDockWidgetArea );
154 #endif
155   theMap.insert( LightApp_Application::WT_ObjectBrowser, Qt::LeftDockWidgetArea   );
156 }
157
158 void HYDROGUI_Module::viewManagers( QStringList& theTypesList ) const
159 {
160   theTypesList << GraphicsView_Viewer::Type();
161 }
162
163 void HYDROGUI_Module::contextMenuPopup( const QString& theClient,
164                                         QMenu* theMenu,
165                                         QString& theTitle )
166 {
167   HYDROGUI_DataModel* aModel = getDataModel();
168
169   size_t aViewId = HYDROGUI_Tool::GetActiveGraphicsViewId( this );
170
171   bool anIsSelection = false;
172   bool anIsVisibleInSelection = false;
173   bool anIsHiddenInSelection = false;
174
175   bool anIsImage = false;
176   bool anIsImportedImage = false;
177   bool anIsCompositeImage = false;
178   bool anIsFusedImage = false;
179   bool anIsCutImage = false;
180   bool anIsSplittedImage = false;
181   bool anIsMustBeUpdatedImage = false;
182   bool anIsPolyline = false;
183   bool anIsCalculation = false;
184   bool anIsVisualState = false;
185
186   HYDROData_SequenceOfObjects aSeq = HYDROGUI_Tool::GetSelectedObjects( this );
187   for( Standard_Integer anIndex = 1, aLength = aSeq.Length(); anIndex <= aLength; anIndex++ )
188   {
189     Handle(HYDROData_Object) anObject = aSeq.Value( anIndex );
190     if( !anObject.IsNull() )
191     {
192       anIsSelection = true;
193
194       bool aVisibility = isObjectVisible( aViewId, anObject );
195       anIsVisibleInSelection |= aVisibility;
196       anIsHiddenInSelection |= !aVisibility;
197
198       if( anObject->GetKind() == KIND_IMAGE )
199       {
200         anIsImage = true;
201         Handle(HYDROData_Image) anImage = Handle(HYDROData_Image)::DownCast( anObject );
202         if( !anImage.IsNull() )
203         {
204           anIsImportedImage = anImage->HasTrsfPoints() && !anImage->IsSelfSplitted();
205           anIsCompositeImage = anImage->NbReferences() > 0;
206           if( HYDROOperations_Factory* aFactory = HYDROOperations_Factory::Factory() )
207           {
208             if( ImageComposer_Operator* anOperator = aFactory->Operator( anImage ) )
209             {
210               if( dynamic_cast<ImageComposer_FuseOperator*>( anOperator ) )
211                 anIsFusedImage = true;
212               else if( dynamic_cast<ImageComposer_CutOperator*>( anOperator ) )
213                 anIsCutImage = true;
214               else if( dynamic_cast<ImageComposer_CropOperator*>( anOperator ) )
215                 anIsSplittedImage = true;
216             }
217           }
218           anIsMustBeUpdatedImage = anImage->MustBeUpdated();
219         }
220       }
221       else if( anObject->GetKind() == KIND_POLYLINE )
222         anIsPolyline = true;
223       else if( anObject->GetKind() == KIND_CALCULATION )
224         anIsCalculation = true;
225       else if( anObject->GetKind() == KIND_VISUAL_STATE )
226         anIsVisualState = true;
227     }
228   }
229
230   if( aSeq.IsEmpty() )
231   {
232     theMenu->addAction( action( SaveVisualStateId ) );
233     theMenu->addSeparator();
234   }
235
236   if( anIsSelection && anIsMustBeUpdatedImage )
237   {
238     theMenu->addAction( action( UpdateImageId ) );
239     theMenu->addSeparator();
240   }
241
242   if( anIsSelection && aSeq.Length() == 1 )
243   {
244     if( anIsImage )
245     {
246       if( anIsImportedImage )
247         theMenu->addAction( action( EditImportedImageId ) );
248       else if( anIsCompositeImage )
249       {
250         if( anIsFusedImage )
251           theMenu->addAction( action( EditFusedImageId ) );
252         else if( anIsCutImage )
253           theMenu->addAction( action( EditCutImageId ) );
254         else if( anIsSplittedImage )
255           theMenu->addAction( action( EditSplittedImageId ) );
256       }
257
258       theMenu->addAction( action( ObserveImageId ) );
259       theMenu->addAction( action( ExportImageId ) );
260       theMenu->addSeparator();
261     }
262     else if( anIsPolyline )
263     {
264       theMenu->addAction( action( EditPolylineId ) );
265       theMenu->addSeparator();
266     }
267     else if( anIsCalculation )
268     {
269       theMenu->addAction( action( EditCalculationId ) );
270       theMenu->addSeparator();
271     }
272     else if( anIsVisualState )
273     {
274       theMenu->addAction( action( SaveVisualStateId ) );
275       theMenu->addAction( action( LoadVisualStateId ) );
276       theMenu->addSeparator();
277     }
278   }
279
280   if( anIsSelection )
281   {
282     theMenu->addAction( action( DeleteId ) );
283     theMenu->addSeparator();
284   }
285
286   if( anIsSelection && ( anIsImage || anIsPolyline ) )
287   {
288     if( anIsHiddenInSelection )
289       theMenu->addAction( action( ShowId ) );
290     theMenu->addAction( action( ShowOnlyId ) );
291     if( anIsVisibleInSelection )
292       theMenu->addAction( action( HideId ) );
293     theMenu->addSeparator();
294   }
295
296   theMenu->addAction( action( ShowAllId ) );
297   theMenu->addAction( action( HideAllId ) );
298   theMenu->addSeparator();
299 }
300
301 void HYDROGUI_Module::update( const int flags )
302 {
303   if( !isUpdateEnabled() )
304     return;
305
306   QApplication::setOverrideCursor( Qt::WaitCursor );
307
308   // To prevent calling this method recursively
309   // from one of the methods called below
310   setUpdateEnabled( false );
311
312   if( ( flags & UF_Viewer ) )
313     updateGV( flags & UF_GV_Init,
314               flags & UF_GV_Forced );
315
316   if( ( flags & UF_Model ) && getDataModel() && getApp() )
317   {
318     getDataModel()->update( getStudyId() );
319
320     // Temporary workaround to prevent breaking
321     // the selection in the object browser.
322     // Note: processEvents() should be called after updateGV(),
323     // otherwise the application crashes from time to time.
324     qApp->processEvents(); 
325     getApp()->updateObjectBrowser( true );
326   }
327
328   // Object browser is currently updated by using UF_Model flag
329   //if( ( flags & UF_ObjBrowser ) && getApp() )
330   //  getApp()->updateObjectBrowser( true );
331
332   if( ( flags & UF_Controls ) && getApp() )
333     getApp()->updateActions();
334
335   setUpdateEnabled( true );
336
337   QApplication::restoreOverrideCursor();
338 }
339
340 void HYDROGUI_Module::updateCommandsStatus()
341 {
342   LightApp_Module::updateCommandsStatus();
343
344   updateUndoRedoControls();
345
346   // to do
347   //action( ... )->setEnabled( ... );
348 }
349
350 HYDROGUI_DataModel* HYDROGUI_Module::getDataModel() const
351 {
352   return (HYDROGUI_DataModel*)dataModel();
353 }
354
355 HYDROGUI_Displayer* HYDROGUI_Module::getDisplayer() const
356 {
357   return myDisplayer;
358 }
359
360 GraphicsView_Viewer* HYDROGUI_Module::getViewer( const int theId ) const
361 {
362   if( myViewManagerMap.contains( theId ) )
363   {
364     ViewManagerInfo anInfo = myViewManagerMap[ theId ];
365     GraphicsView_ViewManager* aViewManager =
366       dynamic_cast<GraphicsView_ViewManager*>( anInfo.first );
367     if( aViewManager )
368       return aViewManager->getViewer();
369   }
370   return NULL;
371 }
372
373 int HYDROGUI_Module::getViewManagerId( SUIT_ViewManager* theViewManager )
374 {
375   ViewManagerMapIterator anIter( myViewManagerMap );
376   while( anIter.hasNext() )
377   {
378     int anId = anIter.next().key();
379     const ViewManagerInfo& anInfo = anIter.value();
380     if( anInfo.first == theViewManager )
381       return anId;
382   }
383   return -1;
384 }
385
386 HYDROGUI_Module::ViewManagerRole HYDROGUI_Module::getViewManagerRole( SUIT_ViewManager* theViewManager )
387 {
388   int anId = getViewManagerId( theViewManager );
389   if( anId != -1 )
390   {
391     const ViewManagerInfo& anInfo = myViewManagerMap[ anId ];
392     return anInfo.second;
393   }
394   return VMR_Unknown;
395 }
396
397 void HYDROGUI_Module::setViewManagerRole( SUIT_ViewManager* theViewManager,
398                                           const ViewManagerRole theRole )
399 {
400   int anId = getViewManagerId( theViewManager );
401   if( anId != -1 )
402   {
403     ViewManagerInfo& anInfo = myViewManagerMap[ anId ];
404     anInfo.second = theRole;
405   }
406 }
407
408 bool HYDROGUI_Module::isObjectVisible( const int theViewId,
409                                        const Handle(HYDROData_Object)& theObject )
410 {
411   if( theObject.IsNull() )
412     return false;
413
414   ViewId2Name2ObjectStateMap::const_iterator anIter1 = myObjectStateMap.find( theViewId );
415   if( anIter1 != myObjectStateMap.end() )
416   {
417     const Name2ObjectStateMap& aName2ObjectStateMap = anIter1.value();
418     Name2ObjectStateMap::const_iterator anIter2 = aName2ObjectStateMap.find( theObject->GetName());
419     if( anIter2 != aName2ObjectStateMap.end() )
420     {
421       const ObjectState& anObjectState = anIter2.value();
422       return anObjectState.Visibility;
423     }
424   }
425   return false;
426 }
427
428 void HYDROGUI_Module::setObjectVisible( const int theViewId,
429                                         const Handle(HYDROData_Object)& theObject,
430                                         const bool theState )
431 {
432   if( !theObject.IsNull() )
433   {
434     Name2ObjectStateMap& aName2ObjectStateMap = myObjectStateMap[ theViewId ];
435     ObjectState& anObjectState = aName2ObjectStateMap[ theObject->GetName() ];
436     anObjectState.Visibility = theState;
437   }
438 }
439
440 CAM_DataModel* HYDROGUI_Module::createDataModel()
441 {
442   return new HYDROGUI_DataModel( this );
443 }
444
445 void HYDROGUI_Module::customEvent( QEvent* e )
446 {
447   int aType = e->type();
448   if ( aType == NewViewEvent )
449   {
450     SALOME_CustomEvent* ce = ( SALOME_CustomEvent* )e;
451     if( GraphicsView_ViewFrame* aViewFrame = ( GraphicsView_ViewFrame* )ce->data() )
452     {
453       if( GraphicsView_Viewer* aViewer = dynamic_cast<GraphicsView_Viewer*>( aViewFrame->getViewer() ) )
454       {
455         if( GraphicsView_ViewPort* aViewPort = aViewer->getActiveViewPort() )
456         {
457           aViewPort->setInteractionFlag( GraphicsView_ViewPort::TraceBoundingRect );
458           aViewPort->setInteractionFlag( GraphicsView_ViewPort::ImmediateContextMenu );
459           aViewPort->setInteractionFlag( GraphicsView_ViewPort::ImmediateSelection );
460
461           //ouv: temporarily commented
462           //aViewPort->setViewLabelPosition( GraphicsView_ViewPort::VLP_BottomLeft, true );
463         }
464
465         SUIT_ViewManager* aViewManager = aViewer->getViewManager();
466         ViewManagerRole aRole = getViewManagerRole( aViewManager );
467         if( aRole != VMR_TransformImage )
468           update( UF_Viewer );
469
470         aViewer->activateTransform( GraphicsView_Viewer::FitAll );
471       }
472     }
473   }
474 }
475
476 bool HYDROGUI_Module::eventFilter( QObject* theObj, QEvent* theEvent )
477 {
478   QEvent::Type aType = theEvent->type();
479   if( theObj->inherits( "GraphicsView_ViewFrame" ) )
480   {
481     if( aType == QEvent::Show )
482     {
483       SALOME_CustomEvent* e = new SALOME_CustomEvent( NewViewEvent );
484       e->setData( theObj );
485       QApplication::postEvent( this, e );
486       theObj->removeEventFilter( this );
487     }
488   }
489   return LightApp_Module::eventFilter( theObj, theEvent );
490 }
491
492 void HYDROGUI_Module::onViewManagerAdded( SUIT_ViewManager* theViewManager )
493 {
494   LightApp_Module::onViewManagerAdded( theViewManager );
495
496   if( theViewManager->getType() == GraphicsView_Viewer::Type() )
497   { 
498     createSelector( theViewManager ); // replace the default selector
499
500     connect( theViewManager, SIGNAL( viewCreated( SUIT_ViewWindow* ) ),
501              this, SLOT( onViewCreated( SUIT_ViewWindow* ) ) );
502   }
503
504   ViewManagerInfo anInfo( theViewManager, VMR_General );
505   myViewManagerMap.insert( ViewManagerId++, anInfo );
506 }
507
508 void HYDROGUI_Module::onViewManagerRemoved( SUIT_ViewManager* theViewManager )
509 {
510   LightApp_Module::onViewManagerRemoved( theViewManager );
511
512   createSelector( theViewManager ); // replace the default selector
513
514   int anId = getViewManagerId( theViewManager );
515   if( anId != -1 )
516     myViewManagerMap.remove( anId );
517 }
518
519 void HYDROGUI_Module::onViewCreated( SUIT_ViewWindow* theViewWindow )
520 {
521   if( theViewWindow && theViewWindow->inherits( "GraphicsView_ViewFrame" ) )
522   {
523     if( GraphicsView_ViewFrame* aViewFrame = dynamic_cast<GraphicsView_ViewFrame*>( theViewWindow ) )
524     {
525       aViewFrame->installEventFilter( this );
526
527       GraphicsView_ViewPort* aViewPort = aViewFrame->getViewPort();
528
529       connect( aViewPort, SIGNAL( vpMouseEvent( QGraphicsSceneMouseEvent* ) ),
530                this, SLOT( onViewPortMouseEvent( QGraphicsSceneMouseEvent* ) ) );
531       return;
532     }
533   }
534 }
535
536 void HYDROGUI_Module::onViewPortMouseEvent( QGraphicsSceneMouseEvent* theEvent )
537 {
538   if( GraphicsView_ViewPort* aViewPort = qobject_cast<GraphicsView_ViewPort*>( sender() ) )
539   {
540     SUIT_ViewManager* aViewManager = 0;
541
542     QObject* aParent = aViewPort;
543     while( aParent = aParent->parent() )
544     {
545       if( GraphicsView_ViewFrame* aViewFrame = dynamic_cast<GraphicsView_ViewFrame*>( aParent ) )
546       {
547         if( GraphicsView_Viewer* aViewer = aViewFrame->getViewer() )
548         {
549           aViewManager = aViewer->getViewManager();
550           break;
551         }
552       }
553     }
554
555     if( !aViewManager )
556       return;
557
558     double aMouseX = theEvent->scenePos().x();
559     double aMouseY = theEvent->scenePos().y();
560
561     ViewManagerRole aRole = getViewManagerRole( aViewManager );
562     if( aRole == VMR_General )
563     {
564       int aXDeg = 0, aYDeg = 0;
565       int aXMin = 0, aYMin = 0;
566       double aXSec = 0, aYSec = 0;
567       HYDROGUI_Tool::DoubleToLambert( aMouseX, aXDeg, aXMin, aXSec );
568       HYDROGUI_Tool::DoubleToLambert( aMouseY, aYDeg, aYMin, aYSec );
569
570       QString aDegSymbol( QChar( 0x00B0 ) );
571       QString aXStr = QString( "%1%2 %3' %4\"" ).arg( aXDeg ).arg( aDegSymbol ).arg( aXMin ).arg( aXSec );
572       QString aYStr = QString( "%1%2 %3' %4\"" ).arg( aYDeg ).arg( aDegSymbol ).arg( aYMin ).arg( aYSec );
573
574       aViewPort->setViewLabelText( QString( "X: %1\nY: %2" ).arg( aXStr ).arg( aYStr ) );
575     }
576     else if( aRole == VMR_TransformImage )
577       aViewPort->setViewLabelText( QString( "X: %1\nY: %2" ).arg( (int)aMouseX ).arg( (int)aMouseY ) );
578   }
579 }
580
581 void HYDROGUI_Module::updateGV( const bool theIsInit,
582                                 const bool theIsForced )
583 {
584   if( !getDisplayer() )
585     return;
586
587   QList<int> aViewManagerIdList;
588
589   // currently, all views are updated
590   ViewManagerMapIterator anIter( myViewManagerMap );
591   while( anIter.hasNext() )
592   {
593     int anId = anIter.next().key();
594     aViewManagerIdList.append( anId );
595   }
596
597   QListIterator<int> anIdIter( aViewManagerIdList );
598   while( anIdIter.hasNext() )
599     getDisplayer()->UpdateAll( anIdIter.next(), theIsInit, theIsForced );
600 }
601
602 void HYDROGUI_Module::createSelector( SUIT_ViewManager* theViewManager )
603 {
604   if( !theViewManager )
605     return;
606
607   LightApp_SelectionMgr* aSelectionMgr = getApp()->selectionMgr();
608   if( !aSelectionMgr )
609     return;
610
611   QString aViewType = theViewManager->getType();
612   if( aViewType != GraphicsView_Viewer::Type() )
613     return;
614
615   GraphicsView_ViewManager* aViewManager =
616     dynamic_cast<GraphicsView_ViewManager*>( theViewManager );
617   if( !aViewManager )
618     return;
619
620   QList<SUIT_Selector*> aSelectorList;
621   aSelectionMgr->selectors( aViewType, aSelectorList );
622
623   // disable all alien selectors
624   QList<SUIT_Selector*>::iterator anIter, anIterEnd = aSelectorList.end();
625   for( anIter = aSelectorList.begin(); anIter != anIterEnd; anIter++ )
626   {
627     SUIT_Selector* aSelector = *anIter;
628     if( aSelector && !dynamic_cast<HYDROGUI_GVSelector*>( aSelector ) )
629       aSelector->setEnabled( false );
630   }
631
632   new HYDROGUI_GVSelector( this, aViewManager->getViewer(), aSelectionMgr );
633 }
634
635 bool HYDROGUI_Module::setUpdateEnabled( const bool theState )
636 {
637   bool aPrevState = myIsUpdateEnabled;
638   myIsUpdateEnabled = theState;
639   return aPrevState;
640 }
641
642 bool HYDROGUI_Module::isUpdateEnabled() const
643 {
644   return myIsUpdateEnabled;
645 }