Salome HOME
Avoid installing redundant files
[modules/geom.git] / src / GEOMToolsGUI / GEOMToolsGUI_ReduceStudyDlg.cxx
index aa9099a79a4e5aea9f446fb82de822bfd20e0004..6763d03849d0027bf1db52521e393c90fbb94f1b 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2014-2021  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 
+// internal includes
 #include "GEOMToolsGUI_ReduceStudyDlg.h"
 
-#include <QVBoxLayout>
-#include <QHBoxLayout>
-#include <QGroupBox>
-#include <QGridLayout>
-#include <QHeaderView>
-#include <QPushButton>
-#include <QRadioButton>
-
+// GEOM includes
+#include <GEOMBase.h>
 
 // GUI includes
 #include <SUIT_Session.h>
 #include <SUIT_ResourceMgr.h>
-#include <SUIT_DataOwner.h>
-#include <SalomeApp_Application.h>
-#include <SalomeApp_Study.h>
-#include <OCCViewer_ViewManager.h>
-#include <LightApp_DataOwner.h>
-#include <GEOMToolsGUI.h>
-
-// GEOM includes
-#include <SALOMEconfig.h>
-#include CORBA_CLIENT_HEADER(GEOM_Gen)
-#include <GEOMBase_Helper.h>
+#include <SUIT_MessageBox.h>
 
 #include <LightApp_SelectionMgr.h>
-#include <SALOME_ListIteratorOfListIO.hxx>
 
-// GEOM includes
-#include <GEOMBase.h>
+#include <SalomeApp_Application.h>
+#include <SalomeApp_Study.h>
+#include <SALOME_ListIO.hxx>
 
-#include <iostream>
+// Qt includes
+#include <QGridLayout>
+#include <QPushButton>
+#include <QRadioButton>
+#include <QHeaderView>
+#include <QMessageBox>
 
 GEOMToolsGUI_ReduceStudyDlg::GEOMToolsGUI_ReduceStudyDlg( QWidget* parent )
-:QDialog( parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint ),
-myDisplayer(NULL)
+:QDialog( parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint )
 {
-  setAttribute(Qt::WA_DeleteOnClose);
-
   SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
   myVisible = QIcon( resMgr->loadPixmap( "SUIT", tr( "ICON_DATAOBJ_VISIBLE" ) ) );
   myInvisible = QIcon( resMgr->loadPixmap( "SUIT", tr( "ICON_DATAOBJ_INVISIBLE" ) ) );
 
   myApp = dynamic_cast< SalomeApp_Application* >( SUIT_Session::session()->activeApplication() );
   if ( !myApp ) return;
-  SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( myApp->activeStudy() );
-  myStudy = GeometryGUI::ClientStudyToStudy( study->studyDS() );
-  myDisplayer = GEOM_Displayer( study );
+
+  myDisplayer = GEOM_Displayer();
 
   setWindowTitle( tr( "GEOM_REDUCE_STUDY_TITLE" ) );
+  setAttribute(Qt::WA_DeleteOnClose);
 
   QGridLayout* topLayout = new QGridLayout( this );
   topLayout->setMargin( 11 ); topLayout->setSpacing( 6 );
@@ -88,7 +75,7 @@ myDisplayer(NULL)
   QGroupBox* groupOptions = new QGroupBox( tr( "GEOM_REDUCE_STUDY_OPTIONS" ) );
   QVBoxLayout* layoutOptions = new QVBoxLayout( groupOptions );
 
-  // Intermidiate objects
+  // Intermediate objects
   QGroupBox* groupIntermediates = createButtonGroup( myGroupIntermediates = new QButtonGroup() );
   groupIntermediates->setTitle( tr( "GEOM_REDUCE_STUDY_INTERMEDIATES" ) );
 
@@ -135,11 +122,11 @@ myDisplayer(NULL)
   connect( myGroupSubObjects, SIGNAL( buttonClicked( int ) ), this, SLOT( update() ) );
 
   connect( buttonOk, SIGNAL( clicked() ), this, SLOT( clickOnOk() ) );
-  connect( buttonCancel, SIGNAL( clicked() ), this, SLOT( clickOnCancel() ) );
+  connect( buttonCancel, SIGNAL( clicked() ), this, SLOT( reject() ) );
   connect( buttonHelp, SIGNAL( clicked() ), this, SLOT( clickOnHelp() ) );
 
-  connect( myApp->selectionMgr(),
-           SIGNAL( currentSelectionChanged() ), this, SLOT( selectionChanged() ) );
+  connect( myApp->selectionMgr(), SIGNAL( currentSelectionChanged() ),
+           this, SLOT( selectionChanged() ) );
 
   init( getSelectedObjects() );
 }
@@ -149,6 +136,10 @@ GEOMToolsGUI_ReduceStudyDlg::~GEOMToolsGUI_ReduceStudyDlg()
   // no need to delete child widgets, Qt does it all for us
 }
 
+//=================================================================================
+// function : init()
+// purpose  : initialize dialog data
+//=================================================================================
 void GEOMToolsGUI_ReduceStudyDlg::init( const std::set<std::string>& theObjectEntries )
 {
   myMainEntries.clear();
@@ -160,59 +151,64 @@ void GEOMToolsGUI_ReduceStudyDlg::init( const std::set<std::string>& theObjectEn
 
   myMainEntries = theObjectEntries;
 
-  std::cout << "\n\n\n myMainEntries = " << myMainEntries.size() << std::endl;
-
-  GEOM::string_array_var selectedObjects = new GEOM::string_array();
+  GEOM::string_array_var keptObjects = new GEOM::string_array();
   int It = 0;
-  selectedObjects->length( theObjectEntries.size() );
+  keptObjects->length( theObjectEntries.size() );
   std::set<std::string>::iterator iter;
   for( iter=theObjectEntries.begin(); iter!=theObjectEntries.end(); ++iter, It++ )
-    selectedObjects[ It ] = (*iter).c_str();
+    keptObjects[ It ] = (*iter).c_str();
 
   GEOM::string_array_var parentsObjects = new GEOM::string_array();
   GEOM::string_array_var subObjects = new GEOM::string_array();
-  GEOM::string_array_var oters = new GEOM::string_array();
+  GEOM::string_array_var otherObjects = new GEOM::string_array();
 
+  GeometryGUI::GetGeomGen()->GetEntriesToReduceStudy( keptObjects, parentsObjects,
+                                                             subObjects, otherObjects );
 
-////// PUT ALGORITHM HERE
-  GeometryGUI::GetGeomGen()->GetEntriesToCleanStudy( myStudy, selectedObjects,
-    parentsObjects, subObjects, oters );
-
-  for ( int i = 0; i < selectedObjects->length(); i++ )
-    myKeptObjects.insert( selectedObjects[i].in() );
-
-  for( int i = 0; i< parentsObjects->length(); i++ )
+  for ( unsigned long i = 0; i < keptObjects->length(); i++ )
+    myKeptObjects.insert( keptObjects[i].in() );
+  for( unsigned long i = 0; i< otherObjects->length(); i++ )
+    myRemovedObjects.insert( otherObjects[i].in() );
+  for( unsigned long i = 0; i< parentsObjects->length(); i++ )
     myListParents.insert( parentsObjects[i].in() );
-
-  for( int i = 0; i< subObjects->length(); i++ )
+  for( unsigned long i = 0; i< subObjects->length(); i++ )
     myListSubObjects.insert( subObjects[i].in() );
 
-  for( int i = 0; i< oters->length(); i++ )
-         myRemovedObjects.insert( oters[i].in() );
-
-//  myParents.insert( "0:1:21" );
-//  myParents.insert( "0:1:17" );
-//  myParents.insert( "0:1:20" );
-//  myParents.insert( "0:1:13" );
-//  myParents.insert( "0:1:12" );
-//
-//  myListSubObjects.insert( "0:1:24" );
-//  myListSubObjects.insert( "0:1:28" );
-//  myListSubObjects.insert( "0:1:29" );
-//  myListSubObjects.insert( "0:1:34" );
-//
-//  myOthers.insert( "0:1:35" );
-//  myOthers.insert( "0:1:36" );
-//  myOthers.insert( "0:1:37" );
-//  myOthers.insert( "0:1:38" );
-//  myOthers.insert( "0:1:39" );
-
   update();
 
   checkVisibleIcon( myTreeKeptObjects );
   checkVisibleIcon( myTreeRemoveObjects );
 }
 
+//=================================================================================
+// function : getSelectedObjects()
+// purpose  : get selected objects in object browser
+//=================================================================================
+std::set<std::string> GEOMToolsGUI_ReduceStudyDlg::getSelectedObjects() const
+{
+  std::set<std::string> objects;
+
+  SALOME_ListIO selected;
+  myApp->selectionMgr()->selectedObjects( selected );
+
+  for( SALOME_ListIteratorOfListIO It( selected ); It.More(); It.Next() ) {
+    Handle( SALOME_InteractiveObject ) io = It.Value();
+    if( !io->hasEntry() )
+      continue;
+    GEOM::GEOM_Object_var geomObject = GEOM::GEOM_Object::_nil();
+    geomObject = GEOMBase::ConvertIOinGEOMObject( io );
+    if( geomObject->_is_nil() )
+      continue;
+    QString entry = geomObject->GetEntry();
+    objects.insert( entry.toStdString().c_str() );
+  }
+  return objects;
+}
+
+//=================================================================================
+// function : createTreeWidget()
+// purpose  : create tree widget for unpublished or removed objects
+//=================================================================================
 void GEOMToolsGUI_ReduceStudyDlg::createTreeWidget( QTreeWidget* theTreeWidget )
 {
   theTreeWidget->setColumnCount( 2 );
@@ -223,12 +219,17 @@ void GEOMToolsGUI_ReduceStudyDlg::createTreeWidget( QTreeWidget* theTreeWidget )
   QTreeWidgetItem * headerItem = new QTreeWidgetItem( columnNames );
   theTreeWidget->setHeaderItem ( headerItem );
   theTreeWidget->header()->moveSection( 1, 0 );
-  theTreeWidget->header()->setClickable( true );
-  theTreeWidget->header()->setMovable( false );
-  theTreeWidget->header()->setResizeMode( 1, QHeaderView::ResizeToContents );
+  theTreeWidget->header()->setSectionsClickable( true );
+  theTreeWidget->header()->setSectionsMovable( false );
+  theTreeWidget->header()->setSectionResizeMode( 1, QHeaderView::ResizeToContents );
+
   theTreeWidget->setSelectionMode( QAbstractItemView::ExtendedSelection );
 }
 
+//=================================================================================
+// function : createButtonGroup()
+// purpose  : create button group for intermediate objects or sub-objects
+//=================================================================================
 QGroupBox* GEOMToolsGUI_ReduceStudyDlg::createButtonGroup( QButtonGroup* theButtonGroup )
 {
   QGroupBox* groupObjects = new QGroupBox();
@@ -251,276 +252,273 @@ QGroupBox* GEOMToolsGUI_ReduceStudyDlg::createButtonGroup( QButtonGroup* theButt
   return groupObjects;
 }
 
-void GEOMToolsGUI_ReduceStudyDlg::update()
+//=================================================================================
+// function : addObjectsToTree()
+// purpose  : add the list of objects to tree
+//=================================================================================
+void GEOMToolsGUI_ReduceStudyDlg::addObjectsToTree( QTreeWidget* theWidget, std::set<std::string>& theObjects )
 {
-
-  myTreeKeptObjects->clear();
-  myTreeRemoveObjects->clear();
-
-  std::set<std::string> keptObjects(myKeptObjects);
-  std::set<std::string> removeObjects(myRemovedObjects);
-
-  // Intermediate objects
-  if( myGroupIntermediates->checkedId() == 2 ) { // remove
-    std::set<std::string>::iterator iter;
-    for( iter=myListParents.begin(); iter!=myListParents.end(); ++iter)
-      removeObjects.insert( *iter );
-  }
-  else { // keep or unpublish
-    std::set<std::string>::iterator iter;
-    for( iter=myListParents.begin(); iter!=myListParents.end(); ++iter)
-      keptObjects.insert( *iter );
+  std::set<std::string>::iterator it;
+  for( it = theObjects.begin(); it != theObjects.end(); ++it ) {
+    std::string objectEntry = *it;
+    GEOM::GEOM_BaseObject_var GeomBaseObject = GeometryGUI::GetGeomGen()->GetObject( objectEntry.c_str() );
+    GEOM::GEOM_Object_var GeomObject = GEOM::GEOM_Object::_narrow( GeomBaseObject );
+    QString studyEntry = GeomBaseObject->GetStudyEntry();
+    if( GeomObject->_is_nil() || studyEntry.isEmpty() || !isObjectDrawable( studyEntry.toStdString() ) )
+      continue;
+    addSubObject( theWidget, theObjects, GeomObject );
   }
+}
 
-  // Sub-objects
-  if( myGroupSubObjects->checkedId() == 2 ) {
-    std::set<std::string>::iterator iter;
-    for( iter=myListSubObjects.begin(); iter!=myListSubObjects.end(); ++iter)
-      removeObjects.insert( *iter );
+//=================================================================================
+// function : addSubObject()
+// purpose  : add sub-object to parent object in the tree
+//=================================================================================
+GEOMToolsGUI_TreeWidgetItem* GEOMToolsGUI_ReduceStudyDlg::addSubObject( QTreeWidget* theWidget,
+                                                                        std::set<std::string>& theObjects,
+                                                                        GEOM::GEOM_Object_var theObject )
+{
+  GEOMToolsGUI_TreeWidgetItem* item;
+  if( !theObject->IsMainShape() ) {
+    GEOM::GEOM_Object_var aMainShape = theObject->GetMainShape();
+    if ( CORBA::is_nil( aMainShape ) )
+      return NULL;
+    GEOMToolsGUI_TreeWidgetItem* parentItem = addSubObject( theWidget, theObjects, aMainShape );
+    item = findObjectInTree( theWidget, theObject );
+    if( !item )
+      item = new GEOMToolsGUI_TreeWidgetItem( parentItem, QStringList() << theObject->GetName(), theObject->GetStudyEntry() );
   }
   else {
-    std::set<std::string>::iterator iter;
-    for( iter=myListSubObjects.begin(); iter!=myListSubObjects.end(); ++iter)
-      keptObjects.insert( *iter );
+    item = findObjectInTree( theWidget, theObject );
+    if( !item )
+      item = new GEOMToolsGUI_TreeWidgetItem( theWidget, QStringList() << theObject->GetName(), theObject->GetStudyEntry() );
   }
 
-  std::cout<<"\n\n\n Objects to be kept: ";
-  std::set<std::string>::iterator it_kept;
-  for ( it_kept=keptObjects.begin(); it_kept!=keptObjects.end(); ++it_kept)
-    std::cout << ", " << *it_kept;
-  std::cout << std::endl;
-
-  std::cout<<"\n\n\n Objects to be remove: ";
-  std::set<std::string>::iterator it_remove;
-  for ( it_remove=removeObjects.begin(); it_remove!=removeObjects.end(); ++it_remove)
-    std::cout << ", " << *it_remove;
-  std::cout << std::endl;
-
-  sortObjects( myTreeKeptObjects, keptObjects );
-  sortObjects( myTreeRemoveObjects, removeObjects );
-
-  myTreeKeptObjects->collapseAll();
-  myTreeRemoveObjects->collapseAll();
+  bool isDisplayed = false;
+  if( theObjects.find( theObject->GetEntry() ) != theObjects.end() ) {
+    isDisplayed = myDisplayer.IsDisplayed( theObject->GetStudyEntry() );
+    if ( isDisplayed )
+      item->setVisible( true, myVisible );
+    else
+      item->setVisible( false, myInvisible );
 
+    if( myMainEntries.find( theObject->GetEntry() ) != myMainEntries.end() ) {
+      QFont Textfont = item->font(0);
+      Textfont.setBold( true );
+      item->setFont( 0, Textfont );
+    }
+  }
+  else {
+    item->setFlags( item->flags() & ~Qt::ItemIsSelectable );
+    item->setTextColor( 0, QColor( 150, 150, 150 ) );
+  }
+  return item;
 }
 
-void GEOMToolsGUI_ReduceStudyDlg::selectionChanged()
+//=================================================================================
+// function : findObjectInTree()
+// purpose  : find object in the tree
+//=================================================================================
+GEOMToolsGUI_TreeWidgetItem* GEOMToolsGUI_ReduceStudyDlg::findObjectInTree( QTreeWidget* theWidget, GEOM::GEOM_Object_var theObject )
 {
-  init( getSelectedObjects() );
+  QTreeWidgetItemIterator it( theWidget );
+  while(*it) {
+    GEOMToolsGUI_TreeWidgetItem* item = dynamic_cast<GEOMToolsGUI_TreeWidgetItem*>(*it);
+    if( QString( item->getStudyEntry() ) == QString( theObject->GetStudyEntry() ) )
+      return item;
+    ++it;
+  }
+  return NULL;
 }
 
-void GEOMToolsGUI_ReduceStudyDlg::clickOnOk()
+//=================================================================================
+// function : checkVisibleIcon()
+// purpose  : set visible or invisible icon in the header of tree
+//=================================================================================
+void GEOMToolsGUI_ReduceStudyDlg::checkVisibleIcon( QTreeWidget* theWidget )
 {
-
-  std::set<std::string> ObjectsToBeRemove = myRemovedObjects;
-  std::set<std::string> ObjectsToBeUnpublish;
-
-  if( myGroupIntermediates->checkedId() == 2 ) {
-    std::set<std::string>::iterator iter;
-    for( iter=myListParents.begin(); iter!=myListParents.end(); ++iter)
-      ObjectsToBeRemove.insert( *iter );
-  }
-  else if( myGroupIntermediates->checkedId() == 1 ) {
-    std::set<std::string>::iterator iter;
-    for( iter=myListParents.begin(); iter!=myListParents.end(); ++iter)
-      ObjectsToBeUnpublish.insert( *iter );
+  bool isInvisible = false;
+  QTreeWidgetItemIterator it( theWidget );
+  while(*it) {
+    GEOMToolsGUI_TreeWidgetItem* item = dynamic_cast<GEOMToolsGUI_TreeWidgetItem*>(*it);
+    //const char* entry = item->getStudyEntry();
+    if( item->flags() & Qt::ItemIsSelectable )
+      if( !item->isVisible() )
+        isInvisible = true;
+    ++it;
   }
 
-  if( myGroupSubObjects->checkedId() == 2 ) {
-    std::set<std::string>::iterator iter;
-    for( iter=myListSubObjects.begin(); iter!=myListSubObjects.end(); ++iter)
-      ObjectsToBeRemove.insert( *iter );
+  if( isInvisible ) {
+    theWidget->headerItem()->setIcon( 1, myInvisible );
+    myMapTreeSelectAll[ theWidget ] = false;
   }
-  else if( myGroupSubObjects->checkedId() == 1 ) {
-    std::set<std::string>::iterator iter;
-    for( iter=myListSubObjects.begin(); iter!=myListSubObjects.end(); ++iter)
-      ObjectsToBeUnpublish.insert( *iter );
+  else {
+    theWidget->headerItem()->setIcon( 1, myVisible );
+    myMapTreeSelectAll[ theWidget ] = true;
   }
-
-  unpublishObjects( ObjectsToBeUnpublish );
-  removeObjects( ObjectsToBeRemove );
-
-
-//  std::cout<< "\n\n REMOVE:" << std::endl;
-//  std::set<std::string>::iterator it;
-//  for( it = ObjectsToBeRemove.begin(); it != ObjectsToBeRemove.end(); ++it )
-//    std::cout <<"  " << (*it) << std::endl;
-//
-//  SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( SUIT_Session::session()->activeApplication() );
-//  if ( !app ) return;
-//  SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( app->activeStudy() );
-//  // get currently opened views
-//  QList<SALOME_View*> views;
-//  SALOME_View* view;
-//  ViewManagerList vmans = app->viewManagers();
-//  SUIT_ViewManager* vman;
-//  foreach ( vman, vmans ) {
-//    SUIT_ViewModel* vmod = vman->getViewModel();
-//    view = dynamic_cast<SALOME_View*> ( vmod ); // must work for OCC and VTK views
-//    if ( view )
-//      views.append( view );
-//  }
-//  _PTR(Study) aStudy = study->studyDS();
-
-
-//  _PTR(StudyBuilder) aStudyBuilder (aStudy->NewBuilder());
-//  _PTR(UseCaseBuilder) aUseCaseBuilder = aStudy->GetUseCaseBuilder();
-//
-//  for( it = ObjectsToBeRemove.begin(); it != ObjectsToBeRemove.end(); ++it ) {
-//    std::string objectEntry = *it;
-//    GEOM::GEOM_BaseObject_var GeomBaseObject = GeometryGUI::GetGeomGen()->GetObject( myStudyId, objectEntry.c_str() );
-//    GEOM::GEOM_Object_var GeomObject = GEOM::GEOM_Object::_narrow( GeomBaseObject );
-//    _PTR(SObject) obj = aStudy->FindObjectID( objectEntry.c_str() );
-//
-//    //Remove visual properties of the object
-//    study->removeObjectFromAll(objectEntry.c_str());
-//
-//    // remove object from study
-//    aStudyBuilder->RemoveObjectWithChildren( obj );
-////    // remove object from use case tree
-////    aUseCaseBuilder->Remove( obj );
-//
-//    // Erase graphical object
-//    QListIterator<SALOME_View*> it( views );
-//    while ( it.hasNext() )
-//      if ( SALOME_View* view = it.next() )
-//        myDisplayer.Erase( GeomObject, true, true, view);
-//
-//    GeometryGUI::GetGeomGen()->RemoveObject( GeomBaseObject );
-//  }
-//
-//  myDisplayer.UpdateViewer();
-//  GeometryGUI* aGeomGUI = dynamic_cast<GeometryGUI*>( app->module( "Geometry" ) );
-//  aGeomGUI->updateObjBrowser();
-//  app->updateActions(); //SRN: To update a Save button in the toolbar
-
-
-//  _PTR(StudyBuilder) B = aStudy->NewBuilder();
-//  for( it = ObjectsToBeUnpublish.begin(); it != ObjectsToBeUnpublish.end(); ++it ) {
-//    std::string objectEntry = *it;
-//    _PTR(SObject) obj ( aStudy->FindObjectID( objectEntry ) );
-//    _PTR(GenericAttribute) anAttr;
-//    if ( obj ) {
-//      _PTR(AttributeDrawable) aDrw = B->FindOrCreateAttribute( obj, "AttributeDrawable" );
-//      aDrw->SetDrawable( false );
-//      myDisplayer.EraseWithChildren( new SALOME_InteractiveObject( objectEntry.c_str(), "GEOM", "TEMP_IO" ) );
-//    } // if ( obj )
-//  } // iterator
-//
-//  app->updateObjectBrowser( false );
-//  app->updateActions();
-//
-
-//  LightApp_SelectionMgr* aSelMgr = app->selectionMgr();
-//  SALOME_ListIO aSelList;
-//
-//  for( it = ObjectsToBeUnpublish.begin(); it != ObjectsToBeUnpublish.end(); ++it ) {
-//    std::string objectEntry = *it;
-//    GEOM::GEOM_BaseObject_var GeomBaseObject = GeometryGUI::GetGeomGen()->GetObject( myStudyId, objectEntry.c_str() );
-//    GEOM::GEOM_Object_var GeomObject = GEOM::GEOM_Object::_narrow( GeomBaseObject );
-//    QString studyEntry = GeomBaseObject->GetStudyEntry();
-//    Handle(SALOME_InteractiveObject) tmpIO =
-//      new SALOME_InteractiveObject( studyEntry.toStdString().c_str(), "GEOM", "TEMP_IO");
-//    aSelList.Append(tmpIO);
-//
-//  }
-//  aSelMgr->clearSelected();
-//  aSelMgr->setSelectedObjects(aSelList);
-//  GEOMToolsGUI::OnUnpublishObject();
-
-  accept();
-
-
-
-//  if( myCBRemoveEmptyFolder->isChecked() ) {
-//
-//       SALOME_ListIO selected;
-//       SalomeApp_Application* app =
-//         dynamic_cast< SalomeApp_Application* >( SUIT_Session::session()->activeApplication() );
-//       if ( !app )
-//         return;
-//
-//       LightApp_SelectionMgr* aSelMgr = app->selectionMgr();
-//       SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*>( app->activeStudy() );
-//       if ( !aSelMgr || !appStudy )
-//         return;
-//
-//       // get selection
-//       aSelMgr->selectedObjects( selected, "ObjectBrowser", false );
-//       if ( selected.IsEmpty() )
-//         return;
-//
-//       _PTR(Study) aStudy = appStudy->studyDS();
-//       _PTR(UseCaseBuilder) aUseCaseBuilder = aStudy->GetUseCaseBuilder();
-//
-//         // ... and then delete all folders
-//         for ( it = toBeDelFolders.begin(); it != toBeDelFolders.end(); ++it ) {
-//           _PTR(SObject) obj ( aStudy->FindObjectID( it.key().toLatin1().data() ) );
-//           // remove object from GEOM engine
-//           removeObjectWithChildren( obj, aStudy, views, disp );
-//           // remove objects from study
-//           aStudyBuilder->RemoveObjectWithChildren( obj );
-//           // remove object from use case tree
-//           aUseCaseBuilder->Remove( obj );
-//         }
-//  }
 }
 
-////=======================================================================
-//// function : getGeomChildrenAndFolders
-//// purpose  : Get direct (1-level) GEOM objects under each folder, sub-folder, etc. and these folders itself
-////=======================================================================
-//static void getGeomChildrenAndFolders( _PTR(SObject) theSO,
-//                                       QMap<QString,QString>& geomObjList,
-//                                       QMap<QString,QString>& folderList ) {
-//  if ( !theSO ) return;
-//  _PTR(Study) aStudy = theSO->GetStudy();
-//  if ( !aStudy ) return;
-//  _PTR(UseCaseBuilder) aUseCaseBuilder = aStudy->GetUseCaseBuilder();
-//
-//  bool isFolder = false;
-//  _PTR(GenericAttribute) anAttr;
-//  if ( theSO->FindAttribute(anAttr, "AttributeLocalID") ) {
-//    _PTR(AttributeLocalID) aLocalID( anAttr );
-//    isFolder = aLocalID->Value() == 999;
-//  }
-//  QString anEntry = theSO->GetID().c_str();
-//  QString aName = theSO->GetName().c_str();
-//  if ( isFolder ) {
-//    folderList.insert( anEntry, aName );
-//    _PTR(UseCaseIterator) ucit ( aUseCaseBuilder->GetUseCaseIterator( theSO ) );
-//    for ( ucit->Init( false ); ucit->More(); ucit->Next() ) {
-//      getGeomChildrenAndFolders( ucit->Value(), geomObjList, folderList );
-//    }
-//  } else {
-//    geomObjList.insert( anEntry, aName );
-//  }
-//}
-
+//=================================================================================
+// function : isObjectDrawable()
+// purpose  : return true if object is drawable, and false if object is hidden in the study
+//=================================================================================
+bool GEOMToolsGUI_ReduceStudyDlg::isObjectDrawable( std::string theStudyEntry )
+{
+  _PTR(Study) aStudy = SalomeApp_Application::getStudy();
+  _PTR(StudyBuilder) aStudyBuilder = aStudy->NewBuilder();
+  //If object hasn't "AttributeDrawable" => it visible
+  bool isDrawable = true;
+  _PTR(SObject) SO ( aStudy->FindObjectID( theStudyEntry ) );
+  _PTR(GenericAttribute) anAttr;
+  if ( SO && SO->FindAttribute( anAttr, "AttributeDrawable" ) ) {
+    _PTR(AttributeDrawable) aDrw (anAttr);
+    isDrawable = aDrw->IsDrawable();
+  }
+  return isDrawable;
+}
 
+//=================================================================================
+// function : unpublishObjects()
+// purpose  : unpublish(hide) objects in the study
+//=================================================================================
 void GEOMToolsGUI_ReduceStudyDlg::unpublishObjects( std::set<std::string>& theObjects )
 {
-
+  _PTR(Study) aStudy = SalomeApp_Application::getStudy();
+  _PTR(StudyBuilder) aStudyBuilder = aStudy->NewBuilder();
+  std::set<std::string>::iterator it;
+  for( it = theObjects.begin(); it != theObjects.end(); ++it ) {
+    std::string objectEntry = *it;
+    GEOM::GEOM_BaseObject_var GeomBaseObject = GeometryGUI::GetGeomGen()->GetObject( objectEntry.c_str() );
+    std::string studyEntry = GeomBaseObject->GetStudyEntry();
+    if ( studyEntry == "" || !isObjectDrawable( studyEntry ) )
+      continue;
+    _PTR(SObject) obj ( aStudy->FindObjectID( studyEntry.c_str() ) );
+    _PTR(GenericAttribute) anAttr;
+    if ( obj ) {
+      _PTR(AttributeDrawable) aDrw = aStudyBuilder->FindOrCreateAttribute( obj, "AttributeDrawable" );
+      aDrw->SetDrawable( false );
+      myDisplayer.EraseWithChildren( new SALOME_InteractiveObject( studyEntry.c_str(), "GEOM", "TEMP_IO" ) );
+      // hide references if any
+      std::vector< _PTR(SObject) > vso = aStudy->FindDependances(obj);
+      for ( int i = 0; i < (int)vso.size(); i++ ) {
+        _PTR(SObject) refObj = vso[i];
+        aDrw = aStudyBuilder->FindOrCreateAttribute( refObj, "AttributeDrawable" );
+        aDrw->SetDrawable( false );
+      }
+    }
+  }
+  myApp->updateObjectBrowser( false );
+  myApp->updateActions();
 }
 
+//=================================================================================
+// function : removeObjects()
+// purpose  : remove objects from the study
+//=================================================================================
 void GEOMToolsGUI_ReduceStudyDlg::removeObjects( std::set<std::string>& theObjects )
 {
-
+  std::set<std::string>::iterator it;
+  for( it = theObjects.begin(); it != theObjects.end(); ++it ) {
+    std::string objectEntry = *it;
+    GEOM::GEOM_BaseObject_var GeomBaseObject = GeometryGUI::GetGeomGen()->GetObject( objectEntry.c_str() );
+    std::string studyEntry = GeomBaseObject->GetStudyEntry();
+    if ( studyEntry == "" )
+      GeometryGUI::GetGeomGen()->RemoveObject( GeomBaseObject );
+    else {
+      if( !isObjectDrawable( studyEntry ) )
+        continue;
+      removeObject( studyEntry );
+    }
+  }
+  myApp->updateObjectBrowser( false );
+  myApp->updateActions();
 }
 
+//=================================================================================
+// function : removeObject()
+// purpose  : remove object with given study entry
+//=================================================================================
+void GEOMToolsGUI_ReduceStudyDlg::removeObject( std::string& theStudyEntry )
+{
+  SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*>( myApp->activeStudy() );
+  _PTR(Study) aStudy = SalomeApp_Application::getStudy();
+  _PTR(StudyBuilder) aStudyBuilder = aStudy->NewBuilder();
+  _PTR(UseCaseBuilder) aUseCaseBuilder = aStudy->GetUseCaseBuilder();
+
+  _PTR(SObject) obj ( aStudy->FindObjectID( theStudyEntry.c_str() ) );
+  if ( obj ) {
+    // remove visual properties of the object
+    appStudy->removeObjectProperties(obj->GetID().c_str());
+    // remove references to this object
+    appStudy->deleteReferencesTo( obj );
+    // remove objects from study
+    aStudyBuilder->RemoveObjectWithChildren( obj );
+    // remove object from use case tree
+    aUseCaseBuilder->Remove( obj );
+    myDisplayer.EraseWithChildren( new SALOME_InteractiveObject( theStudyEntry.c_str(), "GEOM", "TEMP_IO" ) );
+  }
+}
 
-void GEOMToolsGUI_ReduceStudyDlg::clickOnCancel()
+//=================================================================================
+// function : removeEmptyFolders()
+// purpose  : remove empty folders from the study
+//=================================================================================
+void GEOMToolsGUI_ReduceStudyDlg::removeEmptyFolders()
 {
-  close();
+  std::set<std::string> emptyFolders;
+
+  _PTR(Study) aStudy = SalomeApp_Application::getStudy();
+  _PTR(SComponent) SC ( aStudy->FindComponent( "GEOM" ) );
+  if ( !SC )
+    return;
+  _PTR(ChildIterator) anIter ( aStudy->NewChildIterator( SC ) );
+  anIter->InitEx( true );
+  while( anIter->More() ) {
+    _PTR(SObject) valSO ( anIter->Value() );
+    _PTR(SObject) refSO;
+    if ( !valSO->ReferencedObject( refSO ) )
+      getEmptyFolders( valSO, emptyFolders );
+    anIter->Next();
+  }
+
+  std::set<std::string>::iterator iter;
+  for( iter = emptyFolders.begin(); iter != emptyFolders.end(); ++iter ) {
+    std::string studyEntry = *iter;
+    removeObject( studyEntry );
+  }
+  myApp->updateObjectBrowser( false );
+  myApp->updateActions();
 }
-void GEOMToolsGUI_ReduceStudyDlg::clickOnHelp()
+
+//=================================================================================
+// function : removeEmptyFolders()
+// purpose  : remove empty folders from the study
+//=================================================================================
+void GEOMToolsGUI_ReduceStudyDlg::getEmptyFolders( _PTR(SObject) theSO, std::set<std::string>& theFolders )
 {
+  _PTR(UseCaseBuilder) aUseCaseBuilder = SalomeApp_Application::getStudy()->GetUseCaseBuilder();
 
+  bool isFolder = false;
+  _PTR(GenericAttribute) anAttr;
+  if ( theSO->FindAttribute(anAttr, "AttributeLocalID") ) {
+    _PTR(AttributeLocalID) aLocalID( anAttr );
+    isFolder = aLocalID->Value() == 999;
+  }
+  QString studyEntry = theSO->GetID().c_str();
+  if ( isFolder ) {
+    if( !aUseCaseBuilder->HasChildren( theSO ) )
+      theFolders.insert( studyEntry.toStdString() );
+    else {
+      _PTR(UseCaseIterator) ucit ( aUseCaseBuilder->GetUseCaseIterator( theSO ) );
+      for ( ucit->Init( false ); ucit->More(); ucit->Next() )
+        getEmptyFolders( ucit->Value(), theFolders );
+    }
+  }
 }
 
 //=================================================================================
 // function : onItemClicked()
-// purpose  : Called then treeItem clicked
+// purpose  : called when tree item was clicked
 //=================================================================================
 void GEOMToolsGUI_ReduceStudyDlg::onItemClicked( QTreeWidgetItem* theItem, int theColumn )
 {
@@ -543,16 +541,20 @@ void GEOMToolsGUI_ReduceStudyDlg::onItemClicked( QTreeWidgetItem* theItem, int t
   checkVisibleIcon( item->treeWidget() );
 }
 
+//=================================================================================
+// function : onHeaderClicked()
+// purpose  : called when header item of tree was clicked
+//=================================================================================
 void GEOMToolsGUI_ReduceStudyDlg::onHeaderClicked( int theColumn )
 {
   if( theColumn != 1 )
     return;
 
-  QTreeWidget* treeData = dynamic_cast<QTreeWidget*>(sender()->parent());
-  if( myMapTreeSelectAll[ treeData ] ) {
-    myMapTreeSelectAll[ treeData ] = false;
-    treeData->headerItem()->setIcon( 1, myInvisible );
-    QTreeWidgetItemIterator it( treeData );
+  QTreeWidget* treeWidget = dynamic_cast<QTreeWidget*>(sender()->parent());
+  if( myMapTreeSelectAll[ treeWidget ] ) {
+    myMapTreeSelectAll[ treeWidget ] = false;
+    treeWidget->headerItem()->setIcon( 1, myInvisible );
+    QTreeWidgetItemIterator it( treeWidget );
     while(*it) {
       GEOMToolsGUI_TreeWidgetItem* item = dynamic_cast<GEOMToolsGUI_TreeWidgetItem*>(*it);
       if( ( item->flags() & Qt::ItemIsSelectable ) && item->isVisible() ) {
@@ -564,9 +566,9 @@ void GEOMToolsGUI_ReduceStudyDlg::onHeaderClicked( int theColumn )
     }
   }
   else {
-    myMapTreeSelectAll[ treeData ] = true;
-    treeData->headerItem()->setIcon( 1, myVisible );
-    QTreeWidgetItemIterator it( treeData );
+    myMapTreeSelectAll[ treeWidget ] = true;
+    treeWidget->headerItem()->setIcon( 1, myVisible );
+    QTreeWidgetItemIterator it( treeWidget );
     while(*it) {
       GEOMToolsGUI_TreeWidgetItem* item = dynamic_cast<GEOMToolsGUI_TreeWidgetItem*>(*it);
       if( ( item->flags() & Qt::ItemIsSelectable ) && !item->isVisible() ) {
@@ -580,130 +582,138 @@ void GEOMToolsGUI_ReduceStudyDlg::onHeaderClicked( int theColumn )
   myDisplayer.UpdateViewer();
 }
 
-void GEOMToolsGUI_ReduceStudyDlg::checkVisibleIcon( QTreeWidget* theWidget )
+//=================================================================================
+// function : selectionChanged()
+// purpose  : called when selection of object browser was changed
+//=================================================================================
+void GEOMToolsGUI_ReduceStudyDlg::selectionChanged()
 {
-  bool isInvisible = false;
-  QTreeWidgetItemIterator it( theWidget );
-  while(*it) {
-    GEOMToolsGUI_TreeWidgetItem* item = dynamic_cast<GEOMToolsGUI_TreeWidgetItem*>(*it);
-    const char* entry = item->getStudyEntry();
-    if( item->flags() & Qt::ItemIsSelectable )
-      if( !item->isVisible() )
-        isInvisible = true;
-    ++it;
+  init( getSelectedObjects() );
+}
+
+//=================================================================================
+// function : update()
+// purpose  : update tree data
+//=================================================================================
+void GEOMToolsGUI_ReduceStudyDlg::update()
+{
+  myTreeKeptObjects->clear();
+  myTreeRemoveObjects->clear();
+
+  std::set<std::string> keptObjects( myKeptObjects );
+  std::set<std::string> removeObjects( myRemovedObjects );
+
+  // Intermediate objects
+  if( myGroupIntermediates->checkedId() == 2 ) { // remove
+    std::set<std::string>::iterator iter;
+    for( iter=myListParents.begin(); iter!=myListParents.end(); ++iter)
+      removeObjects.insert( *iter );
+  }
+  else { // keep or unpublish
+    std::set<std::string>::iterator iter;
+    for( iter=myListParents.begin(); iter!=myListParents.end(); ++iter)
+      keptObjects.insert( *iter );
   }
 
-  if( isInvisible ) {
-    theWidget->headerItem()->setIcon( 1, myInvisible );
-    myMapTreeSelectAll[ theWidget ] = false;
+  // Sub-objects
+  if( myGroupSubObjects->checkedId() == 2 ) {
+    std::set<std::string>::iterator iter;
+    for( iter=myListSubObjects.begin(); iter!=myListSubObjects.end(); ++iter)
+      removeObjects.insert( *iter );
   }
   else {
-    theWidget->headerItem()->setIcon( 1, myVisible );
-    myMapTreeSelectAll[ theWidget ] = true;
+    std::set<std::string>::iterator iter;
+    for( iter=myListSubObjects.begin(); iter!=myListSubObjects.end(); ++iter)
+      keptObjects.insert( *iter );
   }
-}
 
-void GEOMToolsGUI_ReduceStudyDlg::sortObjects( QTreeWidget* theWidget, std::set<std::string>& theObjects )
-{
-  std::set<std::string>::iterator it;
-  for( it = theObjects.begin(); it != theObjects.end(); ++it ) {
-    std::string objectEntry = *it;
-    GEOM::GEOM_BaseObject_var GeomBaseObject = GeometryGUI::GetGeomGen()->GetObject( myStudy->StudyId(), objectEntry.c_str() );
-    GEOM::GEOM_Object_var GeomObject = GEOM::GEOM_Object::_narrow( GeomBaseObject );
-    QString studyEntry = GeomBaseObject->GetStudyEntry();
-    if( GeomObject->_is_nil() || studyEntry.isEmpty() )
-      continue;
-    addSubObject( theWidget, theObjects, GeomObject );
-  }
+  addObjectsToTree( myTreeKeptObjects, keptObjects );
+  addObjectsToTree( myTreeRemoveObjects, removeObjects );
+
+  myTreeKeptObjects->collapseAll();
+  myTreeRemoveObjects->collapseAll();
+
 }
 
-GEOMToolsGUI_TreeWidgetItem* GEOMToolsGUI_ReduceStudyDlg::addSubObject( QTreeWidget* theWidget, std::set<std::string>& theObjects, GEOM::GEOM_Object_var theObject )
+//=================================================================================
+// function : clickOnOk()
+// purpose  : called when OK button was clicked
+//=================================================================================
+void GEOMToolsGUI_ReduceStudyDlg::clickOnOk()
 {
-  GEOMToolsGUI_TreeWidgetItem* item;
-  if( !theObject->IsMainShape() ) {
-    GEOMToolsGUI_TreeWidgetItem* parentItem = addSubObject( theWidget, theObjects, theObject->GetMainShape() );
-    item = findObjectInTree( theWidget, theObject );
-    if( !item )
-      item = new GEOMToolsGUI_TreeWidgetItem( parentItem, QStringList() << theObject->GetName(), theObject->GetStudyEntry(), false );
+  std::set<std::string> objectsToBeRemoved = myRemovedObjects;
+  std::set<std::string> objectsToBeUnpublished;
+
+  // Create lists of intermediate objects to be removed or to be unpublished
+  std::set<std::string>::iterator iter;
+  if( myGroupIntermediates->checkedId() == 1 ) { // unpublish
+    for( iter = myListParents.begin(); iter != myListParents.end(); ++iter )
+    objectsToBeUnpublished.insert( *iter );
   }
-  else {
-    item = findObjectInTree( theWidget, theObject );
-    if( !item )
-      item = new GEOMToolsGUI_TreeWidgetItem( theWidget, QStringList() << theObject->GetName(), theObject->GetStudyEntry(), false );
+  if( myGroupIntermediates->checkedId() == 2 ) { // remove
+    if( !myCBSoftRemoval->isChecked() && 
+        SUIT_MessageBox::question( this,
+                                   tr( "GEOM_WRN_WARNING" ),
+                                   tr( "GEOM_REDUCE_STUDY_WARNING_DELETE" ),
+                                   QMessageBox::Yes | QMessageBox::No,
+                                   QMessageBox::Yes ) == QMessageBox::No ) {
+      return;
+    }
+    for( iter = myListParents.begin(); iter != myListParents.end(); ++iter )
+      objectsToBeRemoved.insert( *iter );
   }
 
-  bool isDisplayed = false;
-  if( theObjects.find( theObject->GetEntry() ) != theObjects.end() ) {
-    isDisplayed = myDisplayer.IsDisplayed( theObject->GetStudyEntry() );
-    if ( isDisplayed ) {
-      item->setVisible( true, myVisible );
-    }
-    else {
-      item->setVisible( false, myInvisible );
-    }
-    if( myMainEntries.find( theObject->GetEntry() ) != myMainEntries.end() ) {
-      QFont Textfont = item->font(0);
-      Textfont.setBold( true );
-      item->setFont( 0, Textfont );
-    }
+  // Create lists of sub-objects to be removed or to be unpublished
+  if( myGroupSubObjects->checkedId() == 1 ) { // unpublish
+    for( iter = myListSubObjects.begin(); iter != myListSubObjects.end(); ++iter )
+      objectsToBeUnpublished.insert( *iter );
+  }
+  else if( myGroupSubObjects->checkedId() == 2 ) { // remove
+    for( iter = myListSubObjects.begin(); iter != myListSubObjects.end(); ++iter )
+      objectsToBeRemoved.insert( *iter );
+  }
 
+  // if user chosen the soft removal
+  if( myCBSoftRemoval->isChecked() ) {
+    for( iter = objectsToBeRemoved.begin(); iter != objectsToBeRemoved.end(); ++iter )
+      objectsToBeUnpublished.insert( *iter );
+    unpublishObjects( objectsToBeUnpublished );
   }
   else {
-    item->setFlags( item->flags() & ~Qt::ItemIsSelectable );
-    item->setTextColor( 0, QColor( 150, 150, 150 ) );
+    unpublishObjects( objectsToBeUnpublished );
+    removeObjects( objectsToBeRemoved );
   }
 
-  return item;
-}
+  // if user want to delete the empty folders
+  if( myCBRemoveEmptyFolder->isChecked() )
+    removeEmptyFolders();
 
-GEOMToolsGUI_TreeWidgetItem* GEOMToolsGUI_ReduceStudyDlg::findObjectInTree( QTreeWidget* theWidget, GEOM::GEOM_Object_var theObject )
-{
-  QTreeWidgetItemIterator it( theWidget );
-  while(*it) {
-    GEOMToolsGUI_TreeWidgetItem* item = dynamic_cast<GEOMToolsGUI_TreeWidgetItem*>(*it);
-    if( QString( item->getStudyEntry() ) == QString( theObject->GetStudyEntry() ) )
-      return item;
-    ++it;
-  }
-  return NULL;
+  accept();
 }
 
-std::set<std::string> GEOMToolsGUI_ReduceStudyDlg::getSelectedObjects() const
+//=================================================================================
+// function : clickOnHelp()
+// purpose  : called when Help button was clicked to open a help page
+//=================================================================================
+void GEOMToolsGUI_ReduceStudyDlg::clickOnHelp()
 {
-  std::set<std::string> objects;
-
-  SALOME_ListIO selected;
-  myApp->selectionMgr()->selectedObjects( selected );
-
-  for( SALOME_ListIteratorOfListIO It( selected ); It.More(); It.Next() ) {
-    Handle( SALOME_InteractiveObject ) io = It.Value();
-    if( !io->hasEntry() )
-      continue;
-    GEOM::GEOM_Object_var geomObject = GEOM::GEOM_Object::_nil();
-    geomObject = GEOMBase::ConvertIOinGEOMObject( io );
-    if( geomObject->_is_nil() )
-      continue;
-    QString entry = geomObject->GetEntry();
-    objects.insert( entry.toStdString().c_str() );
-  }
-  return objects;
+  myApp->onHelpContextModule( "GEOM", "reduce_study_page.html" );
 }
+
 GEOMToolsGUI_TreeWidgetItem::GEOMToolsGUI_TreeWidgetItem( QTreeWidget* view, const QStringList &strings,
-                                                          char* studyEntry, bool visible, int type )
+                                                          char* studyEntry, int type )
 :QTreeWidgetItem( view, strings, type ),
- myStudyEntry( studyEntry ),
- myVisible( visible )
+ myVisible( false ),
+ myStudyEntry( studyEntry )
 {
-
 }
 
 GEOMToolsGUI_TreeWidgetItem::GEOMToolsGUI_TreeWidgetItem( QTreeWidgetItem* parent, const QStringList &strings,
-                                                          char* studyEntry, bool visible, int type )
+                                                          char* studyEntry, int type )
 :QTreeWidgetItem( parent, strings, type ),
- myStudyEntry( studyEntry ),
- myVisible( visible )
+ myVisible( false ),
+ myStudyEntry( studyEntry )
 {
-
 }
 
 GEOMToolsGUI_TreeWidgetItem::~GEOMToolsGUI_TreeWidgetItem()