Salome HOME
Define color for part result
[modules/shaper.git] / src / XGUI / XGUI_Workshop.cpp
index dfa21b5da8fd497137d746a0f453fa2ff352b00c..0f6cd8c773be3290069b876b37757c29c288d54b 100644 (file)
@@ -18,6 +18,7 @@
 #include "XGUI_ModuleConnector.h"
 #include <XGUI_QtEvents.h>
 #include <XGUI_HistoryMenu.h>
+#include <XGUI_CustomPrs.h>
 
 #include <AppElements_Workbench.h>
 #include <AppElements_Viewer.h>
@@ -67,6 +68,8 @@
 #include <Config_PropManager.h>
 #include <Config_SelectionFilterMessage.h>
 
+#include <SUIT_ResourceMgr.h>
+
 #include <QApplication>
 #include <QFileDialog>
 #include <QMessageBox>
@@ -79,6 +82,7 @@
 #include <QMenu>
 #include <QToolButton>
 #include <QAction>
+#include <QDesktopWidget>
 
 #ifdef _DEBUG
 #include <QDebug>
@@ -93,7 +97,7 @@
 
 //#define DEBUG_FEATURE_CREATED
 //#define DEBUG_FEATURE_REDISPLAY
-
+//#define DEBUG_DELETE
 
 XGUI_Workshop::XGUI_Workshop(XGUI_SalomeConnector* theConnector)
     : QObject(),
@@ -109,14 +113,23 @@ XGUI_Workshop::XGUI_Workshop(XGUI_SalomeConnector* theConnector)
 {
   myMainWindow = mySalomeConnector ? 0 : new AppElements_MainWindow();
 
+  if (myMainWindow) {
+    SUIT_ResourceMgr* aResMgr = ModuleBase_Preferences::resourceMgr();
+    bool aCloc = aResMgr->booleanValue("language", "locale", true);
+    if (aCloc)
+      QLocale::setDefault( QLocale::c() );
+    else 
+      QLocale::setDefault( QLocale::system() );
+  }
+
   myDisplayer = new XGUI_Displayer(this);
 
   mySelector = new XGUI_SelectionMgr(this);
   //connect(mySelector, SIGNAL(selectionChanged()), this, SLOT(updateModuleCommands()));
 
-  myOperationMgr = new XGUI_OperationMgr(this);
+  myOperationMgr = new XGUI_OperationMgr(this, 0);
   myActionsMgr = new XGUI_ActionsMgr(this);
-  myErrorDlg = new XGUI_ErrorDialog(myMainWindow);
+  myErrorDlg = new XGUI_ErrorDialog(QApplication::desktop());
   myContextMenuMgr = new XGUI_ContextMenuMgr(this);
   connect(myContextMenuMgr, SIGNAL(actionTriggered(const QString&, bool)), this,
           SLOT(onContextMenuCommand(const QString&, bool)));
@@ -126,6 +139,7 @@ XGUI_Workshop::XGUI_Workshop(XGUI_SalomeConnector* theConnector)
           myActionsMgr,  SLOT(updateOnViewSelection()));
 
   myModuleConnector = new XGUI_ModuleConnector(this);
+  myOperationMgr->setWorkshop(moduleConnector());
 
   connect(myOperationMgr, SIGNAL(operationStarted(ModuleBase_Operation*)), 
           SLOT(onOperationStarted(ModuleBase_Operation*)));
@@ -137,8 +151,21 @@ XGUI_Workshop::XGUI_Workshop(XGUI_SalomeConnector* theConnector)
           SLOT(onOperationCommitted(ModuleBase_Operation*)));
   connect(myOperationMgr, SIGNAL(operationAborted(ModuleBase_Operation*)), 
           SLOT(onOperationAborted(ModuleBase_Operation*)));
-  connect(myMainWindow, SIGNAL(exitKeySequence()), SLOT(onExit()));
+  if (myMainWindow)
+    connect(myMainWindow, SIGNAL(exitKeySequence()), SLOT(onExit()));
   connect(this, SIGNAL(errorOccurred(const QString&)), myErrorDlg, SLOT(addError(const QString&)));
+
+  //Config_PropManager::registerProp("Visualization", "object_default_color", "Object color",
+  //                                 Config_Prop::Color, "225,225,225");
+
+  Config_PropManager::registerProp("Visualization", "result_body_color", "Body color",
+                                   Config_Prop::Color, ModelAPI_ResultBody::DEFAULT_COLOR());
+  Config_PropManager::registerProp("Visualization", "result_group_color", "Group color",
+                                   Config_Prop::Color, ModelAPI_ResultGroup::DEFAULT_COLOR());
+  Config_PropManager::registerProp("Visualization", "result_construction_color", "Construction color",
+                                   Config_Prop::Color, ModelAPI_ResultConstruction::DEFAULT_COLOR());
+  Config_PropManager::registerProp("Visualization", "result_part_color", "Part color",
+                                   Config_Prop::Color, ModelAPI_ResultPart::DEFAULT_COLOR());
 }
 
 //******************************************************
@@ -175,7 +202,7 @@ void XGUI_Workshop::startApplication()
   // Calling of  loadCustomProps before activating module is required
   // by Config_PropManger to restore user-defined path to plugins
   ModuleBase_Preferences::loadCustomProps();
-  activateModule();
+  createModule();
   if (myMainWindow) {
     myMainWindow->show();
     updateCommandStatus();
@@ -186,6 +213,29 @@ void XGUI_Workshop::startApplication()
   emit applicationStarted();
 }
 
+void XGUI_Workshop::activateModule()
+{
+  myModule->activateSelectionFilters();
+
+  connect(myDisplayer, SIGNAL(objectDisplayed(ObjectPtr, AISObjectPtr)),
+    myModule, SLOT(onObjectDisplayed(ObjectPtr, AISObjectPtr)));
+  connect(myDisplayer, SIGNAL(beforeObjectErase(ObjectPtr, AISObjectPtr)),
+    myModule, SLOT(onBeforeObjectErase(ObjectPtr, AISObjectPtr)));
+
+  myActionsMgr->update();
+
+}
+
+void XGUI_Workshop::deactivateModule()
+{
+  myModule->deactivateSelectionFilters();
+
+  disconnect(myDisplayer, SIGNAL(objectDisplayed(ObjectPtr, AISObjectPtr)),
+    myModule, SLOT(onObjectDisplayed(ObjectPtr, AISObjectPtr)));
+  disconnect(myDisplayer, SIGNAL(beforeObjectErase(ObjectPtr, AISObjectPtr)),
+    myModule, SLOT(onBeforeObjectErase(ObjectPtr, AISObjectPtr)));
+}
+
 //******************************************************
 void XGUI_Workshop::initMenu()
 {
@@ -231,7 +281,7 @@ void XGUI_Workshop::initMenu()
 
   AppElements_Command* aCommand;
 
-  aCommand = aGroup->addFeature("SAVE_CMD", tr("Save..."), tr("Save the document"),
+  aCommand = aGroup->addFeature("SAVE_CMD", tr("Save"), tr("Save the document"),
                                 QIcon(":pictures/save.png"), QKeySequence::Save);
   aCommand->connectTo(this, SLOT(onSave()));
   //aCommand->disable();
@@ -378,6 +428,7 @@ void XGUI_Workshop::processEvent(const std::shared_ptr<Events_Message>& theMessa
   } else if (theMessage->eventID() == Events_Loop::eventByName(EVENT_UPDATE_VIEWER_UNBLOCKED)) {
     // the viewer's update context is unblocked, the viewer's update works
     myDisplayer->enableUpdateViewer(true);
+    myDisplayer->updateViewer();
   } else {
     //Show error dialog if error message received.
     std::shared_ptr<Events_Error> anAppError = std::dynamic_pointer_cast<Events_Error>(theMessage);
@@ -468,25 +519,12 @@ void XGUI_Workshop::onFeatureRedisplayMsg(const std::shared_ptr<ModelAPI_ObjectU
         // of redisplay is called. This modification is made in order to have the line is updated
         // by creation of a horizontal constraint on the line by preselection
         myDisplayer->redisplay(aObj, false);
-        if (myOperationMgr->hasOperation()) {
-          ModuleBase_Operation* aOperation = myOperationMgr->currentOperation();
-          if (!aOperation->isEditOperation() &&
-              aOperation->hasObject(aObj) && myDisplayer->isActive(aObj))
-            myDisplayer->deactivate(aObj);
-        }
+        // Deactivate object of current operation from selection
+        deactivateActiveObject(aObj, false);
       } else { // display object if the current operation has it
         if (displayObject(aObj)) {
-          ModuleBase_Operation* aOperation = myOperationMgr->currentOperation();
-          if (aOperation && aOperation->hasObject(aObj)) {
-            ModuleBase_Operation* aOperation = myOperationMgr->currentOperation();
-            #ifdef DEBUG_FEATURE_REDISPLAY
-              QString anObjInfo = ModuleBase_Tools::objectInfo((aObj));
-              qDebug(QString("  display object = %1").arg(anObjInfo).toStdString().c_str());
-            #endif
-            // Deactivate object of current operation from selection
-            if (myDisplayer->isActive(aObj))
-              myDisplayer->deactivate(aObj);
-          }
+          // Deactivate object of current operation from selection
+          deactivateActiveObject(aObj, false);
         }
       }
     }
@@ -494,6 +532,15 @@ void XGUI_Workshop::onFeatureRedisplayMsg(const std::shared_ptr<ModelAPI_ObjectU
   myDisplayer->updateViewer();
 }
 
+//******************************************************
+void XGUI_Workshop::deactivateActiveObject(const ObjectPtr& theObject, const bool theUpdateViewer)
+{
+  if (!myModule->canActivateSelection(theObject)) {
+    if (myDisplayer->isActive(theObject))
+      myDisplayer->deactivate(theObject, theUpdateViewer);
+  }
+}
+
 //******************************************************
 void XGUI_Workshop::onFeatureCreatedMsg(const std::shared_ptr<ModelAPI_ObjectUpdatedMessage>& theMsg)
 {
@@ -515,8 +562,9 @@ void XGUI_Workshop::onFeatureCreatedMsg(const std::shared_ptr<ModelAPI_ObjectUpd
     // the validity of the data should be checked here in order to avoid display of the objects,
     // which were created, then deleted, but flush for the creation event happens after that
     // we should not display disabled objects
-    bool aHide = !anObject->data() || !anObject->data()->isValid() || 
-      anObject->isDisabled() || (!anObject->isDisplayed());
+    bool aHide = !anObject->data()->isValid() || 
+                 anObject->isDisabled() ||
+                 !anObject->isDisplayed();
     if (!aHide) {
       // setDisplayed has to be called in order to synchronize internal state of the object 
       // with list of displayed objects
@@ -547,7 +595,22 @@ void XGUI_Workshop::onOperationStarted(ModuleBase_Operation* theOperation)
   }
   updateCommandStatus();
 
-  myModule->operationStarted(theOperation);
+  myModule->onOperationStarted(theOperation);
+
+  // the objects of the current operation should be deactivated
+  QObjectPtrList anObjects;
+  FeaturePtr aFeature = theOperation->feature();
+  anObjects.append(aFeature);
+  std::list<ResultPtr> aResults = aFeature->results();
+  std::list<ResultPtr>::const_iterator aIt;
+  for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) {
+    anObjects.append(*aIt);
+  }
+  QObjectPtrList::const_iterator anIt = anObjects.begin(), aLast = anObjects.end();
+  for (; anIt != aLast; anIt++)
+    deactivateActiveObject(*anIt, false);
+  if (anObjects.size() > 0)
+    myDisplayer->updateViewer();
 }
 
 //******************************************************
@@ -561,7 +624,7 @@ void XGUI_Workshop::onOperationResumed(ModuleBase_Operation* theOperation)
   }
   updateCommandStatus();
 
-  myModule->operationResumed(theOperation);
+  myModule->onOperationResumed(theOperation);
 }
 
 
@@ -575,39 +638,36 @@ void XGUI_Workshop::onOperationStopped(ModuleBase_Operation* theOperation)
   hidePropertyPanel();
   myPropertyPanel->cleanContent();
 
-  // Activate objects created by current operation 
-  // in order to clean selection modes
-  // the deactivation should be pefromed in the same place, where the mode is activated,
-  // e.g. activation in the current widget activation, deactivation - in the widget's deactivation
-  //QIntList aModes;
-  //myDisplayer->activateObjects(aModes);
-  myModule->operationStopped(theOperation);
-
-  // if the operation is nested, do not deactivate objects
-  //if (myOperationMgr->operationsCount() == 0) {
-    // Activate selection mode for all objects
+  myModule->onOperationStopped(theOperation);
+
+  // the deactivated objects of the current operation should be activated back.
+  // They were deactivated on operation start or an object redisplay
+  QObjectPtrList anObjects;
+  FeaturePtr aFeature = theOperation->feature();
+  if (myDisplayer->isVisible(aFeature) && !myDisplayer->isActive(aFeature))
+    anObjects.append(aFeature);
+  std::list<ResultPtr> aResults = aFeature->results();
+  std::list<ResultPtr>::const_iterator aIt;
+  for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) {
+    ResultPtr anObject = *aIt;
+    if (myDisplayer->isVisible(anObject) && !myDisplayer->isActive(anObject)) {
+      anObjects.append(anObject);
+    }
+  }
   QIntList aModes;
-  // TODO: check on OCC_6.9.0
-  // the module current active modes should not be deactivated in order to save the objects selected
-  // the deactivate object in the mode of selection leads to the object is deselected in the viewer.
-  // But, in OCC_6.8.0 this deselection does not happened automatically. It is necessary to call
-  // ClearOutdatedSelection, but this method has an error in the realization, which should be fixed in
-  // the OCC_6.9.0 release. Moreother, it is possible that ClearOutdatedSelection will be called inside
-  // Deactivate method of AIS_InteractiveContext. In this case, we need not call it.
   module()->activeSelectionModes(aModes);
-  myDisplayer->activateObjects(aModes);
-  //}
+  myDisplayer->activateObjects(aModes, anObjects);
 }
 
 
 void XGUI_Workshop::onOperationCommitted(ModuleBase_Operation* theOperation)
 {
-  myModule->operationCommitted(theOperation);
+  myModule->onOperationCommitted(theOperation);
 }
 
 void XGUI_Workshop::onOperationAborted(ModuleBase_Operation* theOperation)
 {
-  myModule->operationAborted(theOperation);
+  myModule->onOperationAborted(theOperation);
 }
 
 void XGUI_Workshop::setNestedFeatures(ModuleBase_Operation* theOperation)
@@ -834,7 +894,7 @@ void XGUI_Workshop::onOpen()
   }
 
   //show file dialog, check if readable and open
-  myCurrentDir = QFileDialog::getExistingDirectory(mainWindow());
+  myCurrentDir = QFileDialog::getExistingDirectory(mainWindow(), tr("Select folder"));
   if (myCurrentDir.isEmpty())
     return;
   QFileInfo aFileInfo(myCurrentDir);
@@ -876,7 +936,7 @@ bool XGUI_Workshop::onSaveAs()
   if(!isActiveOperationAborted())
     return false;
   QFileDialog dialog(mainWindow());
-  dialog.setWindowTitle(tr("Select directory to save files..."));
+  dialog.setWindowTitle(tr("Select folder to save files..."));
   dialog.setFileMode(QFileDialog::Directory);
   dialog.setFilter(tr("Folders (*)"));
   dialog.setOptions(QFileDialog::HideNameFilterDetails | QFileDialog::ShowDirsOnly);
@@ -885,6 +945,7 @@ bool XGUI_Workshop::onSaveAs()
   if (!dialog.exec()) {
     return false;
   }
+
   QString aTempDir = dialog.selectedFiles().first();
   QDir aDir(aTempDir);
   if (aDir.exists() && !aDir.entryInfoList(QDir::NoDotAndDotDot | QDir::AllEntries).isEmpty()) {
@@ -1040,7 +1101,7 @@ ModuleBase_IModule* XGUI_Workshop::loadModule(const QString& theModule)
 }
 
 //******************************************************
-bool XGUI_Workshop::activateModule()
+bool XGUI_Workshop::createModule()
 {
   Config_ModuleReader aModuleReader;
   QString moduleName = QString::fromStdString(aModuleReader.getModuleName());
@@ -1048,13 +1109,13 @@ bool XGUI_Workshop::activateModule()
   if (!myModule)
     return false;
 
-  connect(myDisplayer, SIGNAL(objectDisplayed(ObjectPtr, AISObjectPtr)),
-    myModule, SLOT(onObjectDisplayed(ObjectPtr, AISObjectPtr)));
-  connect(myDisplayer, SIGNAL(beforeObjectErase(ObjectPtr, AISObjectPtr)),
-    myModule, SLOT(onBeforeObjectErase(ObjectPtr, AISObjectPtr)));
+  //connect(myDisplayer, SIGNAL(objectDisplayed(ObjectPtr, AISObjectPtr)),
+  //  myModule, SLOT(onObjectDisplayed(ObjectPtr, AISObjectPtr)));
+  //connect(myDisplayer, SIGNAL(beforeObjectErase(ObjectPtr, AISObjectPtr)),
+  //  myModule, SLOT(onBeforeObjectErase(ObjectPtr, AISObjectPtr)));
 
   myModule->createFeatures();
-  myActionsMgr->update();
+  //myActionsMgr->update();
   return true;
 }
 
@@ -1071,20 +1132,16 @@ void XGUI_Workshop::updateCommandStatus()
   }
   SessionPtr aMgr = ModelAPI_Session::get();
   if (aMgr->hasModuleDocument()) {
-    QAction *aUndoCmd, *aRedoCmd;
     foreach(QAction* aCmd, aCommands) {
       QString aId = aCmd->data().toString();
       if (aId == "UNDO_CMD")
-        aUndoCmd = aCmd;
+        aCmd->setEnabled(myModule->canUndo());
       else if (aId == "REDO_CMD")
-        aRedoCmd = aCmd;
+        aCmd->setEnabled(myModule->canRedo());
       else
         // Enable all commands
         aCmd->setEnabled(true);
     }
-
-    aUndoCmd->setEnabled(myModule->canUndo());
-    aRedoCmd->setEnabled(myModule->canRedo());
     updateHistory();
   } else {
     foreach(QAction* aCmd, aCommands) {
@@ -1195,15 +1252,15 @@ void XGUI_Workshop::hideObjectBrowser()
 }
 
 //******************************************************
-void XGUI_Workshop::onFeatureTriggered()
-{
-  QAction* aCmd = dynamic_cast<QAction*>(sender());
-  if (aCmd) {
-    QString aId = salomeConnector()->commandId(aCmd);
-    if (!aId.isNull())
-      myModule->launchOperation(aId);
-  }
-}
+//void XGUI_Workshop::onFeatureTriggered()
+//{
+//  QAction* aCmd = dynamic_cast<QAction*>(sender());
+//  if (aCmd) {
+//    QString aId = salomeConnector()->commandId(aCmd);
+//    if (!aId.isNull())
+//      myModule->launchOperation(aId);
+//  }
+//}
 
 //******************************************************
 void XGUI_Workshop::salomeViewerSelectionChanged()
@@ -1277,7 +1334,8 @@ void XGUI_Workshop::deleteObjects()
   SessionPtr aMgr = ModelAPI_Session::get();
   aMgr->startOperation(aDescription.toStdString());
   // 2. close the documents of the removed parts if the result part is in a list of selected objects
-  foreach (ObjectPtr aObj, anObjects)
+  // this is performed in the RemoveFeature of Part object.
+  /*foreach (ObjectPtr aObj, anObjects)
   {
     ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(aObj);
     if (aPart) {
@@ -1286,7 +1344,7 @@ void XGUI_Workshop::deleteObjects()
         aDoc->close();
       }
     }
-  }
+  }*/
   // 3. delete objects
   QMainWindow* aDesktop = isSalomeMode() ? salomeConnector()->desktop() : myMainWindow;
   std::set<FeaturePtr> anIgnoredFeatures;
@@ -1308,10 +1366,65 @@ bool XGUI_Workshop::deleteFeatures(const QObjectPtrList& theList,
 {
   // 1. find all referenced features
   std::set<FeaturePtr> aRefFeatures;
-  foreach (ObjectPtr aObj, theList) {
-    FeaturePtr aFeature = ModelAPI_Feature::feature(aObj);
-    if (aFeature.get() != NULL) {
-      aObj->document()->refsToFeature(aFeature, aRefFeatures, false);
+  foreach (ObjectPtr aDeletedObj, theList) {
+    FeaturePtr aDeletedFeature = ModelAPI_Feature::feature(aDeletedObj);
+    if (aDeletedFeature.get() != NULL) {
+      DocumentPtr aDeletedFeatureDoc = aDeletedObj->document();
+      // 1.1 find references in the current document
+      aDeletedFeatureDoc->refsToFeature(aDeletedFeature, aRefFeatures, false);
+      // 1.2 find references in all documents if the document of the feature is
+      // "PartSet". Features of this document can be used in all other documents
+      SessionPtr aMgr = ModelAPI_Session::get();
+      DocumentPtr aModuleDoc = aMgr->moduleDocument();
+      if (aDeletedFeatureDoc == aModuleDoc) {
+        // the deleted feature and results of the feature should be found in references
+        std::list<ObjectPtr> aDeletedObjects;
+        aDeletedObjects.push_back(aDeletedFeature);
+        typedef std::list<std::shared_ptr<ModelAPI_Result> > ResultsList;
+        const ResultsList& aDeletedResults = aDeletedFeature->results();
+        ResultsList::const_iterator aRIter = aDeletedResults.begin();
+        for (; aRIter != aDeletedResults.cend(); aRIter++) {
+          ResultPtr aRes = *aRIter;
+          if (aRes.get())
+            aDeletedObjects.push_back(aRes);
+        }
+        // get all opened documents; found features in the documents;
+        // get a list of objects where a feature refers;
+        // search in these objects the deleted objects.
+        std::list<DocumentPtr> anOpenedDocs = aMgr->allOpenedDocuments();
+        std::list<DocumentPtr>::const_iterator anIt = anOpenedDocs.begin(),
+                                               aLast = anOpenedDocs.end();
+        std::list<std::pair<std::string, std::list<ObjectPtr> > > aRefs;
+        for (; anIt != aLast; anIt++) {
+          DocumentPtr aDocument = *anIt;
+          if (aDocument == aDeletedFeatureDoc)
+            continue; // this document has been already processed in 1.1
+
+          int aFeaturesCount = aDocument->size(ModelAPI_Feature::group());
+          for (int aId = 0; aId < aFeaturesCount; aId++) {
+            ObjectPtr anObject = aDocument->object(ModelAPI_Feature::group(), aId);
+            FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(anObject);
+            if (!aFeature.get())
+              continue;
+
+            aRefs.clear();
+            aFeature->data()->referencesToObjects(aRefs);
+            std::list<std::pair<std::string, std::list<ObjectPtr> > >::iterator aRef = aRefs.begin();
+            bool aHasReferenceToDeleted = false;
+            for(; aRef != aRefs.end() && !aHasReferenceToDeleted; aRef++) {
+              std::list<ObjectPtr>::iterator aRefObj = aRef->second.begin();
+              for(; aRefObj != aRef->second.end() && !aHasReferenceToDeleted; aRefObj++) {
+                std::list<ObjectPtr>::const_iterator aDelIt = aDeletedObjects.begin();
+                for(; aDelIt != aDeletedObjects.end() && !aHasReferenceToDeleted; aDelIt++) {
+                  aHasReferenceToDeleted = *aDelIt == *aRefObj;
+                }
+              }
+            }
+            if (aHasReferenceToDeleted)
+              aRefFeatures.insert(aFeature);
+          }
+        }
+      }
     }
   }
   // 2. warn about the references remove, break the delete operation if the user chose it
@@ -1336,22 +1449,52 @@ These features will be deleted also. Would you like to continue?")).arg(aNames),
   // 3. remove referenced features
   std::set<FeaturePtr>::const_iterator anIt = aRefFeatures.begin(),
                                        aLast = aRefFeatures.end();
+#ifdef DEBUG_DELETE
+  QStringList anInfo;
+#endif
   for (; anIt != aLast; anIt++) {
     FeaturePtr aFeature = (*anIt);
     DocumentPtr aDoc = aFeature->document();
-    if (theIgnoredFeatures.find(aFeature) == theIgnoredFeatures.end())
+    if (theIgnoredFeatures.find(aFeature) == theIgnoredFeatures.end()) {
       aDoc->removeFeature(aFeature);
+#ifdef DEBUG_DELETE
+      anInfo.append(ModuleBase_Tools::objectInfo(aFeature).toStdString().c_str());
+#endif
+    }
   }
+#ifdef DEBUG_DELETE
+  qDebug(QString("remove references:%1").arg(anInfo.join("; ")).toStdString().c_str());
+  anInfo.clear();
+#endif
 
   // 4. remove the parameter features
   foreach (ObjectPtr aObj, theList) {
+    ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(aObj);
+    if (aResult.get() != NULL) { // results could not be removed,
+      // they are removed by a corresponded feature remove
+      continue;
+    }
     FeaturePtr aFeature = ModelAPI_Feature::feature(aObj);
     if (aFeature) {
+      // TODO: to learn the workshop to delegate the Part object deletion to the PartSet module
+      // part features are removed in the PartSet module. This condition should be moved there
+      if (aFeature->getKind() == "Part")
+        continue;
+
       DocumentPtr aDoc = aObj->document();
-      if (theIgnoredFeatures.find(aFeature) == theIgnoredFeatures.end())
+      if (theIgnoredFeatures.find(aFeature) == theIgnoredFeatures.end()) {
         aDoc->removeFeature(aFeature);
+#ifdef DEBUG_DELETE
+        QString anInfoStr = ModuleBase_Tools::objectInfo(aFeature);
+        anInfo.append(anInfoStr);
+        qDebug(QString("remove feature :%1").arg(anInfoStr).toStdString().c_str());
+#endif
+      }
     }
   }
+#ifdef DEBUG_DELETE
+  qDebug(QString("remove features:%1").arg(anInfo.join("; ")).toStdString().c_str());
+#endif
   return true;
 }
 
@@ -1422,20 +1565,25 @@ void XGUI_Workshop::changeColor(const QObjectPtrList& theObjects)
           ObjectPtr aObject = aPartDoc->object(ModelAPI_ResultBody::group(), 0);
           ResultBodyPtr aBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(aObject);
           if (aBody.get()) {
-            std::string aSection, aName, aDefault;
-            aBody->colorConfigInfo(aSection, aName, aDefault);
-            if (!aSection.empty() && !aName.empty()) {
-              aColor = Config_PropManager::color(aSection, aName, aDefault);
-            }
+            XGUI_CustomPrs::getResultColor(aBody, aColor);
           }
         }
       }
     }
     else {
-      AISObjectPtr anAISObj = myDisplayer->getAISObject(anObject);
-      if (anAISObj.get()) {
-        aColor.resize(3);
-        anAISObj->getColor(aColor[0], aColor[1], aColor[2]);
+      ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(anObject);
+      if (aResult.get())
+        XGUI_CustomPrs::getResultColor(aResult, aColor);
+      else {
+        // TODO: remove the obtaining a color from the AIS object
+        // this does not happen never because:
+        // 1. The color can be changed only on results
+        // 2. The result can be not visualized in the viewer(e.g. Origin Construction)
+        AISObjectPtr anAISObj = myDisplayer->getAISObject(anObject);
+        if (anAISObj.get()) {
+          aColor.resize(3);
+          anAISObj->getColor(aColor[0], aColor[1], aColor[2]);
+        }
       }
     }
     if (!aColor.empty())
@@ -1492,29 +1640,50 @@ void XGUI_Workshop::changeColor(const QObjectPtrList& theObjects)
 }
 
 //**************************************************************
+#define SET_DISPLAY_GROUP(aGroupName, aDisplay) \
+for (int i = 0; i < aDoc->size(aGroupName); i++) { \
+  aDoc->object(aGroupName, i)->setDisplayed(aDisplay); \
+}
 void XGUI_Workshop::showObjects(const QObjectPtrList& theList, bool isVisible)
 {
   foreach (ObjectPtr aObj, theList) {
-    if (isVisible) {
-      aObj->setDisplayed(true);
-      //displayObject(aObj);
+    /*
+    ResultPartPtr aPartRes = std::dynamic_pointer_cast<ModelAPI_ResultPart>(aObj);
+    if (aPartRes) {
+      DocumentPtr aDoc = aPartRes->partDoc();
+      SET_DISPLAY_GROUP(ModelAPI_ResultBody::group(), isVisible)
+      SET_DISPLAY_GROUP(ModelAPI_ResultConstruction::group(), isVisible)
+      SET_DISPLAY_GROUP(ModelAPI_ResultGroup::group(), isVisible)
     } else {
-      aObj->setDisplayed(false);
-      //myDisplayer->erase(aObj, false);
-    }
+    */
+      aObj->setDisplayed(isVisible);
+    //}
   }
   Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
-  //myDisplayer->updateViewer();
 }
 
 //**************************************************************
 void XGUI_Workshop::showOnlyObjects(const QObjectPtrList& theList)
 {
+  // Hide all displayed objects
   QObjectPtrList aList = myDisplayer->displayedObjects();
   foreach (ObjectPtr aObj, aList)
     aObj->setDisplayed(false);
-  foreach (ObjectPtr aObj, theList)
-    aObj->setDisplayed(true);
+
+  // Show only objects from the list
+  foreach (ObjectPtr aObj, theList) {
+    /*
+    ResultPartPtr aPartRes = std::dynamic_pointer_cast<ModelAPI_ResultPart>(aObj);
+    if (aPartRes) {
+      DocumentPtr aDoc = aPartRes->partDoc();
+      SET_DISPLAY_GROUP(ModelAPI_ResultBody::group(), true)
+      SET_DISPLAY_GROUP(ModelAPI_ResultConstruction::group(), true)
+      SET_DISPLAY_GROUP(ModelAPI_ResultGroup::group(), true)
+    } else {
+    */
+      aObj->setDisplayed(true);
+    //}
+  }
   Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
 
 }
@@ -1528,7 +1697,7 @@ void XGUI_Workshop::registerValidators() const
 }
 
 //**************************************************************
-void XGUI_Workshop::displayAllResults()
+/*void XGUI_Workshop::displayAllResults()
 {
   SessionPtr aMgr = ModelAPI_Session::get();
   DocumentPtr aRootDoc = aMgr->moduleDocument();
@@ -1539,7 +1708,7 @@ void XGUI_Workshop::displayAllResults()
     displayDocumentResults(aPart->partDoc());
   }
   myDisplayer->updateViewer();
-}
+}*/
 
 //**************************************************************
 void XGUI_Workshop::displayDocumentResults(DocumentPtr theDoc)