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