Salome HOME
9b2902ecba69e614908d88253f97bdf88d7dbb4a
[modules/shaper.git] / src / XGUI / XGUI_OperationMgr.cpp
1 // File:        XGUI_OperationMgr.h
2 // Created:     20 Apr 2014
3 // Author:      Natalia ERMOLAEVA
4
5 #include "XGUI_OperationMgr.h"
6
7 #include "ModuleBase_Operation.h"
8 #include <ModelAPI_Validator.h>
9 #include <ModelAPI_FeatureValidator.h>
10
11 #include <QMessageBox>
12 #include <QApplication>
13 #include <QKeyEvent>
14
15 XGUI_OperationMgr::XGUI_OperationMgr(QObject* theParent)
16     : QObject(theParent)
17 {
18   // listen to Escape signal to stop the current operation
19   qApp->installEventFilter(this);
20 }
21
22 XGUI_OperationMgr::~XGUI_OperationMgr()
23 {
24 }
25
26 ModuleBase_Operation* XGUI_OperationMgr::currentOperation() const
27 {
28   return myOperations.count() > 0 ? myOperations.last() : 0;
29 }
30
31 bool XGUI_OperationMgr::hasOperation() const
32 {
33   return (myOperations.count() > 0) && (myOperations.last() != NULL);
34 }
35
36 int XGUI_OperationMgr::operationsCount() const
37 {
38   return myOperations.count();
39 }
40
41 bool XGUI_OperationMgr::startOperation(ModuleBase_Operation* theOperation)
42 {
43   if (!canStartOperation(theOperation))
44     return false;
45
46   myOperations.append(theOperation);
47
48   connect(theOperation, SIGNAL(stopped()), this, SLOT(onOperationStopped()));
49   connect(theOperation, SIGNAL(started()), this, SIGNAL(operationStarted()));
50   connect(theOperation, SIGNAL(resumed()), this, SIGNAL(operationResumed()));
51   connect(theOperation, SIGNAL(activateNextWidget(ModuleBase_ModelWidget*)), this,
52           SIGNAL(activateNextWidget(ModuleBase_ModelWidget*)));
53
54   theOperation->start();
55   validateCurrentOperation();
56   return true;
57 }
58
59 bool XGUI_OperationMgr::abortOperation()
60 {
61   ModuleBase_Operation* aCurrentOp = currentOperation();
62   if (!aCurrentOp || !canStopOperation())
63     return false;
64
65   aCurrentOp->abort();
66   return true;
67 }
68
69 QStringList XGUI_OperationMgr::operationList()
70 {
71   QStringList result;
72   foreach(ModuleBase_Operation* eachOperation, myOperations)
73   {
74     result << eachOperation->id();
75   }
76   return result;
77 }
78
79 void XGUI_OperationMgr::validateOperation(ModuleBase_Operation* theOperation)
80 {
81   //Get operation Id and feature to validate
82   QString anOperationId = theOperation->id();
83   FeaturePtr aFeature = theOperation->feature();
84   //Get validators for the Id
85   SessionPtr aMgr = ModelAPI_Session::get();
86   ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();
87
88   bool isValid = aFactory->validate(aFeature);
89   emit operationValidated(isValid);
90 }
91
92 void XGUI_OperationMgr::validateCurrentOperation()
93 {
94   if (!hasOperation())
95     return;
96   ModuleBase_Operation* anOperation = currentOperation();
97   validateOperation(currentOperation());
98 }
99
100 bool XGUI_OperationMgr::eventFilter(QObject *theObject, QEvent *theEvent)
101 {
102   if (theEvent->type() == QEvent::KeyRelease) {
103     QKeyEvent* aKeyEvent = (QKeyEvent*) theEvent;
104     if (aKeyEvent && aKeyEvent->key() == Qt::Key_Escape) {
105       // TODO: this is Escape button processing when the property panel has empty content,
106       // but the operation should be stopped by the Enter has been clicked
107       onKeyReleased(aKeyEvent);
108       return true;
109     }
110   }
111   return QObject::eventFilter(theObject, theEvent);
112 }
113
114 void XGUI_OperationMgr::resumeOperation(ModuleBase_Operation* theOperation)
115 {
116   theOperation->resume();
117 }
118
119 bool XGUI_OperationMgr::canStartOperation(ModuleBase_Operation* theOperation)
120 {
121   bool aCanStart = true;
122   ModuleBase_Operation* aCurrentOp = currentOperation();
123   if (aCurrentOp) {
124     if (!theOperation->isGranted()) {
125       if (!aCurrentOp->isValid(theOperation)) {
126         if (canStopOperation()) {
127           aCurrentOp->abort();
128         } else {
129           aCanStart = false;
130         }
131       }
132     }
133   }
134   return aCanStart;
135 }
136
137 bool XGUI_OperationMgr::canStopOperation()
138 {
139   ModuleBase_Operation* anOperation = currentOperation();
140   if (anOperation) {
141     if (anOperation->isModified()) {
142       int anAnswer = QMessageBox::question(
143           qApp->activeWindow(), tr("Operation launch"),
144           tr("Previous operation is not finished, abort it?"),
145           QMessageBox::Abort | QMessageBox::Cancel,
146           QMessageBox::Cancel);
147       return anAnswer == QMessageBox::Abort;
148     }
149   }
150   return true;
151 }
152
153 void XGUI_OperationMgr::onCommitOperation()
154 {
155   ModuleBase_Operation* anOperation = currentOperation();
156   anOperation->onWidgetActivated(NULL);
157   if (anOperation)
158     anOperation->commit();
159 }
160
161 void XGUI_OperationMgr::onAbortOperation()
162 {
163   ModuleBase_Operation* anOperation = currentOperation();
164   if (anOperation && canAbortOperation())
165     anOperation->abort();
166 }
167
168 bool XGUI_OperationMgr::canAbortOperation()
169 {
170   ModuleBase_Operation* anOperation = currentOperation();
171   if (anOperation && anOperation->isModified()) {
172     int anAnswer = QMessageBox::question(
173         qApp->activeWindow(), tr("Cancel operation"),
174         tr("Operation %1 will be cancelled. Continue?").arg(anOperation->id()), QMessageBox::Yes,
175         QMessageBox::No);
176     return anAnswer == QMessageBox::Yes;
177   }
178   return true;
179 }
180
181 void XGUI_OperationMgr::onOperationStopped()
182 {
183   ModuleBase_Operation* aSenderOperation = dynamic_cast<ModuleBase_Operation*>(sender());
184   ModuleBase_Operation* anOperation = currentOperation();
185   if (!aSenderOperation || !anOperation || aSenderOperation != anOperation)
186     return;
187
188   myOperations.removeAll(anOperation);
189   anOperation->deleteLater();
190
191   emit operationStopped(anOperation);
192
193   // get last operation which can be resumed
194   ModuleBase_Operation* aResultOp = 0;
195   QListIterator<ModuleBase_Operation*> anIt(myOperations);
196   anIt.toBack();
197   while (anIt.hasPrevious()) {
198     ModuleBase_Operation* anOp = anIt.previous();
199     if (anOp) {
200       aResultOp = anOp;
201       break;
202     }
203   }
204   if (aResultOp) {
205     resumeOperation(aResultOp);
206     validateCurrentOperation();
207   }
208 }
209
210 void XGUI_OperationMgr::onKeyReleased(QKeyEvent* theEvent)
211 {
212   ModuleBase_Operation* anOperation = currentOperation();
213   if (anOperation)
214     anOperation->keyReleased(theEvent->key());
215 }
216
217 void XGUI_OperationMgr::onWidgetActivated(ModuleBase_ModelWidget* theWidget)
218 {
219   ModuleBase_Operation* anOperation = currentOperation();
220   if (anOperation)
221     anOperation->onWidgetActivated(theWidget);
222 }