Salome HOME
New calculation case dialog layout is implemented. Two lists of geometry objects...
[modules/hydro.git] / src / HYDROGUI / HYDROGUI_CalculationOp.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_CalculationOp.h"
24
25 #include "HYDROGUI_DataModel.h"
26 #include "HYDROGUI_CalculationDlg.h"
27 #include "HYDROGUI_Module.h"
28 #include "HYDROGUI_Tool.h"
29 #include "HYDROGUI_UpdateFlags.h"
30 #include "HYDROGUI_Zone.h"
31 #include "HYDROGUI_Region.h"
32
33 #include <HYDROData_Polyline.h>
34 #include <HYDROData_Iterator.h>
35 #include <HYDROData_ImmersibleZone.h>
36 #include <HYDROData_Object.h>
37
38 #include <OCCViewer_ViewManager.h>
39 #include <OCCViewer_ViewModel.h>
40 #include <OCCViewer_ViewWindow.h>
41
42 #include <LightApp_Application.h>
43 #include <LightApp_UpdateFlags.h>
44 #include <LightApp_SelectionMgr.h>
45 #include <LightApp_DataOwner.h>
46
47 #include <SUIT_MessageBox.h>
48 #include <SUIT_Desktop.h>
49
50 #include <QApplication>
51
52 HYDROGUI_CalculationOp::HYDROGUI_CalculationOp( HYDROGUI_Module* theModule, bool theIsEdit )
53 : HYDROGUI_Operation( theModule ),
54   myIsEdit( theIsEdit ),
55   myActiveViewManager( NULL ),
56   myPreviewViewManager( NULL )
57 {
58   setName( myIsEdit ? tr( "EDIT_CALCULATION" ) : tr( "CREATE_CALCULATION" ) );
59 }
60
61 HYDROGUI_CalculationOp::~HYDROGUI_CalculationOp()
62 {
63   closePreview();
64 }
65
66 void HYDROGUI_CalculationOp::startOperation()
67 {
68   HYDROGUI_Operation::startOperation();
69   
70   // Begin transaction
71   startDocOperation();
72
73   HYDROGUI_CalculationDlg* aPanel = 
74     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
75   if ( !aPanel )
76     return;
77
78   aPanel->reset();
79   QStringList aList;
80   QStringList anEntryList;
81   HYDROData_SequenceOfObjects aSeq = HYDROGUI_Tool::GetGeometryObjects( module() );
82   getNamesAndEntries( aSeq, aList, anEntryList );
83   aPanel->setAllGeomObjects( aList, anEntryList );
84
85   QString anObjectName = HYDROGUI_Tool::GenerateObjectName( module(), "Case" );
86
87   QStringList aSelectedObjects;
88
89   myEditedObject.Nullify();
90   if ( myIsEdit )
91   {
92     myEditedObject = Handle(HYDROData_CalculationCase)::DownCast( HYDROGUI_Tool::GetSelectedObject( module() ) );
93     if ( !myEditedObject.IsNull() )
94     {
95       anObjectName = myEditedObject->GetName();
96       aSeq = myEditedObject->GetGeometryObjects();
97       getNamesAndEntries( aSeq, aList, anEntryList );
98       aPanel->includeGeomObjects( aList );
99     }
100   }
101   else
102   {
103     myEditedObject =
104       Handle(HYDROData_CalculationCase)::DownCast( doc()->CreateObject( KIND_CALCULATION ) );
105     myEditedObject->SetName(anObjectName);
106   }
107
108   aPanel->setObjectName( anObjectName );
109   aPanel->setEditedObject( myEditedObject );
110
111   createPreview();
112 }
113
114 void HYDROGUI_CalculationOp::getNamesAndEntries( const HYDROData_SequenceOfObjects& theSeq, 
115                                                 QStringList& theNames, QStringList& theEntries ) const
116 {
117   Handle(HYDROData_Object) anObject;
118   Handle(HYDROData_Entity) anEntity;
119   theNames.clear();
120   theEntries.clear();
121   HYDROData_SequenceOfObjects::Iterator anIter( theSeq );
122   for ( ; anIter.More(); anIter.Next() )
123   {
124     anEntity = anIter.Value();
125     if ( !anEntity.IsNull() )
126     {
127       anObject = Handle(HYDROData_Object)::DownCast( anEntity );
128       if ( !anObject.IsNull() )
129       {
130         theNames.append( anObject->GetName() );
131         theEntries.append( HYDROGUI_DataObject::dataObjectEntry( anObject ) );
132       }
133     }
134   }
135 }
136
137 void HYDROGUI_CalculationOp::abortOperation()
138 {
139   closePreview();
140   // Abort transaction
141   abortDocOperation();
142   HYDROGUI_Operation::abortOperation();
143 }
144
145 void HYDROGUI_CalculationOp::commitOperation()
146 {
147   closePreview();
148   // Commit transaction
149   commitDocOperation();
150   HYDROGUI_Operation::commitOperation();
151 }
152
153 HYDROGUI_InputPanel* HYDROGUI_CalculationOp::createInputPanel() const
154 {
155   HYDROGUI_CalculationDlg* aPanel = new HYDROGUI_CalculationDlg( module(), getName() );
156
157   // Connect signals and slots
158   connect( aPanel, SIGNAL( addObjects() ), SLOT( onAddObjects() ) );
159   connect( aPanel, SIGNAL( removeObjects() ), SLOT( onRemoveObjects() ) );
160   connect( aPanel, SIGNAL( splitZones() ), SLOT( onSplitZones() ) );
161   connect( aPanel, SIGNAL( hideZones() ), SLOT( onHideZones() ) );
162   connect( aPanel, SIGNAL( clicked( SUIT_DataObject* ) ), SLOT( onSelected( SUIT_DataObject* ) ) );
163   connect( aPanel, SIGNAL( setMergeType( int, QString& ) ), SLOT( onSetMergeType( int, QString& ) ) );
164   connect( aPanel, SIGNAL( moveZones( SUIT_DataObject*, const QList<SUIT_DataObject*>& ) ),
165     SLOT( onMoveZones( SUIT_DataObject*, const QList<SUIT_DataObject*>& ) ) );
166   connect( aPanel, SIGNAL( createRegion( const QList<SUIT_DataObject*>& ) ),
167     SLOT( onCreateRegion( const QList<SUIT_DataObject*>& ) ) );
168   connect( aPanel, SIGNAL( clickedInZonesBrowser( SUIT_DataObject* ) ),
169     SLOT( onClickedInZonesBrowser( SUIT_DataObject* ) ) );
170   connect( aPanel, SIGNAL( objectSelected( const QString & ) ), 
171     SLOT( onObjectSelected( const QString & ) ) );
172
173   return aPanel;
174 }
175
176 void HYDROGUI_CalculationOp::onObjectSelected ( const QString & theObjName )
177 {
178   // Select the appropriate geometry object shape in the viewer
179   selectionMgr()->clearSelected();
180
181   // Unhighlight all objects except selected
182   HYDROGUI_Shape* aShape;
183   HYDROGUI_Shape* aSelectedShape = 0;
184   Handle(HYDROData_Entity) anEntity;
185   HYDROData_SequenceOfObjects aSeq = myEditedObject->GetGeometryObjects();
186   HYDROData_SequenceOfObjects::Iterator anIter( aSeq );
187   bool isSelected;
188   QString aName;
189   for ( ; anIter.More(); anIter.Next() )
190   {
191     anEntity = anIter.Value();
192     if ( !anEntity.IsNull() )
193     {
194       aShape = module()->getObjectShape( HYDROGUI_Module::VMR_PreviewCaseZones, anEntity );
195       if ( aShape )
196       {
197         aName = anEntity->GetName();
198         isSelected = ( aName == theObjName );
199         if ( isSelected )
200         {
201           aSelectedShape = aShape;
202         }
203         if ( aShape->isHighlighted() != isSelected )
204         {
205           if ( !isSelected )
206           {
207             aShape->highlight( isSelected );
208             aShape->update();
209           }
210         }
211       }
212     }
213   }
214   if ( aSelectedShape )
215   {
216     aSelectedShape->highlight( true );
217     aSelectedShape->update();
218   }
219 }
220
221 void HYDROGUI_CalculationOp::onClickedInZonesBrowser( SUIT_DataObject* theItem )
222 {
223   HYDROGUI_Region* aRegionItem = dynamic_cast<HYDROGUI_Region*>(theItem);
224   HYDROGUI_Zone* aZoneItem;
225   selectionMgr()->clearSelected();
226   if ( aRegionItem )
227   {
228     // Select a region in preview
229     SUIT_DataOwnerPtrList aList( true );
230     DataObjectList aZones = aRegionItem->children();
231     for ( int i = 0; i < aZones.length(); i++ )
232     {
233       aZoneItem = dynamic_cast<HYDROGUI_Zone*>(aZones.at(i));
234       if ( aZoneItem )
235       {
236         aList.append( SUIT_DataOwnerPtr( new LightApp_DataOwner( aZoneItem->entry() ) ) );
237       }
238     }
239     selectionMgr()->setSelected( aList );
240   }
241   else
242   {
243     // select a single zone
244     aZoneItem = dynamic_cast<HYDROGUI_Zone*>(theItem);
245     if ( aZoneItem )
246     {
247       SUIT_DataOwnerPtrList aList( true );
248       aList.append( SUIT_DataOwnerPtr( new LightApp_DataOwner( aZoneItem->entry() ) ) );
249       selectionMgr()->setSelected( aList );
250     }
251   }
252 }
253
254 void HYDROGUI_CalculationOp::onMoveZones( SUIT_DataObject* theRegionItem, const QList<SUIT_DataObject*>& theZonesList )
255 {
256   HYDROGUI_Region* aRegion = dynamic_cast<HYDROGUI_Region*>(theRegionItem);
257   if ( aRegion )
258   {
259     QList<HYDROGUI_Zone*> aZonesList;
260     HYDROGUI_Zone* aZone;
261     // Get a list of dropped zones
262     for ( int i = 0; i < theZonesList.length(); i++ )
263     {
264       aZone = dynamic_cast<HYDROGUI_Zone*>( theZonesList.at( i ) );
265       if ( aZone )
266       {
267         aZonesList.append( aZone );
268       }
269     }
270     if ( aZonesList.length() > 0 )
271     {
272       aRegion->addZones( aZonesList );
273       HYDROGUI_CalculationDlg* aPanel = 
274         ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
275       if ( aPanel )
276       {
277         aPanel->setEditedObject(myEditedObject);
278       }
279       createPreview();
280     }
281   }
282 }
283
284 void HYDROGUI_CalculationOp::onCreateRegion( const QList<SUIT_DataObject*>& theZonesList )
285 {
286   QList<HYDROGUI_Zone*> aZonesList;
287   HYDROGUI_Zone* aZone;
288   // Get a list of dropped zones
289   for ( int i = 0; i < theZonesList.length(); i++ )
290   {
291     aZone = dynamic_cast<HYDROGUI_Zone*>( theZonesList.at( i ) );
292     if ( aZone )
293     {
294       aZonesList.append( aZone );
295     }
296   }
297   if ( aZonesList.length() > 0 )
298   {
299     module()->getDataModel()->createNewRegion( myEditedObject, aZonesList );
300     HYDROGUI_CalculationDlg* aPanel = 
301       ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
302     if ( aPanel )
303     {
304       aPanel->setEditedObject(myEditedObject);
305     }
306     createPreview();
307   }
308 }
309
310 void HYDROGUI_CalculationOp::onSetMergeType( int theMergeType, QString& theBathymetryName )
311 {
312   HYDROGUI_CalculationDlg* aPanel = 
313     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
314   if ( aPanel )
315   {
316     HYDROGUI_Zone* aZone = aPanel->getCurrentZone();
317     if ( aZone )
318     {
319       aZone->setMergeType( theMergeType, theBathymetryName );
320       HYDROGUI_Shape* aShape = module()->getObjectShape( HYDROGUI_Module::VMR_PreviewCaseZones, aZone->modelObject() );
321       if ( aShape )
322       {
323         aShape->update();
324       }
325     }
326     aPanel->refreshZonesBrowser();
327   }
328 }
329
330 void HYDROGUI_CalculationOp::onAddObjects()
331 {
332   HYDROGUI_CalculationDlg* aPanel = 
333     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
334   if ( aPanel )
335   {
336     // Add geometry objects selected in the module browser to the calculation case
337     Handle(HYDROData_Object) anObject;
338     Handle(HYDROData_Entity) anEntity;
339     QStringList aList;
340     QStringList aSelectedList = aPanel->getSelectedAvailableGeomObjects();
341     for (int i = 0; i < aSelectedList.length(); i++)
342     {
343       anEntity = HYDROGUI_Tool::FindObjectByName( module(), aSelectedList.at(i) );
344       if ( !anEntity.IsNull() )
345       {
346         anObject = Handle(HYDROData_Object)::DownCast( anEntity );
347         if ( !anObject.IsNull() )
348         {
349           if (myEditedObject->AddGeometryObject( anObject ))
350           {
351             aList.append( anObject->GetName() );
352           }
353         }
354       }
355     }
356     if ( !aList.isEmpty() )
357     {
358       aPanel->includeGeomObjects( aList );
359       createPreview();
360     }
361   }
362 }
363
364 void HYDROGUI_CalculationOp::onRemoveObjects()
365 {
366   // Remove selected objects from the calculation case
367   HYDROGUI_CalculationDlg* aPanel = 
368     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
369   if ( aPanel )
370   {
371     QStringList aList = aPanel->getSelectedGeomObjects();
372     Handle(HYDROData_Object) anObject;
373     Handle(HYDROData_Entity) anEntity;
374     for (int i = 0; i < aList.length(); i++)
375     {
376       anEntity = HYDROGUI_Tool::FindObjectByName( module(), aList.at(i) );
377       if ( !anEntity.IsNull() )
378       {
379         anObject = Handle(HYDROData_Object)::DownCast( anEntity );
380         if ( !anObject.IsNull() )
381         {
382           module()->removeObjectShape( HYDROGUI_Module::VMR_PreviewCaseZones, anObject );
383           myEditedObject->RemoveGeometryObject( anObject );
384         }
385       }
386     }
387     if ( !aList.isEmpty() )
388     {
389       aPanel->excludeGeomObjects( aList );
390     }
391   }
392 }
393
394 bool HYDROGUI_CalculationOp::processApply( int&     theUpdateFlags,
395                                            QString& theErrorMsg )
396 {
397   HYDROGUI_CalculationDlg* aPanel = 
398     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
399   if ( !aPanel )
400     return false;
401
402   theUpdateFlags = UF_Model;
403
404   return true;
405 }
406
407 void HYDROGUI_CalculationOp::onApply()
408 {
409   QApplication::setOverrideCursor( Qt::WaitCursor );
410
411   int anUpdateFlags = 0;
412   QString anErrorMsg;
413
414   bool aResult = false;
415   
416   try
417   {
418     aResult = processApply( anUpdateFlags, anErrorMsg );
419   }
420   catch ( Standard_Failure )
421   {
422     Handle(Standard_Failure) aFailure = Standard_Failure::Caught();
423     anErrorMsg = aFailure->GetMessageString();
424     aResult = false;
425   }
426   catch ( ... )
427   {
428     aResult = false;
429   }
430   
431   QApplication::restoreOverrideCursor();
432
433   if ( aResult )
434   {
435     module()->update( anUpdateFlags );
436     commit();
437   }
438   else
439   {
440     abort();
441     QString aMsg = tr( "INPUT_VALID_DATA" );
442     if( !anErrorMsg.isEmpty() )
443       aMsg.prepend( anErrorMsg + "\n" );
444     SUIT_MessageBox::critical( module()->getApp()->desktop(),
445                                tr( "INSUFFICIENT_INPUT_DATA" ),
446                                aMsg ); 
447   }
448 }
449
450 void HYDROGUI_CalculationOp::onSplitZones()
451 {
452   QApplication::setOverrideCursor( Qt::WaitCursor );
453
454   if ( myEditedObject->IsMustBeUpdated() )
455   {
456     myShowZones = true;
457     myEditedObject->SplitGeometryObjects();
458
459     HYDROGUI_CalculationDlg* aPanel = 
460       ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
461     if ( aPanel )
462     {
463       aPanel->setEditedObject( myEditedObject );
464     }
465
466     createPreview();
467   }
468   else
469   {
470     setZonesVisible( true );
471   }
472
473   QApplication::restoreOverrideCursor();
474 }
475
476 void HYDROGUI_CalculationOp::onHideZones()
477 {
478   setZonesVisible( false );
479 }
480
481 void HYDROGUI_CalculationOp::setZonesVisible( bool theIsVisible )
482 {
483   myShowZones = theIsVisible;
484   HYDROData_SequenceOfObjects aRegions = myEditedObject->GetRegions();
485   HYDROData_SequenceOfObjects::Iterator aRegionsIter( aRegions );
486   HYDROData_SequenceOfObjects aZones;
487   Handle(HYDROData_Region) aRegion;
488   if ( myPreviewViewManager ) 
489   {
490     if ( OCCViewer_Viewer* aViewer = myPreviewViewManager->getOCCViewer() )
491     {
492       Handle(AIS_InteractiveContext) aCtx = aViewer->getAISContext();
493       if ( !aCtx.IsNull() )
494       {
495         for ( ; aRegionsIter.More(); aRegionsIter.Next() )
496         {
497           aRegion = Handle(HYDROData_Region)::DownCast( aRegionsIter.Value() );
498           if ( !aRegion.IsNull() )
499           {
500             aZones = aRegion->GetZones();
501             HYDROData_SequenceOfObjects::Iterator aZonesIter( aZones );
502             for ( ; aZonesIter.More(); aZonesIter.Next() )
503             {
504               if ( theIsVisible )
505               {
506                 showObject( aZonesIter.Value(), aCtx );
507               }
508               else
509               {
510                 module()->removeObjectShape( HYDROGUI_Module::VMR_PreviewCaseZones, aZonesIter.Value() );
511               }
512             }
513           }
514         }
515       }
516     }
517   }
518 }
519
520 void HYDROGUI_CalculationOp::createPreview()
521 {
522   LightApp_Application* anApp = module()->getApp();
523   HYDROData_SequenceOfObjects aSeq = myEditedObject->GetGeometryObjects();
524   Handle(HYDROData_Entity) anEntity;
525
526   if ( myShowZones )
527   {
528     // Gather zones for displaying
529     HYDROData_SequenceOfObjects aRegions = myEditedObject->GetRegions();
530     HYDROData_SequenceOfObjects::Iterator aRegionsIter( aRegions );
531     HYDROData_SequenceOfObjects aZones;
532     Handle(HYDROData_Region) aRegion;
533     for ( ; aRegionsIter.More(); aRegionsIter.Next() )
534     {
535       anEntity = aRegionsIter.Value();
536       if ( !anEntity.IsNull() )
537       {
538         aRegion = Handle(HYDROData_Region)::DownCast( anEntity );
539         if ( !aRegion.IsNull() )
540         {
541           aZones = aRegion->GetZones();
542           aSeq.Append( aZones );
543         }
544       }
545     }
546   }
547
548   module()->removeViewShapes( HYDROGUI_Module::VMR_PreviewCaseZones );
549
550   if ( !myActiveViewManager )
551   {
552     if ( aSeq.IsEmpty() )
553       return;
554
555     myActiveViewManager = anApp->activeViewManager();
556   }
557
558   if ( !myPreviewViewManager )
559   {
560     myPreviewViewManager = ::qobject_cast<OCCViewer_ViewManager*>( 
561       anApp->createViewManager( OCCViewer_Viewer::Type() ) );
562     if ( myPreviewViewManager )
563     {
564       connect( myPreviewViewManager, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
565                this, SLOT( onLastViewClosed( SUIT_ViewManager* ) ) );
566
567       module()->setViewManagerRole( myPreviewViewManager, HYDROGUI_Module::VMR_PreviewCaseZones );
568       myPreviewViewManager->setTitle( tr( "PREVIEW_CASE_ZONES" ) );
569     }
570   }
571
572   if ( !myPreviewViewManager )
573     return;
574
575   if ( OCCViewer_Viewer* aViewer = myPreviewViewManager->getOCCViewer() )
576   {
577     Handle(AIS_InteractiveContext) aCtx = aViewer->getAISContext();
578     if ( !aCtx.IsNull() )
579     {
580       HYDROData_SequenceOfObjects::Iterator anIter( aSeq );
581       for ( ; anIter.More(); anIter.Next() )
582       {
583         showObject( anIter.Value(), aCtx );
584       }
585
586       //Process the draw events for viewer
587       QApplication::processEvents();
588       if ( OCCViewer_ViewWindow* vw = (OCCViewer_ViewWindow*)myPreviewViewManager->getActiveView() )
589         vw->onTopView();
590     }
591   }
592 }
593
594 void HYDROGUI_CalculationOp::showObject( Handle(HYDROData_Entity) theEntity, Handle(AIS_InteractiveContext) theCtx )
595 {
596   if ( !theEntity.IsNull() )
597   {
598     HYDROGUI_Shape* aShape = module()->getObjectShape( HYDROGUI_Module::VMR_PreviewCaseZones, theEntity );
599     if ( !aShape )
600     {
601       aShape = new HYDROGUI_Shape( theCtx, theEntity );
602       module()->setObjectShape( HYDROGUI_Module::VMR_PreviewCaseZones, theEntity, aShape );
603     }
604     aShape->update();
605   }
606 }
607
608 void HYDROGUI_CalculationOp::onLastViewClosed( SUIT_ViewManager* theViewManager )
609 {
610   closePreview();
611 }
612
613 void HYDROGUI_CalculationOp::closePreview()
614 {
615   if( myPreviewViewManager )
616   {
617     disconnect( myPreviewViewManager, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
618                 this, SLOT( onLastViewClosed( SUIT_ViewManager* ) ) );
619
620     module()->getApp()->removeViewManager( myPreviewViewManager ); // myPreviewViewManager is deleted here
621     myPreviewViewManager = NULL;
622   }
623
624   if( myActiveViewManager )
625   {
626     HYDROGUI_Tool::SetActiveViewManager( module(), myActiveViewManager );
627     myActiveViewManager = NULL;
628   }
629 }
630
631