<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"/>
myInternal = false;
myUseInput = false;
myNestedFeatures = "";
+ myModal = false;
+ myIsApplyContinue = false;
}
Config_FeatureMessage::~Config_FeatureMessage()
return myModal;
}
+bool Config_FeatureMessage::isApplyContinue() const
+{
+ return myIsApplyContinue;
+}
+
+
void Config_FeatureMessage::setUseInput(bool isUseInput)
{
myUseInput = isUseInput;
{
myIsAutoPreview = isAutoPreview;
}
+
+void Config_FeatureMessage::setApplyContinue(bool isModal)
+{
+ myIsApplyContinue = isModal;
+}
\ No newline at end of file
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
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;
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
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);
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";
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)
{
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
${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}
)
#include <Config_FeatureMessage.h>
#include <Events_Loop.h>
+#include <CollectionPlugin_Group.h>
+
QMap<QString, QString> PartSet_IconFactory::myIcons;
PartSet_IconFactory::PartSet_IconFactory():ModuleBase_IconFactory()
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");
<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>
"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",
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.
{
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
#include <ModuleBase_WidgetFactory.h>
#include <ModuleBase_OperationDescription.h>
#include <ModuleBase_Events.h>
+#include <ModuleBase_IWorkshop.h>
#include <Events_Loop.h>
#include <QVBoxLayout>
#include <QGridLayout>
#include <QWidget>
-#include <QToolButton>
#include <QAction>
#ifdef _DEBUG
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);
/// 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)
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 {
}
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];
}
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));
/// 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";
}
}
+//******************************************************
+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()
{
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()));
/// 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();
<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>