X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FXGUI%2FXGUI_OperationMgr.cpp;h=e8ea75fa06285e197712614a4df74bef1db259cb;hb=0b75d9124e6145d1f69757b56ad37c4aa1dcc9d9;hp=32fa52a85d0dd00f91b7a13f78cd735d1901df04;hpb=2532fb2df83ee1ddd9ff3e8b381d3788eaa15b69;p=modules%2Fshaper.git diff --git a/src/XGUI/XGUI_OperationMgr.cpp b/src/XGUI/XGUI_OperationMgr.cpp index 32fa52a85..e8ea75fa0 100644 --- a/src/XGUI/XGUI_OperationMgr.cpp +++ b/src/XGUI/XGUI_OperationMgr.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 CEA/DEN, EDF R&D +// Copyright (C) 2014-2022 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -12,18 +12,25 @@ // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // #include "XGUI_OperationMgr.h" + +#include "XGUI_ActiveControlMgr.h" +#include "XGUI_ActiveControlSelector.h" +#include "XGUI_FacesPanelSelector.h" #include "XGUI_ModuleConnector.h" #include "XGUI_Workshop.h" #include "XGUI_ErrorMgr.h" +#include "XGUI_FacesPanel.h" #include "XGUI_Tools.h" #include "XGUI_ObjectsBrowser.h" #include "XGUI_ContextMenuMgr.h" +#include "XGUI_Selection.h" +#include "XGUI_SelectionMgr.h" #include #include @@ -35,8 +42,10 @@ #include "ModuleBase_OperationFeature.h" #include "ModuleBase_Tools.h" -#include "ModelAPI_CompositeFeature.h" -#include "ModelAPI_Session.h" +#include + +#include +#include #include #include @@ -45,6 +54,7 @@ #include #include #include +#include //#define DEBUG_CURRENT_FEATURE @@ -57,8 +67,8 @@ public: /// Constructor /// \param theParent the parent to be deleted when the parent is deleted /// \param theOperationMgr the class to perform deletion - XGUI_ShortCutListener(QObject* theParent, XGUI_OperationMgr* theOperationMgr) - : QObject(theParent), myOperationMgr(theOperationMgr) + XGUI_ShortCutListener(XGUI_OperationMgr* theOperationMgr) + : QObject(theOperationMgr), myOperationMgr(theOperationMgr), myIsActive(false) { qApp->installEventFilter(this); } @@ -68,40 +78,76 @@ public: void setActive(const bool theIsActive) { myIsActive = theIsActive; } /// Redefinition of virtual function to process Delete key release - virtual bool eventFilter(QObject *theObject, QEvent *theEvent) - { - bool isAccepted = false; - if (myIsActive && theEvent->type() == QEvent::KeyRelease) { - QKeyEvent* aKeyEvent = dynamic_cast(theEvent); - if (aKeyEvent) { - switch (aKeyEvent->key()) { + virtual bool eventFilter(QObject *theObject, QEvent *theEvent); + +private: + XGUI_OperationMgr* myOperationMgr; /// processor for key event + bool myIsActive; /// boolean state whether the event filter perform own signal processing +}; + +bool XGUI_ShortCutListener::eventFilter(QObject *theObject, QEvent *theEvent) +{ + bool isAccepted = false; + + if (myIsActive) { + // Do not process keys for modal dialogues: all keys has to be processed within the dialog + // There is only one exception: ModuleBase_EditorDialog + QWindow* aWnd = qApp->modalWindow(); + QString aName = "NoModal"; + if (aWnd) { + if (!aWnd->objectName().startsWith("ModuleBase_EditorDialog")) + aName = aWnd->objectName(); + } + if (aName == "NoModal") { + if (theEvent->type() == QEvent::KeyRelease) { + QKeyEvent* aKeyEvent = dynamic_cast(theEvent); + if (aKeyEvent) { + myOperationMgr->setSHIFTPressed(aKeyEvent->modifiers() & Qt::ShiftModifier); + switch (aKeyEvent->key()) { case Qt::Key_Delete: isAccepted = myOperationMgr->onProcessDelete(theObject); - break; + break; + case Qt::Key_F2: + { + QObjectPtrList anObjects = myOperationMgr->xworkshop()->selector()->selection()->selectedObjects(); + if (myOperationMgr->xworkshop()->abortAllOperations()) + { + myOperationMgr->xworkshop()->objectBrowser()->setObjectsSelected(anObjects); + myOperationMgr->xworkshop()->objectBrowser()->onEditItem(); + } + isAccepted = true; + break; + } default: isAccepted = myOperationMgr->onKeyReleased(theObject, aKeyEvent); break; + } + } + } + else if (theEvent->type() == QEvent::KeyPress) { + if (myOperationMgr->hasOperation()) { + QKeyEvent* aKeyEvent = dynamic_cast(theEvent); + myOperationMgr->setSHIFTPressed(aKeyEvent->modifiers() & Qt::ShiftModifier); + isAccepted = myOperationMgr->onKeyPressed(theObject, aKeyEvent); } } } - if (!isAccepted) - isAccepted = QObject::eventFilter(theObject, theEvent); - return isAccepted; } + if (!isAccepted) + isAccepted = QObject::eventFilter(theObject, theEvent); + return isAccepted; +} + -private: - XGUI_OperationMgr* myOperationMgr; /// processor for key event - bool myIsActive; /// boolean state whether the event filter perform own signal processing -}; XGUI_OperationMgr::XGUI_OperationMgr(QObject* theParent, - ModuleBase_IWorkshop* theWorkshop) -: QObject(theParent), myWorkshop(theWorkshop) + ModuleBase_IWorkshop* theWorkshop) +: QObject(theParent), myWorkshop(theWorkshop), myActiveMessageBox(0), mySHIFTPressed(false) { /// we need to install filter to the application in order to react to 'Delete' key button /// this key can not be a short cut for a corresponded action because we need to set /// the actions priority - myShortCutListener = new XGUI_ShortCutListener(theParent, this); + myShortCutListener = new XGUI_ShortCutListener(this); } XGUI_OperationMgr::~XGUI_OperationMgr() @@ -187,6 +233,18 @@ ModuleBase_Operation* XGUI_OperationMgr::previousOperation(ModuleBase_Operation* return myOperations.at(idx - 1); } +ModuleBase_ModelWidget* XGUI_OperationMgr::activeWidget() const +{ + ModuleBase_ModelWidget* anActiveWidget = 0; + ModuleBase_Operation* anOperation = currentOperation(); + if (anOperation) { + ModuleBase_IPropertyPanel* aPanel = anOperation->propertyPanel(); + if (aPanel) + anActiveWidget = aPanel->activeWidget(); + } + return anActiveWidget; +} + bool XGUI_OperationMgr::startOperation(ModuleBase_Operation* theOperation) { if (hasOperation()) @@ -210,7 +268,7 @@ bool XGUI_OperationMgr::startOperation(ModuleBase_Operation* theOperation) return isStarted; } -bool XGUI_OperationMgr::abortAllOperations() +bool XGUI_OperationMgr::abortAllOperations(const XGUI_MessageKind& theMessageKind) { bool aResult = true; if(!hasOperation()) @@ -218,18 +276,25 @@ bool XGUI_OperationMgr::abortAllOperations() if (operationsCount() == 1) { ModuleBase_Operation* aCurrentOperation = currentOperation(); - if (canStopOperation(aCurrentOperation)) { + if (canStopOperation(aCurrentOperation, theMessageKind)) { abortOperation(aCurrentOperation); } else aResult = false; } else { - aResult = QMessageBox::question(qApp->activeWindow(), - tr("Abort operation"), - tr("All active operations will be aborted."), - QMessageBox::Ok | QMessageBox::Cancel, - QMessageBox::Cancel) == QMessageBox::Ok; + if (theMessageKind == XGUI_AbortOperationMessage) { + myActiveMessageBox = createMessageBox(tr("All active operations will be aborted.")); + aResult = myActiveMessageBox->exec() == QMessageBox::Ok; + myActiveMessageBox = 0; + } + else if (theMessageKind == XGUI_InformationMessage) { + QString aMessage = tr("Please validate all your active operations before saving."); + myActiveMessageBox = createInformationBox(aMessage); + myActiveMessageBox->exec(); + myActiveMessageBox = 0; + aResult = false; // do not perform abort + } while(aResult && hasOperation()) { abortOperation(currentOperation()); } @@ -243,7 +308,7 @@ bool XGUI_OperationMgr::commitAllOperations() while (hasOperation()) { ModuleBase_Operation* anOperation = currentOperation(); if (XGUI_Tools::workshop(myWorkshop)->errorMgr()->isApplyEnabled()) { - anOperationProcessed = onCommitOperation(); + anOperationProcessed = commitOperation(); } else { abortOperation(anOperation); anOperationProcessed = true; @@ -297,33 +362,38 @@ void XGUI_OperationMgr::updateApplyOfOperations(ModuleBase_Operation* theOperati onValidateOperation(); } -bool XGUI_OperationMgr::canStopOperation(ModuleBase_Operation* theOperation) +bool XGUI_OperationMgr::canStopOperation(ModuleBase_Operation* theOperation, + const XGUI_OperationMgr::XGUI_MessageKind& theMessageKind) { //in case of nested (sketch) operation no confirmation needed if (isGrantedOperation(theOperation->id())) return true; if (theOperation && theOperation->isModified()) { - QString aMessage = tr("%1 operation will be aborted.").arg(theOperation->id()); - int anAnswer = QMessageBox::question(qApp->activeWindow(), - tr("Abort operation"), - aMessage, - QMessageBox::Ok | QMessageBox::Cancel, - QMessageBox::Cancel); - return anAnswer == QMessageBox::Ok; + ModuleBase_OperationFeature* aOp = dynamic_cast(theOperation); + std::string aContext; + if (aOp && aOp->feature()) + aContext = aOp->feature()->getKind(); + QString aTitle = Config_Translator::translate(aContext, + theOperation->getDescription()->description().toStdString()).c_str(); + + if (theMessageKind == XGUI_AbortOperationMessage) { + QString aMessage = tr("%1 operation will be aborted.").arg(aTitle); + myActiveMessageBox = createMessageBox(aMessage); + bool aResult = myActiveMessageBox->exec() == QMessageBox::Ok; + myActiveMessageBox = 0; + return aResult; + } + else if (theMessageKind == XGUI_InformationMessage) { + QString aMessage = tr("Please validate your %1 before saving.").arg(aTitle); + myActiveMessageBox = createInformationBox(aMessage); + myActiveMessageBox->exec(); + myActiveMessageBox = 0; + return false; + } } return true; } -bool XGUI_OperationMgr::commitOperation() -{ - //if (hasOperation() && currentOperation()->isValid()) { - // onCommitOperation(); - // return true; - //} - //return false; - return onCommitOperation(); -} - void XGUI_OperationMgr::resumeOperation(ModuleBase_Operation* theOperation) { theOperation->resume(); @@ -335,7 +405,6 @@ bool XGUI_OperationMgr::isGrantedOperation(const QString& theId) QListIterator anIt(myOperations); anIt.toBack(); - ModuleBase_Operation* aPreviousOperation = 0; while (anIt.hasPrevious() && !isGranted) { ModuleBase_Operation* anOp = anIt.previous(); if (anOp) @@ -395,9 +464,10 @@ bool XGUI_OperationMgr::canStartOperation(const QString& theId, bool& isCommitte void XGUI_OperationMgr::stopOperation(ModuleBase_Operation* theOperation, bool& isCommitted) { - if (XGUI_Tools::workshop(myWorkshop)->errorMgr()->isApplyEnabled() && theOperation->isModified()) + if (XGUI_Tools::workshop(myWorkshop)->errorMgr()->isApplyEnabled() && + theOperation->isModified()) { isCommitted = theOperation->commit(); - else { + } else { isCommitted = false; abortOperation(theOperation); } @@ -406,22 +476,22 @@ void XGUI_OperationMgr::stopOperation(ModuleBase_Operation* theOperation, bool& void XGUI_OperationMgr::abortOperation(ModuleBase_Operation* theOperation) { ModuleBase_Operation* aCurrentOperation = currentOperation(); - if (theOperation == aCurrentOperation) + if (theOperation && (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) + ModuleBase_Operation* aCurOperation = currentOperation(); + aCurOperation->abort(); + if(theOperation == aCurOperation) break; } } } -bool XGUI_OperationMgr::onCommitOperation() +bool XGUI_OperationMgr::commitOperation() { bool isCommitted = false; ModuleBase_Operation* anOperation = currentOperation(); @@ -438,6 +508,11 @@ void XGUI_OperationMgr::onAbortOperation() } } +void XGUI_OperationMgr::onAbortAllOperation() +{ + abortAllOperations(); +} + void XGUI_OperationMgr::onBeforeOperationStarted() { ModuleBase_Operation* aCurrentOperation = dynamic_cast(sender()); @@ -507,6 +582,8 @@ void XGUI_OperationMgr::onBeforeOperationAborted() void XGUI_OperationMgr::onOperationAborted() { ModuleBase_Operation* aSenderOperation = dynamic_cast(sender()); + XGUI_Workshop* aWorkshop = XGUI_Tools::workshop(myWorkshop); + aWorkshop->setStatusBarMessage(""); emit operationAborted(aSenderOperation); } @@ -589,8 +666,8 @@ void XGUI_OperationMgr::onOperationStopped() } } if (aResultOp) { - bool isModified = aCurrentOperation->isModified(); - aResultOp->setIsModified(aResultOp->isModified() || isModified); + //bool isModified = aCurrentOperation->isModified(); + //aResultOp->setIsModified(aResultOp->isModified() || isModified); resumeOperation(aResultOp); onValidateOperation(); } @@ -598,18 +675,11 @@ void XGUI_OperationMgr::onOperationStopped() bool XGUI_OperationMgr::onKeyReleased(QObject *theObject, QKeyEvent* theEvent) { + bool isAccepted = false; + // Let the manager decide what to do with the given key combination. ModuleBase_Operation* anOperation = currentOperation(); - bool isAccepted = false; switch (theEvent->key()) { - case Qt::Key_Escape: { - ModuleBase_Operation* aOperation = currentOperation(); - if (aOperation) { - onAbortOperation(); - isAccepted = true; - } - } - break; case Qt::Key_Tab: case Qt::Key_Backtab: { @@ -646,12 +716,17 @@ bool XGUI_OperationMgr::onKeyReleased(QObject *theObject, QKeyEvent* theEvent) aContext->HilightNextDetected(aView); else if ((theEvent->key() == Qt::Key_P)) aContext->HilightPreviousDetected(aView); + aViewer->updateHighlight(); + isAccepted = true; } } - } - break; - break; - default: + } + break; + case Qt::Key_H: + if ((theEvent->modifiers() == Qt::NoModifier)) + myWorkshop->viewer()->hideSelectionHighlight(); + break; + default: isAccepted = false; break; } @@ -661,6 +736,58 @@ bool XGUI_OperationMgr::onKeyReleased(QObject *theObject, QKeyEvent* theEvent) return isAccepted; } +bool XGUI_OperationMgr::onKeyPressed(QObject *theObject, QKeyEvent* theEvent) +{ + // Let the manager decide what to do with the given key combination. + bool isAccepted = false; + switch (theEvent->key()) { + case Qt::Key_Escape: { + // processing in message box + if (myActiveMessageBox) + { + myActiveMessageBox->reject(); + isAccepted = true; + } + // processing in the active widget + ModuleBase_Operation* aOperation = currentOperation(); + if (!isAccepted && aOperation) { + ModuleBase_IPropertyPanel* aPanel = aOperation->propertyPanel(); + if (aPanel) { + ModuleBase_ModelWidget* anActiveWgt = aPanel->activeWidget(); + if (anActiveWgt) + { + isAccepted = anActiveWgt && anActiveWgt->processAction(ActionEscape); + if (isAccepted) { + ModuleBase_OperationFeature* aFOperation = + dynamic_cast(currentOperation()); + if (aFOperation) + aFOperation->setNeedToBeAborted(true); + } + } + } + } + if (!isAccepted) + { + XGUI_ActiveControlSelector* anActiveSelector = + XGUI_Tools::workshop(myWorkshop)->activeControlMgr()->activeSelector(); + if (anActiveSelector && anActiveSelector->getType() == XGUI_FacesPanelSelector::Type()) + isAccepted = XGUI_Tools::workshop(myWorkshop)->facesPanel()->processAction(ActionEscape); + } + // default Escape button functionality + if (!isAccepted && aOperation) { + onAbortOperation(); + isAccepted = true; + } + } + break; + case Qt::Key_H: + if ((theEvent->modifiers() == Qt::NoModifier)) + myWorkshop->viewer()->showSelectionHighlight(); + break; + } + return isAccepted; +} + bool XGUI_OperationMgr::onProcessEnter(QObject* theObject) { bool isAccepted = false; @@ -669,6 +796,8 @@ bool XGUI_OperationMgr::onProcessEnter(QObject* theObject) if (!aOperation) return isAccepted; ModuleBase_IPropertyPanel* aPanel = aOperation->propertyPanel(); + if (!aPanel) + return isAccepted; // the next code is obsolete as we want to process Enter in property panel always // only property panel enter is processed in order to do not process enter in application dialogs //bool isPPChild = isChildObject(theObject, aPanel); @@ -688,7 +817,7 @@ bool XGUI_OperationMgr::onProcessEnter(QObject* theObject) } } if (!isAborted) { - isAccepted = anActiveWgt && anActiveWgt->processEnter(); + isAccepted = anActiveWgt && anActiveWgt->processAction(ActionEnter); if (!isAccepted) { isAccepted = myWorkshop->module()->processEnter(anActiveWgt ? anActiveWgt->attributeID() : ""); @@ -735,11 +864,18 @@ bool XGUI_OperationMgr::onProcessDelete(QObject* theObject) if (isPPChildObject) { anActiveWgt = aPanel->activeWidget(); if (anActiveWgt) { - isAccepted = anActiveWgt->processDelete(); + isAccepted = anActiveWgt->processAction(ActionDelete); } } } } + if (!isAccepted) + { + XGUI_ActiveControlSelector* anActiveSelector = + XGUI_Tools::workshop(myWorkshop)->activeControlMgr()->activeSelector(); + if (anActiveSelector && anActiveSelector->getType() == XGUI_FacesPanelSelector::Type()) + isAccepted = XGUI_Tools::workshop(myWorkshop)->facesPanel()->processAction(ActionDelete); + } if (!isAccepted) { // after widget, object browser and viewer should process delete /// other widgets such as line edit controls should not lead to @@ -789,3 +925,31 @@ bool XGUI_OperationMgr::isChildObject(const QObject* theObject, const QObject* t } return isPPChild; } + +QMessageBox* XGUI_OperationMgr::createMessageBox(const QString& theMessage) +{ + QMessageBox * aMessageBox = new QMessageBox(QMessageBox::Question, + QObject::tr("Abort operation"), theMessage, QMessageBox::Ok | QMessageBox::Cancel, + qApp->activeWindow()); + aMessageBox->setDefaultButton(QMessageBox::Cancel); + aMessageBox->setEscapeButton(QMessageBox::No); // operation manager should process Esc key + + return aMessageBox; +} + +QMessageBox* XGUI_OperationMgr::createInformationBox(const QString& theMessage) +{ + QMessageBox * aMessageBox = new QMessageBox(QMessageBox::Question, + QObject::tr("Validate operation"), theMessage, QMessageBox::Ok, + qApp->activeWindow()); + aMessageBox->setDefaultButton(QMessageBox::Ok); + aMessageBox->setEscapeButton(QMessageBox::No); // operation manager should process Esc key + + return aMessageBox; +} + +XGUI_Workshop* XGUI_OperationMgr::xworkshop() const +{ + XGUI_ModuleConnector* aConnector = (XGUI_ModuleConnector*) myWorkshop; + return aConnector->workshop(); +}