From 410f0c3d028be602c474a6ee64b8d3a7a32afb25 Mon Sep 17 00:00:00 2001 From: nds Date: Tue, 4 Apr 2017 08:49:30 +0300 Subject: [PATCH] Issue #2024 Redesign of circle and arc of circle : restart operation will not happen if the previous cannot be committed. E.g. Line feature Sometimes there is a crash by line restart if the previous Line creation is aborted: in processEvent of Line feature, where the attribute of previous created feature is used to build coincidence to start point of new feature Line. --- src/ModuleBase/ModuleBase_IModule.cpp | 24 +++++++++++----- src/ModuleBase/ModuleBase_IModule.h | 5 +++- src/ModuleBase/ModuleBase_IWorkshop.h | 6 ++-- src/PartSet/PartSet_MenuMgr.cpp | 6 ++-- src/PartSet/PartSet_Module.cpp | 30 +++----------------- src/PartSet/PartSet_Module.h | 10 +++---- src/PartSet/PartSet_SketcherMgr.cpp | 14 ++++----- src/PartSet/PartSet_SketcherReentrantMgr.cpp | 7 +++-- src/XGUI/XGUI_ModuleConnector.cpp | 9 +++--- src/XGUI/XGUI_ModuleConnector.h | 8 ++++-- src/XGUI/XGUI_OperationMgr.cpp | 13 +++++---- src/XGUI/XGUI_OperationMgr.h | 6 ++-- 12 files changed, 71 insertions(+), 67 deletions(-) diff --git a/src/ModuleBase/ModuleBase_IModule.cpp b/src/ModuleBase/ModuleBase_IModule.cpp index 7dc2d8f82..39f9abc79 100644 --- a/src/ModuleBase/ModuleBase_IModule.cpp +++ b/src/ModuleBase/ModuleBase_IModule.cpp @@ -56,7 +56,8 @@ ModuleBase_IModule::ModuleBase_IModule(ModuleBase_IWorkshop* theParent) void ModuleBase_IModule::launchModal(const QString& theCmdId) { - if (!myWorkshop->canStartOperation(theCmdId)) + bool isCommitted; + if (!myWorkshop->canStartOperation(theCmdId, isCommitted)) return; std::string aXmlCfg, aDescription; @@ -74,7 +75,8 @@ void ModuleBase_IModule::launchModal(const QString& theCmdId) } -void ModuleBase_IModule::launchOperation(const QString& theCmdId) +void ModuleBase_IModule::launchOperation(const QString& theCmdId, + const bool& isStartAfterCommitOnly) { /// selection should be obtained from workshop before ask if the operation can be started as /// the canStartOperation method performs commit/abort of previous operation. @@ -84,7 +86,12 @@ void ModuleBase_IModule::launchOperation(const QString& theCmdId) QList aPreSelected = aSelection->getSelected(ModuleBase_ISelection::AllControls); - if (!myWorkshop->canStartOperation(theCmdId)) + bool isCommitted; + if (!myWorkshop->canStartOperation(theCmdId, isCommitted)) + return; + + /// reentrant operation(Sketch Line) should not be started if operation is aborted + if (isStartAfterCommitOnly && !isCommitted) return; ModuleBase_OperationFeature* aFOperation = dynamic_cast @@ -220,8 +227,10 @@ void ModuleBase_IModule::onFeatureTriggered() //Do nothing on uncheck if (aCmd->isCheckable() && !aCmd->isChecked()) { ModuleBase_Operation* anOperation = myWorkshop->findStartedOperation(aCmd->data().toString()); - if (myWorkshop->canStopOperation(anOperation)) - myWorkshop->stopOperation(anOperation); + if (myWorkshop->canStopOperation(anOperation)) { + bool isCommitted; + myWorkshop->stopOperation(anOperation, isCommitted); + } else { aCmd->setChecked(true); } @@ -232,7 +241,7 @@ void ModuleBase_IModule::onFeatureTriggered() if (aInfo.get() && aInfo->isModal()) { launchModal(aCmdId); } else { - launchOperation(aCmdId); + launchOperation(aCmdId, false); emit operationLaunched(); } } @@ -241,7 +250,8 @@ void ModuleBase_IModule::onFeatureTriggered() void ModuleBase_IModule::editFeature(FeaturePtr theFeature) { std::string aFeatureId = theFeature->getKind(); - if (!myWorkshop->canStartOperation(aFeatureId.c_str())) + bool isCommitted; + if (!myWorkshop->canStartOperation(aFeatureId.c_str(), isCommitted)) return; ModuleBase_OperationFeature* aFOperation = dynamic_cast diff --git a/src/ModuleBase/ModuleBase_IModule.h b/src/ModuleBase/ModuleBase_IModule.h index 62b746eab..11a32c888 100755 --- a/src/ModuleBase/ModuleBase_IModule.h +++ b/src/ModuleBase/ModuleBase_IModule.h @@ -85,7 +85,10 @@ class MODULEBASE_EXPORT ModuleBase_IModule : public QObject /// Creates an operation and send it to loop /// \param theCmdId the operation name - virtual void launchOperation(const QString& theCmdId); + /// \param isStartAfterCommitOnly operation is launched if there is no active operation or + /// it is committed + virtual void launchOperation(const QString& theCmdId, + const bool& isStartAfterCommitOnly); /// Executes feature as a modal dialog box /// \param theCmdId the operation name diff --git a/src/ModuleBase/ModuleBase_IWorkshop.h b/src/ModuleBase/ModuleBase_IWorkshop.h index a9c66405d..97e13ffbb 100644 --- a/src/ModuleBase/ModuleBase_IWorkshop.h +++ b/src/ModuleBase/ModuleBase_IWorkshop.h @@ -74,7 +74,7 @@ Q_OBJECT virtual ModuleBase_Operation* currentOperation() const = 0; //! Returns true if the operation with id theId can be started - virtual bool canStartOperation(QString theId) = 0; + virtual bool canStartOperation(QString theId, bool& isCommitted) = 0; //! Performs the operation launch //! \param theOperation an operation to be launched @@ -92,7 +92,9 @@ Q_OBJECT //! Commits if possible or aborts the given operation. //! \param theOperation an aborted operation - virtual void stopOperation(ModuleBase_Operation* theOperation) = 0; + /// \param isCommitted boolean value if the operation was committed otherwise it was aborted + virtual void stopOperation(ModuleBase_Operation* theOperation, + bool& isCommitted) = 0; //! Returns AIS object by data object //! \param theObject a data object diff --git a/src/PartSet/PartSet_MenuMgr.cpp b/src/PartSet/PartSet_MenuMgr.cpp index b249f2311..c65d42515 100644 --- a/src/PartSet/PartSet_MenuMgr.cpp +++ b/src/PartSet/PartSet_MenuMgr.cpp @@ -299,7 +299,8 @@ void PartSet_MenuMgr::onLineDetach(QAction* theAction) // the active nested sketch operation should be aborted unconditionally // the Delete action should be additionally granted for the Sketch operation // in order to do not abort/commit it - if (!anOpMgr->canStartOperation(tr("Detach"))) + bool isCommitted; + if (!anOpMgr->canStartOperation(tr("Detach"), isCommitted)) return; // the objects are processed but can not be deleted anOpMgr->startOperation(anOpAction); @@ -358,7 +359,8 @@ void PartSet_MenuMgr::setAuxiliary(const bool isChecked) anOpAction = new ModuleBase_OperationAction(anAction->text(), myModule); bool isSketchOp = PartSet_SketcherMgr::isSketchOperation(anOperation); - if (!anOpMgr->canStartOperation(anOpAction->id())) + bool isCommitted; + if (!anOpMgr->canStartOperation(anOpAction->id(), isCommitted)) return; // the objects are processed but can not be deleted anOpMgr->startOperation(anOpAction); diff --git a/src/PartSet/PartSet_Module.cpp b/src/PartSet/PartSet_Module.cpp index 41c2d3b04..e1bac3b35 100755 --- a/src/PartSet/PartSet_Module.cpp +++ b/src/PartSet/PartSet_Module.cpp @@ -828,7 +828,8 @@ bool PartSet_Module::deleteObjects() // the active nested sketch operation should be aborted unconditionally // the Delete action should be additionally granted for the Sketch operation // in order to do not abort/commit it - if (!anOpMgr->canStartOperation(anOpAction->id())) + bool isCommitted; + if (!anOpMgr->canStartOperation(anOpAction->id(), isCommitted)) return true; // the objects are processed but can not be deleted anOpMgr->startOperation(anOpAction); @@ -850,29 +851,6 @@ bool PartSet_Module::deleteObjects() return isProcessed; } -void PartSet_Module::onFeatureTriggered() -{ - // is commented for imp: Unpressing the button of the current action must behave like - // a validation if the entity can be created (instead of Cancel, as currently) - /*QAction* aCmd = dynamic_cast(sender()); - if (aCmd->isCheckable() && aCmd->isChecked()) { - // 1. check whether the delete should be processed in the module - ModuleBase_Operation* anOperation = myWorkshop->currentOperation(); - bool isNestedOp = myModule->sketchMgr()->isNestedCreateOperation(anOperation); - if (isNestedOp) { - // in case if in the viewer nothing is displayed, the create operation should not be - // comitted even if all values of the feature are initialized - if (!mySketchMgr->canDisplayCurrentCreatedFeature()) { - // the action information should be saved before the operation is aborted - // because this abort leads to update command status, which unchecks this action - anOperation->abort(); - launchOperation(aCmd->data().toString()); - } - } - }*/ - ModuleBase_IModule::onFeatureTriggered(); -} - void PartSet_Module::editFeature(FeaturePtr theFeature) { storeConstraintsState(theFeature->getKind()); @@ -884,13 +862,13 @@ bool PartSet_Module::canCommitOperation() const return true; } -void PartSet_Module::launchOperation(const QString& theCmdId) +void PartSet_Module::launchOperation(const QString& theCmdId, const bool& isStartAfterCommitOnly) { myIsOperationIsLaunched = true; storeConstraintsState(theCmdId.toStdString()); updateConstraintsState(theCmdId.toStdString()); - ModuleBase_IModule::launchOperation(theCmdId); + ModuleBase_IModule::launchOperation(theCmdId, isStartAfterCommitOnly); myIsOperationIsLaunched = false; } diff --git a/src/PartSet/PartSet_Module.h b/src/PartSet/PartSet_Module.h index 7292bb30a..649e3d3e2 100755 --- a/src/PartSet/PartSet_Module.h +++ b/src/PartSet/PartSet_Module.h @@ -106,7 +106,10 @@ public: /// Creates an operation and send it to loop /// \param theCmdId the operation name - virtual void launchOperation(const QString& theCmdId); + /// \param isStartAfterCommitOnly operation is launched if there is no active operation or + /// it is committed + virtual void launchOperation(const QString& theCmdId, + const bool& isStartAfterCommitOnly); /// Realizes some functionality by an operation start /// Displays all sketcher sub-Objects, hides sketcher result, appends selection filters @@ -349,11 +352,6 @@ public: XGUI_Workshop* getWorkshop() const; public slots: - /// 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. - virtual void onFeatureTriggered(); - /// Slolt called on object display /// \param theObject a data object /// \param theAIS a presentation object diff --git a/src/PartSet/PartSet_SketcherMgr.cpp b/src/PartSet/PartSet_SketcherMgr.cpp index a63586cef..f724f3aa6 100755 --- a/src/PartSet/PartSet_SketcherMgr.cpp +++ b/src/PartSet/PartSet_SketcherMgr.cpp @@ -306,17 +306,15 @@ void PartSet_SketcherMgr::onAfterValuesChangedInPropertyPanel() void PartSet_SketcherMgr::onMousePressed(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent) { + // Clear dragging mode + myIsDragging = false; + if (myModule->sketchReentranceMgr()->processMousePressed(theWnd, theEvent)) return; - //get2dPoint(theWnd, theEvent, myClickedPoint); - if (!(theEvent->buttons() & Qt::LeftButton)) return; - // Clear dragging mode - myIsDragging = false; - ModuleBase_IWorkshop* aWorkshop = myModule->workshop(); ModuleBase_IViewer* aViewer = aWorkshop->viewer(); if (!aViewer->canDragByMouse()) @@ -425,6 +423,9 @@ void PartSet_SketcherMgr::onMousePressed(ModuleBase_IViewWindow* theWnd, QMouseE void PartSet_SketcherMgr::onMouseReleased(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent) { + bool aWasDragging = myIsDragging; + myIsDragging = false; + if (myModule->sketchReentranceMgr()->processMouseReleased(theWnd, theEvent)) return; @@ -440,7 +441,7 @@ void PartSet_SketcherMgr::onMouseReleased(ModuleBase_IViewWindow* theWnd, QMouse if (aOp) { if (isNestedSketchOperation(aOp)) { // Only for sketcher operations - if (myIsDragging) { + if (aWasDragging) { if (myDragDone) { myCurrentSelection.clear(); } @@ -449,7 +450,6 @@ void PartSet_SketcherMgr::onMouseReleased(ModuleBase_IViewWindow* theWnd, QMouse } aWorkshop->viewer()->enableDrawMode(myPreviousDrawModeEnabled); - myIsDragging = false; ModuleBase_ModelWidget* anActiveWidget = getActiveWidget(); PartSet_MouseProcessor* aProcessor = dynamic_cast(anActiveWidget); diff --git a/src/PartSet/PartSet_SketcherReentrantMgr.cpp b/src/PartSet/PartSet_SketcherReentrantMgr.cpp index b355a8869..b9c92f940 100644 --- a/src/PartSet/PartSet_SketcherReentrantMgr.cpp +++ b/src/PartSet/PartSet_SketcherReentrantMgr.cpp @@ -546,15 +546,16 @@ void PartSet_SketcherReentrantMgr::restartOperation() QList aPreSelected = aSelection->getSelected(ModuleBase_ISelection::AllControls); - - if (myInternalFeature.get()) copyReetntrantAttributes(myInternalFeature, aFOperation->feature(), module()->sketchMgr()->activeSketch()); myNoMoreWidgetsAttribute = ""; myIsFlagsBlocked = true; - module()->launchOperation(aFOperation->id()); + /// launch has 'false' parameter to do not start new operation if the previous operation + /// is not committed. It is important for Line Sketch feature as it uses the previous + /// created feature parameter(to build coincidence), but by abort the previous is removed + module()->launchOperation(aFOperation->id(), true); myIsFlagsBlocked = false; resetFlags(); diff --git a/src/XGUI/XGUI_ModuleConnector.cpp b/src/XGUI/XGUI_ModuleConnector.cpp index e6b6cf73f..51358f13c 100644 --- a/src/XGUI/XGUI_ModuleConnector.cpp +++ b/src/XGUI/XGUI_ModuleConnector.cpp @@ -131,9 +131,9 @@ void XGUI_ModuleConnector::setStatusBarMessage(const QString& theMessage) myWorkshop->setStatusBarMessage(theMessage); } -bool XGUI_ModuleConnector::canStartOperation(QString theId) +bool XGUI_ModuleConnector::canStartOperation(QString theId, bool& isCommitted) { - return myWorkshop->operationMgr()->canStartOperation(theId); + return myWorkshop->operationMgr()->canStartOperation(theId, isCommitted); } void XGUI_ModuleConnector::processLaunchOperation(ModuleBase_Operation* theOperation) @@ -164,9 +164,10 @@ bool XGUI_ModuleConnector::canStopOperation(ModuleBase_Operation* theOperation) return myWorkshop->operationMgr()->canStopOperation(theOperation); } -void XGUI_ModuleConnector::stopOperation(ModuleBase_Operation* theOperation) +void XGUI_ModuleConnector::stopOperation(ModuleBase_Operation* theOperation, + bool& isCommitted) { - myWorkshop->operationMgr()->stopOperation(theOperation); + myWorkshop->operationMgr()->stopOperation(theOperation, isCommitted); } void XGUI_ModuleConnector::updateCommandStatus() diff --git a/src/XGUI/XGUI_ModuleConnector.h b/src/XGUI/XGUI_ModuleConnector.h index eb4c37c4f..543d0279a 100644 --- a/src/XGUI/XGUI_ModuleConnector.h +++ b/src/XGUI/XGUI_ModuleConnector.h @@ -57,7 +57,9 @@ Q_OBJECT virtual ModuleBase_Operation* currentOperation() const; //! Returns true if the operation with id theId can be started - virtual bool canStartOperation(QString theId); + /// \param theId id of the operation which is going to start + /// \param isCommitted boolean value if the operation was committed otherwise it was aborted + virtual bool canStartOperation(QString theId, bool& isCommitted); //! Performs the operation launch //! \param theOperation an operation to be launched @@ -75,7 +77,9 @@ Q_OBJECT //! Commits if possible or aborts the given operation. //! \param theOperation an aborted operation - virtual void stopOperation(ModuleBase_Operation* theOperation); + /// \param isCommitted boolean value if the operation was committed otherwise it was aborted + virtual void stopOperation(ModuleBase_Operation* theOperation, + bool& isCommitted); //! Returns AIS object by data object virtual AISObjectPtr findPresentation(const ObjectPtr& theObject) const; diff --git a/src/XGUI/XGUI_OperationMgr.cpp b/src/XGUI/XGUI_OperationMgr.cpp index 6c234bee8..61adc99ea 100644 --- a/src/XGUI/XGUI_OperationMgr.cpp +++ b/src/XGUI/XGUI_OperationMgr.cpp @@ -355,9 +355,10 @@ void XGUI_OperationMgr::setCurrentFeature(const FeaturePtr& theFeature) aMgr->finishOperation(); } -bool XGUI_OperationMgr::canStartOperation(const QString& theId) +bool XGUI_OperationMgr::canStartOperation(const QString& theId, bool& isCommitted) { bool aCanStart = true; + isCommitted = false; ModuleBase_Operation* aCurrentOp = currentOperation(); if (aCurrentOp) { bool aGranted = aCurrentOp->isGranted(theId); @@ -375,7 +376,7 @@ bool XGUI_OperationMgr::canStartOperation(const QString& theId) else if (canStopOperation(aCurrentOp)) { // the started operation is granted in the parrent operation, // e.g. current - Line in Sketch, started Circle - stopOperation(aCurrentOp); + stopOperation(aCurrentOp, isCommitted); } else { aCanStart = false; } @@ -384,12 +385,14 @@ bool XGUI_OperationMgr::canStartOperation(const QString& theId) return aCanStart; } -void XGUI_OperationMgr::stopOperation(ModuleBase_Operation* theOperation) +void XGUI_OperationMgr::stopOperation(ModuleBase_Operation* theOperation, bool& isCommitted) { if (XGUI_Tools::workshop(myWorkshop)->errorMgr()->isApplyEnabled() && theOperation->isModified()) - theOperation->commit(); - else + isCommitted = theOperation->commit(); + else { + isCommitted = false; abortOperation(theOperation); + } } void XGUI_OperationMgr::abortOperation(ModuleBase_Operation* theOperation) diff --git a/src/XGUI/XGUI_OperationMgr.h b/src/XGUI/XGUI_OperationMgr.h index cca5bb926..c8ccf9d08 100755 --- a/src/XGUI/XGUI_OperationMgr.h +++ b/src/XGUI/XGUI_OperationMgr.h @@ -101,11 +101,13 @@ Q_OBJECT /// Returns whether the operation can be started. Check if there is already started operation and /// the granted parameter of the launched operation /// \param theId id of the operation which is going to start - bool canStartOperation(const QString& theId); + /// \param isCommitted boolean value if the operation was committed otherwise it was aborted + bool canStartOperation(const QString& theId, bool& isCommitted); /// If Apply is enabled and operation has modification, it is applyed, otherwise aborted /// \param theOperation the started operation - void stopOperation(ModuleBase_Operation* theOperation); + /// \param isCommitted boolean value if the operation was committed otherwise it was aborted + void stopOperation(ModuleBase_Operation* theOperation, bool& isCommitted); /// Aborts the parameter operation if it is current, else abort operations from the stack /// of operations until the operation is found. All operations upper the parameter one are -- 2.30.2