Salome HOME
Merge branch 'Dev_GroupsRevision'
authorvsv <vsv@opencascade.com>
Mon, 25 Dec 2017 14:42:02 +0000 (17:42 +0300)
committervsv <vsv@opencascade.com>
Mon, 25 Dec 2017 14:42:02 +0000 (17:42 +0300)
# Conflicts:
# src/ModuleBase/CMakeLists.txt
# src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp
# src/ModuleBase/ModuleBase_WidgetMultiSelector.h
# src/XGUI/XGUI_pictures.qrc

40 files changed:
src/CollectionPlugin/group_widget.xml
src/CollectionPlugin/plugin-Collection.xml
src/Config/Config_FeatureMessage.cpp
src/Config/Config_FeatureMessage.h
src/Config/Config_FeatureReader.cpp
src/Config/Config_Keywords.h
src/GeomAPI/GeomAPI_Shape.cpp
src/GeomAPI/GeomAPI_Shape.h
src/ModuleBase/CMakeLists.txt
src/ModuleBase/ModuleBase_ChoiceCtrl.cpp [new file with mode: 0644]
src/ModuleBase/ModuleBase_ChoiceCtrl.h [new file with mode: 0644]
src/ModuleBase/ModuleBase_ModelWidget.h
src/ModuleBase/ModuleBase_WidgetChoice.cpp
src/ModuleBase/ModuleBase_WidgetChoice.h
src/ModuleBase/ModuleBase_WidgetFactory.cpp
src/ModuleBase/ModuleBase_WidgetLineEdit.h
src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp
src/ModuleBase/ModuleBase_WidgetMultiSelector.h
src/ModuleBase/ModuleBase_WidgetNameEdit.cpp [new file with mode: 0644]
src/ModuleBase/ModuleBase_WidgetNameEdit.h [new file with mode: 0644]
src/PartSet/CMakeLists.txt
src/PartSet/PartSet_IconFactory.cpp
src/PartSet/PartSet_icons.qrc
src/PartSet/icons/group_edge.png [new file with mode: 0644]
src/PartSet/icons/group_face.png [new file with mode: 0644]
src/PartSet/icons/group_solid.png [new file with mode: 0644]
src/PartSet/icons/group_vertex.png [new file with mode: 0644]
src/XGUI/XGUI_ActionsMgr.cpp
src/XGUI/XGUI_ActionsMgr.h
src/XGUI/XGUI_ErrorMgr.cpp
src/XGUI/XGUI_PropertyPanel.cpp
src/XGUI/XGUI_PropertyPanel.h
src/XGUI/XGUI_Workshop.cpp
src/XGUI/XGUI_Workshop.h
src/XGUI/XGUI_pictures.qrc
src/XGUI/pictures/button_ok-plus.png [new file with mode: 0644]
src/XGUI/pictures/edge32.png [new file with mode: 0644]
src/XGUI/pictures/face32.png [new file with mode: 0644]
src/XGUI/pictures/solid32.png [new file with mode: 0644]
src/XGUI/pictures/vertex32.png [new file with mode: 0644]

index 31c1c367967596c3b2c026ffc469aa3924291416..fab719c415252a9afd7bc0722b5e1bb7a08c1b82 100644 (file)
@@ -20,6 +20,10 @@ email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com
 -->
 
 <source>
+  <namevalue id="name"
+    label="Name"
+    placeholder="Please input the group name">
+  </namevalue>
   <multi_selector id="group_list"
     tooltip="Select a set of objects"
     type_choice="Vertices Edges Faces Solids"
index 215a6b60c80fed94227f2cabb2689fe866630b07..156c1bbd48ef703037e91342bebefc143e5ea0f6 100644 (file)
@@ -25,13 +25,14 @@ email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com
       <feature id="Group"
         title="Group"
         tooltip="Create named collection of geometry entities"
-        icon="icons/Collection/shape_group.png">
+        icon="icons/Collection/shape_group.png"
+        apply_continue="true">
         <source path="group_widget.xml"/>
       </feature>
 
       <feature id="Field"
         title="Field"
-        tooltip="Create create fields for selected shapes"
+        tooltip="Create fields for selected shapes"
         icon="icons/Collection/field.png">
         <field-panel id="selected">
           <validator id="GeomValidators_BodyShapes"/>
index ae86d8b94d2fa9dc2d12ba6f0a090de51f6b2628..c944bc6d4a0045231d48d2f7af8f758310ef9243 100644 (file)
@@ -36,6 +36,8 @@ Config_FeatureMessage::Config_FeatureMessage(const Events_ID theId, const void*
   myInternal = false;
   myUseInput = false;
   myNestedFeatures = "";
+  myModal = false;
+  myIsApplyContinue = false;
 }
 
 Config_FeatureMessage::~Config_FeatureMessage()
@@ -153,6 +155,12 @@ bool Config_FeatureMessage::isModal() const
   return myModal;
 }
 
+bool Config_FeatureMessage::isApplyContinue() const
+{
+  return myIsApplyContinue;
+}
+
+
 void Config_FeatureMessage::setUseInput(bool isUseInput)
 {
   myUseInput = isUseInput;
@@ -192,3 +200,8 @@ void Config_FeatureMessage::setAutoPreview(bool isAutoPreview)
 {
   myIsAutoPreview = isAutoPreview;
 }
+
+void Config_FeatureMessage::setApplyContinue(bool isModal)
+{
+  myIsApplyContinue = isModal;
+}
\ No newline at end of file
index a4c6105511b5301f98fc00626e1c5c3fb1a3cfe7..3bbe0a5faee628e12cd11e0b6f97dbb9df9d3ee6 100644 (file)
@@ -52,6 +52,7 @@ class Config_FeatureMessage : public Events_Message
   bool myInternal;  ///<Internal feature without GUI representation
   bool myModal;     ///<True if the feature has to be represented by modal dialog box
   bool myIsAutoPreview; ///< Preview computation is performed automatically
+  bool myIsApplyContinue;  ///<True if the feature can have Apply/Continue button in its property panel
 
   std::string myNestedFeatures; ///<Space separated list of child features
   std::string myActionsWhenNested; ///<Space separated list of actions
@@ -104,6 +105,10 @@ class Config_FeatureMessage : public Events_Message
   CONFIG_EXPORT bool isInternal() const;
   /// If true - the feature will be represented by modal dialog box GUI
   CONFIG_EXPORT bool isModal() const;
+  /// If true - the feature can have Apply/Continue button in its property panel
+  CONFIG_EXPORT bool isApplyContinue() const;
+
+
 
   /// If true - preview of the feature is done by any modification of the feature attributes
   CONFIG_EXPORT bool isAutoPreview() const;
@@ -138,6 +143,8 @@ class Config_FeatureMessage : public Events_Message
   CONFIG_EXPORT void setAutoPreview(bool isAutoPreview);
   ///Set modality state; If true - the feature will be represented by modal dialog box GUI
   CONFIG_EXPORT void setModal(bool isModal);
+  ///Set Apply/Continue state; If true - the feature can have Apply/Continue button in its property panel
+  CONFIG_EXPORT void setApplyContinue(bool isModal);
 };
 
 #endif // CONFIG_MESSAGE_H
index 6115d715f7f76d90593e8bc51bebbc8492b78e3d..c0af30ac45e5c9ed4960cfa46e242c7aebaede56 100644 (file)
@@ -161,6 +161,8 @@ void Config_FeatureReader::fillFeature(xmlNodePtr theFeatureNode,
   outFeatureMessage->setModal(getBooleanAttribute(theFeatureNode, FEATURE_MODAL, false));
   bool isAutoPreview = getBooleanAttribute(theFeatureNode, FEATURE_AUTO_PREVIEW, true);
   outFeatureMessage->setAutoPreview(isAutoPreview);
+  outFeatureMessage->setApplyContinue(
+    getBooleanAttribute(theFeatureNode, FEATURE_APPLY_CONTINUE, false));
 
   bool isInternal = getBooleanAttribute(theFeatureNode, ATTR_INTERNAL, false);
   outFeatureMessage->setInternal(isInternal);
index da19a07e643d1a85b87774a1ef0ed5316bbbb175..2e8261fef44da4f5ab66f704d7f3703c8911f3db 100644 (file)
@@ -41,6 +41,7 @@ const static char* WDG_DOUBLEVALUELABEL = "labelvalue";
 const static char* WDG_INTEGERVALUE = "integervalue";
 const static char* WDG_BOOLVALUE = "boolvalue";
 const static char* WDG_STRINGVALUE = "stringvalue";
+const static char* WDG_NAMEVALUE = "namevalue";
 const static char* WDG_MULTISELECTOR = "multi_selector";
 const static char* WDG_SHAPE_SELECTOR = "shape_selector";
 const static char* WDG_FEATURE_SELECTOR = "feature_selector";
@@ -76,6 +77,7 @@ 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_MODAL = "modal";
+const static char* FEATURE_APPLY_CONTINUE = "apply_continue";
 const static char* FEATURE_AUTO_PREVIEW = "auto_preview";
 // NODE_VALIDATOR properties
 const static char* _PARAMETERS = "parameters";
index b634f3dcc28f17cef09b31e721bfc28ccece0b07..9b2b5d959e822ce1a6cc600802fd050f312edd90 100644 (file)
@@ -135,6 +135,23 @@ bool GeomAPI_Shape::isCompoundOfSolids() const
   return isAtLeastOne;
 }
 
+GeomAPI_Shape::ShapeType GeomAPI_Shape::typeOfCompoundShapes() const
+{
+  const TopoDS_Shape& aShape = const_cast<GeomAPI_Shape*>(this)->impl<TopoDS_Shape>();
+  if (aShape.IsNull() || aShape.ShapeType() != TopAbs_COMPOUND)
+    return SHAPE;
+  int aType = -1;
+  for(TopoDS_Iterator aSubs(aShape); aSubs.More(); aSubs.Next()) {
+    if (!aSubs.Value().IsNull()) {
+      if (aType == -1)
+        aType = aSubs.Value().ShapeType();
+      else if (aSubs.Value().ShapeType() != aType)
+        return SHAPE;
+    }
+  }
+  return (GeomAPI_Shape::ShapeType) aType;
+}
+
 // adds the nopt-compound elements recursively to the list
 static void addSimpleToList(const TopoDS_Shape& theShape, NCollection_List<TopoDS_Shape>& theList)
 {
index 7138a776dce347f6dacc99dafde533c9fd8bfe75..51cd414c8b637044ad26813678e8d076026fe7f2 100644 (file)
@@ -154,9 +154,13 @@ public:
   GEOMAPI_EXPORT
   bool isIntersect(const std::shared_ptr<GeomAPI_Shape> theShape) const;
 
-  // Translates the shape along the direction for the given offset
+  /// Translates the shape along the direction for the given offset
   GEOMAPI_EXPORT
   void translate(const std::shared_ptr<GeomAPI_Dir> theDir, const double theOffset);
+
+  /// Returns type of shapes in the compound.
+  // If shapes are of different type then it will return SHAPE type
+  GEOMAPI_EXPORT ShapeType typeOfCompoundShapes() const;
 };
 
 //! Pointer on list of shapes
index a9ad6af4db94df5696357cd77897506d818fc9e5..3e8fc7d4bce53a2b352f7f47d45bad5943ca46d8 100644 (file)
@@ -99,6 +99,8 @@ SET(PROJECT_HEADERS
   ModuleBase_ModelDialogWidget.h
   ModuleBase_ActionParameter.h
   ModuleBase_ActionIntParameter.h
+  ModuleBase_ChoiceCtrl.h
+  ModuleBase_WidgetNameEdit.h
 )
 
 SET(PROJECT_MOC_HEADERS
@@ -144,6 +146,8 @@ SET(PROJECT_MOC_HEADERS
   ModuleBase_WidgetSwitch.h
   ModuleBase_WidgetToolbox.h
   ModuleBase_WidgetValidated.h
+  ModuleBase_ChoiceCtrl.h
+  ModuleBase_WidgetNameEdit.h
 )
 
 SET(PROJECT_SOURCES
@@ -208,6 +212,8 @@ SET(PROJECT_SOURCES
   ModuleBase_IconFactory.cpp
   ModuleBase_SelectionValidator.cpp
   ModuleBase_Dialog.cpp
+  ModuleBase_ChoiceCtrl.cpp
+  ModuleBase_WidgetNameEdit.cpp
 )
 
 SET(PROJECT_LIBRARIES
diff --git a/src/ModuleBase/ModuleBase_ChoiceCtrl.cpp b/src/ModuleBase/ModuleBase_ChoiceCtrl.cpp
new file mode 100644 (file)
index 0000000..38afff3
--- /dev/null
@@ -0,0 +1,186 @@
+// Copyright (C) 2014-2017  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or
+// email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+//
+
+#include "ModuleBase_ChoiceCtrl.h"
+#include "ModuleBase_Tools.h"
+#include "ModuleBase_IconFactory.h"
+
+#include <QLayout>
+#include <QLabel>
+#include <QComboBox>
+#include <QGroupBox>
+#include <QButtonGroup>
+#include <QRadioButton>
+#include <QToolButton>
+
+ModuleBase_ChoiceCtrl::ModuleBase_ChoiceCtrl(QWidget* theParent,
+                                             const QStringList& theChoiceList,
+                                             const QStringList& theIconsList,
+                                             ControlType theType,
+                                             Qt::Orientation theButtonsDir)
+ : QWidget(theParent), myType(theType)
+{
+  QHBoxLayout* aLayout = new QHBoxLayout(this);
+  ModuleBase_Tools::adjustMargins(aLayout);
+
+  switch (myType) {
+  case RadioButtons:
+    {
+      myButtons = new QButtonGroup(this);
+      myGroupBox = new QGroupBox("", this);
+      aLayout->addWidget(myGroupBox);
+
+      QLayout* aBtnLayout = 0;
+      switch (theButtonsDir) {
+      case Qt::Horizontal:
+        aBtnLayout = new QHBoxLayout(myGroupBox);
+        break;
+      case Qt::Vertical:
+        aBtnLayout = new QVBoxLayout(myGroupBox);
+        break;
+      }
+      ModuleBase_Tools::adjustMargins(aBtnLayout);
+
+      if (theIconsList.length() == theChoiceList.length()) {
+        int aId = 0;
+        foreach(QString aBtnTxt, theChoiceList) {
+          QToolButton* aBtn = new QToolButton(myGroupBox);
+          aBtn->setFocusPolicy(Qt::StrongFocus);
+          aBtn->setCheckable(true);
+          aBtn->setToolTip(aBtnTxt);
+
+          QPixmap aIcon = ModuleBase_IconFactory::loadPixmap(theIconsList.at(aId));
+          aBtn->setIcon(aIcon);
+          aBtn->setIconSize(aIcon.size());
+
+          aBtnLayout->addWidget(aBtn);
+          myButtons->addButton(aBtn, aId++);
+        }
+      } else {
+        int aId = 0;
+        foreach(QString aBtnTxt, theChoiceList) {
+          QRadioButton* aBtn = new QRadioButton(aBtnTxt, myGroupBox);
+          aBtnLayout->addWidget(aBtn);
+          myButtons->addButton(aBtn, aId++);
+        }
+      }
+      connect(myButtons, SIGNAL(buttonClicked(int)), this, SIGNAL(valueChanged(int)));
+    }
+    break;
+  case ComboBox:
+    myLabel = new QLabel("", this);
+    aLayout->addWidget(myLabel);
+
+    //std::string aToolstr = theData->widgetTooltip();
+    //if (!aToolstr.empty()) {
+    //  myLabel->setToolTip(QString::fromStdString(aToolstr));
+    //}
+
+    myCombo = new QComboBox(this);
+    aLayout->addWidget(myCombo, 1);
+
+    myCombo->addItems(theChoiceList);
+    connect(myCombo, SIGNAL(currentIndexChanged(int)), this, SIGNAL(valueChanged(int)));
+    break;
+  }
+}
+
+void ModuleBase_ChoiceCtrl::setLabel(const QString& theText)
+{
+  switch (myType) {
+  case RadioButtons:
+    myGroupBox->setTitle(theText);
+    break;
+  case ComboBox:
+    myLabel->setText(theText);
+    break;
+  }
+}
+
+void ModuleBase_ChoiceCtrl::setLabelIcon(const QString& theIcon)
+{
+  if (myType == ComboBox)
+    myLabel->setPixmap(ModuleBase_IconFactory::loadPixmap(theIcon));
+}
+
+void ModuleBase_ChoiceCtrl::setValue(int theVal)
+{
+  switch (myType) {
+  case RadioButtons:
+    myButtons->button(theVal)->setChecked(true);
+    break;
+  case ComboBox:
+    myCombo->setCurrentIndex(theVal);
+    break;
+  }
+}
+
+void ModuleBase_ChoiceCtrl::setTooltip(QString theTip)
+{
+  if (myType == ComboBox)
+    myLabel->setToolTip(theTip);
+}
+
+int ModuleBase_ChoiceCtrl::value() const
+{
+  switch (myType) {
+  case RadioButtons:
+    return myButtons->checkedId();
+  case ComboBox:
+    return myCombo->currentIndex();
+  }
+  return -1;
+}
+
+bool ModuleBase_ChoiceCtrl::focusTo()
+{
+  if (myType == ComboBox)
+    ModuleBase_Tools::setFocus(myCombo, "ModuleBase_WidgetChoice::focusTo()");
+  else
+    return false;
+  return true;
+}
+
+QList<QWidget*> ModuleBase_ChoiceCtrl::getControls() const
+{
+  QList<QWidget*> aControls;
+  if (myType == ComboBox)
+    aControls.append(myCombo);
+  return aControls;
+}
+
+void ModuleBase_ChoiceCtrl::setChoiceList(const QStringList& theChoiceList)
+{
+  if (myType == ComboBox) {
+    myCombo->clear();
+    myCombo->addItems(theChoiceList);
+  }
+}
+
+QString ModuleBase_ChoiceCtrl::textValue() const
+{
+  switch (myType) {
+  case RadioButtons:
+    return myButtons->checkedButton()->toolTip();
+  case ComboBox:
+    return myCombo->currentText();
+  }
+  return "";
+}
diff --git a/src/ModuleBase/ModuleBase_ChoiceCtrl.h b/src/ModuleBase/ModuleBase_ChoiceCtrl.h
new file mode 100644 (file)
index 0000000..09530b9
--- /dev/null
@@ -0,0 +1,118 @@
+// Copyright (C) 2014-2017  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or
+// email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+//
+
+#ifndef ModuleBase_ChoiceCtrl_H
+#define ModuleBase_ChoiceCtrl_H
+
+#include "ModuleBase.h"
+
+#include <QWidget>
+#include <QStringList>
+#include <QList>
+
+class QLabel;
+class QComboBox;
+class QGroupBox;
+class QButtonGroup;
+
+/**
+* \ingroup GUI
+* A Choice control. It provides a choice in several strings.
+* It can be represented by several radiobuttons or by combo box.
+* Radio buttons can be represented as by radiou buttons with text
+* or by icons in toggle buttons.
+*/
+class MODULEBASE_EXPORT ModuleBase_ChoiceCtrl: public QWidget
+{
+Q_OBJECT
+public:
+  enum ControlType {
+    RadioButtons,
+    ComboBox
+  };
+
+  /**
+  * Constructor
+  * \param theParent a parent widget
+  * \param theChoiceList a list of choice strings
+  * \param theIconsList a list of icon names for radiou buttons
+  * \param theType a type of choice representation
+  * \param theButtonsDir direction of radio buttons placement
+  */
+  ModuleBase_ChoiceCtrl(QWidget* theParent,
+                        const QStringList& theChoiceList,
+                        const QStringList& theIconsList,
+                        ControlType theType = RadioButtons,
+                        Qt::Orientation theButtonsDir = Qt::Horizontal);
+
+  /// Set label for the controls.
+  /// It is a label for combo box and title for group of radio buttons.
+  /// \param theText a text of the label
+  void setLabel(const QString& theText);
+
+  /// Set Icon for the label. Used only for combo box.
+  /// \param theIcon a name of icon
+  void setLabelIcon(const QString& theIcon);
+
+  /// Set value: Id of button or item of combo box.
+  /// \param theVal a value (from 0 to number of items)
+  void setValue(int theVal);
+
+  /// Set tool tip for label. Used only for combo box.
+  void setTooltip(QString theTip);
+
+  /// Returns currently selected value
+  int value() const;
+
+  /// Returns text of currently selected value
+  QString textValue() const;
+
+  /// Transfer focus on itself
+  bool focusTo();
+
+  /// Returns controls for activation
+  QList<QWidget*> getControls() const;
+
+  /// Set list of choice
+  /// \param theChoiceList a string list of items
+  void setChoiceList(const QStringList& theChoiceList);
+
+signals:
+  /// A signal raised on change of current value
+  void valueChanged(int theVal);
+
+private:
+  /// Control type
+  ControlType myType;
+
+  /// A label for cmbo box
+  QLabel* myLabel;
+
+  /// A combo box represerntation of control
+  QComboBox* myCombo;
+
+  /// A group box for radio buttons
+  QGroupBox* myGroupBox;
+
+  /// A group of buttons
+  QButtonGroup* myButtons;
+};
+
+#endif
\ No newline at end of file
index 61c278353e192758d8cfa3dbb531a419a15f0d35..2e215404f25d7d713a78f515e5d1b748c1ac0c19 100644 (file)
@@ -295,6 +295,11 @@ Q_OBJECT
   /// \return a model widget or NULL
   static ModuleBase_ModelWidget* findModelWidget(ModuleBase_IPropertyPanel* theProp,
                                                  QWidget* theWidget);
+
+  /// Returns True if the widget uses feature attribute.
+  /// If not then it means that the widget do not need attribute at all.
+  virtual bool usesAttribute() const { return true; }
+
 signals:
   /// The signal about widget values are to be changed
   void beforeValuesChanged();
index 7ef0cfb540f37b5c824e455c2b53eafe3da49fef..c259ed3247a00f3f87783b59bb5e973b5a62f654 100644 (file)
@@ -21,6 +21,7 @@
 #include "ModuleBase_WidgetChoice.h"
 #include "ModuleBase_Tools.h"
 #include "ModuleBase_IconFactory.h"
+#include "ModuleBase_ChoiceCtrl.h"
 
 #include <ModelAPI_AttributeInteger.h>
 #include <ModelAPI_AttributeStringArray.h>
 
 ModuleBase_WidgetChoice::ModuleBase_WidgetChoice(QWidget* theParent,
                                                  const Config_WidgetAPI* theData)
-: ModuleBase_ModelWidget(theParent, theData), myCombo(0), myButtons(0)
+: ModuleBase_ModelWidget(theParent, theData)//, myCombo(0), myButtons(0)
 {
-  QHBoxLayout* aLayout = new QHBoxLayout(this);
-  ModuleBase_Tools::adjustMargins(aLayout);
-
   QString aLabelText = translate(theData->widgetLabel());
   QString aLabelIcon = QString::fromStdString(theData->widgetIcon());
   std::string aTypes = theData->getProperty("string_list");
@@ -62,72 +60,28 @@ ModuleBase_WidgetChoice::ModuleBase_WidgetChoice(QWidget* theParent,
 
   bool aHasDefaultValue;
   int aDefaultVal = QString::fromStdString(getDefaultValue()).toInt(&aHasDefaultValue);
+
   // Widget type can be combobox or radiobuttons
   std::string aWgtType = theData->getProperty("widget_type");
-  if ((aWgtType.length() > 0) && (aWgtType == "radiobuttons")) {
-    myButtons = new QButtonGroup(this);
-    QGroupBox* aGroupBox = new QGroupBox(aLabelText, this);
-    aLayout->addWidget(aGroupBox);
-
-
-    QLayout* aBtnLayout = 0;
-    std::string aWgtDir = theData->getProperty("buttons_dir");
-    if (aWgtDir == "horizontal")
-      aBtnLayout = new QHBoxLayout(aGroupBox);
-    else
-      aBtnLayout = new QVBoxLayout(aGroupBox);
-    ModuleBase_Tools::adjustMargins(aBtnLayout);
-
-    std::string aIcons = theData->getProperty("icons_list");
-    QStringList aIconList = QString(aIcons.c_str()).split(' ');
-    if (aIconList.length() == aList.length()) {
-      int aId = 0;
-      foreach(QString aBtnTxt, aList) {
-        QToolButton* aBtn = new QToolButton(aGroupBox);
-        aBtn->setFocusPolicy(Qt::StrongFocus);
-        aBtn->setCheckable(true);
-        aBtn->setToolTip(aBtnTxt);
-
-        QPixmap aIcon = ModuleBase_IconFactory::loadPixmap(aIconList.at(aId));
-        aBtn->setIcon(aIcon);
-        aBtn->setIconSize(aIcon.size());
-
-        aBtnLayout->addWidget(aBtn);
-        myButtons->addButton(aBtn, aId++);
-      }
+  std::string aIcons = theData->getProperty("icons_list");
+  QStringList aIconList = QString(aIcons.c_str()).split(' ');
 
-    } else {
-      int aId = 0;
-      foreach(QString aBtnTxt, aList) {
-        QRadioButton* aBtn = new QRadioButton(aBtnTxt, aGroupBox);
-        aBtnLayout->addWidget(aBtn);
-        myButtons->addButton(aBtn, aId++);
-      }
-    }
-    int aCheckedId = aHasDefaultValue ? aDefaultVal : 0;
-    myButtons->button(aDefaultVal)->setChecked(true);
-    connect(myButtons, SIGNAL(buttonClicked(int)), this, SLOT(onCurrentIndexChanged(int)));
-  } else {
-    myLabel = new QLabel(aLabelText, this);
-    if (!aLabelIcon.isEmpty())
-      myLabel->setPixmap(ModuleBase_IconFactory::loadPixmap(aLabelIcon));
-    aLayout->addWidget(myLabel);
-
-    std::string aToolstr = theData->widgetTooltip();
-    if (!aToolstr.empty()) {
-      myLabel->setToolTip(QString::fromStdString(aToolstr));
-    }
+  std::string aWgtDir = theData->getProperty("buttons_dir");
 
-    myCombo = new QComboBox(this);
-    aLayout->addWidget(myCombo, 1);
+  QHBoxLayout* aLayout = new QHBoxLayout(this);
+  myChoiceCtrl =  new ModuleBase_ChoiceCtrl(this, aList, aIconList,
+    (aWgtType == "radiobuttons")? ModuleBase_ChoiceCtrl::RadioButtons : ModuleBase_ChoiceCtrl::ComboBox,
+    (aWgtDir == "horizontal")? Qt::Horizontal : Qt::Vertical);
+  myChoiceCtrl->setLabel(aLabelText);
 
-    myCombo->addItems(aList);
+  if (!aLabelIcon.isEmpty())
+    myChoiceCtrl->setLabelIcon(aLabelIcon);
 
-    if (aHasDefaultValue && aDefaultVal < aList.size())
-      myCombo->setCurrentIndex(aDefaultVal);
+  connect(myChoiceCtrl, SIGNAL(valueChanged(int)), this, SLOT(onCurrentIndexChanged(int)));
 
-    connect(myCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(onCurrentIndexChanged(int)));
-  }
+  int aCheckedId = aHasDefaultValue ? aDefaultVal : 0;
+  myChoiceCtrl->setValue(aCheckedId);
+  aLayout->addWidget(myChoiceCtrl);
 }
 
 ModuleBase_WidgetChoice::~ModuleBase_WidgetChoice()
@@ -139,10 +93,7 @@ bool ModuleBase_WidgetChoice::storeValueCustom()
   DataPtr aData = myFeature->data();
   std::shared_ptr<ModelAPI_AttributeInteger> aIntAttr = aData->integer(attributeID());
 
-  if (myCombo)
-    aIntAttr->setValue(myCombo->currentIndex());
-  else
-    aIntAttr->setValue(myButtons->checkedId());
+  aIntAttr->setValue(myChoiceCtrl->value());
   updateObject(myFeature);
   return true;
 }
@@ -153,54 +104,38 @@ bool ModuleBase_WidgetChoice::restoreValueCustom()
   std::shared_ptr<ModelAPI_AttributeInteger> aIntAttr = aData->integer(attributeID());
 
   if (aIntAttr->value() != -1) {
-    if (myCombo) {
-      bool isBlocked = myCombo->blockSignals(true);
-      if (myCombo->count() == 0 && !myStringListAttribute.empty()) {
-        AttributeStringArrayPtr aStrAttr = aData->stringArray(myStringListAttribute);
-        if (aStrAttr) {
-          for (int i = 0; i < aStrAttr->size(); i++) {
-            myCombo->insertItem(i, aStrAttr->value(i).c_str());
-          }
+    bool isBlocked = myChoiceCtrl->blockSignals(true);
+    if (!myStringListAttribute.empty()) {
+      AttributeStringArrayPtr aStrAttr = aData->stringArray(myStringListAttribute);
+      QStringList aChoiceList;
+      if (aStrAttr) {
+        for (int i = 0; i < aStrAttr->size(); i++) {
+          aChoiceList << aStrAttr->value(i).c_str();
         }
+        myChoiceCtrl->setChoiceList(aChoiceList);
       }
-      myCombo->setCurrentIndex(aIntAttr->value());
-      myCombo->blockSignals(isBlocked);
-    } else {
-      bool isBlocked = myButtons->blockSignals(true);
-      if (aIntAttr->isInitialized())
-        myButtons->button(aIntAttr->value())->setChecked(true);
-      else {
-        bool aHasDefaultValue;
-        int aDefaultVal = QString::fromStdString(getDefaultValue()).toInt(&aHasDefaultValue);
-        myButtons->button(aHasDefaultValue ? aDefaultVal : 0)->setChecked(true);
-      }
-      myButtons->blockSignals(isBlocked);
-      emit itemSelected(this, aIntAttr->value());
     }
+    if (aIntAttr->isInitialized())
+      myChoiceCtrl->setValue(aIntAttr->value());
+    else {
+      bool aHasDefaultValue;
+      int aDefaultVal = QString::fromStdString(getDefaultValue()).toInt(&aHasDefaultValue);
+      myChoiceCtrl->setValue(aHasDefaultValue ? aDefaultVal : 0);
+    }
+    myChoiceCtrl->blockSignals(isBlocked);
+    emit itemSelected(this, aIntAttr->value());
   }
   return true;
 }
 
 bool ModuleBase_WidgetChoice::focusTo()
 {
-  if (myCombo)
-    ModuleBase_Tools::setFocus(myCombo, "ModuleBase_WidgetChoice::focusTo()");
-  else
-    return false;
-  return true;
+  return myChoiceCtrl->focusTo();
 }
 
 QList<QWidget*> ModuleBase_WidgetChoice::getControls() const
 {
-  QList<QWidget*> aControls;
-  if (myCombo)
-    aControls.append(myCombo);
-  //else {
-  //  //foreach(QAbstractButton* aBtn, myButtons->buttons())
-  //  //if (myButtons->checkedId() != -1)
-  //  //  aControls.append(myButtons->button(myButtons->checkedId()));
-  //}
-  return aControls;
+  return myChoiceCtrl->getControls();
 }
 
 QString ModuleBase_WidgetChoice::getPropertyPanelTitle(int theIndex)
index a6ac35cfcf3eb5aa6205a21de6791d44ff202342..de5b0e5657878a9aa15fbc33a58f8d11cb211253 100644 (file)
@@ -25,9 +25,7 @@
 #include "ModuleBase_ModelWidget.h"
 
 class QWidget;
-class QLabel;
-class QComboBox;
-class QButtonGroup;
+class ModuleBase_ChoiceCtrl;
 
 /**
 * \ingroup GUI
@@ -92,11 +90,12 @@ private slots:
 
 private:
   /// The label
-  QLabel* myLabel;
+  //QLabel* myLabel;
 
   /// The control
-  QComboBox* myCombo;
-  QButtonGroup* myButtons;
+  //QComboBox* myCombo;
+  //QButtonGroup* myButtons;
+  ModuleBase_ChoiceCtrl* myChoiceCtrl;
 
   // XML definition of titles
   QStringList myButtonTitles;
index ecba43238c54b0249e6e9c63b8889e43e8a0fc49..cc62794037c6db483da4dee52bb349a8ce604f64 100644 (file)
@@ -37,6 +37,7 @@
 #include <ModuleBase_IModule.h>
 #include <ModuleBase_Tools.h>
 #include <ModuleBase_WidgetLineEdit.h>
+#include <ModuleBase_WidgetNameEdit.h>
 #include <ModuleBase_WidgetMultiSelector.h>
 #include <ModuleBase_WidgetConcealedObjects.h>
 #include <ModuleBase_WidgetLabel.h>
@@ -317,6 +318,9 @@ ModuleBase_ModelWidget* ModuleBase_WidgetFactory::createWidgetByType(const std::
   } else if (theType == WDG_STRINGVALUE) {
     std::string aPlaceHolder = myWidgetApi->getProperty( WDG_PLACE_HOLDER );
     result = new ModuleBase_WidgetLineEdit( theParent, myWidgetApi, aPlaceHolder );
+  } else if (theType == WDG_NAMEVALUE) {
+    std::string aPlaceHolder = myWidgetApi->getProperty( WDG_PLACE_HOLDER );
+    result = new ModuleBase_WidgetNameEdit( theParent, myWidgetApi, aPlaceHolder );
   } else if (theType == WDG_EXPR_EDITOR) {
     std::string aPlaceHolder = myWidgetApi->getProperty( WDG_PLACE_HOLDER );
     result = new ModuleBase_WidgetExprEditor( theParent, myWidgetApi, aPlaceHolder );
index aee98f9f418735dec8293e96aacafc87091852fd..1ce71ef22e61700e4c7a2c005e43821a86fcb92f 100644 (file)
@@ -63,7 +63,6 @@ protected:
   /// Redefinition of virtual method
   virtual bool restoreValueCustom();
 
-private:
    /// A line edit control
   QLineEdit* myLineEdit;
 };
index 407a59339fe4b113e0c82ffd3e327636adbca5b2..48df5b61bb2a5110692ae7320075bb9bae2fcb3a 100755 (executable)
 #include <ModuleBase_IModule.h>
 #include <ModuleBase_ISelection.h>
 #include <ModuleBase_ISelectionActivate.h>
+#include <ModuleBase_IPropertyPanel.h>
 #include <ModuleBase_IViewer.h>
 #include <ModuleBase_IWorkshop.h>
 #include <ModuleBase_ListView.h>
 #include <ModuleBase_Tools.h>
 #include <ModuleBase_ViewerPrs.h>
 #include <ModuleBase_WidgetShapeSelector.h>
+#include <ModuleBase_ChoiceCtrl.h>
 
 #include <ModelAPI_Data.h>
 #include <ModelAPI_Object.h>
@@ -77,34 +79,50 @@ void printHistoryInfo(const QString& theMethodName, int theCurrentHistoryIndex,
 }
 #endif
 
+
+QStringList getIconsList(const QStringList& theNames)
+{
+  QStringList aIcons;
+  foreach (QString aName, theNames) {
+    QString aUName = aName.toUpper();
+    if ((aUName == "VERTICES") || (aUName == "VERTEX"))
+      aIcons << ":pictures/vertex32.png";
+    else if ((aUName == "EDGES") || (aUName == "EDGE"))
+      aIcons << ":pictures/edge32.png";
+    else if ((aUName == "FACES") || (aUName == "FACE"))
+      aIcons << ":pictures/face32.png";
+    else if ((aUName == "SOLIDS") || (aUName == "SOLID"))
+      aIcons << ":pictures/solid32.png";
+  }
+  return aIcons;
+}
+
+
+
 ModuleBase_WidgetMultiSelector::ModuleBase_WidgetMultiSelector(QWidget* theParent,
                                                                ModuleBase_IWorkshop* theWorkshop,
                                                                const Config_WidgetAPI* theData)
 : ModuleBase_WidgetSelector(theParent, theWorkshop, theData),
   myIsSetSelectionBlocked(false), myCurrentHistoryIndex(-1)
 {
+  std::string aPropertyTypes = theData->getProperty("type_choice");
+  QString aTypesStr = aPropertyTypes.c_str();
+  myShapeTypes = aTypesStr.split(' ', QString::SkipEmptyParts);
+  myIsUseChoice = theData->getBooleanAttribute("use_choice", false);
+
   QGridLayout* aMainLay = new QGridLayout(this);
   ModuleBase_Tools::adjustMargins(aMainLay);
 
-  QLabel* aTypeLabel = new QLabel(tr("Type"), this);
-  aMainLay->addWidget(aTypeLabel, 0, 0);
+  QStringList aIconsList = getIconsList(myShapeTypes);
+  myTypeCtrl = new ModuleBase_ChoiceCtrl(this, myShapeTypes, aIconsList);
+  myTypeCtrl->setLabel(tr("Type"));
+  myTypeCtrl->setValue(0);
+  aMainLay->addWidget(myTypeCtrl, 0, 0, 1, 2);
 
-  myTypeCombo = new QComboBox(this);
   // There is no sense to parameterize list of types while we can not parameterize selection mode
-
-  std::string aPropertyTypes = theData->getProperty("type_choice");
-  QString aTypesStr = aPropertyTypes.c_str();
-  QStringList aShapeTypes = aTypesStr.split(' ', QString::SkipEmptyParts);
-
-  myIsUseChoice = theData->getBooleanAttribute("use_choice", false);
-
-  if (!aShapeTypes.empty())
-    myTypeCombo->addItems(aShapeTypes);
-  aMainLay->addWidget(myTypeCombo, 0, 1);
   // if the xml definition contains one type, the controls to select a type should not be shown
-  if (aShapeTypes.size() <= 1 || !myIsUseChoice) {
-    aTypeLabel->setVisible(false);
-    myTypeCombo->setVisible(false);
+  if (myShapeTypes.size() <= 1 || !myIsUseChoice) {
+    myTypeCtrl->setVisible(false);
   }
 
   QString aLabelText = translate(theData->getProperty("label"));
@@ -112,7 +130,7 @@ ModuleBase_WidgetMultiSelector::ModuleBase_WidgetMultiSelector(QWidget* theParen
   aMainLay->addWidget(aListLabel, 1, 0);
   // if the xml definition contains one type, an information label
   // should be shown near to the latest
-  if (aShapeTypes.size() <= 1) {
+  if (myShapeTypes.size() <= 1) {
     QString aLabelIcon = QString::fromStdString(theData->widgetIcon());
     if (!aLabelIcon.isEmpty()) {
       QLabel* aSelectedLabel = new QLabel("", this);
@@ -133,7 +151,7 @@ ModuleBase_WidgetMultiSelector::ModuleBase_WidgetMultiSelector(QWidget* theParen
   //aMainLay->addWidget(new QLabel(this)); //FIXME(sbh)???
   //aMainLay->setRowMinimumHeight(3, 20);
   //this->setLayout(aMainLay);
-  connect(myTypeCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(onSelectionTypeChanged()));
+  connect(myTypeCtrl, SIGNAL(valueChanged(int)), this, SLOT(onSelectionTypeChanged()));
 
   myIsNeutralPointClear = theData->getBooleanAttribute("clear_in_neutral_point", true);
 }
@@ -187,7 +205,7 @@ bool ModuleBase_WidgetMultiSelector::storeValueCustom()
   std::string aType = anAttribute->attributeType();
   if (aType == ModelAPI_AttributeSelectionList::typeId()) {
     AttributeSelectionListPtr aSelectionListAttr = myFeature->data()->selectionList(attributeID());
-    aSelectionListAttr->setSelectionType(myTypeCombo->currentText().toStdString());
+    aSelectionListAttr->setSelectionType(myTypeCtrl->textValue().toStdString());
   }
   return true;
 }
@@ -427,7 +445,6 @@ bool ModuleBase_WidgetMultiSelector::processDelete()
 QList<QWidget*> ModuleBase_WidgetMultiSelector::getControls() const
 {
   QList<QWidget*> result;
-  //result << myTypeCombo;
   result << myListView->getControl();
   return result;
 }
@@ -450,7 +467,7 @@ void ModuleBase_WidgetMultiSelector::onSelectionTypeChanged()
   std::string aType = anAttribute->attributeType();
   if (aType == ModelAPI_AttributeSelectionList::typeId()) {
     AttributeSelectionListPtr aSelectionListAttr = myFeature->data()->selectionList(attributeID());
-    aSelectionListAttr->setSelectionType(myTypeCombo->currentText().toStdString());
+    aSelectionListAttr->setSelectionType(myTypeCtrl->textValue().toStdString());
   }
 
   // clear attribute values
@@ -479,6 +496,9 @@ void ModuleBase_WidgetMultiSelector::onSelectionTypeChanged()
                             true); /// hope that something is redisplayed by object updated
   // clear history should follow after set selected to do not increase history by setSelected
   clearSelectedHistory();
+
+  if (myWorkshop->propertyPanel()->activeWidget() != this)
+    myWorkshop->propertyPanel()->activateWidget(this);
 }
 
 //********************************************************************
@@ -583,12 +603,13 @@ QIntList ModuleBase_WidgetMultiSelector::shapeTypes() const
 {
   QIntList aShapeTypes;
 
-  if (myTypeCombo->count() > 1 && myIsUseChoice) {
-    aShapeTypes.append(ModuleBase_Tools::shapeType(myTypeCombo->currentText()));
+  if (myShapeTypes.length() > 1 && myIsUseChoice) {
+    aShapeTypes.append(ModuleBase_Tools::shapeType(myTypeCtrl->textValue()));
   }
   else {
-    for (int i = 0, aCount = myTypeCombo->count(); i < aCount; i++)
-      aShapeTypes.append(ModuleBase_Tools::shapeType(myTypeCombo->itemText(i)));
+    foreach (QString aType, myShapeTypes) {
+      aShapeTypes.append(ModuleBase_Tools::shapeType(aType));
+    }
   }
   return aShapeTypes;
 }
@@ -598,17 +619,18 @@ void ModuleBase_WidgetMultiSelector::setCurrentShapeType(const int theShapeType)
 {
   QString aShapeTypeName;
 
-  for (int idx = 0; idx < myTypeCombo->count(); ++idx) {
-    aShapeTypeName = myTypeCombo->itemText(idx);
+  int idx = 0;
+  foreach (QString aShapeTypeName, myShapeTypes) {
     int aRefType = ModuleBase_Tools::shapeType(aShapeTypeName);
-    if(aRefType == theShapeType && idx != myTypeCombo->currentIndex()) {
+    if(aRefType == theShapeType && idx != myTypeCtrl->value()) {
       updateSelectionModesAndFilters(false);
-      bool isBlocked = myTypeCombo->blockSignals(true);
-      myTypeCombo->setCurrentIndex(idx);
-      myTypeCombo->blockSignals(isBlocked);
+      bool isBlocked = myTypeCtrl->blockSignals(true);
+      myTypeCtrl->setValue(idx);
+      myTypeCtrl->blockSignals(isBlocked);
       updateSelectionModesAndFilters(true);
       break;
     }
+    idx++;
   }
 }
 
index f4a155981fc69e822da0d61539aa1b1a0d79eebf..be8bfee91b49e97f17b64547ae34905ea152ba91 100755 (executable)
 #include <QMap>
 
 class QWidget;
-class QComboBox;
+//class QComboBox;
 class ModuleBase_ListView;
 class ModuleBase_IWorkshop;
+class ModuleBase_ChoiceCtrl;
 
 /**
 * \ingroup GUI
@@ -219,8 +220,13 @@ protected:
 
 protected:
   ModuleBase_ListView* myListView; ///< List control
-  QComboBox* myTypeCombo; ///< Combobox of types
-  bool myIsUseChoice; /// A flag to store use_choice parameter state
+
+  bool myIsUseChoice; ///< A flag to store use_choice parameter state
+
+  QStringList myShapeTypes; ///< List of Shape types defined in XML
+
+  /// Control for types
+  ModuleBase_ChoiceCtrl* myTypeCtrl;
 
   /// A flag to clear selection by click in empty place in the viewer
   bool myIsNeutralPointClear;
@@ -230,6 +236,7 @@ protected:
 
   /// A container of selected objects
   QList<QList<std::shared_ptr<ModuleBase_ViewerPrs> > > mySelectedHistoryValues;
+
   /// Position in a container of selected values
   int myCurrentHistoryIndex;
 };
diff --git a/src/ModuleBase/ModuleBase_WidgetNameEdit.cpp b/src/ModuleBase/ModuleBase_WidgetNameEdit.cpp
new file mode 100644 (file)
index 0000000..9261f6f
--- /dev/null
@@ -0,0 +1,52 @@
+// Copyright (C) 2014-2017  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or
+// email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+//
+
+#include "ModuleBase_WidgetNameEdit.h"
+
+#include <ModelAPI_Result.h>
+
+#include <QLineEdit>
+
+bool ModuleBase_WidgetNameEdit::storeValueCustom()
+{
+  if(!myFeature)
+    return false;
+
+  QString aValue = myLineEdit->text();
+  std::string aName = aValue.toStdString();
+  myFeature->data()->setName(aName);
+  ResultPtr aRes = myFeature->firstResult();
+  if (aRes.get())
+    aRes->data()->setName(aName);
+  updateObject(myFeature);
+  return true;
+}
+
+bool ModuleBase_WidgetNameEdit::restoreValueCustom()
+{
+  if(!myFeature)
+    return false;
+
+  bool isBlocked = myLineEdit->blockSignals(true);
+  myLineEdit->setText(QString::fromStdString(myFeature->data()->name()));
+  myLineEdit->blockSignals(isBlocked);
+
+  return true;
+}
\ No newline at end of file
diff --git a/src/ModuleBase/ModuleBase_WidgetNameEdit.h b/src/ModuleBase/ModuleBase_WidgetNameEdit.h
new file mode 100644 (file)
index 0000000..ba090c4
--- /dev/null
@@ -0,0 +1,49 @@
+// Copyright (C) 2014-2017  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or
+// email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+//
+
+#ifndef MODULEBASE_WIDGETNAMEEDIT_H_
+#define MODULEBASE_WIDGETNAMEEDIT_H_
+
+#include <ModuleBase.h>
+#include <ModuleBase_WidgetLineEdit.h>
+
+class ModuleBase_WidgetNameEdit : public ModuleBase_WidgetLineEdit
+{
+  Q_OBJECT
+public:
+  ModuleBase_WidgetNameEdit( QWidget* theParent,
+                             const Config_WidgetAPI* theData,
+                             const std::string& thePlaceHolder )
+             : ModuleBase_WidgetLineEdit(theParent, theData, thePlaceHolder) {}
+
+  /// Returns True if the widget uses feature attribute.
+  /// If not then it means that the widget do not need attribute at all.
+  virtual bool usesAttribute() const { return false; }
+
+protected:
+    /// Saves the internal parameters to the given feature
+  /// \return True in success
+  virtual bool storeValueCustom();
+
+  /// Redefinition of virtual method
+  virtual bool restoreValueCustom();
+};
+
+#endif
\ No newline at end of file
index 8bb95e123773e96885c16eb3ffa570cad42b2c95..389f4904fb89266639dd814f4d8165a018c1213e 100644 (file)
@@ -159,6 +159,7 @@ INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/src/XGUI
                     ${PROJECT_SOURCE_DIR}/src/FeaturesPlugin
                     ${PROJECT_SOURCE_DIR}/src/PartSetPlugin
                     ${PROJECT_SOURCE_DIR}/src/GeomAPI
+                    ${PROJECT_SOURCE_DIR}/src/CollectionPlugin
                     ${CAS_INCLUDE_DIRS}
                     ${SUIT_INCLUDE}
 )
index 5543d690201d7e1a49a1dc6224db81312b6ded3b..42b3d4d62f6f65b516232f300dbc7f603d3ba098 100644 (file)
@@ -29,6 +29,8 @@
 #include <Config_FeatureMessage.h>
 #include <Events_Loop.h>
 
+#include <CollectionPlugin_Group.h>
+
 QMap<QString, QString> PartSet_IconFactory::myIcons;
 
 PartSet_IconFactory::PartSet_IconFactory():ModuleBase_IconFactory()
@@ -94,6 +96,19 @@ QIcon PartSet_IconFactory::getIcon(ObjectPtr theObj)
     if(aShape.get()) {
       switch(aShape->shapeType()) {
         case GeomAPI_Shape::COMPOUND: {
+          FeaturePtr aFeature = ModelAPI_Feature::feature(theObj);
+          if (aFeature.get() && aFeature->getKind() == CollectionPlugin_Group::ID()) {
+            switch (aShape->typeOfCompoundShapes()) {
+            case GeomAPI_Shape::VERTEX:
+              return QIcon(":icons/group_vertex.png");
+            case GeomAPI_Shape::EDGE:
+              return QIcon(":icons/group_edge.png");
+            case GeomAPI_Shape::FACE:
+              return QIcon(":icons/group_face.png");
+            case GeomAPI_Shape::SOLID:
+              return QIcon(":icons/group_solid.png");
+            }
+          }
           ResultBodyPtr aBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(aResult);
           if (aBody.get() && aBody->isConnectedTopology())
             return QIcon(":pictures/compoundofsolids.png");
index ae23920e59fd8439e259b7663450189009f51714..9b19b30a5bd8e5887483f9070d98896f11cadbae 100644 (file)
      <file>icons/sketch_shape.png</file>
      <file>icons/expression.png</file>
      <file>icons/paper_roll.png</file>
+
+     <file>icons/group_edge.png</file>
+     <file>icons/group_face.png</file>
+     <file>icons/group_solid.png</file>
+     <file>icons/group_vertex.png</file>
  </qresource>
  </RCC>
diff --git a/src/PartSet/icons/group_edge.png b/src/PartSet/icons/group_edge.png
new file mode 100644 (file)
index 0000000..b670cd4
Binary files /dev/null and b/src/PartSet/icons/group_edge.png differ
diff --git a/src/PartSet/icons/group_face.png b/src/PartSet/icons/group_face.png
new file mode 100644 (file)
index 0000000..68d152e
Binary files /dev/null and b/src/PartSet/icons/group_face.png differ
diff --git a/src/PartSet/icons/group_solid.png b/src/PartSet/icons/group_solid.png
new file mode 100644 (file)
index 0000000..bb5f6ac
Binary files /dev/null and b/src/PartSet/icons/group_solid.png differ
diff --git a/src/PartSet/icons/group_vertex.png b/src/PartSet/icons/group_vertex.png
new file mode 100644 (file)
index 0000000..63d9ef1
Binary files /dev/null and b/src/PartSet/icons/group_vertex.png differ
index 050b3cef2ffc5811e061c38485121724fd7d2d4c..0d7a57d33a3d337f815ac27dc47066eaf13d84ea 100644 (file)
@@ -255,6 +255,11 @@ QAction* XGUI_ActionsMgr::operationStateAction(OperationStateActionId theId)
                             "Apply" /*empty to show error*/, aParent);
       }
       break;
+      case AcceptPlus: {
+        aResult = ModuleBase_Tools::createAction(QIcon(":pictures/button_ok-plus.png"),
+                            "Apply and continue" /*empty to show error*/, aParent);
+      }
+      break;
       case Abort:
       case AbortAll: {
         aResult = ModuleBase_Tools::createAction(QIcon(":pictures/button_cancel.png"), "Cancel",
index 89693cbc131da4f0a70aa59dcbb81be053d4c5f4..3773ae9bac0b423261ac87ee44d34cca0b47fa55 100644 (file)
@@ -56,10 +56,11 @@ class XGUI_EXPORT XGUI_ActionsMgr : public QObject, public Events_Listener
   enum OperationStateActionId {
     Abort = 0,
     Accept = 1,
-    Help = 2,
-    AbortAll = 3,
-    AcceptAll = 4,
-    Preview = 5
+    AcceptPlus = 2,
+    Help = 3,
+    AbortAll = 4,
+    AcceptAll = 5,
+    Preview = 6
   };
 
   /// Add a command in the manager.
index 5ead6a91dddb364939f278f5b22d9f550c270704..19c1135b9c8c142986d787eba46b2bebee8c625e 100644 (file)
@@ -160,12 +160,15 @@ void XGUI_ErrorMgr::updateAcceptActionState(const QString& theError)
 {
   XGUI_ActionsMgr* anActionsMgr = workshop()->actionsMgr();
   QAction* anAcceptAction = anActionsMgr->operationStateAction(XGUI_ActionsMgr::Accept);
+  QAction* anAcceptPlusAction =
+    anActionsMgr->operationStateAction(XGUI_ActionsMgr::AcceptPlus);
 
   if (myAcceptAllToolTip.isEmpty() && myAcceptToolTip.isEmpty())
     storeInitialActionValues();
 
   bool anEnabled = theError.isEmpty();
   anAcceptAction->setEnabled(anEnabled);
+  anAcceptPlusAction->setEnabled(anEnabled);
   anAcceptAction->setToolTip(anEnabled ? myAcceptToolTip : theError);
   anAcceptAction->setStatusTip(anEnabled ? myAcceptStatusTip : theError);
   // some operations have no property panel, so it is important to check that it is not null
index 3e8e67584c8e6d622abe1213c7e653ca6329ba75..5d287669ffb6cf4794a1ff28c6ad5fcd7a3e0197 100755 (executable)
@@ -36,6 +36,7 @@
 #include <ModuleBase_WidgetFactory.h>
 #include <ModuleBase_OperationDescription.h>
 #include <ModuleBase_Events.h>
+#include <ModuleBase_IWorkshop.h>
 
 #include <Events_Loop.h>
 
@@ -51,7 +52,6 @@
 #include <QVBoxLayout>
 #include <QGridLayout>
 #include <QWidget>
-#include <QToolButton>
 #include <QAction>
 
 #ifdef _DEBUG
@@ -93,6 +93,7 @@ XGUI_PropertyPanel::XGUI_PropertyPanel(QWidget* theParent, XGUI_OperationMgr* th
   QStringList aBtnNames;
   aBtnNames << QString(PROP_PANEL_HELP)
             << QString(PROP_PANEL_OK)
+            << QString(PROP_PANEL_OK_PLUS)
             << QString(PROP_PANEL_CANCEL);
   foreach(QString eachBtnName, aBtnNames) {
     QToolButton* aBtn = new QToolButton(aFrm);
@@ -223,6 +224,9 @@ void XGUI_PropertyPanel::createContentPanel(FeaturePtr theFeature)
     /// Apply button should be update if the feature was modified by the panel
     myOperationMgr->onValidateOperation();
   }
+  std::shared_ptr<Config_FeatureMessage> aFeatureInfo =
+    myOperationMgr->workshop()->featureInfo(theFeature->getKind().c_str());
+  findButton(PROP_PANEL_OK_PLUS)->setVisible(aFeatureInfo->isApplyContinue());
 }
 
 void XGUI_PropertyPanel::activateNextWidget(ModuleBase_ModelWidget* theWidget)
@@ -396,11 +400,11 @@ bool XGUI_PropertyPanel::focusNextPrevChild(bool theIsNext)
     findDirectChildren(this, aChildren, true);
     int aChildrenCount = aChildren.count();
     int aFocusWidgetIndex = aChildren.indexOf(aFocusWidget);
+    QToolButton* anOkBtn = findButton(PROP_PANEL_OK);
     if (aFocusWidgetIndex >= 0) {
       if (theIsNext) {
         if (aFocusWidgetIndex == aChildrenCount-1) {
           // after the last widget focus should be set to "Apply"
-          QToolButton* anOkBtn = findButton(PROP_PANEL_OK);
           if (anOkBtn->isEnabled())
             aNewFocusWidget = anOkBtn;
           else {
@@ -420,7 +424,6 @@ bool XGUI_PropertyPanel::focusNextPrevChild(bool theIsNext)
         }
         else {
           // before the "Apply" button, the last should accept focus for consistency with "Next"
-          QToolButton* anOkBtn = findButton(PROP_PANEL_OK);
           if (aFocusWidget == anOkBtn) {
             aNewFocusWidget = aChildren[aChildrenCount - 1];
           }
@@ -551,10 +554,11 @@ 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 << PROP_PANEL_PREVIEW;
+  aButtonNames << PROP_PANEL_OK<< PROP_PANEL_OK_PLUS << PROP_PANEL_CANCEL
+               << PROP_PANEL_HELP << PROP_PANEL_PREVIEW;
   QList<XGUI_ActionsMgr::OperationStateActionId> aActionIds;
-  aActionIds << XGUI_ActionsMgr::Accept << XGUI_ActionsMgr::Abort << XGUI_ActionsMgr::Help
-             << XGUI_ActionsMgr::Preview;
+  aActionIds << XGUI_ActionsMgr::Accept << XGUI_ActionsMgr::AcceptPlus << XGUI_ActionsMgr::Abort
+             << XGUI_ActionsMgr::Help << XGUI_ActionsMgr::Preview;
   for (int i = 0; i < aButtonNames.size(); ++i) {
     QToolButton* aBtn = findButton(aButtonNames.at(i).toStdString().c_str());
     QAction* anAct = theMgr->operationStateAction(aActionIds.at(i));
index e8b7082c9e81b2a5f54b81b9479a2d3a390d53ec..5b1a68b88c16daf6e677081aa03da9cd2c557acc 100644 (file)
@@ -42,6 +42,9 @@ const static char* PROP_PANEL = "property_panel_dock";
 /// Internal name of Ok button
 const static char* PROP_PANEL_OK = "property_panel_ok";
 
+/// Internal name of Ok button
+const static char* PROP_PANEL_OK_PLUS = "property_panel_ok_plus";
+
 /// Internal name of Cancel button
 const static char* PROP_PANEL_CANCEL = "property_panel_cancel";
 
index da6775edda9bdce6c56ff063242545080657a888..e55494d77bb45f26be0bba2d24ba54841c36a34f 100755 (executable)
@@ -527,6 +527,21 @@ void XGUI_Workshop::onAcceptActionClicked()
   }
 }
 
+//******************************************************
+void XGUI_Workshop::onAcceptPlusActionClicked()
+{
+  QAction* anAction = dynamic_cast<QAction*>(sender());
+  XGUI_OperationMgr* anOperationMgr = operationMgr();
+  if (anOperationMgr) {
+    ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+                                                    (anOperationMgr->currentOperation());
+    if (aFOperation) {
+      myOperationMgr->commitOperation();
+      module()->launchOperation(aFOperation->id(), false);
+    }
+  }
+}
+
 //******************************************************
 void XGUI_Workshop::onPreviewActionClicked()
 {
@@ -595,13 +610,15 @@ void XGUI_Workshop::fillPropertyPanel(ModuleBase_Operation* theOperation)
   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 '%1' has no attribute '%2' used by widget '%3'.";
-      Events_InfoMessage("XGUI_Workshop", anErrorMsg)
-        .arg(aFeatureKind).arg(aWidget->attributeID())
-        .arg(aWidget->metaObject()->className()).send();
-      myPropertyPanel->cleanContent();
-      return;
+    if (aWidget->usesAttribute()) {
+      if (!aWidget->attributeID().empty() && !aFeature->attribute(aWidget->attributeID()).get()) {
+        std::string anErrorMsg = "The feature '%1' has no attribute '%2' used by widget '%3'.";
+        Events_InfoMessage("XGUI_Workshop", anErrorMsg)
+          .arg(aFeatureKind).arg(aWidget->attributeID())
+          .arg(aWidget->metaObject()->className()).send();
+        myPropertyPanel->cleanContent();
+        return;
+      }
     }
   }
   // for performance purpose, flush should be done after all controls are filled
@@ -1358,6 +1375,9 @@ void XGUI_Workshop::createDockWidgets()
   QAction* aOkAct = myActionsMgr->operationStateAction(XGUI_ActionsMgr::Accept);
   connect(aOkAct, SIGNAL(triggered()), this, SLOT(onAcceptActionClicked()));
 
+  QAction* aOkContAct = myActionsMgr->operationStateAction(XGUI_ActionsMgr::AcceptPlus);
+  connect(aOkContAct, SIGNAL(triggered()), this, SLOT(onAcceptPlusActionClicked()));
+
   QAction* aCancelAct = myActionsMgr->operationStateAction(XGUI_ActionsMgr::Abort);
   connect(aCancelAct, SIGNAL(triggered()), myOperationMgr, SLOT(onAbortOperation()));
 
index 8393a2987136d00a7d46a2530e16a6df6b652c45..7495365b43824d14eb09af3ea719752d016a1df4 100755 (executable)
@@ -454,6 +454,10 @@ private:
   /// the operation can be committed and do it if it returns true.
   void onAcceptActionClicked();
 
+  /// Called by OkPlus button clicked in the property panel. Asks the error manager whether
+  /// the operation can be committed and do it if it returns true.
+  void onAcceptPlusActionClicked();
+
   /// Called by Preview button clicked in the property panel. Sends signal to model to
   /// compute preview.
   void onPreviewActionClicked();
index 14e55f36780dc71be9dbd426a0f08b37e3ed7498..913ca9b006711b083ec2e68edc21483ebeac384f 100644 (file)
@@ -30,6 +30,7 @@
      <file>pictures/button_help.png</file>
      <file>pictures/button_ok.png</file>
      <file>pictures/button_ok_error.png</file>
+     <file>pictures/button_ok-plus.png</file>
      <file>pictures/button_plus.png</file>
 
      <file>pictures/assembly.png</file>
      <file>pictures/eyeopen.png</file>
 
      <file>pictures/transparency.png</file>
+     <file>pictures/solid32.png</file>
+     <file>pictures/face32.png</file>
+     <file>pictures/edge32.png</file>
+     <file>pictures/vertex32.png</file>
      <file>pictures/features_folder.png</file>
      <file>pictures/create_folder.png</file>
      <file>pictures/insert_folder_after.png</file>
diff --git a/src/XGUI/pictures/button_ok-plus.png b/src/XGUI/pictures/button_ok-plus.png
new file mode 100644 (file)
index 0000000..e8df2e6
Binary files /dev/null and b/src/XGUI/pictures/button_ok-plus.png differ
diff --git a/src/XGUI/pictures/edge32.png b/src/XGUI/pictures/edge32.png
new file mode 100644 (file)
index 0000000..cb8bc1d
Binary files /dev/null and b/src/XGUI/pictures/edge32.png differ
diff --git a/src/XGUI/pictures/face32.png b/src/XGUI/pictures/face32.png
new file mode 100644 (file)
index 0000000..44bc549
Binary files /dev/null and b/src/XGUI/pictures/face32.png differ
diff --git a/src/XGUI/pictures/solid32.png b/src/XGUI/pictures/solid32.png
new file mode 100644 (file)
index 0000000..6db2ffd
Binary files /dev/null and b/src/XGUI/pictures/solid32.png differ
diff --git a/src/XGUI/pictures/vertex32.png b/src/XGUI/pictures/vertex32.png
new file mode 100644 (file)
index 0000000..edce228
Binary files /dev/null and b/src/XGUI/pictures/vertex32.png differ