Salome HOME
Fix for the issue #2753 : error when dump/load script
[modules/shaper.git] / src / XGUI / XGUI_Workshop.cpp
index a1ae91d19785ea74489c07b27c0a4d771d04cdcc..823d8fe8885d56219c2d64bb417de44914666571 100755 (executable)
@@ -51,6 +51,7 @@
 #include <XGUI_QtEvents.h>
 #include <XGUI_DataModel.h>
 #include <XGUI_InspectionPanel.h>
+#include <XGUI_CompressFiles.h>
 
 #ifndef HAVE_SALOME
 #include <AppElements_Button.h>
 #include <QAction>
 #include <QDesktopWidget>
 #include <QProcess>
+#include <QDesktopServices>
 
 #include <iterator>
 
@@ -168,10 +170,20 @@ QString XGUI_Workshop::MOVE_TO_END_COMMAND = QObject::tr("Move to the end");
 //#define DEBUG_FEATURE_NAME
 //#define DEBUG_CLEAN_HISTORY
 
+#ifdef HAVE_SALOME
+static QString MyFilter(QObject::tr("OpenParts files (*.shaper *.opp)"));
+static QString MyFilter2(QObject::tr("OpenParts files (*.shaper)"));
+static QString MyExtension(".shaper");
+#else
+static QString MyFilter(QObject::tr("OpenParts files (*.opp);;All files (*.*)"));
+static QString MyFilter2(QObject::tr("OpenParts files (*.opp)"));
+static QString MyExtension(".opp");
+#endif
+
+
 //******************************************************
 XGUI_Workshop::XGUI_Workshop(XGUI_SalomeConnector* theConnector)
     : QObject(),
-      myCurrentDir(QString()),
       myModule(NULL),
       mySalomeConnector(theConnector),
       myPropertyPanel(0),
@@ -186,7 +198,7 @@ XGUI_Workshop::XGUI_Workshop(XGUI_SalomeConnector* theConnector)
   myOperationMgr = new XGUI_OperationMgr(this, 0);
   ModuleBase_IWorkshop* aWorkshop = moduleConnector();
   // Has to be defined first in order to get errors and messages from other components
-  myEventsListener = new XGUI_WorkshopListener(aWorkshop);
+  myEventsListener = new XGUI_WorkshopListener(this);
   mySelectionActivate = new XGUI_SelectionActivate(aWorkshop);
 
   SUIT_ResourceMgr* aResMgr = ModuleBase_Preferences::resourceMgr();
@@ -298,6 +310,9 @@ XGUI_Workshop::~XGUI_Workshop(void)
 
   delete myDisplayer;
   delete myDataModelXMLReader;
+  delete mySelectionActivate;
+  delete myMenuMgr;
+  clearTemporaryDir();
 }
 
 //******************************************************
@@ -412,7 +427,7 @@ void XGUI_Workshop::initMenu()
                                                         QKeySequence::Undo, false,
                                                         "MEN_DESK_EDIT");
   QString aToolBarTitle = tr( "INF_DESK_TOOLBAR_STANDARD" );
-  salomeConnector()->addActionInToolbar( aAction,aToolBarTitle  );
+  salomeConnector()->addActionInToolbar( aAction,aToolBarTitle );
 
   connect(aAction, SIGNAL(triggered(bool)), this, SLOT(onUndo()));
   addHistoryMenu(aAction, SIGNAL(updateUndoHistory(const QList<ActionInfo>&)), SLOT(onUndo(int)));
@@ -427,6 +442,18 @@ void XGUI_Workshop::initMenu()
 
   salomeConnector()->addDesktopMenuSeparator("MEN_DESK_EDIT");
 
+  aAction = salomeConnector()->addDesktopCommand("AUTOCOMPUTE_CMD", tr("Auto rebuild"),
+                                              tr("Blocks immediate apply of modifications"),
+                                              QIcon(":pictures/autoapply.png"), QKeySequence(),
+                                              false, "MEN_DESK_EDIT");
+  salomeConnector()->addActionInToolbar( aAction, aToolBarTitle );
+
+  connect(aAction, SIGNAL(triggered(bool)), this, SLOT(onAutoApply()));
+
+  salomeConnector()->addDesktopMenuSeparator("MEN_DESK_EDIT");
+
+
+  // Add commands to a file menu
   aAction = salomeConnector()->addDesktopCommand("SAVEAS_CMD", tr("Export native..."),
                                              tr("Export the current document into a native file"),
                                               QIcon(), QKeySequence(),
@@ -477,9 +504,12 @@ void XGUI_Workshop::initMenu()
                                 QIcon(":pictures/open.png"), QKeySequence::Open);
   aCommand->connectTo(this, SLOT(onOpen()));
 
-  aCommand = aGroup->addFeature("EXEC_CMD", tr("Launch Script"), tr("Launch Python script file"),
-                                QIcon(":pictures/assembly.png"), QKeySequence());
-  aCommand->connectTo(this, SLOT(onFileExec()));
+
+  aCommand = aGroup->addFeature("AUTOCOMPUTE_CMD", tr("Auto rebuild"),
+                                tr("Blocks immediate apply of modifications"),
+                                QIcon(":pictures/autoapply_start.png"), QKeySequence());
+  //aCommand->setChecked(ModelAPI_Session::get()->isAutoUpdateBlocked());
+  aCommand->connectTo(this, SLOT(onAutoApply()));
 
   aCommand = aGroup->addFeature("PREF_CMD", tr("Preferences"), tr("Edit preferences"),
                                 QIcon(":pictures/preferences.png"), QKeySequence::Preferences);
@@ -575,14 +605,14 @@ void XGUI_Workshop::onHelpActionClicked()
       if (!aHelpPage.isEmpty()) {
         QString aDocDir;
         const QChar aSep = QDir::separator();
-        QString platform;
-        SUIT_ResourceMgr* aResMgr = ModuleBase_Preferences::resourceMgr();
-#ifdef WIN32
-        platform = "winapplication";
-#else
-        platform = "application";
-#endif
-        QString aBrowserName = aResMgr->stringValue("ExternalBrowser", platform);
+//        QString platform;
+//        SUIT_ResourceMgr* aResMgr = ModuleBase_Preferences::resourceMgr();
+//#ifdef WIN32
+//        platform = "winapplication";
+//#else
+//        platform = "application";
+//#endif
+//        QString aBrowserName = aResMgr->stringValue("ExternalBrowser", platform);
 
 #ifdef HAVE_SALOME
         QString aDir(getenv("SHAPER_ROOT_DIR"));
@@ -594,9 +624,11 @@ void XGUI_Workshop::onHelpActionClicked()
         QString aDir(getenv("OPENPARTS_ROOT_DIR"));
         aDocDir = aDir + aSep + "doc" + aSep + "gui";
 #endif
-        QStringList aParams;
-        aParams << aDocDir + aSep + aHelpPage;
-        QProcess::startDetached(aBrowserName, aParams);
+        QString aFileName = aDocDir + aSep + aHelpPage;
+        if (QFile::exists(aFileName)) {
+          QUrl aUrl = QUrl::fromLocalFile(aFileName);
+          QDesktopServices::openUrl(aUrl);
+        }
       }
     }
   }
@@ -895,25 +927,26 @@ void XGUI_Workshop::onOpen()
     } else if (anAnswer == QMessageBox::Cancel) {
       return;
     }
-    myCurrentDir = "";
+    myCurrentFile = QString();
   }
 
   //show file dialog, check if readable and open
-  QString aDirectory = QFileDialog::getExistingDirectory(desktop(), tr("Select directory"));
-  openDirectory(aDirectory);
+  QString aFile = QFileDialog::getOpenFileName(desktop(), tr("Open file"), QString(), MyFilter);
+  if (!aFile.isNull())
+    openFile(aFile);
 }
 
 //******************************************************
-void XGUI_Workshop::openDirectory(const QString& theDirectory)
+void XGUI_Workshop::openFile(const QString& theDirectory)
 {
-  myCurrentDir = theDirectory;
-  if (myCurrentDir.isEmpty())
+  myCurrentFile = theDirectory;
+  if (myCurrentFile.isEmpty())
     return;
 
-  QFileInfo aFileInfo(myCurrentDir);
+  QFileInfo aFileInfo(myCurrentFile);
   if (!aFileInfo.exists() || !aFileInfo.isReadable()) {
     QMessageBox::critical(desktop(), tr("Warning"), tr("Unable to open the file."));
-    myCurrentDir = "";
+    myCurrentFile = QString();
     return;
   }
 
@@ -921,7 +954,12 @@ void XGUI_Workshop::openDirectory(const QString& theDirectory)
   module()->closeDocument();
   SessionPtr aSession = ModelAPI_Session::get();
   aSession->closeAll();
-  aSession->load(myCurrentDir.toLatin1().constData());
+
+  clearTemporaryDir();
+  if (!XGUI_CompressFiles::uncompress(myCurrentFile, myTmpDir.path()))
+    return;
+
+  aSession->load(myTmpDir.path().toLatin1().constData());
   myObjectBrowser->rebuildDataTree();
 
   // Open first level of data tree
@@ -932,7 +970,7 @@ void XGUI_Workshop::openDirectory(const QString& theDirectory)
 
   updateCommandStatus();
 #ifndef HAVE_SALOME
-  myMainWindow->setCurrentDir(myCurrentDir, true);
+  myMainWindow->setCurrentDir(myCurrentFile, true);
 #endif
 
 #ifdef _DEBUG
@@ -1028,11 +1066,18 @@ bool XGUI_Workshop::onSave()
 {
   if(!myOperationMgr->abortAllOperations(XGUI_OperationMgr::XGUI_InformationMessage))
     return false;
-  if (myCurrentDir.isEmpty()) {
+  if (myCurrentFile.isEmpty()) {
     return onSaveAs();
   }
+  SessionPtr aMgr = ModelAPI_Session::get();
+  if (aMgr->isAutoUpdateBlocked())
+    aMgr->blockAutoUpdate(false);
+
   std::list<std::string> aFiles;
-  saveDocument(myCurrentDir, aFiles);
+  saveDocument(myTmpDir.path(), aFiles);
+  if (!XGUI_CompressFiles::compress(myCurrentFile, aFiles))
+    return false;
+
   updateCommandStatus();
 #ifndef HAVE_SALOME
     myMainWindow->setModifiedState(false);
@@ -1045,34 +1090,17 @@ bool XGUI_Workshop::onSaveAs()
 {
   if(!myOperationMgr->abortAllOperations(XGUI_OperationMgr::XGUI_InformationMessage))
     return false;
-  QFileDialog dialog(desktop());
-  dialog.setWindowTitle(tr("Select directory to save files..."));
-  dialog.setFileMode(QFileDialog::Directory);
-  dialog.setFilter(QDir::AllDirs);
-  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()) {
-    int answer = QMessageBox::question(
-        desktop(),
-        // Title of the dialog which asks user if he wants to save study
-        // in existing non-empty folder
-        tr("Save"),
-        tr("The directory already contains some files, save anyway?"),
-        QMessageBox::Save | QMessageBox::Cancel);
-    if (answer == QMessageBox::Cancel) {
-      return false;
+  myCurrentFile = QFileDialog::getSaveFileName(desktop(), tr("Select name to save file..."),
+    QString(), MyFilter2);
+  if (!myCurrentFile.isNull()) {
+    if (!myCurrentFile.endsWith(MyExtension)) {
+      myCurrentFile += MyExtension;
     }
   }
-  myCurrentDir = aTempDir;
+  else
+    return false;
 #ifndef HAVE_SALOME
-    myMainWindow->setCurrentDir(myCurrentDir, false);
+    myMainWindow->setCurrentDir(myCurrentFile, false);
     myMainWindow->setModifiedState(false);
 #endif
   return onSave();
@@ -1303,6 +1331,12 @@ void XGUI_Workshop::updateCommandStatus()
         else
           aCmd->setEnabled(myModule->canRedo());
       }
+      else if (aId == "AUTOCOMPUTE_CMD") {
+        //aCmd->setChecked(aMgr->isAutoUpdateBlocked());
+        aCmd->setIcon(aMgr->isAutoUpdateBlocked() ?
+          QIcon(":pictures/autoapply_stop.png") :
+          QIcon(":pictures/autoapply_start.png"));
+      }
       else
         // Enable all commands
         aCmd->setEnabled(true);
@@ -1395,6 +1429,8 @@ void XGUI_Workshop::createDockWidgets()
     Qt::RightDockWidgetArea);
   aDesktop->addDockWidget(Qt::RightDockWidgetArea, myInspectionPanel);
 
+  myInspectionPanel->hide();
+
   aDesktop->addDockWidget(
 #ifdef HAVE_SALOME
     Qt::RightDockWidgetArea,
@@ -2465,11 +2501,14 @@ void XGUI_Workshop::showObjects(const QObjectPtrList& theList, bool isVisible)
 //**************************************************************
 void XGUI_Workshop::showOnlyObjects(const QObjectPtrList& theList)
 {
+  QObjectPtrList aSrcList = theList;
   // Hide all displayed objects
   QObjectPtrList aList = myDisplayer->displayedObjects();
   foreach (ObjectPtr aObj, aList) {
-    if (module()->canEraseObject(aObj))
+    if ((!aSrcList.contains(aObj)) && (module()->canEraseObject(aObj)))
       aObj->setDisplayed(false);
+    else
+      aSrcList.removeAll(aObj);
   }
   //Do not use eraseAll if you didn't send Redisplay event:
   //all objects are erased from viewer, but considered as displayed in displayer
@@ -2481,7 +2520,7 @@ void XGUI_Workshop::showOnlyObjects(const QObjectPtrList& theList)
 #endif
 
   std::set<ObjectPtr> anObjects;
-  foreach (ObjectPtr aObj, theList) {
+  foreach (ObjectPtr aObj, aSrcList) {
     anObjects.insert(aObj);
   }
 
@@ -2489,7 +2528,7 @@ void XGUI_Workshop::showOnlyObjects(const QObjectPtrList& theList)
     return;
 
   // Show only objects from the list
-  foreach (ObjectPtr aObj, theList) {
+  foreach (ObjectPtr aObj, aSrcList) {
     aObj->setDisplayed(true);
   }
   Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
@@ -2793,20 +2832,45 @@ void XGUI_Workshop::moveOutFolder(bool isBefore)
   updateCommandStatus();
 }
 
-#ifndef HAVE_SALOME
-#include <PyConsole_Console.h>
-void XGUI_Workshop::onFileExec()
+void XGUI_Workshop::onAutoApply()
 {
-  QString aScript = QFileDialog::getOpenFileName(myMainWindow, tr("Open script"),
-      QString(), "Python script (*.py)");
+  SessionPtr aMgr = ModelAPI_Session::get();
+  bool isBlocked = aMgr->isAutoUpdateBlocked();
+  aMgr->blockAutoUpdate(!isBlocked);
+}
 
-  if (!aScript.isNull()) {
-    PyConsole_Console* aConsole = myMainWindow->pythonConsole();
-    aConsole->execAndWait(QString("f = open('%1', 'rb')").arg(aScript));
-    QString aExecStr =
-      QString("exec(compile(f.read(), '%1', 'exec'))").arg(aScript);
-    aConsole->execAndWait(aExecStr);
-    aConsole->execAndWait("f.close()");
+void XGUI_Workshop::updateAutoComputeState()
+{
+  SessionPtr aMgr = ModelAPI_Session::get();
+  bool isComputeBlocked = aMgr->isAutoUpdateBlocked();
+#ifdef HAVE_SALOME
+  QAction* aUpdateCmd;
+  QList<QAction*> aCommands = mySalomeConnector->commandList();
+  foreach(QAction* aCmd, aCommands) {
+    if (aCmd->data().toString() == "AUTOCOMPUTE_CMD") {
+      aUpdateCmd = aCmd;
+      break;
+    }
   }
-}
+  aUpdateCmd->setIcon(isComputeBlocked? QIcon(":pictures/autoapply_stop.png") :
+    QIcon(":pictures/autoapply_start.png"));
+#else
+  AppElements_MainMenu* aMenuBar = myMainWindow->menuObject();
+  AppElements_Command* aUpdateCmd = aMenuBar->feature("AUTOCOMPUTE_CMD");
+  aUpdateCmd->button()->setIcon(isComputeBlocked? QIcon(":pictures/autoapply_stop.png") :
+    QIcon(":pictures/autoapply_start.png"));
 #endif
+}
+
+
+void XGUI_Workshop::clearTemporaryDir()
+{
+  QDir aDir(myTmpDir.path());
+  if (!aDir.isEmpty()) {
+    QStringList aEntries;
+    aDir.entryList(aEntries);
+    foreach(QString aFile, aEntries) {
+      aDir.remove(aFile);
+    }
+  }
+}
\ No newline at end of file