X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FXGUI%2FXGUI_OperationMgr.cpp;h=efc2ce9d51237e4490d6a8803b3243843bed21ad;hb=65a616a3bb6cbdf09c61fed7eb91d1f5d9667988;hp=756b7b9354fe34f46db2e52e8a3414e97cb44d82;hpb=ac63def3eb29ba78d5e285c5edb026fb083f302b;p=modules%2Fshaper.git diff --git a/src/XGUI/XGUI_OperationMgr.cpp b/src/XGUI/XGUI_OperationMgr.cpp index 756b7b935..efc2ce9d5 100644 --- a/src/XGUI/XGUI_OperationMgr.cpp +++ b/src/XGUI/XGUI_OperationMgr.cpp @@ -1,17 +1,29 @@ -// File: XGUI_OperationMgr.h +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D --> + +// File: XGUI_OperationMgr.cpp // Created: 20 Apr 2014 // Author: Natalia ERMOLAEVA #include "XGUI_OperationMgr.h" #include "ModuleBase_Operation.h" +#include "ModuleBase_IWorkshop.h" +#include "ModuleBase_IModule.h" +#include +#include "ModuleBase_OperationDescription.h" +#include "ModuleBase_OperationFeature.h" + +#include "ModelAPI_CompositeFeature.h" +#include "ModelAPI_Session.h" #include #include #include -XGUI_OperationMgr::XGUI_OperationMgr(QObject* theParent) - : QObject(theParent) +XGUI_OperationMgr::XGUI_OperationMgr(QObject* theParent, + ModuleBase_IWorkshop* theWorkshop) +: QObject(theParent), myIsValidationLock(false), myIsApplyEnabled(false), + myWorkshop(theWorkshop) { } @@ -64,9 +76,12 @@ QStringList XGUI_OperationMgr::operationList() const { QStringList result; foreach(ModuleBase_Operation* eachOperation, myOperations) { - FeaturePtr aFeature = eachOperation->feature(); - if(aFeature) { - result << QString::fromStdString(aFeature->getKind()); + ModuleBase_OperationFeature* aFOperation = dynamic_cast(eachOperation); + if (aFOperation) { + FeaturePtr aFeature = aFOperation->feature(); + if(aFeature) { + result << QString::fromStdString(aFeature->getKind()); + } } } return result; @@ -103,8 +118,11 @@ bool XGUI_OperationMgr::startOperation(ModuleBase_Operation* theOperation) connect(theOperation, SIGNAL(committed()), SLOT(onOperationCommitted())); connect(theOperation, SIGNAL(stopped()), SLOT(onOperationStopped())); connect(theOperation, SIGNAL(resumed()), SLOT(onOperationResumed())); - connect(theOperation, SIGNAL(activatedByPreselection()), - SIGNAL(operationActivatedByPreselection())); + ModuleBase_OperationFeature* aFOperation = dynamic_cast + (theOperation); + if (aFOperation) + connect(aFOperation, SIGNAL(activatedByPreselection()), + SIGNAL(operationActivatedByPreselection())); theOperation->start(); onValidateOperation(); @@ -113,23 +131,53 @@ 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) { + ModuleBase_Operation* aCurrentOperation = currentOperation(); + if (canStopOperation(aCurrentOperation)) { + abortOperation(aCurrentOperation); + } + 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() +{ + bool isCompositeCommitted = false; + while (hasOperation()) { + ModuleBase_Operation* anOperation = currentOperation(); + if (isApplyEnabled()) { + onCommitOperation(); + } else { + abortOperation(anOperation); + } + ModuleBase_OperationFeature* aFOperation = dynamic_cast + (anOperation); + if (aFOperation) { + FeaturePtr aFeature = aFOperation->feature(); + CompositeFeaturePtr aComposite = + std::dynamic_pointer_cast(aFeature); + isCompositeCommitted = aComposite.get(); + if (isCompositeCommitted) + break; + } + } + return true; } void XGUI_OperationMgr::onValidateOperation() @@ -138,9 +186,74 @@ void XGUI_OperationMgr::onValidateOperation() return; ModuleBase_Operation* anOperation = currentOperation(); if(anOperation) { - bool isValid = anOperation->isValid(); - emit operationValidated(isValid); + bool aCanCommit = myWorkshop->module()->canCommitOperation(); + setApplyEnabled(!myIsValidationLock && aCanCommit && anOperation->isValid()); + } +} + +void XGUI_OperationMgr::setLockValidating(bool toLock) +{ + myIsValidationLock = toLock; + onValidateOperation(); +} + +void XGUI_OperationMgr::setApplyEnabled(const bool theEnabled) +{ + myIsApplyEnabled = theEnabled; + emit validationStateChanged(theEnabled); +} + +void XGUI_OperationMgr::updateApplyOfOperations(ModuleBase_Operation* theOperation) +{ + if (theOperation) + emit nestedStateChanged(theOperation->getDescription()->operationId().toStdString(), + theOperation->isValid()); + else { + foreach(ModuleBase_Operation* anOperation, myOperations) { + emit nestedStateChanged(anOperation->getDescription()->operationId().toStdString(), + anOperation->isValid()); + } + } +} + +bool XGUI_OperationMgr::isApplyEnabled() const +{ + return myIsApplyEnabled; +} + +bool XGUI_OperationMgr::isParentOperationValid() const +{ + bool isValid = false; + // the enable state of the parent operation of the nested one is defined by the rules that + // firstly there are nested operations and secondly the parent operation is valid + ModuleBase_Operation* aPrevOp = 0; + Operations::const_iterator anIt = myOperations.end(); + if (anIt != myOperations.begin()) { // there are items in the operations list + --anIt; + aPrevOp = *anIt; // the last top operation, the operation which is started + if (anIt != myOperations.begin()) { // find the operation where the started operation is nested + --anIt; + aPrevOp = *anIt; + } + } + return aPrevOp && aPrevOp->isValid(); +} + +bool XGUI_OperationMgr::canStopOperation(ModuleBase_Operation* theOperation) +{ + //in case of nested (sketch) operation no confirmation needed + if (isGrantedOperation(theOperation)) + 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; } + return true; } bool XGUI_OperationMgr::commitOperation() @@ -157,14 +270,39 @@ void XGUI_OperationMgr::resumeOperation(ModuleBase_Operation* theOperation) theOperation->resume(); } -bool XGUI_OperationMgr::canStartOperation(QString theId) +bool XGUI_OperationMgr::isGrantedOperation(ModuleBase_Operation* theOperation) +{ + bool isGranted = false; + + QListIterator anIt(myOperations); + anIt.toBack(); + ModuleBase_Operation* aPreviousOperation = 0; + while (anIt.hasPrevious()) { + ModuleBase_Operation* anOp = anIt.previous(); + if (anOp == theOperation) { + if (anIt.hasPrevious()) + aPreviousOperation = anIt.previous(); + break; + } + } + if (aPreviousOperation) + isGranted = aPreviousOperation->isGranted(theOperation->id()); + + return isGranted; +} + +bool XGUI_OperationMgr::canStartOperation(const QString& theId, const bool isAdditionallyGranted) { bool aCanStart = true; ModuleBase_Operation* aCurrentOp = currentOperation(); if (aCurrentOp) { - if (!aCurrentOp->isGranted(theId)) { - if (canAbortOperation()) { - aCurrentOp->abort(); + bool aGranted = aCurrentOp->isGranted(theId) || isAdditionallyGranted; + if (!aGranted) { + if (canStopOperation(aCurrentOp)) { + if (myIsApplyEnabled && aCurrentOp->isModified()) + aCurrentOp->commit(); + else + abortOperation(aCurrentOp); } else { aCanStart = false; } @@ -173,6 +311,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() { @@ -183,31 +338,16 @@ void XGUI_OperationMgr::onCommitOperation() void XGUI_OperationMgr::onAbortOperation() { - if (hasOperation() && canAbortOperation()) { - currentOperation()->abort(); + ModuleBase_Operation* aCurrentOperation = currentOperation(); + if (aCurrentOperation && canStopOperation(aCurrentOperation)) { + abortOperation(aCurrentOperation); } } -bool XGUI_OperationMgr::canAbortOperation() -{ - ModuleBase_Operation* anOperation = currentOperation(); - if(operationsCount() > 1) //in case of nested (sketch) operation no confirmation needed - return true; - if (anOperation && anOperation->isModified()) { - 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; -} - void XGUI_OperationMgr::onOperationStarted() { ModuleBase_Operation* aSenderOperation = dynamic_cast(sender()); + updateApplyOfOperations(aSenderOperation); emit operationStarted(aSenderOperation); } @@ -219,6 +359,8 @@ void XGUI_OperationMgr::onOperationAborted() void XGUI_OperationMgr::onOperationCommitted() { + updateApplyOfOperations(); + ModuleBase_Operation* aSenderOperation = dynamic_cast(sender()); emit operationCommitted(aSenderOperation); } @@ -232,14 +374,14 @@ void XGUI_OperationMgr::onOperationResumed() void XGUI_OperationMgr::onOperationStopped() { ModuleBase_Operation* aSenderOperation = dynamic_cast(sender()); - ModuleBase_Operation* anOperation = currentOperation(); - if (!aSenderOperation || !anOperation || aSenderOperation != anOperation) + ModuleBase_Operation* aCurrentOperation = currentOperation(); + if (!aSenderOperation || !aCurrentOperation || aSenderOperation != aCurrentOperation) return; - myOperations.removeAll(anOperation); - anOperation->deleteLater(); + myOperations.removeAll(aCurrentOperation); + aCurrentOperation->deleteLater(); - emit operationStopped(anOperation); + emit operationStopped(aCurrentOperation); // get last operation which can be resumed ModuleBase_Operation* aResultOp = 0; @@ -253,6 +395,8 @@ void XGUI_OperationMgr::onOperationStopped() } } if (aResultOp) { + bool isModified = aCurrentOperation->isModified(); + aResultOp->setIsModified(aResultOp->isModified() || isModified); resumeOperation(aResultOp); onValidateOperation(); } @@ -269,7 +413,21 @@ bool XGUI_OperationMgr::onKeyReleased(QKeyEvent* theEvent) emit keyEnterReleased(); commitOperation(); } - break; + case Qt::Key_N: + case Qt::Key_P: { + bool noModifiers = (theEvent->modifiers() == Qt::NoModifier); + if (noModifiers) { + ModuleBase_IViewer* aViewer = myWorkshop->viewer(); + Handle(AIS_InteractiveContext) aContext = aViewer->AISContext(); + Handle(V3d_View) aView = aViewer->activeView(); + if ((theEvent->key() == Qt::Key_N)) + aContext->HilightNextDetected(aView); + else if ((theEvent->key() == Qt::Key_P)) + aContext->HilightPreviousDetected(aView); + } + } + + break; default: isAccepted = false; break;