From 8c61cbe058ed744affb3ae76379c8f3ce1d1cdf2 Mon Sep 17 00:00:00 2001 From: nds Date: Mon, 24 Aug 2015 12:02:17 +0300 Subject: [PATCH] Abort operation correction, Cases are: 1. Deselect feature button in ToolBar, 2. "Cancel" in warning of abort dialog should not abort the current operation. --- src/ModuleBase/ModuleBase_IModule.cpp | 18 ++++-- src/ModuleBase/ModuleBase_IWorkshop.h | 13 +++++ src/ModuleBase/ModuleBase_Operation.cpp | 5 -- src/ModuleBase/ModuleBase_Operation.h | 10 ---- src/XGUI/XGUI_ModuleConnector.cpp | 14 +++++ src/XGUI/XGUI_ModuleConnector.h | 13 +++++ src/XGUI/XGUI_OperationMgr.cpp | 78 +++++++++++++------------ src/XGUI/XGUI_OperationMgr.h | 9 ++- src/XGUI/XGUI_Workshop.cpp | 49 ++++------------ src/XGUI/XGUI_Workshop.h | 7 --- 10 files changed, 108 insertions(+), 108 deletions(-) diff --git a/src/ModuleBase/ModuleBase_IModule.cpp b/src/ModuleBase/ModuleBase_IModule.cpp index f15a9321f..1c69f0471 100644 --- a/src/ModuleBase/ModuleBase_IModule.cpp +++ b/src/ModuleBase/ModuleBase_IModule.cpp @@ -38,7 +38,6 @@ ModuleBase_IModule::ModuleBase_IModule(ModuleBase_IWorkshop* theParent) // SLOT(onMouseDoubleClick(QMouseEvent*))); } - void ModuleBase_IModule::launchOperation(const QString& theCmdId) { if (!myWorkshop->canStartOperation(theCmdId)) @@ -137,13 +136,20 @@ void ModuleBase_IModule::onFeatureTriggered() { QAction* aCmd = dynamic_cast(sender()); //Do nothing on uncheck - if (aCmd->isCheckable() && !aCmd->isChecked()) - return; - launchOperation(aCmd->data().toString()); - emit operationLaunched(); + if (aCmd->isCheckable() && !aCmd->isChecked()) { + ModuleBase_Operation* anOperation = myWorkshop->findStartedOperation(aCmd->data().toString()); + if (myWorkshop->canStopOperation()) + myWorkshop->abortOperation(anOperation); + else { + aCmd->setChecked(true); + } + } + else { + launchOperation(aCmd->data().toString()); + emit operationLaunched(); + } } - void ModuleBase_IModule::editFeature(FeaturePtr theFeature) { std::string aFeatureId = theFeature->getKind(); diff --git a/src/ModuleBase/ModuleBase_IWorkshop.h b/src/ModuleBase/ModuleBase_IWorkshop.h index c148fafc7..9e8f1a28f 100644 --- a/src/ModuleBase/ModuleBase_IWorkshop.h +++ b/src/ModuleBase/ModuleBase_IWorkshop.h @@ -74,6 +74,19 @@ Q_OBJECT //! Returns true if the operation with id theId can be started virtual bool canStartOperation(QString theId) = 0; + //! Returns started operation by the operation identifier + //! \param theId an operation id + //! \return an operation instance or NULL + virtual ModuleBase_Operation* findStartedOperation(const QString& theId) = 0; + + //! Returns true if the operation with id theId can be stopped + //! \return boolean result + virtual bool canStopOperation() = 0; + + //! Aborts the operation. + //! \param theId an aborted operation + virtual void abortOperation(ModuleBase_Operation* theOperation) = 0; + //! Returns AIS object by data object virtual AISObjectPtr findPresentation(const ObjectPtr& theObject) const = 0; diff --git a/src/ModuleBase/ModuleBase_Operation.cpp b/src/ModuleBase/ModuleBase_Operation.cpp index 6557d71b8..701b6a0cc 100644 --- a/src/ModuleBase/ModuleBase_Operation.cpp +++ b/src/ModuleBase/ModuleBase_Operation.cpp @@ -261,11 +261,6 @@ bool ModuleBase_Operation::commit() return false; } -void ModuleBase_Operation::setRunning(bool theState) -{ - emit triggered(theState); -} - void ModuleBase_Operation::onValuesChanged() { myIsModified = true; diff --git a/src/ModuleBase/ModuleBase_Operation.h b/src/ModuleBase/ModuleBase_Operation.h index 9d304e715..ec6cc4f49 100644 --- a/src/ModuleBase/ModuleBase_Operation.h +++ b/src/ModuleBase/ModuleBase_Operation.h @@ -151,10 +151,6 @@ signals: /// The operation is postponed void postponed(); - /// The operation is triggered - /// \param theState a new triggered state - void triggered(bool theState); - /// The operation is filled with existing preselection void activatedByPreselection(); @@ -188,12 +184,6 @@ signals: /// Redefine commitOperation method to change behavior of operation instead bool commit(); - /// Alias for start/abort slots - /// Public slot. Aborts operation if false, else does nothing. - /// Provided for S/S compatibility with QAction's toggle(bool) - /// \param theState th flag to abort, if it is true, do nothing, overwise abort - void setRunning(bool theState); - /// Changes the modified flag of the operation void onValuesChanged(); diff --git a/src/XGUI/XGUI_ModuleConnector.cpp b/src/XGUI/XGUI_ModuleConnector.cpp index 700b25bc7..301b10192 100644 --- a/src/XGUI/XGUI_ModuleConnector.cpp +++ b/src/XGUI/XGUI_ModuleConnector.cpp @@ -118,3 +118,17 @@ bool XGUI_ModuleConnector::canStartOperation(QString theId) return myWorkshop->operationMgr()->canStartOperation(theId); } +ModuleBase_Operation* XGUI_ModuleConnector::findStartedOperation(const QString& theId) +{ + return myWorkshop->operationMgr()->findOperation(theId); +} + +bool XGUI_ModuleConnector::canStopOperation() +{ + return myWorkshop->operationMgr()->canStopOperation(); +} + +void XGUI_ModuleConnector::abortOperation(ModuleBase_Operation* theOperation) +{ + myWorkshop->operationMgr()->abortOperation(theOperation); +} diff --git a/src/XGUI/XGUI_ModuleConnector.h b/src/XGUI/XGUI_ModuleConnector.h index cd64ffc09..428cefe32 100644 --- a/src/XGUI/XGUI_ModuleConnector.h +++ b/src/XGUI/XGUI_ModuleConnector.h @@ -57,6 +57,19 @@ Q_OBJECT //! Returns true if the operation with id theId can be started virtual bool canStartOperation(QString theId); + //! Returns started operation by the operation identifier. The operation manager is called. + //! \param theId an operation id + //! \return an operation instance or NULL + virtual ModuleBase_Operation* findStartedOperation(const QString& theId); + + //! Returns true if the operation with id theId can be stopped. The operation manager is called. + //! \return boolean result + virtual bool canStopOperation(); + + //! Aborts the operation. The operation manager is called. + //! \param theId an aborted operation + void abortOperation(ModuleBase_Operation* theOperation); + //! Returns AIS opbject 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 4cf7f3b85..63be4a0e7 100644 --- a/src/XGUI/XGUI_OperationMgr.cpp +++ b/src/XGUI/XGUI_OperationMgr.cpp @@ -123,23 +123,28 @@ bool XGUI_OperationMgr::startOperation(ModuleBase_Operation* theOperation) bool XGUI_OperationMgr::abortAllOperations() { - if(!hasOperation()) { - return true; - } else if (operationsCount() == 1) { - onAbortOperation(); - return true; + bool aResult = true; + if(!hasOperation()) + return aResult; + + if (operationsCount() == 1) { + if (canStopOperation()) { + abortOperation(currentOperation()); + } + else + aResult = false; } - QString aMessage = tr("All active operations will be aborted."); - int anAnswer = QMessageBox::question(qApp->activeWindow(), - tr("Abort operation"), - aMessage, - QMessageBox::Ok | QMessageBox::Cancel, - QMessageBox::Cancel); - bool result = anAnswer == QMessageBox::Ok; - while(result && hasOperation()) { - currentOperation()->abort(); + else { + aResult = QMessageBox::question(qApp->activeWindow(), + tr("Abort operation"), + tr("All active operations will be aborted."), + QMessageBox::Ok | QMessageBox::Cancel, + QMessageBox::Cancel) == QMessageBox::Ok; + while(aResult && hasOperation()) { + abortOperation(currentOperation()); + } } - return result; + return aResult; } bool XGUI_OperationMgr::commitAllOperations() @@ -150,7 +155,7 @@ bool XGUI_OperationMgr::commitAllOperations() if (isApplyEnabled()) { onCommitOperation(); } else { - anOperation->abort(); + abortOperation(anOperation); } FeaturePtr aFeature = anOperation->feature(); CompositeFeaturePtr aComposite = @@ -249,7 +254,7 @@ bool XGUI_OperationMgr::canStartOperation(QString theId) if (myIsApplyEnabled) aCurrentOp->commit(); else - aCurrentOp->abort(); + abortOperation(aCurrentOp); } else { aCanStart = false; } @@ -258,6 +263,23 @@ bool XGUI_OperationMgr::canStartOperation(QString theId) return aCanStart; } +void XGUI_OperationMgr::abortOperation(ModuleBase_Operation* theOperation) +{ + ModuleBase_Operation* aCurrentOperation = currentOperation(); + if (theOperation == aCurrentOperation) + theOperation->abort(); + else { + // it is possible to trigger upper operation(e.g. sketch, current is sketch line) + // all operation from the current to triggered should also be aborted + // operations over the parameter one are not aborted(e.g. extrusion cut, sketch abort) + while(hasOperation()) { + ModuleBase_Operation* aCurrentOperation = currentOperation(); + aCurrentOperation->abort(); + if(theOperation == aCurrentOperation) + break; + } + } +} void XGUI_OperationMgr::onCommitOperation() { @@ -269,7 +291,7 @@ void XGUI_OperationMgr::onCommitOperation() void XGUI_OperationMgr::onAbortOperation() { if (hasOperation() && canStopOperation()) { - currentOperation()->abort(); + abortOperation(currentOperation()); } } @@ -339,26 +361,6 @@ void XGUI_OperationMgr::onOperationStopped() } } -void XGUI_OperationMgr::onOperationTriggered(bool theState) -{ - ModuleBase_Operation* aSenderOperation = dynamic_cast(sender()); - if (aSenderOperation && !theState) { - ModuleBase_Operation* aCurrentOperation = currentOperation(); - if (aSenderOperation == aCurrentOperation) - aCurrentOperation->abort(); - else { - // it is possible to trigger upper operation(e.g. sketch, current is sketch line) - // all operation from the current to triggered should also be aborted - while(hasOperation()) { - ModuleBase_Operation* aCurrentOperation = currentOperation(); - aCurrentOperation->abort(); - if(aSenderOperation == aCurrentOperation) - break; - } - } - } -} - bool XGUI_OperationMgr::onKeyReleased(QKeyEvent* theEvent) { // Let the manager decide what to do with the given key combination. diff --git a/src/XGUI/XGUI_OperationMgr.h b/src/XGUI/XGUI_OperationMgr.h index 80c457b2b..582dc4ce4 100644 --- a/src/XGUI/XGUI_OperationMgr.h +++ b/src/XGUI/XGUI_OperationMgr.h @@ -84,6 +84,12 @@ Q_OBJECT /// \param theId id of the operation which is going to start bool canStartOperation(QString theId); + /// 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 + /// not aborted. + /// \param theOperation an aborted operation + void abortOperation(ModuleBase_Operation* theOperation); + /// Blocking/unblocking enabling of Ok button in property panel. /// It is used when operation can not be validated even all attributes are valid void setLockValidating(bool toLock); @@ -175,9 +181,6 @@ signals: /// Slot called on operation resume void onOperationResumed(); - /// Slot called on operation triggered - void onOperationTriggered(bool theState); - private: typedef QList Operations; ///< definition for a list of operations Operations myOperations; ///< a stack of started operations. The active operation is on top, diff --git a/src/XGUI/XGUI_Workshop.cpp b/src/XGUI/XGUI_Workshop.cpp index 933c8f395..f7c5cfe3b 100644 --- a/src/XGUI/XGUI_Workshop.cpp +++ b/src/XGUI/XGUI_Workshop.cpp @@ -377,7 +377,6 @@ void XGUI_Workshop::onOperationStarted(ModuleBase_Operation* theOperation) setNestedFeatures(theOperation); if (theOperation->getDescription()->hasXmlRepresentation()) { //!< No need for property panel - connectWithOperation(theOperation); setPropertyPanel(theOperation); // filling the operation values by the current selection // if the operation can be commited after the controls filling, the method perform should @@ -414,7 +413,6 @@ void XGUI_Workshop::onOperationResumed(ModuleBase_Operation* theOperation) setNestedFeatures(theOperation); if (theOperation->getDescription()->hasXmlRepresentation()) { //!< No need for property panel - // connectWithOperation(theOperation); already connected setPropertyPanel(theOperation); } updateCommandStatus(); @@ -502,28 +500,6 @@ void XGUI_Workshop::setPropertyPanel(ModuleBase_Operation* theOperation) myErrorMgr->setPropertyPanel(myPropertyPanel); } -/* - * Makes a signal/slot connections between Property Panel - * and given operation. The given operation becomes a - * current operation and previous operation if exists - */ -void XGUI_Workshop::connectWithOperation(ModuleBase_Operation* theOperation) -{ - QAction* aCommand = 0; - if (isSalomeMode()) { - aCommand = salomeConnector()->command(theOperation->getDescription()->operationId()); - } else { - AppElements_MainMenu* aMenu = myMainWindow->menuObject(); - FeaturePtr aFeature = theOperation->feature(); - if(aFeature) - aCommand = aMenu->feature(QString::fromStdString(aFeature->getKind())); - } - //Abort operation on uncheck the command - if (aCommand) { - connect(aCommand, SIGNAL(triggered(bool)), theOperation, SLOT(setRunning(bool))); - } -} - /* * Saves document with given name. */ @@ -677,9 +653,12 @@ bool XGUI_Workshop::onSaveAs() void XGUI_Workshop::onUndo(int theTimes) { objectBrowser()->treeView()->setCurrentIndex(QModelIndex()); + if (operationMgr()->canStopOperation()) + operationMgr()->abortOperation(operationMgr()->currentOperation()); + else + return; + SessionPtr aMgr = ModelAPI_Session::get(); - if (aMgr->isOperation()) - operationMgr()->onAbortOperation(); for (int i = 0; i < theTimes; ++i) { aMgr->undo(); } @@ -690,6 +669,11 @@ void XGUI_Workshop::onUndo(int theTimes) //****************************************************** void XGUI_Workshop::onRedo(int theTimes) { + if (operationMgr()->canStopOperation()) + operationMgr()->abortOperation(operationMgr()->currentOperation()); + else + return; + // the viewer update should be blocked in order to avoid the features blinking. For the created // feature a results are created, the flush of the created signal caused the viewer redisplay for // each created result. After a redisplay signal is flushed. So, the viewer update is blocked until @@ -698,8 +682,6 @@ void XGUI_Workshop::onRedo(int theTimes) objectBrowser()->treeView()->setCurrentIndex(QModelIndex()); SessionPtr aMgr = ModelAPI_Session::get(); - if (aMgr->isOperation()) - operationMgr()->onAbortOperation(); for (int i = 0; i < theTimes; ++i) { aMgr->redo(); } @@ -975,17 +957,6 @@ void XGUI_Workshop::hideObjectBrowser() myObjectBrowser->parentWidget()->hide(); } -//****************************************************** -//void XGUI_Workshop::onFeatureTriggered() -//{ -// QAction* aCmd = dynamic_cast(sender()); -// if (aCmd) { -// QString aId = salomeConnector()->commandId(aCmd); -// if (!aId.isNull()) -// myModule->launchOperation(aId); -// } -//} - //****************************************************** void XGUI_Workshop::salomeViewerSelectionChanged() { diff --git a/src/XGUI/XGUI_Workshop.h b/src/XGUI/XGUI_Workshop.h index cc51d7880..510ee796d 100644 --- a/src/XGUI/XGUI_Workshop.h +++ b/src/XGUI/XGUI_Workshop.h @@ -304,9 +304,6 @@ signals: /// Hide object Browser void hideObjectBrowser(); - /// Reaction on command call - //void onFeatureTriggered(); - /// Close document void closeDocument(); @@ -320,10 +317,6 @@ signals: /// \param theOperation an operation void setPropertyPanel(ModuleBase_Operation* theOperation); - /// Connect to operation signals - /// \param theOperation an operation - void connectWithOperation(ModuleBase_Operation* theOperation); - private: /// Display all results //void displayAllResults(); -- 2.39.2