Salome HOME
Merge remote-tracking branch 'origin/BR_LAND_COVER' into BR_v14_rc
[modules/hydro.git] / src / HYDROGUI / HYDROGUI_CalculationOp.cxx
1 // Copyright (C) 2014-2015  EDF-R&D
2 // This library is free software; you can redistribute it and/or
3 // modify it under the terms of the GNU Lesser General Public
4 // License as published by the Free Software Foundation; either
5 // version 2.1 of the License, or (at your option) any later version.
6 //
7 // This library is distributed in the hope that it will be useful,
8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
10 // Lesser General Public License for more details.
11 //
12 // You should have received a copy of the GNU Lesser General Public
13 // License along with this library; if not, write to the Free Software
14 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
15 //
16 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
17 //
18
19 #include "HYDROGUI_CalculationOp.h"
20
21 #include "HYDROGUI_DataModel.h"
22 #include "HYDROGUI_CalculationDlg.h"
23 #include "HYDROGUI_Module.h"
24 #include "HYDROGUI_Tool.h"
25 #include "HYDROGUI_UpdateFlags.h"
26 #include "HYDROGUI_Zone.h"
27 #include "HYDROGUI_Region.h"
28
29 #include <HYDROData_PolylineXY.h>
30 #include <HYDROData_ShapesGroup.h>
31 #include <HYDROData_Iterator.h>
32 #include <HYDROData_ImmersibleZone.h>
33 #include <HYDROData_Object.h>
34 #include <HYDROData_Tool.h>
35 #include <HYDROData_StricklerTable.h>
36
37 #include <OCCViewer_ViewManager.h>
38 #include <OCCViewer_ViewModel.h>
39 #include <OCCViewer_ViewWindow.h>
40
41 #include <LightApp_Application.h>
42 #include <LightApp_UpdateFlags.h>
43 #include <LightApp_SelectionMgr.h>
44 #include <LightApp_DataOwner.h>
45
46 #include <SUIT_MessageBox.h>
47 #include <SUIT_Desktop.h>
48 #include <SUIT_DataBrowser.h>
49
50 #include <QApplication>
51 #include <QKeySequence>
52 #include <QShortcut>
53
54 HYDROGUI_CalculationOp::HYDROGUI_CalculationOp( HYDROGUI_Module* theModule, bool theIsEdit )
55 : HYDROGUI_Operation( theModule ),
56   myIsEdit( theIsEdit ),
57   myActiveViewManager( NULL ),
58   myPreviewViewManager( NULL ),
59   myShowGeomObjects( true ),
60   myShowZones( false )
61 {
62   setName( myIsEdit ? tr( "EDIT_CALCULATION" ) : tr( "CREATE_CALCULATION" ) );
63 }
64
65 HYDROGUI_CalculationOp::~HYDROGUI_CalculationOp()
66 {
67   closePreview();
68 }
69
70 void HYDROGUI_CalculationOp::startOperation()
71 {
72   HYDROGUI_Operation::startOperation();
73   
74   // Begin transaction
75   startDocOperation();
76
77   HYDROGUI_CalculationDlg* aPanel = 
78     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
79   if ( !aPanel )
80     return;
81
82   SUIT_DataBrowser* aOb = ((LightApp_Application*)module()->application())->objectBrowser();
83   QList<QShortcut*> aShortcuts = aOb->findChildren<QShortcut*>();
84   QShortcut* aShortcut;
85   foreach( aShortcut, aShortcuts )
86   {
87     if ( aShortcut->key() == 
88       QKeySequence(((LightApp_Application*)module()->application())->objectBrowser()->shortcutKey( 
89       SUIT_DataBrowser::RenameShortcut ) ) )
90     {
91       aShortcut->setEnabled( false );
92     }
93   }
94
95   aPanel->reset();
96   QStringList aList;
97   QStringList anEntryList;
98   HYDROData_SequenceOfObjects aSeq = HYDROGUI_Tool::GetGeometryObjects( module() );
99   getNamesAndEntries( aSeq, aList, anEntryList );
100   aPanel->setAllGeomObjects( aList, anEntryList );
101
102   // Get all polylines
103   aList.clear();
104   anEntryList.clear();
105   HYDROData_Iterator anIter( doc(), KIND_POLYLINEXY );
106   Handle(HYDROData_PolylineXY) aPolylineObj;
107   QString aPolylineName;
108   for ( ; anIter.More(); anIter.Next() )
109   {
110     aPolylineObj = Handle(HYDROData_PolylineXY)::DownCast( anIter.Current() );
111
112     if ( !aPolylineObj.IsNull() && aPolylineObj->IsClosed() )
113     { 
114       // Check the polyline shape
115       TopoDS_Shape aPolylineShape = aPolylineObj->GetShape();
116       if ( !aPolylineShape.IsNull() && aPolylineShape.ShapeType() == TopAbs_WIRE ) {
117         aPolylineName = aPolylineObj->GetName();
118         if ( !aPolylineName.isEmpty() )
119         {
120           aList.append( aPolylineName );
121           anEntryList.append( HYDROGUI_DataObject::dataObjectEntry( aPolylineObj ) );
122         }
123       }
124     }
125   }
126   aPanel->setPolylineNames( aList, anEntryList );
127
128   QString anObjectName = HYDROGUI_Tool::GenerateObjectName( module(), tr( "DEFAULT_CALCULATION_CASE_NAME" ) );
129
130   myEditedObject.Nullify();
131   if ( myIsEdit )
132   {
133     myEditedObject = Handle(HYDROData_CalculationCase)::DownCast( HYDROGUI_Tool::GetSelectedObject( module() ) );
134     if ( !myEditedObject.IsNull() )
135     {
136       aPanel->setMode( myEditedObject->GetAssignmentMode() );
137       anObjectName = myEditedObject->GetName();
138       aPolylineObj = myEditedObject->GetBoundaryPolyline();
139       if ( aPolylineObj.IsNull() )
140       {
141         aPanel->setBoundary( QString() );
142       }
143       else
144       {
145         aPolylineName = aPolylineObj->GetName();
146         aPanel->setBoundary( aPolylineName );
147       }
148
149       aSeq = myEditedObject->GetGeometryObjects();
150       getNamesAndEntries( aSeq, aList, anEntryList );
151       aPanel->includeGeomObjects( aList );
152
153       // set rules
154       setRules( HYDROData_CalculationCase::DataTag_CustomRules );      
155     }
156   }
157   else
158   {
159     myEditedObject =
160       Handle(HYDROData_CalculationCase)::DownCast( doc()->CreateObject( KIND_CALCULATION ) );
161     myEditedObject->SetName( anObjectName );
162     myEditedObject->SetAssignmentMode( (HYDROData_CalculationCase::AssignmentMode)aPanel->getMode() );
163   }
164
165   aPanel->setObjectName( anObjectName );
166   aPanel->setEditedObject( myEditedObject );
167
168   createPreview();
169 }
170
171 void HYDROGUI_CalculationOp::getNamesAndEntries( const HYDROData_SequenceOfObjects& theSeq, 
172                                                 QStringList& theNames, QStringList& theEntries ) const
173 {
174  
175   theNames.clear();
176   theEntries.clear();
177   HYDROData_SequenceOfObjects::Iterator anIter( theSeq );
178   for ( ; anIter.More(); anIter.Next() )
179   {
180     Handle(HYDROData_Entity) anEntity = anIter.Value();
181     //if ( !HYDROData_Tool::IsGeometryObject( anEntity ) )
182     //  continue;
183
184     theNames.append( anEntity->GetName() );
185     theEntries.append( HYDROGUI_DataObject::dataObjectEntry( anEntity ) );
186   }
187 }
188
189 void HYDROGUI_CalculationOp::abortOperation()
190 {
191   closePreview();
192   // Abort transaction
193   abortDocOperation();
194   HYDROGUI_Operation::abortOperation();
195   module()->getApp()->updateObjectBrowser();
196 }
197
198 void HYDROGUI_CalculationOp::commitOperation()
199 {
200   closePreview();
201   // Commit transaction
202   commitDocOperation();
203   HYDROGUI_Operation::commitOperation();
204 }
205
206 HYDROGUI_InputPanel* HYDROGUI_CalculationOp::createInputPanel() const
207 {
208   HYDROGUI_CalculationDlg* aPanel = new HYDROGUI_CalculationDlg( module(), getName() );
209
210   // Connect signals and slots
211   connect( aPanel, SIGNAL( changeMode( int ) ), SLOT( onChangeMode( int ) ) );  
212   connect( aPanel, SIGNAL( addObjects() ), SLOT( onAddObjects() ) );
213   connect( aPanel, SIGNAL( removeObjects() ), SLOT( onRemoveObjects() ) );
214   connect( aPanel, SIGNAL( addGroups() ), SLOT( onAddGroups() ) );
215   connect( aPanel, SIGNAL( removeGroups() ), SLOT( onRemoveGroups() ) );
216
217   connect( aPanel, SIGNAL( changeLandCoverMode( int ) ), SLOT( onChangeLandCoverMode( int ) ) );
218   connect( aPanel, SIGNAL( addLandCovers() ), SLOT( onAddLandCovers() ) );
219   connect( aPanel, SIGNAL( removeLandCovers() ), SLOT( onRemoveLandCovers() ) );
220   
221   connect( aPanel, SIGNAL( orderChanged( bool& ) ), SLOT( onOrderChanged( bool& ) ) );
222   connect( aPanel, SIGNAL( orderLandCoverChanged( bool& ) ), SLOT( onOrderLandCoverChanged( bool& ) ) );
223     
224   connect( aPanel, SIGNAL( Next( const int ) ), SLOT( onNext( const int ) ) );
225   connect( aPanel, SIGNAL( Back( const int ) ), SLOT( onBack( const int ) ) );
226   //connect( aPanel, SIGNAL( clicked( SUIT_DataObject* ) ), SLOT( onSelected( SUIT_DataObject* ) ) );
227   connect( aPanel, SIGNAL( setMergeType( int, QString& ) ), SLOT( onSetMergeType( int, QString& ) ) );
228   connect( aPanel, SIGNAL( moveZones( SUIT_DataObject*, const QList<SUIT_DataObject*>& ) ),
229     SLOT( onMoveZones( SUIT_DataObject*, const QList<SUIT_DataObject*>& ) ) );
230   connect( aPanel, SIGNAL( createRegion( const QList<SUIT_DataObject*>& ) ),
231     SLOT( onCreateRegion( const QList<SUIT_DataObject*>& ) ) );
232   connect( aPanel, SIGNAL( clickedInZonesBrowser( SUIT_DataObject* ) ),
233     SLOT( onClickedInZonesBrowser( SUIT_DataObject* ) ) );
234   connect( aPanel, SIGNAL( objectsSelected() ), 
235            SLOT( onObjectsSelected() ) );
236   connect( aPanel, SIGNAL( landCoversSelected() ), 
237            SLOT( onLandCoversSelected() ) );
238   connect( aPanel, SIGNAL( boundarySelected( const QString & ) ), 
239     SLOT( onBoundarySelected( const QString & ) ) );
240   connect( aPanel, SIGNAL( StricklerTableSelected( const QString & ) ), 
241     SLOT( onStricklerTableSelected( const QString & ) ) );
242
243   return aPanel;
244 }
245
246 void HYDROGUI_CalculationOp::onBoundarySelected ( const QString & theObjName )
247 {
248   bool anIsToUpdateViewer = false;
249
250   // Remove the old boundary from the operation viewer
251   Handle(HYDROData_PolylineXY) aPrevPolyline = 
252     myEditedObject->GetBoundaryPolyline();
253   if ( !aPrevPolyline.IsNull() )
254   {
255     setObjectVisibility( aPrevPolyline, false );
256     anIsToUpdateViewer = true;
257   }
258
259   // Set the selected boundary polyline to the calculation case
260   Handle(HYDROData_PolylineXY) aNewPolyline = Handle(HYDROData_PolylineXY)::DownCast(
261     HYDROGUI_Tool::FindObjectByName( module(), theObjName, KIND_POLYLINEXY ) );
262   myEditedObject->SetBoundaryPolyline( aNewPolyline );
263
264   if ( myPreviewViewManager )
265   {
266     OCCViewer_Viewer* aViewer = myPreviewViewManager->getOCCViewer();
267     if ( aViewer )
268     {
269       if ( !aNewPolyline.IsNull() )
270       {
271         Handle(AIS_InteractiveContext) aCtx = aViewer->getAISContext();
272         if ( !aCtx.IsNull() )
273         {
274           setObjectVisibility( aNewPolyline, true );
275           anIsToUpdateViewer = true;
276         }
277       }
278
279       if ( anIsToUpdateViewer )
280         module()->update( UF_OCCViewer );
281     }
282   }
283 }
284
285 void HYDROGUI_CalculationOp::onStricklerTableSelected ( const QString & theObjName )
286 {
287   bool anIsToUpdateViewer = false;
288
289   // Remove old presentations of land covers from the operation viewer  
290   Handle(HYDROData_Entity) anEntity;
291   Handle(HYDROData_LandCover) aLandCover;
292   HYDROData_SequenceOfObjects aLandCovers;
293   HYDROData_SequenceOfObjects aSeq = myEditedObject->GetLandCovers();
294   HYDROData_SequenceOfObjects::Iterator anIter( aSeq );
295   for ( ; anIter.More(); anIter.Next() )
296   {
297     anEntity = anIter.Value();
298     if ( !anEntity.IsNull() )
299     {
300       aLandCover = Handle(HYDROData_LandCover)::DownCast( anEntity );
301       if ( !aLandCover.IsNull() )
302       {
303         aLandCovers.Append( aLandCover );
304         setObjectVisibility( aLandCover, false );
305         anIsToUpdateViewer = true;
306       }
307     }
308   }
309
310   // Set the selected Strickler table to the calculation case
311   Handle(HYDROData_StricklerTable) aNewStricklerTable = Handle(HYDROData_StricklerTable)::DownCast(
312     HYDROGUI_Tool::FindObjectByName( module(), theObjName, KIND_STRICKLER_TABLE ) );
313   myEditedObject->SetStricklerTable( aNewStricklerTable );
314
315   if ( myPreviewViewManager )
316   {
317     OCCViewer_Viewer* aViewer = myPreviewViewManager->getOCCViewer();
318     if ( aViewer )
319     {
320       if ( !aNewStricklerTable.IsNull() )
321       {
322         Handle(AIS_InteractiveContext) aCtx = aViewer->getAISContext();
323         if ( !aCtx.IsNull() )
324         {
325           HYDROData_SequenceOfObjects::Iterator anIter( aLandCovers );
326           for ( ; anIter.More(); anIter.Next() )
327           {
328             anEntity = anIter.Value();
329             if ( !anEntity.IsNull() )
330             {
331               aLandCover = Handle(HYDROData_LandCover)::DownCast( anEntity );
332               if ( !aLandCover.IsNull() )
333               {
334                 setObjectVisibility( aLandCover, true );
335                 anIsToUpdateViewer = true;
336               }
337             }
338           }          
339         }
340       }
341
342       if ( anIsToUpdateViewer )
343         module()->update( UF_OCCViewer );
344     }
345   }
346 }
347
348 void HYDROGUI_CalculationOp::onObjectsSelected()
349 {
350   HYDROGUI_CalculationDlg* aPanel = 
351     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
352
353   QStringList aSelectedObjs = aPanel->getSelectedGeomObjects();
354   QMap<QString, bool> aSelectedObjsMap;
355   foreach( QString aName, aSelectedObjs )
356     aSelectedObjsMap[aName] = true;
357
358
359   // Select the appropriate geometry object shape in the viewer
360   selectionMgr()->clearSelected();
361
362   // Unhighlight all objects except selected
363   HYDROGUI_Shape* aShape = 0, *aLastShape = 0;
364   Handle(HYDROData_Entity) anEntity;
365   HYDROData_SequenceOfObjects aSeq = myEditedObject->GetGeometryObjects();
366   HYDROData_SequenceOfObjects::Iterator anIter( aSeq );
367   bool isSelected;
368   QString aName;
369   for ( ; anIter.More(); anIter.Next() )
370   {
371     anEntity = anIter.Value();
372     if ( !anEntity.IsNull() )
373     {
374       aShape = module()->getObjectShape( HYDROGUI_Module::VMR_PreviewCaseZones, anEntity );
375       if ( aShape )
376       {
377         aName = anEntity->GetName();
378         isSelected = aSelectedObjsMap.contains( aName );
379         aShape->highlight( isSelected, false );
380         aShape->update( false, false );
381         aLastShape = aShape;
382       }
383     }
384   }
385   if( aLastShape )
386     aLastShape->update( true, false );
387 }
388
389 void HYDROGUI_CalculationOp::onLandCoversSelected()
390 {
391   HYDROGUI_CalculationDlg* aPanel = 
392     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
393
394   QStringList aSelectedObjs = aPanel->getSelectedLandCovers();
395   QMap<QString, bool> aSelectedObjsMap;
396   foreach( QString aName, aSelectedObjs )
397     aSelectedObjsMap[aName] = true;
398
399
400   // Select the appropriate land cover shape in the viewer
401   selectionMgr()->clearSelected();
402
403   // Unhighlight all land covers except selected
404   HYDROGUI_Shape* aShape = 0, *aLastShape = 0;
405   Handle(HYDROData_Entity) anEntity;
406   HYDROData_SequenceOfObjects aSeq = myEditedObject->GetLandCovers();
407   HYDROData_SequenceOfObjects::Iterator anIter( aSeq );
408   bool isSelected;
409   QString aName;
410   for ( ; anIter.More(); anIter.Next() )
411   {
412     anEntity = anIter.Value();
413     if ( !anEntity.IsNull() )
414     {
415       aShape = module()->getObjectShape( HYDROGUI_Module::VMR_PreviewCaseZones, anEntity );
416       if ( aShape )
417       {
418         aName = anEntity->GetName();
419         isSelected = aSelectedObjsMap.contains( aName );
420         aShape->highlight( isSelected, false );
421         aShape->update( false, false );
422         aLastShape = aShape;
423       }
424     }
425   }
426   if( aLastShape )
427     aLastShape->update( true, false );
428 }
429
430 void HYDROGUI_CalculationOp::onClickedInZonesBrowser( SUIT_DataObject* theItem )
431 {
432   HYDROGUI_Region* aRegionItem = dynamic_cast<HYDROGUI_Region*>(theItem);
433   HYDROGUI_Zone* aZoneItem;
434   selectionMgr()->clearSelected();
435   if ( aRegionItem )
436   {
437     // Select a region in preview
438     SUIT_DataOwnerPtrList aList( true );
439     DataObjectList aZones = aRegionItem->children();
440     for ( int i = 0; i < aZones.length(); i++ )
441     {
442       aZoneItem = dynamic_cast<HYDROGUI_Zone*>(aZones.at(i));
443       if ( aZoneItem )
444       {
445         aList.append( SUIT_DataOwnerPtr( new LightApp_DataOwner( aZoneItem->entry() ) ) );
446       }
447     }
448     selectionMgr()->setSelected( aList );
449   }
450   else
451   {
452     // select a single zone
453     aZoneItem = dynamic_cast<HYDROGUI_Zone*>(theItem);
454     if ( aZoneItem )
455     {
456       SUIT_DataOwnerPtrList aList( true );
457       aList.append( SUIT_DataOwnerPtr( new LightApp_DataOwner( aZoneItem->entry() ) ) );
458       selectionMgr()->setSelected( aList );
459     }
460   }
461 }
462
463 void HYDROGUI_CalculationOp::onMoveZones( SUIT_DataObject* theRegionItem, const QList<SUIT_DataObject*>& theZonesList )
464 {
465   HYDROGUI_Region* aRegion = dynamic_cast<HYDROGUI_Region*>(theRegionItem);
466   if ( aRegion )
467   {
468     QList<HYDROGUI_Zone*> aZonesList;
469     HYDROGUI_Zone* aZone;
470     // Get a list of dropped zones
471     for ( int i = 0; i < theZonesList.length(); i++ )
472     {
473       aZone = dynamic_cast<HYDROGUI_Zone*>( theZonesList.at( i ) );
474       if ( aZone )
475       {
476         aZonesList.append( aZone );
477       }
478     }
479     if ( aZonesList.length() > 0 )
480     {
481       aRegion->addZones( aZonesList );
482       HYDROGUI_CalculationDlg* aPanel = 
483         ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
484       if ( aPanel )
485       {
486         aPanel->refreshZonesBrowser();
487       }
488       createPreview();
489     }
490   }
491 }
492
493 void HYDROGUI_CalculationOp::onCreateRegion( const QList<SUIT_DataObject*>& theZonesList )
494 {
495   QList<HYDROGUI_Zone*> aZonesList;
496   HYDROGUI_Zone* aZone;
497   // Get a list of dropped zones
498   for ( int i = 0; i < theZonesList.length(); i++ )
499   {
500     aZone = dynamic_cast<HYDROGUI_Zone*>( theZonesList.at( i ) );
501     if ( aZone )
502     {
503       aZonesList.append( aZone );
504     }
505   }
506   if ( aZonesList.length() > 0 )
507   {
508     module()->getDataModel()->createNewRegion( myEditedObject, aZonesList );
509     HYDROGUI_CalculationDlg* aPanel = 
510       ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
511     if ( aPanel )
512     {
513       aPanel->refreshZonesBrowser();
514     }
515     createPreview();
516   }
517 }
518
519 void HYDROGUI_CalculationOp::onSetMergeType( int theMergeType, QString& theAltitudeName )
520 {
521   HYDROGUI_CalculationDlg* aPanel = 
522     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
523   if ( aPanel )
524   {
525     HYDROGUI_Zone* aZone = aPanel->getCurrentZone();
526     if ( aZone )
527     {
528       aZone->setMergeType( theMergeType, theAltitudeName );
529       HYDROGUI_Shape* aShape = module()->getObjectShape( HYDROGUI_Module::VMR_PreviewCaseZones, aZone->modelObject() );
530       if ( aShape )
531       {
532         aShape->update( true, false );
533       }
534     }
535     aPanel->refreshZonesBrowser();
536   }
537 }
538
539 void HYDROGUI_CalculationOp::onAddObjects()
540 {
541   HYDROGUI_CalculationDlg* aPanel = 
542     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
543   if ( !aPanel )
544     return;
545
546   // Add geometry objects selected in the module browser to the calculation case
547   QStringList aSelectedList = aPanel->getSelectedAvailableGeomObjects();
548   if ( aSelectedList.isEmpty() || !confirmRegionsChange() )
549     return;
550
551   QStringList anAddedList;
552   for (int i = 0; i < aSelectedList.length(); i++)
553   {
554     Handle(HYDROData_Object) anObject = Handle(HYDROData_Object)::DownCast( 
555       HYDROGUI_Tool::FindObjectByName( module(), aSelectedList.at( i ) ) );
556     if ( anObject.IsNull() )
557       continue;
558
559     if ( myEditedObject->AddGeometryObject( anObject ) )
560       anAddedList.append( anObject->GetName() );
561   }
562
563   if ( !anAddedList.isEmpty() )
564   {
565     aPanel->includeGeomObjects( anAddedList );
566     createPreview();
567   }
568 }
569
570 void HYDROGUI_CalculationOp::onRemoveObjects()
571 {
572   // Remove selected objects from the calculation case
573   HYDROGUI_CalculationDlg* aPanel = 
574     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
575   if ( !aPanel )
576     return;
577
578   QStringList aSelectedList = aPanel->getSelectedGeomObjects();
579   if ( aSelectedList.isEmpty() || !confirmRegionsChange() )
580     return;
581
582   for (int i = 0; i < aSelectedList.length(); i++)
583   {
584     Handle(HYDROData_Object) anObject = Handle(HYDROData_Object)::DownCast( 
585       HYDROGUI_Tool::FindObjectByName( module(), aSelectedList.at(i) ) );
586     if ( anObject.IsNull() )
587       continue;
588
589     setObjectVisibility( anObject, false );
590     myEditedObject->RemoveGeometryObject( anObject );
591   }
592
593   module()->update( UF_OCCViewer );
594   aPanel->excludeGeomObjects( aSelectedList );
595 }
596
597 bool HYDROGUI_CalculationOp::confirmRegionsChange() const
598 {
599   // Check if the case is already modified or not
600   bool isConfirmed = myEditedObject->IsMustBeUpdated();
601   if ( !isConfirmed )
602   {
603     // If not modified check if the case has already defined regions with zones
604     HYDROData_SequenceOfObjects aSeq = myEditedObject->GetRegions();
605     if ( aSeq.Length() > 0 )
606     {
607       // If there are already defined zones then ask a user to confirm zones recalculation
608       isConfirmed = ( SUIT_MessageBox::question( module()->getApp()->desktop(),
609                                tr( "REGIONS_CHANGED" ),
610                                tr( "CONFIRM_SPLITTING_ZONES_RECALCULATION_REGIONS" ),
611                                QMessageBox::Yes | QMessageBox::No,
612                                QMessageBox::No ) == QMessageBox::Yes );
613     }
614     else
615     {
616       isConfirmed = true; // No regions - no zones - nothing to recalculate
617     }
618   }
619   return isConfirmed;
620 }
621
622 bool HYDROGUI_CalculationOp::confirmOrderChange() const
623 {
624   // Check if the case is already modified or not
625   bool isConfirmed = myEditedObject->IsMustBeUpdated();
626   if ( !isConfirmed )
627   {
628     // If not modified check if the case has already defined regions with zones
629     HYDROData_SequenceOfObjects aSeq = myEditedObject->GetRegions();
630     if ( aSeq.Length() > 0 )
631     {
632       // If there are already defined zones then ask a user to confirm zones recalculation
633       isConfirmed = ( SUIT_MessageBox::question( module()->getApp()->desktop(),
634                                tr( "ORDER_CHANGED" ),
635                                tr( "CONFIRM_SPLITTING_ZONES_RECALCULATION_REGIONS" ),
636                                QMessageBox::Yes | QMessageBox::No,
637                                QMessageBox::No ) == QMessageBox::Yes );
638     }
639     else
640     {
641       isConfirmed = true; // No regions - no zones - nothing to recalculate
642     }
643   }
644   return isConfirmed;
645 }
646
647 bool HYDROGUI_CalculationOp::confirmModeChange() const
648 {
649   // Check if the case is already modified or not
650   bool isConfirmed = myEditedObject->IsMustBeUpdated();
651   if ( !isConfirmed )
652   {
653     // If not modified check if the case has already defined regions with zones
654     HYDROData_SequenceOfObjects aSeq = myEditedObject->GetRegions();
655     if ( aSeq.Length() > 0 )
656     {
657       // If there are already defined zones then ask a user to confirm zones recalculation
658       isConfirmed = ( SUIT_MessageBox::question( module()->getApp()->desktop(),
659                                tr( "MODE_CHANGED" ),
660                                tr( "CONFIRM_SPLITTING_ZONES_RECALCULATION_MODE" ),
661                                QMessageBox::Yes | QMessageBox::No,
662                                QMessageBox::No ) == QMessageBox::Yes );
663     }
664     else
665     {
666       isConfirmed = true; // No regions - no zones - nothing to recalculate
667     }
668   }
669   return isConfirmed;
670 }
671
672 bool HYDROGUI_CalculationOp::confirmContinueWithWarning( const HYDROData_Warning& theWarning ) const
673 {
674   HYDROData_WarningType aType = theWarning.Type;
675   if ( aType == WARN_OK ) {
676     return true;
677   }
678
679   QString aTitle;
680   QString aMsg;
681   switch ( aType )
682   {
683     case WARN_EMPTY_REGIONS:
684       aTitle = tr( "EMPTY_REGIONS" );
685       aMsg = tr( "CONFIRM_CONTINUE_WITH_OBJECTS_NOT_INCLUDED_TO_REGION" ).arg( theWarning.Data );
686       break;
687     default:
688       aTitle = tr( "WARNING" );
689       aMsg = theWarning.Data;
690   }
691
692
693   int anAnswer = SUIT_MessageBox::warning( module()->getApp()->desktop(),
694                                            aTitle, aMsg,
695                                            QMessageBox::Yes | QMessageBox::No,
696                                            QMessageBox::No );
697
698   return ( anAnswer == QMessageBox::Yes );
699 }
700
701 bool HYDROGUI_CalculationOp::confirmLandCoverModeChange() const
702 {
703   // Check if the case is already modified or not
704   bool isConfirmed = myEditedObject->IsMustBeUpdated();
705   if ( !isConfirmed )
706   {
707     // If not modified check if the case has already defined regions with zones
708     // TODO: adapt HYDROData_CalculationCase class to process regions constructed for land covers
709     /*HYDROData_SequenceOfObjects aSeq = myEditedObject->GetLandCoverRegions();
710     if ( aSeq.Length() > 0 )
711     {*/
712       // If there are already defined zones then ask a user to confirm zones recalculation
713       isConfirmed = ( SUIT_MessageBox::question( module()->getApp()->desktop(),
714                                tr( "MODE_CHANGED" ),
715                                tr( "CONFIRM_LAND_COVER_PARTITION_RECALCULATION_MODE" ),
716                                QMessageBox::Yes | QMessageBox::No,
717                                QMessageBox::No ) == QMessageBox::Yes );
718     /*}
719     else
720     {
721       isConfirmed = true; // No regions - no zones - nothing to recalculate
722     }*/
723   }
724   return isConfirmed;
725 }
726
727 bool HYDROGUI_CalculationOp::confirmLandCoverOrderChange() const
728 {
729   // Check if the case is already modified or not
730   bool isConfirmed = myEditedObject->IsMustBeUpdated();
731   if ( !isConfirmed )
732   {
733     // If not modified check if the case has already defined regions with zones
734     // TODO: adapt HYDROData_CalculationCase class to process regions constructed for land covers
735     /*HYDROData_SequenceOfObjects aSeq = myEditedObject->GetLandCoverRegions();
736     if ( aSeq.Length() > 0 )
737     {*/
738       // If there are already defined zones then ask a user to confirm zones recalculation
739       isConfirmed = ( SUIT_MessageBox::question( module()->getApp()->desktop(),
740                                tr( "ORDER_CHANGED" ),
741                                tr( "CONFIRM_LAND_COVER_PARTITION_RECALCULATION_REGIONS" ),
742                                QMessageBox::Yes | QMessageBox::No,
743                                QMessageBox::No ) == QMessageBox::Yes );
744     /*}
745     else
746     {
747       isConfirmed = true; // No regions - no zones - nothing to recalculate
748     }*/
749   }
750   return isConfirmed;
751 }
752
753 bool HYDROGUI_CalculationOp::processApply( int&     theUpdateFlags,
754                                            QString& theErrorMsg,
755                                            QStringList& theBrowseObjectsEntries )
756 {
757   HYDROGUI_CalculationDlg* aPanel = 
758     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
759   if ( !aPanel )
760     return false;
761
762   if( !myIsEdit )
763   {
764     QString anEntry = HYDROGUI_DataObject::dataObjectEntry( myEditedObject );
765     theBrowseObjectsEntries.append( anEntry );
766   }
767
768   // For manual mode priority rules are redundant
769   if ( aPanel->getMode() == HYDROData_CalculationCase::MANUAL ) {
770     myEditedObject->ClearRules( HYDROData_CalculationCase::DataTag_CustomRules, false );
771   }
772   if ( aPanel->getLandCoverMode() == HYDROData_CalculationCase::MANUAL ) {
773     myEditedObject->ClearRules( HYDROData_CalculationCase::DataTag_CustomLandCoverRules, false );
774   }
775  
776   theUpdateFlags = UF_Model | UF_OCCViewer | UF_OCC_Forced | UF_VTKViewer | UF_VTK_Forced | UF_VTK_Init;
777
778   return true;
779 }
780
781 void HYDROGUI_CalculationOp::onApply()
782 {
783   // Check warnings
784   HYDROData_Warning aWarning = myEditedObject->GetLastWarning();
785   if ( aWarning.Type != WARN_OK ) {
786     if ( !confirmContinueWithWarning( aWarning ) ) {
787       // Go back to the first page
788       HYDROGUI_CalculationDlg* aPanel = 
789         ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
790       if ( aPanel ) {
791         aPanel->onFirstPage();
792       }
793       return;
794     }
795   }
796
797   QApplication::setOverrideCursor( Qt::WaitCursor );
798
799   int anUpdateFlags = 0;
800   QString anErrorMsg;
801   QStringList aBrowseObjectsEntries;
802
803   bool aResult = false;
804   
805   try
806   {
807     aResult = processApply( anUpdateFlags, anErrorMsg, aBrowseObjectsEntries );
808   }
809   catch ( Standard_Failure )
810   {
811     Handle(Standard_Failure) aFailure = Standard_Failure::Caught();
812     anErrorMsg = aFailure->GetMessageString();
813     aResult = false;
814   }
815   catch ( ... )
816   {
817     aResult = false;
818   }
819   
820   QApplication::restoreOverrideCursor();
821
822   if ( aResult )
823   {
824     module()->update( anUpdateFlags );
825     commit();
826     browseObjects( aBrowseObjectsEntries );
827   }
828   else
829   {
830     abort();
831     QString aMsg = tr( "INPUT_VALID_DATA" );
832     if( !anErrorMsg.isEmpty() )
833       aMsg.prepend( anErrorMsg + "\n" );
834     SUIT_MessageBox::critical( module()->getApp()->desktop(),
835                                tr( "INSUFFICIENT_INPUT_DATA" ),
836                                aMsg ); 
837   }
838 }
839
840 void HYDROGUI_CalculationOp::onNext( const int theIndex )
841 {
842   if( theIndex==1 )
843   {
844     setAvailableGroups();
845   }
846   else if( theIndex==2 )
847   {
848     // Land covers panel
849      HYDROGUI_CalculationDlg* aPanel = 
850       ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
851     if ( !aPanel )
852       return;
853
854     QStringList aList;
855     QStringList anEntryList;
856     HYDROData_SequenceOfObjects aSeq;
857
858     Handle(HYDROData_StricklerTable) aStricklerTableObj;
859     QString aStricklerTableName;
860
861     // Get all Strickler table objects to fill in combo-box
862     aList.clear();
863     anEntryList.clear();
864     HYDROData_Iterator anIter( doc(), KIND_STRICKLER_TABLE );      
865     for ( ; anIter.More(); anIter.Next() )
866     {
867       aStricklerTableObj = Handle(HYDROData_StricklerTable)::DownCast( anIter.Current() );
868
869       if ( !aStricklerTableObj.IsNull() )
870       { 
871         aStricklerTableName = aStricklerTableObj->GetName();
872         if ( !aStricklerTableName.isEmpty() )
873         {
874           aList.append( aStricklerTableName );
875           anEntryList.append( HYDROGUI_DataObject::dataObjectEntry( aStricklerTableObj ) );
876         }        
877       }
878     }
879     aPanel->setStricklerTableNames( aList, anEntryList );
880     if ( !aList.isEmpty() )
881       aPanel->setStricklerTable( aList.at( 0 ), false );
882
883     // Fill in list widget with all available land covers
884     aSeq = HYDROGUI_Tool::GetLandCovers( module() );
885     getNamesAndEntries( aSeq, aList, anEntryList );
886     aPanel->setAllLandCovers( aList, anEntryList );
887
888     // Set list of included land covers
889     aSeq = myEditedObject->GetLandCovers();
890     getNamesAndEntries( aSeq, aList, anEntryList );
891     aPanel->includeLandCovers( aList, true );
892     
893     if ( !myEditedObject.IsNull() )
894     {
895       if ( myIsEdit )
896       {      
897         // Select the certain Strickler table object in combo-box
898         aStricklerTableObj = myEditedObject->GetStricklerTable();
899         if ( aStricklerTableObj.IsNull() )
900         {
901           aPanel->setStricklerTable( QString() );
902         }
903         else
904         {
905           aStricklerTableName = aStricklerTableObj->GetName();
906           aPanel->setStricklerTable( aStricklerTableName );
907         }
908
909         // Set mode (Auto or Manual) to defined priority of land covers
910         aPanel->setLandCoverMode( myEditedObject->GetAssignmentLandCoverMode() );
911
912         // Set rules defined on land covers
913         setRules( HYDROData_CalculationCase::DataTag_CustomLandCoverRules );
914       }
915       else
916       {
917         myEditedObject->SetAssignmentLandCoverMode( (HYDROData_CalculationCase::AssignmentMode)aPanel->getLandCoverMode() );
918       }
919     }
920   }
921   else if( theIndex==3 )
922   {
923     HYDROGUI_CalculationDlg* aPanel = 
924       ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
925     if ( !aPanel )
926       return;
927
928     QApplication::setOverrideCursor( Qt::WaitCursor );
929
930     setGeomObjectsVisible( false );
931   
932     QString aNewCaseName = aPanel->getObjectName();
933     QString anOldCaseName = myEditedObject->GetName();
934     bool isNameChanged = anOldCaseName != aNewCaseName;
935   
936     bool anIsToUpdateOb = isNameChanged;
937
938     // At first we must to update the case name because of 
939     // automatic names generation for regions and zones
940     myEditedObject->SetName( aNewCaseName );
941     
942     // Set parameters for automatic mode
943     int aMode = aPanel->getMode();
944     if ( aMode == HYDROData_CalculationCase::AUTOMATIC )
945     {
946       // Set objects in the specified order
947       if( myEditedObject->IsMustBeUpdated() )
948       {
949         myEditedObject->RemoveGeometryObjects();
950         foreach ( const QString& aName, aPanel->getAllGeomObjects() )
951         {
952           Handle(HYDROData_Object) anObject = Handle(HYDROData_Object)::DownCast( 
953             HYDROGUI_Tool::FindObjectByName( module(), aName ) );
954           if ( anObject.IsNull() )
955           {
956             continue;
957           }
958           myEditedObject->AddGeometryObject( anObject );
959         }
960
961         // Clear priority rules
962         //@ASL if ( myEditedObject->GetRulesCount() > 0 ) {
963           myEditedObject->ClearRules( HYDROData_CalculationCase::DataTag_CustomRules, true );
964         //@ASL }
965         // Set priority rules
966         foreach ( const HYDROData_CustomRule& aRule, aPanel->getRules() ) {
967           myEditedObject->AddRule( aRule.Object1, aRule.Priority,
968                                   aRule.Object2, aRule.MergeType,
969                                   HYDROData_CalculationCase::DataTag_CustomRules );
970         }
971       }
972     }
973     aPanel->setEditZonesEnabled( aMode == HYDROData_CalculationCase::MANUAL );
974          
975     if ( myEditedObject->IsMustBeUpdated() )
976     {
977       myShowZones = true;
978       myEditedObject->Update();
979       
980       AssignDefaultZonesColors();
981
982       //aPanel->setEditedObject( myEditedObject );
983       aPanel->refreshZonesBrowser();
984     
985       closePreview();
986       createPreview();
987
988       anIsToUpdateOb = true;
989
990       myEditedObject->SetToUpdate( true );
991     }
992     else
993     {
994       setZonesVisible( true );
995
996       if ( isNameChanged ) {
997         module()->getDataModel()->updateObjectTree( myEditedObject );
998       }
999     }
1000
1001     // Move this code to processing od the last panel (see below)
1002     if ( anIsToUpdateOb ) {
1003       SUIT_DataBrowser* anObjBrowser = ((LightApp_Application*)module()->application())->objectBrowser();
1004       if ( anObjBrowser ) {
1005         anObjBrowser->updateTree( module()->getDataModel()->getDataObject( myEditedObject ), false );
1006       }
1007     }
1008
1009     QApplication::restoreOverrideCursor();
1010   }
1011   else if( theIndex==4 )
1012   {
1013     // Partition of Land covers panel
1014     HYDROGUI_CalculationDlg* aPanel = 
1015       ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
1016     if ( !aPanel )
1017       return;
1018
1019     QApplication::setOverrideCursor( Qt::WaitCursor );
1020
1021     // Set parameters for automatic mode
1022     int aMode = aPanel->getLandCoverMode();
1023     if ( aMode == HYDROData_CalculationCase::AUTOMATIC )
1024     {
1025       // Set objects in the specified order
1026       if( myEditedObject->IsMustBeUpdated() )
1027       {
1028         myEditedObject->RemoveLandCovers();
1029         foreach ( const QString& aName, aPanel->getAllLandCovers() )
1030         {
1031           Handle(HYDROData_LandCover) aLandCover = Handle(HYDROData_LandCover)::DownCast( 
1032             HYDROGUI_Tool::FindObjectByName( module(), aName ) );
1033           if ( aLandCover.IsNull() )
1034           {
1035             continue;
1036           }
1037           myEditedObject->AddLandCover( aLandCover );
1038         }
1039
1040         // Clear priority rules
1041         myEditedObject->ClearRules( HYDROData_CalculationCase::DataTag_CustomLandCoverRules, true );
1042         // Set priority rules
1043         foreach ( const HYDROData_CustomRule& aRule, aPanel->getLandCoverRules() ) {
1044           myEditedObject->AddRule( aRule.Object1, aRule.Priority,
1045                                    aRule.Object2, HYDROData_Zone::Merge_Object,
1046                                    HYDROData_CalculationCase::DataTag_CustomLandCoverRules );
1047         }
1048       }
1049     }
1050     aPanel->setEditLandCoversEnabled( aMode == HYDROData_CalculationCase::MANUAL );
1051
1052     QApplication::restoreOverrideCursor();
1053   }
1054 }
1055
1056 void HYDROGUI_CalculationOp::onBack( const int theIndex )
1057 {
1058   setGeomObjectsVisible( theIndex != 2 );
1059   setZonesVisible( false );
1060 }
1061
1062 void HYDROGUI_CalculationOp::setZonesVisible( bool theIsVisible )
1063 {
1064   myShowZones = theIsVisible;
1065   HYDROData_SequenceOfObjects aRegions = myEditedObject->GetRegions();
1066   HYDROData_SequenceOfObjects::Iterator aRegionsIter( aRegions );
1067   HYDROData_SequenceOfObjects aZones;
1068   Handle(HYDROData_Region) aRegion;
1069   if ( myPreviewViewManager ) 
1070   {
1071     if ( OCCViewer_Viewer* aViewer = myPreviewViewManager->getOCCViewer() )
1072     {
1073       Handle(AIS_InteractiveContext) aCtx = aViewer->getAISContext();
1074       if ( !aCtx.IsNull() )
1075       {
1076         for ( ; aRegionsIter.More(); aRegionsIter.Next() )
1077         {
1078           aRegion = Handle(HYDROData_Region)::DownCast( aRegionsIter.Value() );
1079           if ( !aRegion.IsNull() )
1080           {
1081             aZones = aRegion->GetZones();
1082             HYDROData_SequenceOfObjects::Iterator aZonesIter( aZones );
1083             for ( ; aZonesIter.More(); aZonesIter.Next() )
1084             {
1085               setObjectVisibility( aZonesIter.Value(), theIsVisible );
1086             }
1087           }
1088         }
1089       }
1090
1091       module()->update( UF_OCCViewer );
1092     }
1093   }
1094 }
1095
1096 void HYDROGUI_CalculationOp::setGeomObjectsVisible( bool theIsVisible )
1097 {
1098   myShowGeomObjects = theIsVisible;
1099
1100   HYDROData_SequenceOfObjects aSeq = myEditedObject->GetGeometryObjects();
1101
1102   HYDROData_SequenceOfObjects::Iterator anIter( aSeq );
1103   for ( ; anIter.More(); anIter.Next() ) {
1104     setObjectVisibility( anIter.Value(), theIsVisible );
1105   }
1106 }
1107
1108 void HYDROGUI_CalculationOp::AssignDefaultZonesColors()
1109 {
1110   HYDROData_SequenceOfObjects aRegions = myEditedObject->GetRegions();
1111   HYDROData_SequenceOfObjects::Iterator aRegionsIter( aRegions );
1112   HYDROData_SequenceOfObjects aZones;
1113   Handle(HYDROData_Region) aRegion;
1114   if ( myPreviewViewManager ) 
1115   {
1116     if ( OCCViewer_Viewer* aViewer = myPreviewViewManager->getOCCViewer() )
1117     {
1118       Handle(AIS_InteractiveContext) aCtx = aViewer->getAISContext();
1119       if ( !aCtx.IsNull() )
1120       {
1121         int aCounter = 0;        
1122         for ( ; aRegionsIter.More(); aRegionsIter.Next() )
1123         {
1124           aRegion = Handle(HYDROData_Region)::DownCast( aRegionsIter.Value() );
1125           if ( !aRegion.IsNull() )
1126           {
1127             aZones = aRegion->GetZones();
1128             HYDROData_SequenceOfObjects::Iterator aZonesIter( aZones );
1129             for ( ; aZonesIter.More(); aZonesIter.Next() )
1130             {
1131               // Zone
1132               Handle(HYDROData_Zone) aZone = Handle(HYDROData_Zone)::DownCast( aZonesIter.Value() );
1133               if ( !aZone.IsNull() )
1134               {
1135                 QColor aFillingColor = GenerateDefaultZonesColor(++aCounter);
1136                 while (aFillingColor == Qt::red)
1137                   aFillingColor = GenerateDefaultZonesColor(++aCounter);
1138                 
1139                 aZone->SetColor(aFillingColor);
1140               }
1141             }
1142           }
1143         }
1144       }
1145     }
1146   }
1147 }
1148
1149 QColor HYDROGUI_CalculationOp::GenerateDefaultZonesColor( int theIndex,
1150                                                           float theSaturation/* = 0.5*/,
1151                                                           float theValue/* = 0.95*/ ) const
1152 {
1153   float aGoldenRatioConjugate = (float)(360./582.);
1154   float aHue = (float)rand();
1155   aHue += aGoldenRatioConjugate*theIndex;
1156   aHue -= floor(aHue);
1157
1158   float aR = 0., aG = 0., aB = 0.;
1159   int aHueInt = (int)(aHue*6.);
1160   float aF = aHue*6. - aHueInt;
1161   float aP = theValue * (1. - theSaturation);
1162   float aQ = theValue * (1. - aF*theSaturation);
1163   float aT = theValue * (1. - (1. - aF) * theSaturation);
1164   switch (aHueInt)
1165   {
1166   case 0: { aR = theValue; aG = aT; aB = aP; break; }
1167   case 1: { aR = aQ; aG = theValue; aB = aP; break; }
1168   case 2: { aR = aP; aG = theValue; aB = aT; break; }
1169   case 3: { aR = aP; aG = aQ; aB = theValue; break; }
1170   case 4: { aR = aT; aG = aP; aB = theValue; break; }
1171   case 5: { aR = theValue; aG = aP; aB = aQ; break; }
1172   default: break;
1173   }
1174
1175   QColor aColor = QColor( (int)(aR*256.), (int)(aG*256.), (int)(aB*256.) );
1176   return ( aColor.isValid() ? aColor : HYDROData_ImmersibleZone::DefaultFillingColor() );
1177 }
1178
1179 void HYDROGUI_CalculationOp::setRules( HYDROData_CalculationCase::DataTag theDataTag )
1180 {
1181   HYDROGUI_CalculationDlg* aPanel = 
1182     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
1183   if ( !aPanel )
1184     return;
1185
1186   HYDROData_ListOfRules aRules;
1187   Handle(HYDROData_Entity) anObject1, anObject2;
1188   HYDROData_PriorityType aPriority;
1189   HYDROData_Zone::MergeAltitudesType aMergeType;
1190   HYDROData_CalculationCase::DataTag aDataTag = HYDROData_CalculationCase::DataTag_CustomRules;
1191   for ( int anIndex = 0; ; anIndex++ )
1192   {
1193     if ( myEditedObject->GetRule( anIndex, anObject1, aPriority, anObject2, aMergeType, theDataTag ) ) {
1194       HYDROData_CustomRule aRule;
1195       aRule.Object1 = anObject1;
1196       aRule.Object2 = anObject2;
1197       aRule.Priority = aPriority;
1198       aRule.MergeType = aMergeType;
1199
1200       aRules << aRule;
1201     }
1202     else
1203       break;
1204   }
1205
1206   if ( theDataTag == HYDROData_CalculationCase::DataTag_CustomRules )
1207     aPanel->setRules( aRules );
1208   else if ( theDataTag == HYDROData_CalculationCase::DataTag_CustomLandCoverRules )
1209     aPanel->setLandCoverRules( aRules );
1210 }
1211
1212 void HYDROGUI_CalculationOp::createPreview()
1213 {
1214   LightApp_Application* anApp = module()->getApp();
1215   HYDROData_SequenceOfObjects aSeq;
1216   if ( myShowGeomObjects )
1217   {
1218     HYDROData_SequenceOfObjects aGeomObj = myEditedObject->GetGeometryObjects();
1219     aSeq.Append( aGeomObj );
1220   }
1221   Handle(HYDROData_Entity) anEntity;
1222
1223   if ( myShowZones )
1224   {
1225     // Gather zones for displaying
1226     HYDROData_SequenceOfObjects aRegions = myEditedObject->GetRegions();
1227     HYDROData_SequenceOfObjects::Iterator aRegionsIter( aRegions );
1228     HYDROData_SequenceOfObjects aZones;
1229     Handle(HYDROData_Region) aRegion;
1230     for ( ; aRegionsIter.More(); aRegionsIter.Next() )
1231     {
1232       anEntity = aRegionsIter.Value();
1233       if ( !anEntity.IsNull() )
1234       {
1235         aRegion = Handle(HYDROData_Region)::DownCast( anEntity );
1236         if ( !aRegion.IsNull() )
1237         {
1238           aZones = aRegion->GetZones();
1239           aSeq.Append( aZones );
1240         }
1241       }
1242     }
1243   }
1244
1245   // Get a boundary polyline if any
1246   aSeq.Append( myEditedObject->GetBoundaryPolyline() );
1247
1248   module()->removeViewShapes( HYDROGUI_Module::VMR_PreviewCaseZones );
1249
1250   if ( !myActiveViewManager )
1251   {
1252     if ( aSeq.IsEmpty() )
1253       return;
1254
1255     myActiveViewManager = anApp->activeViewManager();
1256   }
1257
1258   if ( !myPreviewViewManager )
1259   {
1260     myPreviewViewManager = ::qobject_cast<OCCViewer_ViewManager*>( 
1261       anApp->createViewManager( OCCViewer_Viewer::Type() ) );
1262     if ( myPreviewViewManager )
1263     {
1264       connect( myPreviewViewManager, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
1265                this, SLOT( onLastViewClosed( SUIT_ViewManager* ) ) );
1266
1267       module()->setViewManagerRole( myPreviewViewManager, HYDROGUI_Module::VMR_PreviewCaseZones );
1268       myPreviewViewManager->setTitle( tr( "PREVIEW_CASE_ZONES" ) );
1269     }
1270   }
1271
1272   if ( !myPreviewViewManager )
1273     return;
1274
1275   if ( OCCViewer_Viewer* aViewer = myPreviewViewManager->getOCCViewer() )
1276   {
1277     Handle(AIS_InteractiveContext) aCtx = aViewer->getAISContext();
1278     if ( !aCtx.IsNull() )
1279     {
1280       HYDROData_SequenceOfObjects::Iterator anIter( aSeq );
1281       for ( ; anIter.More(); anIter.Next() )
1282       {
1283         setObjectVisibility( anIter.Value(), true );
1284       }
1285
1286       //Process the draw events for viewer
1287       QApplication::processEvents( QEventLoop::ExcludeUserInputEvents );
1288       if ( OCCViewer_ViewWindow* vw = (OCCViewer_ViewWindow*)myPreviewViewManager->getActiveView() )
1289         vw->onTopView();
1290     }
1291
1292     module()->update( UF_OCCViewer | UF_FitAll );
1293   }
1294 }
1295
1296 void HYDROGUI_CalculationOp::setObjectVisibility( Handle(HYDROData_Entity) theEntity, const bool theIsVisible )
1297 {
1298   if ( theEntity.IsNull() || !myPreviewViewManager ) {
1299     return;
1300   }
1301
1302   OCCViewer_Viewer* aViewer = myPreviewViewManager->getOCCViewer();
1303   if ( aViewer ) {
1304     module()->setObjectVisible( (size_t)aViewer, theEntity, theIsVisible );
1305   }
1306 }
1307
1308 void HYDROGUI_CalculationOp::onLastViewClosed( SUIT_ViewManager* theViewManager )
1309 {
1310   closePreview();
1311 }
1312
1313 void HYDROGUI_CalculationOp::closePreview()
1314 {
1315   SUIT_DataBrowser* aOb = ((LightApp_Application*)module()->application())->objectBrowser();
1316   QList<QShortcut*> aShortcuts = aOb->findChildren<QShortcut*>();
1317   QShortcut* aShortcut;
1318   foreach( aShortcut, aShortcuts )
1319   {
1320     if ( aShortcut->key() == 
1321       QKeySequence( ((LightApp_Application*)module()->application())->objectBrowser()->shortcutKey( 
1322       SUIT_DataBrowser::RenameShortcut ) ) )
1323     {
1324       aShortcut->setEnabled( true );
1325     }
1326   }
1327
1328
1329   if( myPreviewViewManager )
1330   {
1331     // Hide all the displayed objects in the preview view
1332     OCCViewer_Viewer* aViewer = myPreviewViewManager->getOCCViewer();
1333     if ( aViewer ) {
1334       size_t aViewId = (size_t)aViewer;
1335       HYDROData_Iterator anIterator( doc() );
1336       for( ; anIterator.More(); anIterator.Next() ) {
1337         Handle(HYDROData_Entity) anObject = anIterator.Current();
1338         if( !anObject.IsNull() ) {
1339           module()->setObjectVisible( aViewId, anObject, false );
1340         }
1341       }
1342     }
1343
1344     disconnect( myPreviewViewManager, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
1345                 this, SLOT( onLastViewClosed( SUIT_ViewManager* ) ) );
1346
1347     module()->getApp()->removeViewManager( myPreviewViewManager ); // myPreviewViewManager is deleted here
1348     myPreviewViewManager = NULL;
1349   }
1350
1351   if( myActiveViewManager )
1352   {
1353     HYDROGUI_Tool::SetActiveViewManager( module(), myActiveViewManager );
1354     myActiveViewManager = NULL;
1355   }
1356 }
1357
1358 void HYDROGUI_CalculationOp::setAvailableGroups()
1359 {
1360   HYDROGUI_CalculationDlg* aPanel = 
1361       ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
1362
1363   HYDROData_SequenceOfObjects aSeq = myEditedObject->GetGeometryGroups();
1364   QStringList aList, anEntryList;
1365   getNamesAndEntries( aSeq, aList, anEntryList );
1366
1367   QStringList aGroupsNames;
1368
1369   HYDROData_SequenceOfObjects anObjs = myEditedObject->GetGeometryObjects();
1370   for( int anIndex = 1, aLength = anObjs.Length(); anIndex <= aLength; anIndex++ )
1371   {
1372     Handle_HYDROData_Object anObj = Handle_HYDROData_Object::DownCast( anObjs.Value( anIndex ) );
1373     HYDROData_SequenceOfObjects aGroups = anObj->GetGroups();
1374     for( int aGIndex = 1, aGLength = aGroups.Length(); aGIndex <= aGLength; aGIndex++ )
1375     {
1376       Handle_HYDROData_ShapesGroup aGroup = Handle_HYDROData_ShapesGroup::DownCast( aGroups.Value( aGIndex ) );
1377       aGroupsNames.append( aGroup->GetName() );
1378     }
1379   }
1380   if( myEditedObject->IsMustBeUpdated() ) {
1381     for( int anIndex = 1, aLength = aSeq.Length(); anIndex <= aLength; anIndex++ ) {
1382       Handle(HYDROData_ShapesGroup) aGeomGroup =
1383         Handle(HYDROData_ShapesGroup)::DownCast( aSeq.Value( anIndex ) );
1384       if ( !aGeomGroup.IsNull() && !aGroupsNames.contains( aGeomGroup->GetName() ) ) {
1385         myEditedObject->RemoveGeometryGroup( aGeomGroup );
1386       }
1387     }
1388   }
1389
1390   aPanel->setAvailableGroups( aGroupsNames );
1391   aPanel->includeGroups( aList );
1392
1393   bool isUpdated = myEditedObject->IsMustBeUpdated();
1394 }
1395
1396 void HYDROGUI_CalculationOp::onAddGroups()
1397 {
1398   HYDROGUI_CalculationDlg* aPanel = 
1399     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
1400   if ( !aPanel )
1401     return;
1402
1403   // Add geometry objects selected in the module browser to the calculation case
1404   QStringList aSelectedList = aPanel->getSelectedAvailableGroups();
1405   if ( aSelectedList.isEmpty() || !confirmRegionsChange() )
1406     return;
1407
1408   QStringList anAddedList;
1409   for (int i = 0; i < aSelectedList.length(); i++)
1410   {
1411     Handle(HYDROData_ShapesGroup) aGroup = Handle(HYDROData_ShapesGroup)::DownCast( 
1412       HYDROGUI_Tool::FindObjectByName( module(), aSelectedList.at( i ) ) );
1413     if ( aGroup.IsNull() )
1414       continue;
1415
1416     if ( myEditedObject->AddGeometryGroup( aGroup ) )
1417       anAddedList.append( aGroup->GetName() );
1418   }
1419
1420   if ( !anAddedList.isEmpty() )
1421   {
1422     aPanel->includeGroups( anAddedList );
1423   }
1424 }
1425
1426 void HYDROGUI_CalculationOp::onRemoveGroups()
1427 {
1428   // Remove selected objects from the calculation case
1429   HYDROGUI_CalculationDlg* aPanel = 
1430     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
1431   if ( !aPanel )
1432     return;
1433
1434   QStringList aSelectedList = aPanel->getSelectedGroups();
1435   if ( aSelectedList.isEmpty() || !confirmRegionsChange() )
1436     return;
1437
1438   for (int i = 0; i < aSelectedList.length(); i++)
1439   {
1440     Handle(HYDROData_ShapesGroup) aGroup = Handle(HYDROData_ShapesGroup)::DownCast( 
1441       HYDROGUI_Tool::FindObjectByName( module(), aSelectedList.at(i) ) );
1442     if ( aGroup.IsNull() )
1443       continue;
1444
1445     myEditedObject->RemoveGeometryGroup( aGroup );
1446   }
1447
1448   aPanel->excludeGroups( aSelectedList );
1449 }
1450
1451 void HYDROGUI_CalculationOp::onChangeLandCoverMode( int theMode )
1452 {
1453   HYDROGUI_CalculationDlg* aPanel = 
1454     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
1455   if ( !aPanel )
1456     return;
1457
1458   if ( !confirmLandCoverModeChange() ) {
1459     aPanel->setLandCoverMode( myEditedObject->GetAssignmentLandCoverMode() );
1460     return;
1461   }
1462
1463   myEditedObject->SetAssignmentLandCoverMode( (HYDROData_CalculationCase::AssignmentMode)theMode );
1464   aPanel->setLandCoverMode( theMode );
1465 }
1466
1467 void HYDROGUI_CalculationOp::onAddLandCovers()
1468 {
1469   HYDROGUI_CalculationDlg* aPanel = 
1470     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
1471   if ( !aPanel )
1472     return;
1473
1474   // Add land covers selected in the module browser to the calculation case
1475   QStringList aSelectedList = aPanel->getSelectedAvailableLandCovers();
1476   if ( aSelectedList.isEmpty() || !confirmRegionsChange() )
1477     return;
1478
1479   QStringList anAddedList;
1480   for (int i = 0; i < aSelectedList.length(); i++)
1481   {
1482     Handle(HYDROData_LandCover) anObject = Handle(HYDROData_LandCover)::DownCast( 
1483       HYDROGUI_Tool::FindObjectByName( module(), aSelectedList.at( i ) ) );
1484     if ( anObject.IsNull() )
1485       continue;
1486
1487     if ( myEditedObject->AddLandCover( anObject ) )
1488       anAddedList.append( anObject->GetName() );
1489   }
1490
1491   if ( !anAddedList.isEmpty() )
1492   {
1493     aPanel->includeLandCovers( anAddedList, false );
1494     // TODO: create preview of included land covers
1495     //createPreview();
1496   }
1497 }
1498
1499 void HYDROGUI_CalculationOp::onRemoveLandCovers()
1500 {
1501   // Remove selected objects from the calculation case
1502   HYDROGUI_CalculationDlg* aPanel = 
1503     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
1504   if ( !aPanel )
1505     return;
1506
1507   QStringList aSelectedList = aPanel->getSelectedLandCovers();
1508   if ( aSelectedList.isEmpty() || !confirmRegionsChange() )
1509     return;
1510
1511   for (int i = 0; i < aSelectedList.length(); i++)
1512   {
1513     Handle(HYDROData_LandCover) anObject = Handle(HYDROData_LandCover)::DownCast( 
1514       HYDROGUI_Tool::FindObjectByName( module(), aSelectedList.at(i) ) );
1515     if ( anObject.IsNull() )
1516       continue;
1517
1518     setObjectVisibility( anObject, false );
1519     myEditedObject->RemoveLandCover( anObject );
1520   }
1521
1522   module()->update( UF_OCCViewer );
1523   aPanel->excludeLandCovers( aSelectedList );
1524 }
1525
1526 void HYDROGUI_CalculationOp::onChangeMode( int theMode )
1527 {
1528   HYDROGUI_CalculationDlg* aPanel = 
1529     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
1530   if ( !aPanel )
1531     return;
1532
1533   if ( !confirmModeChange() ) {
1534     aPanel->setMode( myEditedObject->GetAssignmentMode() );
1535     return;
1536   }
1537
1538   myEditedObject->SetAssignmentMode( (HYDROData_CalculationCase::AssignmentMode)theMode );
1539   aPanel->setMode( theMode );
1540 }
1541
1542 void HYDROGUI_CalculationOp::onOrderChanged( bool& isConfirmed )
1543 {
1544   HYDROGUI_CalculationDlg* aPanel = 
1545     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
1546   if ( !aPanel )
1547     return;
1548
1549   isConfirmed = confirmOrderChange();
1550   if( isConfirmed )
1551     myEditedObject->SetToUpdate( true );
1552 }
1553
1554 void HYDROGUI_CalculationOp::onOrderLandCoverChanged( bool& isConfirmed )
1555 {
1556   HYDROGUI_CalculationDlg* aPanel = 
1557     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
1558   if ( !aPanel )
1559     return;
1560
1561   isConfirmed = confirmLandCoverOrderChange();
1562   if( isConfirmed )
1563     myEditedObject->SetToUpdate( true );
1564 }