Salome HOME
Merge changes for HYDRO project : hydro/imps_2017_salome_84 branch.
[modules/geom.git] / src / DependencyTree / DependencyTree_View.cxx
index e675dc410b9d4b8746ec6d4032f417020fe61cfe..2164574db669c68983c5514d8d984bb2765872aa 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2014-2016  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
@@ -28,7 +28,7 @@
 #include <SalomeApp_Study.h>
 #include <QtxActionToolMgr.h>
 #include <LightApp_SelectionMgr.h>
-#include <SALOME_ListIteratorOfListIO.hxx>
+#include <SALOME_ListIO.hxx>
 
 // GEOM includes
 #include <GEOMBase.h>
@@ -36,6 +36,7 @@
 // Qt includes
 #include <QApplication>
 #include <QWidgetAction>
+#include <QWheelEvent>
 
 DependencyTree_View::DependencyTree_View( QWidget* theParent )
 :GraphicsView_ViewPort( theParent ),
@@ -117,8 +118,16 @@ void DependencyTree_View::init( GraphicsView_ViewFrame* theViewFrame )
   connect( myDisplayDescendants, SIGNAL( toggled( bool ) ), this, SLOT( onHierarchyType() ) );
   connect( updateButton, SIGNAL( clicked() ), this, SLOT( onUpdateModel() ) );
 
-  SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
+  SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( SUIT_Session::session()->activeApplication() );
+  GeometryGUI* aGeomGUI = dynamic_cast<GeometryGUI*>( app->module( "Geometry" ) );
+  if ( aGeomGUI ) {
+    connect( aGeomGUI, SIGNAL( SignalDependencyTreeParamChanged( const QString&, const QString& ) ),
+             this, SLOT( onPreferenceChanged( const QString&, const QString& ) ) );
+    connect( aGeomGUI, SIGNAL( SignalDependencyTreeRenameObject( const QString& ) ),
+             this, SLOT( onRenameObject( const QString& ) ) );
+  }
 
+  SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
   setPrefBackgroundColor( resMgr->colorValue( "Geometry", "dependency_tree_background_color", QColor( 255, 255, 255 ) ) );
   setNodesMovable( resMgr->booleanValue( "Geometry", "dependency_tree_move_nodes", true ) );
   setHierarchyType( resMgr->integerValue( "Geometry", "dependency_tree_hierarchy_type", 0 ) );
@@ -143,11 +152,28 @@ void DependencyTree_View::mouseMoveEvent( QMouseEvent *event )
   QGraphicsView::mouseMoveEvent( event );
   ArrowsInfo::const_iterator i;
   for( i = myArrows.begin(); i != myArrows.end(); i++ ) {
-    DependencyTree_Arrow* arrow = myArrows[ i->first ];
-    arrow->update();
+    if( DependencyTree_Arrow* arrow = myArrows[ i->first ] )
+      arrow->update();
   }
 }
 
+//=================================================================================
+// function : wheelEvent()
+// purpose  : add zoom action when wheel is spinning
+//=================================================================================
+void DependencyTree_View::wheelEvent( QWheelEvent* event )
+{
+  int inc = 10; // zoom coefficient
+  double cx = width() / 2;
+  double cy = height() / 2;
+  if( event->delta() > 0 )
+    zoom( cx, cy, cx + inc, cy + inc );
+  else
+    zoom( cx, cy, cx - inc, cy - inc );
+
+  QGraphicsView::wheelEvent( event );
+}
+
 //=================================================================================
 // function : getViewName()
 // purpose  : return the name of current view
@@ -175,22 +201,6 @@ DependencyTree_Object* DependencyTree_View::getObjectByEntry( const std::string&
   return myTreeMap[ theEntry ];
 }
 
-//=================================================================================
-// function : updateObjectName()
-// purpose  : update object name, having edited it in Object Browser
-//=================================================================================
-bool DependencyTree_View::updateObjectName( const std::string& theEntry )
-{
-  bool res = false;
-  for( initSelected(); moreSelected(); nextSelected() ) {
-    if( DependencyTree_Object* aDepObject = dynamic_cast<DependencyTree_Object*>( selectedObject() ) ) {
-      aDepObject->updateName();
-      res = true;
-    }
-  }
-  return res;
-}
-
 //=================================================================================
 // function : setHierarchyType()
 // purpose  : set hierarchy type of dependency tree
@@ -267,6 +277,19 @@ void DependencyTree_View::setMainNodeColor( const QColor& theColor )
   }
 }
 
+//=================================================================================
+// function : setUnpublishNodeColor()
+// purpose  : set unpublished node color from preferences
+//=================================================================================
+void DependencyTree_View::setUnpublishNodeColor( const QColor& theColor )
+{
+  EntryObjectMap::const_iterator i;
+  for( i = myTreeMap.begin(); i != myTreeMap.end(); i++ ) {
+    DependencyTree_Object* object = myTreeMap[ i->first ];
+    object->setUnpublishObjectColor( theColor );
+  }
+}
+
 //=================================================================================
 // function : setSelectNodeColor()
 // purpose  : set selected node color from preferences
@@ -328,6 +351,18 @@ void DependencyTree_View::onRebuildModel()
   updateModel( true, false );
 }
 
+//=================================================================================
+// function : resizeEvent()
+// purpose  : reimplemented from QGraphicsView::resizeEvent()
+//=================================================================================
+void DependencyTree_View::resizeEvent(QResizeEvent *event)
+{
+  QPointF aCenter = mapToScene( event->oldSize().width()/2,
+                                event->oldSize().height()/2 );
+  QGraphicsView::resizeEvent( event );
+  centerOn( aCenter.x(),aCenter.y() );
+}
+
 //=================================================================================
 // function : onUpdateModel()
 // purpose  : slot for updating tree model for main objects in viewer
@@ -369,6 +404,66 @@ void DependencyTree_View::onHierarchyType()
   updateView();
 }
 
+//=================================================================================
+// function : onPreferencesChanged()
+// purpose  : slot for changing tree parameters from preferences
+//=================================================================================
+void DependencyTree_View::onPreferenceChanged( const QString& section, const QString& param )
+{
+  SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
+
+  if( param == QString("dependency_tree_hierarchy_type") ) {
+    int hierarchyType = resMgr->integerValue( section, param, 0);
+    setHierarchyType( hierarchyType );
+  }
+  else if(  param == QString("dependency_tree_move_nodes") ) {
+    bool isNodesMovable = resMgr->booleanValue( section, param, true);
+    setNodesMovable( isNodesMovable );
+  }
+  else if(  param == QString("dependency_tree_background_color") ) {
+    QColor c = resMgr->colorValue( section, param, QColor( 255, 255, 255 ) );
+    setPrefBackgroundColor( c );
+  }
+  else if(  param == QString("dependency_tree_node_color") ) {
+    QColor c = resMgr->colorValue( section, param, QColor( 62, 180, 238 ) );
+    setNodeColor( c );
+  }
+  else if(  param == QString("dependency_tree_main_node_color") ) {
+    QColor c = resMgr->colorValue( section, param, QColor( 238, 90, 125 ) );
+    setMainNodeColor( c );
+  }
+  else if(  param == QString("dependency_tree_unpublish_node_color") ) {
+    QColor c = resMgr->colorValue( section, param, QColor( 255, 255, 255 ) );
+    setUnpublishNodeColor( c );
+  }
+  else if(  param == QString("dependency_tree_select_node_color") ) {
+    QColor c = resMgr->colorValue( section, param, QColor( 237, 243, 58 ) );
+    setSelectNodeColor( c );
+  }
+  else if(  param == QString("dependency_tree_arrow_color") ) {
+    QColor c = resMgr->colorValue( section, param, QColor( 0, 0, 130 ) );
+    setArrowColor( c );
+  }
+  else if(  param == QString("dependency_tree_highlight_arrow_color") ) {
+    QColor c = resMgr->colorValue( section, param, QColor( 0, 0, 255 ) );
+    setHighlightArrowColor( c );
+  }
+  else if(  param == QString("dependency_tree_select_arrow_color") ) {
+    QColor c = resMgr->colorValue( section, param, QColor( 255, 0, 0 ) );
+    setSelectArrowColor( c );
+  }
+}
+
+//=================================================================================
+// function : onRenameObject()
+// purpose  : update object name, having edited it in Object Browser
+//=================================================================================
+void DependencyTree_View::onRenameObject( const QString& theEntry )
+{
+  if( DependencyTree_Object* object = getObjectByEntry( theEntry.toStdString() ) )
+    object->updateName();
+}
+
 //=================================================================================
 // function : parseTree()
 // purpose  : parse created model to initialize all nodes and arrows
@@ -380,10 +475,10 @@ void DependencyTree_View::parseTree()
     std::string objectEntry = i->first;
     addNode( objectEntry );
     parseTreeWard( i->second.first );
-    if( i->second.first.size() > myMaxUpwardLevelsNumber )
+    if((int) i->second.first.size() > myMaxUpwardLevelsNumber )
       myMaxUpwardLevelsNumber = i->second.first.size();
     parseTreeWard( i->second.second );
-    if( i->second.second.size() > myMaxDownwardLevelsNumber )
+    if((int) i->second.second.size() > myMaxDownwardLevelsNumber )
       myMaxDownwardLevelsNumber = i->second.second.size();
   }
 
@@ -394,7 +489,7 @@ void DependencyTree_View::parseTree()
       GEOMUtils::LevelInfo::const_iterator node;
       for( node = Levelup.begin(); node != Levelup.end(); node++ ) {
         DependencyTree_Object* object = myTreeMap[ node->first ];
-        addArrow( Main_object, object );
+        addArrow( object, Main_object );
       }
     }
     parseTreeWardArrow( i->second.first );
@@ -423,16 +518,16 @@ void DependencyTree_View::parseTreeWard( const GEOMUtils::LevelsList& theWard )
 //=================================================================================
 void DependencyTree_View::parseTreeWardArrow( const GEOMUtils::LevelsList& theWard)
 {
-  for( int j = 0; j < theWard.size(); j++ ) {
+  for( size_t j = 0; j < theWard.size(); j++ ) {
     GEOMUtils::LevelInfo Level = theWard.at(j);
     GEOMUtils::LevelInfo::const_iterator node;
     for( node = Level.begin(); node != Level.end(); node++ ) {
       DependencyTree_Object* object = myTreeMap[ node->first ];
       std::vector<std::string> Links = node->second;
-      for( int link = 0; link < Links.size(); link++ ) {
+      for( size_t link = 0; link < Links.size(); link++ ) {
         DependencyTree_Object* LinkObject = myTreeMap[ Links[ link ] ];
         if( object && LinkObject )
-          addArrow( object, LinkObject );
+          addArrow( LinkObject, object );
       }
     }
   }
@@ -511,8 +606,8 @@ void DependencyTree_View::drawTree()
 
   std::map< int, std::vector< std::string > >::const_iterator level;
   for( level = levelObjects.begin(); level != levelObjects.end(); level++ ) {
-    int step = -horDistance * ( level->second.size() - 1 ) / 2;
-    for( int objIter = 0; objIter < level->second.size(); objIter++ ) {
+    int step = -horDistance * ( int(level->second.size()) - 1 ) / 2;
+    for( size_t objIter = 0; objIter < level->second.size(); objIter++ ) {
       DependencyTree_Object* anObject = myTreeMap[ level->second.at( objIter ) ];
       anObject->setPos( step, verDistance * level->first );
       step += horDistance;
@@ -530,7 +625,7 @@ void DependencyTree_View::drawTree()
         for( node = Levelup.begin(); node != Levelup.end(); node++ ) {
           DependencyTree_Object* object = myTreeMap[ node->first ];
           DependencyTree_Arrow* arrow =
-            myArrows[ std::pair<DependencyTree_Object*,DependencyTree_Object*>( Main_object, object )];
+            myArrows[ std::pair<DependencyTree_Object*,DependencyTree_Object*>( object, Main_object )];
           if( arrow && !isItemAdded( arrow ) )
             addItem( arrow );
         }
@@ -552,7 +647,7 @@ void DependencyTree_View::drawWard( const GEOMUtils::LevelsList& theWard,
                                     std::map< int, std::vector< std::string > >& theLevelObjects,
                                     int theCurrentLevel, const int theLevelStep )
 {
-  for( int level = 0; level < theWard.size(); level++ ) {
+  for( int level = 0, size = theWard.size(); level < size; level++ ) {
     if( level >= myLevelsNumber )
       return;
     theCurrentLevel += theLevelStep;
@@ -576,7 +671,7 @@ void DependencyTree_View::drawWard( const GEOMUtils::LevelsList& theWard,
 //=================================================================================
 void DependencyTree_View::drawWardArrows( const GEOMUtils::LevelsList& theWard )
 {
-  for( int j = 0; j < theWard.size(); j++ ) {
+  for( int j = 0, size = theWard.size(); j < size; j++ ) {
     if( j >= myLevelsNumber )
       break;
     GEOMUtils::LevelInfo Level = theWard.at(j);
@@ -584,10 +679,10 @@ void DependencyTree_View::drawWardArrows( const GEOMUtils::LevelsList& theWard )
     for( node = Level.begin(); node != Level.end(); node++ ) {
       DependencyTree_Object* object = myTreeMap[ node->first ];
       GEOMUtils::NodeLinks Links = node->second;
-      for( int link = 0; link < Links.size(); link++ ) {
+      for( size_t link = 0; link < Links.size(); link++ ) {
         DependencyTree_Object* LinkObject = myTreeMap[ Links[ link ] ];
         if( isItemAdded( object ) && isItemAdded( LinkObject ) ) {
-          DependencyTree_Arrow* arrow = myArrows[ std::pair<DependencyTree_Object*,DependencyTree_Object*>( object, LinkObject ) ];
+          DependencyTree_Arrow* arrow = myArrows[ std::pair<DependencyTree_Object*,DependencyTree_Object*>( LinkObject, object ) ];
           if( arrow && !isItemAdded( arrow ) )
             addItem( arrow );
         }
@@ -606,7 +701,7 @@ void DependencyTree_View::updateView()
     return;
 
   drawTree();
-  fitAll();
+  fitWindow();
 }
 
 //=================================================================================
@@ -617,21 +712,30 @@ void DependencyTree_View::clearView( bool isClearModel )
 {
   EntryObjectMap::const_iterator objectIter;
   for( objectIter = myTreeMap.begin(); objectIter != myTreeMap.end(); objectIter++ ) {
-    DependencyTree_Object* object = objectIter->second;
-    if( object )
+    if( DependencyTree_Object* object = objectIter->second )
       if( isItemAdded( object ) )
         removeItem( object );
   }
 
   ArrowsInfo::const_iterator arrowIter;
   for( arrowIter = myArrows.begin(); arrowIter != myArrows.end(); arrowIter++ ) {
-    DependencyTree_Arrow* object = arrowIter->second;
-    if( object )
-      if( isItemAdded( object ) )
-        removeItem( object );
+    if( DependencyTree_Arrow* arrow = arrowIter->second )
+      if( isItemAdded( arrow ) )
+        removeItem( arrow );
   }
 
   if( isClearModel ) {
+    EntryObjectMap::const_iterator objectIter;
+    for( objectIter = myTreeMap.begin(); objectIter != myTreeMap.end(); objectIter++ ) {
+      if( DependencyTree_Object* object = objectIter->second )
+        delete object;
+    }
+
+    ArrowsInfo::const_iterator arrowIter;
+    for( arrowIter = myArrows.begin(); arrowIter != myArrows.end(); arrowIter++ ) {
+      if( DependencyTree_Arrow* arrow = arrowIter->second )
+        delete arrow;
+    }
     myTreeMap.clear();
     myArrows.clear();
     myTreeModel.clear();
@@ -642,6 +746,23 @@ void DependencyTree_View::clearView( bool isClearModel )
   }
 }
 
+//=================================================================================
+// function : fitWindow()
+// purpose  : scale the window considering a size of scene
+//=================================================================================
+void DependencyTree_View::fitWindow()
+{
+  int sizeFactor = 4;
+  if( objectsBoundingRect(true).width() > sizeFactor*size().width() ||
+      objectsBoundingRect(true).height() > sizeFactor*size().width() ) {
+    QRectF aRect = QRectF( -sizeFactor*size().width()/2, -sizeFactor*size().height()/2,
+                           sizeFactor*size().width(), sizeFactor*size().height() );
+    fitInView( aRect, Qt::KeepAspectRatio );
+  }
+  else
+    fitAll();
+}
+
 //=================================================================================
 // function : getNewTreeModel()
 // purpose  : get dependency tree model from engine
@@ -659,6 +780,8 @@ void DependencyTree_View::getNewTreeModel( bool theUseSelectedObject, bool theUs
       objectsEntry->length( mainObjects.Extent() );
       for ( SALOME_ListIteratorOfListIO It( mainObjects ); It.More(); It.Next(), iter++ ) {
         Handle( SALOME_InteractiveObject ) io = It.Value();
+        if( !io->hasEntry() )
+          continue;
         GEOM::GEOM_Object_var geomObject = GEOM::GEOM_Object::_nil();
         geomObject = GEOMBase::ConvertIOinGEOMObject( io );
         QString entry = geomObject->GetEntry();
@@ -701,4 +824,5 @@ int DependencyTree_View::checkMaxLevelsNumber()
     return myMaxUpwardLevelsNumber;
   else if( myDisplayDescendants->isChecked() )
     return  myMaxDownwardLevelsNumber;
+  return 0;
 }