X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FPartSet%2FPartSet_SketcherMgr.cpp;h=b4cf246eac2e7827d57f60dcd9e7cbe781d99850;hb=857b1f72d9703c46c6c8c9bb239821d314344c86;hp=6a8c084db84ed0be24b157c488aaa3546e502622;hpb=7b40e745dd80b0af027783d1d064ba84f44e97bb;p=modules%2Fshaper.git diff --git a/src/PartSet/PartSet_SketcherMgr.cpp b/src/PartSet/PartSet_SketcherMgr.cpp index 6a8c084db..b4cf246ea 100644 --- a/src/PartSet/PartSet_SketcherMgr.cpp +++ b/src/PartSet/PartSet_SketcherMgr.cpp @@ -9,8 +9,7 @@ #include "PartSet_WidgetPoint2d.h" #include "PartSet_WidgetPoint2dDistance.h" #include "PartSet_Tools.h" - -#include +#include "PartSet_WidgetSketchLabel.h" #include #include @@ -18,20 +17,21 @@ #include #include #include -#include #include #include #include +#include -#include - +#include +#include #include #include #include +#include #include -#include -#include +#include #include +#include #include @@ -53,19 +53,29 @@ #include #include #include +#include +#include +#include +#include +#include + +#include #include #include //#include -//#include +#include #include #include +#include #include #include +//#define DEBUG_DO_NOT_BY_ENTER +//#define DEBUG_MOUSE_OVER_WINDOW_FLAGS /// Returns list of unique objects by sum of objects from List1 and List2 /*QList getSumList(const QList& theList1, @@ -83,9 +93,14 @@ return aRes; }*/ -void fillFeature2Attribute(const QList& theList, - QMap >& theFeature2AttributeMap, - const FeaturePtr theSketch) +// Fills the list of features the list of selected presentations. +// \param theList a list of selected presentations +// \param theSketch a sketch to project a vertex shape of a presentation to the plane +// and find the corresponded attribute +// \param theFeatureList an output list of features +void fillFeatureList(const QList& theList, + const FeaturePtr theSketch, + QList& theFeatureList) { QList aRes; @@ -95,34 +110,51 @@ void fillFeature2Attribute(const QList& theList, { ModuleBase_ViewerPrs aPrs = *anIt; FeaturePtr aFeature = ModelAPI_Feature::feature(aPrs.object()); - if (aFeature.get() == NULL) - continue; + if (aFeature.get() && !theFeatureList.contains(aFeature)) + theFeatureList.append(aFeature); + } +} - QList anAttributes; - if (theFeature2AttributeMap.contains(aFeature)) { - anAttributes = theFeature2AttributeMap[aFeature]; +/// Fills attribute and result lists by the selected owner. In case if the attribute is found, +/// by the owner shape, it is put to the list. Otherwise if type of owner shape is edge, put the function +/// result as is to the list of results. +/// \param theOwner a viewer selected owner +/// \param theFeature a feature, where the attribute is searched +/// \param theSketch a current sketch +/// \param theSelectedAttribute an output list of attributes +/// \param theSelectedResults an output list of edge results +void getAttributesOrResults(const Handle(SelectMgr_EntityOwner)& theOwner, + const FeaturePtr& theFeature, const FeaturePtr& theSketch, + const ResultPtr& theResult, + std::set& aSelectedAttributes, + std::set& aSelectedResults) +{ + Handle(StdSelect_BRepOwner) aBRepOwner = Handle(StdSelect_BRepOwner)::DownCast(theOwner); + if (aBRepOwner.IsNull()) + return; + Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast( + aBRepOwner->Selectable()); + if (aBRepOwner->HasShape()) { + const TopoDS_Shape& aShape = aBRepOwner->Shape(); + TopAbs_ShapeEnum aShapeType = aShape.ShapeType(); + if (aShapeType == TopAbs_VERTEX) { + AttributePtr aPntAttr = PartSet_Tools::findAttributeBy2dPoint(theFeature, + aShape, theSketch); + if (aPntAttr.get() != NULL) + aSelectedAttributes.insert(aPntAttr); } - AttributePtr anAttr; - TopoDS_Shape aShape = aPrs.shape(); - if (!aShape.IsNull()) { - if (aShape.ShapeType() == TopAbs_VERTEX) { - anAttr = PartSet_Tools::findAttributeBy2dPoint(aFeature, aShape, theSketch); - if (anAttr.get() != NULL && !anAttributes.contains(anAttr)) - anAttributes.push_back(anAttr); - } + else if (aShapeType == TopAbs_EDGE && + aSelectedResults.find(theResult) == aSelectedResults.end()) { + aSelectedResults.insert(theResult); } - theFeature2AttributeMap[aFeature] = anAttributes; } } - - - PartSet_SketcherMgr::PartSet_SketcherMgr(PartSet_Module* theModule) : QObject(theModule), myModule(theModule), myIsDragging(false), myDragDone(false), - myIsPropertyPanelValueChanged(false), myIsMouseOverWindow(false), + myIsResetCurrentValue(false), myIsMouseOverWindow(false), myIsMouseOverViewProcessed(true), myPreviousUpdateViewerEnabled(true), - myIsPopupMenuActive(false) + myIsPopupMenuActive(false), myIsConstraintsShown(true) { ModuleBase_IWorkshop* anIWorkshop = myModule->workshop(); ModuleBase_IViewer* aViewer = anIWorkshop->viewer(); @@ -154,18 +186,58 @@ PartSet_SketcherMgr::~PartSet_SketcherMgr() void PartSet_SketcherMgr::onEnterViewPort() { - if (!isNestedCreateOperation(getCurrentOperation())) - return; // 1. if the mouse over window, update the next flag. Do not perform update visibility of // created feature because it should be done in onMouseMove(). Some widgets watch // the mouse move and use the cursor position to update own values. If the presentaion is // redisplayed before this update, the feature presentation jumps from reset value to current. myIsMouseOverWindow = true; - myIsPropertyPanelValueChanged = false; + myIsResetCurrentValue = false; + // it is important to validate operation here only if sketch entity create operation is active + // because at this operation we reacts to the mouse leave/enter view port + //operationMgr()->onValidateOperation(); +#ifdef DEBUG_MOUSE_OVER_WINDOW_FLAGS + qDebug(QString("onEnterViewPort: %1").arg(mouseOverWindowFlagsInfo()).toStdString().c_str()); +#endif + + #ifdef DEBUG_DO_NOT_BY_ENTER + return; + #endif + + if (!isNestedCreateOperation(getCurrentOperation())) + return; + operationMgr()->onValidateOperation(); + + // we need change displayed state of the current operation feature + // if the feature is presentable, e.g. distance construction. It has no results, so workshop does + // not accept a signal about the result created. Nothing is shown until mouse is moved out/in view + // port. If the isDisplayed flag is true, the presentable feature is displayed as soon as the + // presentation becomes valid and redisplay happens + //ModuleBase_Operation* aOperation = getCurrentOperation(); + ModuleBase_OperationFeature* aFOperation = dynamic_cast + (getCurrentOperation()); + if (aFOperation) { + FeaturePtr aFeature = aFOperation->feature(); + if (aFeature.get() && aFeature->data()->isValid()) { + visualizeFeature(aFeature, aFOperation->isEditOperation(), canDisplayObject(aFeature), false); + } + } } void PartSet_SketcherMgr::onLeaveViewPort() { + myIsMouseOverViewProcessed = false; + myIsMouseOverWindow = false; + // it is important to validate operation here only if sketch entity create operation is active + // because at this operation we reacts to the mouse leave/enter view port + //operationMgr()->onValidateOperation(); +#ifdef DEBUG_MOUSE_OVER_WINDOW_FLAGS + qDebug(QString("onLeaveViewPort: %1").arg(mouseOverWindowFlagsInfo()).toStdString().c_str()); +#endif + + #ifdef DEBUG_DO_NOT_BY_ENTER + return; + #endif + if (!isNestedCreateOperation(getCurrentOperation())) return; // the method should be performed if the popup menu is called, @@ -173,8 +245,7 @@ void PartSet_SketcherMgr::onLeaveViewPort() if (myIsPopupMenuActive) return; - myIsMouseOverViewProcessed = false; - myIsMouseOverWindow = false; + operationMgr()->onValidateOperation(); // 2. if the mouse IS NOT over window, reset the active widget value and hide the presentation ModuleBase_IWorkshop* aWorkshop = myModule->workshop(); @@ -186,21 +257,26 @@ void PartSet_SketcherMgr::onLeaveViewPort() ModuleBase_Operation* aOperation = getCurrentOperation(); ModuleBase_IPropertyPanel* aPanel = aOperation->propertyPanel(); ModuleBase_ModelWidget* aActiveWgt = aPanel->activeWidget(); - if (aActiveWgt) { - aActiveWgt->reset(); + if (aActiveWgt && aActiveWgt->reset()) { + myIsResetCurrentValue = true; } aDisplayer->enableUpdateViewer(isEnableUpdateViewer); // hides the presentation of the current operation feature - myIsPropertyPanelValueChanged = false; // the feature is to be erased here, but it is correct to call canDisplayObject because // there can be additional check (e.g. editor widget in distance constraint) - FeaturePtr aFeature = getCurrentOperation()->feature(); - visualizeFeature(aOperation, canDisplayObject(aFeature)); + ModuleBase_OperationFeature* aFOperation = dynamic_cast + (getCurrentOperation()); + if (aFOperation) { + FeaturePtr aFeature = aFOperation->feature(); + visualizeFeature(aFeature, aFOperation->isEditOperation(), canDisplayObject(aFeature)); + } } void PartSet_SketcherMgr::onBeforeValuesChangedInPropertyPanel() { + myIsResetCurrentValue = false; + if (isNestedCreateOperation(getCurrentOperation())) return; // it is necessary to save current selection in order to restore it after the values are modifed @@ -236,12 +312,16 @@ void PartSet_SketcherMgr::onValuesChangedInPropertyPanel() return; // visualize the current operation feature - myIsPropertyPanelValueChanged = true; - ModuleBase_Operation* aOperation = getCurrentOperation(); + //myIsResetCurrentValue = false; + operationMgr()->onValidateOperation(); // the feature is to be erased here, but it is correct to call canDisplayObject because // there can be additional check (e.g. editor widget in distance constraint) - FeaturePtr aFeature = getCurrentOperation()->feature(); - visualizeFeature(aOperation, canDisplayObject(aFeature)); + ModuleBase_OperationFeature* aFOperation = dynamic_cast + (getCurrentOperation()); + if (aFOperation) { + FeaturePtr aFeature = aFOperation->feature(); + visualizeFeature(aFeature, aFOperation->isEditOperation(), canDisplayObject(aFeature)); + } } void PartSet_SketcherMgr::onMousePressed(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent) @@ -256,32 +336,37 @@ void PartSet_SketcherMgr::onMousePressed(ModuleBase_IViewWindow* theWnd, QMouseE ModuleBase_IWorkshop* aWorkshop = myModule->workshop(); ModuleBase_IViewer* aViewer = aWorkshop->viewer(); + myPreviousSelectionEnabled = aViewer->isSelectionEnabled(); if (!aViewer->canDragByMouse()) return; - ModuleBase_Operation* aOperation = getCurrentOperation(); - if (aOperation && aOperation->isEditOperation()) { - ModuleBase_IPropertyPanel* aPanel = aOperation->propertyPanel(); + ModuleBase_OperationFeature* aFOperation = dynamic_cast + (getCurrentOperation()); + if (!aFOperation) + return; + + if (aFOperation->isEditOperation()) { + ModuleBase_IPropertyPanel* aPanel = aFOperation->propertyPanel(); ModuleBase_ModelWidget* aActiveWgt = aPanel->activeWidget(); - // If the current widget is a selector, do do nothing, it processes the mouse press + // If the current widget is a selector, do nothing, it processes the mouse press if(aActiveWgt && aActiveWgt->isViewerSelector()) { return; } } // Use only for sketch operations - if (aOperation && myCurrentSketch) { + if (myCurrentSketch) { if (!PartSet_Tools::sketchPlane(myCurrentSketch)) return; - bool isSketcher = isSketchOperation(aOperation); - bool isSketchOpe = isNestedSketchOperation(aOperation); + bool isSketcher = isSketchOperation(aFOperation); + bool isSketchOpe = isNestedSketchOperation(aFOperation); // Avoid non-sketch operations if ((!isSketchOpe) && (!isSketcher)) return; - bool isEditing = aOperation->isEditOperation(); + bool isEditing = aFOperation->isEditOperation(); // Ignore creation sketch operation if ((!isSketcher) && (!isEditing)) @@ -299,20 +384,32 @@ void PartSet_SketcherMgr::onMousePressed(ModuleBase_IViewWindow* theWnd, QMouseE if (myCurrentSelection.empty()) { if (isSketchOpe && (!isSketcher)) // commit previous operation - if (!aOperation->commit()) - aOperation->abort(); + if (!aFOperation->commit()) + aFOperation->abort(); return; } + // Init flyout point for radius rotation + FeaturePtr aFeature = myCurrentSelection.begin().key(); if (isSketcher) { myIsDragging = true; get2dPoint(theWnd, theEvent, myCurrentPoint); myDragDone = false; launchEditing(); - + if (aFeature.get() != NULL) { + std::shared_ptr aSPFeature = + std::dynamic_pointer_cast(aFeature); + if (aSPFeature.get() && aSPFeature->getKind() == SketchPlugin_ConstraintRadius::ID()) { + DataPtr aData = aSPFeature->data(); + AttributePtr aAttr = aData->attribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT()); + std::shared_ptr aFPAttr = + std::dynamic_pointer_cast(aAttr); + aFPAttr->setValue(myCurrentPoint.myCurX, myCurrentPoint.myCurY); + } + } } else if (isSketchOpe && isEditing) { // If selected another object commit current result - aOperation->commit(); + aFOperation->commit(); myIsDragging = true; get2dPoint(theWnd, theEvent, myCurrentPoint); @@ -377,8 +474,12 @@ void PartSet_SketcherMgr::onMouseMoved(ModuleBase_IViewWindow* theWnd, QMouseEve } // the feature is to be erased here, but it is correct to call canDisplayObject because // there can be additional check (e.g. editor widget in distance constraint) - FeaturePtr aFeature = getCurrentOperation()->feature(); - visualizeFeature(aOperation, canDisplayObject(aFeature)); + ModuleBase_OperationFeature* aFOperation = dynamic_cast + (getCurrentOperation()); + if (aFOperation) { + FeaturePtr aFeature = aFOperation->feature(); + visualizeFeature(aFeature, aFOperation->isEditOperation(), canDisplayObject(aFeature)); + } } myClickedPoint.clear(); @@ -391,10 +492,10 @@ void PartSet_SketcherMgr::onMouseMoved(ModuleBase_IViewWindow* theWnd, QMouseEve ModuleBase_IViewer* aViewer = myModule->workshop()->viewer(); aViewer->enableSelection(false); - ModuleBase_Operation* aOperation = getCurrentOperation(); - if (!aOperation) + ModuleBase_Operation* aCurrentOperation = getCurrentOperation(); + if (!aCurrentOperation) return; - if (isSketchOperation(aOperation)) + if (isSketchOperation(aCurrentOperation)) return; // No edit operation activated Handle(V3d_View) aView = theWnd->v3dView(); @@ -417,6 +518,7 @@ void PartSet_SketcherMgr::onMouseMoved(ModuleBase_IViewWindow* theWnd, QMouseEve FeatureToSelectionMap::const_iterator anIt = myCurrentSelection.begin(), aLast = myCurrentSelection.end(); // 4. the features and attributes modification(move) + bool isModified = false; for (; anIt != aLast; anIt++) { FeaturePtr aFeature = anIt.key(); @@ -431,12 +533,13 @@ void PartSet_SketcherMgr::onMouseMoved(ModuleBase_IViewWindow* theWnd, QMouseEve continue; std::string aAttrId = anAttr->id(); DataPtr aData = aFeature->data(); - if (aData.get() != NULL) { + if (aData->isValid()) { std::shared_ptr aPoint = std::dynamic_pointer_cast(aData->attribute(aAttrId)); if (aPoint.get() != NULL) { bool isImmutable = aPoint->setImmutable(true); aPoint->move(dX, dY); + isModified = true; ModelAPI_EventCreator::get()->sendUpdated(aFeature, aMoveEvent); aPoint->setImmutable(isImmutable); } @@ -448,10 +551,16 @@ void PartSet_SketcherMgr::onMouseMoved(ModuleBase_IViewWindow* theWnd, QMouseEve std::dynamic_pointer_cast(aFeature); if (aSketchFeature) { aSketchFeature->move(dX, dY); + isModified = true; ModelAPI_EventCreator::get()->sendUpdated(aSketchFeature, aMoveEvent); } } } + // the modified state of the current operation should be updated if there are features, which + // were changed here + if (isModified) { + aCurrentOperation->onValuesChanged(); + } Events_Loop::loop()->flush(aMoveEvent); // up all move events - to be processed in the solver //Events_Loop::loop()->flush(aUpdateEvent); // up update events - to redisplay presentations @@ -468,13 +577,14 @@ void PartSet_SketcherMgr::onMouseMoved(ModuleBase_IViewWindow* theWnd, QMouseEve void PartSet_SketcherMgr::onMouseDoubleClick(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent) { - ModuleBase_Operation* aOperation = getCurrentOperation(); - if (aOperation && aOperation->isEditOperation()) { - std::string aId = aOperation->id().toStdString(); - if (isDistanceOperation(aOperation)) + ModuleBase_OperationFeature* aFOperation = dynamic_cast + (getCurrentOperation()); + if (aFOperation && aFOperation->isEditOperation()) { + std::string aId = aFOperation->id().toStdString(); + if (isDistanceOperation(aFOperation)) { // Activate dimension value editing on double click - ModuleBase_IPropertyPanel* aPanel = aOperation->propertyPanel(); + ModuleBase_IPropertyPanel* aPanel = aFOperation->propertyPanel(); QList aWidgets = aPanel->modelWidgets(); // Find corresponded widget to activate value editing foreach (ModuleBase_ModelWidget* aWgt, aWidgets) { @@ -547,19 +657,6 @@ void PartSet_SketcherMgr::get2dPoint(ModuleBase_IViewWindow* theWnd, QMouseEvent void PartSet_SketcherMgr::launchEditing() { - // there should be activate the vertex selection mode because the edit can happens by the selected - // point - QIntList aModes; - aModes << TopAbs_VERTEX << TopAbs_EDGE; - // TODO: #391 - to be uncommented - /*aModes.append(AIS_DSM_Text); - aModes.append(AIS_DSM_Line); - aModes.append(AIS_Shape::SelectionMode((TopAbs_ShapeEnum) TopAbs_VERTEX)); - aModes.append(AIS_Shape::SelectionMode((TopAbs_ShapeEnum) TopAbs_EDGE));*/ - - XGUI_ModuleConnector* aConnector = dynamic_cast(myModule->workshop()); - aConnector->activateSubShapesSelection(aModes); - if (!myCurrentSelection.empty()) { FeaturePtr aFeature = myCurrentSelection.begin().key(); std::shared_ptr aSPFeature = @@ -568,11 +665,21 @@ void PartSet_SketcherMgr::launchEditing() myModule->editFeature(aSPFeature); } } - } +bool PartSet_SketcherMgr::sketchSolverError() +{ + bool anError = false; + CompositeFeaturePtr aSketch = activeSketch(); + if (aSketch.get()) { + AttributeStringPtr aAttributeString = aSketch->string(SketchPlugin_Sketch::SOLVER_ERROR()); + anError = !aAttributeString->value().empty(); + } + return anError; +} -QStringList PartSet_SketcherMgr::sketchOperationIdList() + +const QStringList& PartSet_SketcherMgr::sketchOperationIdList() { static QStringList aIds; if (aIds.size() == 0) { @@ -580,6 +687,16 @@ QStringList PartSet_SketcherMgr::sketchOperationIdList() aIds << SketchPlugin_Point::ID().c_str(); aIds << SketchPlugin_Arc::ID().c_str(); aIds << SketchPlugin_Circle::ID().c_str(); + aIds << SketchPlugin_ConstraintFillet::ID().c_str(); + aIds.append(constraintsIdList()); + } + return aIds; +} + +const QStringList& PartSet_SketcherMgr::constraintsIdList() +{ + static QStringList aIds; + if (aIds.size() == 0) { aIds << SketchPlugin_ConstraintLength::ID().c_str(); aIds << SketchPlugin_ConstraintDistance::ID().c_str(); aIds << SketchPlugin_ConstraintRigid::ID().c_str(); @@ -591,10 +708,25 @@ QStringList PartSet_SketcherMgr::sketchOperationIdList() aIds << SketchPlugin_ConstraintEqual::ID().c_str(); aIds << SketchPlugin_ConstraintTangent::ID().c_str(); aIds << SketchPlugin_ConstraintCoincidence::ID().c_str(); + aIds << SketchPlugin_ConstraintMirror::ID().c_str(); + aIds << SketchPlugin_ConstraintAngle::ID().c_str(); + aIds << SketchPlugin_MultiRotation::ID().c_str(); + aIds << SketchPlugin_MultiTranslation::ID().c_str(); } return aIds; } +void PartSet_SketcherMgr::sketchSelectionModes(QIntList& theModes) +{ + theModes.clear(); + + theModes.append(SketcherPrs_Tools::Sel_Dimension_Text); + theModes.append(SketcherPrs_Tools::Sel_Dimension_Line); + theModes.append(SketcherPrs_Tools::Sel_Constraint); + theModes.append(TopAbs_VERTEX); + theModes.append(TopAbs_EDGE); +} + bool PartSet_SketcherMgr::isSketchOperation(ModuleBase_Operation* theOperation) { return theOperation && theOperation->id().toStdString() == SketchPlugin_Sketch::ID(); @@ -608,17 +740,17 @@ bool PartSet_SketcherMgr::isNestedSketchOperation(ModuleBase_Operation* theOpera bool PartSet_SketcherMgr::isNestedCreateOperation(ModuleBase_Operation* theOperation) { - return theOperation && !theOperation->isEditOperation() && isNestedSketchOperation(theOperation); + ModuleBase_OperationFeature* aFOperation = dynamic_cast + (theOperation); + return aFOperation && !aFOperation->isEditOperation() && isNestedSketchOperation(aFOperation); } -bool PartSet_SketcherMgr::isEntityOperation(ModuleBase_Operation* theOperation) +bool PartSet_SketcherMgr::isEntity(const std::string& theId) { - std::string aId = theOperation ? theOperation->id().toStdString() : ""; - - return (aId == SketchPlugin_Line::ID()) || - (aId == SketchPlugin_Point::ID()) || - (aId == SketchPlugin_Arc::ID()) || - (aId == SketchPlugin_Circle::ID()); + return (theId == SketchPlugin_Line::ID()) || + (theId == SketchPlugin_Point::ID()) || + (theId == SketchPlugin_Arc::ID()) || + (theId == SketchPlugin_Circle::ID()); } bool PartSet_SketcherMgr::isDistanceOperation(ModuleBase_Operation* theOperation) @@ -627,23 +759,30 @@ bool PartSet_SketcherMgr::isDistanceOperation(ModuleBase_Operation* theOperation return (aId == SketchPlugin_ConstraintLength::ID()) || (aId == SketchPlugin_ConstraintDistance::ID()) || - (aId == SketchPlugin_ConstraintRadius::ID()); + (aId == SketchPlugin_ConstraintRadius::ID()) || + (aId == SketchPlugin_ConstraintAngle::ID()); } void PartSet_SketcherMgr::startSketch(ModuleBase_Operation* theOperation) { + ModuleBase_OperationFeature* aFOperation = dynamic_cast + (getCurrentOperation()); + if (!aFOperation) + return; + + myModule->onViewTransformed(); + // Display all sketcher sub-Objects - myCurrentSketch = std::dynamic_pointer_cast(theOperation->feature()); + myCurrentSketch = std::dynamic_pointer_cast(aFOperation->feature()); XGUI_ModuleConnector* aConnector = dynamic_cast(myModule->workshop()); - XGUI_Displayer* aDisplayer = aConnector->workshop()->displayer(); // Hide sketcher result std::list aResults = myCurrentSketch->results(); std::list::const_iterator aIt; for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) { - aDisplayer->erase((*aIt), false); + (*aIt)->setDisplayed(false); } - aDisplayer->erase(myCurrentSketch, false); + myCurrentSketch->setDisplayed(false); // Display sketcher objects for (int i = 0; i < myCurrentSketch->numberOfSubs(); i++) { @@ -651,32 +790,45 @@ void PartSet_SketcherMgr::startSketch(ModuleBase_Operation* theOperation) std::list aResults = aFeature->results(); std::list::const_iterator aIt; for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) { - aDisplayer->display((*aIt), false); + (*aIt)->setDisplayed(true); } - aDisplayer->display(aFeature, false); + aFeature->setDisplayed(true); } if (myPlaneFilter.IsNull()) myPlaneFilter = new ModuleBase_ShapeInPlaneFilter(); myModule->workshop()->viewer()->addSelectionFilter(myPlaneFilter); - if (theOperation->isEditOperation()) { + + bool aHasPlane = false; + std::shared_ptr aPln; + if (aFOperation->isEditOperation()) { // If it is editing of sketch then it means that plane is already defined - std::shared_ptr aPln = PartSet_Tools::sketchPlane(myCurrentSketch); - myPlaneFilter->setPlane(aPln->impl()); + aPln = PartSet_Tools::sketchPlane(myCurrentSketch); + if (aPln.get()) + aHasPlane = true; } - aDisplayer->updateViewer(); + myPlaneFilter->setPlane(aPln); + + Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY)); + // all sketch objects should be activated in the sketch selection modes by edit operation start + // in case of creation operation, there is an active widget, which activates own selection mode + if (aFOperation->isEditOperation() && aHasPlane) + aConnector->activateModuleSelectionModes(); } -void PartSet_SketcherMgr::stopSketch(ModuleBase_Operation* theOperation) +void PartSet_SketcherMgr::stopSketch(ModuleBase_Operation* /* theOperation*/) { myIsMouseOverWindow = false; - + myIsConstraintsShown = true; +#ifdef DEBUG_MOUSE_OVER_WINDOW_FLAGS + qDebug(QString("stopSketch: %1").arg(mouseOverWindowFlagsInfo()).toStdString().c_str()); +#endif XGUI_ModuleConnector* aConnector = dynamic_cast(myModule->workshop()); - XGUI_Displayer* aDisplayer = aConnector->workshop()->displayer(); DataPtr aData = myCurrentSketch->data(); - if ((!aData) || (!aData->isValid())) { + if (!aData->isValid()) { + XGUI_Displayer* aDisplayer = aConnector->workshop()->displayer(); // The sketch was aborted myCurrentSketch = CompositeFeaturePtr(); myModule->workshop()->viewer()->removeSelectionFilter(myPlaneFilter); @@ -686,50 +838,74 @@ void PartSet_SketcherMgr::stopSketch(ModuleBase_Operation* theOperation) QObjectPtrList aObjects = aDisplayer->displayedObjects(); foreach (ObjectPtr aObj, aObjects) { DataPtr aObjData = aObj->data(); - if ((!aObjData) || (!aObjData->isValid())) - aDisplayer->erase(aObj); + if (!aObjData->isValid()) + aObj->setDisplayed(false); } - return; } - // Hide all sketcher sub-Objects - for (int i = 0; i < myCurrentSketch->numberOfSubs(); i++) { - FeaturePtr aFeature = myCurrentSketch->subFeature(i); - std::list aResults = aFeature->results(); + else { + // Hide all sketcher sub-Objects + for (int i = 0; i < myCurrentSketch->numberOfSubs(); i++) { + FeaturePtr aFeature = myCurrentSketch->subFeature(i); + std::list aResults = aFeature->results(); + std::list::const_iterator aIt; + for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) { + (*aIt)->setDisplayed(false); + } + aFeature->setDisplayed(false); + } + // Display sketcher result + std::list aResults = myCurrentSketch->results(); std::list::const_iterator aIt; + Events_Loop* aLoop = Events_Loop::loop(); + static Events_ID aDispEvent = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY); for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) { - aDisplayer->erase((*aIt), false); + (*aIt)->setDisplayed(true); + // this display event is needed because sketch already may have "displayed" state, + // but not displayed while it is still active (issue 613, abort of existing sketch) + ModelAPI_EventCreator::get()->sendUpdated(*aIt, aDispEvent); } - aDisplayer->erase(aFeature, false); - } - // Display sketcher result - std::list aResults = myCurrentSketch->results(); - std::list::const_iterator aIt; - for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) { - aDisplayer->display((*aIt), false); - } - aDisplayer->display(myCurrentSketch); + myCurrentSketch->setDisplayed(true); - myCurrentSketch = CompositeFeaturePtr(); - myModule->workshop()->viewer()->removeSelectionFilter(myPlaneFilter); - aDisplayer->updateViewer(); + myCurrentSketch = CompositeFeaturePtr(); + myModule->workshop()->viewer()->removeSelectionFilter(myPlaneFilter); + + Events_Loop::loop()->flush(aDispEvent); + } + // restore the module selection modes, which were changed on startSketch + aConnector->activateModuleSelectionModes(); } -void PartSet_SketcherMgr::startNestedSketch(ModuleBase_Operation* ) +void PartSet_SketcherMgr::startNestedSketch(ModuleBase_Operation* theOperation) { + if (constraintsIdList().contains(theOperation->id())) { + // Show constraints if a constraint was created + onShowConstraintsToggle(true); + } connectToPropertyPanel(true); } -void PartSet_SketcherMgr::stopNestedSketch(ModuleBase_Operation* theOperation) +void PartSet_SketcherMgr::stopNestedSketch(ModuleBase_Operation* theOp) { connectToPropertyPanel(false); - myIsPropertyPanelValueChanged = false; + myIsResetCurrentValue = false; myIsMouseOverViewProcessed = true; + operationMgr()->onValidateOperation(); } void PartSet_SketcherMgr::commitNestedSketch(ModuleBase_Operation* theOperation) { - if (isNestedCreateOperation(theOperation)) - visualizeFeature(theOperation, true); + if (isNestedCreateOperation(theOperation)) { + ModuleBase_OperationFeature* aFOperation = dynamic_cast + (theOperation); + if (aFOperation) { + FeaturePtr aFeature = aFOperation->feature(); + // it is necessary to check the the feature data validity because + // some kind of features are removed by an operation commit(the macro state of a feature) + if (aFeature.get() && aFeature->data()->isValid()) { + visualizeFeature(aFeature, aFOperation->isEditOperation(), true); + } + } + } } bool PartSet_SketcherMgr::canUndo() const @@ -742,159 +918,139 @@ bool PartSet_SketcherMgr::canRedo() const return isNestedCreateOperation(getCurrentOperation()); } +bool PartSet_SketcherMgr::canCommitOperation() const +{ + bool aCanCommit = true; + + if (isNestedCreateOperation(getCurrentOperation()) && myIsResetCurrentValue) + aCanCommit = false; + + return aCanCommit; +} + +bool PartSet_SketcherMgr::canEraseObject(const ObjectPtr& theObject) const +{ + bool aCanErase = true; + // when the sketch operation is active, results of sketch sub-feature can not be hidden + if (myCurrentSketch.get()) { + ResultPtr aResult = std::dynamic_pointer_cast(theObject); + if (aResult.get()) { + // Display sketcher objects + for (int i = 0; i < myCurrentSketch->numberOfSubs() && aCanErase; i++) { + + FeaturePtr aFeature = myCurrentSketch->subFeature(i); + std::list aResults = aFeature->results(); + std::list::const_iterator anIt; + for (anIt = aResults.begin(); anIt != aResults.end() && aCanErase; ++anIt) { + aCanErase = *anIt != aResult; + } + } + } + } + return aCanErase; +} + bool PartSet_SketcherMgr::canDisplayObject(const ObjectPtr& theObject) const { bool aCanDisplay = true; - // 1. the sketch feature should not be displayed during the sketch active operation - // it is hidden by a sketch operation start and shown by a sketch stop, just the sketch - // nested features can be visualized - CompositeFeaturePtr aSketchFeature = activeSketch(); - if (aSketchFeature.get() != NULL) { + + bool aHasActiveSketch = activeSketch().get() != NULL; + if (aHasActiveSketch) { + // 1. the sketch feature should not be displayed during the sketch active operation + // it is hidden by a sketch operation start and shown by a sketch stop, just the sketch + // nested features can be visualized FeaturePtr aFeature = ModelAPI_Feature::feature(theObject); - if (aFeature.get() != NULL && aFeature == aSketchFeature) + if (aFeature.get() != NULL && aFeature == activeSketch()) { aCanDisplay = false; + } + } + else { // there are no an active sketch + // 2. sketch sub-features should not be visualized if the sketch operation is not active + FeaturePtr aFeature = ModelAPI_Feature::feature(theObject); + if (aFeature.get() != NULL) { + std::shared_ptr aSketchFeature = + std::dynamic_pointer_cast(aFeature); + if (aSketchFeature.get()) { + aCanDisplay = false; + } + } } - // 2. For created nested feature operation do not display the created feature if + + // 3. the method should not filter the objects, which are not related to the current operation. + // The object is filtered just if it is a current operation feature or this feature result + bool isObjectFound = false; + ModuleBase_OperationFeature* aFOperation = dynamic_cast + (getCurrentOperation()); + if (aFOperation) { + FeaturePtr aFeature = aFOperation->feature(); + if (aFeature.get()) { + std::list aResults = aFeature->results(); + if (theObject == aFeature) + isObjectFound = true; + else { + std::list::const_iterator anIt = aResults.begin(), aLast = aResults.end(); + for (; anIt != aLast; anIt++) { + isObjectFound = *anIt == theObject; + } + } + } + } + if (!isObjectFound) + return aCanDisplay; + + // 4. For created nested feature operation do not display the created feature if // the mouse curstor leaves the OCC window. // The correction cases, which ignores this condition: // a. the property panel values modification // b. the popup menu activated // c. widget editor control - if (aCanDisplay) { - if (!isNestedCreateOperation(getCurrentOperation())) - return aCanDisplay; - + #ifndef DEBUG_DO_NOT_BY_ENTER + if (aCanDisplay && isNestedCreateOperation(getCurrentOperation())) { ModuleBase_Operation* aOperation = getCurrentOperation(); ModuleBase_IPropertyPanel* aPanel = aOperation->propertyPanel(); ModuleBase_ModelWidget* anActiveWdg = aPanel ? aPanel->activeWidget() : 0; + ModuleBase_WidgetEditor* anEditorWdg = anActiveWdg ? dynamic_cast(anActiveWdg) : 0; // the active widget editor should not influence here. The presentation should be visible always // when this widget is active. - if (anActiveWdg) { - ModuleBase_WidgetEditor* anEditorWdg = dynamic_cast(anActiveWdg); - if (anEditorWdg) { - return aCanDisplay; - } + if (!anEditorWdg && !myIsPopupMenuActive) { + // during a nested create operation, the feature is redisplayed only if the mouse over view + // of there was a value modified in the property panel after the mouse left the view + aCanDisplay = canDisplayCurrentCreatedFeature(); } - if (myIsPopupMenuActive) - return aCanDisplay; - - // during a nested create operation, the feature is redisplayed only if the mouse over view - // of there was a value modified in the property panel after the mouse left the view - aCanDisplay = myIsPropertyPanelValueChanged || myIsMouseOverWindow; } + #endif return aCanDisplay; } -bool PartSet_SketcherMgr::canSetAuxiliary(bool& theValue) const +bool PartSet_SketcherMgr::canDisplayCurrentCreatedFeature() const { - bool anEnabled = false; - ModuleBase_Operation* anOperation = getCurrentOperation(); - - bool isActiveSketch = PartSet_SketcherMgr::isSketchOperation(anOperation) || - PartSet_SketcherMgr::isNestedSketchOperation(anOperation); - if (!isActiveSketch) - return anEnabled; - - QObjectPtrList anObjects; - // 1. change auxiliary type of a created feature - if (PartSet_SketcherMgr::isNestedCreateOperation(anOperation) && - PartSet_SketcherMgr::isEntityOperation(anOperation) ) { - anObjects.append(anOperation->feature()); - } - else { - /// The operation should not be aborted here, because the method does not changed - /// the auxilliary state, but checks the possibility to perform this - ///if (PartSet_SketcherMgr::isNestedSketchOperation(anOperation)) - /// anOperation->abort(); - // 2. change auxiliary type of selected sketch entities - ModuleBase_ISelection* aSelection = myModule->workshop()->selection(); - anObjects = aSelection->selectedPresentations(); - } - anEnabled = anObjects.size() > 0; - - bool isNotAuxiliaryFound = false; - if (anObjects.size() > 0) { - QObjectPtrList::const_iterator anIt = anObjects.begin(), aLast = anObjects.end(); - for (; anIt != aLast && !isNotAuxiliaryFound; anIt++) { - FeaturePtr aFeature = ModelAPI_Feature::feature(*anIt); - if (aFeature.get() != NULL) { - std::shared_ptr aSketchFeature = - std::dynamic_pointer_cast(aFeature); - if (aSketchFeature.get() != NULL) { - std::string anAttribute = SketchPlugin_SketchEntity::AUXILIARY_ID(); - - std::shared_ptr anAuxiliaryAttr = - std::dynamic_pointer_cast(aSketchFeature->data()->attribute(anAttribute)); - if (anAuxiliaryAttr) - isNotAuxiliaryFound = !anAuxiliaryAttr->value(); - } - } - } - } - theValue = anObjects.size() && !isNotAuxiliaryFound; - return anEnabled; + return myIsMouseOverWindow || !myIsResetCurrentValue; +#ifdef DEBUG_MOUSE_OVER_WINDOW_FLAGS + qDebug(QString("canDisplayCurrentCreatedFeature: %1").arg(mouseOverWindowFlagsInfo()).toStdString().c_str()); +#endif } - -void PartSet_SketcherMgr::setAuxiliary(const bool isChecked) -{ - ModuleBase_Operation* anOperation = getCurrentOperation(); - - bool isActiveSketch = PartSet_SketcherMgr::isSketchOperation(anOperation) || - PartSet_SketcherMgr::isNestedSketchOperation(anOperation); - if (!isActiveSketch) - return; - - QObjectPtrList anObjects; - bool isUseTransaction = false; - // 1. change auxiliary type of a created feature - if (PartSet_SketcherMgr::isNestedCreateOperation(anOperation) && - PartSet_SketcherMgr::isEntityOperation(anOperation) ) { - anObjects.append(anOperation->feature()); - } - else { - isUseTransaction = true; - // 2. change auxiliary type of selected sketch entities - ModuleBase_ISelection* aSelection = myModule->workshop()->selection(); - anObjects = aSelection->selectedPresentations(); - } - QAction* anAction = myModule->action("AUXILIARY_CMD"); - SessionPtr aMgr = ModelAPI_Session::get(); - if (isUseTransaction) { - if (PartSet_SketcherMgr::isNestedSketchOperation(anOperation)) - anOperation->abort(); - aMgr->startOperation(anAction->text().toStdString()); - } - storeSelection(); - - if (anObjects.size() > 0) { - QObjectPtrList::const_iterator anIt = anObjects.begin(), aLast = anObjects.end(); - for (; anIt != aLast; anIt++) { - FeaturePtr aFeature = ModelAPI_Feature::feature(*anIt); - if (aFeature.get() != NULL) { - std::shared_ptr aSketchFeature = - std::dynamic_pointer_cast(aFeature); - if (aSketchFeature.get() != NULL) { - std::string anAttribute = SketchPlugin_SketchEntity::AUXILIARY_ID(); - - std::shared_ptr anAuxiliaryAttr = - std::dynamic_pointer_cast(aSketchFeature->data()->attribute(anAttribute)); - if (anAuxiliaryAttr) - anAuxiliaryAttr->setValue(isChecked); - } - } +bool PartSet_SketcherMgr::isObjectOfSketch(const ObjectPtr& theObject) const +{ + bool isFoundObject = false; + + FeaturePtr anObjectFeature = ModelAPI_Feature::feature(theObject); + if (anObjectFeature.get()) { + int aSize = myCurrentSketch->numberOfSubs(); + for (int i = 0; i < myCurrentSketch->numberOfSubs() && !isFoundObject; i++) { + FeaturePtr aCurrentFeature = myCurrentSketch->subFeature(i); + isFoundObject = myCurrentSketch->subFeature(i) == anObjectFeature; } } - if (isUseTransaction) { - aMgr->finishOperation(); - } - Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED)); - restoreSelection(); + return isFoundObject; } void PartSet_SketcherMgr::onPlaneSelected(const std::shared_ptr& thePln) { - myPlaneFilter->setPlane(thePln->impl()); + if (myPlaneFilter.IsNull()) + myPlaneFilter = new ModuleBase_ShapeInPlaneFilter(); + + myPlaneFilter->setPlane(thePln); } void PartSet_SketcherMgr::getCurrentSelection(const FeaturePtr& theFeature, @@ -924,29 +1080,20 @@ void PartSet_SketcherMgr::getCurrentSelection(const FeaturePtr& theFeature, Handle(AIS_InteractiveObject) anAISIO = aAISObj->impl(); for (aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected()) { - Handle(StdSelect_BRepOwner) aBRepOwner = Handle(StdSelect_BRepOwner)::DownCast( - aContext->SelectedOwner()); - if (aBRepOwner.IsNull()) + Handle(SelectMgr_EntityOwner) anOwner = aContext->SelectedOwner(); + if (anOwner->Selectable() != anAISIO) continue; - Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast( - aBRepOwner->Selectable()); - if (anIO != anAISIO) + getAttributesOrResults(anOwner, theFeature, theSketch, aResult, + aSelectedAttributes, aSelectedResults); + } + for (aContext->InitDetected(); aContext->MoreDetected(); aContext->NextDetected()) { + Handle(SelectMgr_EntityOwner) anOwner = aContext->DetectedOwner(); + if (anOwner.IsNull()) continue; - - if (aBRepOwner->HasShape()) { - const TopoDS_Shape& aShape = aBRepOwner->Shape(); - TopAbs_ShapeEnum aShapeType = aShape.ShapeType(); - if (aShapeType == TopAbs_VERTEX) { - AttributePtr aPntAttr = PartSet_Tools::findAttributeBy2dPoint(theFeature, - aShape, theSketch); - if (aPntAttr.get() != NULL) - aSelectedAttributes.insert(aPntAttr); - } - else if (aShapeType == TopAbs_EDGE && - aSelectedResults.find(aResult) == aSelectedResults.end()) { - aSelectedResults.insert(aResult); - } - } + if (anOwner->Selectable() != anAISIO) + continue; + getAttributesOrResults(anOwner, theFeature, theSketch, aResult, + aSelectedAttributes, aSelectedResults); } } theSelection[theFeature] = std::make_pair(aSelectedAttributes, aSelectedResults); @@ -975,7 +1122,7 @@ void PartSet_SketcherMgr::getSelectionOwners(const FeaturePtr& theFeature, if (aAISObj.get() != NULL && aSelectedAttributes.empty() && aSelectedResults.empty()) { Handle(AIS_InteractiveObject) anAISIO = aAISObj->impl(); - SelectMgr_IndexedMapOfOwner aSelectedOwners; + SelectMgr_IndexedMapOfOwner aSelectedOwners; aConnector->workshop()->selector()->selection()->entityOwners(anAISIO, aSelectedOwners); for (Standard_Integer i = 1, n = aSelectedOwners.Extent(); i <= n; i++) { Handle(SelectMgr_EntityOwner) anOwner = aSelectedOwners(i); @@ -1052,36 +1199,42 @@ ModuleBase_Operation* PartSet_SketcherMgr::getCurrentOperation() const return myModule->workshop()->currentOperation(); } -void PartSet_SketcherMgr::visualizeFeature(ModuleBase_Operation* theOperation, - const bool isToDisplay) +void PartSet_SketcherMgr::visualizeFeature(const FeaturePtr& theFeature, + const bool isEditOperation, + const bool isToDisplay, + const bool isFlushRedisplay) { - if (!theOperation || theOperation->isEditOperation()) + #ifdef DEBUG_DO_NOT_BY_ENTER + return; + #endif + + if (isEditOperation || !theFeature.get()) return; ModuleBase_IWorkshop* aWorkshop = myModule->workshop(); XGUI_ModuleConnector* aConnector = dynamic_cast(aWorkshop); - XGUI_Displayer* aDisplayer = aConnector->workshop()->displayer(); // 1. change visibility of the object itself, here the presentable object is processed, // e.g. constraints features - FeaturePtr aFeature = theOperation->feature(); - std::list aResults = aFeature->results(); + //FeaturePtr aFeature = aFOperation->feature(); + std::list aResults = theFeature->results(); if (isToDisplay) - aDisplayer->display(aFeature, false); + theFeature->setDisplayed(true); else - aDisplayer->erase(aFeature, false); + theFeature->setDisplayed(false); // change visibility of the object results, e.g. non-constraint features std::list::const_iterator aIt; for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) { if (isToDisplay) { - aDisplayer->display(*aIt, false); + (*aIt)->setDisplayed(true); } else { - aDisplayer->erase(*aIt, false); + (*aIt)->setDisplayed(false); } } - aDisplayer->updateViewer(); + if (isFlushRedisplay) + Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY)); } void PartSet_SketcherMgr::storeSelection(const bool theHighlightedOnly) @@ -1089,25 +1242,23 @@ void PartSet_SketcherMgr::storeSelection(const bool theHighlightedOnly) ModuleBase_IWorkshop* aWorkshop = myModule->workshop(); ModuleBase_ISelection* aSelect = aWorkshop->selection(); QList aHighlighted = aSelect->getHighlighted(); - - QMap > aFeature2AttributeMap; + + QList aFeatureList; if (theHighlightedOnly) { - fillFeature2Attribute(aHighlighted, aFeature2AttributeMap, myCurrentSketch); + fillFeatureList(aHighlighted, myCurrentSketch, aFeatureList); } else { - fillFeature2Attribute(aHighlighted, aFeature2AttributeMap, myCurrentSketch); + fillFeatureList(aHighlighted, myCurrentSketch, aFeatureList); - QList aSelected = aSelect->getSelected(); - fillFeature2Attribute(aSelected, aFeature2AttributeMap, myCurrentSketch); + QList aSelected = aSelect->getSelected(ModuleBase_ISelection::AllControls); + fillFeatureList(aSelected, myCurrentSketch, aFeatureList); } // 1. it is necessary to save current selection in order to restore it after the features moving myCurrentSelection.clear(); - QMap >::const_iterator anIt = aFeature2AttributeMap.begin(), - aLast = aFeature2AttributeMap.end(); + QList::const_iterator anIt = aFeatureList.begin(), aLast = aFeatureList.end(); for (; anIt != aLast; anIt++) { - FeaturePtr aFeature = anIt.key(); - getCurrentSelection(aFeature, myCurrentSketch, aWorkshop, myCurrentSelection); + getCurrentSelection(*anIt, myCurrentSketch, aWorkshop, myCurrentSelection); } //qDebug(QString(" storeSelection: %1").arg(myCurrentSelection.size()).toStdString().c_str()); } @@ -1127,3 +1278,43 @@ void PartSet_SketcherMgr::restoreSelection() aConnector->workshop()->selector()->setSelectedOwners(anOwnersToSelect, false); } } + +void PartSet_SketcherMgr::onShowConstraintsToggle(bool theOn) +{ + if (myIsConstraintsShown == theOn) + return; + if (myCurrentSketch.get() == NULL) + return; + + myIsConstraintsShown = theOn; + + ModuleBase_IWorkshop* aWorkshop = myModule->workshop(); + XGUI_ModuleConnector* aConnector = dynamic_cast(aWorkshop); + + const QStringList& aConstrIds = constraintsIdList(); + for (int i = 0; i < myCurrentSketch->numberOfSubs(); i++) { + FeaturePtr aSubFeature = myCurrentSketch->subFeature(i); + if (aConstrIds.contains(QString(aSubFeature->getKind().c_str()))) { + if (myIsConstraintsShown) + aSubFeature->setDisplayed(true); + else + aSubFeature->setDisplayed(false); + } + } + Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY)); +} + +QString PartSet_SketcherMgr::mouseOverWindowFlagsInfo() const +{ + return QString("myIsResetCurrentValue = %1, myIsMouseOverWindow = %2") + .arg(myIsResetCurrentValue).arg(myIsMouseOverWindow); +} + +XGUI_OperationMgr* PartSet_SketcherMgr::operationMgr() const +{ + ModuleBase_IWorkshop* anIWorkshop = myModule->workshop(); + XGUI_ModuleConnector* aConnector = dynamic_cast(anIWorkshop); + XGUI_Workshop* aWorkshop = aConnector->workshop(); + + return aWorkshop->operationMgr(); +}