1 // Copyright (C) 2015 CEA/DEN, EDF R&D, OPEN CASCADE
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.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // File : GEOMGUI_TextTreeWdg.cxx
20 // Author : Alexander KOVALEV (akl)
22 #include "GEOMGUI_TextTreeWdg.h"
24 #include "GEOMGUI_DimensionProperty.h"
25 #include "GeometryGUI.h"
26 #include "GeometryGUI_Operations.h"
27 #include <GEOM_Constants.h>
28 #include <GEOMUtils.hxx>
31 #include <LightApp_Module.h>
32 #include <SalomeApp_Application.h>
33 #include <SalomeApp_Study.h>
34 #include <SUIT_Desktop.h>
35 #include <SUIT_Session.h>
36 #include <SUIT_ResourceMgr.h>
37 #include <SUIT_DataBrowser.h>
45 #include <QTreeWidget>
46 #include <QHeaderView>
48 #include <QVBoxLayout>
49 #include <QHBoxLayout>
52 GEOMGUI_TextTreeWdg::GEOMGUI_TextTreeWdg( SalomeApp_Application* app )
55 myStudy = dynamic_cast<SalomeApp_Study*>( app->activeStudy() );
56 myDisplayer = GEOM_Displayer( myStudy );
58 SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
59 myVisibleIcon = QIcon( resMgr->loadPixmap( "SUIT", tr( "ICON_DATAOBJ_VISIBLE" ) ) );
60 myInvisibleIcon = QIcon( resMgr->loadPixmap( "SUIT", tr( "ICON_DATAOBJ_INVISIBLE" ) ) );
62 setWindowTitle( tr( "TEXT_TREE_VIEW_TITLE" ) );
63 setObjectName( "geomTextTreeWdg" );
65 setRootIsDecorated( true );
66 setSelectionMode( QAbstractItemView::ExtendedSelection );
67 setAllColumnsShowFocus( true );
68 setUniformRowHeights( true );
70 QStringList columnNames;
71 columnNames << tr("TEXT_TREE_VIEW_NAME") << "";
72 QTreeWidgetItem * headerItem = new QTreeWidgetItem( columnNames );
73 headerItem->setIcon( 1, myVisibleIcon );
74 setHeaderItem ( headerItem );
75 header()->moveSection( 1, 0 );
76 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
77 header()->setResizeMode( 1, QHeaderView::ResizeToContents );
79 header()->setSectionResizeMode( 1, QHeaderView::ResizeToContents );
81 QStringList rootNames;
82 rootNames << tr("GEOM_DIMENSIONS") << "";
83 myDimensionsItem = new QTreeWidgetItem( this, rootNames );
84 myDimensionsItem->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled );
85 addTopLevelItem( myDimensionsItem );
87 // get a free dockable window id
89 while( app->dockWindow( myWindowID ))
94 setContextMenuPolicy( Qt::CustomContextMenu );
95 connect( this, SIGNAL( customContextMenuRequested(const QPoint&) ),
96 this, SLOT( showContextMenu(const QPoint&) ) );
98 connect( myStudy, SIGNAL( objVisibilityChanged( QString, Qtx::VisibilityState ) ),
99 this, SLOT( updateVisibilityColumn( QString, Qtx::VisibilityState ) ) );
100 connect( app->objectBrowser(), SIGNAL( updated() ), this, SLOT( updateTree() ) );
101 GeometryGUI* aGeomGUI = dynamic_cast<GeometryGUI*>( app->module( "Geometry" ) );
102 connect( aGeomGUI, SIGNAL( DimensionsUpdated( const QString& ) ), this, SLOT( updateBranch( const QString& ) ) );
103 connect( this, SIGNAL( itemClicked( QTreeWidgetItem*, int) ),
104 this, SLOT( onItemClicked( QTreeWidgetItem*, int ) ) );
108 GEOMGUI_TextTreeWdg::~GEOMGUI_TextTreeWdg()
110 //std::cout<<"~GEOMGUI_TextTreeWdg"<<std::endl;
113 //=================================================================================
114 // function : createActions
115 // purpose : Create context popup menu actions.
116 //=================================================================================
117 void GEOMGUI_TextTreeWdg::createActions()
119 QAction* a = new QAction( tr( "MEN_DISPLAY" ), this );
120 a->setIcon( myVisibleIcon );
121 myActions.insert( GEOMOp::OpShow, a );
123 QAction* b = new QAction( tr( "MEN_ERASE" ), this );
124 b->setIcon( myInvisibleIcon );
125 myActions.insert( GEOMOp::OpHide, b );
128 //=================================================================================
129 // function : updateTree
131 //=================================================================================
132 void GEOMGUI_TextTreeWdg::updateTree()
134 myStudy = dynamic_cast<SalomeApp_Study*>( SUIT_Session::session()->activeApplication()->activeStudy() );
135 _PTR(Study) aDSStudy = myStudy->studyDS();
137 _PTR(SComponent) SC ( aDSStudy->FindComponent( "GEOM" ) );
139 _PTR(ChildIterator) anIter ( aDSStudy->NewChildIterator( SC ) );
140 anIter->InitEx( true );
141 QList<QString> objEntries = myObjects.keys();
142 while( anIter->More() ) {
143 _PTR(SObject) valSO ( anIter->Value() );
145 if ( !valSO->ReferencedObject( refSO ) ) {
146 // update tree of object's dimensions
147 QString anEntry = valSO->GetID().c_str();
148 updateBranch( anEntry );
149 objEntries.removeAll( anEntry );
153 foreach (QString entry, objEntries) {
154 removeBranch( entry, true );
160 //=================================================================================
161 // function : updateBranch
163 //=================================================================================
164 void GEOMGUI_TextTreeWdg::updateBranch( const QString& theEntry )
166 myStudy = dynamic_cast<SalomeApp_Study*>( SUIT_Session::session()->activeApplication()->activeStudy() );
168 _PTR(Study) aStudyDS = myStudy->studyDS();
170 _PTR(SObject) obj( aStudyDS->FindObjectID( theEntry.toStdString() ) );
171 QString aName = obj->GetName().c_str();
173 GEOMGUI_DimensionProperty aProp;
174 aProp.LoadFromAttribute( myStudy, theEntry.toStdString() );
175 int nbProps = aProp.GetNumber();
177 QTreeWidgetItem* objectItem = itemFromEntry( theEntry );
179 removeBranch( theEntry, nbProps > 0 ? false : true );
181 QStringList itemName;
183 itemName << aName << "";
185 objectItem = new QTreeWidgetItem( myDimensionsItem, itemName );
186 objectItem->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled );
187 objectItem->setData( 1, Qt::UserRole, theEntry );
188 myDimensionsItem->addChild( objectItem );
189 myObjects.insert( theEntry, objectItem );
190 if ( myDimensionsItem->childCount() == 1 )
191 myDimensionsItem->setExpanded( true );
193 bool isDisplayed = myDisplayer.IsDisplayed( theEntry );
194 // read dimension records from property
195 for ( int anIt = 0; anIt < aProp.GetNumber(); ++anIt )
197 QString aName = aProp.GetName( anIt );
198 bool isVisible = aProp.IsVisible( anIt );
200 QTreeWidgetItem* anItem = new QTreeWidgetItem;
201 anItem->setText( 0, aName );
202 // if ( isDisplayed )
203 anItem->setIcon( 1, isVisible ? myVisibleIcon : myInvisibleIcon );
204 anItem->setData( 0, Qt::UserRole, anIt );
205 anItem->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled );
206 objectItem->addChild( anItem );
213 //=================================================================================
214 // function : removeBranch
216 //=================================================================================
217 void GEOMGUI_TextTreeWdg::removeBranch( const QString& theEntry, bool force )
219 QTreeWidgetItem* objectItem = itemFromEntry( theEntry );
222 qDeleteAll( objectItem->takeChildren() );
224 myDimensionsItem->removeChild( objectItem );
225 myObjects.remove( theEntry );
229 //=================================================================================
230 // function : onItemClicked()
231 // purpose : called when tree item was clicked
232 //=================================================================================
233 void GEOMGUI_TextTreeWdg::onItemClicked( QTreeWidgetItem* theItem, int theColumn )
235 if( theColumn != 1 || theItem->icon( 1 ).isNull() || theItem->isDisabled() )
238 std::string anEntry = entryFromItem( theItem->parent() ).toStdString();
239 int aDimIndex = idFromItem( theItem );
240 GEOMGUI_DimensionProperty aProp;
241 aProp.LoadFromAttribute( myStudy, anEntry );
242 if ( aProp.IsVisible( aDimIndex ) ) {
243 aProp.SetVisible( aDimIndex, false );
244 theItem->setIcon( 1, myInvisibleIcon );
246 aProp.SetVisible( aDimIndex, true );
247 theItem->setIcon( 1, myVisibleIcon );
249 aProp.SaveToAttribute( myStudy, anEntry );
250 redisplay( anEntry.c_str() );
253 //=================================================================================
254 // function : idFromItem
256 //=================================================================================
257 int GEOMGUI_TextTreeWdg::idFromItem( QTreeWidgetItem* theItem )
263 const int anId = theItem->data( 0, Qt::UserRole ).toInt( &isIdOK );
265 return isIdOK ? anId : -1;
268 //=================================================================================
269 // function : entryFromItem
271 //=================================================================================
272 QString GEOMGUI_TextTreeWdg::entryFromItem( QTreeWidgetItem* theShapeItem )
277 return theShapeItem->data( 1, Qt::UserRole ).toString();
280 //=================================================================================
281 // function : itemFromEntry
283 //=================================================================================
284 QTreeWidgetItem* GEOMGUI_TextTreeWdg::itemFromEntry( QString theEntry )
286 if ( theEntry.isEmpty() )
289 return myObjects.value( theEntry, 0 );
292 //=================================================================================
293 // function : updateVisibilityColumn
294 // purpose : Update icons of dimension items.
295 //=================================================================================
296 void GEOMGUI_TextTreeWdg::updateVisibilityColumn( QString theEntry, Qtx::VisibilityState theState )
298 QTreeWidgetItem* anItem = itemFromEntry( theEntry );
301 anItem->setDisabled( theState != Qtx::ShownState );
302 QTreeWidgetItem* aChildItem;
303 GEOMGUI_DimensionProperty aProp;
304 for ( int i=0; i < anItem->childCount(); i++ ) {
305 aChildItem = anItem->child( i );
306 if ( theState == Qtx::ShownState ) {
307 aProp.LoadFromAttribute( myStudy, theEntry.toStdString() );
308 if ( aProp.GetNumber() == 0 )
310 aChildItem->setIcon( 1, aProp.IsVisible( idFromItem( aChildItem ) ) ? myVisibleIcon : myInvisibleIcon );
311 aChildItem->setDisabled( false );
313 aChildItem->setIcon( 1, QIcon() );
314 aChildItem->setDisabled( true );
319 //=================================================================================
320 // function : showContextMenu
322 //=================================================================================
323 void GEOMGUI_TextTreeWdg::showContextMenu( const QPoint& pos )
325 if ( selectedItems().isEmpty() )
328 aMenu.addAction( myActions[GEOMOp::OpShow] );
329 aMenu.addAction( myActions[GEOMOp::OpHide] );
330 if ( selectedItems().count() == 1 ) {
331 QTreeWidgetItem* anItem = selectedItems().first();
332 QString anEntry = entryFromItem( anItem->parent() );
333 if ( !anEntry.isEmpty() ) {
334 GEOMGUI_DimensionProperty aProp;
335 aProp.LoadFromAttribute( myStudy, anEntry.toStdString() );
336 if ( aProp.GetNumber() == 0 )
339 if ( aProp.IsVisible( idFromItem( anItem ) ) )
340 aMenu.addAction( myActions[GEOMOp::OpHide] );
342 aMenu.addAction( myActions[GEOMOp::OpShow] );
345 QAction* selPopupItem = aMenu.exec( viewport()->mapToGlobal(pos) );
346 if ( selPopupItem == myActions[GEOMOp::OpShow] )
347 setVisibility( true );
348 else if ( selPopupItem == myActions[GEOMOp::OpHide] )
349 setVisibility( false );
352 //=================================================================================
353 // function : setVisibility
355 //=================================================================================
356 void GEOMGUI_TextTreeWdg::setVisibility( bool theVisibility )
358 if ( myDimensionsItem->isSelected() ) {
359 // set visibility for all dimensions
360 QTreeWidgetItem* anItem;
361 foreach ( QString entry, myObjects.keys() ) {
362 anItem = itemFromEntry( entry );
363 if ( !anItem->isDisabled() )
364 setShapeDimensionsVisibility( entry, theVisibility );
368 foreach ( QTreeWidgetItem* item, selectedItems() ) {
369 if ( item->isDisabled() || item->parent()->isSelected() )
371 QString anEntry = entryFromItem( item );
372 if ( !anEntry.isEmpty() ) {
373 // it is a shape item
374 setShapeDimensionsVisibility( anEntry, theVisibility );
376 // it is a dimension item
377 anEntry = entryFromItem( item->parent() );
378 setDimensionVisibility( anEntry, item, theVisibility );
383 //=================================================================================
384 // function : setShapeDimensionsVisibility
386 //=================================================================================
387 void GEOMGUI_TextTreeWdg::setShapeDimensionsVisibility( QString theEntry, bool theVisibility )
389 QTreeWidgetItem* anItem = itemFromEntry( theEntry );
390 QTreeWidgetItem* aChildItem;
391 for ( int i=0; i < anItem->childCount(); i++ ) {
392 aChildItem = anItem->child( i );
393 setDimensionVisibility( theEntry, aChildItem, theVisibility );
395 redisplay( theEntry );
398 //=================================================================================
399 // function : setDimensionVisibility
401 //=================================================================================
402 void GEOMGUI_TextTreeWdg::setDimensionVisibility( QString theEntry, QTreeWidgetItem* theDimItem, bool theVisibility )
404 GEOMGUI_DimensionProperty aProp;
405 aProp.LoadFromAttribute( myStudy, theEntry.toStdString() );
406 int aDimIndex = idFromItem( theDimItem );
407 if ( aProp.GetNumber() == 0 || aProp.IsVisible( aDimIndex ) == theVisibility )
409 aProp.SetVisible( aDimIndex, theVisibility );
410 aProp.SaveToAttribute( myStudy, theEntry.toStdString() );
412 theDimItem->setIcon( 1, theVisibility ? myVisibleIcon : myInvisibleIcon );
413 redisplay( theEntry );
416 //=================================================================================
417 // function : redisplay
419 //=================================================================================
420 void GEOMGUI_TextTreeWdg::redisplay( QString theEntry )
422 Handle(SALOME_InteractiveObject) io = new SALOME_InteractiveObject( theEntry.toLatin1().constData(), "GEOM", "TEMP_IO" );
423 myDisplayer.Redisplay( io );