1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
3 // File: XGUI_OperationMgr.cpp
4 // Created: 20 Apr 2014
5 // Author: Natalia ERMOLAEVA
7 #include "XGUI_OperationMgr.h"
9 #include "ModuleBase_Operation.h"
10 #include "ModuleBase_IWorkshop.h"
11 #include "ModuleBase_IModule.h"
13 #include "ModelAPI_CompositeFeature.h"
14 #include "ModelAPI_Session.h"
16 #include <QMessageBox>
17 #include <QApplication>
20 XGUI_OperationMgr::XGUI_OperationMgr(QObject* theParent,
21 ModuleBase_IWorkshop* theWorkshop)
22 : QObject(theParent), myIsValidationLock(false), myIsApplyEnabled(false),
23 myWorkshop(theWorkshop)
27 XGUI_OperationMgr::~XGUI_OperationMgr()
31 ModuleBase_Operation* XGUI_OperationMgr::currentOperation() const
33 return myOperations.count() > 0 ? myOperations.last() : 0;
36 bool XGUI_OperationMgr::isCurrentOperation(ModuleBase_Operation* theOperation)
40 return currentOperation() == theOperation;
43 bool XGUI_OperationMgr::hasOperation() const
45 return !myOperations.isEmpty() && (myOperations.last() != NULL);
48 bool XGUI_OperationMgr::hasOperation(const QString& theId) const
50 foreach(ModuleBase_Operation* aOp, myOperations) {
51 if (aOp->id() == theId)
57 ModuleBase_Operation* XGUI_OperationMgr::findOperation(const QString& theId) const
59 foreach(ModuleBase_Operation* aOp, myOperations) {
60 if (aOp->id() == theId)
67 int XGUI_OperationMgr::operationsCount() const
69 return myOperations.count();
72 QStringList XGUI_OperationMgr::operationList() const
75 foreach(ModuleBase_Operation* eachOperation, myOperations) {
76 FeaturePtr aFeature = eachOperation->feature();
78 result << QString::fromStdString(aFeature->getKind());
84 ModuleBase_Operation* XGUI_OperationMgr::previousOperation(ModuleBase_Operation* theOperation) const
86 int idx = myOperations.lastIndexOf(theOperation);
87 if(idx == -1 || idx == 0) {
90 return myOperations.at(idx - 1);
93 bool XGUI_OperationMgr::eventFilter(QObject *theObject, QEvent *theEvent)
95 if (theEvent->type() == QEvent::KeyRelease) {
96 QKeyEvent* aKeyEvent = dynamic_cast<QKeyEvent*>(theEvent);
98 return onKeyReleased(aKeyEvent);
101 return QObject::eventFilter(theObject, theEvent);
104 bool XGUI_OperationMgr::startOperation(ModuleBase_Operation* theOperation)
107 currentOperation()->postpone();
108 myOperations.append(theOperation);
110 connect(theOperation, SIGNAL(started()), SLOT(onOperationStarted()));
111 connect(theOperation, SIGNAL(aborted()), SLOT(onOperationAborted()));
112 connect(theOperation, SIGNAL(committed()), SLOT(onOperationCommitted()));
113 connect(theOperation, SIGNAL(stopped()), SLOT(onOperationStopped()));
114 connect(theOperation, SIGNAL(resumed()), SLOT(onOperationResumed()));
115 connect(theOperation, SIGNAL(triggered(bool)), SLOT(onOperationTriggered(bool)));
116 connect(theOperation, SIGNAL(activatedByPreselection()),
117 SIGNAL(operationActivatedByPreselection()));
119 theOperation->start();
120 onValidateOperation();
124 bool XGUI_OperationMgr::abortAllOperations()
130 if (operationsCount() == 1) {
131 if (canStopOperation()) {
132 abortOperation(currentOperation());
138 aResult = QMessageBox::question(qApp->activeWindow(),
139 tr("Abort operation"),
140 tr("All active operations will be aborted."),
141 QMessageBox::Ok | QMessageBox::Cancel,
142 QMessageBox::Cancel) == QMessageBox::Ok;
143 while(aResult && hasOperation()) {
144 abortOperation(currentOperation());
150 bool XGUI_OperationMgr::commitAllOperations()
152 bool isCompositeCommitted = false;
153 while (hasOperation()) {
154 ModuleBase_Operation* anOperation = currentOperation();
155 if (isApplyEnabled()) {
158 abortOperation(anOperation);
160 FeaturePtr aFeature = anOperation->feature();
161 CompositeFeaturePtr aComposite =
162 std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aFeature);
163 isCompositeCommitted = aComposite.get();
164 if (isCompositeCommitted)
170 void XGUI_OperationMgr::onValidateOperation()
174 ModuleBase_Operation* anOperation = currentOperation();
176 bool aCanCommit = myWorkshop->module()->canCommitOperation();
177 setApplyEnabled(!myIsValidationLock && aCanCommit && anOperation->isValid());
181 void XGUI_OperationMgr::setLockValidating(bool toLock)
183 myIsValidationLock = toLock;
184 onValidateOperation();
187 void XGUI_OperationMgr::setApplyEnabled(const bool theEnabled)
189 myIsApplyEnabled = theEnabled;
190 emit validationStateChanged(theEnabled);
192 bool aParentValid = true;//isParentOperationValid();
193 emit nestedStateChanged(aParentValid);
196 bool XGUI_OperationMgr::isApplyEnabled() const
198 return myIsApplyEnabled;
201 bool XGUI_OperationMgr::isParentOperationValid() const
203 bool isValid = false;
204 // the enable state of the parent operation of the nested one is defined by the rules that
205 // firstly there are nested operations and secondly the parent operation is valid
206 ModuleBase_Operation* aPrevOp = 0;
207 Operations::const_iterator anIt = myOperations.end();
208 if (anIt != myOperations.begin()) { // there are items in the operations list
210 aPrevOp = *anIt; // the last top operation, the operation which is started
211 if (anIt != myOperations.begin()) { // find the operation where the started operation is nested
216 return aPrevOp && aPrevOp->isValid();
219 bool XGUI_OperationMgr::canStopOperation()
221 ModuleBase_Operation* anOperation = currentOperation();
222 if(operationsCount() > 1) //in case of nested (sketch) operation no confirmation needed
224 if (anOperation && anOperation->isModified()) {
225 QString aMessage = tr("%1 operation will be aborted.").arg(anOperation->id());
226 int anAnswer = QMessageBox::question(qApp->activeWindow(),
227 tr("Abort operation"),
229 QMessageBox::Ok | QMessageBox::Cancel,
230 QMessageBox::Cancel);
231 return anAnswer == QMessageBox::Ok;
236 bool XGUI_OperationMgr::commitOperation()
238 if (hasOperation() && currentOperation()->isValid()) {
245 void XGUI_OperationMgr::resumeOperation(ModuleBase_Operation* theOperation)
247 theOperation->resume();
250 bool XGUI_OperationMgr::canStartOperation(QString theId)
252 bool aCanStart = true;
253 ModuleBase_Operation* aCurrentOp = currentOperation();
255 if (!aCurrentOp->isGranted(theId)) {
256 if (canStopOperation()) {
257 if (myIsApplyEnabled)
258 aCurrentOp->commit();
260 abortOperation(aCurrentOp);
269 void XGUI_OperationMgr::abortOperation(ModuleBase_Operation* theOperation)
271 ModuleBase_Operation* aCurrentOperation = currentOperation();
272 if (theOperation == aCurrentOperation)
273 theOperation->abort();
275 // it is possible to trigger upper operation(e.g. sketch, current is sketch line)
276 // all operation from the current to triggered should also be aborted
277 // operations over the parameter one are not aborted(e.g. extrusion cut, sketch abort)
278 while(hasOperation()) {
279 ModuleBase_Operation* aCurrentOperation = currentOperation();
280 aCurrentOperation->abort();
281 if(theOperation == aCurrentOperation)
287 void XGUI_OperationMgr::onCommitOperation()
289 ModuleBase_Operation* anOperation = currentOperation();
291 anOperation->commit();
294 void XGUI_OperationMgr::onAbortOperation()
296 if (hasOperation() && canStopOperation()) {
297 abortOperation(currentOperation());
301 void XGUI_OperationMgr::onOperationStarted()
303 ModuleBase_Operation* aSenderOperation = dynamic_cast<ModuleBase_Operation*>(sender());
304 emit operationStarted(aSenderOperation);
307 void XGUI_OperationMgr::onOperationAborted()
309 ModuleBase_Operation* aSenderOperation = dynamic_cast<ModuleBase_Operation*>(sender());
310 emit operationAborted(aSenderOperation);
313 void XGUI_OperationMgr::onOperationCommitted()
315 ModuleBase_Operation* aSenderOperation = dynamic_cast<ModuleBase_Operation*>(sender());
316 emit operationCommitted(aSenderOperation);
319 void XGUI_OperationMgr::onOperationResumed()
321 ModuleBase_Operation* aSenderOperation = dynamic_cast<ModuleBase_Operation*>(sender());
322 emit operationResumed(aSenderOperation);
325 void XGUI_OperationMgr::onOperationStopped()
327 ModuleBase_Operation* aSenderOperation = dynamic_cast<ModuleBase_Operation*>(sender());
328 ModuleBase_Operation* aCurrentOperation = currentOperation();
329 if (!aSenderOperation || !aCurrentOperation || aSenderOperation != aCurrentOperation)
332 myOperations.removeAll(aCurrentOperation);
333 aCurrentOperation->deleteLater();
335 emit operationStopped(aCurrentOperation);
337 // get last operation which can be resumed
338 ModuleBase_Operation* aResultOp = 0;
339 QListIterator<ModuleBase_Operation*> anIt(myOperations);
341 while (anIt.hasPrevious()) {
342 ModuleBase_Operation* anOp = anIt.previous();
349 bool isModified = aCurrentOperation->isModified();
350 aResultOp->setIsModified(aResultOp->isModified() || isModified);
351 resumeOperation(aResultOp);
352 onValidateOperation();
356 bool XGUI_OperationMgr::onKeyReleased(QKeyEvent* theEvent)
358 // Let the manager decide what to do with the given key combination.
359 ModuleBase_Operation* anOperation = currentOperation();
360 bool isAccepted = true;
361 switch (theEvent->key()) {
363 case Qt::Key_Enter: {
364 emit keyEnterReleased();
373 // anOperation->keyReleased(theEvent->key());