X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FPartSet%2FPartSet_SketcherReetntrantMgr.cpp;h=cc5f7602aa78a45708a57cda6975a04ac168cdfb;hb=c8ab29e531ee03054976a7606076f2c4ee1d9f6b;hp=5e45abfee7253fc32f55e81d05e6249d43b70d1c;hpb=a6d1e8be5db1d94fdee39c412b8393d74bfcca2f;p=modules%2Fshaper.git diff --git a/src/PartSet/PartSet_SketcherReetntrantMgr.cpp b/src/PartSet/PartSet_SketcherReetntrantMgr.cpp index 5e45abfee..cc5f7602a 100755 --- a/src/PartSet/PartSet_SketcherReetntrantMgr.cpp +++ b/src/PartSet/PartSet_SketcherReetntrantMgr.cpp @@ -6,6 +6,10 @@ #include "PartSet_WidgetPoint2d.h" #include "ModelAPI_Session.h" +#include "ModelAPI_AttributeString.h" +#include "ModelAPI_AttributeRefAttr.h" + +#include "GeomDataAPI_Point2D.h" #include #include @@ -16,21 +20,27 @@ #include #include #include +#include "ModuleBase_ToolBox.h" #include #include +#include +#include #include #include #include #include +#include + PartSet_SketcherReetntrantMgr::PartSet_SketcherReetntrantMgr(ModuleBase_IWorkshop* theWorkshop) : QObject(theWorkshop), myWorkshop(theWorkshop), myRestartingMode(RM_None), myIsFlagsBlocked(false), - myIsInternalEditOperation(false) + myIsInternalEditOperation(false), + myNoMoreWidgetsAttribute("") { } @@ -44,9 +54,9 @@ ModuleBase_ModelWidget* PartSet_SketcherReetntrantMgr::internalActiveWidget() co 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; @@ -59,6 +69,26 @@ bool PartSet_SketcherReetntrantMgr::isInternalEditActive() const return myIsInternalEditOperation; } +void PartSet_SketcherReetntrantMgr::updateInternalEditActiveState() +{ + if (myIsInternalEditOperation) { + ModuleBase_OperationFeature* aFOperation = dynamic_cast + (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; @@ -95,24 +125,56 @@ bool PartSet_SketcherReetntrantMgr::processMouseMoved(ModuleBase_IViewWindow* /* return aProcessed; if (myIsInternalEditOperation) { - PartSet_WidgetPoint2D* aPoint2DWdg = dynamic_cast(module()->activeWidget()); - if (aPoint2DWdg && aPoint2DWdg->canBeActivatedByMove()) { - ModuleBase_OperationFeature* aFOperation = dynamic_cast + ModuleBase_OperationFeature* aFOperation = dynamic_cast (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(aPanel->activeWidget()); - if (aPoint2DWdg && aPoint2DWdg->canBeActivatedByMove()) { - QList 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(anActiveWidget); + if (aPoint2DWdg) { // line, start point should be equal last point of the last feature line + QList aSelection; + aSelection.append(std::shared_ptr( + 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 aData = aLastFeature->data(); + std::shared_ptr aPointAttr = + std::dynamic_pointer_cast( + 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; @@ -137,6 +199,14 @@ bool PartSet_SketcherReetntrantMgr::processMouseReleased(ModuleBase_IViewWindow* 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; @@ -148,6 +218,8 @@ bool PartSet_SketcherReetntrantMgr::processMouseReleased(ModuleBase_IViewWindow* if (aPoint2DWdg && aPoint2DWdg == aFirstWidget) { aPoint2DWdg->onMouseRelease(theWnd, theEvent); } + // unblock viewer update + ModuleBase_Tools::blockUpdateViewer(false); } } @@ -176,23 +248,31 @@ void PartSet_SketcherReetntrantMgr::onNoMoreWidgets(const std::string& thePrevio if (!isActiveMgr()) return; + // we should avoid processing of the signal about no more widgets attributes and + // do this after the restart operaion is finished if it was called + // onNoMoreWidgets depends on myIsFlagsBlocked and fill myNoMoreWidgetsAttribute + // if it should be called after restart + if (myIsFlagsBlocked) { + myNoMoreWidgetsAttribute = thePreviousAttributeID; + return; + } + ModuleBase_OperationFeature* aFOperation = dynamic_cast (myWorkshop->currentOperation()); if (!myWorkshop->module()->getFeatureError(aFOperation->feature()).isEmpty()) return; - bool isStarted = false; - bool isSketchSolverError = module()->sketchMgr()->sketchSolverError(); - if (!isSketchSolverError && - aFOperation && PartSet_SketcherMgr::isNestedSketchOperation(aFOperation)) { - if (myRestartingMode != RM_Forbided) { - myRestartingMode = RM_LastFeatureUsed; - isStarted = startInternalEdit(thePreviousAttributeID); + if (aFOperation && PartSet_SketcherMgr::isNestedSketchOperation(aFOperation)) { + bool isStarted = false; + if (!module()->sketchMgr()->sketchSolverError()) { + if (myRestartingMode != RM_Forbided) { + myRestartingMode = RM_LastFeatureUsed; + isStarted = startInternalEdit(thePreviousAttributeID); + } } + if (!isStarted) + aFOperation->commit(); } - - if (!isStarted) - aFOperation->commit(); } bool PartSet_SketcherReetntrantMgr::processEnter(const std::string& thePreviousAttributeID) @@ -202,12 +282,18 @@ bool PartSet_SketcherReetntrantMgr::processEnter(const std::string& thePreviousA 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 (myWorkshop->currentOperation()); if (!myWorkshop->module()->getFeatureError(aFOperation->feature()).isEmpty()) return isDone; bool isSketchSolverError = module()->sketchMgr()->sketchSolverError(); + if (!isSketchSolverError) { myRestartingMode = RM_EmptyFeatureUsed; isDone = startInternalEdit(thePreviousAttributeID); @@ -221,10 +307,11 @@ void PartSet_SketcherReetntrantMgr::onVertexSelected() 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& aWidgets = aPanel->modelWidgets(); QList::const_iterator anIt = aWidgets.begin(), aLast = aWidgets.end(); @@ -284,7 +371,7 @@ bool PartSet_SketcherReetntrantMgr::startInternalEdit(const std::string& thePrev (myWorkshop->currentOperation()); if (aFOperation && PartSet_SketcherMgr::isNestedSketchOperation(aFOperation)) { - aFOperation->setEditOperation(false); + aFOperation->setEditOperation(true/*, false*/); workshop()->operationMgr()->updateApplyOfOperations(); createInternalFeature(); @@ -305,13 +392,33 @@ bool PartSet_SketcherReetntrantMgr::startInternalEdit(const std::string& thePrev ModuleBase_ModelWidget* aPreviousAttributeWidget = 0; QList 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(aPanel)->findButton(PROP_PANEL_OK); + if (anOkBtn) + anOkBtn->setFocus(Qt::TabFocusReason); + } } } } @@ -340,11 +447,26 @@ void PartSet_SketcherReetntrantMgr::restartOperation() ModuleBase_OperationFeature* aFOperation = dynamic_cast( myWorkshop->currentOperation()); 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( + myWorkshop->currentOperation()); + copyReetntrantAttributes(aPrevFeature, aCurrentOperation->feature()); + myIsFlagsBlocked = false; resetFlags(); + // we should avoid processing of the signal about no more widgets attributes and + // do this after the restart operaion is finished if it was called + // onNoMoreWidgets depends on myIsFlagsBlocked and fill myNoMoreWidgetsAttribute + // if it should be called after restart + if (!myNoMoreWidgetsAttribute.empty()) { + onNoMoreWidgets(myNoMoreWidgetsAttribute); + myNoMoreWidgetsAttribute = ""; + } } } } @@ -359,6 +481,8 @@ void PartSet_SketcherReetntrantMgr::createInternalFeature() CompositeFeaturePtr aSketch = module()->sketchMgr()->activeSketch(); myInternalFeature = aSketch->addFeature(anOperationFeature->getKind()); + + bool isFeatureChanged = copyReetntrantAttributes(anOperationFeature, myInternalFeature); XGUI_PropertyPanel* aPropertyPanel = dynamic_cast (aFOperation->propertyPanel()); @@ -374,8 +498,14 @@ void PartSet_SketcherReetntrantMgr::createInternalFeature() QList 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) @@ -407,6 +537,43 @@ void PartSet_SketcherReetntrantMgr::resetFlags() } } +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 + (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(myWorkshop);