1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
3 #include "PartSet_SketcherReetntrantMgr.h"
4 #include "PartSet_Module.h"
5 #include "PartSet_SketcherMgr.h"
6 #include "PartSet_WidgetPoint2d.h"
8 #include "ModelAPI_Session.h"
9 #include "ModelAPI_AttributeString.h"
10 #include "ModelAPI_AttributeRefAttr.h"
12 #include "GeomDataAPI_Point2D.h"
14 #include <ModuleBase_IPropertyPanel.h>
15 #include <ModuleBase_OperationFeature.h>
16 #include <ModuleBase_ModelWidget.h>
17 #include <ModuleBase_ViewerPrs.h>
18 #include <ModuleBase_WidgetSelector.h>
19 #include <ModuleBase_PageWidget.h>
20 #include <ModuleBase_PageBase.h>
21 #include <ModuleBase_WidgetFactory.h>
22 #include <ModuleBase_OperationDescription.h>
23 #include "ModuleBase_ToolBox.h"
24 #include "ModuleBase_ISelection.h"
26 #include <SketchPlugin_Feature.h>
27 #include <SketchPlugin_Line.h>
28 #include <SketchPlugin_Arc.h>
29 #include <SketchPlugin_Circle.h>
30 #include <SketchPlugin_Point.h>
32 #include <XGUI_Workshop.h>
33 #include <XGUI_ModuleConnector.h>
34 #include <XGUI_OperationMgr.h>
35 #include <XGUI_PropertyPanel.h>
36 #include <XGUI_ErrorMgr.h>
38 #include <QToolButton>
40 PartSet_SketcherReetntrantMgr::PartSet_SketcherReetntrantMgr(ModuleBase_IWorkshop* theWorkshop)
41 : QObject(theWorkshop),
42 myWorkshop(theWorkshop),
43 myRestartingMode(RM_None),
44 myIsFlagsBlocked(false),
45 myIsInternalEditOperation(false),
46 myNoMoreWidgetsAttribute("")
50 PartSet_SketcherReetntrantMgr::~PartSet_SketcherReetntrantMgr()
54 ModuleBase_ModelWidget* PartSet_SketcherReetntrantMgr::internalActiveWidget() const
56 ModuleBase_ModelWidget* aWidget = 0;
60 ModuleBase_Operation* anOperation = myWorkshop->currentOperation();
62 ModuleBase_IPropertyPanel* aPanel = anOperation->propertyPanel();
63 if (aPanel) { // check for case when the operation is started but property panel is not filled
64 ModuleBase_ModelWidget* anActiveWidget = aPanel->activeWidget();
65 if (myIsInternalEditOperation && (!anActiveWidget || !anActiveWidget->isViewerSelector()))
66 aWidget = myInternalActiveWidget;
72 bool PartSet_SketcherReetntrantMgr::isInternalEditActive() const
74 return myIsInternalEditOperation;
77 void PartSet_SketcherReetntrantMgr::updateInternalEditActiveState()
79 if (myIsInternalEditOperation) {
80 ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
81 (myWorkshop->currentOperation());
83 FeaturePtr aFeature = aFOperation->feature();
84 QString anError = myWorkshop->module()->getFeatureError(aFeature);
85 // stop started internal edit operation as soon as the operation becomes invalid
86 // it is especially important for the sketch tangent arc feature
87 if (!anError.isEmpty()) {
88 aFOperation->setEditOperation(false);
89 //workshop()->operationMgr()->updateApplyOfOperations();
90 myIsInternalEditOperation = false;
91 updateAcceptAllAction();
97 bool PartSet_SketcherReetntrantMgr::operationCommitted(ModuleBase_Operation* theOperation)
99 bool aProcessed = false;
103 aProcessed = myIsInternalEditOperation;
109 void PartSet_SketcherReetntrantMgr::operationStarted(ModuleBase_Operation* theOperation)
114 if (myPreviousFeature.get() && myRestartingMode == RM_LastFeatureUsed) {
115 ModuleBase_OperationFeature* aCurrentOperation = dynamic_cast<ModuleBase_OperationFeature*>(
116 myWorkshop->currentOperation());
117 CompositeFeaturePtr aSketch = module()->sketchMgr()->activeSketch();
118 copyReetntrantAttributes(myPreviousFeature, aCurrentOperation->feature(), aSketch);
123 void PartSet_SketcherReetntrantMgr::operationAborted(ModuleBase_Operation* theOperation)
131 bool PartSet_SketcherReetntrantMgr::processMouseMoved(ModuleBase_IViewWindow* theWnd,
132 QMouseEvent* theEvent)
134 bool aProcessed = false;
138 if (myIsInternalEditOperation) {
139 ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
140 (myWorkshop->currentOperation());
141 FeaturePtr aLastFeature = myRestartingMode == RM_LastFeatureUsed ? aFOperation->feature()
144 ModuleBase_ModelWidget* anActiveWidget = module()->activeWidget();
145 ModuleBase_IPropertyPanel* aPanel = myWorkshop->currentOperation()->propertyPanel();
147 FeaturePtr aCurrentFeature = aFOperation->feature();
148 bool isLineFeature = false, isArcFeature = false;
149 std::string anAttributeOnStart;
150 if (aCurrentFeature->getKind() == SketchPlugin_Line::ID()) {
151 anAttributeOnStart = SketchPlugin_Line::START_ID();
152 isLineFeature = anActiveWidget->attributeID() == anAttributeOnStart;
154 else if (isTangentArc(aFOperation, module()->sketchMgr()->activeSketch())) {
155 anAttributeOnStart = SketchPlugin_Arc::TANGENT_POINT_ID();
156 isArcFeature = anActiveWidget->attributeID() == anAttributeOnStart;
158 bool aCanBeActivatedByMove = isLineFeature || isArcFeature;
159 if (aCanBeActivatedByMove) {
160 myPreviousFeature = aFOperation->feature();
162 myPreviousFeature = FeaturePtr();
164 anActiveWidget = module()->activeWidget();
165 aCurrentFeature = anActiveWidget->feature();
167 if (anActiveWidget->attributeID() == anAttributeOnStart) {
168 // it was not deactivated by preselection processing
169 aPanel->activateNextWidget(anActiveWidget);
172 // processing mouse move in active widget of restarted operation
173 ModuleBase_ModelWidget* anActiveWidget = module()->activeWidget();
174 PartSet_MouseProcessor* aProcessor = dynamic_cast<PartSet_MouseProcessor*>(anActiveWidget);
176 aProcessor->mouseMoved(theWnd, theEvent);
183 bool PartSet_SketcherReetntrantMgr::processMousePressed(ModuleBase_IViewWindow* /* theWnd*/,
184 QMouseEvent* /* theEvent*/)
186 return isActiveMgr() && myIsInternalEditOperation;
189 bool PartSet_SketcherReetntrantMgr::processMouseReleased(ModuleBase_IViewWindow* theWnd,
190 QMouseEvent* theEvent)
192 bool aProcessed = false;
196 if (myIsInternalEditOperation) {
197 ModuleBase_Operation* anOperation = myWorkshop->currentOperation();
198 ModuleBase_IPropertyPanel* aPanel = anOperation->propertyPanel();
200 ModuleBase_ModelWidget* anActiveWidget = aPanel->activeWidget();
201 if (!anActiveWidget || !anActiveWidget->isViewerSelector()) {
203 // block of viewer update
204 // we need to block update content of the viewer because of Sketch Point feature
205 // in activate() the value of the point is initialized and it can be displayed
206 // but the default value is [0, 0]. So, we block update viewer contentent until
207 // onMouseRelease happens, which correct the point position
208 ModuleBase_Tools::blockUpdateViewer(true);
210 ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
211 (myWorkshop->currentOperation());
212 myPreviousFeature = aFOperation->feature();
214 /// selection should be obtained from workshop before ask if the operation can be started as
215 /// the canStartOperation method performs commit/abort of previous operation. Sometimes commit/abort
216 /// may cause selection clear(Sketch operation) as a result it will be lost and is not used for preselection.
217 ModuleBase_ISelection* aSelection = myWorkshop->selection();
218 QList<ModuleBase_ViewerPrsPtr> aPreSelected = aSelection->getSelected(ModuleBase_ISelection::AllControls);
221 myPreviousFeature = FeaturePtr();
224 // fill the first widget by the mouse event point
225 // if the active widget is not the first, it means that the restarted operation is filled by
226 // the current preselection.
227 PartSet_WidgetPoint2D* aPoint2DWdg = dynamic_cast<PartSet_WidgetPoint2D*>(module()->activeWidget());
228 ModuleBase_ModelWidget* aFirstWidget = aPanel->findFirstAcceptingValueWidget();
229 if (aPoint2DWdg && aPoint2DWdg == aFirstWidget) {
230 if (!aPreSelected.empty())
231 aPoint2DWdg->setPreSelection(aPreSelected.front());
232 aPoint2DWdg->mouseReleased(theWnd, theEvent);
233 if (!aPreSelected.empty())
234 aPoint2DWdg->setPreSelection(ModuleBase_ViewerPrsPtr());
236 // unblock viewer update
237 ModuleBase_Tools::blockUpdateViewer(false);
244 void PartSet_SketcherReetntrantMgr::onWidgetActivated()
248 if (!myIsInternalEditOperation)
251 PartSet_Module* aModule = module();
252 ModuleBase_ModelWidget* aFirstWidget = aModule->activeWidget();
253 ModuleBase_IPropertyPanel* aPanel = aModule->currentOperation()->propertyPanel();
254 if (aFirstWidget != aPanel->activeWidget()) {
255 ModuleBase_WidgetSelector* aWSelector = dynamic_cast<ModuleBase_WidgetSelector*>(aFirstWidget);
257 aWSelector->activateSelectionAndFilters(true);
261 void PartSet_SketcherReetntrantMgr::onNoMoreWidgets(const std::string& thePreviousAttributeID)
266 // we should avoid processing of the signal about no more widgets attributes and
267 // do this after the restart operaion is finished if it was called
268 // onNoMoreWidgets depends on myIsFlagsBlocked and fill myNoMoreWidgetsAttribute
269 // if it should be called after restart
270 if (myIsFlagsBlocked) {
271 myNoMoreWidgetsAttribute = thePreviousAttributeID;
275 ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
276 (myWorkshop->currentOperation());
277 if (!myWorkshop->module()->getFeatureError(aFOperation->feature()).isEmpty())
280 if (aFOperation && module()->sketchMgr()->isNestedSketchOperation(aFOperation)) {
281 bool isStarted = false;
282 if (!module()->sketchMgr()->sketchSolverError()) {
283 if (myRestartingMode != RM_Forbided) {
284 myRestartingMode = RM_LastFeatureUsed;
285 isStarted = startInternalEdit(thePreviousAttributeID);
289 aFOperation->commit();
293 bool PartSet_SketcherReetntrantMgr::processEnter(const std::string& thePreviousAttributeID)
300 // empty previous attribute means that the Apply/Ok button has focus and the enter
301 // should not lead to start edition mode of the previous operation
302 if (thePreviousAttributeID.empty())
305 ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
306 (myWorkshop->currentOperation());
307 if (!myWorkshop->module()->getFeatureError(aFOperation->feature()).isEmpty())
310 bool isSketchSolverError = module()->sketchMgr()->sketchSolverError();
312 if (!isSketchSolverError) {
313 myRestartingMode = RM_EmptyFeatureUsed;
314 isDone = startInternalEdit(thePreviousAttributeID);
320 void PartSet_SketcherReetntrantMgr::onVertexSelected()
325 ModuleBase_Operation* anOperation = myWorkshop->currentOperation();
326 std::string anOperationId = anOperation->id().toStdString();
327 if (anOperationId == SketchPlugin_Line::ID() ||
328 isTangentArc(anOperation, module()->sketchMgr()->activeSketch())) {
329 /// If last line finished on vertex the lines creation sequence has to be break
330 ModuleBase_IPropertyPanel* aPanel = anOperation->propertyPanel();
331 ModuleBase_ModelWidget* anActiveWidget = aPanel->activeWidget();
332 const QList<ModuleBase_ModelWidget*>& aWidgets = aPanel->modelWidgets();
333 QList<ModuleBase_ModelWidget*>::const_iterator anIt = aWidgets.begin(), aLast = aWidgets.end();
334 bool aFoundWidget = false;
335 bool aFoundObligatory = false;
336 for (; anIt != aLast && !aFoundObligatory; anIt++) {
338 aFoundWidget = *anIt == anActiveWidget;
340 aFoundObligatory = (*anIt)->isObligatory();
342 if (!aFoundObligatory)
343 myRestartingMode = RM_Forbided;
347 void PartSet_SketcherReetntrantMgr::onBeforeStopped()
349 if (!isActiveMgr() || !myIsInternalEditOperation)
352 beforeStopInternalEdit();
355 bool PartSet_SketcherReetntrantMgr::canBeCommittedByPreselection()
357 return !isActiveMgr() || myRestartingMode == RM_None;
360 bool PartSet_SketcherReetntrantMgr::isInternalEditStarted() const
362 return myIsInternalEditOperation;
365 bool PartSet_SketcherReetntrantMgr::isActiveMgr() const
367 ModuleBase_Operation* aCurrentOperation = myWorkshop->currentOperation();
369 bool anActive = PartSet_SketcherMgr::isSketchOperation(aCurrentOperation);
371 anActive = module()->sketchMgr()->isNestedSketchOperation(aCurrentOperation);
372 if (anActive) { // the manager is not active when the current operation is a usual Edit
373 ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
374 (myWorkshop->currentOperation());
375 if (aFOperation->isEditOperation())
376 anActive = myIsInternalEditOperation;
382 bool PartSet_SketcherReetntrantMgr::startInternalEdit(const std::string& thePreviousAttributeID)
385 /// this is workaround for ModuleBase_WidgetEditor, used in SALOME mode. Sometimes key enter
386 /// event comes two times, so we should not start another internal edit operation
387 /// the Apply button becomes disabled becase the second additional internal feature is created
388 if (myIsInternalEditOperation)
391 ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
392 (myWorkshop->currentOperation());
394 if (aFOperation && module()->sketchMgr()->isNestedSketchOperation(aFOperation)) {
395 aFOperation->setEditOperation(true/*, false*/);
396 createInternalFeature();
398 myIsInternalEditOperation = true;
399 updateAcceptAllAction();
402 connect(aFOperation, SIGNAL(beforeCommitted()), this, SLOT(onBeforeStopped()));
403 connect(aFOperation, SIGNAL(beforeAborted()), this, SLOT(onBeforeStopped()));
405 // activate selection filters of the first widget in the viewer
408 // activate the last active widget in the Property Panel
409 if (!thePreviousAttributeID.empty()) {
410 ModuleBase_Operation* anEditOperation = module()->currentOperation();
411 if (anEditOperation) {
412 ModuleBase_IPropertyPanel* aPanel = aFOperation->propertyPanel();
413 ModuleBase_ModelWidget* aPreviousAttributeWidget = 0;
414 QList<ModuleBase_ModelWidget*> aWidgets = aPanel->modelWidgets();
415 for (int i = 0, aNb = aWidgets.size(); i < aNb && !aPreviousAttributeWidget; i++) {
416 if (aWidgets[i]->attributeID() == thePreviousAttributeID) {
417 /// workaround for the same attributes used in different stacked widgets(attribute types)
418 if (ModuleBase_ToolBox::isOffToolBoxParent(aWidgets[i]))
420 aPreviousAttributeWidget = aWidgets[i];
423 // If the current widget is a selector, do nothing, it processes the mouse press
424 if (aPreviousAttributeWidget) {
425 if (!aPreviousAttributeWidget->isViewerSelector()) {
426 aPreviousAttributeWidget->focusTo();
427 aPreviousAttributeWidget->selectContent();
430 // in case of shape multi selector, the widget does not lose focus by filling
431 // like it is in shape selector. So, if enter is pressed, the multi shape selector
432 // control should be deactivated. The focus is moved to Apply button and there
433 // should not be active control visualized in property panel
434 if (aPreviousAttributeWidget == aPanel->activeWidget()) {
435 aPanel->activateWidget(NULL, false);
437 // if there is no the next widget to be automatically activated, the Ok button in property
438 // panel should accept the focus(example is parallel constraint on sketch lines)
439 QToolButton* anOkBtn = dynamic_cast<XGUI_PropertyPanel*>(aPanel)->findButton(PROP_PANEL_OK);
441 anOkBtn->setFocus(Qt::TabFocusReason);
448 module()->sketchMgr()->clearClickedFlags();
453 void PartSet_SketcherReetntrantMgr::beforeStopInternalEdit()
455 ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
456 (myWorkshop->currentOperation());
458 disconnect(aFOperation, SIGNAL(beforeCommitted()), this, SLOT(onBeforeStopped()));
459 disconnect(aFOperation, SIGNAL(beforeAborted()), this, SLOT(onBeforeStopped()));
462 deleteInternalFeature();
465 void PartSet_SketcherReetntrantMgr::restartOperation()
467 if (myIsInternalEditOperation) {
468 ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>(
469 myWorkshop->currentOperation());
471 myNoMoreWidgetsAttribute = "";
472 myIsFlagsBlocked = true;
473 module()->launchOperation(aFOperation->id());
474 myIsFlagsBlocked = false;
476 // we should avoid processing of the signal about no more widgets attributes and
477 // do this after the restart operaion is finished if it was called
478 // onNoMoreWidgets depends on myIsFlagsBlocked and fill myNoMoreWidgetsAttribute
479 // if it should be called after restart
480 if (!myNoMoreWidgetsAttribute.empty()) {
481 onNoMoreWidgets(myNoMoreWidgetsAttribute);
482 myNoMoreWidgetsAttribute = "";
488 void PartSet_SketcherReetntrantMgr::createInternalFeature()
490 ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
491 (myWorkshop->currentOperation());
493 if (aFOperation && module()->sketchMgr()->isNestedSketchOperation(aFOperation)) {
494 FeaturePtr anOperationFeature = aFOperation->feature();
496 CompositeFeaturePtr aSketch = module()->sketchMgr()->activeSketch();
497 myInternalFeature = aSketch->addFeature(anOperationFeature->getKind());
499 bool isFeatureChanged = copyReetntrantAttributes(anOperationFeature, myInternalFeature,
501 XGUI_PropertyPanel* aPropertyPanel = dynamic_cast<XGUI_PropertyPanel*>
502 (aFOperation->propertyPanel());
504 myInternalWidget = new QWidget(aPropertyPanel->contentWidget()->pageWidget());
505 myInternalWidget->setVisible(false);
507 ModuleBase_PageWidget* anInternalPage = new ModuleBase_PageWidget(myInternalWidget);
509 QString aXmlRepr = aFOperation->getDescription()->xmlRepresentation();
510 ModuleBase_WidgetFactory aFactory(aXmlRepr.toStdString(), myWorkshop);
512 aFactory.createWidget(anInternalPage);
513 QList<ModuleBase_ModelWidget*> aWidgets = aFactory.getModelWidgets();
515 foreach (ModuleBase_ModelWidget* aWidget, aWidgets) {
516 bool isStoreValue = !aFOperation->isEditOperation() &&
517 !aWidget->getDefaultValue().empty() &&
518 !aWidget->isComputedDefault();
519 aWidget->setFeature(myInternalFeature, isStoreValue);
520 if (!isStoreValue && isFeatureChanged)
521 aWidget->restoreValue();
524 ModuleBase_ModelWidget* aFirstWidget = ModuleBase_IPropertyPanel::findFirstAcceptingValueWidget
527 myInternalActiveWidget = aFirstWidget;
531 void PartSet_SketcherReetntrantMgr::deleteInternalFeature()
533 if (myInternalActiveWidget) {
534 ModuleBase_WidgetSelector* aWSelector = dynamic_cast<ModuleBase_WidgetSelector*>(myInternalActiveWidget);
536 aWSelector->activateSelectionAndFilters(false);
537 myInternalActiveWidget = 0;
539 delete myInternalWidget;
540 myInternalWidget = 0;
542 QObjectPtrList anObjects;
543 anObjects.append(myInternalFeature);
544 workshop()->deleteFeatures(anObjects);
545 myInternalFeature = FeaturePtr();
548 void PartSet_SketcherReetntrantMgr::resetFlags()
550 if (!myIsFlagsBlocked) {
551 myIsInternalEditOperation = false;
552 updateAcceptAllAction();
553 myRestartingMode = RM_None;
557 bool PartSet_SketcherReetntrantMgr::copyReetntrantAttributes(const FeaturePtr& theSourceFeature,
558 const FeaturePtr& theNewFeature,
559 const CompositeFeaturePtr& theSketch,
560 const bool isTemporary)
562 bool aChanged = false;
563 if (!theSourceFeature.get() || !theSourceFeature->data().get() ||
564 !theSourceFeature->data()->isValid())
567 std::string aFeatureKind = theSourceFeature->getKind();
568 if (aFeatureKind == SketchPlugin_Line::ID()) {
569 // Initialize new line with first point equal to end of previous
570 std::shared_ptr<ModelAPI_Data> aSFData = theSourceFeature->data();
571 std::shared_ptr<GeomDataAPI_Point2D> aSPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
572 aSFData->attribute(SketchPlugin_Line::END_ID()));
573 std::shared_ptr<ModelAPI_Data> aNFData = theNewFeature->data();
574 std::shared_ptr<GeomDataAPI_Point2D> aNPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
575 aNFData->attribute(SketchPlugin_Line::START_ID()));
576 aNPoint->setValue(aSPoint->x(), aSPoint->y());
577 PartSet_Tools::createConstraint(theSketch, aSPoint, aNPoint);
579 aNPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
580 aSFData->attribute(SketchPlugin_Line::END_ID()));
581 aNPoint->setValue(aSPoint->x(), aSPoint->y());
583 else if (aFeatureKind == SketchPlugin_Circle::ID()) {
585 std::string aTypeAttributeId = SketchPlugin_Circle::CIRCLE_TYPE();
586 AttributeStringPtr aSourceFeatureTypeAttr = theSourceFeature->data()->string(aTypeAttributeId);
587 AttributeStringPtr aNewFeatureTypeAttr = theNewFeature->data()->string(aTypeAttributeId);
588 aNewFeatureTypeAttr->setValue(aSourceFeatureTypeAttr->value());
589 //ModuleBase_Tools::flushUpdated(theNewFeature);
592 else if (aFeatureKind == SketchPlugin_Arc::ID()) {
594 std::string aTypeAttributeId = SketchPlugin_Arc::ARC_TYPE();
595 AttributeStringPtr aSourceFeatureTypeAttr = theSourceFeature->data()->string(aTypeAttributeId);
596 AttributeStringPtr aNewFeatureTypeAttr = theNewFeature->data()->string(aTypeAttributeId);
597 aNewFeatureTypeAttr->setValue(aSourceFeatureTypeAttr->value());
599 // if the arc is tangent, set coincidence to end point of the previous arc
600 std::string anArcType = aSourceFeatureTypeAttr->value();
601 if (anArcType == SketchPlugin_Arc::ARC_TYPE_TANGENT()) {
602 // get the last point of the previuos arc feature(geom point 2d)
603 std::shared_ptr<ModelAPI_Data> aSData = theSourceFeature->data();
604 std::shared_ptr<GeomDataAPI_Point2D> aSPointAttr =
605 std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
606 aSData->attribute(SketchPlugin_Arc::END_ID()));
607 // get point attribute on the current feature
608 AttributeRefAttrPtr aTangentPointAttr = theNewFeature->data()->refattr(
609 SketchPlugin_Arc::TANGENT_POINT_ID());
610 aTangentPointAttr->setAttr(aSPointAttr);
612 std::shared_ptr<GeomDataAPI_Point2D> aNPointAttr =
613 std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
614 theNewFeature->data()->attribute(SketchPlugin_Arc::END_ID()));
615 aNPointAttr->setValue(aSPointAttr->x(), aSPointAttr->y());
618 //ModuleBase_Tools::flushUpdated(theNewFeature);
624 bool PartSet_SketcherReetntrantMgr::isTangentArc(ModuleBase_Operation* theOperation,
625 const CompositeFeaturePtr& /*theSketch*/) const
627 bool aTangentArc = false;
628 ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
630 if (aFOperation && module()->sketchMgr()->isNestedSketchOperation(aFOperation)) {
631 FeaturePtr aFeature = aFOperation->feature();
632 if (aFeature.get() && aFeature->getKind() == SketchPlugin_Arc::ID()) {
633 AttributeStringPtr aTypeAttr = aFeature->data()->string(SketchPlugin_Arc::ARC_TYPE());
634 std::string anArcType = aTypeAttr.get() ? aTypeAttr->value() : "";
635 aTangentArc = anArcType == SketchPlugin_Arc::ARC_TYPE_TANGENT();
641 void PartSet_SketcherReetntrantMgr::updateAcceptAllAction()
643 CompositeFeaturePtr aSketch = module()->sketchMgr()->activeSketch();
645 workshop()->errorMgr()->updateAcceptAllAction(aSketch);
648 XGUI_Workshop* PartSet_SketcherReetntrantMgr::workshop() const
650 XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(myWorkshop);
651 return aConnector->workshop();
654 PartSet_Module* PartSet_SketcherReetntrantMgr::module() const
656 return dynamic_cast<PartSet_Module*>(myWorkshop->module());