Salome HOME
Issue #1368: Creation of a Qt panel. Persistent mechanism.
authornds <nds@opencascade.com>
Fri, 1 Apr 2016 16:05:20 +0000 (19:05 +0300)
committernds <nds@opencascade.com>
Fri, 1 Apr 2016 16:05:56 +0000 (19:05 +0300)
18 files changed:
src/ModuleBase/ModuleBase_IWidgetCreator.cpp
src/ModuleBase/ModuleBase_IWidgetCreator.h
src/ModuleBase/ModuleBase_WidgetCreatorFactory.cpp
src/ModuleBase/ModuleBase_WidgetCreatorFactory.h
src/ModuleBase/ModuleBase_WidgetFactory.cpp
src/ModuleBase/ModuleBase_WidgetFactory.h
src/SamplePanelPlugin/CMakeLists.txt
src/SamplePanelPlugin/SamplePanelPlugin_Feature.cpp
src/SamplePanelPlugin/SamplePanelPlugin_Feature.h
src/SamplePanelPlugin/SamplePanelPlugin_Panel.cpp
src/SamplePanelPlugin/SamplePanelPlugin_Panel.h
src/SamplePanelPlugin/SamplePanelPlugin_WidgetCreator.cpp
src/SamplePanelPlugin/SamplePanelPlugin_WidgetCreator.h
src/XGUI/XGUI_OperationMgr.cpp
src/XGUI/XGUI_OperationMgr.h
src/XGUI/XGUI_PropertyPanel.cpp
src/XGUI/XGUI_PropertyPanel.h
src/XGUI/XGUI_WorkshopListener.cpp

index 1ea485604b2e71b4137679dd5c500bee9ad9e2ce..10e495f7b6f11d8665f02cd80916072c2927ba50 100755 (executable)
@@ -11,7 +11,8 @@ ModuleBase_IWidgetCreator::~ModuleBase_IWidgetCreator()
 }
 
 QWidget* ModuleBase_IWidgetCreator::createPanelByType(const std::string& theType,
-                                                      QWidget* theParent)
+                                                      QWidget* theParent,
+                                                      const FeaturePtr& theFeature)
 {
   return 0;
 }
index cbab144bed2bda4c567efaa159edab5d164afa8e..eac9882635f416b2e0dd52c89c67c5e1277bcd6d 100755 (executable)
@@ -5,6 +5,8 @@
 
 #include "ModuleBase.h"
 
+#include "ModelAPI_Feature.h"
+
 #include <set>
 #include <string>
 #include <memory>
@@ -48,9 +50,11 @@ public:
   /// The default implementation is empty
   /// \param theType a panel type
   /// \param theParent a parent widget
+  /// \param theFeature a feature modified in the panel
   /// \return created widget or null
   virtual QWidget* createPanelByType(const std::string& theType,
-                                     QWidget* theParent);
+                                     QWidget* theParent,
+                                     const FeaturePtr& theFeature);
 
   /// Create page by its type
   /// The default implementation is empty
index 2c5d6772b0255af622839791c11317bff98b7582..13c7bf571d9e5db21073f67610ebd1a15d7dc1c8 100755 (executable)
@@ -80,12 +80,14 @@ bool ModuleBase_WidgetCreatorFactory::hasPanelWidget(const std::string& theType)
   return myPanelToCreator.contains(theType);
 }
 
-QWidget* ModuleBase_WidgetCreatorFactory::createPanel(const std::string& theType, QWidget* theParent)
+QWidget* ModuleBase_WidgetCreatorFactory::createPanelByType(const std::string& theType,
+                                                            QWidget* theParent,
+                                                            const FeaturePtr& theFeature)
 {
   QWidget* aPanel = 0;
   if (myPanelToCreator.contains(theType)) {
     WidgetCreatorPtr aCreator = myPanelToCreator[theType];
-    aPanel = aCreator->createPanelByType(theType, theParent);
+    aPanel = aCreator->createPanelByType(theType, theParent, theFeature);
   }
   return aPanel;
 }
index 6373eebba0b99b64b2bb4a5a635e1d8cce567aab..5cbc34c06bc2bb582cc295e85193548bc4906204 100755 (executable)
@@ -16,6 +16,8 @@
 
 #include <ModuleBase_IWidgetCreator.h>
 
+#include <ModelAPI_Feature.h>
+
 class ModuleBase_ModelWidget;
 class ModuleBase_PageBase;
 class ModuleBase_IWorkshop;
@@ -48,8 +50,10 @@ class MODULEBASE_EXPORT ModuleBase_WidgetCreatorFactory
   /// Create panel by its type
   /// \param theType a type
   /// \param theParent a parent widget
+  /// \param theFeature a feature to fill the panel
   /// \return a created panel or null
-  QWidget* createPanel(const std::string& theType, QWidget* theParent);
+  QWidget* createPanelByType(const std::string& theType, QWidget* theParent,
+                             const FeaturePtr& theFeature);
 
   /// Returns true if there is a creator, which can make a page by the type
   /// \param theType a type
index e8ae59b507d7ae2a7401fa7b4a52737d3638bf94..70eef3959a96f42f70f7ca2dedefcd854cc0f19a 100644 (file)
@@ -73,12 +73,14 @@ void ModuleBase_WidgetFactory::createWidget(ModuleBase_PageBase* thePage)
 {
   std::string aWType = myWidgetApi->widgetType();
   if (aWType == NODE_FEATURE) {
-    QWidget* aPanel = createPanel(thePage->pageWidget());
-    if (aPanel) {
-      thePage->addWidget(aPanel);
-      thePage->alignToTop();
+    // if XML definition of the feature contains the next key, the widgets should not be created,
+    // but a specific panel should be made. However, to provide persistent of the panel values,
+    // we need to get into the panel the feature of the operation. As a result this panel should
+    // be created after the feature creating(create operation). The method setPanel() of this
+    // class is used for this. Here, we just return to avoid the widgets creation.
+    std::string aPanelName = myWidgetApi->getProperty(PROPERTY_PANEL_ID);
+    if (!aPanelName.empty())
       return;
-    }
   }
 
   if (!myWidgetApi->toChildWidget())
@@ -130,6 +132,18 @@ void ModuleBase_WidgetFactory::createWidget(ModuleBase_PageBase* thePage)
   thePage->alignToTop();
 }
 
+void ModuleBase_WidgetFactory::createPanel(ModuleBase_PageBase* thePage,
+                                           const FeaturePtr& theFeature)
+{
+  std::string aPanelName = myWidgetApi->getProperty(PROPERTY_PANEL_ID);
+  if (!aPanelName.empty() && ModuleBase_WidgetCreatorFactory::get()->hasPanelWidget(aPanelName)) {
+    QWidget* aPanel = ModuleBase_WidgetCreatorFactory::get()->createPanelByType(aPanelName,
+                                                               thePage->pageWidget(), theFeature);
+    thePage->addWidget(aPanel);
+    thePage->alignToTop();
+  }
+}
+
 void ModuleBase_WidgetFactory::createWidget(ModuleBase_PageBase* thePage,
                                             const std::string& theWidgetId)
 {
@@ -227,15 +241,6 @@ void ModuleBase_WidgetFactory::moveToWidgetId(const std::string& theWidgetId, bo
   } while (!theFound && myWidgetApi->toNextWidget());
 }
 
-QWidget* ModuleBase_WidgetFactory::createPanel(QWidget* theParent)
-{
-  QWidget* aPanel = 0;
-  std::string aPanelName = myWidgetApi->getProperty(PROPERTY_PANEL_ID);
-  if (!aPanelName.empty() && ModuleBase_WidgetCreatorFactory::get()->hasPanelWidget(aPanelName))
-    aPanel = ModuleBase_WidgetCreatorFactory::get()->createPanel(aPanelName, theParent);
-  return aPanel;
-}
-
 ModuleBase_PageBase* ModuleBase_WidgetFactory::createPageByType(const std::string& theType,
                                                                 QWidget* theParent)
 {
index 180c265b8279b9ec0fcd6bfff3369236c1a44e0a..96489ce8e52ba0129700a5b5c81b6bb54959b5fb 100644 (file)
@@ -41,6 +41,11 @@ class MODULEBASE_EXPORT ModuleBase_WidgetFactory
   /// \param thePage a parent page
   void createWidget(ModuleBase_PageBase* thePage);
 
+  /// Creates property panel content for the feature
+  /// \param thePage a parent page
+  /// \param theFeature a feature to fill the panel
+  void createPanel(ModuleBase_PageBase* thePage, const FeaturePtr& theFeature);
+
   /// Creates one widget for property panel for the widget with given index
   /// \param theParent a parent widget
   /// \param theWidgetId a widget index
@@ -67,11 +72,6 @@ protected:
   /// check if ModuleBase_Widget has expandable widgets in getControls
   bool hasExpandingControls(QWidget* theParent);
 
-  /// creates panel control, if the corresponded parameter is provided by feature
-  /// \param theParent a parent widget
-  /// \return true if the panel is created
-  QWidget* createPanel(QWidget* theParent);
-
   /// Create page by its type
   /// \param theType a type
   /// \param theParent a parent widget
index afb6f04826769adddacd9333033196ec0a47fe92..ab48f60733b9cef6089f16c57c6a39d25264b70c 100755 (executable)
@@ -1,7 +1,7 @@
 ## Copyright (C) 2014-20xx CEA/DEN, EDF R&D
 
 INCLUDE(Common)
-INCLUDE(UnitTest)
+SET(CMAKE_AUTOMOC ON)
 
 SET(PROJECT_HEADERS
     SamplePanelPlugin.h
index 3beab1b74db557de0c15f01b11149cbd771b107e..e2959314a5051aa40e3545c3b44b9f6514e60bb8 100755 (executable)
@@ -6,7 +6,14 @@
 
 #include "SamplePanelPlugin_Feature.h"
 
+#include "ModelAPI_AttributeInteger.h"
+
 SamplePanelPlugin_Feature::SamplePanelPlugin_Feature()
 : ModelAPI_Feature()
 {
 }
+
+void SamplePanelPlugin_Feature::initAttributes()
+{
+  data()->addAttribute(VALUE_ID(), ModelAPI_AttributeInteger::typeId());
+}
index 3353b906dae84153eb8ffcf84d99616e0379be61..c174836242f151fdb00f90199993d4e9f987f4f8 100755 (executable)
@@ -25,8 +25,15 @@ class SamplePanelPlugin_Feature : public ModelAPI_Feature
     return MY_SAMPLE_PANEL_FEATURE_ID;
   }
 
+  /// Total number of objects, initial and translated objects
+  inline static const std::string& VALUE_ID()
+  {
+    static const std::string MY_VALUE_ID("Value");
+    return MY_VALUE_ID;
+  }
+
   /// Request for initialization of data model of the object: adding all attributes
-  virtual void initAttributes() {};
+  virtual void initAttributes();
 
   /// Returns the unique kind of a feature
   virtual const std::string& getKind() {
index baaecd720c2c010589b7ea9aaed993f80651d6d0..36225355fb521aa5f9cf945bfd07d23b23653ccb 100755 (executable)
@@ -5,21 +5,62 @@
 // Author:      Natalia ERMOLAEVA
 
 #include <SamplePanelPlugin_Panel.h>
+#include <SamplePanelPlugin_Feature.h>
+
+#include <ModelAPI_AttributeInteger.h>
+#include <ModelAPI_Events.h>
+
+#include <Events_Loop.h>
 
 #include <QGridLayout>
 #include <QLabel>
 #include <QComboBox>
 
 SamplePanelPlugin_Panel::SamplePanelPlugin_Panel(QWidget* theParent)
-  : QWidget(theParent)
+: QWidget(theParent), myDefaultValue(0)
 {
   QGridLayout* aLayout = new QGridLayout(this);
   aLayout->addWidget(new QLabel("Values:"), 0, 0);
 
-  QComboBox* aComboBox = new QComboBox(this);
-  aComboBox->addItem("Value_1");
-  aComboBox->addItem("Value_2");
-  aComboBox->addItem("Value_3");
+  myComboBox = new QComboBox(this);
+  myComboBox->addItem("Value_1");
+  myComboBox->addItem("Value_2");
+  myComboBox->addItem("Value_3");
+
+  connect(myComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(onCurrentIndexChanged(int)));
+  aLayout->addWidget(myComboBox, 0, 1);
+}
+
+void SamplePanelPlugin_Panel::setFeature(const FeaturePtr& theFeature)
+{
+  myFeature = theFeature;
+
+  AttributePtr anAttribute = myFeature->attribute(SamplePanelPlugin_Feature::VALUE_ID());
+  AttributeIntegerPtr aValueAttribute =
+                        std::dynamic_pointer_cast<ModelAPI_AttributeInteger>(anAttribute);
+  /// the attribute should be filled with some value, because Apply button of the Property
+  /// panel is enabled only if all attributes of the feature are initialized
+  /// It is possible to make it in the initializeAttribute method of the feature after
+  /// attribute creation
+  if (!aValueAttribute->isInitialized()) {
+    aValueAttribute->setValue(myDefaultValue);
+    /// to update error state of the feature: previous value was that this attribute is not
+    /// initialized yet. Apply of Property panel was disabled.
+    Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
+  }
+
+  int aValueId = aValueAttribute->value();
+  myComboBox->setCurrentIndex(aValueId);
+}
+
+void SamplePanelPlugin_Panel::onCurrentIndexChanged(int theIndex)
+{
+  if (!myFeature.get())
+    return;
 
-  aLayout->addWidget(aComboBox, 0, 1);
+  AttributePtr anAttribute = myFeature->attribute(SamplePanelPlugin_Feature::VALUE_ID());
+  AttributeIntegerPtr aValueAttribute =
+                        std::dynamic_pointer_cast<ModelAPI_AttributeInteger>(anAttribute);
+  aValueAttribute->setValue(theIndex);
+  Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
 }
index 29c2859d8cc449a7a3697fb78eac1c875394a732..1855e093fe7df7823d0f2e1353b7eb41fb533158 100755 (executable)
@@ -9,17 +9,36 @@
 
 #include <QWidget>
 
+#include <ModelAPI_Feature.h>
+
+class QComboBox;
+
 /*!
  * \ingroup GUI
- * Represent a property panel's list of ModuleBase_ModelWidgets.
+ * Represent a content of the property panel to show/modify parameters of some feature.
  */
 class SamplePanelPlugin_Panel : public QWidget
 {
+ Q_OBJECT
 public:
   /// Constructs a panel page
   SamplePanelPlugin_Panel(QWidget* theParent);
   /// Destructs the page
   virtual ~SamplePanelPlugin_Panel() {}
+
+  /// Fill the panel by the feature
+  /// \param theFeature a feature to fill the panel controls
+  void setFeature(const FeaturePtr& theFeature);
+
+protected slots:
+  /// Update feature attribute by the current value of combo box
+  /// \param theIndex a combo box modified value
+  void onCurrentIndexChanged(int theIndex);
+
+private:
+  FeaturePtr myFeature; // the feature which corresponds to the current panel
+  QComboBox* myComboBox; // control for value attribute of the current feature
+  int myDefaultValue; /// the default combo box value
 };
 
 #endif /* SAMPLEPANELPLUGIN_PANEL_H_ */
index 9389905cefbd2469a5d7826fd3c4357b880c2cef..90c9249de10f143a7226ee853d3998b437fba699 100755 (executable)
@@ -20,14 +20,17 @@ void SamplePanelPlugin_WidgetCreator::panelTypes(std::set<std::string>& theTypes
 }
 
 QWidget* SamplePanelPlugin_WidgetCreator::createPanelByType(const std::string& theType,
-                                                            QWidget* theParent)
+                                                            QWidget* theParent,
+                                                            const FeaturePtr& theFeature)
 {
   QWidget* aWidget = 0;
   if (myPanelTypes.find(theType) == myPanelTypes.end())
     return aWidget;
 
   if (theType == "QtPanel") {
-    aWidget = new SamplePanelPlugin_Panel(theParent);
+    SamplePanelPlugin_Panel* aPanel = new SamplePanelPlugin_Panel(theParent);
+    aPanel->setFeature(theFeature);
+    aWidget = aPanel;
   }
 
   return aWidget;
index 315742fa60eb42e12175233c8135c71766f9e310..548cbba1aa1cecd02fe0fe7f7a3d6df2fbd9bf98 100755 (executable)
@@ -36,9 +36,11 @@ public:
   /// Create panel control by its type.
   /// \param theType a panel type
   /// \param theParent a parent widget
+  /// \param theFeature a feature to fill the panel
   /// \return created widget or null
   virtual QWidget* createPanelByType(const std::string& theType,
-                                     QWidget* theParent);
+                                     QWidget* theParent,
+                                     const FeaturePtr& theFeature);
 private:
   std::set<std::string> myPanelTypes; /// types of panels
 };
index 949d9f9f3262990a4ba1afba9a8e6f4f07c11be8..ad8596ab3eff716d1d4f09e28806e3fc75be7595 100644 (file)
@@ -8,7 +8,8 @@
 #include "XGUI_ModuleConnector.h"
 #include "XGUI_Workshop.h"
 #include "XGUI_ErrorMgr.h"
-#include <XGUI_ObjectsBrowser.h>
+#include "XGUI_Tools.h"
+#include "XGUI_ObjectsBrowser.h"
 
 #include <ModuleBase_IPropertyPanel.h>
 #include <ModuleBase_ModelWidget.h>
@@ -233,7 +234,7 @@ bool XGUI_OperationMgr::commitAllOperations()
   bool isCompositeCommitted = false;
   while (hasOperation()) {
     ModuleBase_Operation* anOperation = currentOperation();
-    if (workshop()->errorMgr()->isApplyEnabled()) {
+    if (XGUI_Tools::workshop(myWorkshop)->errorMgr()->isApplyEnabled()) {
       onCommitOperation();
     } else {
       abortOperation(anOperation);
@@ -259,12 +260,12 @@ void XGUI_OperationMgr::onValidateOperation()
   ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
                                                                           (currentOperation());
   if(aFOperation && aFOperation->feature().get())
-    workshop()->errorMgr()->updateActions(aFOperation->feature());
+    XGUI_Tools::workshop(myWorkshop)->errorMgr()->updateActions(aFOperation->feature());
 }
 
 void XGUI_OperationMgr::updateApplyOfOperations(ModuleBase_Operation* theOperation)
 {
-  XGUI_ErrorMgr* anErrorMgr = workshop()->errorMgr();
+  XGUI_ErrorMgr* anErrorMgr = XGUI_Tools::workshop(myWorkshop)->errorMgr();
   if (theOperation) {
     ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>(theOperation);
     if (aFOperation)
@@ -356,7 +357,7 @@ bool XGUI_OperationMgr::canStartOperation(const QString& theId)
       else if (canStopOperation(aCurrentOp)) {
         // the started operation is granted in the parrent operation,
         // e.g. current - Line in Sketch, started Circle 
-        if (workshop()->errorMgr()->isApplyEnabled() && aCurrentOp->isModified())
+        if (XGUI_Tools::workshop(myWorkshop)->errorMgr()->isApplyEnabled() && aCurrentOp->isModified())
           aCurrentOp->commit();
         else
           abortOperation(aCurrentOp);
@@ -661,25 +662,19 @@ bool XGUI_OperationMgr::onProcessDelete(QObject* theObject)
     // after widget, object browser and viewer should process delete
     /// other widgets such as line edit controls should not lead to
     /// processing delete by workshop
-    XGUI_ObjectsBrowser* aBrowser = workshop()->objectBrowser();
+    XGUI_ObjectsBrowser* aBrowser = XGUI_Tools::workshop(myWorkshop)->objectBrowser();
     QWidget* aViewPort = myWorkshop->viewer()->activeViewPort();
     // property panel child object is processed to process delete performed on Apply button of PP
     if (theObject == aBrowser->treeView() ||
         isChildObject(theObject, aViewPort) ||
         isPPChildObject)
-      workshop()->deleteObjects();
+      XGUI_Tools::workshop(myWorkshop)->deleteObjects();
     isAccepted = true;
   }
 
   return isAccepted;
 }
 
-XGUI_Workshop* XGUI_OperationMgr::workshop() const
-{
-  XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(myWorkshop);
-  return aConnector->workshop();
-}
-
 bool XGUI_OperationMgr::isChildObject(const QObject* theObject, const QObject* theParent)
 {
   bool isPPChild = false;
index 3b08ba8b9ef7b72b82cc3fa270dbfd8dd90209cf..bbc07a9a4d159a562e7492ad466f1d0f09748e6e 100755 (executable)
@@ -53,6 +53,9 @@ Q_OBJECT
   void setWorkshop(ModuleBase_IWorkshop* theWorkshop)
   { myWorkshop = theWorkshop; };
 
+  /// Current workshop
+  ModuleBase_IWorkshop* workshop() const { return myWorkshop; }
+
   /// Returns the current operation or NULL
   /// \return the current operation
   ModuleBase_Operation* currentOperation() const;
@@ -208,8 +211,6 @@ protected: // TEMPORARY
   void onOperationResumed();
 
 private:
-  XGUI_Workshop* workshop() const;
-
   /// Checks if the object is a parent or a child under
   /// \param theObject an investivated object
   /// \param theParent a candidate to be a parent
index 8b1ab4f03e5f035e1222f19c354945b178e60566..a3abb42d2dcc30cec0f94a21e40341304db58788 100755 (executable)
@@ -15,6 +15,8 @@
 #include <ModuleBase_Tools.h>
 #include <ModuleBase_PageBase.h>
 #include <ModuleBase_PageWidget.h>
+#include <ModuleBase_WidgetFactory.h>
+#include <ModuleBase_OperationDescription.h>
 
 #include <ModelAPI_Session.h>
 #include <ModelAPI_Validator.h>
@@ -155,6 +157,25 @@ void XGUI_PropertyPanel::updateContentWidget(FeaturePtr theFeature)
   repaint();
 }
 
+void XGUI_PropertyPanel::createContentPanel(FeaturePtr theFeature)
+{
+  // Invalid feature case on abort of the operation
+  if (theFeature.get() == NULL)
+    return;
+  if (theFeature->isAction() || !theFeature->data())
+    return;
+
+  if (myWidgets.empty()) {
+    ModuleBase_Operation* anOperation = myOperationMgr->currentOperation();
+    QString aXmlRepr = anOperation->getDescription()->xmlRepresentation();
+
+    ModuleBase_WidgetFactory aFactory(aXmlRepr.toStdString(), myOperationMgr->workshop());
+    aFactory.createPanel(contentWidget(), theFeature);
+    /// Apply button should be update if the feature was modified by the panel
+    myOperationMgr->onValidateOperation();
+  }
+}
+
 void XGUI_PropertyPanel::activateNextWidget(ModuleBase_ModelWidget* theWidget)
 {
   // it is possible that the property panel widgets have not been visualized
index a4df2a0727c36602676b90634d88f35708bc2452..a1ee29db6e288ab15696f24960bc555b48631f13 100644 (file)
@@ -106,11 +106,15 @@ Q_OBJECT
   XGUI_OperationMgr* operationMgr() const { return myOperationMgr; }
 
 public slots:
-
-   /// \brief Update all widgets in property panel with values from the given feature
-   /// \param theFeature a Feature to update values in widgets
+  /// \brief Update all widgets in property panel with values from the given feature
+  /// \param theFeature a Feature to update values in widgets
   void updateContentWidget(FeaturePtr theFeature);
 
+  /// \brief If the XML definition of the feature contains information about specific
+  /// content of the property panel, it creates the panel and allow filling it by the given feature
+  /// \param theFeature a Feature to fill property panel
+  void createContentPanel(FeaturePtr theFeature);
+
   /**
   * Makes the given widget active, highlights it and removes
   * highlighting from the previous active widget
index 5a4b943f79f04fedaf489a0d2056ac276d3fb0ea..d418c1ba3eaf23b11390552aea2d37a53ea40a7d 100755 (executable)
@@ -167,8 +167,10 @@ void XGUI_WorkshopListener::processEvent(const std::shared_ptr<Events_Message>&
 
     if (anOperationMgr->startOperation(anOperation)) {
       ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>(anOperation);
-      if (aFOperation)
+      if (aFOperation) {
         workshop()->propertyPanel()->updateContentWidget(aFOperation->feature());
+        workshop()->propertyPanel()->createContentPanel(aFOperation->feature());
+      }
       if (!anOperation->getDescription()->hasXmlRepresentation()) {
         if (anOperation->commit())
           workshop()->updateCommandStatus();