Salome HOME
8ac82917eff6034f7497ad77a7240f32ad18270b
[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_PolylineXY.h>
34 #include <HYDROData_ShapesGroup.h>
35 #include <HYDROData_Iterator.h>
36 #include <HYDROData_Object.h>
37 #include <HYDROData_Tool.h>
38
39 #include <OCCViewer_ViewManager.h>
40 #include <OCCViewer_ViewModel.h>
41 #include <OCCViewer_ViewWindow.h>
42
43 #include <LightApp_Application.h>
44 #include <LightApp_UpdateFlags.h>
45 #include <LightApp_SelectionMgr.h>
46 #include <LightApp_DataOwner.h>
47
48 #include <SUIT_MessageBox.h>
49 #include <SUIT_Desktop.h>
50 #include <SUIT_DataBrowser.h>
51
52 #include <QApplication>
53 #include <QKeySequence>
54 #include <QShortcut>
55
56 HYDROGUI_CalculationOp::HYDROGUI_CalculationOp( HYDROGUI_Module* theModule, bool theIsEdit )
57 : HYDROGUI_Operation( theModule ),
58   myIsEdit( theIsEdit ),
59   myActiveViewManager( NULL ),
60   myPreviewViewManager( NULL )
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       HYDROData_ListOfRules aRules;
155       Handle(HYDROData_Object) anObject1, anObject2;
156       HYDROData_PriorityType aPriority;
157       HYDROData_Zone::MergeAltitudesType aMergeType;
158       int aRulesNb = myEditedObject->GetRulesCount();
159       for ( int anIndex = 0; anIndex < aRulesNb; anIndex++ ) {
160         if ( myEditedObject->GetRule( anIndex, anObject1, aPriority, anObject2, aMergeType ) ) {
161           HYDROData_CustomRule aRule;
162           aRule.Object1 = anObject1;
163           aRule.Object2 = anObject2;
164           aRule.Priority = aPriority;
165           aRule.MergeType = aMergeType;
166
167           aRules << aRule;
168         }
169       }
170       aPanel->setRules( aRules );
171     }
172   }
173   else
174   {
175     myEditedObject =
176       Handle(HYDROData_CalculationCase)::DownCast( doc()->CreateObject( KIND_CALCULATION ) );
177     myEditedObject->SetName( anObjectName );
178     myEditedObject->SetAssignmentMode( (HYDROData_CalculationCase::AssignmentMode)aPanel->getMode() );
179   }
180
181   aPanel->setObjectName( anObjectName );
182   aPanel->setEditedObject( myEditedObject );
183
184   createPreview();
185 }
186
187 void HYDROGUI_CalculationOp::getNamesAndEntries( const HYDROData_SequenceOfObjects& theSeq, 
188                                                 QStringList& theNames, QStringList& theEntries ) const
189 {
190  
191   theNames.clear();
192   theEntries.clear();
193   HYDROData_SequenceOfObjects::Iterator anIter( theSeq );
194   for ( ; anIter.More(); anIter.Next() )
195   {
196     Handle(HYDROData_Entity) anEntity = anIter.Value();
197     //if ( !HYDROData_Tool::IsGeometryObject( anEntity ) )
198     //  continue;
199
200     theNames.append( anEntity->GetName() );
201     theEntries.append( HYDROGUI_DataObject::dataObjectEntry( anEntity ) );
202   }
203 }
204
205 void HYDROGUI_CalculationOp::abortOperation()
206 {
207   closePreview();
208   // Abort transaction
209   abortDocOperation();
210   HYDROGUI_Operation::abortOperation();
211   module()->getApp()->updateObjectBrowser();
212 }
213
214 void HYDROGUI_CalculationOp::commitOperation()
215 {
216   closePreview();
217   // Commit transaction
218   commitDocOperation();
219   HYDROGUI_Operation::commitOperation();
220 }
221
222 HYDROGUI_InputPanel* HYDROGUI_CalculationOp::createInputPanel() const
223 {
224   HYDROGUI_CalculationDlg* aPanel = new HYDROGUI_CalculationDlg( module(), getName() );
225
226   // Connect signals and slots
227   connect( aPanel, SIGNAL( changeMode( int ) ), SLOT( onChangeMode( int ) ) );
228   connect( aPanel, SIGNAL( addObjects() ), SLOT( onAddObjects() ) );
229   connect( aPanel, SIGNAL( removeObjects() ), SLOT( onRemoveObjects() ) );
230   connect( aPanel, SIGNAL( addGroups() ), SLOT( onAddGroups() ) );
231   connect( aPanel, SIGNAL( removeGroups() ), SLOT( onRemoveGroups() ) );
232   connect( aPanel, SIGNAL( Next( const int ) ), SLOT( onNext( const int ) ) );
233   connect( aPanel, SIGNAL( Back( const int ) ), SLOT( onHideZones() ) );
234   //connect( aPanel, SIGNAL( clicked( SUIT_DataObject* ) ), SLOT( onSelected( SUIT_DataObject* ) ) );
235   connect( aPanel, SIGNAL( setMergeType( int, QString& ) ), SLOT( onSetMergeType( int, QString& ) ) );
236   connect( aPanel, SIGNAL( moveZones( SUIT_DataObject*, const QList<SUIT_DataObject*>& ) ),
237     SLOT( onMoveZones( SUIT_DataObject*, const QList<SUIT_DataObject*>& ) ) );
238   connect( aPanel, SIGNAL( createRegion( const QList<SUIT_DataObject*>& ) ),
239     SLOT( onCreateRegion( const QList<SUIT_DataObject*>& ) ) );
240   connect( aPanel, SIGNAL( clickedInZonesBrowser( SUIT_DataObject* ) ),
241     SLOT( onClickedInZonesBrowser( SUIT_DataObject* ) ) );
242   connect( aPanel, SIGNAL( objectsSelected() ), 
243            SLOT( onObjectsSelected() ) );
244   connect( aPanel, SIGNAL( boundarySelected( const QString & ) ), 
245     SLOT( onBoundarySelected( const QString & ) ) );
246
247   return aPanel;
248 }
249
250 void HYDROGUI_CalculationOp::onBoundarySelected ( const QString & theObjName )
251 {
252   bool anIsToUpdateViewer = false;
253
254   // Remove the old boundary from the operation viewer
255   Handle(HYDROData_PolylineXY) aPrevPolyline = 
256     myEditedObject->GetBoundaryPolyline();
257   if ( !aPrevPolyline.IsNull() )
258   {
259     setObjectVisibility( aPrevPolyline, false );
260     anIsToUpdateViewer = true;
261   }
262
263   // Set the selected boundary polyline to the calculation case
264   Handle(HYDROData_PolylineXY) aNewPolyline = Handle(HYDROData_PolylineXY)::DownCast(
265     HYDROGUI_Tool::FindObjectByName( module(), theObjName, KIND_POLYLINEXY ) );
266   myEditedObject->SetBoundaryPolyline( aNewPolyline );
267
268   if ( myPreviewViewManager )
269   {
270     OCCViewer_Viewer* aViewer = myPreviewViewManager->getOCCViewer();
271     if ( aViewer )
272     {
273       if ( !aNewPolyline.IsNull() )
274       {
275         Handle(AIS_InteractiveContext) aCtx = aViewer->getAISContext();
276         if ( !aCtx.IsNull() )
277         {
278           setObjectVisibility( aNewPolyline, true );
279           anIsToUpdateViewer = true;
280         }
281       }
282
283       if ( anIsToUpdateViewer )
284         module()->update( UF_OCCViewer );
285     }
286   }
287 }
288
289 void HYDROGUI_CalculationOp::onObjectsSelected()
290 {
291   HYDROGUI_CalculationDlg* aPanel = 
292     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
293
294   QStringList aSelectedObjs = aPanel->getSelectedGeomObjects();
295   QMap<QString, bool> aSelectedObjsMap;
296   foreach( QString aName, aSelectedObjs )
297     aSelectedObjsMap[aName] = true;
298
299
300   // Select the appropriate geometry object shape in the viewer
301   selectionMgr()->clearSelected();
302
303   // Unhighlight all objects except selected
304   HYDROGUI_Shape* aShape = 0, *aLastShape = 0;
305   Handle(HYDROData_Entity) anEntity;
306   HYDROData_SequenceOfObjects aSeq = myEditedObject->GetGeometryObjects();
307   HYDROData_SequenceOfObjects::Iterator anIter( aSeq );
308   bool isSelected;
309   QString aName;
310   for ( ; anIter.More(); anIter.Next() )
311   {
312     anEntity = anIter.Value();
313     if ( !anEntity.IsNull() )
314     {
315       aShape = module()->getObjectShape( HYDROGUI_Module::VMR_PreviewCaseZones, anEntity );
316       if ( aShape )
317       {
318         aName = anEntity->GetName();
319         isSelected = aSelectedObjsMap.contains( aName );
320         aShape->highlight( isSelected, false );
321         aShape->update( false, false );
322         aLastShape = aShape;
323       }
324     }
325   }
326   if( aLastShape )
327     aLastShape->update( true, false );
328 }
329
330 void HYDROGUI_CalculationOp::onClickedInZonesBrowser( SUIT_DataObject* theItem )
331 {
332   HYDROGUI_Region* aRegionItem = dynamic_cast<HYDROGUI_Region*>(theItem);
333   HYDROGUI_Zone* aZoneItem;
334   selectionMgr()->clearSelected();
335   if ( aRegionItem )
336   {
337     // Select a region in preview
338     SUIT_DataOwnerPtrList aList( true );
339     DataObjectList aZones = aRegionItem->children();
340     for ( int i = 0; i < aZones.length(); i++ )
341     {
342       aZoneItem = dynamic_cast<HYDROGUI_Zone*>(aZones.at(i));
343       if ( aZoneItem )
344       {
345         aList.append( SUIT_DataOwnerPtr( new LightApp_DataOwner( aZoneItem->entry() ) ) );
346       }
347     }
348     selectionMgr()->setSelected( aList );
349   }
350   else
351   {
352     // select a single zone
353     aZoneItem = dynamic_cast<HYDROGUI_Zone*>(theItem);
354     if ( aZoneItem )
355     {
356       SUIT_DataOwnerPtrList aList( true );
357       aList.append( SUIT_DataOwnerPtr( new LightApp_DataOwner( aZoneItem->entry() ) ) );
358       selectionMgr()->setSelected( aList );
359     }
360   }
361 }
362
363 void HYDROGUI_CalculationOp::onMoveZones( SUIT_DataObject* theRegionItem, const QList<SUIT_DataObject*>& theZonesList )
364 {
365   HYDROGUI_Region* aRegion = dynamic_cast<HYDROGUI_Region*>(theRegionItem);
366   if ( aRegion )
367   {
368     QList<HYDROGUI_Zone*> aZonesList;
369     HYDROGUI_Zone* aZone;
370     // Get a list of dropped zones
371     for ( int i = 0; i < theZonesList.length(); i++ )
372     {
373       aZone = dynamic_cast<HYDROGUI_Zone*>( theZonesList.at( i ) );
374       if ( aZone )
375       {
376         aZonesList.append( aZone );
377       }
378     }
379     if ( aZonesList.length() > 0 )
380     {
381       aRegion->addZones( aZonesList );
382       HYDROGUI_CalculationDlg* aPanel = 
383         ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
384       if ( aPanel )
385       {
386         aPanel->refreshZonesBrowser();
387       }
388       createPreview();
389     }
390   }
391 }
392
393 void HYDROGUI_CalculationOp::onCreateRegion( const QList<SUIT_DataObject*>& theZonesList )
394 {
395   QList<HYDROGUI_Zone*> aZonesList;
396   HYDROGUI_Zone* aZone;
397   // Get a list of dropped zones
398   for ( int i = 0; i < theZonesList.length(); i++ )
399   {
400     aZone = dynamic_cast<HYDROGUI_Zone*>( theZonesList.at( i ) );
401     if ( aZone )
402     {
403       aZonesList.append( aZone );
404     }
405   }
406   if ( aZonesList.length() > 0 )
407   {
408     module()->getDataModel()->createNewRegion( myEditedObject, aZonesList );
409     HYDROGUI_CalculationDlg* aPanel = 
410       ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
411     if ( aPanel )
412     {
413       aPanel->refreshZonesBrowser();
414     }
415     createPreview();
416   }
417 }
418
419 void HYDROGUI_CalculationOp::onSetMergeType( int theMergeType, QString& theAltitudeName )
420 {
421   HYDROGUI_CalculationDlg* aPanel = 
422     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
423   if ( aPanel )
424   {
425     HYDROGUI_Zone* aZone = aPanel->getCurrentZone();
426     if ( aZone )
427     {
428       aZone->setMergeType( theMergeType, theAltitudeName );
429       HYDROGUI_Shape* aShape = module()->getObjectShape( HYDROGUI_Module::VMR_PreviewCaseZones, aZone->modelObject() );
430       if ( aShape )
431       {
432         aShape->update( true, false );
433       }
434     }
435     aPanel->refreshZonesBrowser();
436   }
437 }
438
439 void HYDROGUI_CalculationOp::onAddObjects()
440 {
441   HYDROGUI_CalculationDlg* aPanel = 
442     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
443   if ( !aPanel )
444     return;
445
446   // Add geometry objects selected in the module browser to the calculation case
447   QStringList aSelectedList = aPanel->getSelectedAvailableGeomObjects();
448   if ( aSelectedList.isEmpty() || !confirmRegionsChange() )
449     return;
450
451   QStringList anAddedList;
452   for (int i = 0; i < aSelectedList.length(); i++)
453   {
454     Handle(HYDROData_Object) anObject = Handle(HYDROData_Object)::DownCast( 
455       HYDROGUI_Tool::FindObjectByName( module(), aSelectedList.at( i ) ) );
456     if ( anObject.IsNull() )
457       continue;
458
459     if ( myEditedObject->AddGeometryObject( anObject ) )
460       anAddedList.append( anObject->GetName() );
461   }
462
463   if ( !anAddedList.isEmpty() )
464   {
465     aPanel->includeGeomObjects( anAddedList );
466     createPreview();
467   }
468 }
469
470 void HYDROGUI_CalculationOp::onRemoveObjects()
471 {
472   // Remove selected objects from the calculation case
473   HYDROGUI_CalculationDlg* aPanel = 
474     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
475   if ( !aPanel )
476     return;
477
478   QStringList aSelectedList = aPanel->getSelectedGeomObjects();
479   if ( aSelectedList.isEmpty() || !confirmRegionsChange() )
480     return;
481
482   for (int i = 0; i < aSelectedList.length(); i++)
483   {
484     Handle(HYDROData_Object) anObject = Handle(HYDROData_Object)::DownCast( 
485       HYDROGUI_Tool::FindObjectByName( module(), aSelectedList.at(i) ) );
486     if ( anObject.IsNull() )
487       continue;
488
489     setObjectVisibility( anObject, false );
490     myEditedObject->RemoveGeometryObject( anObject );
491   }
492
493   module()->update( UF_OCCViewer );
494   aPanel->excludeGeomObjects( aSelectedList );
495 }
496
497 bool HYDROGUI_CalculationOp::confirmRegionsChange() const
498 {
499   // Check if the case is already modified or not
500   bool isConfirmed = myEditedObject->IsMustBeUpdated();
501   if ( !isConfirmed )
502   {
503     // If not modified check if the case has already defined regions with zones
504     HYDROData_SequenceOfObjects aSeq = myEditedObject->GetRegions();
505     if ( aSeq.Length() > 0 )
506     {
507       // If there are already defined zones then ask a user to confirm zones recalculation
508       isConfirmed = ( SUIT_MessageBox::question( module()->getApp()->desktop(),
509                                tr( "REGIONS_CHANGED" ),
510                                tr( "CONFIRM_SPLITTING_ZONES_RECALCULATION_REGIONS" ),
511                                QMessageBox::Yes | QMessageBox::No,
512                                QMessageBox::No ) == QMessageBox::Yes );
513     }
514     else
515     {
516       isConfirmed = true; // No regions - no zones - nothing to recalculate
517     }
518   }
519   return isConfirmed;
520 }
521
522 bool HYDROGUI_CalculationOp::confirmModeChange() const
523 {
524   // Check if the case is already modified or not
525   bool isConfirmed = myEditedObject->IsMustBeUpdated();
526   if ( !isConfirmed )
527   {
528     // If not modified check if the case has already defined regions with zones
529     HYDROData_SequenceOfObjects aSeq = myEditedObject->GetRegions();
530     if ( aSeq.Length() > 0 )
531     {
532       // If there are already defined zones then ask a user to confirm zones recalculation
533       isConfirmed = ( SUIT_MessageBox::question( module()->getApp()->desktop(),
534                                tr( "MODE_CHANGED" ),
535                                tr( "CONFIRM_SPLITTING_ZONES_RECALCULATION_MODE" ),
536                                QMessageBox::Yes | QMessageBox::No,
537                                QMessageBox::No ) == QMessageBox::Yes );
538     }
539     else
540     {
541       isConfirmed = true; // No regions - no zones - nothing to recalculate
542     }
543   }
544   return isConfirmed;
545 }
546
547 bool HYDROGUI_CalculationOp::confirmContinueWithWarning( const HYDROData_Warning& theWarning ) const
548 {
549   HYDROData_WarningType aType = theWarning.Type;
550   if ( aType == WARN_OK ) {
551     return true;
552   }
553
554   QString aTitle;
555   QString aMsg;
556   switch ( aType )
557   {
558     case WARN_EMPTY_REGIONS:
559       aTitle = tr( "EMPTY_REGIONS" );
560       aMsg = tr( "CONFIRM_CONTINUE_WITH_OBJECTS_NOT_INCLUDED_TO_REGION" ).arg( theWarning.Data );
561       break;
562     default:
563       aTitle = tr( "WARNING" );
564       aMsg = theWarning.Data;
565   }
566
567
568   int anAnswer = SUIT_MessageBox::warning( module()->getApp()->desktop(),
569                                            aTitle, aMsg,
570                                            QMessageBox::Yes | QMessageBox::No,
571                                            QMessageBox::No );
572
573   return ( anAnswer == QMessageBox::Yes );
574 }
575
576 bool HYDROGUI_CalculationOp::processApply( int&     theUpdateFlags,
577                                            QString& theErrorMsg,
578                                            QStringList& theBrowseObjectsEntries )
579 {
580   HYDROGUI_CalculationDlg* aPanel = 
581     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
582   if ( !aPanel )
583     return false;
584
585   if( !myIsEdit )
586   {
587     QString anEntry = HYDROGUI_DataObject::dataObjectEntry( myEditedObject );
588     theBrowseObjectsEntries.append( anEntry );
589   }
590
591   // For manual mode priority rules are redundant
592   if ( aPanel->getMode() == HYDROData_CalculationCase::MANUAL &&
593        myEditedObject->GetRulesCount() > 0 ) {
594     myEditedObject->ClearRules( false );
595   }
596  
597   theUpdateFlags = UF_Model | UF_OCCViewer | UF_OCC_Forced | UF_VTKViewer | UF_VTK_Forced | UF_VTK_Init;
598
599   return true;
600 }
601
602 void HYDROGUI_CalculationOp::onApply()
603 {
604   // Check warnings
605   HYDROData_Warning aWarning = myEditedObject->GetLastWarning();
606   if ( aWarning.Type != WARN_OK ) {
607     if ( !confirmContinueWithWarning( aWarning ) ) {
608       // Go back to the first page
609       HYDROGUI_CalculationDlg* aPanel = 
610         ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
611       if ( aPanel ) {
612         aPanel->onFirstPage();
613       }
614       return;
615     }
616   }
617
618   QApplication::setOverrideCursor( Qt::WaitCursor );
619
620   int anUpdateFlags = 0;
621   QString anErrorMsg;
622   QStringList aBrowseObjectsEntries;
623
624   bool aResult = false;
625   
626   try
627   {
628     aResult = processApply( anUpdateFlags, anErrorMsg, aBrowseObjectsEntries );
629   }
630   catch ( Standard_Failure )
631   {
632     Handle(Standard_Failure) aFailure = Standard_Failure::Caught();
633     anErrorMsg = aFailure->GetMessageString();
634     aResult = false;
635   }
636   catch ( ... )
637   {
638     aResult = false;
639   }
640   
641   QApplication::restoreOverrideCursor();
642
643   if ( aResult )
644   {
645     module()->update( anUpdateFlags );
646     commit();
647     browseObjects( aBrowseObjectsEntries );
648   }
649   else
650   {
651     abort();
652     QString aMsg = tr( "INPUT_VALID_DATA" );
653     if( !anErrorMsg.isEmpty() )
654       aMsg.prepend( anErrorMsg + "\n" );
655     SUIT_MessageBox::critical( module()->getApp()->desktop(),
656                                tr( "INSUFFICIENT_INPUT_DATA" ),
657                                aMsg ); 
658   }
659 }
660
661 void HYDROGUI_CalculationOp::onNext( const int theIndex )
662 {
663   if( theIndex==1 )
664   {
665     setAvailableGroups();
666   }
667   else if( theIndex==2 )
668   {
669     HYDROGUI_CalculationDlg* aPanel = 
670       ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
671     if ( !aPanel )
672       return;
673
674     QApplication::setOverrideCursor( Qt::WaitCursor );
675   
676     QString aNewCaseName = aPanel->getObjectName();
677     QString anOldCaseName = myEditedObject->GetName();
678     bool isNameChanged = anOldCaseName != aNewCaseName;
679   
680     bool anIsToUpdateOb = isNameChanged;
681
682     // At first we must to update the case name because of 
683     // automatic names generation for regions and zones
684     myEditedObject->SetName( aNewCaseName );
685     
686     // Set parameters for automatic mode
687     int aMode = aPanel->getMode();
688     if ( aMode == HYDROData_CalculationCase::AUTOMATIC ) {
689       // Set objects in the specified order
690       myEditedObject->RemoveGeometryObjects();
691       foreach ( const QString& aName, aPanel->getAllGeomObjects() ) {
692         Handle(HYDROData_Object) anObject = Handle(HYDROData_Object)::DownCast( 
693           HYDROGUI_Tool::FindObjectByName( module(), aName ) );
694         if ( anObject.IsNull() ) {
695           continue;
696         }
697
698         myEditedObject->AddGeometryObject( anObject );
699       }
700
701       // Clear priority rules
702       if ( myEditedObject->GetRulesCount() > 0 ) {
703         myEditedObject->ClearRules( true );
704       }
705       // Set priority rules
706       foreach ( const HYDROData_CustomRule& aRule, aPanel->getRules() ) {
707         myEditedObject->AddRule( aRule.Object1, aRule.Priority,
708                                  aRule.Object2, aRule.MergeType );
709       }
710     }
711     aPanel->setEditZonesEnabled( aMode == HYDROData_CalculationCase::MANUAL );
712          
713     if ( myEditedObject->IsMustBeUpdated() )
714     {
715       myShowZones = true;
716       myEditedObject->Update();
717       
718       //aPanel->setEditedObject( myEditedObject );
719       aPanel->refreshZonesBrowser();
720     
721       closePreview();
722       createPreview();
723
724       anIsToUpdateOb = true;
725     }
726     else
727     {
728       setZonesVisible( true );
729
730       if ( isNameChanged ) {
731         module()->getDataModel()->updateObjectTree( myEditedObject );
732       }
733     }
734
735     if ( anIsToUpdateOb ) {
736       SUIT_DataBrowser* anObjBrowser = ((LightApp_Application*)module()->application())->objectBrowser();
737       if ( anObjBrowser ) {
738         anObjBrowser->updateTree( module()->getDataModel()->getDataObject( myEditedObject ), false );
739       }
740     }
741
742     QApplication::restoreOverrideCursor();
743   }
744 }
745
746 void HYDROGUI_CalculationOp::onHideZones()
747 {
748   setZonesVisible( false );
749 }
750
751 void HYDROGUI_CalculationOp::setZonesVisible( bool theIsVisible )
752 {
753   myShowZones = theIsVisible;
754   HYDROData_SequenceOfObjects aRegions = myEditedObject->GetRegions();
755   HYDROData_SequenceOfObjects::Iterator aRegionsIter( aRegions );
756   HYDROData_SequenceOfObjects aZones;
757   Handle(HYDROData_Region) aRegion;
758   if ( myPreviewViewManager ) 
759   {
760     if ( OCCViewer_Viewer* aViewer = myPreviewViewManager->getOCCViewer() )
761     {
762       Handle(AIS_InteractiveContext) aCtx = aViewer->getAISContext();
763       if ( !aCtx.IsNull() )
764       {
765         for ( ; aRegionsIter.More(); aRegionsIter.Next() )
766         {
767           aRegion = Handle(HYDROData_Region)::DownCast( aRegionsIter.Value() );
768           if ( !aRegion.IsNull() )
769           {
770             aZones = aRegion->GetZones();
771             HYDROData_SequenceOfObjects::Iterator aZonesIter( aZones );
772             for ( ; aZonesIter.More(); aZonesIter.Next() )
773             {
774               setObjectVisibility( aZonesIter.Value(), theIsVisible );
775             }
776           }
777         }
778       }
779
780       module()->update( UF_OCCViewer );
781     }
782   }
783 }
784
785 void HYDROGUI_CalculationOp::createPreview()
786 {
787   LightApp_Application* anApp = module()->getApp();
788   HYDROData_SequenceOfObjects aSeq = myEditedObject->GetGeometryObjects();
789   Handle(HYDROData_Entity) anEntity;
790
791   if ( myShowZones )
792   {
793     // Gather zones for displaying
794     HYDROData_SequenceOfObjects aRegions = myEditedObject->GetRegions();
795     HYDROData_SequenceOfObjects::Iterator aRegionsIter( aRegions );
796     HYDROData_SequenceOfObjects aZones;
797     Handle(HYDROData_Region) aRegion;
798     for ( ; aRegionsIter.More(); aRegionsIter.Next() )
799     {
800       anEntity = aRegionsIter.Value();
801       if ( !anEntity.IsNull() )
802       {
803         aRegion = Handle(HYDROData_Region)::DownCast( anEntity );
804         if ( !aRegion.IsNull() )
805         {
806           aZones = aRegion->GetZones();
807           aSeq.Append( aZones );
808         }
809       }
810     }
811   }
812
813   // Get a boundary polyline if any
814   aSeq.Append( myEditedObject->GetBoundaryPolyline() );
815
816   module()->removeViewShapes( HYDROGUI_Module::VMR_PreviewCaseZones );
817
818   if ( !myActiveViewManager )
819   {
820     if ( aSeq.IsEmpty() )
821       return;
822
823     myActiveViewManager = anApp->activeViewManager();
824   }
825
826   if ( !myPreviewViewManager )
827   {
828     myPreviewViewManager = ::qobject_cast<OCCViewer_ViewManager*>( 
829       anApp->createViewManager( OCCViewer_Viewer::Type() ) );
830     if ( myPreviewViewManager )
831     {
832       connect( myPreviewViewManager, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
833                this, SLOT( onLastViewClosed( SUIT_ViewManager* ) ) );
834
835       module()->setViewManagerRole( myPreviewViewManager, HYDROGUI_Module::VMR_PreviewCaseZones );
836       myPreviewViewManager->setTitle( tr( "PREVIEW_CASE_ZONES" ) );
837     }
838   }
839
840   if ( !myPreviewViewManager )
841     return;
842
843   if ( OCCViewer_Viewer* aViewer = myPreviewViewManager->getOCCViewer() )
844   {
845     Handle(AIS_InteractiveContext) aCtx = aViewer->getAISContext();
846     if ( !aCtx.IsNull() )
847     {
848       HYDROData_SequenceOfObjects::Iterator anIter( aSeq );
849       for ( ; anIter.More(); anIter.Next() )
850       {
851         setObjectVisibility( anIter.Value(), true );
852       }
853
854       //Process the draw events for viewer
855       QApplication::processEvents( QEventLoop::ExcludeUserInputEvents );
856       if ( OCCViewer_ViewWindow* vw = (OCCViewer_ViewWindow*)myPreviewViewManager->getActiveView() )
857         vw->onTopView();
858     }
859
860     module()->update( UF_OCCViewer | UF_FitAll );
861   }
862 }
863
864 void HYDROGUI_CalculationOp::setObjectVisibility( Handle(HYDROData_Entity) theEntity, const bool theIsVisible )
865 {
866   if ( theEntity.IsNull() || !myPreviewViewManager ) {
867     return;
868   }
869
870   OCCViewer_Viewer* aViewer = myPreviewViewManager->getOCCViewer();
871   if ( aViewer ) {
872     module()->setObjectVisible( (size_t)aViewer, theEntity, theIsVisible );
873   }
874 }
875
876 void HYDROGUI_CalculationOp::onLastViewClosed( SUIT_ViewManager* theViewManager )
877 {
878   closePreview();
879 }
880
881 void HYDROGUI_CalculationOp::closePreview()
882 {
883   SUIT_DataBrowser* aOb = ((LightApp_Application*)module()->application())->objectBrowser();
884   QList<QShortcut*> aShortcuts = aOb->findChildren<QShortcut*>();
885   QShortcut* aShortcut;
886   foreach( aShortcut, aShortcuts )
887   {
888     if ( aShortcut->key() == 
889       QKeySequence( ((LightApp_Application*)module()->application())->objectBrowser()->shortcutKey( 
890       SUIT_DataBrowser::RenameShortcut ) ) )
891     {
892       aShortcut->setEnabled( true );
893     }
894   }
895
896
897   if( myPreviewViewManager )
898   {
899     // Hide all the displayed objects in the preview view
900     OCCViewer_Viewer* aViewer = myPreviewViewManager->getOCCViewer();
901     if ( aViewer ) {
902       size_t aViewId = (size_t)aViewer;
903       HYDROData_Iterator anIterator( doc() );
904       for( ; anIterator.More(); anIterator.Next() ) {
905         Handle(HYDROData_Entity) anObject = anIterator.Current();
906         if( !anObject.IsNull() ) {
907           module()->setObjectVisible( aViewId, anObject, false );
908         }
909       }
910     }
911
912     disconnect( myPreviewViewManager, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
913                 this, SLOT( onLastViewClosed( SUIT_ViewManager* ) ) );
914
915     module()->getApp()->removeViewManager( myPreviewViewManager ); // myPreviewViewManager is deleted here
916     myPreviewViewManager = NULL;
917   }
918
919   if( myActiveViewManager )
920   {
921     HYDROGUI_Tool::SetActiveViewManager( module(), myActiveViewManager );
922     myActiveViewManager = NULL;
923   }
924 }
925
926 void HYDROGUI_CalculationOp::setAvailableGroups()
927 {
928   HYDROGUI_CalculationDlg* aPanel = 
929       ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
930
931   HYDROData_SequenceOfObjects aSeq = myEditedObject->GetGeometryGroups();
932   QStringList aList, anEntryList;
933   getNamesAndEntries( aSeq, aList, anEntryList );
934
935   QStringList aGroupsNames;
936
937   HYDROData_SequenceOfObjects anObjs = myEditedObject->GetGeometryObjects();
938   for( int anIndex = 1, aLength = anObjs.Length(); anIndex <= aLength; anIndex++ )
939   {
940     Handle_HYDROData_Object anObj = Handle_HYDROData_Object::DownCast( anObjs.Value( anIndex ) );
941     HYDROData_SequenceOfObjects aGroups = anObj->GetGroups();
942     for( int aGIndex = 1, aGLength = aGroups.Length(); aGIndex <= aGLength; aGIndex++ )
943     {
944       Handle_HYDROData_ShapesGroup aGroup = Handle_HYDROData_ShapesGroup::DownCast( aGroups.Value( aGIndex ) );
945       aGroupsNames.append( aGroup->GetName() );
946     }
947   }
948   if( myEditedObject->IsMustBeUpdated() ) {
949     for( int anIndex = 1, aLength = aSeq.Length(); anIndex <= aLength; anIndex++ ) {
950       Handle(HYDROData_ShapesGroup) aGeomGroup =
951         Handle(HYDROData_ShapesGroup)::DownCast( aSeq.Value( anIndex ) );
952       if ( !aGeomGroup.IsNull() && !aGroupsNames.contains( aGeomGroup->GetName() ) ) {
953         myEditedObject->RemoveGeometryGroup( aGeomGroup );
954       }
955     }
956   }
957
958   aPanel->setAvailableGroups( aGroupsNames );
959   aPanel->includeGroups( aList );
960
961   bool isUpdated = myEditedObject->IsMustBeUpdated();
962 }
963
964 void HYDROGUI_CalculationOp::onAddGroups()
965 {
966   HYDROGUI_CalculationDlg* aPanel = 
967     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
968   if ( !aPanel )
969     return;
970
971   // Add geometry objects selected in the module browser to the calculation case
972   QStringList aSelectedList = aPanel->getSelectedAvailableGroups();
973   if ( aSelectedList.isEmpty() || !confirmRegionsChange() )
974     return;
975
976   QStringList anAddedList;
977   for (int i = 0; i < aSelectedList.length(); i++)
978   {
979     Handle(HYDROData_ShapesGroup) aGroup = Handle(HYDROData_ShapesGroup)::DownCast( 
980       HYDROGUI_Tool::FindObjectByName( module(), aSelectedList.at( i ) ) );
981     if ( aGroup.IsNull() )
982       continue;
983
984     if ( myEditedObject->AddGeometryGroup( aGroup ) )
985       anAddedList.append( aGroup->GetName() );
986   }
987
988   if ( !anAddedList.isEmpty() )
989   {
990     aPanel->includeGroups( anAddedList );
991   }
992 }
993
994 void HYDROGUI_CalculationOp::onRemoveGroups()
995 {
996   // Remove selected objects from the calculation case
997   HYDROGUI_CalculationDlg* aPanel = 
998     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
999   if ( !aPanel )
1000     return;
1001
1002   QStringList aSelectedList = aPanel->getSelectedGroups();
1003   if ( aSelectedList.isEmpty() || !confirmRegionsChange() )
1004     return;
1005
1006   for (int i = 0; i < aSelectedList.length(); i++)
1007   {
1008     Handle(HYDROData_ShapesGroup) aGroup = Handle(HYDROData_ShapesGroup)::DownCast( 
1009       HYDROGUI_Tool::FindObjectByName( module(), aSelectedList.at(i) ) );
1010     if ( aGroup.IsNull() )
1011       continue;
1012
1013     myEditedObject->RemoveGeometryGroup( aGroup );
1014   }
1015
1016   aPanel->excludeGroups( aSelectedList );
1017 }
1018
1019 void HYDROGUI_CalculationOp::onChangeMode( int theMode )
1020 {
1021   HYDROGUI_CalculationDlg* aPanel = 
1022     ::qobject_cast<HYDROGUI_CalculationDlg*>( inputPanel() );
1023   if ( !aPanel )
1024     return;
1025
1026   if ( !confirmModeChange() ) {
1027     aPanel->setMode( myEditedObject->GetAssignmentMode() );
1028     return;
1029   }
1030
1031   myEditedObject->SetAssignmentMode( (HYDROData_CalculationCase::AssignmentMode)theMode );
1032   aPanel->setMode( theMode );
1033 }