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