Salome HOME
Merge branch 'V7_dev'
[modules/geom.git] / src / GEOMToolsGUI / GEOMToolsGUI_ReduceStudyDlg.cxx
1 // Copyright (C) 2014-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
20 // internal includes
21 #include "GEOMToolsGUI_ReduceStudyDlg.h"
22
23 // GEOM includes
24 #include <GEOMBase.h>
25
26 // GUI includes
27 #include <SUIT_Session.h>
28 #include <SUIT_ResourceMgr.h>
29 #include <SUIT_MessageBox.h>
30
31 #include <LightApp_SelectionMgr.h>
32
33 #include <SalomeApp_Application.h>
34 #include <SalomeApp_Study.h>
35 #include <SALOME_ListIO.hxx>
36
37 // Qt includes
38 #include <QGridLayout>
39 #include <QPushButton>
40 #include <QRadioButton>
41 #include <QHeaderView>
42 #include <QMessageBox>
43
44 GEOMToolsGUI_ReduceStudyDlg::GEOMToolsGUI_ReduceStudyDlg( QWidget* parent )
45 :QDialog( parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint ),
46 myDisplayer(NULL)
47 {
48   SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
49   myVisible = QIcon( resMgr->loadPixmap( "SUIT", tr( "ICON_DATAOBJ_VISIBLE" ) ) );
50   myInvisible = QIcon( resMgr->loadPixmap( "SUIT", tr( "ICON_DATAOBJ_INVISIBLE" ) ) );
51
52   myApp = dynamic_cast< SalomeApp_Application* >( SUIT_Session::session()->activeApplication() );
53   if ( !myApp ) return;
54   SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( myApp->activeStudy() );
55   myStudy = dynamic_cast<SalomeApp_Study*>( myApp->activeStudy() )->studyDS();
56   myDisplayer = GEOM_Displayer( study );
57
58   setWindowTitle( tr( "GEOM_REDUCE_STUDY_TITLE" ) );
59   setAttribute(Qt::WA_DeleteOnClose);
60
61   QGridLayout* topLayout = new QGridLayout( this );
62   topLayout->setMargin( 11 ); topLayout->setSpacing( 6 );
63
64   /**********************   Objects to be kept    **********************/
65   QGroupBox* groupKeptObjects = new QGroupBox( tr( "GEOM_REDUCE_STUDY_KEPT_OBJECTS" ) );
66   QGridLayout* layoutKeptObjects = new QGridLayout( groupKeptObjects );
67   createTreeWidget( myTreeKeptObjects = new QTreeWidget() );
68   layoutKeptObjects->addWidget( myTreeKeptObjects );
69
70   /**********************  Objects to be removed  **********************/
71   QGroupBox* groupRemoveObjects = new QGroupBox( tr( "GEOM_REDUCE_STUDY_REMOVE_OBJECTS" ) );
72   QGridLayout* layoutRemoveObjects = new QGridLayout( groupRemoveObjects );
73   createTreeWidget( myTreeRemoveObjects = new QTreeWidget() );
74   layoutRemoveObjects->addWidget( myTreeRemoveObjects );
75
76   /**********************         Options         **********************/
77   QGroupBox* groupOptions = new QGroupBox( tr( "GEOM_REDUCE_STUDY_OPTIONS" ) );
78   QVBoxLayout* layoutOptions = new QVBoxLayout( groupOptions );
79
80   // Intermediate objects
81   QGroupBox* groupIntermediates = createButtonGroup( myGroupIntermediates = new QButtonGroup() );
82   groupIntermediates->setTitle( tr( "GEOM_REDUCE_STUDY_INTERMEDIATES" ) );
83
84   // Sub-objects
85   QGroupBox* groupSubObjects = createButtonGroup( myGroupSubObjects = new QButtonGroup() );
86   groupSubObjects->setTitle( tr( "GEOM_REDUCE_STUDY_SUB_OBJECTS" ) );
87
88   // Others
89   myCBRemoveEmptyFolder = new QCheckBox( tr( "GEOM_REDUCE_STUDY_REMOVE_EMPTY_FOLDER" ) );
90   myCBRemoveEmptyFolder->setChecked( true );
91   myCBSoftRemoval = new QCheckBox( tr( "GEOM_REDUCE_STUDY_SOFT_REMOVAL" ) );
92
93   layoutOptions->addWidget( groupIntermediates );
94   layoutOptions->addWidget( groupSubObjects );
95   layoutOptions->addWidget( myCBRemoveEmptyFolder );
96   layoutOptions->addWidget( myCBSoftRemoval );
97
98   /**********************         Buttons         **********************/
99   QGroupBox* groupButtons = new QGroupBox();
100   QHBoxLayout* layoutButtons = new QHBoxLayout( groupButtons );
101
102   QPushButton* buttonOk = new QPushButton( tr( "GEOM_BUT_OK" ) );
103   QPushButton* buttonCancel = new QPushButton( tr( "GEOM_BUT_CANCEL" ) );
104   QPushButton* buttonHelp = new QPushButton( tr( "GEOM_BUT_HELP" ) );
105
106   layoutButtons->addWidget( buttonOk );
107   layoutButtons->addStretch();
108   layoutButtons->addWidget( buttonCancel );
109   layoutButtons->addWidget( buttonHelp );
110
111   topLayout->addWidget( groupKeptObjects, 0, 0 );
112   topLayout->addWidget( groupRemoveObjects, 0, 1 );
113   topLayout->addWidget( groupOptions, 1, 0, 1, 2 );
114   topLayout->addWidget( groupButtons, 2, 0, 1, 2 );
115
116   // Signals and slots connections
117
118   connect( myTreeKeptObjects, SIGNAL( itemClicked( QTreeWidgetItem*, int) ), this, SLOT( onItemClicked( QTreeWidgetItem*, int ) ) );
119   connect( myTreeRemoveObjects, SIGNAL( itemClicked( QTreeWidgetItem*, int) ), this, SLOT( onItemClicked( QTreeWidgetItem*, int ) ) );
120   connect( myTreeKeptObjects->header(), SIGNAL( sectionClicked ( int ) ), this, SLOT( onHeaderClicked( int ) ) );
121   connect( myTreeRemoveObjects->header(), SIGNAL( sectionClicked ( int ) ), this, SLOT( onHeaderClicked( int ) ) );
122
123   connect( myGroupIntermediates, SIGNAL( buttonClicked( int ) ), this, SLOT( update() ) );
124   connect( myGroupSubObjects, SIGNAL( buttonClicked( int ) ), this, SLOT( update() ) );
125
126   connect( buttonOk, SIGNAL( clicked() ), this, SLOT( clickOnOk() ) );
127   connect( buttonCancel, SIGNAL( clicked() ), this, SLOT( reject() ) );
128   connect( buttonHelp, SIGNAL( clicked() ), this, SLOT( clickOnHelp() ) );
129
130   connect( myApp->selectionMgr(), SIGNAL( currentSelectionChanged() ),
131            this, SLOT( selectionChanged() ) );
132
133   init( getSelectedObjects() );
134 }
135
136 GEOMToolsGUI_ReduceStudyDlg::~GEOMToolsGUI_ReduceStudyDlg()
137 {
138   // no need to delete child widgets, Qt does it all for us
139 }
140
141 //=================================================================================
142 // function : init()
143 // purpose  : initialize dialog data
144 //=================================================================================
145 void GEOMToolsGUI_ReduceStudyDlg::init( const std::set<std::string>& theObjectEntries )
146 {
147   myMainEntries.clear();
148
149   myKeptObjects.clear();
150   myListParents.clear();
151   myListSubObjects.clear();
152   myRemovedObjects.clear();
153
154   myMainEntries = theObjectEntries;
155
156   GEOM::string_array_var keptObjects = new GEOM::string_array();
157   int It = 0;
158   keptObjects->length( theObjectEntries.size() );
159   std::set<std::string>::iterator iter;
160   for( iter=theObjectEntries.begin(); iter!=theObjectEntries.end(); ++iter, It++ )
161     keptObjects[ It ] = (*iter).c_str();
162
163   GEOM::string_array_var parentsObjects = new GEOM::string_array();
164   GEOM::string_array_var subObjects = new GEOM::string_array();
165   GEOM::string_array_var otherObjects = new GEOM::string_array();
166
167   GeometryGUI::GetGeomGen()->GetEntriesToReduceStudy( GeometryGUI::ClientStudyToStudy( myStudy ),
168                                                              keptObjects, parentsObjects,
169                                                              subObjects, otherObjects );
170
171   for ( int i = 0; i < keptObjects->length(); i++ )
172     myKeptObjects.insert( keptObjects[i].in() );
173   for( int i = 0; i< otherObjects->length(); i++ )
174     myRemovedObjects.insert( otherObjects[i].in() );
175   for( int i = 0; i< parentsObjects->length(); i++ )
176     myListParents.insert( parentsObjects[i].in() );
177   for( int i = 0; i< subObjects->length(); i++ )
178     myListSubObjects.insert( subObjects[i].in() );
179
180   update();
181
182   checkVisibleIcon( myTreeKeptObjects );
183   checkVisibleIcon( myTreeRemoveObjects );
184 }
185
186 //=================================================================================
187 // function : getSelectedObjects()
188 // purpose  : get selected objects in object browser
189 //=================================================================================
190 std::set<std::string> GEOMToolsGUI_ReduceStudyDlg::getSelectedObjects() const
191 {
192   std::set<std::string> objects;
193
194   SALOME_ListIO selected;
195   myApp->selectionMgr()->selectedObjects( selected );
196
197   for( SALOME_ListIteratorOfListIO It( selected ); It.More(); It.Next() ) {
198     Handle( SALOME_InteractiveObject ) io = It.Value();
199     if( !io->hasEntry() )
200       continue;
201     GEOM::GEOM_Object_var geomObject = GEOM::GEOM_Object::_nil();
202     geomObject = GEOMBase::ConvertIOinGEOMObject( io );
203     if( geomObject->_is_nil() )
204       continue;
205     QString entry = geomObject->GetEntry();
206     objects.insert( entry.toStdString().c_str() );
207   }
208   return objects;
209 }
210
211 //=================================================================================
212 // function : createTreeWidget()
213 // purpose  : create tree widget for unpublished or removed objects
214 //=================================================================================
215 void GEOMToolsGUI_ReduceStudyDlg::createTreeWidget( QTreeWidget* theTreeWidget )
216 {
217   theTreeWidget->setColumnCount( 2 );
218   QStringList columnNames;
219   columnNames.append(tr( "GEOM_REDUCE_STUDY_NAME" ));
220   columnNames.append("");
221   theTreeWidget->setHeaderLabels( columnNames );
222   QTreeWidgetItem * headerItem = new QTreeWidgetItem( columnNames );
223   theTreeWidget->setHeaderItem ( headerItem );
224   theTreeWidget->header()->moveSection( 1, 0 );
225 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
226   theTreeWidget->header()->setClickable( true );
227   theTreeWidget->header()->setMovable( false );
228   theTreeWidget->header()->setResizeMode( 1, QHeaderView::ResizeToContents );
229 #else
230   theTreeWidget->header()->setSectionsClickable( true );
231   theTreeWidget->header()->setSectionsMovable( false );
232   theTreeWidget->header()->setSectionResizeMode( 1, QHeaderView::ResizeToContents );
233 #endif
234   theTreeWidget->setSelectionMode( QAbstractItemView::ExtendedSelection );
235 }
236
237 //=================================================================================
238 // function : createButtonGroup()
239 // purpose  : create button group for intermediate objects or sub-objects
240 //=================================================================================
241 QGroupBox* GEOMToolsGUI_ReduceStudyDlg::createButtonGroup( QButtonGroup* theButtonGroup )
242 {
243   QGroupBox* groupObjects = new QGroupBox();
244   QHBoxLayout* layoutObjects = new QHBoxLayout( groupObjects );
245
246   QRadioButton* buttonKeep = new QRadioButton( tr( "GEOM_REDUCE_STUDY_KEEP") );
247   theButtonGroup->addButton( buttonKeep, 0 );
248   QRadioButton* buttonUnpublish = new QRadioButton( tr( "GEOM_REDUCE_STUDY_UNPUBLISH") );
249   theButtonGroup->addButton( buttonUnpublish, 1 );
250   QRadioButton* buttonRemove = new QRadioButton( tr( "GEOM_REDUCE_STUDY_REMOVE") );
251   theButtonGroup->addButton( buttonRemove, 2 );
252
253   theButtonGroup->button( 0 )->setChecked( true );
254   theButtonGroup->setExclusive( true );
255
256   layoutObjects->addWidget( buttonKeep );
257   layoutObjects->addWidget( buttonUnpublish );
258   layoutObjects->addWidget( buttonRemove );
259
260   return groupObjects;
261 }
262
263 //=================================================================================
264 // function : addObjectsToTree()
265 // purpose  : add the list of objects to tree
266 //=================================================================================
267 void GEOMToolsGUI_ReduceStudyDlg::addObjectsToTree( QTreeWidget* theWidget, std::set<std::string>& theObjects )
268 {
269   std::set<std::string>::iterator it;
270   for( it = theObjects.begin(); it != theObjects.end(); ++it ) {
271     std::string objectEntry = *it;
272     GEOM::GEOM_BaseObject_var GeomBaseObject = GeometryGUI::GetGeomGen()->GetObject( myStudy->StudyId(), objectEntry.c_str() );
273     GEOM::GEOM_Object_var GeomObject = GEOM::GEOM_Object::_narrow( GeomBaseObject );
274     QString studyEntry = GeomBaseObject->GetStudyEntry();
275     if( GeomObject->_is_nil() || studyEntry.isEmpty() || !isObjectDrawable( studyEntry.toStdString() ) )
276       continue;
277     addSubObject( theWidget, theObjects, GeomObject );
278   }
279 }
280
281 //=================================================================================
282 // function : addSubObject()
283 // purpose  : add sub-object to parent object in the tree
284 //=================================================================================
285 GEOMToolsGUI_TreeWidgetItem* GEOMToolsGUI_ReduceStudyDlg::addSubObject( QTreeWidget* theWidget,
286                                                                         std::set<std::string>& theObjects,
287                                                                         GEOM::GEOM_Object_var theObject )
288 {
289   GEOMToolsGUI_TreeWidgetItem* item;
290   if( !theObject->IsMainShape() ) {
291     GEOM::GEOM_Object_var aMainShape = theObject->GetMainShape();
292     if ( CORBA::is_nil( aMainShape ) )
293       return NULL;
294     GEOMToolsGUI_TreeWidgetItem* parentItem = addSubObject( theWidget, theObjects, aMainShape );
295     item = findObjectInTree( theWidget, theObject );
296     if( !item )
297       item = new GEOMToolsGUI_TreeWidgetItem( parentItem, QStringList() << theObject->GetName(), theObject->GetStudyEntry() );
298   }
299   else {
300     item = findObjectInTree( theWidget, theObject );
301     if( !item )
302       item = new GEOMToolsGUI_TreeWidgetItem( theWidget, QStringList() << theObject->GetName(), theObject->GetStudyEntry() );
303   }
304
305   bool isDisplayed = false;
306   if( theObjects.find( theObject->GetEntry() ) != theObjects.end() ) {
307     isDisplayed = myDisplayer.IsDisplayed( theObject->GetStudyEntry() );
308     if ( isDisplayed )
309       item->setVisible( true, myVisible );
310     else
311       item->setVisible( false, myInvisible );
312
313     if( myMainEntries.find( theObject->GetEntry() ) != myMainEntries.end() ) {
314       QFont Textfont = item->font(0);
315       Textfont.setBold( true );
316       item->setFont( 0, Textfont );
317     }
318   }
319   else {
320     item->setFlags( item->flags() & ~Qt::ItemIsSelectable );
321     item->setTextColor( 0, QColor( 150, 150, 150 ) );
322   }
323   return item;
324 }
325
326 //=================================================================================
327 // function : findObjectInTree()
328 // purpose  : find object in the tree
329 //=================================================================================
330 GEOMToolsGUI_TreeWidgetItem* GEOMToolsGUI_ReduceStudyDlg::findObjectInTree( QTreeWidget* theWidget, GEOM::GEOM_Object_var theObject )
331 {
332   QTreeWidgetItemIterator it( theWidget );
333   while(*it) {
334     GEOMToolsGUI_TreeWidgetItem* item = dynamic_cast<GEOMToolsGUI_TreeWidgetItem*>(*it);
335     if( QString( item->getStudyEntry() ) == QString( theObject->GetStudyEntry() ) )
336       return item;
337     ++it;
338   }
339   return NULL;
340 }
341
342 //=================================================================================
343 // function : checkVisibleIcon()
344 // purpose  : set visible or invisible icon in the header of tree
345 //=================================================================================
346 void GEOMToolsGUI_ReduceStudyDlg::checkVisibleIcon( QTreeWidget* theWidget )
347 {
348   bool isInvisible = false;
349   QTreeWidgetItemIterator it( theWidget );
350   while(*it) {
351     GEOMToolsGUI_TreeWidgetItem* item = dynamic_cast<GEOMToolsGUI_TreeWidgetItem*>(*it);
352     const char* entry = item->getStudyEntry();
353     if( item->flags() & Qt::ItemIsSelectable )
354       if( !item->isVisible() )
355         isInvisible = true;
356     ++it;
357   }
358
359   if( isInvisible ) {
360     theWidget->headerItem()->setIcon( 1, myInvisible );
361     myMapTreeSelectAll[ theWidget ] = false;
362   }
363   else {
364     theWidget->headerItem()->setIcon( 1, myVisible );
365     myMapTreeSelectAll[ theWidget ] = true;
366   }
367 }
368
369 //=================================================================================
370 // function : isObjectDrawable()
371 // purpose  : return true if object is drawable, and false if object is hidden in the study
372 //=================================================================================
373 bool GEOMToolsGUI_ReduceStudyDlg::isObjectDrawable( std::string theStudyEntry )
374 {
375   _PTR(StudyBuilder) aStudyBuilder = myStudy->NewBuilder();
376   //If object hasn't "AttributeDrawable" => it visible
377   bool isDrawable = true;
378   _PTR(SObject) SO ( myStudy->FindObjectID( theStudyEntry ) );
379   _PTR(GenericAttribute) anAttr;
380   if ( SO && SO->FindAttribute( anAttr, "AttributeDrawable" ) ) {
381     _PTR(AttributeDrawable) aDrw (anAttr);
382     isDrawable = aDrw->IsDrawable();
383   }
384   return isDrawable;
385 }
386
387 //=================================================================================
388 // function : unpublishObjects()
389 // purpose  : unpublish(hide) objects in the study
390 //=================================================================================
391 void GEOMToolsGUI_ReduceStudyDlg::unpublishObjects( std::set<std::string>& theObjects )
392 {
393   _PTR(StudyBuilder) aStudyBuilder = myStudy->NewBuilder();
394   std::set<std::string>::iterator it;
395   for( it = theObjects.begin(); it != theObjects.end(); ++it ) {
396     std::string objectEntry = *it;
397     GEOM::GEOM_BaseObject_var GeomBaseObject = GeometryGUI::GetGeomGen()->GetObject( myStudy->StudyId(),
398                                                                                      objectEntry.c_str() );
399     std::string studyEntry = GeomBaseObject->GetStudyEntry();
400     if ( studyEntry == "" || !isObjectDrawable( studyEntry ) )
401       continue;
402     _PTR(SObject) obj ( myStudy->FindObjectID( studyEntry.c_str() ) );
403     _PTR(GenericAttribute) anAttr;
404     if ( obj ) {
405       _PTR(AttributeDrawable) aDrw = aStudyBuilder->FindOrCreateAttribute( obj, "AttributeDrawable" );
406       aDrw->SetDrawable( false );
407       myDisplayer.EraseWithChildren( new SALOME_InteractiveObject( studyEntry.c_str(), "GEOM", "TEMP_IO" ) );
408       // hide references if any
409       std::vector< _PTR(SObject) > vso = myStudy->FindDependances(obj);
410       for ( int i = 0; i < vso.size(); i++ ) {
411         _PTR(SObject) refObj = vso[i];
412         aDrw = aStudyBuilder->FindOrCreateAttribute( refObj, "AttributeDrawable" );
413         aDrw->SetDrawable( false );
414       }
415     }
416   }
417   myApp->updateObjectBrowser( false );
418   myApp->updateActions();
419 }
420
421 //=================================================================================
422 // function : removeObjects()
423 // purpose  : remove objects from the study
424 //=================================================================================
425 void GEOMToolsGUI_ReduceStudyDlg::removeObjects( std::set<std::string>& theObjects )
426 {
427   std::set<std::string>::iterator it;
428   for( it = theObjects.begin(); it != theObjects.end(); ++it ) {
429     std::string objectEntry = *it;
430     GEOM::GEOM_BaseObject_var GeomBaseObject = GeometryGUI::GetGeomGen()->GetObject( myStudy->StudyId(),
431                                                                                      objectEntry.c_str() );
432     std::string studyEntry = GeomBaseObject->GetStudyEntry();
433     if ( studyEntry == "" )
434       GeometryGUI::GetGeomGen()->RemoveObject( GeomBaseObject );
435     else {
436       if( !isObjectDrawable( studyEntry ) )
437         continue;
438       removeObject( studyEntry );
439     }
440   }
441   myApp->updateObjectBrowser( false );
442   myApp->updateActions();
443 }
444
445 //=================================================================================
446 // function : removeObject()
447 // purpose  : remove object with given study entry
448 //=================================================================================
449 void GEOMToolsGUI_ReduceStudyDlg::removeObject( std::string& theStudyEntry )
450 {
451   SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*>( myApp->activeStudy() );
452   _PTR(StudyBuilder) aStudyBuilder = myStudy->NewBuilder();
453   _PTR(UseCaseBuilder) aUseCaseBuilder = myStudy->GetUseCaseBuilder();
454
455   _PTR(SObject) obj ( myStudy->FindObjectID( theStudyEntry.c_str() ) );
456   if ( obj ) {
457     // remove visual properties of the object
458     appStudy->removeObjectProperties(obj->GetID().c_str());
459     // remove references to this object
460     appStudy->deleteReferencesTo( obj );
461     // remove objects from study
462     aStudyBuilder->RemoveObjectWithChildren( obj );
463     // remove object from use case tree
464     aUseCaseBuilder->Remove( obj );
465     myDisplayer.EraseWithChildren( new SALOME_InteractiveObject( theStudyEntry.c_str(), "GEOM", "TEMP_IO" ) );
466   }
467 }
468
469 //=================================================================================
470 // function : removeEmptyFolders()
471 // purpose  : remove empty folders from the study
472 //=================================================================================
473 void GEOMToolsGUI_ReduceStudyDlg::removeEmptyFolders()
474 {
475   std::set<std::string> emptyFolders;
476
477   _PTR(SComponent) SC ( myStudy->FindComponent( "GEOM" ) );
478   if ( !SC )
479     return;
480   _PTR(ChildIterator) anIter ( myStudy->NewChildIterator( SC ) );
481   anIter->InitEx( true );
482   while( anIter->More() ) {
483     _PTR(SObject) valSO ( anIter->Value() );
484     _PTR(SObject) refSO;
485     if ( !valSO->ReferencedObject( refSO ) )
486       getEmptyFolders( valSO, emptyFolders );
487     anIter->Next();
488   }
489
490   std::set<std::string>::iterator iter;
491   for( iter = emptyFolders.begin(); iter != emptyFolders.end(); ++iter ) {
492     std::string studyEntry = *iter;
493     removeObject( studyEntry );
494   }
495   myApp->updateObjectBrowser( false );
496   myApp->updateActions();
497 }
498
499 //=================================================================================
500 // function : removeEmptyFolders()
501 // purpose  : remove empty folders from the study
502 //=================================================================================
503 void GEOMToolsGUI_ReduceStudyDlg::getEmptyFolders( _PTR(SObject) theSO, std::set<std::string>& theFolders )
504 {
505   _PTR(UseCaseBuilder) aUseCaseBuilder = myStudy->GetUseCaseBuilder();
506
507   bool isFolder = false;
508   _PTR(GenericAttribute) anAttr;
509   if ( theSO->FindAttribute(anAttr, "AttributeLocalID") ) {
510     _PTR(AttributeLocalID) aLocalID( anAttr );
511     isFolder = aLocalID->Value() == 999;
512   }
513   QString studyEntry = theSO->GetID().c_str();
514   if ( isFolder ) {
515     if( !aUseCaseBuilder->HasChildren( theSO ) )
516       theFolders.insert( studyEntry.toStdString() );
517     else {
518       _PTR(UseCaseIterator) ucit ( aUseCaseBuilder->GetUseCaseIterator( theSO ) );
519       for ( ucit->Init( false ); ucit->More(); ucit->Next() )
520         getEmptyFolders( ucit->Value(), theFolders );
521     }
522   }
523 }
524
525 //=================================================================================
526 // function : onItemClicked()
527 // purpose  : called when tree item was clicked
528 //=================================================================================
529 void GEOMToolsGUI_ReduceStudyDlg::onItemClicked( QTreeWidgetItem* theItem, int theColumn )
530 {
531   if( theColumn != 1 || !( theItem->flags() & Qt::ItemIsSelectable ) )
532     return;
533
534   GEOMToolsGUI_TreeWidgetItem* item = dynamic_cast<GEOMToolsGUI_TreeWidgetItem*>( theItem );
535
536   const char* entry = item->getStudyEntry();
537   Handle(SALOME_InteractiveObject) io = new SALOME_InteractiveObject( entry, "GEOM", "TEMP_IO" );
538   if( myDisplayer.IsDisplayed( entry ) ) {
539     item->setVisible( false, myInvisible );
540     myDisplayer.Erase( io );
541   }
542   else {
543     item->setVisible( true, myVisible );
544     myDisplayer.Display( io );
545   }
546   myDisplayer.UpdateViewer();
547   checkVisibleIcon( item->treeWidget() );
548 }
549
550 //=================================================================================
551 // function : onHeaderClicked()
552 // purpose  : called when header item of tree was clicked
553 //=================================================================================
554 void GEOMToolsGUI_ReduceStudyDlg::onHeaderClicked( int theColumn )
555 {
556   if( theColumn != 1 )
557     return;
558
559   QTreeWidget* treeWidget = dynamic_cast<QTreeWidget*>(sender()->parent());
560   if( myMapTreeSelectAll[ treeWidget ] ) {
561     myMapTreeSelectAll[ treeWidget ] = false;
562     treeWidget->headerItem()->setIcon( 1, myInvisible );
563     QTreeWidgetItemIterator it( treeWidget );
564     while(*it) {
565       GEOMToolsGUI_TreeWidgetItem* item = dynamic_cast<GEOMToolsGUI_TreeWidgetItem*>(*it);
566       if( ( item->flags() & Qt::ItemIsSelectable ) && item->isVisible() ) {
567         const char* entry = item->getStudyEntry();
568         item->setVisible( false, myInvisible );
569         myDisplayer.Erase( new SALOME_InteractiveObject( entry, "GEOM", "TEMP_IO" ) );
570       }
571       ++it;
572     }
573   }
574   else {
575     myMapTreeSelectAll[ treeWidget ] = true;
576     treeWidget->headerItem()->setIcon( 1, myVisible );
577     QTreeWidgetItemIterator it( treeWidget );
578     while(*it) {
579       GEOMToolsGUI_TreeWidgetItem* item = dynamic_cast<GEOMToolsGUI_TreeWidgetItem*>(*it);
580       if( ( item->flags() & Qt::ItemIsSelectable ) && !item->isVisible() ) {
581         const char* entry = item->getStudyEntry();
582         item->setVisible( true, myVisible );
583         myDisplayer.Display( new SALOME_InteractiveObject( entry, "GEOM", "TEMP_IO" ) );
584       }
585       ++it;
586     }
587   }
588   myDisplayer.UpdateViewer();
589 }
590
591 //=================================================================================
592 // function : selectionChanged()
593 // purpose  : called when selection of object browser was changed
594 //=================================================================================
595 void GEOMToolsGUI_ReduceStudyDlg::selectionChanged()
596 {
597   init( getSelectedObjects() );
598 }
599
600 //=================================================================================
601 // function : update()
602 // purpose  : update tree data
603 //=================================================================================
604 void GEOMToolsGUI_ReduceStudyDlg::update()
605 {
606   myTreeKeptObjects->clear();
607   myTreeRemoveObjects->clear();
608
609   std::set<std::string> keptObjects( myKeptObjects );
610   std::set<std::string> removeObjects( myRemovedObjects );
611
612   // Intermediate objects
613   if( myGroupIntermediates->checkedId() == 2 ) { // remove
614     std::set<std::string>::iterator iter;
615     for( iter=myListParents.begin(); iter!=myListParents.end(); ++iter)
616       removeObjects.insert( *iter );
617   }
618   else { // keep or unpublish
619     std::set<std::string>::iterator iter;
620     for( iter=myListParents.begin(); iter!=myListParents.end(); ++iter)
621       keptObjects.insert( *iter );
622   }
623
624   // Sub-objects
625   if( myGroupSubObjects->checkedId() == 2 ) {
626     std::set<std::string>::iterator iter;
627     for( iter=myListSubObjects.begin(); iter!=myListSubObjects.end(); ++iter)
628       removeObjects.insert( *iter );
629   }
630   else {
631     std::set<std::string>::iterator iter;
632     for( iter=myListSubObjects.begin(); iter!=myListSubObjects.end(); ++iter)
633       keptObjects.insert( *iter );
634   }
635
636   addObjectsToTree( myTreeKeptObjects, keptObjects );
637   addObjectsToTree( myTreeRemoveObjects, removeObjects );
638
639   myTreeKeptObjects->collapseAll();
640   myTreeRemoveObjects->collapseAll();
641
642 }
643
644 //=================================================================================
645 // function : clickOnOk()
646 // purpose  : called when OK button was clicked
647 //=================================================================================
648 void GEOMToolsGUI_ReduceStudyDlg::clickOnOk()
649 {
650   std::set<std::string> objectsToBeRemoved = myRemovedObjects;
651   std::set<std::string> objectsToBeUnpublished;
652
653   // Create lists of intermediate objects to be removed or to be unpublished
654   std::set<std::string>::iterator iter;
655   if( myGroupIntermediates->checkedId() == 1 ) { // unpublish
656     for( iter = myListParents.begin(); iter != myListParents.end(); ++iter )
657     objectsToBeUnpublished.insert( *iter );
658   }
659   if( myGroupIntermediates->checkedId() == 2 ) { // remove
660     if( !myCBSoftRemoval->isChecked() && 
661         SUIT_MessageBox::question( this,
662                                    tr( "GEOM_WRN_WARNING" ),
663                                    tr( "GEOM_REDUCE_STUDY_WARNING_DELETE" ),
664                                    QMessageBox::Yes | QMessageBox::No,
665                                    QMessageBox::Yes ) == QMessageBox::No ) {
666       return;
667     }
668     for( iter = myListParents.begin(); iter != myListParents.end(); ++iter )
669       objectsToBeRemoved.insert( *iter );
670   }
671
672   // Create lists of sub-objects to be removed or to be unpublished
673   if( myGroupSubObjects->checkedId() == 1 ) { // unpublish
674     for( iter = myListSubObjects.begin(); iter != myListSubObjects.end(); ++iter )
675       objectsToBeUnpublished.insert( *iter );
676   }
677   else if( myGroupSubObjects->checkedId() == 2 ) { // remove
678     for( iter = myListSubObjects.begin(); iter != myListSubObjects.end(); ++iter )
679       objectsToBeRemoved.insert( *iter );
680   }
681
682   // if user chosen the soft removal
683   if( myCBSoftRemoval->isChecked() ) {
684     for( iter = objectsToBeRemoved.begin(); iter != objectsToBeRemoved.end(); ++iter )
685       objectsToBeUnpublished.insert( *iter );
686     unpublishObjects( objectsToBeUnpublished );
687   }
688   else {
689     unpublishObjects( objectsToBeUnpublished );
690     removeObjects( objectsToBeRemoved );
691   }
692
693   // if user want to delete the empty folders
694   if( myCBRemoveEmptyFolder->isChecked() )
695     removeEmptyFolders();
696
697   accept();
698 }
699
700 //=================================================================================
701 // function : clickOnHelp()
702 // purpose  : called when Help button was clicked to open a help page
703 //=================================================================================
704 void GEOMToolsGUI_ReduceStudyDlg::clickOnHelp()
705 {
706   myApp->onHelpContextModule( "GEOM", "reduce_study_page.html" );
707 }
708
709 GEOMToolsGUI_TreeWidgetItem::GEOMToolsGUI_TreeWidgetItem( QTreeWidget* view, const QStringList &strings,
710                                                           char* studyEntry, int type )
711 :QTreeWidgetItem( view, strings, type ),
712  myStudyEntry( studyEntry ),
713  myVisible( false )
714 {
715 }
716
717 GEOMToolsGUI_TreeWidgetItem::GEOMToolsGUI_TreeWidgetItem( QTreeWidgetItem* parent, const QStringList &strings,
718                                                           char* studyEntry, int type )
719 :QTreeWidgetItem( parent, strings, type ),
720  myStudyEntry( studyEntry ),
721  myVisible( false )
722 {
723 }
724
725 GEOMToolsGUI_TreeWidgetItem::~GEOMToolsGUI_TreeWidgetItem()
726 {
727 }
728
729 bool GEOMToolsGUI_TreeWidgetItem::isVisible()
730 {
731   return myVisible;
732 }
733
734 void GEOMToolsGUI_TreeWidgetItem::setVisible( bool theIsVisible, QIcon& theIcon )
735 {
736   myVisible = theIsVisible;
737   setIcon( 1, theIcon );
738 }
739
740 char* GEOMToolsGUI_TreeWidgetItem::getStudyEntry() const
741 {
742   return myStudyEntry;
743 }