Salome HOME
Merge branch 'BR_H2018_2' of https://codev-tuleap.cea.fr/plugins/git/salome/hydro...
[modules/hydro.git] / src / HYDROGUI / HYDROGUI_LandCoverMapOp.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_LandCoverMapOp.h"
20
21 #include "HYDROGUI_Module.h"
22 #include "HYDROGUI_OCCDisplayer.h"
23 #include "HYDROGUI_Operations.h"
24 #include "HYDROGUI_LandCoverMapDlg.h"
25 #include "HYDROGUI_Tool2.h"
26 #include "HYDROGUI_UpdateFlags.h"
27 #include "HYDROGUI_DataObject.h"
28 #include "HYDROGUI_ShapeLandCoverMap.h"
29 #include "HYDROGUI_OCCSelector.h"
30
31 #include <HYDROData_Iterator.h>
32 #include <HYDROData_StricklerTable.h>
33 #include <HYDROData_PolylineXY.h>
34 #include <HYDROData_Object.h>
35
36 #include <OCCViewer_ViewManager.h>
37 #include <OCCViewer_ViewModel.h>
38 #include <OCCViewer_ViewWindow.h>
39 #include <OCCViewer_ViewPort3d.h>
40
41 #include <OCCViewer_ViewManager.h>
42
43 #include <SalomeApp_Study.h>
44 #include <LightApp_Application.h>
45 #include <LightApp_SelectionMgr.h>
46 #include <LightApp_DataOwner.h>
47 #include <SUIT_ViewWindow.h>
48 #include <SUIT_DataObject.h>
49
50 #include <TopoDS.hxx>
51 #include <TopoDS_Face.hxx>
52 #include <TopTools_ListOfShape.hxx>
53 #include <TopTools_ListIteratorOfListOfShape.hxx>
54 #include <AIS_Shape.hxx>
55
56 #include <QApplication>
57 #include <QMouseEvent>
58
59 HYDROGUI_LandCoverMapOp::HYDROGUI_LandCoverMapOp( HYDROGUI_Module* theModule, const int theOperationId )
60 : HYDROGUI_Operation( theModule ),
61   myOperationId( theOperationId ),
62   myPreviewPrs( 0 ),
63   myPolylineFacePreviewPrs( 0 )
64 {
65   switch( myOperationId )
66   {
67     case CreateLandCoverMapId:
68       setName( tr( "CREATE_LAND_COVER_MAP" ) );
69       break;
70     case AddLandCoverId:
71       setName( tr( "ADD_LAND_COVER" ) );
72       break;
73     case RemoveLandCoverId:
74       setName( tr( "REMOVE_LAND_COVER" ) );
75       break;
76     case SplitLandCoverId:
77       setName( tr( "SPLIT_LAND_COVER" ) );
78       break;
79     case MergeLandCoverId:
80       setName( tr( "MERGE_LAND_COVER" ) );
81       break;
82     case ChangeLandCoverTypeId:
83       setName( tr( "CHANGE_LAND_COVER_TYPE" ) );
84       break;
85   }  
86 }
87
88 HYDROGUI_LandCoverMapOp::~HYDROGUI_LandCoverMapOp()
89 {
90   closePreview();
91 }
92
93 void HYDROGUI_LandCoverMapOp::startOperation()
94 {
95   HYDROGUI_Operation::startOperation();
96
97   HYDROGUI_LandCoverMapDlg* aPanel = ::qobject_cast<HYDROGUI_LandCoverMapDlg*>( inputPanel() );
98   if ( !aPanel )
99     return;
100
101   aPanel->blockSignals( true );
102
103   aPanel->reset();
104
105   // Set name of the created/edited land cover map object
106   QString anObjectName = HYDROGUI_Tool::GenerateObjectName( module(), tr( "DEFAULT_LAND_COVER_MAP_NAME" ) );
107   if ( myOperationId != CreateLandCoverMapId )
108   {
109     if ( isApplyAndClose() )
110       myEditedObject = Handle(HYDROData_LandCoverMap)::DownCast( HYDROGUI_Tool::GetSelectedObject( module() ) );
111     
112     // Construct a list of names of all land cover map objects defined within the data model
113     QStringList aLandCoverMapNames;
114     HYDROData_Iterator anIterator( doc(), KIND_LAND_COVER_MAP );
115     for( ; anIterator.More(); anIterator.Next() )
116     {
117       Handle(HYDROData_LandCoverMap) aLandCoverObj =
118         Handle(HYDROData_LandCoverMap)::DownCast( anIterator.Current() );       
119       if ( !aLandCoverObj.IsNull() )
120         aLandCoverMapNames.append( aLandCoverObj->GetName() );
121     }
122     
123     //aLandCoverMapNames.sort();
124     aPanel->setObjectNames( aLandCoverMapNames );
125
126     if ( myEditedObject.IsNull() )
127     {
128       if ( !aLandCoverMapNames.empty() )
129       {
130         anObjectName = aLandCoverMapNames.first();
131         if ( !anObjectName.isEmpty())
132         {
133           Handle(HYDROData_LandCoverMap) anObject =
134             Handle(HYDROData_LandCoverMap)::DownCast( HYDROGUI_Tool::FindObjectByName( module(), anObjectName ) );
135           if( !anObject.IsNull() )
136             myEditedObject = anObject;
137         }
138       }
139     }
140     else
141       anObjectName = myEditedObject->GetName();
142   }  
143   aPanel->setObjectName( anObjectName );
144
145   closePreview();
146   if ( myOperationId != CreateLandCoverMapId )
147     onCreatePreview();
148
149   aPanel->blockSignals( false );
150
151   module()->update( UF_OCCViewer | UF_FitAll );
152 }
153
154 void HYDROGUI_LandCoverMapOp::abortOperation()
155 {
156   closePreview();
157
158   bool aNoActiveOps = module()->getActiveOperations().isEmpty();
159
160   HYDROGUI_Operation::abortOperation();
161
162   SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( module()->getApp()->activeStudy() );
163   if ( aStudy && !aNoActiveOps )
164     module()->update( UF_OCCViewer | UF_FitAll );
165 }
166
167 void HYDROGUI_LandCoverMapOp::commitOperation()
168 {
169   closePreview();
170
171   HYDROGUI_Operation::commitOperation();
172
173   module()->update( UF_OCCViewer | UF_FitAll );
174 }
175
176 HYDROGUI_InputPanel* HYDROGUI_LandCoverMapOp::createInputPanel() const
177 {
178   HYDROGUI_LandCoverMapDlg* aPanel = new HYDROGUI_LandCoverMapDlg( module(), getName(), myOperationId );
179   connect( aPanel, SIGNAL( landCoverMapChanged( const QString& ) ),
180            this, SLOT( onLandCoverMapChanged( const QString& ) ) );
181   connect( aPanel, SIGNAL( polylineFaceChanged() ),
182            this, SLOT( onPolylineFaceChanged() ) );
183   return aPanel;
184 }
185
186 bool HYDROGUI_LandCoverMapOp::processApply( int& theUpdateFlags,
187                                             QString& theErrorMsg,
188                                             QStringList& theBrowseObjectsEntries )
189 {
190   HYDROGUI_LandCoverMapDlg* aPanel = ::qobject_cast<HYDROGUI_LandCoverMapDlg*>( inputPanel() );
191   if ( !aPanel )
192     return false;
193
194   // Check name of the created/edited object
195   QString anObjectName = aPanel->getObjectName().simplified();
196   if ( anObjectName.isEmpty() )
197   {
198     theErrorMsg = tr( "INCORRECT_OBJECT_NAME" );
199     return false;
200   }
201
202   if ( myOperationId == CreateLandCoverMapId || ( !myEditedObject.IsNull() && myEditedObject->GetName() != anObjectName ) )
203   {
204     // check that there are no other objects with the same name in the document
205     Handle(HYDROData_Entity) anObject = HYDROGUI_Tool::FindObjectByName( module(), anObjectName );
206     if( !anObject.IsNull() )
207     {
208       theErrorMsg = tr( "OBJECT_EXISTS_IN_DOCUMENT" ).arg( anObjectName );
209       return false;
210     }
211   }
212
213   Handle(HYDROData_PolylineXY) aPolyline;
214   Handle(HYDROData_Object) aFace;
215
216   TopTools_ListOfShape aFacesSelectedInViewer;
217
218   // Get polyline/face selected in combo-box
219   if ( myOperationId == CreateLandCoverMapId || myOperationId == AddLandCoverId || myOperationId == SplitLandCoverId )
220   {
221     Handle(HYDROData_Entity) aPolylineFace = aPanel->getPolylineFace();
222     aPolyline = Handle(HYDROData_PolylineXY)::DownCast( aPolylineFace );
223     aFace = Handle(HYDROData_Object)::DownCast( aPolylineFace );
224     if ( aPolyline.IsNull() && aFace.IsNull() )
225     {
226       theErrorMsg = tr( "POLYLINE_FACE_NOT_DEFINED" );
227       return false;
228     }
229   }
230   // Get face(s) selected in the 3d viewer
231   else if ( myOperationId == RemoveLandCoverId || 
232             myOperationId == MergeLandCoverId || 
233             myOperationId == ChangeLandCoverTypeId )
234   {
235     if ( myPreviewPrs )
236       // Fill in aFacesSelectedInViewer list
237       getSelectedShapes( aFacesSelectedInViewer );
238   }
239
240   // Get selected Strickler type
241   QString aSelectedStricklerType;
242   if ( myOperationId == CreateLandCoverMapId || 
243        myOperationId == AddLandCoverId || 
244        myOperationId == MergeLandCoverId ||
245        myOperationId == ChangeLandCoverTypeId )
246   {
247     aSelectedStricklerType = aPanel->getSelectedStricklerTypeName();
248     if ( aSelectedStricklerType.isEmpty() )
249     {
250       theErrorMsg = tr( "STRICKLER_TYPE_NOT_DEFINED" );
251       return false;
252     }
253   }
254
255   // Create / find the new / edited land cover map object
256   Handle(HYDROData_LandCoverMap) aLandCoverMapObj = myOperationId != CreateLandCoverMapId ? myEditedObject :
257     Handle(HYDROData_LandCoverMap)::DownCast( doc()->CreateObject( KIND_LAND_COVER_MAP ) );
258   if ( aLandCoverMapObj.IsNull() )
259   {
260     theErrorMsg = tr( "LAND_COVER_MAP_UNDEFINED" );
261     return false;
262   }
263
264   // Set land cover map name
265   aLandCoverMapObj->SetName( anObjectName );
266   
267   // Add land cover to new / edited land cover map
268   if ( myOperationId == CreateLandCoverMapId || myOperationId == AddLandCoverId )
269   {
270     bool aLandCoverAdded = false;
271     if ( !aPolyline.IsNull() )
272       aLandCoverAdded = aLandCoverMapObj->Add( aPolyline, aSelectedStricklerType );
273     else if ( !aFace.IsNull() )
274       aLandCoverAdded = aLandCoverMapObj->Add( aFace, aSelectedStricklerType );
275     if ( !aLandCoverAdded )
276     {
277       theErrorMsg = tr( "LAND_COVER_NOT_ADDED" );
278       return false;
279     }
280   }
281
282   // Remove land cover from edited land cover map
283   if ( myOperationId == RemoveLandCoverId )
284   {
285     bool aLandCoverRemoved = false;
286     if ( !aFacesSelectedInViewer.IsEmpty() )
287     {
288       aLandCoverRemoved = aLandCoverMapObj->Remove( aFacesSelectedInViewer );
289       if ( !aLandCoverRemoved )
290       {
291         theErrorMsg = tr( "LAND_COVER_NOT_REMOVED" );
292         return false;
293       }
294     }
295   }
296
297   // Split land cover(s) inside edited land cover map
298   if ( myOperationId == SplitLandCoverId )
299   {
300     bool aLandCoverSplit = false;
301     if ( !aPolyline.IsNull() )
302       aLandCoverSplit = aLandCoverMapObj->Split( aPolyline );
303     else if ( !aFace.IsNull() )
304     {
305       // Get the complete boundary of the object face as the splitting polyline
306       QList<TopoDS_Shape> aBoundShapes;
307       QStringList aBoundNames;
308       aFace->GetBoundaries( aBoundShapes, aBoundNames );
309
310       for( int i=0, n=aBoundShapes.size(); i<n; i++ )
311       {
312         TopoDS_Shape aShape = aBoundShapes[i];
313         if( aShape.IsNull() )
314           continue;
315
316         bool aSplitResult = aLandCoverMapObj->Split( aShape );
317         aLandCoverSplit = ( i==0 ? aSplitResult : aLandCoverSplit && aSplitResult );
318       }
319     }
320     if ( !aLandCoverSplit )
321     {
322       theErrorMsg = tr( "LAND_COVER_NOT_SPLIT" );
323       return false;
324     }
325   }
326
327   // Merge land covers inside edited land cover map
328   if ( myOperationId == MergeLandCoverId )
329   {
330     bool aLandCoverMerged = false;
331     if ( !aFacesSelectedInViewer.IsEmpty() )
332     {
333       aLandCoverMerged = aLandCoverMapObj->Merge( aFacesSelectedInViewer, aSelectedStricklerType );
334       if ( !aLandCoverMerged )
335       {
336         theErrorMsg = tr( "LAND_COVER_NOT_MERGED" );
337         return false;
338       }
339     }
340   }
341
342   // Change Strickler type for land cover(s) inside edited land cover map
343   if ( myOperationId == ChangeLandCoverTypeId )
344   {
345     bool aLandCoverChangeType = false;
346     if ( !aFacesSelectedInViewer.IsEmpty() )
347     {
348       aLandCoverChangeType = aLandCoverMapObj->ChangeType( aFacesSelectedInViewer, aSelectedStricklerType );
349       if ( !aLandCoverChangeType )
350       {
351         theErrorMsg = tr( "LAND_COVER_TYPE_NOT_CHANGED" );
352         return false;
353       }
354     }
355   }
356     
357   // Update land cover map object and close preview
358   aLandCoverMapObj->Update();
359
360   closePreview();
361
362   // Publish the newly created land cover map in the Object Browser
363   module()->setObjectVisible( HYDROGUI_Tool::GetActiveOCCViewId( module() ), aLandCoverMapObj, true );
364   if ( myOperationId == CreateLandCoverMapId )
365   {
366     QString anEntry = HYDROGUI_DataObject::dataObjectEntry( aLandCoverMapObj );
367     theBrowseObjectsEntries.append( anEntry );
368   }
369
370   // Update presentation of land cover object in the 3d viewer
371   module()->setIsToUpdate( aLandCoverMapObj );
372   module()->getOCCDisplayer()->SetToUpdateColorScale();
373
374   theUpdateFlags = UF_Model | UF_OCCViewer | UF_OCC_Forced | UF_VTKViewer;
375
376   if ( myOperationId == CreateLandCoverMapId )
377     module()->enableLCMActions();
378
379   if ( myOperationId == RemoveLandCoverId || myOperationId == MergeLandCoverId || myOperationId == ChangeLandCoverTypeId )
380     aPanel->updateSelectedLandCoversLabel( getNbSelected() );
381
382   return true;
383 }
384
385 void HYDROGUI_LandCoverMapOp::onLandCoverMapChanged( const QString& theName )
386 {
387   // If the edited land cover map was changed in the combo-box, update myEditedObject
388   if ( myOperationId != CreateLandCoverMapId )
389   {
390     myEditedObject = Handle(HYDROData_LandCoverMap)::DownCast( HYDROGUI_Tool::FindObjectByName( module(), theName ) );
391     if ( !myEditedObject.IsNull() )
392     {
393       // Show preview of the newly selected land cover map
394       closePreview();
395       onCreatePreview();
396     }
397   }
398 }
399
400 void HYDROGUI_LandCoverMapOp::onPolylineFaceChanged()
401 {
402   HYDROGUI_LandCoverMapDlg* aPanel = ::qobject_cast<HYDROGUI_LandCoverMapDlg*>( inputPanel() );
403   if ( !aPanel )
404     return;
405
406   LightApp_DataOwner* aPolylineFaceDataOwner = NULL;
407   Handle(HYDROData_Entity) aPolylineFace = aPanel->getPolylineFace();
408   if ( !aPolylineFace.IsNull() )
409   {
410     // Select chosen polyline/face in the Object Browser, if it is not selected yet
411     // (i.e. object was chosen not in the Object Browser or 3d Viewer, but in combo-box)
412     aPolylineFaceDataOwner = new LightApp_DataOwner( HYDROGUI_DataObject::dataObjectEntry( aPolylineFace ) );  
413     LightApp_SelectionMgr* aSelectionMgr = module()->getApp()->selectionMgr();
414     if ( aSelectionMgr )
415     {
416       bool bIsAlreadySelected = false;
417       SUIT_DataOwnerPtrList aSelectedOwners;
418       aSelectionMgr->selected( aSelectedOwners );
419       foreach( SUIT_DataOwner* aSUITOwner, aSelectedOwners )
420       {
421         if ( LightApp_DataOwner* anOwner = dynamic_cast<LightApp_DataOwner*>( aSUITOwner ) )
422         {
423           if ( anOwner->entry() == aPolylineFaceDataOwner->entry() )
424           {
425             bIsAlreadySelected = true;
426             break;
427           }
428         }
429       }
430       if ( !bIsAlreadySelected )
431       {
432         SUIT_DataOwnerPtrList aList( true );
433         aList.append( SUIT_DataOwnerPtr( aPolylineFaceDataOwner ) );
434         aSelectionMgr->setSelected( aList );
435       }
436     }
437
438     // Show Preview of selected polyline/face
439     Handle(HYDROData_PolylineXY) aPolyline = Handle(HYDROData_PolylineXY)::DownCast( aPolylineFace );
440     Handle(HYDROData_Object) aFace = Handle(HYDROData_Object)::DownCast( aPolylineFace );
441     if ( !aPolyline.IsNull() || !aFace.IsNull() )
442     {
443       TopoDS_Shape aTopoDSShape;
444       if ( !aPolyline.IsNull() )
445         aTopoDSShape = aPolyline->GetShape();
446       else
447         aTopoDSShape = aFace->GetTopShape();
448
449       OCCViewer_ViewManager* aViewManager = ::qobject_cast<OCCViewer_ViewManager*>( 
450         module()->getApp()->getViewManager( OCCViewer_Viewer::Type(), true ) );
451       if ( aViewManager )
452       {
453         if ( OCCViewer_Viewer* aViewer = aViewManager->getOCCViewer() )
454         {
455           if ( myPolylineFacePreviewPrs )
456           {
457             delete myPolylineFacePreviewPrs;
458             myPolylineFacePreviewPrs = 0;
459           }
460
461           int aViewerId = (size_t)aViewer;
462           if ( !module()->isObjectVisible( aViewerId, aPolylineFace ) )
463           {
464             Handle(AIS_InteractiveContext) aCtx = aViewer->getAISContext();
465             if ( !aCtx.IsNull() )
466             {
467               myPolylineFacePreviewPrs = new HYDROGUI_Shape( aCtx, NULL, getPreviewZLayer() );
468               aCtx->ClearSelected(true);
469
470               myPolylineFacePreviewPrs->setBorderColor( Qt::white, false, false );
471               myPolylineFacePreviewPrs->setShape( aTopoDSShape, true, true, !aPolyline.IsNull() ? AIS_WireFrame : AIS_Shaded );
472
473               module()->update( UF_OCCViewer | UF_FitAll );
474             }       
475           }
476         }
477       }
478     }
479   }
480 }
481
482 void HYDROGUI_LandCoverMapOp::onCreatePreview()
483 {
484   HYDROGUI_LandCoverMapDlg* aPanel = ::qobject_cast<HYDROGUI_LandCoverMapDlg*>( inputPanel() );
485   if ( !aPanel )
486     return;
487
488   QApplication::setOverrideCursor( Qt::WaitCursor );  
489
490   LightApp_Application* anApp = module()->getApp();
491   if ( !getPreviewManager() )
492     setPreviewManager( ::qobject_cast<OCCViewer_ViewManager*>( 
493                        anApp->getViewManager( OCCViewer_Viewer::Type(), true ) ) );
494   OCCViewer_ViewManager* aViewManager = getPreviewManager();
495   if ( aViewManager && !myPreviewPrs )
496   {
497     if ( OCCViewer_Viewer* aViewer = aViewManager->getOCCViewer() )
498     {
499       Handle(AIS_InteractiveContext) aCtx = aViewer->getAISContext();
500       if ( !aCtx.IsNull() )
501       {
502         if ( myOperationId == RemoveLandCoverId || 
503              myOperationId == MergeLandCoverId ||
504              myOperationId == ChangeLandCoverTypeId )
505         {
506           disconnect(aViewManager, SIGNAL(mousePress(SUIT_ViewWindow*, QMouseEvent*)), 
507             aViewer, SLOT(onMousePress(SUIT_ViewWindow*, QMouseEvent*)));
508           disconnect(aViewManager, SIGNAL(mouseRelease(SUIT_ViewWindow*, QMouseEvent*)), 
509             aViewer, SLOT(onMouseRelease(SUIT_ViewWindow*, QMouseEvent*)));        
510
511           connect(aViewManager, SIGNAL(mousePress(SUIT_ViewWindow*, QMouseEvent*)), 
512               this, SLOT(onMousePress(SUIT_ViewWindow*, QMouseEvent*)));
513           connect(aViewManager, SIGNAL(mouseRelease(SUIT_ViewWindow*, QMouseEvent*)),
514             this, SLOT(onMouseRelease(SUIT_ViewWindow*, QMouseEvent*)));
515
516           LightApp_SelectionMgr* aSelectionMgr = module()->getApp()->selectionMgr();
517           if ( aSelectionMgr )
518           {
519             QList<SUIT_Selector*> aSelectorList;
520             aSelectionMgr->selectors( aViewManager->getType(), aSelectorList );
521             QList<SUIT_Selector*>::iterator anIter, anIterEnd = aSelectorList.end();
522             for( anIter = aSelectorList.begin(); anIter != anIterEnd; anIter++ )
523             {
524               HYDROGUI_OCCSelector* aHydroSelector = dynamic_cast<HYDROGUI_OCCSelector*>( *anIter );
525               if ( aHydroSelector )
526               {
527                 disconnect( aHydroSelector->viewer(), SIGNAL( deselection() ), aHydroSelector, SLOT( onDeselection() ) );
528                 connect( this, SIGNAL( deselection() ), aHydroSelector, SLOT( onDeselection() ) );
529               }
530             }
531           }
532         
533           connect( this, SIGNAL( selectionChanged() ), this, SLOT( onViewerSelectionChanged() ) );
534         }
535         else
536           connect( aViewer, SIGNAL( selectionChanged() ), this, SLOT( onViewerSelectionChanged() ) );
537         myPreviewPrs = new HYDROGUI_ShapeLandCoverMap( module()->getOCCDisplayer(), aCtx, myEditedObject, getPreviewZLayer()/*, theIsScalarMapMode*/ );
538       }
539     }
540   }
541
542   if ( aViewManager && myPreviewPrs && !myEditedObject.IsNull() )
543   {
544     if ( myOperationId == RemoveLandCoverId || 
545          myOperationId == MergeLandCoverId ||
546          myOperationId == ChangeLandCoverTypeId )
547       myPreviewPrs->setSelectionMode( AIS_Shape::SelectionMode( TopAbs_FACE ) ); 
548     myPreviewPrs->update( false, false );
549     
550     if ( myOperationId == ChangeLandCoverTypeId )
551       selectLandCoverInPreview();
552   }
553   
554   module()->update( UF_OCCViewer | UF_FitAll );
555
556   QApplication::restoreOverrideCursor();  
557 }
558
559 void HYDROGUI_LandCoverMapOp::onViewerSelectionChanged()
560 {
561   HYDROGUI_LandCoverMapDlg* aPanel = ::qobject_cast<HYDROGUI_LandCoverMapDlg*>( inputPanel() );
562   if ( !aPanel )
563     return;
564
565   int aNbSelected = getNbSelected();
566
567   if ( myOperationId == RemoveLandCoverId || myOperationId == ChangeLandCoverTypeId )
568     // Enable Apply, Apply and Close buttons only if at least one face (land cover) is selected in the 3d viewer
569     aPanel->setApplyEnabled( aNbSelected > 0 );
570   else if ( myOperationId == MergeLandCoverId )
571     // Enable Apply, Apply and Close buttons only if at least two faces (land covers) are selected in the 3d viewer
572     aPanel->setApplyEnabled( aNbSelected > 1 );
573
574   if ( myOperationId == MergeLandCoverId || myOperationId == ChangeLandCoverTypeId )
575   {
576     if ( aNbSelected == 1 && !myEditedObject.IsNull() )
577     {
578       TopTools_ListOfShape aFacesSelectedInViewer;
579       getSelectedShapes( aFacesSelectedInViewer );
580       if ( aFacesSelectedInViewer.Extent() == 1 )
581       {
582         QString aType = myEditedObject->StricklerType( TopoDS::Face( aFacesSelectedInViewer.First() ) );
583         if ( !aType.isEmpty() )
584           aPanel->setSelectedStricklerTypeName( aType );
585       }
586     }
587   }
588
589   if ( myOperationId == RemoveLandCoverId || myOperationId == MergeLandCoverId || myOperationId == ChangeLandCoverTypeId )
590     aPanel->updateSelectedLandCoversLabel( aNbSelected );
591 }
592
593 void HYDROGUI_LandCoverMapOp::onMousePress(SUIT_ViewWindow* theWindow, QMouseEvent* theEvent)
594 {
595   myStartPnt.setX(theEvent->x()); myStartPnt.setY(theEvent->y());
596 }
597
598 void HYDROGUI_LandCoverMapOp::onMouseRelease(SUIT_ViewWindow* theWindow, QMouseEvent* theEvent)
599 {
600   if (theEvent->button() != Qt::LeftButton) return;
601   if (!theWindow->inherits("OCCViewer_ViewWindow")) return;
602
603   OCCViewer_ViewWindow* aView = (OCCViewer_ViewWindow*) theWindow;
604   if (!aView )
605     return;
606
607   OCCViewer_ViewManager* aViewManager = getPreviewManager();
608   if ( !aViewManager )
609     return;
610   
611   OCCViewer_Viewer* aViewer = aViewManager->getOCCViewer();
612   if ( !aViewer )
613     return;
614
615   Handle(AIS_InteractiveContext) aCtx = getInteractiveContext();
616   if ( aCtx.IsNull() )
617     return;
618
619   myEndPnt.setX(theEvent->x()); myEndPnt.setY(theEvent->y());
620
621   if (myStartPnt == myEndPnt)
622   {
623     if ( !aViewer->isPreselectionEnabled() ) {
624       Handle(V3d_View) aView3d = aView->getViewPort()->getView();
625       if ( !aView3d.IsNull() ) {
626         aCtx->MoveTo(myEndPnt.x(), myEndPnt.y(), aView3d, true);
627       }
628     }
629
630     Handle(StdSelect_ViewerSelector3d) aMainSelector = aCtx->MainSelector();
631     if ( aMainSelector.IsNull() )
632       return;
633     const Standard_Integer aDetectedNb = aMainSelector->NbPicked();
634     if ( aDetectedNb == 0 )
635     {
636       aCtx->ClearSelected( false );
637       emit deselection();
638     }
639
640     for (Standard_Integer aDetIter = 1; aDetIter <= aDetectedNb; ++aDetIter)
641     {
642       Handle(SelectMgr_EntityOwner) anOwner = aMainSelector->Picked (aDetIter);
643       aCtx->AddOrRemoveSelected( anOwner, Standard_False );
644     }
645   }
646   else
647   {
648     aCtx->ShiftSelect(myStartPnt.x(), myStartPnt.y(),
649                       myEndPnt.x(), myEndPnt.y(),
650                       aView->getViewPort()->getView(), Standard_False );
651   }
652
653   aCtx->UpdateCurrentViewer();
654   emit selectionChanged();  
655 }
656
657 void HYDROGUI_LandCoverMapOp::closePreview()
658 {
659   if ( myPreviewPrs )
660   {
661     delete myPreviewPrs;
662     myPreviewPrs = 0;
663   }
664
665   if ( myPolylineFacePreviewPrs )
666   {
667     delete myPolylineFacePreviewPrs;
668     myPolylineFacePreviewPrs = 0;
669   }
670
671   HYDROGUI_LandCoverMapDlg* aPanel = ::qobject_cast<HYDROGUI_LandCoverMapDlg*>( inputPanel() );
672   if ( !aPanel )
673     return;
674
675   if ( myOperationId == RemoveLandCoverId || myOperationId == MergeLandCoverId || myOperationId == ChangeLandCoverTypeId )
676     aPanel->setApplyEnabled( false );
677
678   if ( myOperationId == RemoveLandCoverId || 
679        myOperationId == MergeLandCoverId ||
680        myOperationId == ChangeLandCoverTypeId )
681   {
682     OCCViewer_ViewManager* aViewManager = getPreviewManager();
683     if ( aViewManager )
684     {
685       if ( OCCViewer_Viewer* aViewer = aViewManager->getOCCViewer() )
686       {
687         disconnect(aViewManager, SIGNAL(mousePress(SUIT_ViewWindow*, QMouseEvent*)), 
688           this, SLOT(onMousePress(SUIT_ViewWindow*, QMouseEvent*)));
689         disconnect(aViewManager, SIGNAL(mouseRelease(SUIT_ViewWindow*, QMouseEvent*)),
690           this, SLOT(onMouseRelease(SUIT_ViewWindow*, QMouseEvent*)));
691         connect(aViewManager, SIGNAL(mousePress(SUIT_ViewWindow*, QMouseEvent*)), 
692           aViewer, SLOT(onMousePress(SUIT_ViewWindow*, QMouseEvent*)));
693         connect(aViewManager, SIGNAL(mouseRelease(SUIT_ViewWindow*, QMouseEvent*)), 
694           aViewer, SLOT(onMouseRelease(SUIT_ViewWindow*, QMouseEvent*)));  
695
696         LightApp_SelectionMgr* aSelectionMgr = module()->getApp()->selectionMgr();
697         if ( aSelectionMgr )
698         {
699           QList<SUIT_Selector*> aSelectorList;
700           aSelectionMgr->selectors( aViewManager->getType(), aSelectorList );
701           QList<SUIT_Selector*>::iterator anIter, anIterEnd = aSelectorList.end();
702           for( anIter = aSelectorList.begin(); anIter != anIterEnd; anIter++ )
703           {
704             HYDROGUI_OCCSelector* aHydroSelector = dynamic_cast<HYDROGUI_OCCSelector*>( *anIter );
705             if ( aHydroSelector )
706             {
707               disconnect( this, SIGNAL( deselection() ), aHydroSelector, SLOT( onDeselection() ) );
708               connect( aHydroSelector->viewer(), SIGNAL( deselection() ), aHydroSelector, SLOT( onDeselection() ) );            
709             }
710           }
711         }
712       }
713     }
714   }
715 }
716
717 Handle(AIS_InteractiveContext) HYDROGUI_LandCoverMapOp::getInteractiveContext()
718 {
719   OCCViewer_ViewManager* aViewManager = getPreviewManager();
720   Handle(AIS_InteractiveContext) aCtx = NULL;
721   if ( aViewManager ) {
722     if ( OCCViewer_Viewer* aViewer = aViewManager->getOCCViewer() ) {
723       aCtx = aViewer->getAISContext();
724     }
725   }
726   return aCtx;
727 }
728
729 void HYDROGUI_LandCoverMapOp::getSelectedShapes( TopTools_ListOfShape& theSelectedShapes )
730 {
731   Handle(AIS_InteractiveContext) aCtx = getInteractiveContext();
732   if ( !aCtx.IsNull() )
733   {
734     for ( aCtx->InitSelected(); aCtx->MoreSelected(); aCtx->NextSelected() )
735     {
736       TopoDS_Shape aSelectedShape = aCtx->SelectedShape();
737       if ( aSelectedShape.IsNull() )
738         continue;
739
740       theSelectedShapes.Append( aSelectedShape );
741     }
742   }
743 }
744
745 int HYDROGUI_LandCoverMapOp::getNbSelected()
746 {
747   int aNbSelected = 0;
748
749   Handle(AIS_InteractiveContext) aCtx = getInteractiveContext();
750   if ( !aCtx.IsNull() )
751   {
752     for ( aCtx->InitSelected(); aCtx->MoreSelected(); aCtx->NextSelected() )
753     {
754       TopoDS_Shape aSelectedShape = aCtx->SelectedShape();
755       if ( aSelectedShape.IsNull() )
756         continue;
757       aNbSelected++;
758     }
759   }
760
761   return aNbSelected;
762 }
763
764 void HYDROGUI_LandCoverMapOp::selectLandCoverInPreview()
765 {
766   if ( myPreviewPrs && !myEditedObject.IsNull() && myEditedObject->GetLCCount() == 1 )
767   {
768     OCCViewer_ViewManager* aViewManager = getPreviewManager();
769     if ( !aViewManager )
770       return;
771     
772     Handle(AIS_InteractiveContext) aCtx = getInteractiveContext();
773     if ( aCtx.IsNull() )
774       return;
775     
776     OCCViewer_ViewWindow* aViewWindow = (OCCViewer_ViewWindow*)aViewManager->getActiveView();
777     if ( !aViewWindow )
778       return;
779
780     OCCViewer_ViewPort3d* aViewPort = aViewWindow->getViewPort();
781     if ( !aViewPort )
782       return;
783
784     Handle(V3d_View) aView = aViewPort->getView();
785     if ( aView.IsNull() )
786       return;
787
788     aCtx->ShiftSelect( 0, 0, aViewPort->width(), aViewPort->height(), aView, Standard_False );
789     aCtx->UpdateCurrentViewer();
790     emit selectionChanged();
791   }
792 }