From 4f0958d924fe4fdd5f960b9b3fbacdcc43513a9f Mon Sep 17 00:00:00 2001 From: nds Date: Wed, 28 Oct 2015 13:48:24 +0300 Subject: [PATCH] Sepate reentant functionality to a separate manager. --- src/PartSet/CMakeLists.txt | 2 + src/PartSet/PartSet_Module.cpp | 202 ++----------- src/PartSet/PartSet_Module.h | 21 +- src/PartSet/PartSet_SketcherMgr.cpp | 20 +- src/PartSet/PartSet_SketcherReetntrantMgr.cpp | 278 ++++++++++++++++++ src/PartSet/PartSet_SketcherReetntrantMgr.h | 121 ++++++++ src/PartSet/PartSet_WidgetPoint2d.cpp | 33 ++- 7 files changed, 462 insertions(+), 215 deletions(-) create mode 100755 src/PartSet/PartSet_SketcherReetntrantMgr.cpp create mode 100755 src/PartSet/PartSet_SketcherReetntrantMgr.h diff --git a/src/PartSet/CMakeLists.txt b/src/PartSet/CMakeLists.txt index 350924e1f..35275b60f 100644 --- a/src/PartSet/CMakeLists.txt +++ b/src/PartSet/CMakeLists.txt @@ -26,6 +26,7 @@ SET(PROJECT_HEADERS PartSet_LockApplyMgr.h PartSet_FilterInfinite.h PartSet_SketcherMgr.h + PartSet_SketcherReetntrantMgr.h PartSet_MenuMgr.h PartSet_WidgetSketchCreator.h PartSet_IconFactory.h @@ -51,6 +52,7 @@ SET(PROJECT_SOURCES PartSet_LockApplyMgr.cpp PartSet_FilterInfinite.cpp PartSet_SketcherMgr.cpp + PartSet_SketcherReetntrantMgr.cpp PartSet_MenuMgr.cpp PartSet_WidgetSketchCreator.cpp PartSet_IconFactory.cpp diff --git a/src/PartSet/PartSet_Module.cpp b/src/PartSet/PartSet_Module.cpp index 7e940adef..d55095a44 100755 --- a/src/PartSet/PartSet_Module.cpp +++ b/src/PartSet/PartSet_Module.cpp @@ -14,6 +14,7 @@ #include "PartSet_WidgetFileSelector.h" #include "PartSet_WidgetSketchCreator.h" #include "PartSet_SketcherMgr.h" +#include "PartSet_SketcherReetntrantMgr.h" #include "PartSet_MenuMgr.h" #include "PartSet_CustomPrs.h" #include "PartSet_IconFactory.h" @@ -73,10 +74,6 @@ #include #include -#include -#include -#include -#include #include #include #include @@ -123,13 +120,13 @@ extern "C" PARTSET_EXPORT ModuleBase_IModule* createModule(ModuleBase_IWorkshop* } PartSet_Module::PartSet_Module(ModuleBase_IWorkshop* theWshop) - : ModuleBase_IModule(theWshop), - myRestartingMode(RM_None), myVisualLayerId(0), myHasConstraintShown(true), - myIsInternalEditOperation(false) +: ModuleBase_IModule(theWshop), + myVisualLayerId(0), myHasConstraintShown(true) { new PartSet_IconFactory(); mySketchMgr = new PartSet_SketcherMgr(this); + mySketchReentrantMgr = new PartSet_SketcherReetntrantMgr(theWshop); XGUI_ModuleConnector* aConnector = dynamic_cast(theWshop); XGUI_Workshop* aWorkshop = aConnector->workshop(); @@ -253,82 +250,21 @@ void PartSet_Module::onOperationCommitted(ModuleBase_Operation* theOperation) mySketchMgr->commitNestedSketch(theOperation); } - ModuleBase_OperationFeature* aFOperation = dynamic_cast(theOperation); - if (!aFOperation) - return; - // the clear selection is obsolete because during restart of the creation operation - // we would like to use selected object, e.g. a line in a parallel constraint - - // the selection is cleared after commit the create operation - // in order to do not use the same selected objects in the restarted operation - // for common behaviour, the selection is cleared even if the operation is not restarted - /*XGUI_ModuleConnector* aConnector = dynamic_cast(workshop()); - XGUI_Workshop* aWorkshop = aConnector->workshop(); - aWorkshop->selector()->clearSelection();*/ - /// Restart sketcher operations automatically - FeaturePtr aFeature = aFOperation->feature(); - std::shared_ptr aSPFeature = - std::dynamic_pointer_cast(aFeature); - if (aSPFeature && (myRestartingMode == RM_LastFeatureUsed || - myRestartingMode == RM_EmptyFeatureUsed)) { - myLastOperationId = aFOperation->id(); - myLastFeature = myRestartingMode == RM_LastFeatureUsed ? aFOperation->feature() : FeaturePtr(); - if (!sketchMgr()->sketchSolverError()) { - if (!aFOperation->isEditOperation()) { - FeaturePtr anOperationFeature = aFOperation->feature(); - if (anOperationFeature.get() != NULL) { - editFeature(anOperationFeature); - myIsInternalEditOperation = true; - onInternalActivateFirstWidgetSelection(); - - // activate the last active widget in the Property Panel - if (!myPreviousAttributeID.empty()) { - ModuleBase_Operation* anEditOperation = currentOperation(); - if (anEditOperation) { - ModuleBase_IPropertyPanel* aPanel = aFOperation->propertyPanel(); - ModuleBase_ModelWidget* aPreviousAttributeWidget = 0; - QList aWidgets = aPanel->modelWidgets(); - for (int i = 0, aNb = aWidgets.size(); i < aNb && !aPreviousAttributeWidget; i++) { - if (aWidgets[i]->attributeID() == myPreviousAttributeID) - aPreviousAttributeWidget = aWidgets[i]; - } - // If the current widget is a selector, do nothing, it processes the mouse press - if (aPreviousAttributeWidget && !aPreviousAttributeWidget->isViewerSelector()) - aPreviousAttributeWidget->focusTo(); - } - } - } - } - else { - // the flag should be reset before start to do not react to the widget deactivate - myIsInternalEditOperation = false; - launchOperation(myLastOperationId); - breakOperationSequence(); - } - } + if (!mySketchReentrantMgr->operationCommitted(theOperation)) { + // the selection is cleared after commit the create operation + // in order to do not use the same selected objects in the restarted operation + // for common behaviour, the selection is cleared even if the operation is not restarted + XGUI_ModuleConnector* aConnector = dynamic_cast(workshop()); + XGUI_Workshop* aWorkshop = aConnector->workshop(); + aWorkshop->selector()->clearSelection(); } } -void PartSet_Module::breakOperationSequence() -{ - myLastOperationId = ""; - myLastFeature = FeaturePtr(); - myRestartingMode = RM_None; -} - void PartSet_Module::onOperationAborted(ModuleBase_Operation* theOperation) { - if (myIsInternalEditOperation) { - // abort the created feature, which is currently edited - SessionPtr aMgr = ModelAPI_Session::get(); - if (aMgr->hasModuleDocument() && aMgr->canUndo()) { - aMgr->undo(); - } - } - - myIsInternalEditOperation = false; - breakOperationSequence(); + /// Restart sketcher operations automatically + mySketchReentrantMgr->operationAborted(theOperation); } void PartSet_Module::onOperationStarted(ModuleBase_Operation* theOperation) @@ -525,36 +461,7 @@ void PartSet_Module::clearViewer() void PartSet_Module::propertyPanelDefined(ModuleBase_Operation* theOperation) { - ModuleBase_OperationFeature* aFOperation = dynamic_cast(theOperation); - if (!aFOperation) - return; - - ModuleBase_IPropertyPanel* aPanel = aFOperation->propertyPanel(); - if (PartSet_SketcherMgr::isSketchOperation(aFOperation) && (aFOperation->isEditOperation())) { - // we have to manually activate the sketch label in edit mode - aPanel->activateWidget(aPanel->modelWidgets().first()); - return; - } - - // Restart last operation type - if ((aFOperation->id() == myLastOperationId) && myLastFeature) { - ModuleBase_ModelWidget* aWgt = aPanel->activeWidget(); - if (aFOperation->id().toStdString() == SketchPlugin_Line::ID()) { - // Initialise new line with first point equal to end of previous - PartSet_WidgetPoint2D* aPnt2dWgt = dynamic_cast(aWgt); - if (aPnt2dWgt) { - std::shared_ptr aData = myLastFeature->data(); - std::shared_ptr aPoint = - std::dynamic_pointer_cast(aData->attribute(SketchPlugin_Line::END_ID())); - if (aPoint) { - aPnt2dWgt->setPoint(aPoint->x(), aPoint->y()); - PartSet_Tools::setConstraints(mySketchMgr->activeSketch(), aFOperation->feature(), - aWgt->attributeID(), aPoint->x(), aPoint->y()); - aPanel->activateNextWidget(aPnt2dWgt); - } - } - } - } + mySketchReentrantMgr->propertyPanelDefined(theOperation); } @@ -600,15 +507,12 @@ void PartSet_Module::onKeyRelease(ModuleBase_IViewWindow* theWnd, QKeyEvent* the void PartSet_Module::onEnterReleased() { - ModuleBase_OperationFeature* aFOperation = dynamic_cast - (currentOperation()); - if (/*!aFOperation->isEditOperation() || */myIsInternalEditOperation) - myRestartingMode = RM_EmptyFeatureUsed; + mySketchReentrantMgr->enterReleased(); } void PartSet_Module::onOperationActivatedByPreselection() { - if (myRestartingMode != RM_None) + if (!mySketchReentrantMgr->canBeCommittedByPreselection()) return; ModuleBase_Operation* anOperation = myWorkshop->currentOperation(); @@ -623,57 +527,12 @@ void PartSet_Module::onOperationActivatedByPreselection() void PartSet_Module::onNoMoreWidgets(const std::string& thePreviousAttributeID) { - ModuleBase_Operation* anOperation = myWorkshop->currentOperation(); - if (anOperation) { - if (PartSet_SketcherMgr::isNestedSketchOperation(anOperation)) { - if (myRestartingMode != RM_Forbided) { - myRestartingMode = RM_LastFeatureUsed; - myPreviousAttributeID = thePreviousAttributeID; - } - XGUI_ModuleConnector* aConnector = dynamic_cast(workshop()); - XGUI_Workshop* aWorkshop = aConnector->workshop(); - XGUI_OperationMgr* anOpMgr = aWorkshop->operationMgr(); - // do nothing if the feature can not be applyed - if (anOpMgr->isApplyEnabled()) - anOperation->commit(); - } - } -} - -void PartSet_Module::onInternalActivateFirstWidgetSelection() -{ - if (!myIsInternalEditOperation) - return; - - ModuleBase_ModelWidget* aFirstWidget = activeWidget(); - ModuleBase_IPropertyPanel* aPanel = currentOperation()->propertyPanel(); - if (aFirstWidget != aPanel->activeWidget()) { - ModuleBase_WidgetSelector* aWSelector = dynamic_cast(aFirstWidget); - if (aWSelector) - aWSelector->activateSelectionAndFilters(true); - } + mySketchReentrantMgr->noMoreWidgets(thePreviousAttributeID); } void PartSet_Module::onVertexSelected() { - ModuleBase_Operation* aOperation = myWorkshop->currentOperation(); - if (aOperation->id().toStdString() == SketchPlugin_Line::ID()) { - /// If last line finished on vertex the lines creation sequence has to be break - ModuleBase_IPropertyPanel* aPanel = aOperation->propertyPanel(); - ModuleBase_ModelWidget* anActiveWidget = aPanel->activeWidget(); - const QList& aWidgets = aPanel->modelWidgets(); - QList::const_iterator anIt = aWidgets.begin(), aLast = aWidgets.end(); - bool aFoundWidget = false; - bool aFoundObligatory = false; - for (; anIt != aLast && !aFoundObligatory; anIt++) { - if (!aFoundWidget) - aFoundWidget = *anIt == anActiveWidget; - else - aFoundObligatory = (*anIt)->isObligatory(); - } - if (!aFoundObligatory) - myRestartingMode = RM_Forbided; - } + mySketchReentrantMgr->vertexSelected(); } ModuleBase_ModelWidget* PartSet_Module::createWidgetByType(const std::string& theType, QWidget* theParent, @@ -736,26 +595,15 @@ ModuleBase_ModelWidget* PartSet_Module::createWidgetByType(const std::string& th ModuleBase_ModelWidget* PartSet_Module::activeWidget() const { ModuleBase_ModelWidget* anActiveWidget = 0; - ModuleBase_Operation* aOperation = myWorkshop->currentOperation(); - if (aOperation) { - ModuleBase_IPropertyPanel* aPanel = aOperation->propertyPanel(); - anActiveWidget = aPanel->activeWidget(); - if (myIsInternalEditOperation && (!anActiveWidget || !anActiveWidget->isViewerSelector())) { - // finds the first widget which can accept a value - QList aWidgets = aPanel->modelWidgets(); - ModuleBase_ModelWidget* aFirstWidget = 0; - ModuleBase_ModelWidget* aWgt; - QList::const_iterator aWIt; - for (aWIt = aWidgets.begin(); aWIt != aWidgets.end() && !aFirstWidget; ++aWIt) { - aWgt = (*aWIt); - if (aWgt->canSetValue()) - aFirstWidget = aWgt; - } - if (aFirstWidget) - anActiveWidget = aFirstWidget; + + anActiveWidget = mySketchReentrantMgr->activeWidget(); + if (!anActiveWidget) { + ModuleBase_Operation* aOperation = myWorkshop->currentOperation(); + if (aOperation) { + ModuleBase_IPropertyPanel* aPanel = aOperation->propertyPanel(); + anActiveWidget = aPanel->activeWidget(); } } - return anActiveWidget; } diff --git a/src/PartSet/PartSet_Module.h b/src/PartSet/PartSet_Module.h index eac6dad27..8db2d8305 100644 --- a/src/PartSet/PartSet_Module.h +++ b/src/PartSet/PartSet_Module.h @@ -31,6 +31,7 @@ class ModuleBase_IViewWindow; class PartSet_MenuMgr; class PartSet_CustomPrs; class PartSet_SketcherMgr; +class PartSet_SketcherReetntrantMgr; class QAction; @@ -162,6 +163,9 @@ public: /// Returns sketch manager object PartSet_SketcherMgr* sketchMgr() const { return mySketchMgr; } + /// Returns sketch reentrant manager + PartSet_SketcherReetntrantMgr* sketchReentranceMgr() { return mySketchReentrantMgr; } + /// Performs functionality on closing document virtual void closeDocument(); @@ -207,15 +211,11 @@ public: /// Returns list of granted operation indices virtual void grantedOperationIds(ModuleBase_Operation* theOperation, QStringList& theIds) const; - bool isInternalEditOperation() { return myIsInternalEditOperation; } - public slots: /// SLOT, that is called by no more widget signal emitted by property panel /// Set a specific flag to restart the sketcher operation void onNoMoreWidgets(const std::string& thePreviousAttributeID); - void onInternalActivateFirstWidgetSelection(); - /// Redefines the parent method in order to customize the next case: /// If the sketch nested operation is active and the presentation is not visualized in the viewer, /// the operation should be always aborted. @@ -272,26 +272,15 @@ protected slots: void onTreeViewDoubleClick(const QModelIndex&); private: - /// Breaks sequense of automatically resterted operations - void breakOperationSequence(); //! Delete features virtual bool deleteObjects(); private: - QString myLastOperationId; - FeaturePtr myLastFeature; - - std::string myPreviousAttributeID; - - // Automatical restarting mode flag - RestartingMode myRestartingMode; - - bool myIsInternalEditOperation; - SelectMgr_ListOfFilter mySelectionFilters; PartSet_SketcherMgr* mySketchMgr; + PartSet_SketcherReetntrantMgr* mySketchReentrantMgr; PartSet_MenuMgr* myMenuMgr; /// A default custom presentation, which is used for references objects of started operation PartSet_CustomPrs* myCustomPrs; diff --git a/src/PartSet/PartSet_SketcherMgr.cpp b/src/PartSet/PartSet_SketcherMgr.cpp index 2e0435d62..572bea5a2 100644 --- a/src/PartSet/PartSet_SketcherMgr.cpp +++ b/src/PartSet/PartSet_SketcherMgr.cpp @@ -5,6 +5,7 @@ // Author: Vitaly SMETANNIKOV #include "PartSet_SketcherMgr.h" +#include "PartSet_SketcherReetntrantMgr.h" #include "PartSet_Module.h" #include "PartSet_WidgetPoint2d.h" #include "PartSet_WidgetPoint2dDistance.h" @@ -336,7 +337,7 @@ void PartSet_SketcherMgr::onMousePressed(ModuleBase_IViewWindow* theWnd, QMouseE if (!(theEvent->buttons() & Qt::LeftButton)) return; - if (myModule->isInternalEditOperation()) // it should be processed by mouse release + if (myModule->sketchReentranceMgr()->processMousePressed()) return; // Clear dragging mode @@ -437,12 +438,8 @@ void PartSet_SketcherMgr::onMousePressed(ModuleBase_IViewWindow* theWnd, QMouseE void PartSet_SketcherMgr::onMouseReleased(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent) { - if (myModule->isInternalEditOperation()) { - ModuleBase_Operation* anOperation = getCurrentOperation(); - //if (operationMgr()->isApplyEnabled()) - anOperation->commit(); + if (myModule->sketchReentranceMgr()->processMouseReleased()) return; - } ModuleBase_IWorkshop* aWorkshop = myModule->workshop(); ModuleBase_IViewer* aViewer = aWorkshop->viewer(); @@ -479,15 +476,8 @@ void PartSet_SketcherMgr::onMouseReleased(ModuleBase_IViewWindow* theWnd, QMouse void PartSet_SketcherMgr::onMouseMoved(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent) { - if (myModule->isInternalEditOperation()) { - PartSet_WidgetPoint2D* aPoint2DWdg = dynamic_cast(myModule->activeWidget()); - if (aPoint2DWdg && aPoint2DWdg->canBeActivatedByMove()) { - ModuleBase_Operation* anOperation = getCurrentOperation(); - //if (operationMgr()->isApplyEnabled()) - anOperation->commit(); - return; - } - } + if (myModule->sketchReentranceMgr()->processMouseMoved()) + return; if (isNestedCreateOperation(getCurrentOperation()) && !myIsMouseOverViewProcessed) { myIsMouseOverViewProcessed = true; diff --git a/src/PartSet/PartSet_SketcherReetntrantMgr.cpp b/src/PartSet/PartSet_SketcherReetntrantMgr.cpp new file mode 100755 index 000000000..b4b926ae4 --- /dev/null +++ b/src/PartSet/PartSet_SketcherReetntrantMgr.cpp @@ -0,0 +1,278 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D + +#include "PartSet_SketcherReetntrantMgr.h" +#include "PartSet_Module.h" +#include "PartSet_SketcherMgr.h" +#include "PartSet_WidgetPoint2D.h" + +#include "ModelAPI_Session.h" + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +PartSet_SketcherReetntrantMgr::PartSet_SketcherReetntrantMgr(ModuleBase_IWorkshop* theWorkshop) +: QObject(theWorkshop), + myWorkshop(theWorkshop), + myIsInternalEditOperation(false), + myLastOperationId(""), + myPreviousAttributeID(""), + myRestartingMode(RM_None) +{ +} + +PartSet_SketcherReetntrantMgr::~PartSet_SketcherReetntrantMgr() +{ +} + +ModuleBase_ModelWidget* PartSet_SketcherReetntrantMgr::activeWidget() const +{ + ModuleBase_ModelWidget* aWidget = 0; + + ModuleBase_Operation* aOperation = myWorkshop->currentOperation(); + if (aOperation) { + ModuleBase_IPropertyPanel* aPanel = aOperation->propertyPanel(); + ModuleBase_ModelWidget* anActiveWidget = aPanel->activeWidget(); + if (myIsInternalEditOperation && (!anActiveWidget || !anActiveWidget->isViewerSelector())) { + // finds the first widget which can accept a value + QList aWidgets = aPanel->modelWidgets(); + ModuleBase_ModelWidget* aFirstWidget = 0; + ModuleBase_ModelWidget* aWgt; + QList::const_iterator aWIt; + for (aWIt = aWidgets.begin(); aWIt != aWidgets.end() && !aFirstWidget; ++aWIt) { + aWgt = (*aWIt); + if (aWgt->canSetValue()) + aFirstWidget = aWgt; + } + if (aFirstWidget) + aWidget = aFirstWidget; + } + } + return aWidget; +} + +bool PartSet_SketcherReetntrantMgr::operationCommitted(ModuleBase_Operation* theOperation) +{ + bool aProcessed = false; + ModuleBase_OperationFeature* aFOperation = dynamic_cast(theOperation); + if (!aFOperation) + return aProcessed; + + FeaturePtr aFeature = aFOperation->feature(); + std::shared_ptr aSPFeature = + std::dynamic_pointer_cast(aFeature); + if (aSPFeature && (myRestartingMode == RM_LastFeatureUsed || + myRestartingMode == RM_EmptyFeatureUsed)) { + myLastOperationId = aFOperation->id().toStdString(); + myLastFeature = myRestartingMode == RM_LastFeatureUsed ? aFOperation->feature() : FeaturePtr(); + PartSet_Module* aModule = module(); + if (!aModule->sketchMgr()->sketchSolverError()) { + if (!aFOperation->isEditOperation()) { + FeaturePtr anOperationFeature = aFOperation->feature(); + if (anOperationFeature.get() != NULL) { + aModule->editFeature(anOperationFeature); + aProcessed = true; + + myIsInternalEditOperation = true; + // activate selection filters of the first widget in the viewer + onInternalActivateFirstWidgetSelection(); + + // activate the last active widget in the Property Panel + if (!myPreviousAttributeID.empty()) { + ModuleBase_Operation* anEditOperation = aModule->currentOperation(); + if (anEditOperation) { + ModuleBase_IPropertyPanel* aPanel = aFOperation->propertyPanel(); + ModuleBase_ModelWidget* aPreviousAttributeWidget = 0; + QList aWidgets = aPanel->modelWidgets(); + for (int i = 0, aNb = aWidgets.size(); i < aNb && !aPreviousAttributeWidget; i++) { + if (aWidgets[i]->attributeID() == myPreviousAttributeID) + aPreviousAttributeWidget = aWidgets[i]; + } + // If the current widget is a selector, do nothing, it processes the mouse press + if (aPreviousAttributeWidget && !aPreviousAttributeWidget->isViewerSelector()) + aPreviousAttributeWidget->focusTo(); + } + } + } + } + else { + // the flag should be reset before start to do not react to the widget deactivate + myIsInternalEditOperation = false; + aModule->launchOperation(myLastOperationId.c_str()); + breakOperationSequence(); + aProcessed = true; + } + } + } + + if (!aProcessed) + breakOperationSequence(); + + return aProcessed; +} + +void PartSet_SketcherReetntrantMgr::operationAborted(ModuleBase_Operation* theOperation) +{ + if (myIsInternalEditOperation) { + // abort the created feature, which is currently edited + SessionPtr aMgr = ModelAPI_Session::get(); + if (aMgr->hasModuleDocument() && aMgr->canUndo()) { + aMgr->undo(); + } + } + myIsInternalEditOperation = false; + breakOperationSequence(); +} + +bool PartSet_SketcherReetntrantMgr::processMouseMoved() +{ + bool isProcessed = false; + if (myIsInternalEditOperation) { + PartSet_WidgetPoint2D* aPoint2DWdg = dynamic_cast(module()->activeWidget()); + if (aPoint2DWdg && aPoint2DWdg->canBeActivatedByMove()) { + ModuleBase_Operation* anOperation = myWorkshop->currentOperation(); + //if (operationMgr()->isApplyEnabled()) + anOperation->commit(); + isProcessed = true; + } + } + return isProcessed; +} + +bool PartSet_SketcherReetntrantMgr::processMousePressed() +{ + return myIsInternalEditOperation; +} + +bool PartSet_SketcherReetntrantMgr::processMouseReleased() +{ + bool isProcessed = false; + if (myIsInternalEditOperation) { + ModuleBase_Operation* anOperation = myWorkshop->currentOperation(); + //if (operationMgr()->isApplyEnabled()) + anOperation->commit(); + isProcessed = true; + } + return isProcessed; +} + +void PartSet_SketcherReetntrantMgr::propertyPanelDefined(ModuleBase_Operation* theOperation) +{ + ModuleBase_OperationFeature* aFOperation = dynamic_cast(theOperation); + if (!aFOperation) + return; + + ModuleBase_IPropertyPanel* aPanel = aFOperation->propertyPanel(); + if (PartSet_SketcherMgr::isSketchOperation(aFOperation) && (aFOperation->isEditOperation())) { + // we have to manually activate the sketch label in edit mode + aPanel->activateWidget(aPanel->modelWidgets().first()); + return; + } + + // Restart last operation type + if ((aFOperation->id() == myLastOperationId.c_str()) && myLastFeature) { + ModuleBase_ModelWidget* aWgt = aPanel->activeWidget(); + PartSet_WidgetPoint2D* aPoint2DWdg = dynamic_cast(module()->activeWidget()); + if (aPoint2DWdg && aPoint2DWdg->canBeActivatedByMove()) { + QList aSelection; + aSelection.append(ModuleBase_ViewerPrs(myLastFeature, TopoDS_Shape(), NULL)); + if (aPoint2DWdg->setSelection(aSelection, true)) + aPanel->activateNextWidget(aPoint2DWdg); + } + } +} + +void PartSet_SketcherReetntrantMgr::noMoreWidgets(const std::string& thePreviousAttributeID) +{ + ModuleBase_Operation* anOperation = myWorkshop->currentOperation(); + if (anOperation) { + if (PartSet_SketcherMgr::isNestedSketchOperation(anOperation)) { + if (myRestartingMode != RM_Forbided) { + myRestartingMode = RM_LastFeatureUsed; + myPreviousAttributeID = thePreviousAttributeID; + } + XGUI_Workshop* aWorkshop = workshop(); + XGUI_OperationMgr* anOpMgr = aWorkshop->operationMgr(); + // do nothing if the feature can not be applyed + if (anOpMgr->isApplyEnabled()) + anOperation->commit(); + } + } +} + +void PartSet_SketcherReetntrantMgr::vertexSelected() +{ + ModuleBase_Operation* aOperation = myWorkshop->currentOperation(); + if (aOperation->id().toStdString() == SketchPlugin_Line::ID()) { + /// If last line finished on vertex the lines creation sequence has to be break + ModuleBase_IPropertyPanel* aPanel = aOperation->propertyPanel(); + ModuleBase_ModelWidget* anActiveWidget = aPanel->activeWidget(); + const QList& aWidgets = aPanel->modelWidgets(); + QList::const_iterator anIt = aWidgets.begin(), aLast = aWidgets.end(); + bool aFoundWidget = false; + bool aFoundObligatory = false; + for (; anIt != aLast && !aFoundObligatory; anIt++) { + if (!aFoundWidget) + aFoundWidget = *anIt == anActiveWidget; + else + aFoundObligatory = (*anIt)->isObligatory(); + } + if (!aFoundObligatory) + myRestartingMode = RM_Forbided; + } +} + +void PartSet_SketcherReetntrantMgr::enterReleased() +{ + ModuleBase_OperationFeature* aFOperation = dynamic_cast + (myWorkshop->currentOperation()); + if (/*!aFOperation->isEditOperation() || */myIsInternalEditOperation) + myRestartingMode = RM_EmptyFeatureUsed; +} + +bool PartSet_SketcherReetntrantMgr::canBeCommittedByPreselection() +{ + return myRestartingMode == RM_None; +} + +void PartSet_SketcherReetntrantMgr::onInternalActivateFirstWidgetSelection() +{ + if (!myIsInternalEditOperation) + return; + + PartSet_Module* aModule = module(); + ModuleBase_ModelWidget* aFirstWidget = aModule->activeWidget(); + ModuleBase_IPropertyPanel* aPanel = aModule->currentOperation()->propertyPanel(); + if (aFirstWidget != aPanel->activeWidget()) { + ModuleBase_WidgetSelector* aWSelector = dynamic_cast(aFirstWidget); + if (aWSelector) + aWSelector->activateSelectionAndFilters(true); + } +} + +void PartSet_SketcherReetntrantMgr::breakOperationSequence() +{ + myLastOperationId = ""; + myLastFeature = FeaturePtr(); + myRestartingMode = RM_None; +} + +XGUI_Workshop* PartSet_SketcherReetntrantMgr::workshop() +{ + XGUI_ModuleConnector* aConnector = dynamic_cast(myWorkshop); + return aConnector->workshop(); +} + +PartSet_Module* PartSet_SketcherReetntrantMgr::module() +{ + return dynamic_cast(myWorkshop->module()); +} diff --git a/src/PartSet/PartSet_SketcherReetntrantMgr.h b/src/PartSet/PartSet_SketcherReetntrantMgr.h new file mode 100755 index 000000000..a3513ac6d --- /dev/null +++ b/src/PartSet/PartSet_SketcherReetntrantMgr.h @@ -0,0 +1,121 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D + +#ifndef PartSet_SketcherReetntrantMgr_H +#define PartSet_SketcherReetntrantMgr_H + +#include "PartSet.h" + +#include + +#include + +#include + +class ModuleBase_IWorkshop; +class ModuleBase_Operation; +class ModuleBase_ModelWidget; + +class XGUI_Workshop; +class PartSet_Module; + +/// \ingroup PartSet_SketcherReetntrantMgr +/// It provides reentrant create operations in sketch, that is when all inputs are valid, +/// automatic validation of the creation and switch the created entity to edit mode +/// ('internal' edit operation), +/// with the ability to simultaneously create the next entity of same type (re-entrance of the operation). +/// OK valids the current edition and exits from the operation (no re-entrance). +/// Cancel removes (undo) the entity currently edited and exits from the operation (no re-entrance). +class PARTSET_EXPORT PartSet_SketcherReetntrantMgr : public QObject +{ +Q_OBJECT + +/// Enumeration to specify the restart operation properties. +enum RestartingMode { + RM_None, /// the operation should not be restarted + RM_Forbided, /// the operation should not be restarted after there is no active widget + RM_LastFeatureUsed, /// the operation is restarted and use the previous feature for own initialization + RM_EmptyFeatureUsed /// the operation is restarted and does not use the previous feature +}; + +public: + /// Constructor + /// \param theParent a parent object + PartSet_SketcherReetntrantMgr(ModuleBase_IWorkshop* theWorkshop); + virtual ~PartSet_SketcherReetntrantMgr(); + +public: + /// If the internal edit operation is started, this is the first widget of the operation + ModuleBase_ModelWidget* activeWidget() const; + + /// Restarts sketcher operation automatically. If the commited operation is created, it starts + /// an 'internal' edit operation for the created feature. If an 'internal' operation is committed, + /// a create operation for a new feature with the current feature kind is started. + /// Some internal flags are taken into accout, such as whether the previous feature should be + /// used for initialization of created one or whether the restart of operation is forbidden. + /// \param theOperation a committed operation + /// \return true if an operation restarted + bool operationCommitted(ModuleBase_Operation* theOperation); + + /// \param theOperation a committed operation + void operationAborted(ModuleBase_Operation* theOperation); + + /// Return true if the manager processes the mouse move event + /// It happens if the current operation is an internal edit operation and the first + /// control can be filled by the mouse move event. The operation is committed. + /// \return true if operation is committed. + bool processMouseMoved(); + + /// Return true if the manager processes the mouse press event + /// \return true if the current operation is an internal edit operation. + bool processMousePressed(); + + /// Return true if the manager processes the mouse enter event + /// It happens if the current operation is an internal edit operation. + /// The operation is committed. + /// \return true if operation is committed. + bool processMouseReleased(); + + /// Activates the operation widgets relatively the internal reentrant flags + void propertyPanelDefined(ModuleBase_Operation* theOperation); + + /// It is called by no more widget signal emitted by property panel + /// Set a specific flag to restart the sketcher operation + void noMoreWidgets(const std::string& thePreviousAttributeID); + + /// Processing of vertex selected, if the feature is line, save flags to stop reentrant operation + void vertexSelected(); + + /// It is called by enter key released + /// Set a specific type of restarting the current operation + void enterReleased(); + + /// It is called by the current operation filling with the preselection. + /// Returns false if the reentrant mode of the operation is not empty. + bool canBeCommittedByPreselection(); + +public slots: + void onInternalActivateFirstWidgetSelection(); + +private: + /// Breaks sequense of automatically resterted operations + void breakOperationSequence(); + + /// Returns the workshop + XGUI_Workshop* workshop(); + + /// Returns the workshop module + PartSet_Module* module(); + +private: + ModuleBase_IWorkshop* myWorkshop; /// the workshop + + bool myIsInternalEditOperation; /// true when the 'internal' edit is started + + std::string myLastOperationId; + FeaturePtr myLastFeature; + + std::string myPreviousAttributeID; + RestartingMode myRestartingMode; /// Automatical restarting mode flag +}; + +#endif diff --git a/src/PartSet/PartSet_WidgetPoint2d.cpp b/src/PartSet/PartSet_WidgetPoint2d.cpp index 40b221c45..cbd3c9734 100644 --- a/src/PartSet/PartSet_WidgetPoint2d.cpp +++ b/src/PartSet/PartSet_WidgetPoint2d.cpp @@ -147,17 +147,36 @@ PartSet_WidgetPoint2D::~PartSet_WidgetPoint2D() bool PartSet_WidgetPoint2D::setSelection(QList& theValues, const bool theToValidate) { + bool isDone = false; if (theValues.empty()) - return false; + return isDone; ModuleBase_ViewerPrs aValue = theValues.takeFirst(); - - Handle(V3d_View) aView = myWorkshop->viewer()->activeView(); - bool isDone = false; TopoDS_Shape aShape = aValue.shape(); - double aX, aY; - if (getPoint2d(aView, aShape, aX, aY)) { - isDone = setPoint(aX, aY); + if (!aShape.IsNull()) { + Handle(V3d_View) aView = myWorkshop->viewer()->activeView(); + double aX, aY; + if (getPoint2d(aView, aShape, aX, aY)) { + isDone = setPoint(aX, aY); + } + } + else if (canBeActivatedByMove()) { + if (feature()->getKind() == SketchPlugin_Line::ID()) { + FeaturePtr aFeature = std::dynamic_pointer_cast(aValue.object()); + // Initialise new line with first point equal to end of previous + if (aFeature.get()) { + std::shared_ptr aData = aFeature->data(); + std::shared_ptr aPoint = + std::dynamic_pointer_cast( + aData->attribute(SketchPlugin_Line::END_ID())); + if (aPoint) { + setPoint(aPoint->x(), aPoint->y()); + PartSet_Tools::setConstraints(mySketch, feature(), attributeID(), aPoint->x(), + aPoint->y()); + isDone = true; + } + } + } } return isDone; } -- 2.39.2