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