Salome HOME
Correction for the previous integration
[modules/shaper.git] / src / XGUI / XGUI_Workshop.cpp
index 20d21f7918956375d98b5fea10b52997840bd520..84cbda90551f8c23f60403aa6ea4cfa55bd591c9 100644 (file)
@@ -1,47 +1,50 @@
 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
 
 //#include "XGUI_Constants.h"
-#include "XGUI_Tools.h"
 #include "XGUI_Workshop.h"
-#include "XGUI_SelectionMgr.h"
-#include "XGUI_Selection.h"
-#include "XGUI_ObjectsBrowser.h"
-#include "XGUI_Displayer.h"
-#include "XGUI_OperationMgr.h"
-#include "XGUI_SalomeConnector.h"
+
 #include "XGUI_ActionsMgr.h"
-#include "XGUI_ErrorDialog.h"
 #include "XGUI_ColorDialog.h"
-#include "XGUI_ViewerProxy.h"
-#include "XGUI_PropertyPanel.h"
 #include "XGUI_ContextMenuMgr.h"
+#include "XGUI_Displayer.h"
+#include "XGUI_ErrorDialog.h"
+#include "XGUI_ErrorMgr.h"
 #include "XGUI_ModuleConnector.h"
-#include <XGUI_QtEvents.h>
+#include "XGUI_ObjectsBrowser.h"
+#include "XGUI_OperationMgr.h"
+#include "XGUI_PropertyPanel.h"
+#include "XGUI_SalomeConnector.h"
+#include "XGUI_Selection.h"
+#include "XGUI_SelectionMgr.h"
+#include "XGUI_Tools.h"
+#include "XGUI_ViewerProxy.h"
+#include "XGUI_WorkshopListener.h"
+#include <XGUI_CustomPrs.h>
 #include <XGUI_HistoryMenu.h>
+#include <XGUI_QtEvents.h>
 
-#include <AppElements_Workbench.h>
-#include <AppElements_Viewer.h>
+#include <AppElements_Button.h>
 #include <AppElements_Command.h>
 #include <AppElements_MainMenu.h>
 #include <AppElements_MainWindow.h>
 #include <AppElements_MenuGroupPanel.h>
-#include <AppElements_Button.h>
-
-#include <ModuleBase_IModule.h>
-#include <ModuleBase_Preferences.h>
+#include <AppElements_Viewer.h>
+#include <AppElements_Workbench.h>
 
+#include <ModelAPI_AttributeDocRef.h>
+#include <ModelAPI_AttributeIntArray.h>
+#include <ModelAPI_Data.h>
 #include <ModelAPI_Events.h>
-#include <ModelAPI_Session.h>
 #include <ModelAPI_Feature.h>
-#include <ModelAPI_Data.h>
-#include <ModelAPI_AttributeDocRef.h>
 #include <ModelAPI_Object.h>
-#include <ModelAPI_Validator.h>
-#include <ModelAPI_ResultGroup.h>
-#include <ModelAPI_ResultConstruction.h>
 #include <ModelAPI_ResultBody.h>
-#include <ModelAPI_AttributeIntArray.h>
+#include <ModelAPI_ResultConstruction.h>
+#include <ModelAPI_ResultGroup.h>
 #include <ModelAPI_ResultParameter.h>
+#include <ModelAPI_Session.h>
+#include <ModelAPI_Validator.h>
+#include <ModelAPI_ResultCompSolid.h>
+#include <ModelAPI_Tools.h>
 
 //#include <PartSetPlugin_Part.h>
 
 #include <Events_Error.h>
 #include <Events_LongOp.h>
 
-#include <ModuleBase_Operation.h>
+#include <ModuleBase_FilterFactory.h>
+#include <ModuleBase_IModule.h>
+#include <ModuleBase_IViewer.h>
 #include <ModuleBase_Operation.h>
 #include <ModuleBase_OperationDescription.h>
-#include <ModuleBase_SelectionValidator.h>
-#include <ModuleBase_WidgetFactory.h>
-#include <ModuleBase_Tools.h>
-#include <ModuleBase_IViewer.h>
-#include <ModuleBase_FilterFactory.h>
 #include <ModuleBase_PageBase.h>
+#include <ModuleBase_Preferences.h>
+#include <ModuleBase_SelectionValidator.h>
 #include <ModuleBase_Tools.h>
+#include <ModuleBase_WidgetFactory.h>
+#include <ModuleBase_OperationFeature.h>
+#include <ModuleBase_OperationAction.h>
 
 #include <Config_Common.h>
 #include <Config_FeatureMessage.h>
-#include <Config_PointerMessage.h>
 #include <Config_ModuleReader.h>
+#include <Config_PointerMessage.h>
 #include <Config_PropManager.h>
 #include <Config_SelectionFilterMessage.h>
 
+#include <SUIT_ResourceMgr.h>
+
 #include <QApplication>
 #include <QFileDialog>
 #include <QMessageBox>
@@ -79,6 +86,9 @@
 #include <QMenu>
 #include <QToolButton>
 #include <QAction>
+#include <QDesktopWidget>
+
+#include <iterator>
 
 #ifdef _DEBUG
 #include <QDebug>
 #include <dlfcn.h>
 #endif
 
-//#define DEBUG_FEATURE_CREATED
-//#define DEBUG_FEATURE_REDISPLAY
-
+//#define DEBUG_DELETE
 
 XGUI_Workshop::XGUI_Workshop(XGUI_SalomeConnector* theConnector)
     : QObject(),
@@ -102,21 +110,27 @@ XGUI_Workshop::XGUI_Workshop(XGUI_SalomeConnector* theConnector)
       mySalomeConnector(theConnector),
       myPropertyPanel(0),
       myObjectBrowser(0),
-      myDisplayer(0),
-      myUpdatePrefs(false),
-      myPartActivating(false),
-      myIsLoadingData(false)
+      myDisplayer(0)
 {
   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)));
@@ -127,6 +141,12 @@ XGUI_Workshop::XGUI_Workshop(XGUI_SalomeConnector* theConnector)
 
   myModuleConnector = new XGUI_ModuleConnector(this);
 
+  ModuleBase_IWorkshop* aWorkshop = moduleConnector();
+  myOperationMgr->setWorkshop(aWorkshop);
+
+  myErrorMgr = new XGUI_ErrorMgr(this, aWorkshop);
+  myEventsListener = new XGUI_WorkshopListener(aWorkshop);
+
   connect(myOperationMgr, SIGNAL(operationStarted(ModuleBase_Operation*)), 
           SLOT(onOperationStarted(ModuleBase_Operation*)));
   connect(myOperationMgr, SIGNAL(operationResumed(ModuleBase_Operation*)),
@@ -137,8 +157,26 @@ 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()));
+  //connect(myOperationMgr, SIGNAL(validationStateChanged(bool)), 
+  //        myErrorMgr, SLOT(onValidationStateChanged()));
+
+  if (myMainWindow)
+    connect(myMainWindow, SIGNAL(exitKeySequence()), SLOT(onExit()));
   connect(this, SIGNAL(errorOccurred(const QString&)), myErrorDlg, SLOT(addError(const QString&)));
+  connect(myEventsListener, 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());
 }
 
 //******************************************************
@@ -156,28 +194,14 @@ void XGUI_Workshop::startApplication()
                                    Config_Prop::Directory, "");
 
   //Initialize event listening
-  Events_Loop* aLoop = Events_Loop::loop();
-  aLoop->registerListener(this, Events_Error::errorID());  //!< Listening application errors.
-  aLoop->registerListener(this, Events_Loop::eventByName(Config_FeatureMessage::GUI_EVENT()));
-  aLoop->registerListener(this, Events_Loop::eventByName(EVENT_OPERATION_LAUNCHED));
-  aLoop->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
-  aLoop->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_CREATED));
-  aLoop->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
-  aLoop->registerListener(this, Events_LongOp::eventID());
-  aLoop->registerListener(this, Events_Loop::eventByName(EVENT_PLUGIN_LOADED));
-  aLoop->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_TOSHOW));
-  aLoop->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_TOHIDE));
-  aLoop->registerListener(this, Events_Loop::eventByName(EVENT_SELFILTER_LOADED));
-
-  aLoop->registerListener(this, Events_Loop::eventByName(EVENT_UPDATE_VIEWER_BLOCKED));
-  aLoop->registerListener(this, Events_Loop::eventByName(EVENT_UPDATE_VIEWER_UNBLOCKED));
+  myEventsListener->initializeEventListening();
 
   registerValidators();
 
   // 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();
@@ -188,6 +212,42 @@ 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();
+
+  // activate visualized objects in the viewer
+  XGUI_Displayer* aDisplayer = displayer();
+  QObjectPtrList aDisplayed = aDisplayer->displayedObjects();
+  QIntList aModes;
+  module()->activeSelectionModes(aModes);
+  aDisplayer->activateObjects(aModes, aDisplayed);
+}
+
+void XGUI_Workshop::deactivateModule()
+{
+  myModule->deactivateSelectionFilters();
+
+  // remove internal displayer filter
+  displayer()->deactivateSelectionFilters();
+
+  disconnect(myDisplayer, SIGNAL(objectDisplayed(ObjectPtr, AISObjectPtr)),
+    myModule, SLOT(onObjectDisplayed(ObjectPtr, AISObjectPtr)));
+  disconnect(myDisplayer, SIGNAL(beforeObjectErase(ObjectPtr, AISObjectPtr)),
+    myModule, SLOT(onBeforeObjectErase(ObjectPtr, AISObjectPtr)));
+
+  XGUI_Displayer* aDisplayer = displayer();
+  QObjectPtrList aDisplayed = aDisplayer->displayedObjects();
+  aDisplayer->deactivateObjects(aDisplayed, true);
+}
+
 //******************************************************
 void XGUI_Workshop::initMenu()
 {
@@ -199,12 +259,17 @@ void XGUI_Workshop::initMenu()
                                                          tr("Undo last command"),
                                                          QIcon(":pictures/undo.png"),
                                                          QKeySequence::Undo, false, "MEN_DESK_EDIT");
+    QString aToolBarTitle = tr( "INF_DESK_TOOLBAR_STANDARD" );
+    salomeConnector()->addActionInToolbar( aAction,aToolBarTitle  );
+
     connect(aAction, SIGNAL(triggered(bool)), this, SLOT(onUndo()));
     addHistoryMenu(aAction, SIGNAL(updateUndoHistory(const QList<ActionInfo>&)), SLOT(onUndo(int)));
 
     aAction = salomeConnector()->addDesktopCommand("REDO_CMD", tr("Redo"), tr("Redo last command"),
                                                 QIcon(":pictures/redo.png"), QKeySequence::Redo,
                                                 false, "MEN_DESK_EDIT");
+    salomeConnector()->addActionInToolbar( aAction, aToolBarTitle );
+
     connect(aAction, SIGNAL(triggered(bool)), this, SLOT(onRedo()));
     addHistoryMenu(aAction, SIGNAL(updateRedoHistory(const QList<ActionInfo>&)), SLOT(onRedo(int)));
 
@@ -212,6 +277,8 @@ void XGUI_Workshop::initMenu()
     aAction = salomeConnector()->addDesktopCommand("REBUILD_CMD", tr("Rebuild"), tr("Rebuild data objects"),
                                                 QIcon(":pictures/rebuild.png"), QKeySequence(),
                                                 false, "MEN_DESK_EDIT");
+    salomeConnector()->addActionInToolbar( aAction, aToolBarTitle );
+
     connect(aAction, SIGNAL(triggered(bool)), this, SLOT(onRebuild()));
     salomeConnector()->addDesktopMenuSeparator("MEN_DESK_EDIT");
 
@@ -233,7 +300,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();
@@ -295,124 +362,6 @@ AppElements_Workbench* XGUI_Workshop::addWorkbench(const QString& theName)
   return aMenuBar->addWorkbench(theName);
 }
 
-//******************************************************
-void XGUI_Workshop::processEvent(const std::shared_ptr<Events_Message>& theMessage)
-{
-  if (QApplication::instance()->thread() != QThread::currentThread()) {
-    #ifdef _DEBUG
-    std::cout << "XGUI_Workshop::processEvent: " << "Working in another thread." << std::endl;
-    #endif
-    SessionPtr aMgr = ModelAPI_Session::get();
-    PostponeMessageQtEvent* aPostponeEvent = new PostponeMessageQtEvent(theMessage);
-    QApplication::postEvent(this, aPostponeEvent);
-    return;
-  }
-
-  //A message to start feature creation received.
-  if (theMessage->eventID() == Events_Loop::loop()->eventByName(Config_FeatureMessage::GUI_EVENT())) {
-    std::shared_ptr<Config_FeatureMessage> aFeatureMsg =
-       std::dynamic_pointer_cast<Config_FeatureMessage>(theMessage);
-    if (!aFeatureMsg->isInternal()) {
-      addFeature(aFeatureMsg);
-    }
-  }
-  // Process creation of Part
-  else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_CREATED)) {
-    std::shared_ptr<ModelAPI_ObjectUpdatedMessage> aUpdMsg =
-        std::dynamic_pointer_cast<ModelAPI_ObjectUpdatedMessage>(theMessage);
-    onFeatureCreatedMsg(aUpdMsg);
-    if (myUpdatePrefs) {
-      if (mySalomeConnector)
-        mySalomeConnector->createPreferences();
-      myUpdatePrefs = false;
-    }
-  }
-  else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_PLUGIN_LOADED)) {
-    myUpdatePrefs = true;
-  }
-  // Redisplay feature
-  else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY)) {
-    std::shared_ptr<ModelAPI_ObjectUpdatedMessage> aUpdMsg =
-        std::dynamic_pointer_cast<ModelAPI_ObjectUpdatedMessage>(theMessage);
-    onFeatureRedisplayMsg(aUpdMsg);
-  }
-  //Update property panel on corresponding message. If there is no current operation (no
-  //property panel), or received message has different feature to the current - do nothing.
-  else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_UPDATED)) {
-    std::shared_ptr<ModelAPI_ObjectUpdatedMessage> anUpdateMsg =
-        std::dynamic_pointer_cast<ModelAPI_ObjectUpdatedMessage>(theMessage);
-    onFeatureUpdatedMsg(anUpdateMsg);
-  } else if (theMessage->eventID() == Events_LongOp::eventID()) {
-    if (Events_LongOp::isPerformed()) {
-      QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
-    } else {
-      QApplication::restoreOverrideCursor();
-    }
-  } else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_TOSHOW)) {
-    std::shared_ptr<ModelAPI_ObjectUpdatedMessage> anUpdateMsg =
-        std::dynamic_pointer_cast<ModelAPI_ObjectUpdatedMessage>(theMessage);
-    const std::set<ObjectPtr>& aObjList = anUpdateMsg->objects();
-    QObjectPtrList aList;
-    std::set<ObjectPtr>::const_iterator aIt;
-    for (aIt = aObjList.cbegin(); aIt != aObjList.cend(); ++aIt)
-      aList.append(*aIt);
-    showObjects(aList, true);
-  } else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_TOHIDE)) {
-    std::shared_ptr<ModelAPI_ObjectUpdatedMessage> anUpdateMsg =
-        std::dynamic_pointer_cast<ModelAPI_ObjectUpdatedMessage>(theMessage);
-    const std::set<ObjectPtr>& aObjList = anUpdateMsg->objects();
-    QObjectPtrList aList;
-    std::set<ObjectPtr>::const_iterator aIt;
-    for (aIt = aObjList.cbegin(); aIt != aObjList.cend(); ++aIt)
-      aList.append(*aIt);
-    showObjects(aList, false);
-  }
-  //An operation passed by message. Start it, process and commit.
-  else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OPERATION_LAUNCHED)) {
-    std::shared_ptr<Config_PointerMessage> aPartSetMsg =
-        std::dynamic_pointer_cast<Config_PointerMessage>(theMessage);
-    //myPropertyPanel->cleanContent();
-    ModuleBase_Operation* anOperation = (ModuleBase_Operation*) aPartSetMsg->pointer();
-
-    if (myOperationMgr->startOperation(anOperation)) {
-      myPropertyPanel->updateContentWidget(anOperation->feature());
-      if (!anOperation->getDescription()->hasXmlRepresentation()) {
-        if (anOperation->commit())
-          updateCommandStatus();
-      }
-    }
-  } 
-  else if (theMessage->eventID() == Events_Loop::eventByName(EVENT_SELFILTER_LOADED)) {
-    std::shared_ptr<Config_SelectionFilterMessage> aMsg = 
-      std::dynamic_pointer_cast<Config_SelectionFilterMessage>(theMessage);
-    if (aMsg) {
-      ModuleBase_FilterFactory* aFactory = moduleConnector()->selectionFilters();
-      if (!aMsg->attributeId().empty()) {
-        aFactory->assignFilter(aMsg->selectionFilterId(), aMsg->featureId(), aMsg->attributeId(),
-                               aMsg->parameters());
-      }
-    }
-  } else if (theMessage->eventID() == Events_Loop::eventByName(EVENT_UPDATE_VIEWER_BLOCKED)) {
-    // the viewer's update context will not happens until viewer updated is emitted
-    myDisplayer->enableUpdateViewer(false);
-  } 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);
-  } else {
-    //Show error dialog if error message received.
-    std::shared_ptr<Events_Error> anAppError = std::dynamic_pointer_cast<Events_Error>(theMessage);
-    if (anAppError) {
-      emit errorOccurred(QString::fromLatin1(anAppError->description()));
-    }
-    return;
-  }
-  if (!isSalomeMode()) {
-    SessionPtr aMgr = ModelAPI_Session::get();
-    if (aMgr->isModified() != myMainWindow->isModifiedState())
-      myMainWindow->setModifiedState(aMgr->isModified());
-  }
-}
-
 //******************************************************
 QMainWindow* XGUI_Workshop::desktop() const
 {
@@ -428,217 +377,193 @@ void XGUI_Workshop::onStartWaiting()
 }
 
 //******************************************************
-void XGUI_Workshop::onFeatureUpdatedMsg(const std::shared_ptr<ModelAPI_ObjectUpdatedMessage>& theMsg)
-{
-  std::set<ObjectPtr> aFeatures = theMsg->objects();
-  if (myOperationMgr->hasOperation()) {
-    FeaturePtr aCurrentFeature = myOperationMgr->currentOperation()->feature();
-    std::set<ObjectPtr>::const_iterator aIt;
-    for (aIt = aFeatures.begin(); aIt != aFeatures.end(); ++aIt) {
-      ObjectPtr aNewFeature = (*aIt);
-      if (aNewFeature == aCurrentFeature) {
-        myPropertyPanel->updateContentWidget(aCurrentFeature);
-        break;
-      }
+void XGUI_Workshop::onAcceptActionClicked()
+{
+  QAction* anAction = dynamic_cast<QAction*>(sender());
+  XGUI_OperationMgr* anOperationMgr = operationMgr();
+  if (anOperationMgr) {
+    ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+                                                    (anOperationMgr->currentOperation());
+    if (aFOperation) {
+      if (errorMgr()->canProcessClick(anAction, aFOperation->feature()))
+        myOperationMgr->onCommitOperation();
     }
   }
-  myOperationMgr->onValidateOperation();
-  //if (myObjectBrowser)
-  //  myObjectBrowser->processEvent(theMsg);
 }
 
 //******************************************************
-void XGUI_Workshop::onFeatureRedisplayMsg(const std::shared_ptr<ModelAPI_ObjectUpdatedMessage>& theMsg)
+/*void XGUI_Workshop::onValidationStateChanged(bool theEnabled)
 {
-  std::set<ObjectPtr> aObjects = theMsg->objects();
-  std::set<ObjectPtr>::const_iterator aIt;
-
-#ifdef DEBUG_FEATURE_REDISPLAY
-  QStringList anInfo;
-  for (aIt = aObjects.begin(); aIt != aObjects.end(); ++aIt) {
-    anInfo.append(ModuleBase_Tools::objectInfo((*aIt)));
+  XGUI_OperationMgr* anOperationMgr = operationMgr();
+  if (anOperationMgr) {
+    ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+                                                    (anOperationMgr->currentOperation());
+    if (aFOperation) {
+      QAction* anAction = myActionsMgr->operationStateAction(XGUI_ActionsMgr::Accept);
+      myErrorMgr->updateActionState(anAction, aFOperation->feature(), theEnabled);
+    }
   }
-  QString anInfoStr = anInfo.join(", ");
-  qDebug(QString("onFeatureRedisplayMsg: %1, %2").arg(aObjects.size()).arg(anInfoStr).toStdString().c_str());
-#endif
+}*/
 
-  for (aIt = aObjects.begin(); aIt != aObjects.end(); ++aIt) {
-    ObjectPtr aObj = (*aIt);
 
-    // Hide the object if it is invalid or concealed one
-    bool aHide = !aObj->data() || !aObj->data()->isValid();
-    if (!aHide) { // check that this is not hidden result
-      ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(aObj);
-      aHide = aRes && aRes->isConcealed();
-    }
-    if (aHide)
-      myDisplayer->erase(aObj, false);
-    else {
-      // Redisplay the visible object or the object of the current operation
-      bool isVisibleObject = myDisplayer->isVisible(aObj);
-      #ifdef DEBUG_FEATURE_REDISPLAY
-      //QString anObjInfo = ModuleBase_Tools::objectInfo((aObj));
-      //qDebug(QString("visible=%1 : display= %2").arg(isVisibleObject).arg(anObjInfo).toStdString().c_str());
-      #endif
-
-      if (isVisibleObject)  { // redisplay visible object
-        //displayObject(aObj);  // In order to update presentation
-        // in order to avoid the check whether the object can be redisplayed, the exact method
-        // 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);
-        }
-      } else { // display object if the current operation has it
-        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
-          if (displayObject(aObj)) {
-            // Deactivate object of current operation from selection
-            if (myDisplayer->isActive(aObj))
-              myDisplayer->deactivate(aObj);
-          }
-        }
-      }
+//******************************************************
+void XGUI_Workshop::deactivateActiveObject(const ObjectPtr& theObject, const bool theUpdateViewer)
+{
+  if (!myModule->canActivateSelection(theObject)) {
+    if (myDisplayer->isActive(theObject)) {
+      QObjectPtrList anObjects;
+      anObjects.append(theObject);
+      myDisplayer->deactivateObjects(anObjects, theUpdateViewer);
     }
   }
-  myDisplayer->updateViewer();
 }
 
 //******************************************************
-void XGUI_Workshop::onFeatureCreatedMsg(const std::shared_ptr<ModelAPI_ObjectUpdatedMessage>& theMsg)
+bool XGUI_Workshop::isFeatureOfNested(const FeaturePtr& theFeature)
 {
-  std::set<ObjectPtr> aObjects = theMsg->objects();
-  std::set<ObjectPtr>::const_iterator aIt;
-#ifdef DEBUG_FEATURE_CREATED
-  QStringList anInfo;
-  for (aIt = aObjects.begin(); aIt != aObjects.end(); ++aIt) {
-    anInfo.append(ModuleBase_Tools::objectInfo((*aIt)));
-  }
-  QString anInfoStr = anInfo.join(", ");
-  qDebug(QString("onFeatureCreatedMsg: %1, %2").arg(aObjects.size()).arg(anInfoStr).toStdString().c_str());
-#endif
-
-  //bool aHasPart = false;
-  bool isDisplayed = false;
-  for (aIt = aObjects.begin(); aIt != aObjects.end(); ++aIt) {
-    ObjectPtr anObject = *aIt;
-    // 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
-    if (!anObject->data() || !anObject->data()->isValid())
-      continue;
-    //ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aIt);
-    //if (aPart) {
-      //aHasPart = true;
-      // If a feature is created from the aplication's python console  
-      // it doesn't stored in the operation mgr and doesn't displayed
-    //} else {
-    isDisplayed = displayObject(*aIt);
-    //}
+  bool aHasNested = false;
+  std::string aFeatureKind = theFeature->getKind();
+  if (isSalomeMode()) {
+    XGUI_SalomeConnector* aSalomeConnector = salomeConnector();
+    if (aSalomeConnector->isFeatureOfNested(actionsMgr()->action(aFeatureKind.c_str())))
+      aHasNested = true;
+  } else {
+    AppElements_MainMenu* aMenuBar = mainWindow()->menuObject();
+    AppElements_Command* aCommand = aMenuBar->feature(aFeatureKind.c_str());
+    if (aCommand && aCommand->button()->additionalButtonWidget())
+      aHasNested = true;
   }
-  //if (myObjectBrowser)
-  //  myObjectBrowser->processEvent(theMsg);
-  if (isDisplayed)
-    myDisplayer->updateViewer();
-  //if (aHasPart) { // TODO: Avoid activate last part on loading of document
-  //  activateLastPart();
-  //}
+  return aHasNested;
 }
 
 //******************************************************
 void XGUI_Workshop::onOperationStarted(ModuleBase_Operation* theOperation)
 {
-  setNestedFeatures(theOperation);
+  setGrantedFeatures(theOperation);
 
-  if (theOperation->getDescription()->hasXmlRepresentation()) {  //!< No need for property panel
-    connectWithOperation(theOperation);
-    setPropertyPanel(theOperation);
+  ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+                                                                               (theOperation);
+  if (!aFOperation)
+    return;
+
+  if (aFOperation->getDescription()->hasXmlRepresentation()) {  //!< No need for property panel
+    setPropertyPanel(aFOperation);
+    // filling the operation values by the current selection
+    // if the operation can be committed after the controls filling, the method perform should
+    // be stopped. Otherwise unnecessary presentations can be shown(e.g. operation prs in sketch)
+    if (!aFOperation->isEditOperation()) {
+      aFOperation->activateByPreselection();
+      if (operationMgr()->currentOperation() != aFOperation)
+        return;
+    }
   }
   updateCommandStatus();
 
-  myModule->operationStarted(theOperation);
+  myModule->onOperationStarted(aFOperation);
+
+  // the objects of the current operation should be deactivated
+  QObjectPtrList anObjects;
+  FeaturePtr aFeature = aFOperation->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();
 }
 
 //******************************************************
 void XGUI_Workshop::onOperationResumed(ModuleBase_Operation* theOperation)
 {
-  setNestedFeatures(theOperation);
+  setGrantedFeatures(theOperation);
 
   if (theOperation->getDescription()->hasXmlRepresentation()) {  //!< No need for property panel
-    // connectWithOperation(theOperation); already connected
     setPropertyPanel(theOperation);
   }
   updateCommandStatus();
 
-  myModule->operationResumed(theOperation);
+  myModule->onOperationResumed(theOperation);
 }
 
 
 //******************************************************
 void XGUI_Workshop::onOperationStopped(ModuleBase_Operation* theOperation)
 {
+  updateCommandStatus();
+
+  ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+                                                                        (theOperation);
+  if (!aFOperation)
+    return;
+
   ModuleBase_ISelection* aSel = mySelector->selection();
   QObjectPtrList aObj = aSel->selectedPresentations();
   //!< No need for property panel
-  updateCommandStatus();
   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(aFOperation);
+
+  // 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 = aFOperation->feature();
+  if (aFeature.get()) { // feature may be not created (plugin load fail)
+    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)
+void XGUI_Workshop::setGrantedFeatures(ModuleBase_Operation* theOperation)
 {
-  if (this->isSalomeMode()) 
-    theOperation->setNestedFeatures(mySalomeConnector->nestedActions(theOperation->id()));
-  else 
-    theOperation->setNestedFeatures(myActionsMgr->nestedCommands(theOperation->id()));
+  ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>(theOperation);
+  if (!aFOperation)
+    return;
+
+  QStringList aGrantedIds;
+  if (isSalomeMode())
+    aGrantedIds = mySalomeConnector->nestedActions(theOperation->id());
+  else
+    aGrantedIds = myActionsMgr->nestedCommands(theOperation->id());
+
+  aFOperation->setGrantedOperationIds(aGrantedIds);
 }
 
 void XGUI_Workshop::setPropertyPanel(ModuleBase_Operation* theOperation)
 {
+  ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>(theOperation);
+  if (!aFOperation)
+    return;
+
   showPropertyPanel();
-  QString aXmlRepr = theOperation->getDescription()->xmlRepresentation();
+  QString aXmlRepr = aFOperation->getDescription()->xmlRepresentation();
   ModuleBase_WidgetFactory aFactory = ModuleBase_WidgetFactory(aXmlRepr.toStdString(),
                                                                 myModuleConnector);
 
@@ -647,130 +572,21 @@ void XGUI_Workshop::setPropertyPanel(ModuleBase_Operation* theOperation)
 
   QList<ModuleBase_ModelWidget*> aWidgets = aFactory.getModelWidgets();
   foreach (ModuleBase_ModelWidget* aWidget, aWidgets) {
-    bool isStoreValue = !theOperation->isEditOperation() &&
+    bool isStoreValue = !aFOperation->isEditOperation() &&
                         !aWidget->getDefaultValue().empty() &&
                         !aWidget->isComputedDefault();
-    aWidget->setFeature(theOperation->feature(), isStoreValue);
+    aWidget->setFeature(aFOperation->feature(), isStoreValue);
     aWidget->enableFocusProcessing();
   }
   
   myPropertyPanel->setModelWidgets(aWidgets);
-  theOperation->setPropertyPanel(myPropertyPanel);
+  aFOperation->setPropertyPanel(myPropertyPanel);
 
   myModule->propertyPanelDefined(theOperation);
 
   myPropertyPanel->setWindowTitle(theOperation->getDescription()->description());
-}
 
-bool XGUI_Workshop::event(QEvent * theEvent)
-{
-  PostponeMessageQtEvent* aPostponedEv = dynamic_cast<PostponeMessageQtEvent*>(theEvent);
-  if (aPostponedEv) {
-    std::shared_ptr<Events_Message> aEventPtr = aPostponedEv->postponedMessage();
-    processEvent(aEventPtr);
-    return true;
-  }
-  return false;
-}
-
-/*
- *
- */
-void XGUI_Workshop::addFeature(const std::shared_ptr<Config_FeatureMessage>& theMessage)
-{
-  if (!theMessage) {
-#ifdef _DEBUG
-    qDebug() << "XGUI_Workshop::addFeature: NULL message.";
-#endif
-    return;
-  }
-  ActionInfo aFeatureInfo;
-  aFeatureInfo.initFrom(theMessage);
-
-  QString aWchName = QString::fromStdString(theMessage->workbenchId());
-  QStringList aNestedFeatures =
-      QString::fromStdString(theMessage->nestedFeatures()).split(" ", QString::SkipEmptyParts);
-  QString aDocKind = QString::fromStdString(theMessage->documentKind());
-  QList<QAction*> aNestedActList;
-  bool isColumnButton = !aNestedFeatures.isEmpty();
-  if (isColumnButton) {
-    QString aNestedActions = QString::fromStdString(theMessage->actionsWhenNested());
-    if (aNestedActions.contains("accept")) {
-      QAction* anAction = myActionsMgr->operationStateAction(XGUI_ActionsMgr::AcceptAll, NULL);
-      connect(anAction, SIGNAL(triggered()), myOperationMgr, SLOT(commitAllOperations()));
-      aNestedActList << anAction;
-    }
-    if (aNestedActions.contains("abort")) {
-      QAction* anAction = myActionsMgr->operationStateAction(XGUI_ActionsMgr::AbortAll, NULL);
-      connect(anAction, SIGNAL(triggered()), myOperationMgr, SLOT(abortAllOperations()));
-      aNestedActList << anAction;
-    }
-  }
-
-  if (isSalomeMode()) {
-    QAction* aAction;
-    if (isColumnButton) {
-      aAction = salomeConnector()->addNestedFeature(aWchName, aFeatureInfo, aNestedActList);
-    } else {
-      aAction = salomeConnector()->addFeature(aWchName, aFeatureInfo);
-    }
-    salomeConnector()->setNestedActions(aFeatureInfo.id, aNestedFeatures);
-    salomeConnector()->setDocumentKind(aFeatureInfo.id, aDocKind);
-
-    myActionsMgr->addCommand(aAction);
-    myModule->actionCreated(aAction);
-  } else {
-    //Find or create Workbench
-    AppElements_MainMenu* aMenuBar = myMainWindow->menuObject();
-    AppElements_Workbench* aPage = aMenuBar->findWorkbench(aWchName);
-    if (!aPage) {
-      aPage = addWorkbench(aWchName);
-    }
-    //Find or create Group
-    QString aGroupName = QString::fromStdString(theMessage->groupId());
-    AppElements_MenuGroupPanel* aGroup = aPage->findGroup(aGroupName);
-    if (!aGroup) {
-      aGroup = aPage->addGroup(aGroupName);
-    }
-    // Check if hotkey sequence is already defined:
-    QKeySequence aHotKey = myActionsMgr->registerShortcut(aFeatureInfo.shortcut);
-    if(aHotKey != aFeatureInfo.shortcut) {
-      aFeatureInfo.shortcut = aHotKey;
-    }
-    // Create feature...
-    AppElements_Command* aCommand = aGroup->addFeature(aFeatureInfo,
-                                                       aDocKind,
-                                                       aNestedFeatures);
-    // Enrich created button with accept/abort buttons if necessary
-    AppElements_Button* aButton = aCommand->button();
-    if (aButton->isColumnButton()) {
-      aButton->setAdditionalButtons(aNestedActList);
-    }
-    myActionsMgr->addCommand(aCommand);
-    myModule->actionCreated(aCommand);
-  }
-}
-
-/*
- * Makes a signal/slot connections between Property Panel
- * and given operation. The given operation becomes a
- * current operation and previous operation if exists
- */
-void XGUI_Workshop::connectWithOperation(ModuleBase_Operation* theOperation)
-{
-  QAction* aCommand = 0;
-  if (isSalomeMode()) {
-    aCommand = salomeConnector()->command(theOperation->getDescription()->operationId());
-  } else {
-    AppElements_MainMenu* aMenu = myMainWindow->menuObject();
-    FeaturePtr aFeature = theOperation->feature();
-    if(aFeature)
-      aCommand = aMenu->feature(QString::fromStdString(aFeature->getKind()));
-  }
-  //Abort operation on uncheck the command
-  if (aCommand) {
-    connect(aCommand, SIGNAL(triggered(bool)), theOperation, SLOT(setRunning(bool)));
-  }
+  myErrorMgr->setPropertyPanel(myPropertyPanel);
 }
 
 /*
@@ -784,7 +600,7 @@ void XGUI_Workshop::saveDocument(const QString& theName, std::list<std::string>&
   QApplication::restoreOverrideCursor();
 }
 
-bool XGUI_Workshop::isActiveOperationAborted()
+bool XGUI_Workshop::abortAllOperations()
 {
   return myOperationMgr->abortAllOperations();
 }
@@ -832,7 +648,7 @@ void XGUI_Workshop::onNew()
 //******************************************************
 void XGUI_Workshop::onOpen()
 {
-  if(!isActiveOperationAborted())
+  if(!abortAllOperations())
     return;
   //save current file before close if modified
   SessionPtr aSession = ModelAPI_Session::get();
@@ -847,12 +663,11 @@ void XGUI_Workshop::onOpen()
     } else if (anAnswer == QMessageBox::Cancel) {
       return;
     }
-    aSession->closeAll();
     myCurrentDir = "";
   }
 
   //show file dialog, check if readable and open
-  myCurrentDir = QFileDialog::getExistingDirectory(mainWindow());
+  myCurrentDir = QFileDialog::getExistingDirectory(mainWindow(), tr("Select directory"));
   if (myCurrentDir.isEmpty())
     return;
   QFileInfo aFileInfo(myCurrentDir);
@@ -862,19 +677,17 @@ void XGUI_Workshop::onOpen()
     return;
   }
   QApplication::setOverrideCursor(Qt::WaitCursor);
-  myIsLoadingData = true;
+  aSession->closeAll();
   aSession->load(myCurrentDir.toLatin1().constData());
   myObjectBrowser->rebuildDataTree();
-  displayAllResults();
   updateCommandStatus();
-  myIsLoadingData = false;
   QApplication::restoreOverrideCursor();
 }
 
 //******************************************************
 bool XGUI_Workshop::onSave()
 {
-  if(!isActiveOperationAborted())
+  if(!abortAllOperations())
     return false;
   if (myCurrentDir.isEmpty()) {
     return onSaveAs();
@@ -890,18 +703,19 @@ bool XGUI_Workshop::onSave()
 //******************************************************
 bool XGUI_Workshop::onSaveAs()
 {
-  if(!isActiveOperationAborted())
+  if(!abortAllOperations())
     return false;
   QFileDialog dialog(mainWindow());
   dialog.setWindowTitle(tr("Select directory to save files..."));
   dialog.setFileMode(QFileDialog::Directory);
-  dialog.setFilter(tr("Folders (*)"));
+  dialog.setFilter(tr("Directories (*)"));
   dialog.setOptions(QFileDialog::HideNameFilterDetails | QFileDialog::ShowDirsOnly);
   dialog.setViewMode(QFileDialog::Detail);
 
   if (!dialog.exec()) {
     return false;
   }
+
   QString aTempDir = dialog.selectedFiles().first();
   QDir aDir(aTempDir);
   if (aDir.exists() && !aDir.entryInfoList(QDir::NoDotAndDotDot | QDir::AllEntries).isEmpty()) {
@@ -909,7 +723,7 @@ bool XGUI_Workshop::onSaveAs()
         myMainWindow,
         //: Title of the dialog which asks user if he wants to save study in existing non-empty folder
         tr("Save"),
-        tr("The folder already contains some files, save anyway?"),
+        tr("The directory already contains some files, save anyway?"),
         QMessageBox::Save | QMessageBox::Cancel);
     if (answer == QMessageBox::Cancel) {
       return false;
@@ -928,11 +742,17 @@ void XGUI_Workshop::onUndo(int theTimes)
 {
   objectBrowser()->treeView()->setCurrentIndex(QModelIndex());
   SessionPtr aMgr = ModelAPI_Session::get();
-  if (aMgr->isOperation())
+  if (aMgr->isOperation()) {
+    /// this is important for nested operrations
+    /// when sketch opeation is active, this condition is false and 
+    /// the sketch operation is not aborted
     operationMgr()->onAbortOperation();
+  }
   for (int i = 0; i < theTimes; ++i) {
     aMgr->undo();
   }
+
+  operationMgr()->updateApplyOfOperations();
   updateCommandStatus();
 }
 
@@ -947,11 +767,16 @@ void XGUI_Workshop::onRedo(int theTimes)
 
   objectBrowser()->treeView()->setCurrentIndex(QModelIndex());
   SessionPtr aMgr = ModelAPI_Session::get();
-  if (aMgr->isOperation())
+  if (aMgr->isOperation()) {
+    /// this is important for nested operrations
+    /// when sketch opeation is active, this condition is false and 
+    /// the sketch operation is not aborted
     operationMgr()->onAbortOperation();
+  }
   for (int i = 0; i < theTimes; ++i) {
     aMgr->redo();
   }
+  operationMgr()->updateApplyOfOperations();
   updateCommandStatus();
 
   // unblock the viewer update functionality and make update on purpose
@@ -994,6 +819,7 @@ void XGUI_Workshop::onPreferences()
           myMainWindow->menuObject()->updateFromResources();
       }
     }
+    displayer()->redisplayObjects();
   }
 }
 
@@ -1057,7 +883,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());
@@ -1065,13 +891,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;
 }
 
@@ -1088,20 +914,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) {
@@ -1138,7 +960,10 @@ QDockWidget* XGUI_Workshop::createObjectBrowser(QWidget* theParent)
   aObjDock->setStyleSheet(
       "::title { position: relative; padding-left: 5px; text-align: left center }");
   myObjectBrowser = new XGUI_ObjectsBrowser(aObjDock);
+#ifdef ModuleDataModel
   myObjectBrowser->setDataModel(myModule->dataModel());
+#endif
+  myModule->customizeObjectBrowser(myObjectBrowser);
   aObjDock->setWidget(myObjectBrowser);
 
   myContextMenuMgr->connectObjectBrowser();
@@ -1165,18 +990,15 @@ void XGUI_Workshop::createDockWidgets()
   myPropertyPanel->installEventFilter(myOperationMgr);
 
   QAction* aOkAct = myActionsMgr->operationStateAction(XGUI_ActionsMgr::Accept);
-  connect(aOkAct, SIGNAL(triggered()), myOperationMgr, SLOT(onCommitOperation()));
+  connect(aOkAct, SIGNAL(triggered()), this, SLOT(onAcceptActionClicked()));
+
   QAction* aCancelAct = myActionsMgr->operationStateAction(XGUI_ActionsMgr::Abort);
   connect(aCancelAct, SIGNAL(triggered()), myOperationMgr, SLOT(onAbortOperation()));
   connect(myPropertyPanel, SIGNAL(noMoreWidgets()), myModule, SLOT(onNoMoreWidgets()));
   connect(myPropertyPanel, SIGNAL(keyReleased(QKeyEvent*)),
           myOperationMgr,  SLOT(onKeyReleased(QKeyEvent*)));
-  connect(myOperationMgr,  SIGNAL(validationStateChanged(bool)),
-          aOkAct,          SLOT(setEnabled(bool)));
-  QAction* aAcceptAllAct = myActionsMgr->operationStateAction(XGUI_ActionsMgr::AcceptAll);
-  connect(myOperationMgr,  SIGNAL(nestedStateChanged(bool)),
-          aAcceptAllAct,   SLOT(setEnabled(bool)));
-
+  //connect(myOperationMgr,  SIGNAL(validationStateChanged(bool)),
+  //        this, SLOT(onValidationStateChanged(bool)));
 }
 
 //******************************************************
@@ -1210,17 +1032,6 @@ void XGUI_Workshop::hideObjectBrowser()
   myObjectBrowser->parentWidget()->hide();
 }
 
-//******************************************************
-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()
 {
@@ -1239,6 +1050,8 @@ void XGUI_Workshop::onContextMenuCommand(const QString& theId, bool isChecked)
   QObjectPtrList aObjects = mySelector->selection()->selectedObjects();
   if (theId == "DELETE_CMD")
     deleteObjects();
+  else if (theId == "MOVE_CMD")
+    moveObjects();
   else if (theId == "COLOR_CMD")
     changeColor(aObjects);
   else if (theId == "SHOW_CMD")
@@ -1251,8 +1064,14 @@ void XGUI_Workshop::onContextMenuCommand(const QString& theId, bool isChecked)
     setDisplayMode(aObjects, XGUI_Displayer::Shading);
   else if (theId == "WIREFRAME_CMD")
     setDisplayMode(aObjects, XGUI_Displayer::Wireframe);
-  else if (theId == "HIDEALL_CMD")
-    myDisplayer->eraseAll();
+  else if (theId == "HIDEALL_CMD") {
+    QObjectPtrList aList = myDisplayer->displayedObjects();
+    foreach (ObjectPtr aObj, aList) {
+      if (module()->canEraseObject(aObj))
+        aObj->setDisplayed(false);
+    }
+    Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
+  }
 }
 
 //**************************************************************
@@ -1265,13 +1084,21 @@ void XGUI_Workshop::deleteObjects()
     return;
   }
 
-  if (!isActiveOperationAborted())
+  if (!abortAllOperations())
     return;
   QObjectPtrList anObjects = mySelector->selection()->selectedObjects();
+  // It is necessary to clear selection in order to avoid selection changed event during
+  // deleteion and negative consequences connected with processing of already deleted items
+  mySelector->clearSelection();
+  // check whether the object can be deleted. There should not be parts which are not loaded
+  if (!XGUI_Tools::canRemoveOrRename(myMainWindow, anObjects))
+    return;
+
   bool hasResult = false;
   bool hasFeature = false;
   bool hasParameter = false;
-  ModuleBase_Tools::checkObjects(anObjects, hasResult, hasFeature, hasParameter);
+  bool hasSubFeature = false;
+  ModuleBase_Tools::checkObjects(anObjects, hasResult, hasFeature, hasParameter, hasSubFeature);
   if (!(hasFeature || hasParameter))
     return;
 
@@ -1280,90 +1107,166 @@ void XGUI_Workshop::deleteObjects()
   aDescription += tr(" %1");
   QStringList aObjectNames;
   foreach (ObjectPtr aObj, anObjects) {
-    if (!aObj->data().get())
+    if (!aObj->data()->isValid())
       continue;
     aObjectNames << QString::fromStdString(aObj->data()->name());
   }
   aDescription = aDescription.arg(aObjectNames.join(", "));
+  ModuleBase_OperationAction* anOpAction = new ModuleBase_OperationAction(aDescription, module());
 
-  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)
-  {
-    ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(aObj);
-    if (aPart) {
-      DocumentPtr aDoc = aObj->document();
-      if (aDoc == aMgr->activeDocument()) {
-        aDoc->close();
-      }
-    }
-  }
+  operationMgr()->startOperation(anOpAction);
   // 3. delete objects
   QMainWindow* aDesktop = isSalomeMode() ? salomeConnector()->desktop() : myMainWindow;
   std::set<FeaturePtr> anIgnoredFeatures;
   if (deleteFeatures(anObjects, anIgnoredFeatures, aDesktop, true)) {
-    myDisplayer->updateViewer();
-    aMgr->finishOperation();
-    updateCommandStatus();
+    operationMgr()->commitOperation();
   }
   else {
-    aMgr->abortOperation();
+    operationMgr()->abortOperation(operationMgr()->currentOperation());
+  }
+}
+
+//**************************************************************
+void XGUI_Workshop::moveObjects()
+{
+  if (!abortAllOperations())
+    return;
+
+  SessionPtr aMgr = ModelAPI_Session::get();
+
+  QString anActionId = "MOVE_CMD";
+  QString aDescription = contextMenuMgr()->action(anActionId)->text();
+  aMgr->startOperation(aDescription.toStdString());
+
+  QObjectPtrList anObjects = mySelector->selection()->selectedObjects();
+  // It is necessary to clear selection in order to avoid selection changed event during
+  // moving and negative consequences connected with processing of already moved items
+  mySelector->clearSelection();
+  // check whether the object can be moved. There should not be parts which are not loaded
+  if (!XGUI_Tools::canRemoveOrRename(myMainWindow, anObjects))
+    return;
+
+  DocumentPtr anActiveDocument = aMgr->activeDocument();
+  FeaturePtr aCurrentFeature = anActiveDocument->currentFeature(true);
+  foreach (ObjectPtr aObject, anObjects) {
+    if (!myModule->canApplyAction(aObject, anActionId))
+      continue;
+
+    FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aObject);
+    if (aFeature.get()) {
+      anActiveDocument->moveFeature(aFeature, aCurrentFeature);
+      aCurrentFeature = anActiveDocument->currentFeature(true);
+    }
   }
+  aMgr->finishOperation();
 }
 
 //**************************************************************
 bool XGUI_Workshop::deleteFeatures(const QObjectPtrList& theList,
-                                   std::set<FeaturePtr> theIgnoredFeatures,
+                                   const std::set<FeaturePtr>& theIgnoredFeatures,
                                    QWidget* theParent,
                                    const bool theAskAboutDeleteReferences)
 {
+#ifdef DEBUG_DELETE
+  QStringList aDInfo;
+  QObjectPtrList::const_iterator aDIt = theList.begin(), aDLast = theList.end();
+  for (; aDIt != aDLast; ++aDIt) {
+    aDInfo.append(ModuleBase_Tools::objectInfo((*aDIt)));
+  }
+  QString anInfoStr = aDInfo.join(", ");
+  qDebug(QString("deleteFeatures: %1, %2").arg(theList.size()).arg(anInfoStr).toStdString().c_str());
+#endif
+
   // 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);
-    }
+  std::set<FeaturePtr> aDirectRefFeatures, aIndirectRefFeatures;
+  foreach (ObjectPtr aDeletedObj, theList) {
+    XGUI_Tools::refsToFeatureInAllDocuments(aDeletedObj, aDeletedObj, aDirectRefFeatures, aIndirectRefFeatures);
+    std::set<FeaturePtr> aDifference;
+    std::set_difference(aIndirectRefFeatures.begin(), aIndirectRefFeatures.end(), 
+                        aDirectRefFeatures.begin(), aDirectRefFeatures.end(), 
+                        std::inserter(aDifference, aDifference.begin()));
+    aIndirectRefFeatures = aDifference;
   }
   // 2. warn about the references remove, break the delete operation if the user chose it
-  if (theAskAboutDeleteReferences && !aRefFeatures.empty()) {
-    QStringList aRefNames;
-    std::set<FeaturePtr>::const_iterator anIt = aRefFeatures.begin(),
-                                         aLast = aRefFeatures.end();
-    for (; anIt != aLast; anIt++) {
-      aRefNames.append((*anIt)->name().c_str());
-    }
-    QString aNames = aRefNames.join(", ");
+  if (theAskAboutDeleteReferences && !aDirectRefFeatures.empty()) {
+    QStringList aDirectRefNames;
+    foreach(const FeaturePtr& aFeature, aDirectRefFeatures)
+      aDirectRefNames.append(aFeature->name().c_str());
+    QString aDirectNames = aDirectRefNames.join(", ");
+
+    QStringList aIndirectRefNames;
+    foreach(const FeaturePtr& aFeature, aIndirectRefFeatures)
+      aIndirectRefNames.append(aFeature->name().c_str());
+    QString aIndirectNames = aIndirectRefNames.join(", ");
 
     QMessageBox::StandardButton aRes = QMessageBox::warning(
         theParent, tr("Delete features"),
         QString(tr("Selected features are used in the following features: %1.\
-These features will be deleted also. Would you like to continue?")).arg(aNames),
+ These features will be deleted.\n%2Would you like to continue?")).arg(aDirectNames)
+            .arg(aIndirectNames.isEmpty() ? QString() : QString("Also these features will be deleted: %1.\n").arg(aIndirectNames)),
         QMessageBox::No | QMessageBox::Yes, QMessageBox::No);
     if (aRes != QMessageBox::Yes)
       return false;
   }
 
   // 3. remove referenced features
-  std::set<FeaturePtr>::const_iterator anIt = aRefFeatures.begin(),
-                                       aLast = aRefFeatures.end();
+  std::set<FeaturePtr> aFeaturesToDelete = aDirectRefFeatures;
+  aFeaturesToDelete.insert(aIndirectRefFeatures.begin(), aIndirectRefFeatures.end());
+  std::set<FeaturePtr>::const_iterator anIt = aFeaturesToDelete.begin(),
+                                       aLast = aFeaturesToDelete.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
 
+  QString anActionId = "DELETE_CMD";
+  QString anId = QString::fromStdString(anActionId.toStdString().c_str());
+  QStringList anObjectGroups = contextMenuMgr()->actionObjectGroups(anId);
   // 4. remove the parameter features
   foreach (ObjectPtr aObj, theList) {
+    // features and parameters can be removed here,
+    // the results are removed only by a corresponded feature remove
+    std::string aGroupName = aObj->groupName();
+    if (!anObjectGroups.contains(aGroupName.c_str()))
+      continue;
+
+    if (!myModule->canApplyAction(aObj, anActionId))
+      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()) {
+#ifdef DEBUG_DELETE
+        QString anInfoStr = ModuleBase_Tools::objectInfo(aFeature);
+        anInfo.append(anInfoStr);
+        qDebug(QString("remove feature :%1").arg(anInfoStr).toStdString().c_str());
+#endif
         aDoc->removeFeature(aFeature);
+      }
     }
   }
+#ifdef DEBUG_DELETE
+  qDebug(QString("remove features:%1").arg(anInfo.join("; ")).toStdString().c_str());
+#endif
   return true;
 }
 
@@ -1383,6 +1286,123 @@ bool hasResults(QObjectPtrList theObjects, const std::set<std::string>& theTypes
   return isFoundResultType;
 }
 
+//**************************************************************
+// Returns the list of all features for theDocument and all features of
+// all nested parts.
+std::list<FeaturePtr> allFeatures(const DocumentPtr& theDocument)
+{
+  std::list<FeaturePtr> aResultList;
+  std::list<FeaturePtr> anAllFeatures = theDocument->allFeatures();
+  foreach (const FeaturePtr& aFeature, anAllFeatures) {
+    // The order of appending features of the part and the part itself is important
+
+    // Append features from a part feature
+    foreach (const ResultPtr& aResult, aFeature->results()) {
+      ResultPartPtr aResultPart =
+          std::dynamic_pointer_cast<ModelAPI_ResultPart>(aResult);
+      if (aResultPart.get() && aResultPart->partDoc().get()) {
+        // Recursion
+        std::list<FeaturePtr> anAllFeatures = allFeatures(aResultPart->partDoc());
+        aResultList.insert(aResultList.end(), anAllFeatures.begin(), anAllFeatures.end());
+      }
+    }
+
+    aResultList.push_back(aFeature);
+  }
+  return aResultList;
+}
+
+//**************************************************************
+// Returns the list of features placed between theObject and the current feature
+// in the same document. Excludes theObject, includes the current feature.
+std::list<FeaturePtr> toCurrentFeatures(const ObjectPtr& theObject)
+{
+  std::list<FeaturePtr> aResult;
+  DocumentPtr aDocument = theObject->document();
+  std::list<FeaturePtr> anAllFeatures = allFeatures(aDocument);
+  // find the object iterator
+  std::list<FeaturePtr>::iterator aObjectIt = std::find(anAllFeatures.begin(), anAllFeatures.end(), theObject);
+  if (aObjectIt == anAllFeatures.end())
+    return aResult;
+  // find the current feature iterator
+  std::list<FeaturePtr>::iterator aCurrentIt = std::find(anAllFeatures.begin(), anAllFeatures.end(), aDocument->currentFeature(true));
+  if (aCurrentIt == anAllFeatures.end())
+    return aResult;
+  // check the right order
+  if (std::distance(aObjectIt, anAllFeatures.end()) <= std::distance(aCurrentIt, anAllFeatures.end()))
+    return aResult;
+  // exclude the object
+  std::advance(aObjectIt, 1);
+  // include the current feature
+  std::advance(aCurrentIt, 1);
+  return std::list<FeaturePtr>(aObjectIt, aCurrentIt);
+}
+
+bool XGUI_Workshop::canMoveFeature()
+{
+  QString anActionId = "MOVE_CMD";
+
+  QObjectPtrList aObjects = mySelector->selection()->selectedObjects();
+  QObjectPtrList aValidatedObjects;
+  foreach (ObjectPtr aObject, aObjects) {
+    if (!myModule->canApplyAction(aObject, anActionId))
+      continue;
+    // To be moved feature should be in active document
+    if (aObject->document() != ModelAPI_Session::get()->activeDocument())
+      continue;
+    aValidatedObjects.append(aObject);
+  }
+  if (aValidatedObjects.size() != aObjects.size())
+    aObjects = aValidatedObjects;
+
+  bool aCanMove = !aObjects.empty();
+
+  QObjectPtrList::const_iterator anIt = aObjects.begin(), aLast = aObjects.end();
+  for (; anIt != aLast && aCanMove; anIt++) {
+    ObjectPtr aObject = *anIt;
+    // 1. Get features placed between selected and current in the document 
+    std::list<FeaturePtr> aFeaturesBetween = toCurrentFeatures(aObject);
+    // if aFeaturesBetween is empty it means wrong order or aObject is the current feature
+    if (aFeaturesBetween.empty())
+      aCanMove = false;
+    else {
+      std::set<FeaturePtr> aPlacedFeatures(aFeaturesBetween.begin(), aFeaturesBetween.end());
+      // 2. Get all reference features to the selected object in the document 
+      std::set<FeaturePtr> aRefFeatures;
+      XGUI_Tools::refsToFeatureInFeatureDocument(aObject, aRefFeatures);
+
+      if (aRefFeatures.empty())
+        continue;
+      else {
+        // 3. Find any placed features in all reference features
+        std::set<FeaturePtr> aIntersectionFeatures;
+        std::set_intersection(aRefFeatures.begin(), aRefFeatures.end(),
+                              aPlacedFeatures.begin(), aPlacedFeatures.end(),
+                              std::inserter(aIntersectionFeatures, aIntersectionFeatures.begin()));
+        // 4. Return false if any reference feature is placed before current feature
+        if (!aIntersectionFeatures.empty())
+          aCanMove = false;
+      }
+    }
+  }
+  return aCanMove;
+}
+
+//**************************************************************
+bool XGUI_Workshop::canBeShaded(const ObjectPtr& theObject) const
+{
+  bool aCanBeShaded = myDisplayer->canBeShaded(theObject);
+  if (!aCanBeShaded) {
+    ResultCompSolidPtr aCompsolidResult =
+                std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(theObject);
+    if (aCompsolidResult.get() != NULL) { // change colors for all sub-solids
+      for(int i = 0; i < aCompsolidResult->numberOfSubs() && !aCanBeShaded; i++)
+        aCanBeShaded = myDisplayer->canBeShaded(aCompsolidResult->subResult(i));
+    }
+  }
+  return aCanBeShaded;
+}
+
 //**************************************************************
 bool XGUI_Workshop::canChangeColor() const
 {
@@ -1421,29 +1441,15 @@ void XGUI_Workshop::changeColor(const QObjectPtrList& theObjects)
   // The objects are iterated until a first valid color is found 
   std::vector<int> aColor;
   foreach(ObjectPtr anObject, theObjects) {
-    if (anObject->groupName() == ModelAPI_ResultPart::group()) {
-      ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(anObject);
-      DocumentPtr aPartDoc = aPart->partDoc();
-      // the document should be checked on null, because in opened document if the part
-      // has not been activated yet, the part document is empty
-      if (!aPartDoc.get()) {
-        emit errorOccurred(QString::fromLatin1("Color can not be changed on a part with an empty document"));
-      }
-      else {
-        if (aPartDoc->size(ModelAPI_ResultBody::group()) > 0) {
-          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);
-            }
-          }
-        }
-      }
+    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);
@@ -1475,27 +1481,16 @@ void XGUI_Workshop::changeColor(const QObjectPtrList& theObjects)
   }
 
   // 4. set the value to all results
+  std::vector<int> aColorResult = aDlg->getColor();
   foreach(ObjectPtr anObj, theObjects) {
     ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(anObj);
     if (aResult.get() != NULL) {
-      if (aResult->groupName() == ModelAPI_ResultPart::group()) {
-        ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(aResult);
-        DocumentPtr aPartDoc = aPart->partDoc();
-        // the document should be checked on null, because in opened document if the part
-        // has not been activated yet, the part document is empty
-        if (aPartDoc.get()) {
-          for (int i = 0; i < aPartDoc->size(ModelAPI_ResultBody::group()); i++) {
-            ObjectPtr aObject = aPartDoc->object(ModelAPI_ResultBody::group(), i);
-            ResultBodyPtr aBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(aObject);
-            std::vector<int> aColorResult = aDlg->getColor();
-            setColor(aBody, aColorResult);
-          }
-        }
-      }
-      else {
-        std::vector<int> aColorResult = aDlg->getColor();
-        setColor(aResult, aColorResult);
+      ResultCompSolidPtr aCompsolidResult = std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(aResult);
+      if (aCompsolidResult.get() != NULL) { // change colors for all sub-solids
+        for(int i = 0; i < aCompsolidResult->numberOfSubs(); i++)
+          setColor(aCompsolidResult->subResult(i), aColorResult);
       }
+      setColor(aResult, aColorResult);
     }
   }
   if (!aWasOperation)
@@ -1504,23 +1499,54 @@ 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) {
-      displayObject(aObj);
+  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(), isVisible)
+      SET_DISPLAY_GROUP(ModelAPI_ResultConstruction::group(), isVisible)
+      SET_DISPLAY_GROUP(ModelAPI_ResultGroup::group(), isVisible)
     } else {
-      myDisplayer->erase(aObj, false);
-    }
+    */
+      aObj->setDisplayed(isVisible);
+    //}
   }
-  myDisplayer->updateViewer();
+  Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
 }
 
 //**************************************************************
 void XGUI_Workshop::showOnlyObjects(const QObjectPtrList& theList)
 {
-  myDisplayer->showOnly(theList);
+  // Hide all displayed objects
+  QObjectPtrList aList = myDisplayer->displayedObjects();
+  foreach (ObjectPtr aObj, aList) {
+    if (module()->canEraseObject(aObj))
+      aObj->setDisplayed(false);
+  }
+
+  // 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));
+
 }
 
 
@@ -1531,20 +1557,6 @@ void XGUI_Workshop::registerValidators() const
   ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();
 }
 
-//**************************************************************
-void XGUI_Workshop::displayAllResults()
-{
-  SessionPtr aMgr = ModelAPI_Session::get();
-  DocumentPtr aRootDoc = aMgr->moduleDocument();
-  displayDocumentResults(aRootDoc);
-  for (int i = 0; i < aRootDoc->size(ModelAPI_ResultPart::group()); i++) {
-    ObjectPtr aObject = aRootDoc->object(ModelAPI_ResultPart::group(), i);
-    ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(aObject);
-    displayDocumentResults(aPart->partDoc());
-  }
-  myDisplayer->updateViewer();
-}
-
 //**************************************************************
 void XGUI_Workshop::displayDocumentResults(DocumentPtr theDoc)
 {
@@ -1557,8 +1569,10 @@ void XGUI_Workshop::displayDocumentResults(DocumentPtr theDoc)
 //**************************************************************
 void XGUI_Workshop::displayGroupResults(DocumentPtr theDoc, std::string theGroup)
 {
-  for (int i = 0; i < theDoc->size(theGroup); i++)
-    displayObject(theDoc->object(theGroup, i));
+  for (int i = 0; i < theDoc->size(theGroup); i++) 
+    theDoc->object(theGroup, i)->setDisplayed(true);
+    //displayObject(theDoc->object(theGroup, i));
+  Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
 }
 
 //**************************************************************
@@ -1566,6 +1580,14 @@ void XGUI_Workshop::setDisplayMode(const QObjectPtrList& theList, int theMode)
 {
   foreach(ObjectPtr aObj, theList) {
     myDisplayer->setDisplayMode(aObj, (XGUI_Displayer::DisplayMode)theMode, false);
+
+    ResultCompSolidPtr aCompsolidResult = std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(aObj);
+    if (aCompsolidResult.get() != NULL) { // change colors for all sub-solids
+      for(int i = 0; i < aCompsolidResult->numberOfSubs(); i++) {
+          myDisplayer->setDisplayMode(aCompsolidResult->subResult(i),
+                                      (XGUI_Displayer::DisplayMode)theMode, false);
+      }
+    }
   }
   if (theList.size() > 0)
     myDisplayer->updateViewer();
@@ -1583,27 +1605,10 @@ void XGUI_Workshop::closeDocument()
   myDisplayer->eraseAll();
   objectBrowser()->clearContent();
 
+  module()->closeDocument();
+
   SessionPtr aMgr = ModelAPI_Session::get();
   aMgr->closeAll();
-  objectBrowser()->clearContent();
-}
-
-//**************************************************************
-bool XGUI_Workshop::displayObject(ObjectPtr theObj)
-{
-  if (!myModule->canDisplayObject(theObj))
-    return false;
-
-  ResultBodyPtr aBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(theObj);
-  if (aBody.get() != NULL) {
-    int aNb = myDisplayer->objectsCount();
-    myDisplayer->display(theObj, false);
-    if (aNb == 0)
-      viewer()->fitAll();
-  } else if (!(myIsLoadingData || myPartActivating))
-    myDisplayer->display(theObj, false);
-
-  return true;
 }
 
 void XGUI_Workshop::addHistoryMenu(QObject* theObject, const char* theSignal, const char* theSlot)
@@ -1628,9 +1633,9 @@ QList<ActionInfo> XGUI_Workshop::processHistoryList(const std::list<std::string>
   std::list<std::string>::const_iterator it = theList.cbegin();
   for (; it != theList.cend(); it++) {
     QString anId = QString::fromStdString(*it);
-    bool isEditing = anId.endsWith(ModuleBase_Operation::EditSuffix());
+    bool isEditing = anId.endsWith(ModuleBase_OperationFeature::EditSuffix());
     if (isEditing) {
-      anId.chop(ModuleBase_Operation::EditSuffix().size());
+      anId.chop(ModuleBase_OperationFeature::EditSuffix().size());
     }
     ActionInfo anInfo;
     QAction* aContextMenuAct = myContextMenuMgr->actionByName(anId);