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 header()->setResizeMode( 1, QHeaderView::ResizeToContents );
78 QStringList rootNames;
79 rootNames << tr("GEOM_DIMENSIONS") << "";
80 myDimensionsItem = new QTreeWidgetItem( this, rootNames );
81 myDimensionsItem->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled );
82 addTopLevelItem( myDimensionsItem );
84 // get a free dockable window id
86 while( app->dockWindow( myWindowID ))
91 setContextMenuPolicy( Qt::CustomContextMenu );
92 connect( this, SIGNAL( customContextMenuRequested(const QPoint&) ),
93 this, SLOT( showContextMenu(const QPoint&) ) );
95 connect( myStudy, SIGNAL( objVisibilityChanged( QString, Qtx::VisibilityState ) ),
96 this, SLOT( updateVisibilityColumn( QString, Qtx::VisibilityState ) ) );
97 connect( app->objectBrowser(), SIGNAL( updated() ), this, SLOT( updateTree() ) );
98 GeometryGUI* aGeomGUI = dynamic_cast<GeometryGUI*>( app->module( "Geometry" ) );
99 connect( aGeomGUI, SIGNAL( DimensionsUpdated( const QString& ) ), this, SLOT( updateBranch( const QString& ) ) );
100 connect( this, SIGNAL( itemClicked( QTreeWidgetItem*, int) ),
101 this, SLOT( onItemClicked( QTreeWidgetItem*, int ) ) );
105 GEOMGUI_TextTreeWdg::~GEOMGUI_TextTreeWdg()
107 //std::cout<<"~GEOMGUI_TextTreeWdg"<<std::endl;
110 //=================================================================================
111 // function : createActions
112 // purpose : Create context popup menu actions.
113 //=================================================================================
114 void GEOMGUI_TextTreeWdg::createActions()
116 QAction* a = new QAction( tr( "MEN_DISPLAY" ), this );
117 a->setIcon( myVisibleIcon );
118 myActions.insert( GEOMOp::OpShow, a );
120 QAction* b = new QAction( tr( "MEN_ERASE" ), this );
121 b->setIcon( myInvisibleIcon );
122 myActions.insert( GEOMOp::OpHide, b );
125 //=================================================================================
126 // function : updateTree
128 //=================================================================================
129 void GEOMGUI_TextTreeWdg::updateTree()
131 myStudy = dynamic_cast<SalomeApp_Study*>( SUIT_Session::session()->activeApplication()->activeStudy() );
132 _PTR(Study) aDSStudy = myStudy->studyDS();
134 _PTR(SComponent) SC ( aDSStudy->FindComponent( "GEOM" ) );
136 _PTR(ChildIterator) anIter ( aDSStudy->NewChildIterator( SC ) );
137 anIter->InitEx( true );
138 QList<QString> objEntries = myObjects.keys();
139 while( anIter->More() ) {
140 _PTR(SObject) valSO ( anIter->Value() );
142 if ( !valSO->ReferencedObject( refSO ) ) {
143 // update tree of object's dimensions
144 QString anEntry = valSO->GetID().c_str();
145 updateBranch( anEntry );
146 objEntries.removeAll( anEntry );
150 foreach (QString entry, objEntries) {
151 removeBranch( entry, true );
157 //=================================================================================
158 // function : updateBranch
160 //=================================================================================
161 void GEOMGUI_TextTreeWdg::updateBranch( const QString& theEntry )
163 myStudy = dynamic_cast<SalomeApp_Study*>( SUIT_Session::session()->activeApplication()->activeStudy() );
165 _PTR(Study) aStudyDS = myStudy->studyDS();
167 _PTR(SObject) obj( aStudyDS->FindObjectID( theEntry.toStdString() ) );
168 QString aName = obj->GetName().c_str();
170 GEOMGUI_DimensionProperty aProp;
171 aProp.LoadFromAttribute( myStudy, theEntry.toStdString() );
172 int nbProps = aProp.GetNumber();
174 QTreeWidgetItem* objectItem = itemFromEntry( theEntry );
176 removeBranch( theEntry, nbProps > 0 ? false : true );
178 QStringList itemName;
180 itemName << aName << "";
182 objectItem = new QTreeWidgetItem( myDimensionsItem, itemName );
183 objectItem->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled );
184 objectItem->setData( 1, Qt::UserRole, theEntry );
185 myDimensionsItem->addChild( objectItem );
186 myObjects.insert( theEntry, objectItem );
187 if ( myDimensionsItem->childCount() == 1 )
188 myDimensionsItem->setExpanded( true );
190 bool isDisplayed = myDisplayer.IsDisplayed( theEntry );
191 // read dimension records from property
192 for ( int anIt = 0; anIt < aProp.GetNumber(); ++anIt )
194 QString aName = aProp.GetName( anIt );
195 bool isVisible = aProp.IsVisible( anIt );
197 QTreeWidgetItem* anItem = new QTreeWidgetItem;
198 anItem->setText( 0, aName );
199 // if ( isDisplayed )
200 anItem->setIcon( 1, isVisible ? myVisibleIcon : myInvisibleIcon );
201 anItem->setData( 0, Qt::UserRole, anIt );
202 anItem->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled );
203 objectItem->addChild( anItem );
210 //=================================================================================
211 // function : removeBranch
213 //=================================================================================
214 void GEOMGUI_TextTreeWdg::removeBranch( const QString& theEntry, bool force )
216 QTreeWidgetItem* objectItem = itemFromEntry( theEntry );
219 qDeleteAll( objectItem->takeChildren() );
221 myDimensionsItem->removeChild( objectItem );
222 myObjects.remove( theEntry );
226 //=================================================================================
227 // function : onItemClicked()
228 // purpose : called when tree item was clicked
229 //=================================================================================
230 void GEOMGUI_TextTreeWdg::onItemClicked( QTreeWidgetItem* theItem, int theColumn )
232 if( theColumn != 1 || theItem->icon( 1 ).isNull() || theItem->isDisabled() )
235 std::string anEntry = entryFromItem( theItem->parent() ).toStdString();
236 int aDimIndex = idFromItem( theItem );
237 GEOMGUI_DimensionProperty aProp;
238 aProp.LoadFromAttribute( myStudy, anEntry );
239 if ( aProp.IsVisible( aDimIndex ) ) {
240 aProp.SetVisible( aDimIndex, false );
241 theItem->setIcon( 1, myInvisibleIcon );
243 aProp.SetVisible( aDimIndex, true );
244 theItem->setIcon( 1, myVisibleIcon );
246 aProp.SaveToAttribute( myStudy, anEntry );
247 redisplay( anEntry.c_str() );
250 //=================================================================================
251 // function : idFromItem
253 //=================================================================================
254 int GEOMGUI_TextTreeWdg::idFromItem( QTreeWidgetItem* theItem )
260 const int anId = theItem->data( 0, Qt::UserRole ).toInt( &isIdOK );
262 return isIdOK ? anId : -1;
265 //=================================================================================
266 // function : entryFromItem
268 //=================================================================================
269 QString GEOMGUI_TextTreeWdg::entryFromItem( QTreeWidgetItem* theShapeItem )
274 return theShapeItem->data( 1, Qt::UserRole ).toString();
277 //=================================================================================
278 // function : itemFromEntry
280 //=================================================================================
281 QTreeWidgetItem* GEOMGUI_TextTreeWdg::itemFromEntry( QString theEntry )
283 if ( theEntry.isEmpty() )
286 return myObjects.value( theEntry, 0 );
289 //=================================================================================
290 // function : updateVisibilityColumn
291 // purpose : Update icons of dimension items.
292 //=================================================================================
293 void GEOMGUI_TextTreeWdg::updateVisibilityColumn( QString theEntry, Qtx::VisibilityState theState )
295 QTreeWidgetItem* anItem = itemFromEntry( theEntry );
298 anItem->setDisabled( theState != Qtx::ShownState );
299 QTreeWidgetItem* aChildItem;
300 GEOMGUI_DimensionProperty aProp;
301 for ( int i=0; i < anItem->childCount(); i++ ) {
302 aChildItem = anItem->child( i );
303 if ( theState == Qtx::ShownState ) {
304 aProp.LoadFromAttribute( myStudy, theEntry.toStdString() );
305 if ( aProp.GetNumber() == 0 )
307 aChildItem->setIcon( 1, aProp.IsVisible( idFromItem( aChildItem ) ) ? myVisibleIcon : myInvisibleIcon );
308 aChildItem->setDisabled( false );
310 aChildItem->setIcon( 1, QIcon() );
311 aChildItem->setDisabled( true );
316 //=================================================================================
317 // function : showContextMenu
319 //=================================================================================
320 void GEOMGUI_TextTreeWdg::showContextMenu( const QPoint& pos )
322 if ( selectedItems().isEmpty() )
325 aMenu.addAction( myActions[GEOMOp::OpShow] );
326 aMenu.addAction( myActions[GEOMOp::OpHide] );
327 if ( selectedItems().count() == 1 ) {
328 QTreeWidgetItem* anItem = selectedItems().first();
329 QString anEntry = entryFromItem( anItem->parent() );
330 if ( !anEntry.isEmpty() ) {
331 GEOMGUI_DimensionProperty aProp;
332 aProp.LoadFromAttribute( myStudy, anEntry.toStdString() );
333 if ( aProp.GetNumber() == 0 )
336 if ( aProp.IsVisible( idFromItem( anItem ) ) )
337 aMenu.addAction( myActions[GEOMOp::OpHide] );
339 aMenu.addAction( myActions[GEOMOp::OpShow] );
342 QAction* selPopupItem = aMenu.exec( viewport()->mapToGlobal(pos) );
343 if ( selPopupItem == myActions[GEOMOp::OpShow] )
344 setVisibility( true );
345 else if ( selPopupItem == myActions[GEOMOp::OpHide] )
346 setVisibility( false );
349 //=================================================================================
350 // function : setVisibility
352 //=================================================================================
353 void GEOMGUI_TextTreeWdg::setVisibility( bool theVisibility )
355 if ( myDimensionsItem->isSelected() ) {
356 // set visibility for all dimensions
357 QTreeWidgetItem* anItem;
358 foreach ( QString entry, myObjects.keys() ) {
359 anItem = itemFromEntry( entry );
360 if ( !anItem->isDisabled() )
361 setShapeDimensionsVisibility( entry, theVisibility );
365 foreach ( QTreeWidgetItem* item, selectedItems() ) {
366 if ( item->isDisabled() || item->parent()->isSelected() )
368 QString anEntry = entryFromItem( item );
369 if ( !anEntry.isEmpty() ) {
370 // it is a shape item
371 setShapeDimensionsVisibility( anEntry, theVisibility );
373 // it is a dimension item
374 anEntry = entryFromItem( item->parent() );
375 setDimensionVisibility( anEntry, item, theVisibility );
380 //=================================================================================
381 // function : setShapeDimensionsVisibility
383 //=================================================================================
384 void GEOMGUI_TextTreeWdg::setShapeDimensionsVisibility( QString theEntry, bool theVisibility )
386 QTreeWidgetItem* anItem = itemFromEntry( theEntry );
387 QTreeWidgetItem* aChildItem;
388 for ( int i=0; i < anItem->childCount(); i++ ) {
389 aChildItem = anItem->child( i );
390 setDimensionVisibility( theEntry, aChildItem, theVisibility );
392 redisplay( theEntry );
395 //=================================================================================
396 // function : setDimensionVisibility
398 //=================================================================================
399 void GEOMGUI_TextTreeWdg::setDimensionVisibility( QString theEntry, QTreeWidgetItem* theDimItem, bool theVisibility )
401 GEOMGUI_DimensionProperty aProp;
402 aProp.LoadFromAttribute( myStudy, theEntry.toStdString() );
403 int aDimIndex = idFromItem( theDimItem );
404 if ( aProp.GetNumber() == 0 || aProp.IsVisible( aDimIndex ) == theVisibility )
406 aProp.SetVisible( aDimIndex, theVisibility );
407 aProp.SaveToAttribute( myStudy, theEntry.toStdString() );
409 theDimItem->setIcon( 1, theVisibility ? myVisibleIcon : myInvisibleIcon );
410 redisplay( theEntry );
413 //=================================================================================
414 // function : redisplay
416 //=================================================================================
417 void GEOMGUI_TextTreeWdg::redisplay( QString theEntry )
419 Handle(SALOME_InteractiveObject) io = new SALOME_InteractiveObject( theEntry.toLatin1().constData(), "GEOM", "TEMP_IO" );
420 myDisplayer.Redisplay( io );