From 02bc870879ae19215d5ef6f721acd5b12d245473 Mon Sep 17 00:00:00 2001 From: sbh Date: Wed, 17 Sep 2014 12:18:36 +0400 Subject: [PATCH] Bugfix for issue #107 which also works for issue #82 * Process Enter, Retrun and Esc keys for all operations * Same behavior for property pannel's ok/cancel and return/esc shortcuts * Abort all active operations on Save/Open actions, not only the current one --- src/ModuleBase/ModuleBase_Operation.cpp | 3 +- src/ModuleBase/ModuleBase_Operation.h | 2 +- .../PartSet_OperationFeatureCreate.cpp | 25 ++-- src/PartSet/PartSet_OperationFeatureCreate.h | 2 +- src/PartSet/PartSet_OperationFeatureEdit.cpp | 7 +- src/PartSet/PartSet_OperationFeatureEdit.h | 2 +- src/PartSet/PartSet_OperationSketchBase.cpp | 23 ---- src/PartSet/PartSet_OperationSketchBase.h | 4 - src/XGUI/XGUI_OperationMgr.cpp | 120 ++++++++++-------- src/XGUI/XGUI_OperationMgr.h | 35 ++--- src/XGUI/XGUI_Workshop.cpp | 10 +- 11 files changed, 112 insertions(+), 121 deletions(-) diff --git a/src/ModuleBase/ModuleBase_Operation.cpp b/src/ModuleBase/ModuleBase_Operation.cpp index 30062efc4..12eb36e53 100644 --- a/src/ModuleBase/ModuleBase_Operation.cpp +++ b/src/ModuleBase/ModuleBase_Operation.cpp @@ -174,8 +174,9 @@ bool ModuleBase_Operation::hasObject(ObjectPtr theObj) const return false; } -void ModuleBase_Operation::keyReleased(const int theKey) +bool ModuleBase_Operation::keyReleased(const int theKey) { // Do nothing... + return false; } diff --git a/src/ModuleBase/ModuleBase_Operation.h b/src/ModuleBase/ModuleBase_Operation.h index 4fd5eff1b..e29bdc6bc 100644 --- a/src/ModuleBase/ModuleBase_Operation.h +++ b/src/ModuleBase/ModuleBase_Operation.h @@ -72,7 +72,7 @@ Q_OBJECT /// Returns True if the current operation works with the given object (feature or result) virtual bool hasObject(ObjectPtr theObj) const; - virtual void keyReleased(const int theKey); + virtual bool keyReleased(const int theKey); public slots: /// Slots which listen the mode widget activation diff --git a/src/PartSet/PartSet_OperationFeatureCreate.cpp b/src/PartSet/PartSet_OperationFeatureCreate.cpp index c56fe194f..0bfd4a4bc 100644 --- a/src/PartSet/PartSet_OperationFeatureCreate.cpp +++ b/src/PartSet/PartSet_OperationFeatureCreate.cpp @@ -35,6 +35,7 @@ #ifdef _DEBUG #include +#include #endif #include @@ -103,13 +104,6 @@ void PartSet_OperationFeatureCreate::mouseReleased( const std::list& theSelected, const std::list& /*theHighlighted*/) { - if (commit()) { - // if the point creation is finished, the next mouse release should commit the modification - // the next release can happens by double click in the viewer - restartOperation(feature()->getKind(), feature()); - return; - } - gp_Pnt aPoint = PartSet_Tools::convertClickToPoint(theEvent->pos(), theView); double aX = aPoint.X(), anY = aPoint.Y(); @@ -126,8 +120,7 @@ void PartSet_OperationFeatureCreate::mouseReleased( aPoint = BRep_Tool::Pnt(aVertex); PartSet_Tools::convertTo2D(aPoint, sketch(), theView, aX, anY); - PartSet_Tools::setConstraints(sketch(), feature(), myActiveWidget->attributeID(), aX, - anY); + PartSet_Tools::setConstraints(sketch(), feature(), myActiveWidget->attributeID(), aX, anY); } } else if (aShape.ShapeType() == TopAbs_EDGE) // the line is selected { @@ -152,19 +145,22 @@ void PartSet_OperationFeatureCreate::mouseReleased( flushUpdated(); emit activateNextWidget(myActiveWidget); } + + if (commit()) { + // if the point creation is finished, the next mouse release should commit the modification + // the next release can happens by double click in the viewer + restartOperation(feature()->getKind(), feature()); + return; + } } void PartSet_OperationFeatureCreate::mouseMoved(QMouseEvent* theEvent, Handle(V3d_View) theView) { - if (commit()) { - restartOperation(feature()->getKind(), feature()); - } else { double aX, anY; gp_Pnt aPoint = PartSet_Tools::convertClickToPoint(theEvent->pos(), theView); PartSet_Tools::convertTo2D(aPoint, sketch(), theView, aX, anY); setWidgetValue(feature(), aX, anY); flushUpdated(); - } } void PartSet_OperationFeatureCreate::onWidgetActivated(ModuleBase_ModelWidget* theWidget) @@ -188,7 +184,7 @@ void PartSet_OperationFeatureCreate::onWidgetActivated(ModuleBase_ModelWidget* t } } -void PartSet_OperationFeatureCreate::keyReleased(const int theKey) +bool PartSet_OperationFeatureCreate::keyReleased(const int theKey) { switch (theKey) { case Qt::Key_Return: @@ -208,6 +204,7 @@ void PartSet_OperationFeatureCreate::keyReleased(const int theKey) default: break; } + return true; } void PartSet_OperationFeatureCreate::startOperation() diff --git a/src/PartSet/PartSet_OperationFeatureCreate.h b/src/PartSet/PartSet_OperationFeatureCreate.h index 730ab7aa6..6fcadf5c0 100644 --- a/src/PartSet/PartSet_OperationFeatureCreate.h +++ b/src/PartSet/PartSet_OperationFeatureCreate.h @@ -71,7 +71,7 @@ Q_OBJECT virtual void mouseMoved(QMouseEvent* theEvent, Handle_V3d_View theView); /// Processes the key pressed in the view /// \param theKey a key value - virtual void keyReleased(const int theKey); + virtual bool keyReleased(const int theKey); public slots: /// Slots which listen the mode widget activation diff --git a/src/PartSet/PartSet_OperationFeatureEdit.cpp b/src/PartSet/PartSet_OperationFeatureEdit.cpp index 2bbc2229e..6524fc215 100644 --- a/src/PartSet/PartSet_OperationFeatureEdit.cpp +++ b/src/PartSet/PartSet_OperationFeatureEdit.cpp @@ -161,12 +161,13 @@ void PartSet_OperationFeatureEdit::mouseDoubleClick( } } -void PartSet_OperationFeatureEdit::keyReleased(const int theKey) +bool PartSet_OperationFeatureEdit::keyReleased(const int theKey) { if (theKey == Qt::Key_Return || theKey == Qt::Key_Enter) { commit(); - } else - PartSet_OperationSketchBase::keyReleased(theKey); + return true; + } + return PartSet_OperationSketchBase::keyReleased(theKey); } void PartSet_OperationFeatureEdit::startOperation() diff --git a/src/PartSet/PartSet_OperationFeatureEdit.h b/src/PartSet/PartSet_OperationFeatureEdit.h index 3d73b3bd3..0f7ed18c8 100644 --- a/src/PartSet/PartSet_OperationFeatureEdit.h +++ b/src/PartSet/PartSet_OperationFeatureEdit.h @@ -113,7 +113,7 @@ Q_OBJECT /// Processes the key pressed in the view /// \param theKey a key value - virtual void keyReleased(const int theKey); + virtual bool keyReleased(const int theKey); protected: /// \brief Virtual method called when operation is started diff --git a/src/PartSet/PartSet_OperationSketchBase.cpp b/src/PartSet/PartSet_OperationSketchBase.cpp index 93c1818e1..398293c61 100644 --- a/src/PartSet/PartSet_OperationSketchBase.cpp +++ b/src/PartSet/PartSet_OperationSketchBase.cpp @@ -96,29 +96,6 @@ void PartSet_OperationSketchBase::mouseDoubleClick( { } -void PartSet_OperationSketchBase::keyReleased(const int theKey) -{ - switch (theKey) { - case Qt::Key_Escape: { - bool toAbort = true; - if (isModified()) { - int anAnswer = QMessageBox::question( - qApp->activeWindow(), - tr("Cancel operation"), - tr("Do you want to cancel %1 operation?").arg(id()), - QMessageBox::Yes, - QMessageBox::No); - toAbort = (anAnswer == QMessageBox::Yes); - } - if (toAbort) - abort(); - } - break; - default: - break; - } -} - void PartSet_OperationSketchBase::restartOperation(const std::string& theType, ObjectPtr theFeature) { FeaturePtr aFeature = ModelAPI_Feature::feature(theFeature); diff --git a/src/PartSet/PartSet_OperationSketchBase.h b/src/PartSet/PartSet_OperationSketchBase.h index e2e992dd7..878c56dd4 100644 --- a/src/PartSet/PartSet_OperationSketchBase.h +++ b/src/PartSet/PartSet_OperationSketchBase.h @@ -114,10 +114,6 @@ Q_OBJECT const std::list& theSelected, const std::list& theHighlighted); - /// Processes the key pressed in the view - /// \param theKey a key value - virtual void keyReleased(const int theKey); - /// Emits a signal about the operation start. This signal has an information about the feature. /// If the provided feature is empty, the current operation feature is used. /// \param theType a type of an operation started diff --git a/src/XGUI/XGUI_OperationMgr.cpp b/src/XGUI/XGUI_OperationMgr.cpp index 9b2902ecb..3a5060d8c 100644 --- a/src/XGUI/XGUI_OperationMgr.cpp +++ b/src/XGUI/XGUI_OperationMgr.cpp @@ -38,6 +38,16 @@ int XGUI_OperationMgr::operationsCount() const return myOperations.count(); } +QStringList XGUI_OperationMgr::operationList() +{ + QStringList result; + foreach(ModuleBase_Operation* eachOperation, myOperations) + { + result << eachOperation->id(); + } + return result; +} + bool XGUI_OperationMgr::startOperation(ModuleBase_Operation* theOperation) { if (!canStartOperation(theOperation)) @@ -52,34 +62,32 @@ bool XGUI_OperationMgr::startOperation(ModuleBase_Operation* theOperation) SIGNAL(activateNextWidget(ModuleBase_ModelWidget*))); theOperation->start(); - validateCurrentOperation(); - return true; -} - -bool XGUI_OperationMgr::abortOperation() -{ - ModuleBase_Operation* aCurrentOp = currentOperation(); - if (!aCurrentOp || !canStopOperation()) - return false; - - aCurrentOp->abort(); + onValidateOperation(); return true; } -QStringList XGUI_OperationMgr::operationList() +bool XGUI_OperationMgr::abortAllOperations() { - QStringList result; - foreach(ModuleBase_Operation* eachOperation, myOperations) - { - result << eachOperation->id(); + if (operationsCount() == 1) { + onAbortOperation(); + return true; + } + 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(); } return result; } -void XGUI_OperationMgr::validateOperation(ModuleBase_Operation* theOperation) +bool XGUI_OperationMgr::validateOperation(ModuleBase_Operation* theOperation) { - //Get operation Id and feature to validate - QString anOperationId = theOperation->id(); + //Get operation feature to validate FeaturePtr aFeature = theOperation->feature(); //Get validators for the Id SessionPtr aMgr = ModelAPI_Session::get(); @@ -87,9 +95,10 @@ void XGUI_OperationMgr::validateOperation(ModuleBase_Operation* theOperation) bool isValid = aFactory->validate(aFeature); emit operationValidated(isValid); + return isValid; } -void XGUI_OperationMgr::validateCurrentOperation() +void XGUI_OperationMgr::onValidateOperation() { if (!hasOperation()) return; @@ -100,10 +109,10 @@ void XGUI_OperationMgr::validateCurrentOperation() bool XGUI_OperationMgr::eventFilter(QObject *theObject, QEvent *theEvent) { if (theEvent->type() == QEvent::KeyRelease) { - QKeyEvent* aKeyEvent = (QKeyEvent*) theEvent; - if (aKeyEvent && aKeyEvent->key() == Qt::Key_Escape) { - // TODO: this is Escape button processing when the property panel has empty content, - // but the operation should be stopped by the Enter has been clicked + QKeyEvent* aKeyEvent = dynamic_cast(theEvent); + // TODO: this is Escape button processing when the property panel has empty content, + // but the operation should be stopped by the Enter has been clicked + if(aKeyEvent) { onKeyReleased(aKeyEvent); return true; } @@ -111,6 +120,13 @@ bool XGUI_OperationMgr::eventFilter(QObject *theObject, QEvent *theEvent) return QObject::eventFilter(theObject, theEvent); } +void XGUI_OperationMgr::commitOperation() +{ + if (validateOperation(currentOperation())) { + onCommitOperation(); + } +} + void XGUI_OperationMgr::resumeOperation(ModuleBase_Operation* theOperation) { theOperation->resume(); @@ -123,7 +139,7 @@ bool XGUI_OperationMgr::canStartOperation(ModuleBase_Operation* theOperation) if (aCurrentOp) { if (!theOperation->isGranted()) { if (!aCurrentOp->isValid(theOperation)) { - if (canStopOperation()) { + if (canAbortOperation()) { aCurrentOp->abort(); } else { aCanStart = false; @@ -134,21 +150,6 @@ bool XGUI_OperationMgr::canStartOperation(ModuleBase_Operation* theOperation) return aCanStart; } -bool XGUI_OperationMgr::canStopOperation() -{ - ModuleBase_Operation* anOperation = currentOperation(); - if (anOperation) { - if (anOperation->isModified()) { - int anAnswer = QMessageBox::question( - qApp->activeWindow(), tr("Operation launch"), - tr("Previous operation is not finished, abort it?"), - QMessageBox::Abort | QMessageBox::Cancel, - QMessageBox::Cancel); - return anAnswer == QMessageBox::Abort; - } - } - return true; -} void XGUI_OperationMgr::onCommitOperation() { @@ -160,20 +161,22 @@ void XGUI_OperationMgr::onCommitOperation() void XGUI_OperationMgr::onAbortOperation() { - ModuleBase_Operation* anOperation = currentOperation(); - if (anOperation && canAbortOperation()) - anOperation->abort(); + if (hasOperation() && canAbortOperation()) { + currentOperation()->abort(); + } } bool XGUI_OperationMgr::canAbortOperation() { ModuleBase_Operation* anOperation = currentOperation(); if (anOperation && anOperation->isModified()) { - int anAnswer = QMessageBox::question( - qApp->activeWindow(), tr("Cancel operation"), - tr("Operation %1 will be cancelled. Continue?").arg(anOperation->id()), QMessageBox::Yes, - QMessageBox::No); - return anAnswer == QMessageBox::Yes; + QString aMessage = tr("%1 operation will be aborted.").arg(anOperation->id()); + int anAnswer = QMessageBox::question(qApp->activeWindow(), + tr("Abort operation"), + aMessage, + QMessageBox::Ok | QMessageBox::Cancel, + QMessageBox::Cancel); + return anAnswer == QMessageBox::Ok; } return true; } @@ -203,15 +206,30 @@ void XGUI_OperationMgr::onOperationStopped() } if (aResultOp) { resumeOperation(aResultOp); - validateCurrentOperation(); + onValidateOperation(); } } void XGUI_OperationMgr::onKeyReleased(QKeyEvent* theEvent) { ModuleBase_Operation* anOperation = currentOperation(); - if (anOperation) - anOperation->keyReleased(theEvent->key()); + if (anOperation) { + bool isFinished = anOperation->keyReleased(theEvent->key()); + if(isFinished) + return; + } + // Let the manager decide what to do with the given key combination. + switch (theEvent->key()) { + case Qt::Key_Escape: + onAbortOperation(); + break; + case Qt::Key_Return: + case Qt::Key_Enter: + commitOperation(); + break; + default: + break; + } } void XGUI_OperationMgr::onWidgetActivated(ModuleBase_ModelWidget* theWidget) diff --git a/src/XGUI/XGUI_OperationMgr.h b/src/XGUI/XGUI_OperationMgr.h index 5dbd3cbce..954f61e88 100644 --- a/src/XGUI/XGUI_OperationMgr.h +++ b/src/XGUI/XGUI_OperationMgr.h @@ -41,21 +41,25 @@ Q_OBJECT bool hasOperation() const; /// Returns number of operations in the stack int operationsCount() const; + /// Returns list of all operations IDs + QStringList operationList(); + + virtual bool eventFilter(QObject *theObject, QEvent *theEvent); + /// Start the operation and append it to the stack of operations /// \param theOperation the started operation /// \return the state whether the current operation is started bool startOperation(ModuleBase_Operation* theOperation); - /// Abort the operation and append it to the stack of operations - /// \return the state whether the current operation is aborted - bool abortOperation(); - ///Returns list of all operations IDs - QStringList operationList(); - - virtual bool eventFilter(QObject *theObject, QEvent *theEvent); + bool abortAllOperations(); public slots: - void validateCurrentOperation(); + /// Slot that commits the current operation. + void onCommitOperation(); + /// Slot that aborts the current operation. + void onAbortOperation(); + /// Slot that validates the current operation using the validateOperation method. + void onValidateOperation(); signals: /// Signal about an operation is started. It is emitted after the start() of operation is done. @@ -72,31 +76,30 @@ signals: void activateNextWidget(ModuleBase_ModelWidget* theWidget); protected: + + /// Commits the current operatin if it is valid + void commitOperation(); /// Sets the current operation or NULL /// \param theOperation the started operation /// \param isCheckBeforeStart the flag whether to check whether the operation can be started /// \return the state whether the operation is resumed void resumeOperation(ModuleBase_Operation* theOperation); + /// Checks if given operation is Valid, if so sends operationValidated signal + /// \param theOperation to be validated + /// \return validation state (true means valid) + bool validateOperation(ModuleBase_Operation* theOperation); /// Returns whether the operation can be started. Check if there is already started operation and /// the granted parameter of the launched operation /// \param theOperation an operation to check bool canStartOperation(ModuleBase_Operation* theOperation); - /// Returns whether the operation can be stopped. bool canStopOperation(); /// Returns true if the operation can be aborted bool canAbortOperation(); - void validateOperation(ModuleBase_Operation* theOperation); - protected slots: - /// Slot that commits the current operation. - void onCommitOperation(); - /// Slot that aborts the current operation. - void onAbortOperation(); - /// Slot that is called by an operation stop. Removes the stopped operation form the stack. /// If there is a suspended operation, restart it. void onOperationStopped(); diff --git a/src/XGUI/XGUI_Workshop.cpp b/src/XGUI/XGUI_Workshop.cpp index d337c1856..0f3fa139c 100644 --- a/src/XGUI/XGUI_Workshop.cpp +++ b/src/XGUI/XGUI_Workshop.cpp @@ -372,7 +372,7 @@ void XGUI_Workshop::onFeatureUpdatedMsg(const boost::shared_ptrvalidateCurrentOperation(); + myOperationMgr->onValidateOperation(); if (myObjectBrowser) myObjectBrowser->processEvent(theMsg); } @@ -594,9 +594,7 @@ void XGUI_Workshop::saveDocument(const QString& theName, std::list& bool XGUI_Workshop::isActiveOperationAborted() { - if(!myOperationMgr->hasOperation()) - return true; - return myOperationMgr->abortOperation(); + return myOperationMgr->abortAllOperations(); } //****************************************************** @@ -736,7 +734,7 @@ void XGUI_Workshop::onUndo() objectBrowser()->treeView()->setCurrentIndex(QModelIndex()); SessionPtr aMgr = ModelAPI_Session::get(); if (aMgr->isOperation()) - operationMgr()->abortOperation(); + operationMgr()->onAbortOperation(); aMgr->undo(); updateCommandStatus(); } @@ -747,7 +745,7 @@ void XGUI_Workshop::onRedo() objectBrowser()->treeView()->setCurrentIndex(QModelIndex()); SessionPtr aMgr = ModelAPI_Session::get(); if (aMgr->isOperation()) - operationMgr()->abortOperation(); + operationMgr()->onAbortOperation(); aMgr->redo(); updateCommandStatus(); } -- 2.39.2