]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
bos #26446: SHAPER: customize study opening; bos #26447: SHAPER: customize script...
authorAlexey Kondratyev <alexey.kondratyev@opencascade.com>
Mon, 18 Oct 2021 08:12:43 +0000 (11:12 +0300)
committerazv <azv@opencascade.com>
Tue, 23 Nov 2021 19:56:50 +0000 (22:56 +0300)
* Add tab "General" in Preferences window.
* Add algorithm to update displaying elements depending of settings.
* Update opening file algorithm to activating parts depending of settings.
* Update activating part algorithm to display elements depending of settings.
* Update activating part algorithm to display elements depending of sub elements.
* Update the documentation.

12 files changed:
doc/gui/General/Introduction.rst
doc/gui/images/general_preferences.png [new file with mode: 0644]
src/ModuleBase/ModuleBase_Preferences.cpp
src/ModuleBase/ModuleBase_Preferences.h
src/PartSet/PartSet_MenuMgr.cpp
src/SHAPERGUI/resources/LightApp.xml.in
src/XGUI/SHAPER.xml
src/XGUI/XGUI_Tools.cpp
src/XGUI/XGUI_Tools.h
src/XGUI/XGUI_Workshop.cpp
src/XGUI/XGUI_WorkshopListener.cpp
src/XGUI/XGUI_WorkshopListener.h

index 35e17284c3f8df4180ac7fb4ebe704862081b62a..359a7f5ec3eca0c4777150594e5a9f66e3508fa1 100644 (file)
@@ -451,6 +451,7 @@ To call **Preferences** dialog box:
 
 SHAPER preferences contains the following tabs:
 
+- :ref:`general_preferences`;
 - :ref:`visualization_preferences`;
 - :ref:`plugins_preferences`;
 - :ref:`shortcuts_preferences`;
@@ -458,10 +459,42 @@ SHAPER preferences contains the following tabs:
 - :ref:`sketch_preferences`.
 - :ref:`viewer_preferences`.
 
-Visualization tab is activated by default when **Preferences** dialog box is opened in the active SHAPER module.
+General tab is activated by default when **Preferences** dialog box is opened in the active SHAPER module.
 
 Other tabs are activated by click on tab header.
 
+.. _general_preferences:
+
+General tab
+^^^^^^^^^^^
+
+This tab defines what parts to be activated and what elements to be visible after opening a study or a script.
+
+.. figure:: /images/general_preferences.png
+   :align: center
+
+   **Preferences**: General tab
+
+**Input fields**:
+- **Activate** relates to activation of part when opening a HDF document. Its could be one of the following:
+
+  - \93Last part\94 \96 activate last part in the document (**default value**);
+  - \93All parts\94 \96 activate all parts within the document;
+  - \93No activation\94 \96 do not activate any part.
+
+- **Display** in "Opening a study". It specifies the shapes, which should be visualized when activating a part. It could be one of the following:
+
+  - \93As stored in HDF\94 \96 display only the shapes visible before the document is saved (**default value**);
+  - \93Last item in each folder\94 \96 show only the last result in each folder of the part: Constructions, Results, Groups, Fields;
+  - \93All items\94 \96 show all shapes from each folder;
+  - \93No visualization\94 \96 do not display any shape.
+
+- **Display** in "Launching a python script". It specifies the shapes, which should be visualized when loading a script using "File -> Load Script..." menu. It could be one of the following:
+
+  - \93Last item in each folder\94 \96 show only the last result in each folder of the part: Constructions, Results, Groups, Fields;
+  - \93All items\94 \96 show all shapes from each folder(**default value**);
+  - \93No visualization\94 \96 do not display any shape.
+
 .. _visualization_preferences:
 
 Visualization tab
diff --git a/doc/gui/images/general_preferences.png b/doc/gui/images/general_preferences.png
new file mode 100644 (file)
index 0000000..e7eee17
Binary files /dev/null and b/doc/gui/images/general_preferences.png differ
index c651c7d46f36cc16d515bef47f77f074df6091a6..229603f834503abe506ae7dbab73070b643a1c3c 100644 (file)
@@ -35,6 +35,7 @@
 
 const QString ModuleBase_Preferences::VIEWER_SECTION = "Viewer";
 const QString ModuleBase_Preferences::MENU_SECTION = "Menu";
+const QString ModuleBase_Preferences::GENERAL_SECTION = "General";
 
 SUIT_ResourceMgr* ModuleBase_Preferences::myResourceMgr = 0;
 
@@ -115,6 +116,7 @@ void ModuleBase_Preferences::loadCustomProps()
 void ModuleBase_Preferences::createEditContent(ModuleBase_IPrefMgr* thePref, int thePage)
 {
   thePref->prefMgr()->setItemIcon(thePage, QIcon(":pictures/module.png"));
+  createGeneralTab(thePref, thePage);
   createCustomPage(thePref, thePage);
 }
 
@@ -150,6 +152,64 @@ void ModuleBase_Preferences::resetConfigPropPreferences(SUIT_PreferenceMgr* theP
   }
 }
 
+void ModuleBase_Preferences::createGeneralTab(ModuleBase_IPrefMgr* thePref, int thePageId)
+{
+  int generalTab = thePref->addPreference(QObject::tr("General"), thePageId,
+                                          SUIT_PreferenceMgr::Auto, QString(), QString());
+  thePref->setItemProperty("columns", 2, generalTab);
+
+  QStringList actItemList;
+  actItemList << QObject::tr("Last part")
+              << QObject::tr("All parts")
+              << QObject::tr("No activation");
+
+  QList<QVariant> actIdList;
+  actIdList << 0 << 1 << 2;
+
+  // Group related to opening a study
+  int group = thePref->addPreference(QObject::tr("Opening a study"), generalTab,
+                                     SUIT_PreferenceMgr::Auto, QString(), QString());
+
+  int actId = thePref->addPreference(QObject::tr("Activate"), group, SUIT_PreferenceMgr::Selector,
+                                     ModuleBase_Preferences::GENERAL_SECTION,
+                                     "part_activation_study");
+  thePref->setItemProperty("strings", actItemList, actId);
+  thePref->setItemProperty("indexes", actIdList, actId);
+
+  QStringList visuItemList;
+  visuItemList << QObject::tr("As stored in HDF")
+               << QObject::tr("Last item in each folder")
+               << QObject::tr("All items")
+               << QObject::tr("No visualization");
+
+  QList<QVariant> visuIdList;
+  visuIdList << 0 << 1 << 2 << 3;
+
+  int visuId = thePref->addPreference(QObject::tr("Display"), group, SUIT_PreferenceMgr::Selector,
+                                      ModuleBase_Preferences::GENERAL_SECTION,
+                                      "part_visualization_study");
+  thePref->setItemProperty("strings", visuItemList, visuId);
+  thePref->setItemProperty("indexes", visuIdList, visuId);
+
+  // Group related to running a python script
+  group = thePref->addPreference(QObject::tr("Launching a python script"), generalTab,
+                                 SUIT_PreferenceMgr::Auto, QString(), QString());
+
+  visuItemList.clear();
+  visuItemList << QObject::tr("Last item in each folder")
+               << QObject::tr("All items")
+               << QObject::tr("No visualization");
+
+  visuIdList.clear();
+  visuIdList << 0 << 1 << 2;
+
+  visuId = thePref->addPreference(QObject::tr("Display"), group, SUIT_PreferenceMgr::Selector,
+                                  ModuleBase_Preferences::GENERAL_SECTION,
+                                  "part_visualization_script");
+  thePref->setItemProperty("strings", visuItemList, visuId);
+  thePref->setItemProperty("indexes", visuIdList, visuId);
+}
+
 void ModuleBase_Preferences::createCustomPage(ModuleBase_IPrefMgr* thePref, int thePageId)
 {
   SUIT_ResourceMgr* aResMgr = ModuleBase_Preferences::resourceMgr();
index 9852625692d79526381c222bd0382a0d074d739f..65b2a2d7a748c3428e8fe708514061b9fd919588 100644 (file)
@@ -47,6 +47,9 @@ class MODULEBASE_EXPORT ModuleBase_Preferences
    /// Name of preferences of menu section
   static const QString MENU_SECTION;
 
+  /// Name of preferences of general section
+  static const QString GENERAL_SECTION;
+
   /// Shows a dialog box to edit preferences
   /// \param theModified a list of modified preferences
   static bool editPreferences(ModuleBase_Prefs& theModified);
@@ -83,6 +86,9 @@ private:
   /// Set default values to the Config_PropManager properties
   static void resetConfig();
 
+  /// Creates a content for General tab, which defines behavior of loading parts and displaying shapes
+  static void createGeneralTab(ModuleBase_IPrefMgr* thePref, int thePageId);
+
   /// Creates content of preferences editing widget
   static void createCustomPage(ModuleBase_IPrefMgr* thePref, int thePageId);
 
index ce5f478a3d2568c9c1c740897ec72f592193c65e..d9e7aa8bea61b8cea264159b9468e5b1b4ca3d3a 100644 (file)
@@ -46,6 +46,7 @@
 #include <XGUI_DataModel.h>
 #include <XGUI_OperationMgr.h>
 #include <XGUI_ObjectsBrowser.h>
+#include <XGUI_Tools.h>
 #include <XGUI_ViewerProxy.h>
 
 #include <Events_Loop.h>
@@ -495,15 +496,20 @@ void PartSet_MenuMgr::onActivatePart(bool)
 void PartSet_MenuMgr::activatePart(ResultPartPtr thePart) const
 {
   bool isFirstLoad = !thePart->partDoc().get();
+  ModuleBase_Tools::blockUpdateViewer(true);
   thePart->activate();
   if (isFirstLoad) {
     XGUI_Workshop* aWorkshop = myModule->getWorkshop();
     XGUI_ObjectsBrowser* aObjBrowser = aWorkshop->objectBrowser();
+    XGUI_Tools::setDisplaying(thePart);
+    Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
+    aObjBrowser->onSelectionChanged();
     DocumentPtr aDoc = thePart->partDoc();
     std::list<bool> aStates;
     aDoc->restoreNodesState(aStates);
     aObjBrowser->setStateForDoc(aDoc, aStates);
   }
+  ModuleBase_Tools::blockUpdateViewer(false);
 }
 
 void PartSet_MenuMgr::onActivateAllParts()
index 33908724f1de83403969f09bfd6e7ce62a43e555..0a0028ab87e15d8f8f2664b16057aba2e44caabc 100644 (file)
     <parameter name="PartSet" value="%SHAPER_ROOT_DIR%/share/salome/resources/shaper"/>
     <parameter name="XGUI" value="%SHAPER_ROOT_DIR%/share/salome/resources/shaper"/>
   </section>
+  <section name="General">
+    <!-- Common settings of part's activation and visualization -->
+    <parameter name="part_activation_study" value="0"/>
+    <parameter name="part_visualization_study" value="0"/>
+    <parameter name="part_visualization_script" value="1"/>
+  </section>
   <section name="Viewer" >
     <!-- Viewer preferences -->
     <parameter name="face-selection" value="true" />
index 879498824de975c3d7122204266dd0ccf6031883..94ff4fcc67ccd25b3ed3aab3eee02339243ac1aa 100644 (file)
@@ -4,6 +4,12 @@
     <parameter name="language"    value="en"/>
     <parameter name="locale"      value="true"/>
   </section>
+  <section name="General">
+    <!-- Common settings of part's activation and visualization -->
+    <parameter name="part_activation_study" value="0"/>
+    <parameter name="part_visualization_study" value="0"/>
+    <parameter name="part_visualization_script" value="1"/>
+  </section>
   <section name="Viewer" >
     <!-- Viewer preferences -->
     <parameter name="background" value="bt=2;fn=;tm=0;ts=false;c1=#cddbff;c2=#698fff;gt=1;gr=" />
index 6ff19daae3e6324a989ff8e6f1e2ce069c5614d3..3314814f141008621c92c5f0c4a6b9af6e976367 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "ModuleBase_IWorkshop.h"
 #include "ModuleBase_Tools.h"
+#include "ModuleBase_Preferences.h"
 
 #include <TopoDS_Shape.hxx>
 #include <ModelAPI_Object.h>
 #include <ModelAPI_CompositeFeature.h>
 #include <ModelAPI_Tools.h>
 #include <ModelAPI_ResultConstruction.h>
+#include <ModelAPI_ResultGroup.h>
 #include <ModelAPI_ResultBody.h>
+#include <ModelAPI_ResultField.h>
 #include <Events_InfoMessage.h>
 
+#include <SUIT_ResourceMgr.h>
+
 #include <GeomAPI_Shape.h>
 #include <GeomAlgoAPI_CompoundBuilder.h>
 
@@ -401,4 +406,44 @@ void removeTemporaryFiles(const std::string& theDirectory,
   }
 }
 
+// Set displaying status to every element on group
+static void setDisplayingByLoop(DocumentPtr theDoc, int theSize,
+  std::string theGroup, bool theDisplayFromScript)
+{
+  int aDisplayingId = -1;
+  if (theDisplayFromScript) {
+    aDisplayingId = ModuleBase_Preferences::resourceMgr()->integerValue("General",
+      "part_visualization_script", -1);
+    // Increase ID to prevert using "As stored in HDF"
+    ++aDisplayingId;
+  }
+  else {
+    aDisplayingId = ModuleBase_Preferences::resourceMgr()->integerValue("General",
+      "part_visualization_study", -1);
+
+    // if chosen "As stored in HDF" then don't change displaying
+    if (aDisplayingId == 0)
+      return;
+  }
+
+  for (int anIndex = theSize - 1; anIndex >= 0; --anIndex) {
+    ObjectPtr anObject = theDoc->object(theGroup, anIndex);
+    anObject->setDisplayed((aDisplayingId == 1 && anIndex == theSize - 1) || aDisplayingId == 2);
+  }
+}
+
+void setDisplaying(ResultPartPtr thePart, bool theDisplayFromScript)
+{
+  DocumentPtr aDoc = thePart->partDoc();
+  int aConstructionSize = aDoc->size(ModelAPI_ResultConstruction::group());
+  int aGroupSize = aDoc->size(ModelAPI_ResultGroup::group());
+  int aFieldSize = aDoc->size(ModelAPI_ResultField::group());
+  int aResultSize = aDoc->size(ModelAPI_ResultBody::group());
+  setDisplayingByLoop(aDoc, aConstructionSize,
+                      ModelAPI_ResultConstruction::group(), theDisplayFromScript);
+  setDisplayingByLoop(aDoc, aGroupSize, ModelAPI_ResultGroup::group(), theDisplayFromScript);
+  setDisplayingByLoop(aDoc, aFieldSize, ModelAPI_ResultField::group(), theDisplayFromScript);
+  setDisplayingByLoop(aDoc, aResultSize, ModelAPI_ResultBody::group(), theDisplayFromScript);
+}
+
 }
index 478857fb302a8b5d64c6f00d09f744da72e81673..65d0f424d7be83011ddf931863ed26886499eaae 100644 (file)
@@ -25,6 +25,7 @@
 #include <QRect>
 
 #include <ModelAPI_Feature.h>
+#include <ModelAPI_ResultPart.h>
 #include <ModuleBase_ViewerPrs.h>
 
 #include <ModuleBase_Definitions.h>
@@ -135,6 +136,10 @@ std::string getTmpDirByEnv( const char* thePathEnv);
 /// Removes files and directory where they are located
 void removeTemporaryFiles(const std::string& theDirectory,
   const std::list<std::string>& theFiles);
+
+/// Set displaying status for elements from part depending on the settings
+/// \param thePart a pointer of part
+XGUI_EXPORT void setDisplaying(ResultPartPtr thePart, bool theDisplayFromScript = false);
 };
 
 #endif
index 4342023ae4653ec085b1b1636606393714314c04..a572b5294f97d48d0857db40ad37ec9f1e3cf445 100644 (file)
@@ -706,6 +706,21 @@ void XGUI_Workshop::deactivateActiveObject(const ObjectPtr& theObject, const boo
       myDisplayer->deactivateObjects(anObjects, theUpdateViewer);
     }
   }
+
+  SUIT_Application * app = SUIT_Session::session()->activeApplication();
+
+  QVariant aVar = app->property("IsLoadedScript");
+
+  if (!aVar.isNull() && aVar.toBool()) {
+    DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
+    int aSize = aRootDoc->size(ModelAPI_ResultPart::group());
+    if (aSize > 0) {
+      ObjectPtr anPartObject = aRootDoc->object(ModelAPI_ResultPart::group(), aSize - 1);
+      ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(anPartObject);
+      XGUI_Tools::setDisplaying(aPart, true);
+      Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
+    }
+  }
 }
 
 //******************************************************
@@ -1067,6 +1082,37 @@ void XGUI_Workshop::openFile(const QString& theDirectory)
   }
 #endif
 
+  int anActivationId =
+    ModuleBase_Preferences::resourceMgr()->integerValue("General", "part_activation_study", -1);
+  int aSize = aRootDoc->size(ModelAPI_ResultPart::group());
+
+  if (anActivationId == 0 && aSize > 0) {
+    ObjectPtr anObject = aRootDoc->object(ModelAPI_ResultPart::group(), aSize - 1);
+    ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(anObject);
+    if (aPart.get()) {
+      aPart->activate();
+      XGUI_Tools::setDisplaying(aPart);
+    }
+  }
+  else if (anActivationId == 1) {
+    for (int anIndex = 0; anIndex < aSize; ++anIndex) {
+      ObjectPtr anObject = aRootDoc->object(ModelAPI_ResultPart::group(), anIndex);
+      ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(anObject);
+      if (aPart.get()) {
+        aPart->activate();
+        XGUI_Tools::setDisplaying(aPart);
+
+        if (anIndex < aSize - 1) {
+          SessionPtr aMgr = ModelAPI_Session::get();
+          aMgr->startOperation("Activation");
+          aMgr->setActiveDocument(aMgr->moduleDocument());
+          aMgr->finishOperation();
+          updateCommandStatus();
+          viewer()->update();
+        }
+      }
+    }
+  }
   QApplication::restoreOverrideCursor();
 }
 
index b1092af83136403d6777998c1cffde2e88b4909a..8a3f3d1814e29b30b910571ac314e6e9a6860b46 100644 (file)
 #include <ModuleBase_Tools.h>
 #include <ModuleBase_WidgetSelector.h>
 
+#ifdef HAVE_SALOME
+#include <SUIT_Application.h>
+#include <SUIT_Session.h>
+#endif
+
 #include "XGUI_ActionsMgr.h"
 #include "XGUI_Displayer.h"
 #include "XGUI_ErrorMgr.h"
@@ -392,6 +397,10 @@ void XGUI_WorkshopListener::
 void XGUI_WorkshopListener::
   onFeatureCreatedMsg(const std::shared_ptr<ModelAPI_ObjectUpdatedMessage>& theMsg)
 {
+  SUIT_Application * app = SUIT_Session::session()->activeApplication();
+
+  QVariant aVar = app->property("IsLoadedScript");
+
   std::set<ObjectPtr> anObjects = theMsg->objects();
   std::set<ObjectPtr>::const_iterator aIt;
 #ifdef DEBUG_FEATURE_CREATED
@@ -406,46 +415,32 @@ void XGUI_WorkshopListener::
 
   //bool aHasPart = false;
   bool aDisplayed = false;
-  for (aIt = anObjects.begin(); aIt != anObjects.end(); ++aIt) {
-    ObjectPtr anObject = *aIt;
+  if (aVar.isNull() || !aVar.toBool()) {
+    for (aIt = anObjects.begin(); aIt != anObjects.end(); ++aIt) {
+      ObjectPtr anObject = *aIt;
 
 #ifdef DEBUG_RESULT_COMPSOLID
-    ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(anObject);
-    if (aRes.get()) {
-      ResultCompSolidPtr aCompSolidRes = std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(aRes);
-      if (aCompSolidRes.get()) {
-          qDebug(QString("COMPSOLID, numberOfSubs = %1")
-            .arg(aCompSolidRes->numberOfSubs()).toStdString().c_str());
+      ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(anObject);
+      if (aRes.get()) {
+        ResultCompSolidPtr aCompSolidRes = std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(aRes);
+        if (aCompSolidRes.get()) {
+            qDebug(QString("COMPSOLID, numberOfSubs = %1")
+              .arg(aCompSolidRes->numberOfSubs()).toStdString().c_str());
+        }
+        if (ModelAPI_Tools::compSolidOwner(aRes))
+          qDebug("COMPSOLID sub-object");
       }
-      if (ModelAPI_Tools::compSolidOwner(aRes))
-        qDebug("COMPSOLID sub-object");
-    }
 #endif
-    // the validity of the data should be checked here in order to avoid display of the objects,
-    // which were created, then deleted, but flush for the creation event happens after that
-    // we should not display disabled objects
-    bool aHide = !anObject->data()->isValid() ||
-                 anObject->isDisabled() ||
-                 !anObject->isDisplayed();
-    if (!aHide) { // check that this is not hidden result
-      ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(anObject);
-      aHide = aRes && aRes->isConcealed();
-      // Hide the presentation with an empty shape. But isDisplayed state of the object should not
-      // be changed to the object becomes visible when the shape becomes not empty
-      if (!aHide && aRes.get())
-        aHide = !aRes->shape().get() || aRes->shape()->isNull();
-    }
-    if (!aHide) {
-      // setDisplayed has to be called in order to synchronize internal state of the object
-      // with list of displayed objects
-      if (myWorkshop->module()->canDisplayObject(anObject)) {
-        anObject->setDisplayed(true);
-        aDisplayed = displayObject(anObject);
-      } else
-        anObject->setDisplayed(false);
+
+      ResultBodyPtr aRes = std::dynamic_pointer_cast<ModelAPI_ResultBody>(anObject);
+
+      if (aRes.get() && aRes->numberOfSubs() > 0)
+        for (int anIndex = 0; anIndex < aRes->numberOfSubs(); ++anIndex)
+          setDisplayed(aRes->subResult(anIndex), aDisplayed);
+      else
+        setDisplayed(anObject, aDisplayed);
     }
   }
-
   MAYBE_UNUSED bool isCustomized = customizeFeature(anObjects, aDisplayed);
 
   //if (myObjectBrowser)
@@ -558,3 +553,32 @@ XGUI_Workshop* XGUI_WorkshopListener::workshop() const
 {
   return myWorkshop;
 }
+
+
+void XGUI_WorkshopListener::setDisplayed(ObjectPtr theObject, bool& theDisplayed)
+{
+  // the validity of the data should be checked here in order to avoid display of the objects,
+  // which were created, then deleted, but flush for the creation event happens after that
+  // we should not display disabled objects
+  bool aHide = !theObject->data()->isValid() ||
+                theObject->isDisabled() ||
+               !theObject->isDisplayed();
+  if (!aHide) { // check that this is not hidden result
+    ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
+    aHide = aRes && aRes->isConcealed();
+    // Hide the presentation with an empty shape. But isDisplayed state of the object should not
+    // be changed to the object becomes visible when the shape becomes not empty
+    if (!aHide && aRes.get())
+      aHide = !aRes->shape().get() || aRes->shape()->isNull();
+  }
+  if (!aHide) {
+    // setDisplayed has to be called in order to synchronize internal state of the object
+    // with list of displayed objects
+    if (myWorkshop->module()->canDisplayObject(theObject)) {
+      theObject->setDisplayed(true);
+      theDisplayed = displayObject(theObject);
+    }
+    else
+      theObject->setDisplayed(false);
+  }
+}
index d8827d57b05f9778d333547576b13afa3b0ff36f..dcedeb713f8ab6c12a8755e602547b7db090c0a8 100644 (file)
@@ -103,6 +103,9 @@ protected:
   XGUI_Workshop* workshop() const;
 
 private:
+
+  void setDisplayed(ObjectPtr theObject, bool& theDisplayed);
+
   XGUI_Workshop* myWorkshop; // the current workshop
 
   bool myUpdatePrefs;