Salome HOME
Disable undo on active operation (to prevent crash on undo the sketch creation)
[modules/shaper.git] / src / XGUI / XGUI_Workshop.cpp
index 6df891cd4944d3b843f7e9dedcac036c3af12ac5..c7a98185b9d71246dce94c5d101a9e77e0bae25b 100644 (file)
@@ -119,9 +119,11 @@ XGUI_Workshop::XGUI_Workshop(XGUI_SalomeConnector* theConnector)
   connect(myOperationMgr, SIGNAL(operationStopped(ModuleBase_Operation*)),
           SLOT(onOperationStopped(ModuleBase_Operation*)));
   connect(myMainWindow, SIGNAL(exitKeySequence()), SLOT(onExit()));
-  connect(myOperationMgr, SIGNAL(operationStarted()), myActionsMgr, SLOT(update()));
-  connect(myOperationMgr, SIGNAL(operationStopped(ModuleBase_Operation*)), myActionsMgr,
-          SLOT(update()));
+  // TODO(sbh): It seems that application works properly without update on operationStarted
+  connect(myOperationMgr, SIGNAL(operationStarted(ModuleBase_Operation*)),
+          myActionsMgr,   SLOT(update()));
+  connect(myOperationMgr, SIGNAL(operationStopped(ModuleBase_Operation*)),
+          myActionsMgr,   SLOT(update()));
   connect(this, SIGNAL(errorOccurred(const QString&)), myErrorDlg, SLOT(addError(const QString&)));
 }
 
@@ -138,9 +140,7 @@ void XGUI_Workshop::startApplication()
   //Initialize event listening
   Events_Loop* aLoop = Events_Loop::loop();
   aLoop->registerListener(this, Events_Error::errorID());  //!< Listening application errors.
-  //TODO(sbh): Implement static method to extract event id [SEID]
-  aLoop->registerListener(this, Events_Loop::eventByName(EVENT_FEATURE_LOADED));
-  // TODO Is it good to use non standard event within workshop?
+  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));
@@ -257,7 +257,7 @@ void XGUI_Workshop::processEvent(const boost::shared_ptr<Events_Message>& theMes
   }
 
   //A message to start feature creation received.
-  if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_FEATURE_LOADED)) {
+  if (theMessage->eventID() == Events_Loop::loop()->eventByName(Config_FeatureMessage::GUI_EVENT())) {
     boost::shared_ptr<Config_FeatureMessage> aFeatureMsg =
        boost::dynamic_pointer_cast<Config_FeatureMessage>(theMessage);
     if (!aFeatureMsg->isInternal()) {
@@ -416,9 +416,15 @@ void XGUI_Workshop::onFeatureRedisplayMsg(const boost::shared_ptr<ModelAPI_Objec
 {
   std::set<ObjectPtr> aObjects = theMsg->objects();
   std::set<ObjectPtr>::const_iterator aIt;
+  QIntList aModes;
   for (aIt = aObjects.begin(); aIt != aObjects.end(); ++aIt) {
     ObjectPtr aObj = (*aIt);
-    if (!aObj->data() || !aObj->data()->isValid() || aObj->document()->isConcealed(aObj))
+    bool aHide = !aObj->data() || !aObj->data()->isValid();
+    if (!aHide) { // check that this is not hidden result
+      ResultPtr aRes = boost::dynamic_pointer_cast<ModelAPI_Result>(aObj);
+      aHide = aRes && aRes->isConcealed();
+    }
+    if (aHide)
       myDisplayer->erase(aObj, false);
     else {
       if (myDisplayer->isVisible(aObj))  {
@@ -427,7 +433,7 @@ void XGUI_Workshop::onFeatureRedisplayMsg(const boost::shared_ptr<ModelAPI_Objec
           ModuleBase_Operation* aOperation = myOperationMgr->currentOperation();
           if (!aOperation->hasObject(aObj))
             if (!myDisplayer->isActive(aObj))
-              myDisplayer->activate(aObj);
+              myDisplayer->activate(aObj, aModes);
         }
       } else {
         if (myOperationMgr->hasOperation()) {
@@ -462,8 +468,7 @@ void XGUI_Workshop::onFeatureCreatedMsg(const boost::shared_ptr<ModelAPI_ObjectU
       // it doesn't stored in the operation mgr and doesn't displayed
     } else if (myOperationMgr->hasOperation()) {
       ModuleBase_Operation* aOperation = myOperationMgr->currentOperation();
-      if (!(*aIt)->document()->isConcealed(*aIt) &&
-          aOperation->hasObject(*aIt)) {  // Display only current operation results
+      if (aOperation->hasObject(*aIt)) {  // Display only current operation results
         myDisplayer->display(*aIt, false);
         isDisplayed = true;
       }
@@ -508,10 +513,7 @@ void XGUI_Workshop::onOperationStarted()
     ModuleBase_Tools::zeroMargins(myPropertyPanel->contentWidget());
 
     QList<ModuleBase_ModelWidget*> aWidgets = aFactory.getModelWidgets();
-    QList<ModuleBase_ModelWidget*>::const_iterator anIt = aWidgets.begin(), aLast = aWidgets.end();
-    ModuleBase_ModelWidget* aWidget;
-    for (; anIt != aLast; anIt++) {
-      aWidget = *anIt;
+    foreach (ModuleBase_ModelWidget* aWidget, aWidgets) {
       aWidget->setFeature(aOperation->feature());
       aWidget->enableFocusProcessing();
       QObject::connect(aWidget, SIGNAL(valuesChanged()), this, SLOT(onWidgetValuesChanged()));
@@ -523,7 +525,8 @@ void XGUI_Workshop::onOperationStarted()
 
     aOperation->setPropertyPanel(myPropertyPanel);
     myPropertyPanel->setModelWidgets(aWidgets);
-    myPropertyPanel->activateNextWidget(NULL);
+    if (!aOperation->activateByPreselection())
+      myPropertyPanel->activateNextWidget(NULL);
     // Widget activation (from the previous method) may commit the current operation
     // if pre-selection is enougth for it. So we shouldn't update prop panel's title
     if(myOperationMgr->isCurrentOperation(aOperation)) {
@@ -580,6 +583,8 @@ void XGUI_Workshop::addFeature(const boost::shared_ptr<Config_FeatureMessage>& t
                                                      QKeySequence(),
                                                      isUsePropPanel);
     salomeConnector()->setNestedActions(aFeatureId, aNestedFeatures.split(" ", QString::SkipEmptyParts));
+    salomeConnector()->setDocumentKind(aFeatureId, QString::fromStdString(theMessage->documentKind()));
+
     myActionsMgr->addCommand(aAction);
     myModule->featureCreated(aAction);
   } else {
@@ -926,8 +931,7 @@ void XGUI_Workshop::updateCommandStatus()
   }
   SessionPtr aMgr = ModelAPI_Session::get();
   if (aMgr->hasModuleDocument()) {
-    QAction* aUndoCmd;
-    QAction* aRedoCmd;
+    QAction *aUndoCmd, *aRedoCmd;
     foreach(QAction* aCmd, aCommands) {
       QString aId = aCmd->data().toString();
       if (aId == "UNDO_CMD")
@@ -938,8 +942,8 @@ void XGUI_Workshop::updateCommandStatus()
         // Enable all commands
         aCmd->setEnabled(true);
     }
-    aUndoCmd->setEnabled(aMgr->canUndo());
-    aRedoCmd->setEnabled(aMgr->canRedo());
+    aUndoCmd->setEnabled(aMgr->canUndo() && !aMgr->isOperation());
+    aRedoCmd->setEnabled(aMgr->canRedo() && !aMgr->isOperation());
   } else {
     foreach(QAction* aCmd, aCommands) {
       QString aId = aCmd->data().toString();
@@ -1003,6 +1007,7 @@ void XGUI_Workshop::createDockWidgets()
   hidePropertyPanel();  //<! Invisible by default
   hideObjectBrowser();
   aDesktop->tabifyDockWidget(aObjDock, myPropertyPanel);
+  myPropertyPanel->installEventFilter(myOperationMgr);
 
   QPushButton* aOkBtn = myPropertyPanel->findChild<QPushButton*>(XGUI::PROP_PANEL_OK);
   connect(aOkBtn, SIGNAL(clicked()), myOperationMgr, SLOT(onCommitOperation()));
@@ -1010,10 +1015,6 @@ void XGUI_Workshop::createDockWidgets()
   connect(aCancelBtn, SIGNAL(clicked()), myOperationMgr, SLOT(onAbortOperation()));
   connect(myPropertyPanel, SIGNAL(keyReleased(QKeyEvent*)), myOperationMgr,
           SLOT(onKeyReleased(QKeyEvent*)));
-  //connect(myPropertyPanel, SIGNAL(widgetActivated(ModuleBase_ModelWidget*)), myOperationMgr,
-  //        SLOT(onWidgetActivated(ModuleBase_ModelWidget*)));
-  //connect(myOperationMgr, SIGNAL(activateNextWidget(ModuleBase_ModelWidget*)), myPropertyPanel,
-  //        SLOT(onActivateNextWidget(ModuleBase_ModelWidget*)));
   connect(myOperationMgr, SIGNAL(operationValidated(bool)), myPropertyPanel,
           SLOT(setAcceptEnabled(bool)));
 
@@ -1304,3 +1305,15 @@ void XGUI_Workshop::setDisplayMode(const QList<ObjectPtr>& theList, int theMode)
   if (theList.size() > 0)
     myDisplayer->updateViewer();
 }
+
+//**************************************************************
+void XGUI_Workshop::closeDocument()
+{
+  myDisplayer->closeLocalContexts();
+  myDisplayer->eraseAll();
+  objectBrowser()->clearContent();
+
+  SessionPtr aMgr = ModelAPI_Session::get();
+  aMgr->moduleDocument()->close();
+  objectBrowser()->clearContent();
+}