return myInternal;
}
+bool Config_FeatureMessage::isAutoPreview() const
+{
+ return myIsAutoPreview;
+}
+
void Config_FeatureMessage::setUseInput(bool isUseInput)
{
myUseInput = isUseInput;
{
myActionsWhenNested = theActions;
}
+
+void Config_FeatureMessage::setAutoPreview(bool isAutoPreview)
+{
+ myIsAutoPreview = isAutoPreview;
+}
\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
/// 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
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
aDocKind = restoreAttribute(NODE_WORKBENCH, WORKBENCH_DOC);
}
outFeatureMessage->setDocumentKind(aDocKind);
+ bool isAutoPreview = getBooleanAttribute(theFeatureNode, FEATURE_AUTO_PREVIEW, true);
+ outFeatureMessage->setAutoPreview(isAutoPreview);
}
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";
<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">
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
}
// 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);
}
aResult->setToolTip("Help");
}
break;
+ case Preview: {
+ aResult = new QAction("See the preview", theParent);
+ aResult->setToolTip("Compute preview");
+ }
+ break;
default:
break;
}
Accept = 1,
Help = 2,
AbortAll = 3,
- AcceptAll = 4
+ AcceptAll = 4,
+ Preview = 5
};
//! Add a command in the manager.
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;
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);
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);
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()
myWidgets.clear();
myPanelPage->clearPage();
myActiveWidget = NULL;
+
+ findButton(PROP_PANEL_PREVIEW)->setVisible(false); /// by default it is hidden
setWindowTitle(tr("Property Panel"));
}
// 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;
}
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;
}
}
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];
}
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();
}
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);
}
} else
ModuleBase_IPropertyPanel::closeEvent(theEvent);
}
+
+QToolButton* XGUI_PropertyPanel::findButton(const char* theInternalName) const
+{
+ return findChild<QToolButton*>(theInternalName);
+}
class XGUI_ActionsMgr;
class QKeyEvent;
class QGridLayout;
+class QToolButton;
class ModuleBase_PageBase;
class ModuleBase_PageWidget;
class XGUI_OperationMgr;
/// 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.
/// 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
/// \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;
}
}
+//******************************************************
+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)
{
// 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);
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);
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*)));
}
/// 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();
// 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()) {