Salome HOME
refs #568: Land Cover: a draft of data model and implementation of dialog box and...
[modules/hydro.git] / src / HYDROGUI / HYDROGUI_Module.cxx
index c8da5e4d08c7e7451192408b1e43091dee9d5b36..3d5dc177b24e0ea104e9ad3e3db34593e223479e 100644 (file)
@@ -1,12 +1,8 @@
-// Copyright (C) 2007-2013  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
-//
+// Copyright (C) 2014-2015  EDF-R&D
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 // License as published by the Free Software Foundation; either
-// version 2.1 of the License.
+// version 2.1 of the License, or (at your option) any later version.
 //
 // This library is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
 #include "HYDROGUI_PolylineOp.h"
 #include "HYDROGUI_SetColorOp.h"
 #include "HYDROGUI_ImportGeomObjectOp.h"
+#include "HYDROGUI_ShowHideOp.h"
 
+#include <HYDROData_Tool.h>
 #include <HYDROData_Image.h>
+#include <HYDROData_Stream.h>
 #include <HYDROData_Profile.h>
 #include <HYDROData_Lambert93.h>
-#include <HYDROData_Tool.h>
+#include <HYDROData_Polyline3D.h>
 
 #include <HYDROData_OperationsFactory.h>
 
-#include <CurveCreator_Utils.h>
+#include <CurveCreator_Utils.hxx>
 
 #include <GraphicsView_ViewFrame.h>
 #include <GraphicsView_ViewManager.h>
 #include <SALOME_Event.h>
 
 #include <SUIT_DataBrowser.h>
-#include <SUIT_Desktop.h>
-#include <SUIT_Study.h>
+#include <SUIT_DataObject.h>
 #include <SUIT_ViewManager.h>
 #include <SUIT_ResourceMgr.h>
+#include <SUIT_Desktop.h>
+#include <SUIT_Study.h>
+#include <SUIT_Session.h>
 
 #include <SVTK_ViewManager.h>
 #include <SVTK_ViewModel.h>
 #include <SVTK_ViewWindow.h>
 #include <SVTK_Selector.h>
-#include <vtkRenderWindowInteractor.h>
-#include <vtkRenderer.h>
-#include <vtkWorldPointPicker.h>
-#include <vtkCamera.h>
 
 #include <OCCViewer_ViewPort3d.h>
 
 #include <QMenu>
 #include <QMouseEvent>
 #include <QStatusBar>
-
-const double LOCAL_SELECTION_TOLERANCE = 0.0001;
+#include <QCursor>
 
 static int ViewManagerId = 0;
 
@@ -190,7 +186,6 @@ bool HYDROGUI_Module::activateModule( SUIT_Study* theStudy )
   foreach ( const int anId, anObsoleteIds ) {
     myViewManagerMap.remove( anId );
     myObjectStateMap.remove( anId );
-    myObjectDisplayOrderMap.remove( anId );
     myShapesMap.remove( anId );
     myVTKPrsMap.remove( anId );
   }
@@ -238,6 +233,10 @@ bool HYDROGUI_Module::activateModule( SUIT_Study* theStudy )
     }
   }
 
+//  SUIT_DataBrowser* ob = getApp()->objectBrowser();
+//  SUIT_AbstractModel* treeModel = dynamic_cast<SUIT_AbstractModel*>( ob->model() );
+//  treeModel->setAppropriate( SUIT_DataObject::VisibilityId, Qtx::Toggled );
+
   return aRes;
 }
 
@@ -264,6 +263,12 @@ bool HYDROGUI_Module::deactivateModule( SUIT_Study* theStudy )
   myVTKPrsMap.clear();
   */
 
+  // clear the status bar
+  SUIT_Desktop* aDesktop = getApp()->desktop();
+  if ( aDesktop && aDesktop->statusBar() ) {
+    aDesktop->statusBar()->clearMessage();
+  }
+
   // clear the data model's list of copying objects
   HYDROGUI_DataModel::changeCopyingObjects( HYDROData_SequenceOfObjects() );
 
@@ -274,6 +279,7 @@ bool HYDROGUI_Module::deactivateModule( SUIT_Study* theStudy )
 
   HYDROGUI_Tool::setOCCActionShown( this, OCCViewer_ViewWindow::MaximizedId, true );
 
+  myActiveOperationMap.clear();
   return LightApp_Module::deactivateModule( theStudy );
 }
 
@@ -330,12 +336,27 @@ void HYDROGUI_Module::contextMenuPopup( const QString& theClient,
   bool anIsRegion = false;
   bool anIsZone = false;
   bool anIsObstacle = false;
+  bool anIsStricklerTable = false;
+  bool anIsLandCover = false;
   bool anIsStream = false;
   bool anIsChannel = false;
   bool anIsDigue = false;
   bool anIsDummyObject3D = false;
   bool anIsGroup = false;
   bool anIsObjectCanBeColored = false;
+  bool isRoot = false;
+  bool isStreamHasBottom = false;
+
+  SUIT_SelectionMgr* aSelectionMgr = getApp()->selectionMgr();
+  SUIT_DataOwnerPtrList anOwners;
+  aSelectionMgr->selected( anOwners );
+  if( anIsObjectBrowser && anOwners.size()==1 )
+  {
+    QString anEntry = anOwners[0]->keyString();
+    LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>( getApp()->activeStudy() );
+    if( aStudy )
+      isRoot = aStudy->isComponent( anEntry );
+  }
 
   // Check the selected GEOM objects (take into account the Object Browser only)
   if ( anIsObjectBrowser ) {
@@ -435,8 +456,18 @@ void HYDROGUI_Module::contextMenuPopup( const QString& theClient,
         anIsBathymetry = true;
       else if( anObjectKind == KIND_OBSTACLE )
         anIsObstacle = true;
+      else if( anObjectKind == KIND_STRICKLER_TABLE )
+        anIsStricklerTable = true;
+      else if( anObjectKind == KIND_LAND_COVER )
+        anIsLandCover = true;
       else if( anObjectKind == KIND_STREAM )
+      {
         anIsStream = true;
+        Handle(HYDROData_Stream) aStream = 
+          Handle(HYDROData_Stream)::DownCast( anObject );
+        if ( !aStream.IsNull() )
+            isStreamHasBottom = !aStream->GetBottomPolyline().IsNull();
+      }
       else if( anObjectKind == KIND_CHANNEL )
         anIsChannel = true;
       else if( anObjectKind == KIND_DIGUE )
@@ -482,6 +513,12 @@ void HYDROGUI_Module::contextMenuPopup( const QString& theClient,
           theMenu->addAction( action( CreateBoxId ) );
           theMenu->addAction( action( CreateCylinderId ) );
           break;
+        case KIND_STRICKLER_TABLE:
+          theMenu->addAction( action( ImportStricklerTableFromFileId ) );          
+          break;
+        case KIND_LAND_COVER:
+          theMenu->addAction( action( CreateLandCoverId ) );          
+          break;
         case KIND_CALCULATION:
           theMenu->addAction( action( CreateCalculationId ) );
           break;
@@ -585,6 +622,12 @@ void HYDROGUI_Module::contextMenuPopup( const QString& theClient,
       else if( anIsStream )
       {
         theMenu->addAction( action( EditStreamId ) );
+        if ( action( RiverBottomContextId ) )
+        {
+            theMenu->addAction( action( RiverBottomContextId ) );
+            action( RiverBottomContextId )->setEnabled( !isStreamHasBottom );
+        }
+        theMenu->addAction( action( ProfileInterpolateId ) );
         theMenu->addSeparator();
       }
       else if( anIsChannel )
@@ -597,6 +640,23 @@ void HYDROGUI_Module::contextMenuPopup( const QString& theClient,
         theMenu->addAction( action( EditDigueId ) );
         theMenu->addSeparator();
       }
+      else if( anIsObstacle )
+      {
+        theMenu->addAction( action( TranslateObstacleId ) );
+        theMenu->addSeparator();
+      }
+      else if( anIsStricklerTable )
+      {
+        theMenu->addAction( action( EditStricklerTableId ) );
+        theMenu->addAction( action( ExportStricklerTableFromFileId ) );
+        theMenu->addAction( action( DuplicateStricklerTableId ) );
+        theMenu->addSeparator();
+      }
+      else if( anIsLandCover )
+      {
+        theMenu->addAction( action( EditLandCoverId ) );
+        theMenu->addSeparator();
+      }      
       else if( anIsVisualState && anIsObjectBrowser )
       {
         theMenu->addAction( action( SaveVisualStateId ) );
@@ -610,19 +670,22 @@ void HYDROGUI_Module::contextMenuPopup( const QString& theClient,
         theMenu->addAction( action( SetColorId ) );
         theMenu->addSeparator();
       }
-
-      // Add copy action
-      if( aModel->canCopy() ) {
-        theMenu->addAction( action( CopyId ) );
-        theMenu->addSeparator();
-      }
     } else if ( anAllAreProfiles ) {
       theMenu->addAction( action( SelectedGeoreferencementId ) );
       theMenu->addSeparator();
     }
 
+    // Add copy action
+    QAction* aCopyAction = action( CopyId );
+    if( aCopyAction && aCopyAction->isEnabled() ) {
+      theMenu->addAction( action( CopyId ) );
+      theMenu->addSeparator();
+    }
+
+    // Add delete action
     if( !anIsDummyObject3D )
       theMenu->addAction( action( DeleteId ) );
+
     theMenu->addSeparator();
 
     if( anIsImage || anIsPolyline || anIsPolyline3D || 
@@ -646,6 +709,10 @@ void HYDROGUI_Module::contextMenuPopup( const QString& theClient,
     HYDROGUI_PolylineOp* aPolylineOp = dynamic_cast<HYDROGUI_PolylineOp*>( anOp );
     if ( aPolylineOp && aPolylineOp->deleteEnabled() )
       theMenu->addAction( action( DeleteId ) );
+
+    theMenu->addSeparator();
+    theMenu->addAction( action( SetZLevelId ) );
+    theMenu->addSeparator();
   }
 
   if( anIsObjectBrowser || anIsGraphicsView || anIsOCCView || anIsVTKView )
@@ -654,11 +721,80 @@ void HYDROGUI_Module::contextMenuPopup( const QString& theClient,
     theMenu->addAction( action( HideAllId ) );
     theMenu->addSeparator();
   }
+  
+  if ( anIsOCCView || anIsVTKView )
+  {
+    theMenu->addSeparator();
+    theMenu->addAction( action( CopyViewerPositionId ) );
+  }
+
+  if( isRoot )
+    theMenu->addAction( action( EditLocalCSId ) );
+
+  if( anIsObjectBrowser && anOwners.size()==1 )
+  {
+    if( aSeq.Size() > 0 )
+    {
+      Handle( HYDROData_Object ) anObject = Handle( HYDROData_Object )::DownCast( aSeq.First() );
+      if( !anObject.IsNull() )
+      {
+        theMenu->addSeparator();
+        theMenu->addAction( action( SubmersibleId ) );
+        action( SubmersibleId )->setCheckable( true );
+        action( SubmersibleId )->setChecked( anObject->IsSubmersible() );
+      }
+    }
+  }
+}
+
+void HYDROGUI_Module::createPreferences()
+{
+  int genTab = addPreference( tr( "PREF_TAB_GENERAL" ) );
+  int CursorGroup = addPreference( tr( "PREF_GROUP_CURSOR" ), genTab );
+
+  int typeOfCursor = addPreference( tr( "PREF_TYPE_OF_CURSOR" ), CursorGroup,
+                                    LightApp_Preferences::Selector, "preferences", "type_of_cursor" );
+
+  // Set property cursor type
+  QList<QVariant> aCursorTypeIndicesList;
+  QList<QVariant> aCursorTypeIconsList;
+
+  SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
+  for ( int i = CT_ArrowCursor; i < CT_User; i++ ) {
+    QString icoFile = QString( "ICON_CURSOR_%1" ).arg( i+1 );
+    QPixmap pixmap = resMgr->loadPixmap( "HYDRO", tr( qPrintable( icoFile ) ) );
+    aCursorTypeIndicesList << i;
+    aCursorTypeIconsList << pixmap;
+  }
+
+  setPreferenceProperty( typeOfCursor, "indexes", aCursorTypeIndicesList );
+  setPreferenceProperty( typeOfCursor, "icons",   aCursorTypeIconsList );
+
+  int viewerGroup = addPreference( tr( "PREF_GROUP_VIEWER" ), genTab );
+  addPreference( tr( "PREF_VIEWER_AUTO_FITALL" ), viewerGroup,
+                 LightApp_Preferences::Bool, "HYDRO", "auto_fit_all" );
+
+  int StricklerTableGroup = addPreference( tr( "PREF_GROUP_STRICKLER_TABLE" ), genTab );
+  int defaultStricklerCoef = addPreference( tr( "PREF_DEFAULT_STRICKLER_COEFFICIENT" ), StricklerTableGroup,
+                                            LightApp_Preferences::DblSpin, "HYDRO", "default_strickler_coefficient" );
+  setPreferenceProperty( defaultStricklerCoef, "precision", 2 );
+  setPreferenceProperty( defaultStricklerCoef, "min", 0.00 );
+  setPreferenceProperty( defaultStricklerCoef, "max", 1000000.00 );
+  setPreferenceProperty( defaultStricklerCoef, "step", 0.01 );
+}
+
+QCursor HYDROGUI_Module::getPrefEditCursor() const
+{
+  int aCursorType = SUIT_Session::session()->resourceMgr()->integerValue("preferences", "type_of_cursor", (int)CT_CrossCursor );
+  if ( aCursorType >= Qt::BlankCursor)
+    aCursorType++;
+  QCursor aCursor = QCursor( Qt::CursorShape(aCursorType) );
+  return aCursor;
 }
 
 void HYDROGUI_Module::update( const int flags )
 {
-  if( !isUpdateEnabled() )
+  if ( !isUpdateEnabled() )
     return;
 
   QApplication::setOverrideCursor( Qt::WaitCursor );
@@ -671,6 +807,12 @@ void HYDROGUI_Module::update( const int flags )
   QStringList aSelectedEntries = storeSelection();
 
   bool aDoFitAll = flags & UF_FitAll;
+  if ( aDoFitAll )
+  {
+    SUIT_ResourceMgr* aResMgr = getApp()->resourceMgr();
+    aDoFitAll = aResMgr->booleanValue( "HYDRO", "auto_fit_all", false );
+  }
+
   if( ( flags & UF_Viewer ) )
     updateViewer( getDisplayer(), flags & UF_GV_Init, flags & UF_GV_Forced, aDoFitAll ); 
 
@@ -841,6 +983,17 @@ bool HYDROGUI_Module::isObjectVisible( const int theViewId,
   if( theObject.IsNull() )
     return false;
 
+  if( theViewId < 0 )
+  {
+    //search in all
+    foreach( int aViewId, myObjectStateMap.keys() )
+    {
+      if( isObjectVisible( aViewId, theObject ) )
+        return true;
+    }
+    return false;
+  }
+
   ViewId2Entry2ObjectStateMap::const_iterator anIter1 = myObjectStateMap.find( theViewId );
   if( anIter1 != myObjectStateMap.end() )
   {
@@ -869,11 +1022,14 @@ void HYDROGUI_Module::setObjectVisible( const int theViewId,
     ObjectState& anObjectState = aEntry2ObjectStateMap[ anEntry ];
     anObjectState.Visibility = theState;
 
-    // Remember the display order ( needed for Z layers assignment only )
-    QStringList& anObjectEntries = myObjectDisplayOrderMap[ theViewId ];
-    anObjectEntries.removeAll( anEntry );
-    if ( theState ) {
-      anObjectEntries.append( anEntry );
+    HYDROGUI_DataObject* hydroObject = getDataModel()->getDataObject( theObject );
+    if ( hydroObject )
+    {
+        SUIT_AbstractModel* treeModel = dynamic_cast<SUIT_AbstractModel*>( getApp()->objectBrowser()->model() );
+        QString id = hydroObject->text( hydroObject->customData( Qtx::IdType ).toInt() );
+        Qtx::VisibilityState visState = treeModel->visibilityState( id );
+        if ( visState != Qtx::UnpresentableState )
+            treeModel->setVisibilityState( id, theState ? Qtx::ShownState : Qtx::HiddenState );
     }
   }
 }
@@ -915,6 +1071,23 @@ void HYDROGUI_Module::setIsToUpdate( const Handle(HYDROData_Entity)& theObject,
 }
 
 /////////////////// OCC SHAPES PROCESSING
+QList<HYDROGUI_Shape*> HYDROGUI_Module::getObjectShapes( const int  theViewId,
+                                                         ObjectKind theKind ) const
+{
+  QList<HYDROGUI_Shape*> aResult;
+
+  if ( myShapesMap.contains( theViewId ) )
+  {
+    const ListOfShapes& aViewShapes = myShapesMap.value( theViewId );
+    foreach ( HYDROGUI_Shape* aShape, aViewShapes )
+    {
+      if( aShape && aShape->getObject()->GetKind()==theKind )
+        aResult.append( aShape );
+    }
+  }
+  return aResult;
+}
+
 HYDROGUI_Shape* HYDROGUI_Module::getObjectShape( const int                       theViewId,
                                                  const Handle(HYDROData_Entity)& theObject ) const
 {
@@ -1047,6 +1220,35 @@ void HYDROGUI_Module::setObjectVTKPrs( const int                       theViewId
   aViewShapes.append( theShape );
 }
 
+void HYDROGUI_Module::removeObjectVTKPrs( const int      theViewId,
+                                          const QString& theEntry )
+{
+  if ( !myVTKPrsMap.contains( theViewId ) )
+    return;
+
+  ListOfVTKPrs& aViewShapes = myVTKPrsMap[ theViewId ];
+  Handle(HYDROData_Entity) anObject;
+  QString anEntryRef;
+  for ( int i = 0; i < aViewShapes.length(); )
+  {
+    HYDROGUI_VTKPrs* aShape = aViewShapes.at( i );
+    anObject = aShape->getObject();
+    anEntryRef = HYDROGUI_DataObject::dataObjectEntry( anObject );
+    if ( aShape && (!anObject.IsNull()) && ( anEntryRef == theEntry ) )
+    {
+      delete aShape;
+      aViewShapes.removeAt( i );
+      continue;
+    }
+
+    ++i;
+  }
+
+  // Invalidate global Z range
+  double anInvalidRange[2] = { HYDROGUI_VTKPrs::InvalidZValue(), HYDROGUI_VTKPrs::InvalidZValue() };
+  getVTKDisplayer()->SetZRange( theViewId, anInvalidRange );
+}
+
 void HYDROGUI_Module::removeObjectVTKPrs( const int                       theViewId,
                                           const Handle(HYDROData_Entity)& theObject )
 {
@@ -1448,96 +1650,96 @@ void HYDROGUI_Module::restoreSelection( const QStringList& theEntryList )
   }
 }
 
-void HYDROGUI_Module::onMouseMove( SUIT_ViewWindow* theViewWindow, QMouseEvent* theEvent )
+void HYDROGUI_Module::onMouseMove( SUIT_ViewWindow* theViewWindow, QMouseEvent* )
 {
-  OCCViewer_ViewWindow* anOCCViewWindow = 
-    dynamic_cast<OCCViewer_ViewWindow*>(theViewWindow);
+  double X, Y, Z;
   bool doShow = false;
-  gp_Pnt aPnt;
-  if ( anOCCViewWindow ) {
-    // Get the selected point coordinates
-    OCCViewer_ViewPort3d* aViewPort = anOCCViewWindow->getViewPort();
-    if ( !aViewPort ) {
-      return;
-    }
+  HYDROGUI_Displayer* aDisplayer = getDisplayer();
+  if ( aDisplayer )
+    aDisplayer->SaveCursorViewPosition( theViewWindow );
+    doShow = aDisplayer->GetCursorViewCoordinates( theViewWindow, X, Y, Z );
 
-    aPnt = CurveCreator_Utils::ConvertClickToPoint( theEvent->x(), theEvent->y(), 
-                                                           aViewPort->getView() );
-    doShow = true;
-  } 
-  else
-  {
-    SVTK_ViewWindow* aViewWindow = 
-      dynamic_cast<SVTK_ViewWindow*>(theViewWindow);
-    if ( aViewWindow ) {
-      vtkRenderer* aRen = aViewWindow->getRenderer();
-      if ( aRen )
-      {
-        vtkCamera* aCamera = aRen->GetActiveCamera();
-        double* aNormal = aCamera->GetViewPlaneNormal();
-        int event_x, event_y;
-        vtkRenderWindowInteractor* anInteractor = aViewWindow->getInteractor();
-        if ( anInteractor )
-        {
-          anInteractor->GetLastEventPosition(event_x, event_y);
-          // Use a WorldPicker to get current coords
-          myPicker->Pick( event_x, event_y, 0, aRen );
-          double* aCoords = myPicker->GetPickPosition();
-          /////////////////////// Use the same algorithm as for OCC
-          double X, Y, Z;
-          double aXp, aYp, aZp;
-          double Vx, Vy, Vz;
-          X = aCoords[0];
-          Y = aCoords[1];
-          Z = aCoords[2];
-          Vx = aNormal[0];
-          Vy = aNormal[1];
-          Vz = aNormal[2];
-          Standard_Real aPrec = LOCAL_SELECTION_TOLERANCE;
-          if ( fabs( Vz ) > aPrec ) {
-            double aT = -Z/Vz;
-            aXp = X + aT*Vx;
-            aYp = Y + aT*Vy;
-            aZp = Z + aT*Vz;
-          }
-          else { // Vz = 0 - the eyed plane is orthogonal to Z plane - XOZ, or YOZ
-            aXp = aYp = aZp = 0;
-            if ( fabs( Vy ) < aPrec ) // Vy = 0 - the YOZ plane
-              aYp = Y;
-            else if ( fabs( Vx ) < aPrec ) // Vx = 0 - the XOZ plane
-              aXp = X;
-          }
-          /////////////////////////
-          doShow = true;
-          aPnt.SetX( aXp );
-          aPnt.SetY( aYp );
-        }
-      }
-    } 
-  }
   if ( doShow )
   {
     // Show the coordinates in the status bar
     SUIT_Desktop* aDesktop = getApp()->desktop();
-    if ( aDesktop && aDesktop->statusBar() ) {
-      QString aX = HYDROGUI_Tool::GetCoordinateString( aPnt.X() );
-      QString anY = HYDROGUI_Tool::GetCoordinateString( aPnt.Y() );
-      aDesktop->statusBar()->showMessage( tr("COORDINATES_INFO").arg( aX ).arg( anY ) );
+    if ( aDesktop && aDesktop->statusBar() )
+    {
+      gp_Pnt aWPnt( X, Y, Z );
+      int aStudyId = application()->activeStudy()->id();
+      HYDROData_Document::Document( aStudyId )->Transform( aWPnt, false );
+      double WX = aWPnt.X(), WY = aWPnt.Y();
+
+      QString aXStr = HYDROGUI_Tool::GetCoordinateString( X, true );
+      QString anYStr = HYDROGUI_Tool::GetCoordinateString( Y, true );
+      QString aWXStr = HYDROGUI_Tool::GetCoordinateString( WX, true );
+      QString aWYStr = HYDROGUI_Tool::GetCoordinateString( WY, true );
+      QString aMsg = tr( "COORDINATES_INFO" );
+      aMsg = aMsg.arg( aXStr ).arg( anYStr ).arg( aWXStr ).arg( aWYStr );
+      aDesktop->statusBar()->showMessage( aMsg );
     }
   }
 }
 
 /**
- * Get the object display order. Needed for Z layers assignment only.
+ * Returns stack of active operations;
  */
-int HYDROGUI_Module::getObjectDisplayOrder( 
-  const int theViewId, const Handle(HYDROData_Entity)& theObject) const
+QStack<HYDROGUI_Operation*>& HYDROGUI_Module::getActiveOperations()
 {
-  if( theObject.IsNull() )
-    return -1;
+  return myActiveOperationMap;
+}
+
+/**
+ * Returns the module active operation. If the active operation is show/hide,
+ * the method returns the previous operation if it is.
+ */
+HYDROGUI_Operation* HYDROGUI_Module::activeOperation()
+{
+  HYDROGUI_Operation* anOp = !myActiveOperationMap.empty() ? myActiveOperationMap.top() : 0;
+
+  if ( dynamic_cast<HYDROGUI_ShowHideOp*>( anOp ) )
+  {
+    QVectorIterator<HYDROGUI_Operation*> aVIt( myActiveOperationMap );
+    aVIt.toBack();
+    aVIt.previous(); // skip the top show/hide operation
+    anOp = aVIt.hasPrevious() ? aVIt.previous() : 0;
+  }
+
+  return anOp;
+}
+
+/*!
+ * \brief Virtual public slot
+ *
+ * This method is called after the object inserted into data view to update their visibility state
+ * This is default implementation
+ */
+void HYDROGUI_Module::onObjectClicked( SUIT_DataObject* theObject, int theColumn )
+{
+  if ( !isActiveModule() )
+      return;
+
+  HYDROGUI_DataObject* hydroObject = dynamic_cast<HYDROGUI_DataObject*>( theObject );
 
-  QString anEntry = HYDROGUI_DataObject::dataObjectEntry( theObject );
-  QStringList anObjectEntries = myObjectDisplayOrderMap.value( theViewId );
+  // change visibility of object
+  if ( !hydroObject || theColumn != SUIT_DataObject::VisibilityId )
+      return;
+
+  SUIT_AbstractModel* treeModel = dynamic_cast<SUIT_AbstractModel*>( getApp()->objectBrowser()->model() );
+
+  QString id = theObject->text( theObject->customData( Qtx::IdType ).toInt() );
+  Qtx::VisibilityState visState = treeModel->visibilityState( id );
+  if ( visState == Qtx::UnpresentableState )
+      return;
+
+  visState = visState == Qtx::ShownState ? Qtx::HiddenState : Qtx::ShownState;
+  treeModel->setVisibilityState( id, visState );
 
-  return anObjectEntries.indexOf( anEntry );
-}
\ No newline at end of file
+  bool vis = visState == Qtx::ShownState;
+  if ( vis == isObjectVisible( HYDROGUI_Tool::GetActiveViewId( this ), hydroObject->modelObject() ) )
+      return;
+
+  setObjectVisible( HYDROGUI_Tool::GetActiveViewId( this ), hydroObject->modelObject(), vis );
+
+  update( UF_OCCViewer | ( visState == Qtx::ShownState ? UF_FitAll : 0 ) );
+}