#include "PartSet_WidgetPoint2d.h"
#include "ModelAPI_Session.h"
+#include "ModelAPI_AttributeString.h"
+#include "ModelAPI_AttributeRefAttr.h"
+
+#include "GeomDataAPI_Point2D.h"
#include <ModuleBase_IPropertyPanel.h>
#include <ModuleBase_OperationFeature.h>
#include <ModuleBase_PageBase.h>
#include <ModuleBase_WidgetFactory.h>
#include <ModuleBase_OperationDescription.h>
+#include "ModuleBase_ToolBox.h"
#include <SketchPlugin_Feature.h>
#include <SketchPlugin_Line.h>
+#include <SketchPlugin_Arc.h>
+#include <SketchPlugin_Circle.h>
#include <XGUI_Workshop.h>
#include <XGUI_ModuleConnector.h>
#include <XGUI_OperationMgr.h>
#include <XGUI_PropertyPanel.h>
+#include <QToolButton>
+
PartSet_SketcherReetntrantMgr::PartSet_SketcherReetntrantMgr(ModuleBase_IWorkshop* theWorkshop)
: QObject(theWorkshop),
myWorkshop(theWorkshop),
if (!isActiveMgr())
return aWidget;
- ModuleBase_Operation* aOperation = myWorkshop->currentOperation();
- if (aOperation) {
- ModuleBase_IPropertyPanel* aPanel = aOperation->propertyPanel();
+ ModuleBase_Operation* anOperation = myWorkshop->currentOperation();
+ if (anOperation) {
+ ModuleBase_IPropertyPanel* aPanel = anOperation->propertyPanel();
ModuleBase_ModelWidget* anActiveWidget = aPanel->activeWidget();
if (myIsInternalEditOperation && (!anActiveWidget || !anActiveWidget->isViewerSelector()))
aWidget = myInternalActiveWidget;
return myIsInternalEditOperation;
}
+void PartSet_SketcherReetntrantMgr::updateInternalEditActiveState()
+{
+ if (myIsInternalEditOperation) {
+ ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+ (myWorkshop->currentOperation());
+ if (aFOperation) {
+ FeaturePtr aFeature = aFOperation->feature();
+ QString anError = myWorkshop->module()->getFeatureError(aFeature);
+ // stop started internal edit operation as soon as the operation becomes invalid
+ // it is especially important for the sketch tangent arc feature
+ if (!anError.isEmpty()) {
+ aFOperation->setEditOperation(false);
+ //workshop()->operationMgr()->updateApplyOfOperations();
+ beforeStopInternalEdit();
+ myIsInternalEditOperation = false;
+ }
+ }
+ }
+}
+
bool PartSet_SketcherReetntrantMgr::operationCommitted(ModuleBase_Operation* theOperation)
{
bool aProcessed = false;
return aProcessed;
if (myIsInternalEditOperation) {
- PartSet_WidgetPoint2D* aPoint2DWdg = dynamic_cast<PartSet_WidgetPoint2D*>(module()->activeWidget());
- if (aPoint2DWdg && aPoint2DWdg->canBeActivatedByMove()) {
- ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+ ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
(myWorkshop->currentOperation());
- FeaturePtr aLastFeature = myRestartingMode == RM_LastFeatureUsed ? aFOperation->feature() : FeaturePtr();
- restartOperation();
- aProcessed = true;
-
- if (aLastFeature) {
- ModuleBase_IPropertyPanel* aPanel = myWorkshop->currentOperation()->propertyPanel();
- PartSet_WidgetPoint2D* aPoint2DWdg = dynamic_cast<PartSet_WidgetPoint2D*>(aPanel->activeWidget());
- if (aPoint2DWdg && aPoint2DWdg->canBeActivatedByMove()) {
- QList<ModuleBase_ViewerPrs> aSelection;
- aSelection.append(ModuleBase_ViewerPrs(aLastFeature, TopoDS_Shape(), NULL));
- if (aPoint2DWdg->setSelection(aSelection, true))
- aPanel->activateNextWidget(aPoint2DWdg);
+ FeaturePtr aLastFeature = myRestartingMode == RM_LastFeatureUsed ? aFOperation->feature()
+ : FeaturePtr();
+ if (aLastFeature) {
+ ModuleBase_ModelWidget* anActiveWidget = module()->activeWidget();
+ ModuleBase_IPropertyPanel* aPanel = myWorkshop->currentOperation()->propertyPanel();
+ bool aWidgetIsFilled = false;
+
+ //bool aCanBeActivatedByMove = false;
+ FeaturePtr aCurrentFeature = aFOperation->feature();
+ bool isLineFeature = false, isArcFeature = false;
+ if (aCurrentFeature->getKind() == SketchPlugin_Line::ID())
+ isLineFeature = anActiveWidget->attributeID() == SketchPlugin_Line::START_ID();
+ else if (isTangentArc(aFOperation))
+ isArcFeature = anActiveWidget->attributeID() == SketchPlugin_Arc::TANGENT_POINT_ID();
+
+ bool aCanBeActivatedByMove = isLineFeature || isArcFeature;
+ if (aCanBeActivatedByMove) {
+ restartOperation();
+
+ anActiveWidget = module()->activeWidget();
+ aCurrentFeature = anActiveWidget->feature();
+ aProcessed = true;
+ if (isLineFeature) {
+ PartSet_WidgetPoint2D* aPoint2DWdg = dynamic_cast<PartSet_WidgetPoint2D*>(anActiveWidget);
+ if (aPoint2DWdg) { // line, start point should be equal last point of the last feature line
+ QList<ModuleBase_ViewerPrsPtr> aSelection;
+ aSelection.append(std::shared_ptr<ModuleBase_ViewerPrs>(
+ new ModuleBase_ViewerPrs(aLastFeature, GeomShapePtr(), NULL)));
+ aWidgetIsFilled = aPoint2DWdg->setSelection(aSelection, true);
+ }
+ }
+ else if (isArcFeature) { // arc, start point should be equal last point of the last feature arc
+ if (aCurrentFeature->getKind() == SketchPlugin_Arc::ID()) {
+ // get the last point of the previuos arc feature(geom point 2d)
+ std::shared_ptr<ModelAPI_Data> aData = aLastFeature->data();
+ std::shared_ptr<GeomDataAPI_Point2D> aPointAttr =
+ std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ aData->attribute(SketchPlugin_Arc::END_ID()));
+ // get point attribute on the current feature
+ AttributeRefAttrPtr aTangentPointAttr = aCurrentFeature->data()->refattr(
+ SketchPlugin_Arc::TANGENT_POINT_ID());
+ aTangentPointAttr->setAttr(aPointAttr);
+ aWidgetIsFilled = true;
+ }
}
}
+ if (aWidgetIsFilled)
+ aPanel->activateNextWidget(anActiveWidget);
}
}
return aProcessed;
ModuleBase_ModelWidget* anActiveWidget = aPanel->activeWidget();
if (!anActiveWidget || !anActiveWidget->isViewerSelector()) {
+
+ // block of viewer update
+ // we need to block update content of the viewer because of Sketch Point feature
+ // in activate() the value of the point is initialized and it can be displayed
+ // but the default value is [0, 0]. So, we block update viewer contentent until
+ // onMouseRelease happens, which correct the point position
+ ModuleBase_Tools::blockUpdateViewer(true);
+
restartOperation();
aProcessed = true;
if (aPoint2DWdg && aPoint2DWdg == aFirstWidget) {
aPoint2DWdg->onMouseRelease(theWnd, theEvent);
}
+ // unblock viewer update
+ ModuleBase_Tools::blockUpdateViewer(false);
}
}
if (!isActiveMgr())
return isDone;
+ // empty previous attribute means that the Apply/Ok button has focus and the enter
+ // should not lead to start edition mode of the previous operation
+ if (thePreviousAttributeID.empty())
+ return isDone;
+
ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
(myWorkshop->currentOperation());
if (!myWorkshop->module()->getFeatureError(aFOperation->feature()).isEmpty())
return isDone;
bool isSketchSolverError = module()->sketchMgr()->sketchSolverError();
+
if (!isSketchSolverError) {
myRestartingMode = RM_EmptyFeatureUsed;
isDone = startInternalEdit(thePreviousAttributeID);
if (!isActiveMgr())
return;
- ModuleBase_Operation* aOperation = myWorkshop->currentOperation();
- if (aOperation->id().toStdString() == SketchPlugin_Line::ID()) {
+ ModuleBase_Operation* anOperation = myWorkshop->currentOperation();
+ std::string anOperationId = anOperation->id().toStdString();
+ if (anOperationId == SketchPlugin_Line::ID() || isTangentArc(anOperation)) {
/// If last line finished on vertex the lines creation sequence has to be break
- ModuleBase_IPropertyPanel* aPanel = aOperation->propertyPanel();
+ ModuleBase_IPropertyPanel* aPanel = anOperation->propertyPanel();
ModuleBase_ModelWidget* anActiveWidget = aPanel->activeWidget();
const QList<ModuleBase_ModelWidget*>& aWidgets = aPanel->modelWidgets();
QList<ModuleBase_ModelWidget*>::const_iterator anIt = aWidgets.begin(), aLast = aWidgets.end();
(myWorkshop->currentOperation());
if (aFOperation && PartSet_SketcherMgr::isNestedSketchOperation(aFOperation)) {
- aFOperation->setEditOperation(false);
+ aFOperation->setEditOperation(true/*, false*/);
workshop()->operationMgr()->updateApplyOfOperations();
createInternalFeature();
ModuleBase_ModelWidget* aPreviousAttributeWidget = 0;
QList<ModuleBase_ModelWidget*> aWidgets = aPanel->modelWidgets();
for (int i = 0, aNb = aWidgets.size(); i < aNb && !aPreviousAttributeWidget; i++) {
- if (aWidgets[i]->attributeID() == thePreviousAttributeID)
+ if (aWidgets[i]->attributeID() == thePreviousAttributeID) {
+ /// workaround for the same attributes used in different stacked widgets(attribute types)
+ if (ModuleBase_ToolBox::isOffToolBoxParent(aWidgets[i]))
+ continue;
aPreviousAttributeWidget = aWidgets[i];
+ }
}
// If the current widget is a selector, do nothing, it processes the mouse press
- if (aPreviousAttributeWidget && !aPreviousAttributeWidget->isViewerSelector()) {
- aPreviousAttributeWidget->focusTo();
- aPreviousAttributeWidget->selectContent();
+ if (aPreviousAttributeWidget) {
+ if (!aPreviousAttributeWidget->isViewerSelector()) {
+ aPreviousAttributeWidget->focusTo();
+ aPreviousAttributeWidget->selectContent();
+ }
+ else {
+ // in case of shape multi selector, the widget does not lose focus by filling
+ // like it is in shape selector. So, if enter is pressed, the multi shape selector
+ // control should be deactivated. The focus is moved to Apply button and there
+ // should not be active control visualized in property panel
+ if (aPreviousAttributeWidget == aPanel->activeWidget()) {
+ aPanel->activateWidget(NULL, false);
+ }
+ // 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 = dynamic_cast<XGUI_PropertyPanel*>(aPanel)->findButton(PROP_PANEL_OK);
+ if (anOkBtn)
+ anOkBtn->setFocus(Qt::TabFocusReason);
+ }
}
}
}
if (aFOperation) {
myNoMoreWidgetsAttribute = "";
myIsFlagsBlocked = true;
+ FeaturePtr aPrevFeature = aFOperation->feature();
aFOperation->commit();
module()->launchOperation(aFOperation->id());
+ // allow the same attribute values in restarted operation
+ ModuleBase_OperationFeature* aCurrentOperation = dynamic_cast<ModuleBase_OperationFeature*>(
+ myWorkshop->currentOperation());
+ copyReetntrantAttributes(aPrevFeature, aCurrentOperation->feature());
+
myIsFlagsBlocked = false;
resetFlags();
// we should avoid processing of the signal about no more widgets attributes and
CompositeFeaturePtr aSketch = module()->sketchMgr()->activeSketch();
myInternalFeature = aSketch->addFeature(anOperationFeature->getKind());
+
+ bool isFeatureChanged = copyReetntrantAttributes(anOperationFeature, myInternalFeature);
XGUI_PropertyPanel* aPropertyPanel = dynamic_cast<XGUI_PropertyPanel*>
(aFOperation->propertyPanel());
QList<ModuleBase_ModelWidget*> aWidgets = aFactory.getModelWidgets();
foreach (ModuleBase_ModelWidget* aWidget, aWidgets) {
- aWidget->setFeature(myInternalFeature, true);
+ bool isStoreValue = !aFOperation->isEditOperation() &&
+ !aWidget->getDefaultValue().empty() &&
+ !aWidget->isComputedDefault();
+ aWidget->setFeature(myInternalFeature, isStoreValue);
+ if (!isStoreValue && isFeatureChanged)
+ aWidget->restoreValue();
}
+
ModuleBase_ModelWidget* aFirstWidget = ModuleBase_IPropertyPanel::findFirstAcceptingValueWidget
(aWidgets);
if (aFirstWidget)
}
}
+bool PartSet_SketcherReetntrantMgr::copyReetntrantAttributes(const FeaturePtr& theSourceFeature,
+ const FeaturePtr& theNewFeature)
+{
+ bool aChanged = false;
+ std::string aTypeAttributeId;
+ if (theSourceFeature->getKind() == SketchPlugin_Circle::ID()) {
+ aTypeAttributeId = SketchPlugin_Circle::CIRCLE_TYPE();
+ }
+ if (theSourceFeature->getKind() == SketchPlugin_Arc::ID()) {
+ aTypeAttributeId = SketchPlugin_Arc::ARC_TYPE();
+ }
+ if (!aTypeAttributeId.empty()) {
+ AttributeStringPtr aSourceFeatureTypeAttr = theSourceFeature->data()->string(aTypeAttributeId);
+ AttributeStringPtr aNewFeatureTypeAttr = theNewFeature->data()->string(aTypeAttributeId);
+ aNewFeatureTypeAttr->setValue(aSourceFeatureTypeAttr->value());
+ ModuleBase_Tools::flushUpdated(theNewFeature);
+ aChanged = true;
+ }
+ return aChanged;
+}
+
+bool PartSet_SketcherReetntrantMgr::isTangentArc(ModuleBase_Operation* theOperation)
+{
+ bool aTangentArc = false;
+ ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
+ (theOperation);
+ if (aFOperation && PartSet_SketcherMgr::isNestedSketchOperation(aFOperation)) {
+ FeaturePtr aFeature = aFOperation->feature();
+ if (aFeature.get() && aFeature->getKind() == SketchPlugin_Arc::ID()) {
+ AttributeStringPtr aTypeAttr = aFeature->data()->string(SketchPlugin_Arc::ARC_TYPE());
+ std::string anArcType = aTypeAttr.get() ? aTypeAttr->value() : "";
+ aTangentArc = anArcType == SketchPlugin_Arc::ARC_TYPE_TANGENT();
+ }
+ }
+ return aTangentArc;
+}
+
XGUI_Workshop* PartSet_SketcherReetntrantMgr::workshop() const
{
XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(myWorkshop);