Salome HOME
Handle Alt+F4 as regular exit action. Do not exit on exit->save->cancel. Fixes #43
[modules/shaper.git] / src / XGUI / XGUI_Workshop.cpp
index 85046a2db26f5ded3eb2a860dfcbd747ee9d7a83..08713ee470cea09fcef4cb02b30affea929cbd07 100644 (file)
@@ -45,6 +45,7 @@
 #include <QPushButton>
 #include <QDockWidget>
 #include <QLayout>
+#include <QTimer>
 
 #ifdef _DEBUG
 #include <QDebug>
@@ -91,10 +92,12 @@ XGUI_Workshop::XGUI_Workshop(XGUI_SalomeConnector* theConnector)
 
   myViewerProxy = new XGUI_ViewerProxy(this);
 
-  connect(myOperationMgr, SIGNAL(operationStarted()),  this, SLOT(onOperationStarted()));
-  connect(myOperationMgr, SIGNAL(operationResumed()),  this, SLOT(onOperationStarted()));
-  connect(myOperationMgr, SIGNAL(operationStopped(ModuleBase_Operation*)),
-          this, SLOT(onOperationStopped(ModuleBase_Operation*)));
+  connect(myOperationMgr, SIGNAL(operationStarted()), SLOT(onOperationStarted()));
+  connect(myOperationMgr, SIGNAL(operationResumed()), SLOT(onOperationStarted()));
+  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()), myActionsMgr, SLOT(update()));
   connect(this, SIGNAL(errorOccurred(const QString&)), myErrorDlg, SLOT(addError(const QString&)));
 }
 
@@ -117,6 +120,9 @@ void XGUI_Workshop::startApplication()
   aLoop->registerListener(this, aPartSetId);
   Events_ID aFeatureUpdatedId = aLoop->eventByName(EVENT_FEATURE_UPDATED);
   aLoop->registerListener(this, aFeatureUpdatedId);
+  aLoop->registerListener(this, Events_Loop::eventByName(EVENT_FEATURE_CREATED));
+  aLoop->registerListener(this, Events_Loop::eventByName(EVENT_FEATURE_DELETED));
+
   activateModule();
   if (myMainWindow) {
     myMainWindow->show();
@@ -184,6 +190,12 @@ void XGUI_Workshop::initMenu()
   aCommand = aGroup->addFeature("EXIT_CMD", tr("Exit"), tr("Exit application"),
                                 QIcon(":pictures/close.png"), QKeySequence::Close);
   aCommand->connectTo(this, SLOT(onExit()));
+  //FIXME: SBH's test action. Can be used for some GUI tests.
+  //#ifdef _DEBUG
+  //  aCommand = aGroup->addFeature("TEST_CMD", "Test!", "Private debug button",
+  //                                QIcon(":pictures/close.png"));
+  //  aCommand->connectTo(myActionsMgr, SLOT(update()));
+  //#endif
 }
 
 //******************************************************
@@ -200,9 +212,39 @@ void XGUI_Workshop::processEvent(const Events_Message* theMessage)
   static Events_ID aFeatureLoadedId = Events_Loop::loop()->eventByName(EVENT_FEATURE_LOADED);
   if (theMessage->eventID() == aFeatureLoadedId) {
     const Config_FeatureMessage* aFeatureMsg = dynamic_cast<const Config_FeatureMessage*>(theMessage);
-    addFeature(aFeatureMsg);
+    if(!aFeatureMsg->isInternal()) {
+      addFeature(aFeatureMsg);
+    }
     return;
   }
+  // Process creation of Part
+  if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_FEATURE_CREATED)) {
+    const Model_FeatureUpdatedMessage* aUpdMsg = dynamic_cast<const Model_FeatureUpdatedMessage*>(theMessage);
+    std::set<FeaturePtr> aFeatures = aUpdMsg->features();
+
+    std::set<FeaturePtr>::const_iterator aIt;
+    bool aHasPart = false;
+    for (aIt = aFeatures.begin(); aIt != aFeatures.end(); ++aIt) {
+      FeaturePtr aFeature = (*aIt);
+      if (aFeature->getKind() == "Part") {
+        aHasPart = true;
+        break;
+      }
+    }
+    if (aHasPart) {
+      //The created part will be created in Object Browser later and we have to activate it
+      // only when it is created everywere
+      QTimer::singleShot(50, this, SLOT(activateLastPart()));
+    }
+  }
+
+  // Process deletion of a part
+  if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_FEATURE_DELETED)) {
+    PluginManagerPtr aMgr = ModelAPI_PluginManager::get();
+    if (aMgr->currentDocument() == aMgr->rootDocument())
+      activatePart(FeaturePtr()); // Activate PartSet
+  }
+
   //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.
   static Events_ID aFeatureUpdatedId = Events_Loop::loop()->eventByName(EVENT_FEATURE_UPDATED);
@@ -210,10 +252,16 @@ void XGUI_Workshop::processEvent(const Events_Message* theMessage)
   {
     const Model_FeatureUpdatedMessage* anUpdateMsg =
         dynamic_cast<const Model_FeatureUpdatedMessage*>(theMessage);
-    FeaturePtr aNewFeature = anUpdateMsg->feature();
+    std::set<FeaturePtr> aFeatures = anUpdateMsg->features();
+
     FeaturePtr aCurrentFeature = myOperationMgr->currentOperation()->feature();
-    if(aNewFeature == aCurrentFeature) {
-      myPropertyPanel->updateContentWidget(aCurrentFeature);
+    std::set<FeaturePtr>::const_iterator aIt;
+    for (aIt = aFeatures.begin(); aIt != aFeatures.end(); ++aIt) {
+      FeaturePtr aNewFeature = (*aIt);
+      if(aNewFeature == aCurrentFeature) {
+        myPropertyPanel->updateContentWidget(aCurrentFeature);
+        break;
+      } 
     }
   }
   //An operation passed by message. Start it, process and commit.
@@ -264,18 +312,9 @@ void XGUI_Workshop::onOperationStarted()
 //******************************************************
 void XGUI_Workshop::onOperationStopped(ModuleBase_Operation* theOperation)
 {
-  ModuleBase_Operation* aOperation = myOperationMgr->currentOperation();
-
   //!< No need for property panel
   updateCommandStatus();
   hidePropertyPanel();
-  if(myOperationMgr->operationsCount() > 1) {
-    myActionsMgr->updateAction(theOperation->getDescription()->operationId());
-    return;
-  }
-  if(!aOperation->getDescription()->xmlRepresentation().isEmpty()) { 
-    myActionsMgr->restoreCommandState();
-  }
 }
 
 /*
@@ -296,8 +335,8 @@ void XGUI_Workshop::addFeature(const Config_FeatureMessage* theMessage)
   QString aWchName = QString::fromStdString(theMessage->workbenchId());
   QString aNestedFeatures = QString::fromStdString(theMessage->nestedFeatures());
   bool isUsePropPanel = theMessage->isUseInput();
+  QString aId = QString::fromStdString(theMessage->id());
   if (isSalomeMode()) {
-    QString aId = QString::fromStdString(theMessage->id());
     QAction* aAction = salomeConnector()->addFeature(aWchName,
                               aId,
                               QString::fromStdString(theMessage->text()),
@@ -321,12 +360,12 @@ void XGUI_Workshop::addFeature(const Config_FeatureMessage* theMessage)
       aGroup = aPage->addGroup(aGroupName);
     }
     //Create feature...
-    XGUI_Command* aCommand = aGroup->addFeature(QString::fromStdString(theMessage->id()),
+    XGUI_Command* aCommand = aGroup->addFeature(aId,
                                                 QString::fromStdString(theMessage->text()),
                                                 QString::fromStdString(theMessage->tooltip()),
                                                 QIcon(theMessage->icon().c_str()),
                                                 QKeySequence(), isUsePropPanel);
-    aCommand->setUnblockableCommands(aNestedFeatures.split(" "));
+    aCommand->setNestedCommands(aNestedFeatures.split(" ", QString::SkipEmptyParts));
     myActionsMgr->addCommand(aCommand);
     myPartSetModule->featureCreated(aCommand);
   }
@@ -373,7 +412,10 @@ void XGUI_Workshop::onExit()
         tr("The document is modified, save before exit?"),
         QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Cancel);
     if(anAnswer == QMessageBox::Save) {
-      onSave();
+      bool saved = onSave();
+      if(!saved) {
+        return;
+      }
     } else if (anAnswer == QMessageBox::Cancel) {
       return;
     }
@@ -438,18 +480,18 @@ void XGUI_Workshop::onOpen()
 }
 
 //******************************************************
-void XGUI_Workshop::onSave()
+bool XGUI_Workshop::onSave()
 {
   if(myCurrentDir.isEmpty()) {
-    onSaveAs();
-    return;
+    return onSaveAs();
   }
   saveDocument(myCurrentDir);
   updateCommandStatus();
+  return true;
 }
 
 //******************************************************
-void XGUI_Workshop::onSaveAs()
+bool XGUI_Workshop::onSaveAs()
 {
   QFileDialog dialog(mainWindow());
   dialog.setWindowTitle(tr("Select directory to save files..."));
@@ -459,7 +501,7 @@ void XGUI_Workshop::onSaveAs()
   dialog.setViewMode(QFileDialog::Detail);
 
   if(!dialog.exec()) {
-    return;
+    return false;
   }
   QString aTempDir = dialog.selectedFiles().first();
   QDir aDir(aTempDir);
@@ -468,11 +510,12 @@ void XGUI_Workshop::onSaveAs()
                                        QString(),
                                        tr("The folder already contains some files, save anyway?"),
                                        QMessageBox::Save|QMessageBox::Cancel);
-    if(answer == QMessageBox::Cancel)
-      return;
+    if(answer == QMessageBox::Cancel) {
+      return false;
+    }
   }
   myCurrentDir = aTempDir;
-  onSave();
+  return onSave();
 }
 
 //******************************************************
@@ -535,7 +578,7 @@ XGUI_Module* XGUI_Workshop::loadModule(const QString& theModule)
     }
   }
 #else
-  void* modLib = dlopen( libName.toLatin1(), RTLD_LAZY );
+  void* modLib = dlopen( libName.toLatin1(), RTLD_LAZY | RTLD_GLOBAL );
   if ( !modLib ) {
     err = QString( "Can not load library %1. %2" ).arg( libName ).arg( dlerror() );
   } else {
@@ -567,6 +610,7 @@ bool XGUI_Workshop::activateModule()
   if (!myPartSetModule)
     return false;
   myPartSetModule->createFeatures();
+  myActionsMgr->update();
   return true;
 }
 
@@ -608,6 +652,7 @@ void XGUI_Workshop::updateCommandStatus()
         aCmd->setEnabled(false);
     }
   }
+  myActionsMgr->update();
 }
 
 //******************************************************
@@ -718,25 +763,51 @@ XGUI_SalomeViewer* XGUI_Workshop::salomeViewer() const
 //**************************************************************
 void XGUI_Workshop::onContextMenuCommand(const QString& theId, bool isChecked)
 {
-  if (theId == "ACTIVATE_PART_CMD")
-    activatePart(true);
+  QFeatureList aFeatures = mySelector->selectedFeatures();
+  if ((theId == "ACTIVATE_PART_CMD") && (aFeatures.size() > 0))
+    activatePart(aFeatures.first());
   else if (theId == "DEACTIVATE_PART_CMD") 
-    activatePart(false);
+    activatePart(FeaturePtr());
+  else if (theId == "DELETE_CMD")
+    deleteFeatures(aFeatures);
+}
 
+//**************************************************************
+void XGUI_Workshop::activatePart(FeaturePtr theFeature)
+{
+  changeCurrentDocument(theFeature);
+  myObjectBrowser->activatePart(theFeature);
 }
 
 //**************************************************************
-void XGUI_Workshop::activatePart(bool toActivate)
+void XGUI_Workshop::activateLastPart()
 {
-  if (toActivate) {
-    QFeatureList aFeatures = mySelector->selectedFeatures();
-    if (aFeatures.size() > 0) {
-      changeCurrentDocument(aFeatures.first());
-      myObjectBrowser->activateCurrentPart(true);
+  PluginManagerPtr aMgr = ModelAPI_PluginManager::get();
+  DocumentPtr aDoc = aMgr->rootDocument();
+  FeaturePtr aLastPart = aDoc->feature(PARTS_GROUP, aDoc->size(PARTS_GROUP) - 1, true);
+  activatePart(aLastPart);
+}
+
+//**************************************************************
+void XGUI_Workshop::deleteFeatures(QFeatureList theList)
+{
+  QMainWindow* aDesktop = isSalomeMode()? salomeConnector()->desktop() : myMainWindow;
+  QMessageBox::StandardButton aRes = QMessageBox::warning(aDesktop, tr("Delete features"), 
+                                                          tr("Seleted features will be deleted. Continue?"), 
+                                                          QMessageBox::No | QMessageBox::Yes, QMessageBox::No);
+  if (aRes == QMessageBox::Yes) {
+    PluginManagerPtr aMgr = ModelAPI_PluginManager::get();
+    aMgr->rootDocument()->startOperation();
+    foreach (FeaturePtr aFeature, theList) {
+      if (aFeature->getKind() == "Part") {
+        DocumentPtr aDoc = aFeature->data()->docRef("PartDocument")->value();
+        if (aDoc == aMgr->currentDocument()) {
+          aDoc->close();
+        }
+      } //else
+        //aDoc = aFeature->document();
+      aMgr->rootDocument()->removeFeature(aFeature);
     }
-  } else {
-    changeCurrentDocument(FeaturePtr());
-    myObjectBrowser->activateCurrentPart(false);
+    aMgr->rootDocument()->finishOperation();
   }
 }
-