]> SALOME platform Git repositories - modules/geom.git/blob - src/DependencyTree/DependencyTree_View.cxx
Salome HOME
- clean programming code
[modules/geom.git] / src / DependencyTree / DependencyTree_View.cxx
1 // Copyright (C) 2014  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 // Internal includes
21 #include "DependencyTree_View.h"
22 #include "DependencyTree_Object.h"
23 #include "DependencyTree_Arrow.h"
24
25 // GUI includes
26 #include <SUIT_Session.h>
27 #include <SUIT_ResourceMgr.h>
28 #include <SalomeApp_Study.h>
29 #include <QtxActionToolMgr.h>
30 #include <LightApp_SelectionMgr.h>
31 #include <SALOME_ListIteratorOfListIO.hxx>
32
33 // GEOM includes
34 #include <GEOMBase.h>
35
36 // Qt includes
37 #include <QApplication>
38 #include <QWidgetAction>
39
40 DependencyTree_View::DependencyTree_View( QWidget* theParent )
41 :GraphicsView_ViewPort( theParent ),
42 myLevelsNumber(0),
43 myMaxDownwardLevelsNumber(0),
44 myMaxUpwardLevelsNumber(0),
45 myIsUpdate( true )
46 {
47   SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( SUIT_Session::session()->activeApplication() );
48   if ( !app ) return;
49
50   SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( app->activeStudy() );
51   myStudy = GeometryGUI::ClientStudyToStudy( study->studyDS());
52
53   mySelectionMgr = app->selectionMgr();
54   if ( !mySelectionMgr ) return;
55
56   myMainEntries = new GEOM::string_array();
57
58   getNewTreeModel();
59 }
60
61 DependencyTree_View::~DependencyTree_View()
62 {
63   clearView( true );
64 }
65
66 //=================================================================================
67 // function : init()
68 // purpose  : this method is obligatory for initialize view frame actions
69 //=================================================================================
70 void DependencyTree_View::init( GraphicsView_ViewFrame* theViewFrame )
71 {
72   myNodesMovable = new QCheckBox( tr( "MOVE_NODES" ) );
73   QWidgetAction* nodesMovableAction = new QWidgetAction( theViewFrame );
74   nodesMovableAction->setDefaultWidget( myNodesMovable );
75
76   myDisplayAscendants = new QCheckBox( tr( "DISPLAY_ASCENDANTS" ) );
77   QWidgetAction* displayAscendantsAction = new QWidgetAction( theViewFrame );
78   displayAscendantsAction->setDefaultWidget( myDisplayAscendants  );
79
80   myDisplayDescendants = new QCheckBox(tr("DISPLAY_DESCENDANTS"));
81   QWidgetAction* displayDescendantsAction = new QWidgetAction( theViewFrame );
82   displayDescendantsAction->setDefaultWidget( myDisplayDescendants );
83
84   QLabel* hierarchyDepthLabel = new QLabel( tr( "HIERARCHY_DEPTH" ) );
85   QWidgetAction* hierarchyDepthLabelAction = new QWidgetAction( theViewFrame );
86   hierarchyDepthLabelAction->setDefaultWidget( hierarchyDepthLabel );
87
88   myLevelsNumber = checkMaxLevelsNumber();
89
90   myHierarchyDepth = new QSpinBox();
91   myHierarchyDepth->setRange( 0, checkMaxLevelsNumber() );
92   myHierarchyDepth->setSpecialValueText( tr( "SHOW_ALL" ) );
93   myHierarchyDepth->setValue( 0 );
94   QWidgetAction* hierarchyDepthAction = new QWidgetAction( theViewFrame );
95   hierarchyDepthAction->setDefaultWidget( myHierarchyDepth );
96
97   updateButton = new QPushButton( tr( "UPDATE" ) );
98   QWidgetAction* updateAction = new QWidgetAction( theViewFrame );
99   updateAction->setDefaultWidget( updateButton );
100
101   QAction* separator1 = theViewFrame->toolMgr()->separator( false );
102   QAction* separator2 = theViewFrame->toolMgr()->separator( false );
103
104   theViewFrame->toolMgr()->append( separator1, theViewFrame->getToolBarId() );
105   theViewFrame->toolMgr()->append( hierarchyDepthLabelAction, theViewFrame->getToolBarId() );
106   theViewFrame->toolMgr()->append( hierarchyDepthAction, theViewFrame->getToolBarId() );
107   theViewFrame->toolMgr()->append( displayAscendantsAction, theViewFrame->getToolBarId() );
108   theViewFrame->toolMgr()->append( displayDescendantsAction, theViewFrame->getToolBarId() );
109   theViewFrame->toolMgr()->append( nodesMovableAction, theViewFrame->getToolBarId() );
110
111   theViewFrame->toolMgr()->append( separator2, theViewFrame->getToolBarId() );
112   theViewFrame->toolMgr()->append( updateAction, theViewFrame->getToolBarId() );
113
114   connect( myNodesMovable, SIGNAL( toggled( bool ) ), this, SLOT( onMoveNodes( bool ) ) );
115   connect( myHierarchyDepth, SIGNAL( valueChanged ( int ) ), this, SLOT( onHierarchyType() ) );
116   connect( myDisplayAscendants , SIGNAL( toggled( bool ) ), this, SLOT( onHierarchyType() ) );
117   connect( myDisplayDescendants, SIGNAL( toggled( bool ) ), this, SLOT( onHierarchyType() ) );
118   connect( updateButton, SIGNAL( clicked() ), this, SLOT( onUpdateModel() ) );
119
120   SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( SUIT_Session::session()->activeApplication() );
121   GeometryGUI* aGeomGUI = dynamic_cast<GeometryGUI*>( app->module( "Geometry" ) );
122   if ( aGeomGUI ) {
123     connect( aGeomGUI, SIGNAL( SignalDependencyTreeParamChanged( const QString&, const QString& ) ),
124              this, SLOT( onPreferenceChanged( const QString&, const QString& ) ) );
125     connect( aGeomGUI, SIGNAL( SignalDependencyTreeRenameObject( const QString& ) ),
126              this, SLOT( onRenameObject( const QString& ) ) );
127   }
128
129   SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
130   setPrefBackgroundColor( resMgr->colorValue( "Geometry", "dependency_tree_background_color", QColor( 255, 255, 255 ) ) );
131   setNodesMovable( resMgr->booleanValue( "Geometry", "dependency_tree_move_nodes", true ) );
132   setHierarchyType( resMgr->integerValue( "Geometry", "dependency_tree_hierarchy_type", 0 ) );
133 }
134
135 //=================================================================================
136 // function : updateModel()
137 // purpose  : run all stage of dependency tree creation
138 //=================================================================================
139 void DependencyTree_View::updateModel( bool theUseSelectedObject, bool theUseOB )
140 {
141   getNewTreeModel( theUseSelectedObject, theUseOB );
142   onHierarchyType();
143 }
144
145 //=================================================================================
146 // function : mouseMoveEvent()
147 // purpose  : make some actions when mouse was moved
148 //=================================================================================
149 void DependencyTree_View::mouseMoveEvent( QMouseEvent *event )
150 {
151   QGraphicsView::mouseMoveEvent( event );
152   ArrowsInfo::const_iterator i;
153   for( i = myArrows.begin(); i != myArrows.end(); i++ ) {
154     DependencyTree_Arrow* arrow = myArrows[ i->first ];
155     arrow->update();
156   }
157 }
158
159 //=================================================================================
160 // function : getViewName()
161 // purpose  : return the name of current view
162 //=================================================================================
163 QString DependencyTree_View::getViewName() const
164 {
165   return tr( "DEPENDENCY_TREE" );
166 }
167
168 //=================================================================================
169 // function : getStudyId()
170 // purpose  : return Id of current study
171 //=================================================================================
172 int DependencyTree_View::getStudyId() const
173 {
174   return myStudy->StudyId();
175 }
176
177 //=================================================================================
178 // function : getObjectByEntry()
179 // purpose  : return DependencyTree_Object by entry
180 //=================================================================================
181 DependencyTree_Object* DependencyTree_View::getObjectByEntry( const std::string& theEntry )
182 {
183   return myTreeMap[ theEntry ];
184 }
185
186 //=================================================================================
187 // function : setHierarchyType()
188 // purpose  : set hierarchy type of dependency tree
189 //=================================================================================
190 void DependencyTree_View::setHierarchyType( const int theType )
191 {
192   myIsUpdate = false;
193   switch( theType ) {
194   case 0:
195     myDisplayAscendants->setChecked( true );
196     myDisplayDescendants->setChecked( true );
197     break;
198   case 1:
199     myDisplayAscendants->setChecked( true );
200     myDisplayDescendants->setChecked( false );
201     break;
202   case 2:
203     myDisplayAscendants->setChecked( false );
204     myDisplayDescendants->setChecked( true );
205     break;
206   }
207   myIsUpdate = true;
208   myLevelsNumber = checkMaxLevelsNumber();
209   onHierarchyType();
210 }
211
212 //=================================================================================
213 // function : setNodesMovable()
214 // purpose  : set possibility to move nodes or not
215 //=================================================================================
216 void DependencyTree_View::setNodesMovable( const bool theIsMovable )
217 {
218   myNodesMovable->setChecked( theIsMovable );
219 }
220
221 //=================================================================================
222 // function : setPrefBackgroundColor()
223 // purpose  : set background color from preferences
224 //=================================================================================
225 void DependencyTree_View::setPrefBackgroundColor( const QColor& theColor )
226 {
227   if( isForegroundEnabled() )
228   {
229     setForegroundColor( theColor );
230     updateForeground();
231   }
232   else
233     setBackgroundColor( theColor );
234 }
235
236 //=================================================================================
237 // function : setNodeColor()
238 // purpose  : set node color from preferences
239 //=================================================================================
240 void DependencyTree_View::setNodeColor( const QColor& theColor )
241 {
242   EntryObjectMap::const_iterator i;
243   for( i = myTreeMap.begin(); i != myTreeMap.end(); i++ ) {
244     DependencyTree_Object* object = myTreeMap[ i->first ];
245     object->setColor( theColor );
246   }
247 }
248
249 //=================================================================================
250 // function : setMainNodeColor()
251 // purpose  : set main node color from preferences
252 //=================================================================================
253 void DependencyTree_View::setMainNodeColor( const QColor& theColor )
254 {
255   EntryObjectMap::const_iterator i;
256   for( i = myTreeMap.begin(); i != myTreeMap.end(); i++ ) {
257     DependencyTree_Object* object = myTreeMap[ i->first ];
258     object->setMainObjectColor( theColor );
259   }
260 }
261
262 //=================================================================================
263 // function : setUnpublishNodeColor()
264 // purpose  : set unpublished node color from preferences
265 //=================================================================================
266 void DependencyTree_View::setUnpublishNodeColor( const QColor& theColor )
267 {
268   EntryObjectMap::const_iterator i;
269   for( i = myTreeMap.begin(); i != myTreeMap.end(); i++ ) {
270     DependencyTree_Object* object = myTreeMap[ i->first ];
271     object->setUnpublishObjectColor( theColor );
272   }
273 }
274
275 //=================================================================================
276 // function : setSelectNodeColor()
277 // purpose  : set selected node color from preferences
278 //=================================================================================
279 void DependencyTree_View::setSelectNodeColor( const QColor& theColor )
280 {
281   EntryObjectMap::const_iterator i;
282   for( i = myTreeMap.begin(); i != myTreeMap.end(); i++ ) {
283     DependencyTree_Object* object = myTreeMap[ i->first ];
284     object->setSelectColor( theColor );
285   }
286 }
287
288 //=================================================================================
289 // function : setArrowColor()
290 // purpose  : set arrow color from preferences
291 //=================================================================================
292 void DependencyTree_View::setArrowColor( const QColor& theColor )
293 {
294   ArrowsInfo::const_iterator i;
295   for( i = myArrows.begin(); i != myArrows.end(); i++ ) {
296     DependencyTree_Arrow* arrow = myArrows[ i->first ];
297     arrow->setColor( theColor );
298   }
299 }
300
301 //=================================================================================
302 // function : setHighlightArrowColor()
303 // purpose  : set highlighted arrow color from preferences
304 //=================================================================================
305 void DependencyTree_View::setHighlightArrowColor( const QColor& theColor )
306 {
307   ArrowsInfo::const_iterator i;
308   for( i = myArrows.begin(); i != myArrows.end(); i++ ) {
309     DependencyTree_Arrow* arrow = myArrows[ i->first ];
310     arrow->setHighlightColor( theColor );
311   }
312 }
313
314 //=================================================================================
315 // function : setSelectArrowColor()
316 // purpose  : set selected arrow color from preferences
317 //=================================================================================
318 void DependencyTree_View::setSelectArrowColor( const QColor& theColor )
319 {
320   ArrowsInfo::const_iterator i;
321   for( i = myArrows.begin(); i != myArrows.end(); i++ ) {
322     DependencyTree_Arrow* arrow = myArrows[ i->first ];
323     arrow->setSelectColor( theColor );
324   }
325 }
326
327 //=================================================================================
328 // function : onRebuildModel()
329 // purpose  : slot for updating tree model using selected objects in viewer
330 //=================================================================================
331 void DependencyTree_View::onRebuildModel()
332 {
333   updateModel( true, false );
334 }
335
336 //=================================================================================
337 // function : onUpdateModel()
338 // purpose  : slot for updating tree model for main objects in viewer
339 //=================================================================================
340 void DependencyTree_View::onUpdateModel()
341 {
342   updateModel( false );
343 }
344
345 //=================================================================================
346 // function : onMoveNodes()
347 // purpose  : slot for setting the possibility to move nodes in viewer
348 //=================================================================================
349 void DependencyTree_View::onMoveNodes( bool theIsMoveNodes )
350 {
351   EntryObjectMap::const_iterator i;
352   for( i = myTreeMap.begin(); i != myTreeMap.end(); i++ ) {
353     DependencyTree_Object* object = myTreeMap[ i->first ];
354     if( object )
355       object->setMovable( theIsMoveNodes );
356   }
357 }
358
359 //=================================================================================
360 // function : onHierarchyType()
361 // purpose  : slot for setting the hierarchy type of tree
362 //=================================================================================
363 void DependencyTree_View::onHierarchyType()
364 {
365   myHierarchyDepth->setRange( 0, checkMaxLevelsNumber() );
366   if( myHierarchyDepth->value() > checkMaxLevelsNumber() )
367     myHierarchyDepth->setValue( checkMaxLevelsNumber() );
368
369   if( myHierarchyDepth->value() == 0 )
370     myLevelsNumber = myHierarchyDepth->maximum();
371   else
372     myLevelsNumber = myHierarchyDepth->value();
373
374   updateView();
375 }
376
377 //=================================================================================
378 // function : onPreferencesChanged()
379 // purpose  : slot for changing tree parameters from preferences
380 //=================================================================================
381 void DependencyTree_View::onPreferenceChanged( const QString& section, const QString& param )
382 {
383   SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
384
385   if( param == QString("dependency_tree_hierarchy_type") ) {
386     int hierarchyType = resMgr->integerValue( section, param, 0);
387     setHierarchyType( hierarchyType );
388   }
389   else if(  param == QString("dependency_tree_move_nodes") ) {
390     bool isNodesMovable = resMgr->booleanValue( section, param, true);
391     setNodesMovable( isNodesMovable );
392   }
393   else if(  param == QString("dependency_tree_background_color") ) {
394     QColor c = resMgr->colorValue( section, param, QColor( 255, 255, 255 ) );
395     setPrefBackgroundColor( c );
396   }
397   else if(  param == QString("dependency_tree_node_color") ) {
398     QColor c = resMgr->colorValue( section, param, QColor( 62, 180, 238 ) );
399     setNodeColor( c );
400   }
401   else if(  param == QString("dependency_tree_main_node_color") ) {
402     QColor c = resMgr->colorValue( section, param, QColor( 238, 90, 125 ) );
403     setMainNodeColor( c );
404   }
405   else if(  param == QString("dependency_tree_unpublish_node_color") ) {
406     QColor c = resMgr->colorValue( section, param, QColor( 255, 255, 255 ) );
407     setUnpublishNodeColor( c );
408   }
409   else if(  param == QString("dependency_tree_select_node_color") ) {
410     QColor c = resMgr->colorValue( section, param, QColor( 237, 243, 58 ) );
411     setSelectNodeColor( c );
412   }
413   else if(  param == QString("dependency_tree_arrow_color") ) {
414     QColor c = resMgr->colorValue( section, param, QColor( 0, 0, 130 ) );
415     setArrowColor( c );
416   }
417   else if(  param == QString("dependency_tree_highlight_arrow_color") ) {
418     QColor c = resMgr->colorValue( section, param, QColor( 0, 0, 255 ) );
419     setHighlightArrowColor( c );
420   }
421   else if(  param == QString("dependency_tree_select_arrow_color") ) {
422     QColor c = resMgr->colorValue( section, param, QColor( 255, 0, 0 ) );
423     setSelectArrowColor( c );
424   }
425 }
426
427 //=================================================================================
428 // function : onRenameObject()
429 // purpose  : update object name, having edited it in Object Browser
430 //=================================================================================
431 void DependencyTree_View::onRenameObject( const QString& theEntry )
432 {
433   DependencyTree_Object* object = getObjectByEntry( theEntry.toStdString() );
434   object->updateName();
435 }
436
437 //=================================================================================
438 // function : parseTree()
439 // purpose  : parse created model to initialize all nodes and arrows
440 //=================================================================================
441 void DependencyTree_View::parseTree()
442 {
443   GEOMUtils::TreeModel::const_iterator i;
444   for( i = myTreeModel.begin(); i != myTreeModel.end(); i++ ) {
445     std::string objectEntry = i->first;
446     addNode( objectEntry );
447     parseTreeWard( i->second.first );
448     if( i->second.first.size() > myMaxUpwardLevelsNumber )
449       myMaxUpwardLevelsNumber = i->second.first.size();
450     parseTreeWard( i->second.second );
451     if( i->second.second.size() > myMaxDownwardLevelsNumber )
452       myMaxDownwardLevelsNumber = i->second.second.size();
453   }
454
455   for( i = myTreeModel.begin(); i != myTreeModel.end(); i++ ) {
456     DependencyTree_Object* Main_object = myTreeMap[ i->first ];
457     if( i->second.first.size() > 0 ) {
458       GEOMUtils::LevelInfo Levelup = i->second.first.at(0);
459       GEOMUtils::LevelInfo::const_iterator node;
460       for( node = Levelup.begin(); node != Levelup.end(); node++ ) {
461         DependencyTree_Object* object = myTreeMap[ node->first ];
462         addArrow( Main_object, object );
463       }
464     }
465     parseTreeWardArrow( i->second.first );
466     parseTreeWardArrow( i->second.second );
467   }
468 }
469
470 //=================================================================================
471 // function : parseTreeWard()
472 // purpose  : parse tree ward to initialize all nodes of current ward
473 //=================================================================================
474 void DependencyTree_View::parseTreeWard( const GEOMUtils::LevelsList& theWard )
475 {
476   int levelsNumber = theWard.size();
477   for( int level = 0; level < levelsNumber; level++ ) {
478     GEOMUtils::LevelInfo levelInfo = theWard[ level ];
479     GEOMUtils::LevelInfo::const_iterator node;
480     for( node = levelInfo.begin(); node != levelInfo.end(); node++ )
481       addNode( node->first );
482   }
483 }
484
485 //=================================================================================
486 // function : parseTreeWardArrow()
487 // purpose  : parse tree ward to initialize all arrows of current ward
488 //=================================================================================
489 void DependencyTree_View::parseTreeWardArrow( const GEOMUtils::LevelsList& theWard)
490 {
491   for( int j = 0; j < theWard.size(); j++ ) {
492     GEOMUtils::LevelInfo Level = theWard.at(j);
493     GEOMUtils::LevelInfo::const_iterator node;
494     for( node = Level.begin(); node != Level.end(); node++ ) {
495       DependencyTree_Object* object = myTreeMap[ node->first ];
496       std::vector<std::string> Links = node->second;
497       for( int link = 0; link < Links.size(); link++ ) {
498         DependencyTree_Object* LinkObject = myTreeMap[ Links[ link ] ];
499         if( object && LinkObject )
500           addArrow( object, LinkObject );
501       }
502     }
503   }
504 }
505
506 //=================================================================================
507 // function : addNode()
508 // purpose  : add node to viewer
509 //=================================================================================
510 void DependencyTree_View::addNode( const std::string& theEntry )
511 {
512   if( !myTreeMap[theEntry] )
513     myTreeMap[theEntry] = new DependencyTree_Object( theEntry );
514 }
515
516 //=================================================================================
517 // function : addArrow()
518 // purpose  : add arrow to viewer
519 //=================================================================================
520 void DependencyTree_View::addArrow( DependencyTree_Object* startItem, DependencyTree_Object* endItem )
521 {
522   bool isFind = false;
523
524   ArrowsInfo::const_iterator i;
525   for( i = myArrows.begin(); i != myArrows.end(); i++ ) {
526     DependencyTree_Arrow* arrow = i->second;
527     if( arrow->getStartItem() == startItem && arrow->getEndItem() == endItem )
528       isFind = true;
529     else if( arrow->getStartItem() == endItem && arrow->getEndItem() == startItem ) {
530       arrow->setIsBiLink( true );
531       isFind = true;
532     }
533   }
534   if( !isFind ) {
535     DependencyTree_Arrow *arrow = new DependencyTree_Arrow( startItem, endItem );
536     myArrows[ std::pair<DependencyTree_Object*,DependencyTree_Object*>( startItem, endItem ) ] = arrow;
537   }
538 }
539
540 //=================================================================================
541 // function : drawTree()
542 // purpose  : redraw dependency tree using existing model
543 //=================================================================================
544 void DependencyTree_View::drawTree()
545 {
546   clearView( false );
547   clearSelected();
548
549   // draw nodes on scene
550   std::map< std::string, int > entryLevelMap;
551   std::map< int, std::vector< std::string > > levelObjects;
552   int currentLevel;
553   int horDistance, verDistance;
554   GEOMUtils::TreeModel::const_reverse_iterator i;
555   for( i = myTreeModel.rbegin(); i != myTreeModel.rend(); i++ ) {
556     currentLevel = 0;
557     std::string objectEntry = i->first;
558     DependencyTree_Object* objectItem = myTreeMap[ objectEntry ];
559     horDistance = 100 + int( objectItem->boundingRect().width() );
560     verDistance = 3 * int( objectItem->boundingRect().height() );
561     if( isItemAdded( objectItem ) )
562       currentLevel = entryLevelMap[ objectEntry ];
563     else {
564       addItem( objectItem );
565       objectItem->unselect();
566       entryLevelMap[ objectEntry ] = currentLevel;
567       levelObjects[ currentLevel ].push_back( objectEntry );
568     }
569     objectItem->setIsMainObject( true );
570
571     if( myDisplayAscendants->isChecked() )
572       drawWard( i->second.first, entryLevelMap, levelObjects, currentLevel, -1 );
573     if( myDisplayDescendants->isChecked() )
574       drawWard( i->second.second, entryLevelMap, levelObjects, currentLevel, 1 );
575   }
576
577   std::map< int, std::vector< std::string > >::const_iterator level;
578   for( level = levelObjects.begin(); level != levelObjects.end(); level++ ) {
579     int step = -horDistance * ( level->second.size() - 1 ) / 2;
580     for( int objIter = 0; objIter < level->second.size(); objIter++ ) {
581       DependencyTree_Object* anObject = myTreeMap[ level->second.at( objIter ) ];
582       anObject->setPos( step, verDistance * level->first );
583       step += horDistance;
584     }
585   }
586
587   // draw arrows on scene
588   GEOMUtils::TreeModel::const_iterator j;
589   for( j = myTreeModel.begin(); j != myTreeModel.end(); j++ ) {
590     DependencyTree_Object* Main_object = myTreeMap[ j->first ];
591     if( j->second.first.size() > 0 ) {
592       GEOMUtils::LevelInfo Levelup = j->second.first.at(0);
593       if( myDisplayAscendants ->isChecked() ) {
594         GEOMUtils::LevelInfo::const_iterator node;
595         for( node = Levelup.begin(); node != Levelup.end(); node++ ) {
596           DependencyTree_Object* object = myTreeMap[ node->first ];
597           DependencyTree_Arrow* arrow =
598             myArrows[ std::pair<DependencyTree_Object*,DependencyTree_Object*>( Main_object, object )];
599           if( arrow && !isItemAdded( arrow ) )
600             addItem( arrow );
601         }
602       }
603     }
604     if( myDisplayAscendants->isChecked() )
605       drawWardArrows( j->second.first );
606     if( myDisplayDescendants->isChecked() )
607       drawWardArrows( j->second.second );
608   }
609 }
610
611 //=================================================================================
612 // function : drawWard()
613 // purpose  : draw nodes of dependency tree ward (ascendant or descendant)
614 //=================================================================================
615 void DependencyTree_View::drawWard( const GEOMUtils::LevelsList& theWard,
616                                     std::map< std::string, int >& theEntryLevelMap,
617                                     std::map< int, std::vector< std::string > >& theLevelObjects,
618                                     int theCurrentLevel, const int theLevelStep )
619 {
620   for( int level = 0; level < theWard.size(); level++ ) {
621     if( level >= myLevelsNumber )
622       return;
623     theCurrentLevel += theLevelStep;
624     GEOMUtils::LevelInfo levelInfo = theWard.at( level );
625     GEOMUtils::LevelInfo::const_iterator node;
626     for( node = levelInfo.begin(); node != levelInfo.end(); node++ ) {
627       DependencyTree_Object* object = myTreeMap[ node->first ];
628       if( object && !isItemAdded( object ) ) {
629         addItem( object );
630         object->unselect();
631         theEntryLevelMap[ node->first ] = theCurrentLevel;
632         theLevelObjects[ theCurrentLevel ].push_back( node->first );
633       }
634     }
635   }
636 }
637
638 //=================================================================================
639 // function : drawWardArrows()
640 // purpose  : draw arrows of dependency tree ward (ascendant or descendant)
641 //=================================================================================
642 void DependencyTree_View::drawWardArrows( const GEOMUtils::LevelsList& theWard )
643 {
644   for( int j = 0; j < theWard.size(); j++ ) {
645     if( j >= myLevelsNumber )
646       break;
647     GEOMUtils::LevelInfo Level = theWard.at(j);
648     GEOMUtils::LevelInfo::const_iterator node;
649     for( node = Level.begin(); node != Level.end(); node++ ) {
650       DependencyTree_Object* object = myTreeMap[ node->first ];
651       GEOMUtils::NodeLinks Links = node->second;
652       for( int link = 0; link < Links.size(); link++ ) {
653         DependencyTree_Object* LinkObject = myTreeMap[ Links[ link ] ];
654         if( isItemAdded( object ) && isItemAdded( LinkObject ) ) {
655           DependencyTree_Arrow* arrow = myArrows[ std::pair<DependencyTree_Object*,DependencyTree_Object*>( object, LinkObject ) ];
656           if( arrow && !isItemAdded( arrow ) )
657             addItem( arrow );
658         }
659       }
660     }
661   }
662 }
663
664 //=================================================================================
665 // function : updateView()
666 // purpose  : update viewer using created dependency tree model
667 //=================================================================================
668 void DependencyTree_View::updateView()
669 {
670   if( !myIsUpdate )
671     return;
672
673   drawTree();
674   fitAll();
675 }
676
677 //=================================================================================
678 // function : clearView()
679 // purpose  : clear viewer and initialize all variables
680 //=================================================================================
681 void DependencyTree_View::clearView( bool isClearModel )
682 {
683   EntryObjectMap::const_iterator objectIter;
684   for( objectIter = myTreeMap.begin(); objectIter != myTreeMap.end(); objectIter++ ) {
685     DependencyTree_Object* object = objectIter->second;
686     if( object )
687       if( isItemAdded( object ) )
688         removeItem( object );
689   }
690
691   ArrowsInfo::const_iterator arrowIter;
692   for( arrowIter = myArrows.begin(); arrowIter != myArrows.end(); arrowIter++ ) {
693     DependencyTree_Arrow* object = arrowIter->second;
694     if( object )
695       if( isItemAdded( object ) )
696         removeItem( object );
697   }
698
699   if( isClearModel ) {
700     myTreeMap.clear();
701     myArrows.clear();
702     myTreeModel.clear();
703     myLevelsNumber = 0;
704     myMaxDownwardLevelsNumber = 0;
705     myMaxUpwardLevelsNumber = 0;
706     myIsUpdate = true;
707   }
708 }
709
710 //=================================================================================
711 // function : getNewTreeModel()
712 // purpose  : get dependency tree model from engine
713 //=================================================================================
714 void DependencyTree_View::getNewTreeModel( bool theUseSelectedObject, bool theUseOB )
715 {
716   GEOM::string_array_var objectsEntry = new GEOM::string_array();
717   int iter = 0;
718
719   if( theUseSelectedObject ) {
720     if( theUseOB ) {
721       SALOME_ListIO mainObjects;
722       mySelectionMgr->selectedObjects( mainObjects );
723       // create a list of selected object entry
724       objectsEntry->length( mainObjects.Extent() );
725       for ( SALOME_ListIteratorOfListIO It( mainObjects ); It.More(); It.Next(), iter++ ) {
726         Handle( SALOME_InteractiveObject ) io = It.Value();
727         GEOM::GEOM_Object_var geomObject = GEOM::GEOM_Object::_nil();
728         geomObject = GEOMBase::ConvertIOinGEOMObject( io );
729         QString entry = geomObject->GetEntry();
730         objectsEntry[ iter ] = entry.toLatin1().constData();
731       }
732     }
733     else {
734       objectsEntry->length( nbSelected() );
735       for( initSelected(); moreSelected(); nextSelected(), iter++ )
736         if( DependencyTree_Object* treeObject = dynamic_cast<DependencyTree_Object*>( selectedObject() ) )
737           objectsEntry[ iter ] = treeObject->getEntry().c_str();
738     }
739     myMainEntries = objectsEntry;
740   }
741
742   // get string which describes dependency tree structure
743   SALOMEDS::TMPFile_var SeqFile =
744     GeometryGUI::GetGeomGen()->GetDependencyTree( myStudy, myMainEntries );
745   char* buf = (char*)&SeqFile[0];
746
747   clearView( true );
748   mySelectionMgr->clearSelected();
749
750   // get dependency tree structure
751   GEOMUtils::ConvertStringToTree( buf, myTreeModel );
752
753   parseTree();
754 }
755
756 //=================================================================================
757 // function : checkMaxLevelsNumber()
758 // purpose  : calculate max levels number
759 //=================================================================================
760 int DependencyTree_View::checkMaxLevelsNumber()
761 {
762   if( myDisplayAscendants->isChecked() && myDisplayDescendants->isChecked() )
763     return myMaxUpwardLevelsNumber > myMaxDownwardLevelsNumber ?
764            myMaxUpwardLevelsNumber : myMaxDownwardLevelsNumber;
765   else if( myDisplayAscendants ->isChecked() )
766     return myMaxUpwardLevelsNumber;
767   else if( myDisplayDescendants->isChecked() )
768     return  myMaxDownwardLevelsNumber;
769 }