Salome HOME
Merge master branch into V9_dev.
[modules/geom.git] / src / GEOMGUI / GEOMGUI_TextTreeWdg.cxx
1 // Copyright (C) 2015-2016  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 // File      : GEOMGUI_TextTreeWdg.cxx
20 // Author    : Alexander KOVALEV (akl)
21
22 #include "GEOMGUI_TextTreeWdg.h"
23
24 #include "GEOMGUI_DimensionProperty.h"
25 #include "GEOMGUI_AnnotationAttrs.h"
26 #include "GEOMGUI_AnnotationMgr.h"
27 #include "GeometryGUI.h"
28 #include "GeometryGUI_Operations.h"
29 #include <GEOM_Constants.h>
30 #include <GEOMUtils.hxx>
31
32 // GUI includes
33 #include <LightApp_Module.h>
34 #include <SalomeApp_Application.h>
35 #include <SalomeApp_Study.h>
36 #include <SUIT_Desktop.h>
37 #include <SUIT_Session.h>
38 #include <SUIT_ResourceMgr.h>
39 #include <SUIT_DataBrowser.h>
40
41 // Qt includes
42 #include <QAction>
43 #include <QMenu>
44 #include <QString>
45 #include <QLabel>
46 #include <QLineEdit>
47 #include <QTreeWidget>
48 #include <QHeaderView>
49 #include <QGroupBox>
50 #include <QVBoxLayout>
51 #include <QHBoxLayout>
52 #include <QHash>
53
54 // ----------------------------------------------------------------------------
55 // Common style interface for managing dimension and annotation properties
56 // ----------------------------------------------------------------------------
57 namespace
58 {
59   //! Access interface implementation for shape dimension attribute/property.
60   class DimensionsProperty : public GEOMGUI_TextTreeWdg::VisualProperty
61   {
62   public:
63
64     DimensionsProperty( const std::string& theEntry ) :
65       myEntry( theEntry ) {
66       myAttr.LoadFromAttribute( theEntry );
67     }
68     virtual int GetNumber() Standard_OVERRIDE {
69       return myAttr.GetNumber();
70     }
71     virtual QString GetName( const int theIndex ) Standard_OVERRIDE {
72       return myAttr.GetName( theIndex );
73     }
74     virtual bool GetIsVisible( const int theIndex ) Standard_OVERRIDE {
75       return myAttr.IsVisible( theIndex );
76     }
77     virtual void SetIsVisible( const int theIndex, const bool theIsVisible ) Standard_OVERRIDE {
78       myAttr.SetVisible( theIndex, theIsVisible );
79     }
80     virtual void Save() Standard_OVERRIDE {
81       myAttr.SaveToAttribute( myEntry );
82     }
83     GEOMGUI_DimensionProperty& Attr() { return myAttr; }
84
85   private:
86     GEOMGUI_DimensionProperty myAttr;
87     std::string myEntry;
88   };
89
90   //! Access interface implementation for shape annotation attribute.
91   class AnnotationsProperty : public GEOMGUI_TextTreeWdg::VisualProperty
92   {
93   public:
94
95     AnnotationsProperty( const std::string& theEntry ) {
96       myEntry = theEntry.c_str();
97       _PTR(SObject) aSObj = SalomeApp_Application::getStudy()->FindObjectID( theEntry );
98       if ( aSObj ) {
99         myAttr = GEOMGUI_AnnotationAttrs::FindAttributes( aSObj );
100       }
101     }
102     virtual int GetNumber() Standard_OVERRIDE {
103       return !myAttr.IsNull() ? myAttr->GetNbAnnotation() : 0;
104     }
105     virtual QString GetName( const int theIndex ) Standard_OVERRIDE {
106       return !myAttr.IsNull() ? myAttr->GetText( theIndex ) : QString();
107     }
108     virtual bool GetIsVisible( const int theIndex ) Standard_OVERRIDE {
109       GEOMGUI_AnnotationMgr* aMgr = annotationMgr();
110       if (!aMgr) {
111         return false;
112       }
113       return aMgr->IsDisplayed( myEntry, theIndex );
114     }
115     virtual void SetIsVisible( const int theIndex, const bool theIsVisible ) Standard_OVERRIDE {
116       GEOMGUI_AnnotationMgr* aMgr = annotationMgr();
117       if (!aMgr) {
118         return;
119       }
120       if (theIsVisible)
121         annotationMgr()->Display(myEntry, theIndex);
122       else
123         annotationMgr()->Erase(myEntry, theIndex);
124     }
125     virtual void Save() Standard_OVERRIDE {
126       /* every change is automatically saved */
127     }
128     Handle(GEOMGUI_AnnotationAttrs) Attr() { return myAttr; }
129
130 protected:
131     GEOMGUI_AnnotationMgr* annotationMgr() const
132     {
133       CAM_Application* anApp = dynamic_cast<CAM_Application*>(SUIT_Session::session()->activeApplication());
134       GeometryGUI* aModule = dynamic_cast<GeometryGUI*>(anApp->activeModule());
135       if (!aModule) {
136         return NULL;
137       }
138       return aModule->GetAnnotationMgr();
139     }
140
141 private:
142     QString myEntry;
143     Handle(GEOMGUI_AnnotationAttrs) myAttr;
144   };
145 }
146
147 // ----------------------------------------------------------------------------
148 // Text tree widget implementation
149 // ----------------------------------------------------------------------------
150
151 //=================================================================================
152 // function : Constructor
153 // purpose  :
154 //=================================================================================
155 GEOMGUI_TextTreeWdg::GEOMGUI_TextTreeWdg( SalomeApp_Application* app )
156 {
157   myStudy = dynamic_cast<SalomeApp_Study*>( app->activeStudy() );
158   myDisplayer = GEOM_Displayer();
159
160   SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
161   myVisibleIcon = QIcon( resMgr->loadPixmap( "SUIT", tr( "ICON_DATAOBJ_VISIBLE" ) ) );
162   myInvisibleIcon = QIcon( resMgr->loadPixmap( "SUIT", tr( "ICON_DATAOBJ_INVISIBLE" ) ) );
163
164   setWindowTitle( tr( "TEXT_TREE_VIEW_TITLE" ) );
165   setObjectName( "geomTextTreeWdg" );
166
167   setRootIsDecorated( true );
168   setSelectionMode( QAbstractItemView::ExtendedSelection );
169   setAllColumnsShowFocus( true );
170   setUniformRowHeights( true );
171
172   QStringList columnNames;
173   columnNames << tr("TEXT_TREE_VIEW_NAME") << "";
174   QTreeWidgetItem * headerItem = new QTreeWidgetItem( columnNames );
175   headerItem->setIcon( 1, myVisibleIcon );
176   setHeaderItem ( headerItem ); 
177   header()->moveSection( 1, 0 );
178 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
179   header()->setResizeMode( 1, QHeaderView::ResizeToContents );
180 #else
181   header()->setSectionResizeMode( 1, QHeaderView::ResizeToContents );
182 #endif
183   QStringList rootNames;
184   rootNames << tr("GEOM_DIMENSIONS") << "";
185   myDimensionsItem = new QTreeWidgetItem( this, rootNames );
186   myDimensionsItem->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled );
187   addTopLevelItem( myDimensionsItem );
188
189   rootNames.clear();
190   rootNames << tr("GEOM_ANNOTATIONS") << "";
191   myAnnotationsItem = new QTreeWidgetItem( this, rootNames );
192   myAnnotationsItem->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled );
193   addTopLevelItem( myAnnotationsItem );
194
195   // get a free dockable window id
196   myWindowID = 11;
197   while( app->dockWindow( myWindowID ))
198     ++myWindowID;
199   ++myWindowID;
200
201   createActions();
202   setContextMenuPolicy( Qt::CustomContextMenu );
203   connect( this, SIGNAL( customContextMenuRequested(const QPoint&) ),
204            this, SLOT( showContextMenu(const QPoint&) ) );
205
206   connect( app->objectBrowser(), SIGNAL( updated() ), this, SLOT( updateTree() ) );
207
208   GeometryGUI* aGeomGUI = dynamic_cast<GeometryGUI*>( app->module( "Geometry" ) );
209   connect( aGeomGUI, SIGNAL( DimensionsUpdated( const QString& ) ),
210            this, SLOT( updateDimensionBranch( const QString& ) ) );
211   connect( aGeomGUI, SIGNAL( SignalAnnotationsUpdated( const QString& ) ),
212            this, SLOT( updateAnnotationBranch( const QString& ) ) );
213   connect( aGeomGUI, SIGNAL( SignalTextTreeRenameObject( const QString& ) ),
214            this, SLOT( updateObjectName( const QString& ) ) );
215
216   connect( this, SIGNAL( itemClicked( QTreeWidgetItem*, int) ), 
217            this, SLOT( onItemClicked( QTreeWidgetItem*, int ) ) );
218   connect( myStudy, SIGNAL( objVisibilityChanged( QString, Qtx::VisibilityState ) ),
219          this, SLOT( onUpdateVisibilityColumn( QString, Qtx::VisibilityState ) ) );
220 }
221
222 //=================================================================================
223 // function : Destructor
224 // purpose  :
225 //=================================================================================
226 GEOMGUI_TextTreeWdg::~GEOMGUI_TextTreeWdg()
227 {
228   //std::cout<<"~GEOMGUI_TextTreeWdg"<<std::endl;
229 }
230
231 //=================================================================================
232 // function : createActions
233 // purpose  : Create context popup menu actions.
234 //=================================================================================
235 void GEOMGUI_TextTreeWdg::createActions()
236 {
237   QAction* a = new QAction( tr( "MEN_DISPLAY" ), this );
238   a->setIcon( myVisibleIcon );
239   myActions.insert( GEOMOp::OpShow, a );
240   
241   QAction* b = new QAction( tr( "MEN_ERASE" ), this );
242   b->setIcon( myInvisibleIcon );
243   myActions.insert( GEOMOp::OpHide, b );
244 }
245
246 //=================================================================================
247 // function : updateTree
248 // purpose  : Rebuild branches of objects and remove objects if there are no more annotations
249 //            for it
250 //=================================================================================
251 void GEOMGUI_TextTreeWdg::updateTree()
252 {
253   myStudy = dynamic_cast<SalomeApp_Study*>( SUIT_Session::session()->activeApplication()->activeStudy() );
254   _PTR(Study) aDSStudy = myStudy->studyDS();
255   if ( aDSStudy ) {
256     _PTR(SComponent) SC ( aDSStudy->FindComponent( "GEOM" ) );
257     if ( SC ) {
258       _PTR(ChildIterator) anIter ( aDSStudy->NewChildIterator( SC ) );
259       anIter->InitEx( true );
260       QList<QString> aDimensionObjEntries = getObjects( DimensionShape ).keys();
261       QList<QString> anAnnotationObjEntries = getObjects( AnnotationShape ).keys();
262       while( anIter->More() ) {
263         _PTR(SObject) valSO ( anIter->Value() );
264         _PTR(SObject) refSO;
265         if ( !valSO->ReferencedObject( refSO ) ) {
266           // update tree of object's dimensions
267           QString anEntry = valSO->GetID().c_str();
268           updateBranches( anEntry );
269           aDimensionObjEntries.removeAll( anEntry );
270           anAnnotationObjEntries.removeAll( anEntry );
271         }
272         anIter->Next();
273       }
274       foreach ( QString entry, aDimensionObjEntries ) {
275         removeBranch( DimensionShape, entry, true );
276       }
277       foreach ( QString entry, anAnnotationObjEntries ) {
278         removeBranch( AnnotationShape, entry, true );
279       }
280     }
281   }
282 }
283
284 //=================================================================================
285 // function : updateBranches
286 // purpose  : Rebuild branches for object of the given entry
287 //=================================================================================
288 void GEOMGUI_TextTreeWdg::updateBranches( const QString& theEntry )
289 {
290   updateDimensionBranch( theEntry );
291   updateAnnotationBranch( theEntry );
292 }
293
294 //=================================================================================
295 // function : updateDimensionBranch
296 // purpose  : Rebuild branch of dimension type for object of the given entry
297 //=================================================================================
298 void GEOMGUI_TextTreeWdg::updateDimensionBranch( const QString& theEntry )
299 {
300   fillBranch( DimensionShape, theEntry );
301 }
302
303 //=================================================================================
304 // function : updateAnnotationBranch
305 // purpose  : Rebuild branch of annotation type for object of the given entry
306 //=================================================================================
307 void GEOMGUI_TextTreeWdg::updateAnnotationBranch( const QString& theEntry )
308 {
309   fillBranch( AnnotationShape, theEntry );
310 }
311
312 //=================================================================================
313 // function : updateObjectName
314 // purpose  : Find name of the given object and set the name for corresponded tree item
315 //=================================================================================
316 void GEOMGUI_TextTreeWdg::updateObjectName( const QString& theEntry )
317 {
318   QTreeWidgetItem* anObjectItem = 0;
319
320   QHash<QString, QTreeWidgetItem*> anObjects = getObjects( DimensionShape );
321   if ( anObjects.contains( theEntry ) )
322     anObjectItem = anObjects.value( theEntry );
323   else {
324     anObjects = getObjects( AnnotationShape );
325     if ( anObjects.contains( theEntry ) )
326       anObjectItem = anObjects.value( theEntry );
327   }
328   if ( !anObjectItem )
329     return;
330
331   myStudy = dynamic_cast<SalomeApp_Study*>( SUIT_Session::session()->activeApplication()->activeStudy() );
332   if ( myStudy ) {
333     _PTR(Study) aStudyDS = myStudy->studyDS();
334     if ( aStudyDS ) {
335       _PTR(SObject) anObject( aStudyDS->FindObjectID( theEntry.toStdString() ) );
336       if ( anObject.get() )
337         anObjectItem->setText( 0, anObject->GetName().c_str() );
338     }
339   }
340 }
341
342 //=================================================================================
343 // function : fillBranch
344 // purpose  :
345 //=================================================================================
346 void GEOMGUI_TextTreeWdg::fillBranch( const BranchType& theBranchType, const QString& theEntry )
347 {
348   myStudy = dynamic_cast<SalomeApp_Study*>( SUIT_Session::session()->activeApplication()->activeStudy() );
349
350   if ( myStudy && !theEntry.isEmpty() ) {
351     QSharedPointer<VisualProperty> aProp = getVisualProperty( theBranchType, myStudy, theEntry.toStdString() );
352     if ( !aProp ) {
353       return;
354     }
355
356     _PTR(Study) aStudyDS = myStudy->studyDS();
357     if ( aStudyDS ) {
358       _PTR(SObject) obj( aStudyDS->FindObjectID( theEntry.toStdString() ) );
359       const QString aName = obj->GetName().c_str();
360       const int nbProps = aProp->GetNumber();
361
362       QTreeWidgetItem* objectItem = itemFromEntry( theBranchType, theEntry );
363       if ( objectItem ) {
364         removeBranch( theBranchType, theEntry, nbProps > 0 ? false : true );
365       }
366       QStringList itemName;
367       if ( nbProps > 0 ) {
368         itemName << aName << "";
369         if ( !objectItem ) {
370           QTreeWidgetItem* aPropRootItem = getPropertyRootItem( theBranchType );
371
372           objectItem = new QTreeWidgetItem( aPropRootItem, itemName );
373           objectItem->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled );
374           objectItem->setData( 1, Qt::UserRole, theEntry );
375           aPropRootItem->addChild( objectItem );
376           getObjects( theBranchType ).insert( theEntry, objectItem );
377           if ( aPropRootItem->childCount() == 1 )
378             aPropRootItem->setExpanded( true );
379         }
380         for ( int anIt = 0; anIt < nbProps; ++anIt ) {
381           const QString aPropName  = aProp->GetName( anIt );
382           const bool isVisible = aProp->GetIsVisible( anIt );
383           QTreeWidgetItem* anItem = new QTreeWidgetItem;
384           anItem->setText( 0, aPropName );
385           anItem->setIcon( 1, isVisible ? myVisibleIcon : myInvisibleIcon );
386           anItem->setData( 0, Qt::UserRole, anIt );
387           anItem->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled );
388           objectItem->addChild( anItem );
389         }
390       }
391     }
392   }
393 }
394
395 //=================================================================================
396 // function : getVisualProperty
397 // purpose  :
398 //=================================================================================
399 QSharedPointer<GEOMGUI_TextTreeWdg::VisualProperty>
400   GEOMGUI_TextTreeWdg::getVisualProperty( const BranchType& theBranchType,
401                                           SalomeApp_Study* theStudy,
402                                           const std::string& theEntry )
403 {
404   switch ( theBranchType )
405   {
406     case DimensionShape  : return QSharedPointer<VisualProperty>( new DimensionsProperty( theEntry ) );
407     case AnnotationShape : return QSharedPointer<VisualProperty>( new AnnotationsProperty( theEntry ) );
408     default: break;
409   }
410   return QSharedPointer<VisualProperty>();
411 }
412
413 //=================================================================================
414 // function : removeBranch
415 // purpose  :
416 //=================================================================================
417 void GEOMGUI_TextTreeWdg::removeBranch( const BranchType& theBranchType, const QString& theEntry,
418                                         bool force )
419 {
420   QTreeWidgetItem* objectItem = itemFromEntry( theBranchType, theEntry );
421   if ( !objectItem )
422     return;
423   qDeleteAll( objectItem->takeChildren() );
424   if ( force ) {
425     QTreeWidgetItem* aPropRootItem = getPropertyRootItem( theBranchType );
426     aPropRootItem->removeChild( objectItem );
427     getObjects( theBranchType ).remove( theEntry );
428   }
429 }
430
431 //=================================================================================
432 // function : onItemClicked()
433 // purpose  : called when tree item was clicked
434 //=================================================================================
435 void GEOMGUI_TextTreeWdg::onItemClicked( QTreeWidgetItem* theItem, int theColumn )
436 {
437   if( theColumn != 1 || theItem->icon( 1 ).isNull() || theItem->isDisabled() )
438     return;
439   
440   std::string anEntry = entryFromItem( theItem->parent() ).toStdString();
441   BranchType aBranchType = branchTypeFromItem( theItem );
442
443   int aDimIndex = idFromItem( theItem );
444
445   QSharedPointer<VisualProperty> aProp = getVisualProperty( aBranchType, myStudy, anEntry );
446
447   SalomeApp_Application* anApp =
448     dynamic_cast< SalomeApp_Application* >( SUIT_Session::session()->activeApplication() );
449   GeometryGUI* aModule = dynamic_cast<GeometryGUI*>(anApp->activeModule());
450   if ( aProp->GetIsVisible( aDimIndex ) ) {
451     aModule->GetAnnotationMgr()->Erase(anEntry.c_str(), aDimIndex);
452     theItem->setIcon( 1, myInvisibleIcon );
453   } else {
454     aModule->GetAnnotationMgr()->Display(anEntry.c_str(), aDimIndex);
455
456     theItem->setIcon( 1, myVisibleIcon );
457   }
458   redisplay( anEntry.c_str() );
459 }
460
461 //=================================================================================
462 // function : idFromItem
463 // purpose  :
464 //=================================================================================
465 int GEOMGUI_TextTreeWdg::idFromItem( QTreeWidgetItem* theItem )
466 {
467   if ( !theItem )
468     return -1;
469
470   bool isIdOK = false;
471   const int anId = theItem->data( 0, Qt::UserRole ).toInt( &isIdOK );
472
473   return isIdOK ? anId : -1;
474 }
475
476 //=================================================================================
477 // function : entryFromItem
478 // purpose  :
479 //=================================================================================
480 QString GEOMGUI_TextTreeWdg::entryFromItem( QTreeWidgetItem* theShapeItem ) const
481 {
482   if ( !theShapeItem )
483     return "";
484
485   return theShapeItem->data( 1, Qt::UserRole ).toString();
486 }
487
488 //=================================================================================
489 // function : itemFromEntry
490 // purpose  :
491 //=================================================================================
492 QTreeWidgetItem* GEOMGUI_TextTreeWdg::itemFromEntry( const BranchType& theBranchType, QString theEntry )
493 {
494   if ( theEntry.isEmpty() )
495     return 0;
496
497   return getObjects(theBranchType).value( theEntry, 0 );
498 }
499
500 //=================================================================================
501 // function : onUpdateVisibilityColumn
502 // purpose  : Update visible state of icons of entry items.
503 //=================================================================================
504 void GEOMGUI_TextTreeWdg::onUpdateVisibilityColumn( QString theEntry, Qtx::VisibilityState theState )
505 {
506   // dimension property branch
507   updateVisibilityColumn( DimensionShape, theEntry, theState );
508
509   // annotation property branch
510   updateVisibilityColumn( AnnotationShape, theEntry, theState );
511 }
512
513 //=================================================================================
514 // function : updateVisibilityColumn
515 // purpose  : Update icons of dimension items.
516 //=================================================================================
517 void GEOMGUI_TextTreeWdg::updateVisibilityColumn( const BranchType& theBranchType, QString theEntry,
518                                                   Qtx::VisibilityState theState )
519 {
520   QTreeWidgetItem* anItem = itemFromEntry( theBranchType, theEntry );
521   if ( !anItem )
522     return;
523   anItem->setDisabled( theState != Qtx::ShownState );
524   QTreeWidgetItem* aChildItem;
525
526   QSharedPointer<VisualProperty> aProp = getVisualProperty( theBranchType, myStudy, theEntry.toStdString() );
527
528   for ( int i=0; i < anItem->childCount(); i++ ) {
529     aChildItem = anItem->child( i );
530     if ( theState == Qtx::ShownState ) {
531       if ( aProp->GetNumber() == 0 )
532         continue;
533       aChildItem->setIcon( 1, aProp->GetIsVisible( idFromItem( aChildItem ) ) ? myVisibleIcon
534                                                                               : myInvisibleIcon );
535       aChildItem->setDisabled( false );
536     } else {
537       aChildItem->setIcon( 1, QIcon() );
538       aChildItem->setDisabled( true );
539     }
540   }
541 }
542
543 //=================================================================================
544 // function : showContextMenu
545 // purpose  : 
546 //=================================================================================
547 void GEOMGUI_TextTreeWdg::showContextMenu( const QPoint& pos )
548 {
549   CAM_Application* anApp = dynamic_cast<CAM_Application*>(myStudy->application());
550   GeometryGUI* aModule = dynamic_cast<GeometryGUI*>(anApp->activeModule());
551
552   QMenu aMenu;
553   if ( !selectedItems().isEmpty() && selectedItems().count() == 1 ) {
554     QTreeWidgetItem* anItem = selectedItems().first();
555     QString anEntry = entryFromItem( anItem->parent() );
556     if ( !anEntry.isEmpty() ) {
557       BranchType aBranchType = branchTypeFromItem( anItem );
558       QSharedPointer<VisualProperty>
559         aProp = getVisualProperty( aBranchType, myStudy, anEntry.toStdString() );
560
561       if ( aProp->GetNumber() == 0 )
562         return;
563       // Edit annotation action
564       QAction* anEditAction = aModule->action(GEOMOp::OpEditAnnotation);
565       if ( anEditAction )
566         aMenu.addAction( anEditAction );
567       QAction* aDeleteAction = aModule->action(GEOMOp::OpDeleteAnnotation);
568       if ( aDeleteAction )
569         aMenu.addAction( aDeleteAction );
570       // Show/Hide actions
571       if ( aProp->GetIsVisible( idFromItem( anItem ) ) )
572         aMenu.addAction( myActions[GEOMOp::OpHide] );
573       else
574         aMenu.addAction( myActions[GEOMOp::OpShow] );
575     }
576   }
577
578   if (selectedItems().isEmpty() && currentItem()) {
579     QTreeWidgetItem* anItem = currentItem();
580     bool aShowAll = false;
581     if (anItem == getPropertyRootItem(AnnotationShape))
582       aShowAll = true;
583     else {
584       QHash<QString, QTreeWidgetItem*> anObjects = getObjects( AnnotationShape );
585       QHash<QString, QTreeWidgetItem*>::const_iterator anIt = anObjects.begin(),
586                                                        aLast = anObjects.end();
587       for (; anIt != aLast && !aShowAll; anIt++) {
588         aShowAll = anIt.value() == anItem;
589       }
590     }
591     if (aShowAll) {
592       aMenu.addAction( aModule->action(GEOMOp::OpShowAllAnnotations) );
593       aMenu.addAction( aModule->action(GEOMOp::OpHideAllAnnotations) );
594     }
595   }
596   QAction* selPopupItem = aMenu.exec( viewport()->mapToGlobal(pos) );
597
598   if ( selPopupItem == myActions[GEOMOp::OpShow] ||
599        selPopupItem == myActions[GEOMOp::OpHide] ) {
600     bool isVisible = selPopupItem == myActions[GEOMOp::OpShow];
601     foreach ( QTreeWidgetItem* anItem, selectedItems() ) {
602       setVisibility( anItem, isVisible );
603     }
604   }
605 }
606
607 //=================================================================================
608 // function : setVisibility
609 // purpose  : set item visible
610 //=================================================================================
611 void GEOMGUI_TextTreeWdg::setVisibility( QTreeWidgetItem* theItem, bool theVisibility )
612 {
613   BranchType aBranchType = branchTypeFromItem( theItem );
614   if ( theItem == myDimensionsItem ||
615        theItem == myAnnotationsItem ) {
616
617     QTreeWidgetItem* anItem;
618     foreach ( QString entry, getObjects( aBranchType ).keys() ) {
619       anItem = itemFromEntry( aBranchType, entry );
620       if ( !anItem->isDisabled() )
621         setAllShapeItemsVisibility( aBranchType, entry, theVisibility );
622     }
623     return;
624   }
625   else {
626     if ( !theItem->isDisabled() && !theItem->parent()->isSelected() ) {
627       QString anEntry = entryFromItem( theItem );
628       if ( !anEntry.isEmpty() ) {
629         // it is a shape item
630         setAllShapeItemsVisibility( aBranchType, anEntry, theVisibility );
631       } else {
632         // it is a dimension item
633         anEntry = entryFromItem( theItem->parent() );
634         setShapeItemVisibility( aBranchType, anEntry, theItem, theVisibility );
635       }
636     }
637   }
638 }
639
640 //=================================================================================
641 // function : setAllShapeItemsVisibility
642 // purpose  : 
643 //=================================================================================
644 void GEOMGUI_TextTreeWdg::setAllShapeItemsVisibility( const BranchType& theBranchType,
645                                                       const QString& theEntry,
646                                                       const bool theVisibility )
647 {
648   QSharedPointer<VisualProperty>
649     aProp = getVisualProperty( theBranchType, myStudy, theEntry.toStdString() );
650
651   QTreeWidgetItem* anItem = itemFromEntry( theBranchType, theEntry );
652   QTreeWidgetItem* aChildItem;
653   for ( int i=0; i < anItem->childCount(); i++ ) {
654     aChildItem = anItem->child( i );
655     setShapeItemVisibility( aProp, aChildItem, theVisibility );
656   }
657
658   aProp->Save();
659
660   redisplay( theEntry );
661 }
662
663 //=================================================================================
664 // function : setShapeItemVisibility
665 // purpose  : 
666 //=================================================================================
667 void GEOMGUI_TextTreeWdg::setShapeItemVisibility( const BranchType& theBranchType,
668                                                   const QString& theEntry,
669                                                   QTreeWidgetItem* theWidgetItem,
670                                                   const bool theVisibility )
671 {
672   QSharedPointer<VisualProperty>
673     aProp = getVisualProperty( theBranchType, myStudy, theEntry.toStdString() );
674
675   if ( setShapeItemVisibility( aProp, theWidgetItem, theVisibility ) ) {
676     aProp->Save();
677     redisplay( theEntry );
678   }
679 }
680
681 //=================================================================================
682 // function : setShapeItemVisibility
683 // purpose  : 
684 //=================================================================================
685 void GEOMGUI_TextTreeWdg::updateVisibility()
686 {
687   //QList<QString> aDimensionObjEntries = getObjects( DimensionShape ).keys();
688   BranchType aBranchType = AnnotationShape;
689
690   QList<QString> anAnnotationObjEntries = getObjects( aBranchType ).keys();
691
692   QTreeWidgetItem* anEntryItem;
693   foreach ( QString anEntry, getObjects( aBranchType ).keys() )
694   {
695     anEntryItem = itemFromEntry( aBranchType, anEntry );
696
697     QTreeWidgetItem* anItem;
698     for ( int i = 0; i < anEntryItem->childCount(); i++ ) {
699       anItem = anEntryItem->child( i );
700       int aDimIndex = idFromItem( anItem );
701       QSharedPointer<VisualProperty> aProp = getVisualProperty( aBranchType, myStudy,
702                                                                 anEntry.toStdString() );
703       bool isItemVisible = aProp->GetIsVisible( aDimIndex );
704       anItem->setIcon( 1, isItemVisible ? myVisibleIcon : myInvisibleIcon );
705     }
706
707     redisplay( anEntry );
708   }
709 }
710
711 //=================================================================================
712 // function : getSelected
713 // purpose  :
714 //=================================================================================
715 void GEOMGUI_TextTreeWdg::getSelected( QMap<QString, QList<int> >& theAnnotations )
716 {
717   theAnnotations.clear();
718
719   QItemSelectionModel* aSelectionModel = selectionModel();
720   QModelIndexList aSelectedIndices = aSelectionModel->selectedIndexes();
721
722   for (int i = 0, aNbItems = aSelectedIndices.size(); i < aNbItems; i++) {
723     QTreeWidgetItem* anItem = itemFromIndex( aSelectedIndices[i] );
724     if ( !anItem )
725       continue;
726     QString anEntry = entryFromItem( anItem->parent() );
727     int aDimIndex = idFromItem( anItem );
728     if ( aDimIndex < 0 )
729       continue;
730
731     if ( theAnnotations.contains( anEntry ) )
732       theAnnotations[anEntry].append( aDimIndex );
733     else {
734       QList<int> anIndices;
735       anIndices.append( aDimIndex );
736       theAnnotations[anEntry] = anIndices;
737     }
738   }
739 }
740
741 //=================================================================================
742 // function : setSelected
743 // purpose  :
744 //=================================================================================
745 void GEOMGUI_TextTreeWdg::setSelected( const QMap<QString, QList<int> >& theAnnotations )
746 {
747   QItemSelectionModel* aSelectionModel = selectionModel();
748   aSelectionModel->clearSelection();
749
750   QMap<QString, QList<int> >::const_iterator anIt = theAnnotations.begin(),
751                                              aLast = theAnnotations.end();
752   BranchType aBranchType = AnnotationShape;
753   for ( ; anIt != aLast; anIt++ ) {
754     QString anEntry = anIt.key();
755     QTreeWidgetItem* anEntryItem = itemFromEntry( aBranchType, anEntry );
756     if ( !anEntryItem )
757       continue;
758
759     QList<int> anAnnotationIds = anIt.value();
760     QTreeWidgetItem* anItem;
761     for ( int i = 0; i < anEntryItem->childCount(); i++ ) {
762       anItem = anEntryItem->child( i );
763       int aDimIndex = idFromItem( anItem );
764       if ( anAnnotationIds.contains( aDimIndex ) ) {
765         QModelIndex anIndex = indexFromItem( anItem );
766         aSelectionModel->select( anIndex, QItemSelectionModel::Select );
767       }
768     }
769   }
770 }
771
772 //=================================================================================
773 // function : getAllEntries
774 // purpose  :
775 //=================================================================================
776 QList<QString> GEOMGUI_TextTreeWdg::getAllEntries( const BranchType& theBranchType )
777 {
778   return getObjects( theBranchType ).keys();
779 }
780
781 //=================================================================================
782 // function : getSingleSelectedObject
783 // purpose  :
784 //=================================================================================
785 QString GEOMGUI_TextTreeWdg::getSingleSelectedObject()
786 {
787   QString anEntry;
788   QTreeWidgetItem* anItem = currentItem();
789   if (anItem) {
790     QHash<QString, QTreeWidgetItem*> anObjects = getObjects( AnnotationShape );
791     QHash<QString, QTreeWidgetItem*>::const_iterator anIt = anObjects.begin(),
792                                                      aLast = anObjects.end();
793     for (; anIt != aLast; anIt++) {
794       if ( anIt.value() == anItem ) {
795         anEntry = anIt.key();
796         break;
797       }
798     }
799   }
800   return anEntry;
801 }
802
803 //=================================================================================
804 // function : setShapeItemVisibility
805 // purpose  :
806 //=================================================================================
807 bool GEOMGUI_TextTreeWdg::setShapeItemVisibility( QSharedPointer<VisualProperty>& theProps,
808                                                   QTreeWidgetItem* theWidgetItem,
809                                                   const bool theVisibility )
810 {
811   int aDimIndex = idFromItem( theWidgetItem );
812   if ( theProps->GetNumber() == 0 
813     || theProps->GetIsVisible( aDimIndex ) == theVisibility ) {
814     return false;
815   }
816   theProps->SetIsVisible( aDimIndex, theVisibility );
817
818   theWidgetItem->setIcon( 1, theVisibility ? myVisibleIcon : myInvisibleIcon );
819
820   return true;
821 }
822
823 //=================================================================================
824 // function : redisplay
825 // purpose  : 
826 //=================================================================================
827 void GEOMGUI_TextTreeWdg::redisplay( QString theEntry )
828 {
829   Handle(SALOME_InteractiveObject) io = new SALOME_InteractiveObject( theEntry.toLatin1().constData(), "GEOM", "TEMP_IO" );
830   myDisplayer.Redisplay( io );
831 }
832
833 //=================================================================================
834 // function : getPropertyRootItem
835 // purpose  :
836 //=================================================================================
837 QTreeWidgetItem* GEOMGUI_TextTreeWdg::getPropertyRootItem( const BranchType& theBranchType )
838 {
839   return (theBranchType == DimensionShape) ? myDimensionsItem : myAnnotationsItem;
840 }
841
842 //=================================================================================
843 // function : getObjects
844 // purpose  :
845 //=================================================================================
846 QHash<QString, QTreeWidgetItem*>& GEOMGUI_TextTreeWdg::getObjects( const BranchType& theBranchType )
847 {
848   return (theBranchType == DimensionShape) ? myDimensionObjects : myAnnotationObjects;
849 }
850
851 //=================================================================================
852 // function : branchTypeFromItem
853 // purpose  :
854 //=================================================================================
855 GEOMGUI_TextTreeWdg::BranchType GEOMGUI_TextTreeWdg::branchTypeFromItem( QTreeWidgetItem* theItem )
856 {
857   BranchType aBranchType = DimensionShape;
858
859   bool aBranchTypeFound = false;
860   QTreeWidgetItem* anItem = theItem;
861   while( !aBranchTypeFound && anItem ) {
862     if ( anItem == myDimensionsItem ||
863          anItem == myAnnotationsItem) {
864       aBranchTypeFound = true;
865       aBranchType = (anItem == myDimensionsItem) ? DimensionShape : AnnotationShape;
866     }
867     else {
868       anItem = anItem->parent();
869     }
870   }
871
872   return aBranchType;
873 }