]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Issue #1383 Preview button: providing the Preview button, which sends signals to...
authornds <nds@opencascade.com>
Tue, 12 Apr 2016 08:18:26 +0000 (11:18 +0300)
committernds <nds@opencascade.com>
Tue, 12 Apr 2016 08:18:52 +0000 (11:18 +0300)
15 files changed:
src/Config/Config_FeatureMessage.cpp
src/Config/Config_FeatureMessage.h
src/Config/Config_FeatureReader.cpp
src/Config/Config_Keywords.h
src/FeaturesPlugin/plugin-Features.xml
src/ModelAPI/ModelAPI_Events.h
src/PartSet/PartSet_SketcherReetntrantMgr.cpp
src/XGUI/XGUI_ActionsMgr.cpp
src/XGUI/XGUI_ActionsMgr.h
src/XGUI/XGUI_OperationMgr.cpp
src/XGUI/XGUI_PropertyPanel.cpp
src/XGUI/XGUI_PropertyPanel.h
src/XGUI/XGUI_Workshop.cpp
src/XGUI/XGUI_Workshop.h
src/XGUI/XGUI_WorkshopListener.cpp

index 954099ea3ae156614d64003873e6925aec765553..a5fd9fd45fbe12e1868f1d44de797a3a6fc544c2 100644 (file)
@@ -125,6 +125,11 @@ bool Config_FeatureMessage::isInternal() const
   return myInternal;
 }
 
+bool Config_FeatureMessage::isAutoPreview() const
+{
+  return myIsAutoPreview;
+}
+
 void Config_FeatureMessage::setUseInput(bool isUseInput)
 {
   myUseInput = isUseInput;
@@ -154,3 +159,8 @@ void Config_FeatureMessage::setActionsWhenNested(const std::string& theActions)
 {
   myActionsWhenNested = theActions;
 }
+
+void Config_FeatureMessage::setAutoPreview(bool isAutoPreview)
+{
+  myIsAutoPreview = isAutoPreview;
+}
index 98201cf6f57d9c57f7349da91266acca706828d9..481bbf97bc0a025b32794742ccf1f24a4b50010b 100644 (file)
@@ -32,6 +32,8 @@ class Config_FeatureMessage : public Events_Message
 \r
   bool myUseInput;  ///<Action is being checked until user commit the operation\r
   bool myInternal;  ///<Internal feature without GUI representation\r
+  bool myIsAutoPreview; ///< Preview computation is performed automatically\r
+\r
   std::string myNestedFeatures; ///<Space separated list of child features\r
   std::string myActionsWhenNested; ///<Space separated list of actions\r
 \r
@@ -82,6 +84,9 @@ class Config_FeatureMessage : public Events_Message
   /// If true - feature will not be added into the workbench\r
   CONFIG_EXPORT bool isInternal() const;\r
 \r
+  /// If true - preview of the feature is done by any modification of the feature attributes\r
+  CONFIG_EXPORT bool isAutoPreview() const;\r
+\r
   ///Set feature's Id\r
   CONFIG_EXPORT void setId(const std::string& id);\r
   ///Set feature's Icon\r
@@ -108,6 +113,8 @@ class Config_FeatureMessage : public Events_Message
   CONFIG_EXPORT void setUseInput(bool isUseInput);\r
   ///Set internal state; If true - feature will not be added into the workbench\r
   CONFIG_EXPORT void setInternal(bool isInternal);\r
+  ///Set auto preview state; If true - preview of the feature is computed automatically\r
+  CONFIG_EXPORT void setAutoPreview(bool isAutoPreview);\r
 };\r
 \r
 #endif // CONFIG_MESSAGE_H\r
index 7bf841b060b7c0ee9f3e41a2ead85aa63c947f5b..6998dcecfa012a0a0fdddacb1948a0526331e948 100644 (file)
@@ -139,4 +139,6 @@ void Config_FeatureReader::fillFeature(xmlNodePtr theFeatureNode,
     aDocKind = restoreAttribute(NODE_WORKBENCH, WORKBENCH_DOC);
   }
   outFeatureMessage->setDocumentKind(aDocKind);
+  bool isAutoPreview = getBooleanAttribute(theFeatureNode, FEATURE_AUTO_PREVIEW, true);
+  outFeatureMessage->setAutoPreview(isAutoPreview);
 }
index a59fc84730addc42ab107d55b87adff302868f9a..ae6dc346d5744c9df83e3ed9668a21ec111c6b89 100644 (file)
@@ -62,6 +62,7 @@ const static char* FEATURE_WHEN_NESTED = "when_nested";
 const static char* FEATURE_WHEN_NESTED_ACCEPT = "accept";
 const static char* FEATURE_WHEN_NESTED_ABORT = "abort";
 const static char* FEATURE_DOC = WORKBENCH_DOC;
+const static char* FEATURE_AUTO_PREVIEW = "auto_preview";
 // NODE_VALIDATOR properties, NODE_SELFILTER properties
 const static char* _PARAMETERS = "parameters";
 
index 9f5cbd74ecf8cb765ff59b8d0c8000d575693267..ee7cdbbfb2d4981f47a5303b4ff066f8464badb2 100644 (file)
@@ -3,7 +3,7 @@
 <plugin>
   <workbench id="Features" document="Part">
     <group id="Extrusion">
-      <feature id="Extrusion" title="Extrusion" tooltip="Create a solid by extrusion of a face" icon=":icons/extrusion.png">
+      <feature id="Extrusion" title="Extrusion" tooltip="Create a solid by extrusion of a face" icon=":icons/extrusion.png" auto_preview="false">
           <source path="extrusion_widget.xml"/>
       </feature>
       <!--<feature id="ExtrusionSketch" title="ExtrusionSketch" tooltip="Create a solids by extrusion of a sketch" icon=":icons/extrusionsketch.png">
index 39518f563a3ee234afb53083eb60ecbc89c7fca9..6a5d674e60391c89fa2b7a9c47d7161a3fff3685 100644 (file)
@@ -50,6 +50,9 @@ static const char * EVENT_FEATURE_STATE_RESPONSE = "FeatureStateResponse";
 static const char * EVENT_UPDATE_VIEWER_BLOCKED = "UpdateViewerBlocked";
 static const char * EVENT_UPDATE_VIEWER_UNBLOCKED = "UpdateViewerUnblocked";
 
+static const char * EVENT_PREVIEW_BLOCKED = "PreviewBlocked";
+static const char * EVENT_PREVIEW_REQUESTED = "PreviewRequested";
+
 /// Event ID that solver has conflicting constraints (comes with ModelAPI_SolverFailedMessage)
 static const char * EVENT_SOLVER_FAILED = "SolverFailed";
 /// Event ID that the problem in solver disappeared
index 84205e1a4f9ec5d4dcc8e6c506bc29e145e427f5..943e488a0da4bab9d2ccba0a7f753d9eba2c8b19 100755 (executable)
@@ -415,7 +415,7 @@ bool PartSet_SketcherReetntrantMgr::startInternalEdit(const std::string& thePrev
             }
             // if there is no the next widget to be automatically activated, the Ok button in property
             // panel should accept the focus(example is parallel constraint on sketch lines)
-            QToolButton* anOkBtn = aPanel->findChild<QToolButton*>(PROP_PANEL_OK);
+            QToolButton* anOkBtn = dynamic_cast<XGUI_PropertyPanel*>(aPanel)->findButton(PROP_PANEL_OK);
             if (anOkBtn)
               anOkBtn->setFocus(Qt::TabFocusReason);
           }
index 66c6bf5a8ec945aeb6062ea0873488c4008633c5..89c0d002fb0ab58e6f43b087602cb381865bd6f5 100644 (file)
@@ -243,6 +243,11 @@ QAction* XGUI_ActionsMgr::operationStateAction(OperationStateActionId theId, QOb
         aResult->setToolTip("Help");
       }
       break;
+      case Preview: {
+        aResult = new QAction("See the preview", theParent);
+        aResult->setToolTip("Compute preview");
+      }
+      break;
       default:
         break;
     }
index 3788197734e5ad3352bb732bd34e9dd2696cb80b..d101a64cf7419552a623437175721f98e0984082 100644 (file)
@@ -45,7 +45,8 @@ class XGUI_EXPORT XGUI_ActionsMgr : public QObject, public Events_Listener
     Accept = 1,
     Help = 2,
     AbortAll = 3,
-    AcceptAll = 4
+    AcceptAll = 4,
+    Preview = 5
   };
 
   //! Add a command in the manager.
index 9f29412ebda7f1d0e7ff34134d0bc996d9c72d05..814d0b4542cbc09e27c7c8bd0fd27520af3cf070 100644 (file)
@@ -619,7 +619,7 @@ bool XGUI_OperationMgr::onProcessEnter(QObject* theObject)
   bool isAborted = false;
   if (!anActiveWgt) {
     QWidget* aFocusWidget = aPanel->focusWidget();
-    QToolButton* aCancelBtn = aPanel->findChild<QToolButton*>(PROP_PANEL_CANCEL);
+    QToolButton* aCancelBtn = dynamic_cast<XGUI_PropertyPanel*>(aPanel)->findButton(PROP_PANEL_CANCEL);
     if (aFocusWidget && aCancelBtn && aFocusWidget == aCancelBtn) {
       abortOperation(aOperation);
       isAccepted = true;
index a3abb42d2dcc30cec0f94a21e40341304db58788..c1b78937e34eeac2f4cf5cfb9a3599cb2d225561 100755 (executable)
@@ -46,9 +46,9 @@ XGUI_PropertyPanel::XGUI_PropertyPanel(QWidget* theParent, XGUI_OperationMgr* th
     myPanelPage(NULL),
     myOperationMgr(theMgr)
 {
-  this->setWindowTitle(tr("Property Panel"));
-  QAction* aViewAct = this->toggleViewAction();
-  this->setObjectName(PROP_PANEL);
+  setWindowTitle(tr("Property Panel"));
+  QAction* aViewAct = toggleViewAction();
+  setObjectName(PROP_PANEL);
   setStyleSheet("::title { position: relative; padding-left: 5px; text-align: left center }");
 
   QWidget* aContent = new QWidget(this);
@@ -56,7 +56,7 @@ XGUI_PropertyPanel::XGUI_PropertyPanel(QWidget* theParent, XGUI_OperationMgr* th
   const int kPanelColumn = 0;
   int aPanelRow = 0;
   aMainLayout->setContentsMargins(3, 3, 3, 3);
-  this->setWidget(aContent);
+  setWidget(aContent);
 
   QFrame* aFrm = new QFrame(aContent);
   aFrm->setFrameStyle(QFrame::Raised);
@@ -81,7 +81,21 @@ XGUI_PropertyPanel::XGUI_PropertyPanel(QWidget* theParent, XGUI_OperationMgr* th
 
   myPanelPage = new ModuleBase_PageWidget(aContent);
   myPanelPage->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding);
-  aMainLayout->addWidget(myPanelPage, aPanelRow, kPanelColumn);
+  aMainLayout->addWidget(myPanelPage, aPanelRow++, kPanelColumn);
+
+  // spit to make the preview button on the bottom of the panel
+  aMainLayout->setRowStretch(aPanelRow++, 1);
+
+  // preview button on the bottom of panel
+  aFrm = new QFrame(aContent);
+  aBtnLay = new QHBoxLayout(aFrm);
+  aBtnLay->addStretch(1);
+  ModuleBase_Tools::zeroMargins(aBtnLay);
+  aMainLayout->addWidget(aFrm, aPanelRow++, kPanelColumn);
+
+  QToolButton* aBtn = new QToolButton(aFrm);
+  aBtn->setObjectName(PROP_PANEL_PREVIEW);
+  aBtnLay->addWidget(aBtn);
 }
 
 XGUI_PropertyPanel::~XGUI_PropertyPanel()
@@ -111,6 +125,8 @@ void XGUI_PropertyPanel::cleanContent()
   myWidgets.clear();
   myPanelPage->clearPage();
   myActiveWidget = NULL;
+
+  findButton(PROP_PANEL_PREVIEW)->setVisible(false); /// by default it is hidden
   setWindowTitle(tr("Property Panel"));
 }
 
@@ -240,11 +256,11 @@ void XGUI_PropertyPanel::activateNextWidget(ModuleBase_ModelWidget* theWidget,
   // it should be performed before activateWidget(NULL) because it emits some signals which
   // can be processed by moudule for example as to activate another widget with setting focus
   QWidget* aNewFocusWidget = 0;
-  QToolButton* anOkBtn = findChild<QToolButton*>(PROP_PANEL_OK);
+  QToolButton* anOkBtn = findButton(PROP_PANEL_OK);
   if (anOkBtn->isEnabled())
     aNewFocusWidget = anOkBtn;
   else {
-    QToolButton* aCancelBtn = findChild<QToolButton*>(PROP_PANEL_CANCEL);
+    QToolButton* aCancelBtn = findButton(PROP_PANEL_CANCEL);
     if (aCancelBtn->isEnabled())
       aNewFocusWidget = aCancelBtn;
   }
@@ -333,11 +349,11 @@ bool XGUI_PropertyPanel::focusNextPrevChild(bool theIsNext)
       if (theIsNext) {
         if (aFocusWidgetIndex == aChildrenCount-1) {
           // after the last widget focus should be set to "Apply"
-          QToolButton* anOkBtn = findChild<QToolButton*>(PROP_PANEL_OK);
+          QToolButton* anOkBtn = findButton(PROP_PANEL_OK);
           if (anOkBtn->isEnabled())
             aNewFocusWidget = anOkBtn;
           else {
-            QToolButton* aCancelBtn = findChild<QToolButton*>(PROP_PANEL_CANCEL);
+            QToolButton* aCancelBtn = findButton(PROP_PANEL_CANCEL);
             if (aCancelBtn->isEnabled())
               aNewFocusWidget = aCancelBtn;
           }
@@ -353,7 +369,7 @@ bool XGUI_PropertyPanel::focusNextPrevChild(bool theIsNext)
         }
         else {
           // before the "Apply" button, the last should accept focus for consistency with "Next"
-          QToolButton* anOkBtn = findChild<QToolButton*>(PROP_PANEL_OK);
+          QToolButton* anOkBtn = findButton(PROP_PANEL_OK);
           if (aFocusWidget == anOkBtn) {
             aNewFocusWidget = aChildren[aChildrenCount - 1];
           }
@@ -424,19 +440,19 @@ bool XGUI_PropertyPanel::setActiveWidget(ModuleBase_ModelWidget* theWidget)
 
 void XGUI_PropertyPanel::setFocusOnOkButton()
 {
-  QToolButton* anOkBtn = findChild<QToolButton*>(PROP_PANEL_OK);
+  QToolButton* anOkBtn = findButton(PROP_PANEL_OK);
   ModuleBase_Tools::setFocus(anOkBtn, "XGUI_PropertyPanel::setFocusOnOkButton()");
 }
 
 void XGUI_PropertyPanel::setCancelEnabled(bool theEnabled)
 {
-  QToolButton* anCancelBtn = findChild<QToolButton*>(PROP_PANEL_CANCEL);
+  QToolButton* anCancelBtn = findButton(PROP_PANEL_CANCEL);
   anCancelBtn->setEnabled(theEnabled);
 }
 
 bool XGUI_PropertyPanel::isCancelEnabled() const
 {
-  QToolButton* anCancelBtn = findChild<QToolButton*>(PROP_PANEL_CANCEL);
+  QToolButton* anCancelBtn = findButton(PROP_PANEL_CANCEL);
   return anCancelBtn->isEnabled();
 }
 
@@ -451,11 +467,12 @@ void XGUI_PropertyPanel::setEditingMode(bool isEditing)
 void XGUI_PropertyPanel::setupActions(XGUI_ActionsMgr* theMgr)
 {
   QStringList aButtonNames;
-  aButtonNames << PROP_PANEL_OK << PROP_PANEL_CANCEL << PROP_PANEL_HELP;
+  aButtonNames << PROP_PANEL_OK << PROP_PANEL_CANCEL << PROP_PANEL_HELP << PROP_PANEL_PREVIEW;
   QList<XGUI_ActionsMgr::OperationStateActionId> aActionIds;
-  aActionIds << XGUI_ActionsMgr::Accept << XGUI_ActionsMgr::Abort << XGUI_ActionsMgr::Help;
+  aActionIds << XGUI_ActionsMgr::Accept << XGUI_ActionsMgr::Abort << XGUI_ActionsMgr::Help
+             << XGUI_ActionsMgr::Preview;
   for (int i = 0; i < aButtonNames.size(); ++i) {
-    QToolButton* aBtn = findChild<QToolButton*>(aButtonNames.at(i));
+    QToolButton* aBtn = findButton(aButtonNames.at(i).toStdString().c_str());
     QAction* anAct = theMgr->operationStateAction(aActionIds.at(i));
     aBtn->setDefaultAction(anAct);
   }
@@ -487,3 +504,8 @@ void XGUI_PropertyPanel::closeEvent(QCloseEvent* theEvent)
   } else
     ModuleBase_IPropertyPanel::closeEvent(theEvent);
 }
+
+QToolButton* XGUI_PropertyPanel::findButton(const char* theInternalName) const
+{
+  return findChild<QToolButton*>(theInternalName);
+}
index a1ee29db6e288ab15696f24960bc555b48631f13..a360a449d093a1b21b96031910d1d0bdbc40ff2b 100644 (file)
@@ -20,6 +20,7 @@
 class XGUI_ActionsMgr;
 class QKeyEvent;
 class QGridLayout;
+class QToolButton;
 class ModuleBase_PageBase;
 class ModuleBase_PageWidget;
 class XGUI_OperationMgr;
@@ -36,6 +37,9 @@ const static char* PROP_PANEL_CANCEL = "property_panel_cancel";
 /// Internal name of Help button
 const static char* PROP_PANEL_HELP = "property_panel_help";
 
+/// Internal name of Preview button
+const static char* PROP_PANEL_PREVIEW = "property_panel_preview";
+
 /**
 * \ingroup GUI
 * Realization of Property panel object.
@@ -105,6 +109,11 @@ Q_OBJECT
   /// Returns operation manager
   XGUI_OperationMgr* operationMgr() const { return myOperationMgr; }
 
+  /// Find under the panel a child button with the parameter name
+  /// \param theInternalName a button object name
+  /// \return button instance or NULL
+  QToolButton* findButton(const char* theInternalName) const;
+
 public slots:
   /// \brief Update all widgets in property panel with values from the given feature
   /// \param theFeature a Feature to update values in widgets
@@ -156,10 +165,9 @@ protected:
    /// \param theEvent a close event
    void closeEvent(QCloseEvent* theEvent);
 
-  /// A header widget
-  QWidget* myHeaderWidget;
+private:
+  QWidget* myHeaderWidget;  ///< A header widget
 
- private:
   ModuleBase_PageWidget* myPanelPage;
   QList<ModuleBase_ModelWidget*> myWidgets;
 
index a4b1385fe27dea82891cb5b5d72a530338247c6f..75de3174c1dcee76aeccae7f357bb40172a20d8f 100755 (executable)
@@ -407,6 +407,14 @@ void XGUI_Workshop::onAcceptActionClicked()
   }
 }
 
+//******************************************************
+void XGUI_Workshop::onPreivewActionClicked()
+{
+  std::shared_ptr<Events_Message> aMsg = std::shared_ptr<Events_Message>(
+                new Events_Message(Events_Loop::eventByName(EVENT_PREVIEW_REQUESTED)));
+  Events_Loop::loop()->send(aMsg);
+}
+
 //******************************************************
 void XGUI_Workshop::deactivateActiveObject(const ObjectPtr& theObject, const bool theUpdateViewer)
 {
@@ -456,9 +464,10 @@ void XGUI_Workshop::setPropertyPanel(ModuleBase_Operation* theOperation)
 
   // check compatibility of feature and widgets
   FeaturePtr aFeature = aFOperation->feature();
+  std::string aFeatureKind = aFeature->getKind();
   foreach (ModuleBase_ModelWidget* aWidget, aWidgets) {
     if (!aWidget->attributeID().empty() && !aFeature->attribute(aWidget->attributeID()).get()) {
-      std::string anErrorMsg = "The feature '" + aFeature->getKind() + "' has no attribute '"
+      std::string anErrorMsg = "The feature '" + aFeatureKind + "' has no attribute '"
           + aWidget->attributeID() + "' used by widget '"
           + aWidget->metaObject()->className() + "'.";
       Events_Error::send(anErrorMsg);
@@ -466,15 +475,30 @@ void XGUI_Workshop::setPropertyPanel(ModuleBase_Operation* theOperation)
       return;
     }
   }
-
   foreach (ModuleBase_ModelWidget* aWidget, aWidgets) {
     bool isStoreValue = !aFOperation->isEditOperation() &&
                         !aWidget->getDefaultValue().empty() &&
                         !aWidget->isComputedDefault();
-    aWidget->setFeature(aFOperation->feature(), isStoreValue);
+    aWidget->setFeature(aFeature, isStoreValue);
     aWidget->enableFocusProcessing();
   }
 
+  // update visible state of Preview button
+#ifdef HAVE_SALOME
+  bool anIsAutoPreview = true;//mySalomeConnector->featureInfo(aFeatureKind)->isAutoPreview();
+#else
+  AppElements_MainMenu* aMenuBar = mainWindow()->menuObject();
+  AppElements_Command* aCommand = aMenuBar->feature(aFeatureKind.c_str());
+  bool anIsAutoPreview = aCommand && aCommand->isAutoPreview();
+#endif
+  if (!anIsAutoPreview) {
+    myPropertyPanel->findButton(PROP_PANEL_PREVIEW)->setVisible(true);
+    // send signal about preview should not be computed automatically, click on preview
+    // button should initiate it
+    std::shared_ptr<Events_Message> aMsg = std::shared_ptr<Events_Message>(
+                  new Events_Message(Events_Loop::eventByName(EVENT_PREVIEW_BLOCKED)));
+    Events_Loop::loop()->send(aMsg);
+  }
   myPropertyPanel->setModelWidgets(aWidgets);
   aFOperation->setPropertyPanel(myPropertyPanel);
 
@@ -1057,9 +1081,12 @@ void XGUI_Workshop::createDockWidgets()
 
   QAction* aCancelAct = myActionsMgr->operationStateAction(XGUI_ActionsMgr::Abort);
   connect(aCancelAct, SIGNAL(triggered()), myOperationMgr, SLOT(onAbortOperation()));
+
+  QAction* aPreviewAct = myActionsMgr->operationStateAction(XGUI_ActionsMgr::Preview);
+  connect(aPreviewAct, SIGNAL(triggered()), this, SLOT(onPreivewActionClicked()));
+
   connect(myPropertyPanel, SIGNAL(keyReleased(QObject*, QKeyEvent*)),
           myOperationMgr,  SLOT(onKeyReleased(QObject*, QKeyEvent*)));
-
   connect(myPropertyPanel, SIGNAL(enterClicked(QObject*)),
           myOperationMgr,  SLOT(onProcessEnter(QObject*)));
 }
index 4cda396f14e7150760cb9d5da6c34ffa1144f4fa..e72ad9b6229299592b15326523ea042bf2a6e1a8 100755 (executable)
@@ -453,6 +453,10 @@ private:
   /// the operation can be committed and do it if it returns true.
   void onAcceptActionClicked();
 
+  /// Called by Preview button clicked in the property panel. Sends signal to model to
+  /// compute preview.
+  void onPreivewActionClicked();
+
  private:
    /// Init menu
   void initMenu();
index d418c1ba3eaf23b11390552aea2d37a53ea40a7d..3d1d5c70fda4845d7210d90b553233b29ea80b10 100755 (executable)
@@ -539,7 +539,8 @@ void XGUI_WorkshopListener::addFeature(const std::shared_ptr<Config_FeatureMessa
   // Create feature...
   AppElements_Command* aCommand = aGroup->addFeature(aFeatureInfo,
                                                       aDocKind,
-                                                      aNestedFeatures);
+                                                      aNestedFeatures,
+                                                      theMessage->isAutoPreview());
   // Enrich created button with accept/abort buttons if necessary
   AppElements_Button* aButton = aCommand->button();
   if (aButton->isColumnButton()) {