]> SALOME platform Git repositories - modules/shaper.git/blob - src/XGUI/XGUI_OperationMgr.cpp
Salome HOME
b8e43d7ea0ac8d07bd6a8b61f81869643fc0485a
[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 QStringList XGUI_OperationMgr::operationList()
42 {
43   QStringList result;
44   foreach(ModuleBase_Operation* eachOperation, myOperations)
45   {
46     result << eachOperation->id();
47   }
48   return result;
49 }
50
51 bool XGUI_OperationMgr::eventFilter(QObject *theObject, QEvent *theEvent)
52 {
53   if (theEvent->type() == QEvent::KeyRelease) {
54     QKeyEvent* aKeyEvent = dynamic_cast<QKeyEvent*>(theEvent);
55     if(aKeyEvent) {
56       onKeyReleased(aKeyEvent);
57       return true;
58     }
59   }
60   return QObject::eventFilter(theObject, theEvent);
61 }
62
63 bool XGUI_OperationMgr::startOperation(ModuleBase_Operation* theOperation)
64 {
65   if (!canStartOperation(theOperation))
66     return false;
67
68   myOperations.append(theOperation);
69
70   connect(theOperation, SIGNAL(stopped()), this, SLOT(onOperationStopped()));
71   connect(theOperation, SIGNAL(started()), this, SIGNAL(operationStarted()));
72   connect(theOperation, SIGNAL(resumed()), this, SIGNAL(operationResumed()));
73   connect(theOperation, SIGNAL(activateNextWidget(ModuleBase_ModelWidget*)), this,
74           SIGNAL(activateNextWidget(ModuleBase_ModelWidget*)));
75
76   theOperation->start();
77   onValidateOperation();
78   return true;
79 }
80
81 bool XGUI_OperationMgr::abortAllOperations()
82 {
83   if (operationsCount() == 1) {
84     onAbortOperation();
85     return true;
86   }
87   QString aMessage = tr("All active operations will be aborted.");
88   int anAnswer = QMessageBox::question(qApp->activeWindow(),
89                                        tr("Abort operation"),
90                                        aMessage,
91                                        QMessageBox::Ok | QMessageBox::Cancel,
92                                        QMessageBox::Cancel);
93   bool result = anAnswer == QMessageBox::Ok;
94   while(result && hasOperation()) {
95     currentOperation()->abort();
96   }
97   return result;
98 }
99
100 bool XGUI_OperationMgr::validateOperation(ModuleBase_Operation* theOperation)
101 {
102   //Get operation feature to validate
103   FeaturePtr aFeature = theOperation->feature();
104   //Get validators for the Id
105   SessionPtr aMgr = ModelAPI_Session::get();
106   ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();
107
108   bool isValid = aFactory->validate(aFeature);
109   emit operationValidated(isValid);
110   return isValid;
111 }
112
113 void XGUI_OperationMgr::onValidateOperation()
114 {
115   if (!hasOperation())
116     return;
117   ModuleBase_Operation* anOperation = currentOperation();
118   validateOperation(currentOperation());
119 }
120
121 bool XGUI_OperationMgr::commitOperation()
122 {
123   if (validateOperation(currentOperation())) {
124     onCommitOperation();
125     return true;
126   }
127   return false;
128 }
129
130 void XGUI_OperationMgr::resumeOperation(ModuleBase_Operation* theOperation)
131 {
132   theOperation->resume();
133 }
134
135 bool XGUI_OperationMgr::canStartOperation(ModuleBase_Operation* theOperation)
136 {
137   bool aCanStart = true;
138   ModuleBase_Operation* aCurrentOp = currentOperation();
139   if (aCurrentOp) {
140     if (!theOperation->isGranted()) {
141       if (!aCurrentOp->isValid(theOperation)) {
142         if (canAbortOperation()) {
143           aCurrentOp->abort();
144         } else {
145           aCanStart = false;
146         }
147       }
148     }
149   }
150   return aCanStart;
151 }
152
153
154 void XGUI_OperationMgr::onCommitOperation()
155 {
156   ModuleBase_Operation* anOperation = currentOperation();
157   if (anOperation)
158     anOperation->commit();
159 }
160
161 void XGUI_OperationMgr::onAbortOperation()
162 {
163   if (hasOperation() && canAbortOperation()) {
164     currentOperation()->abort();
165   }
166 }
167
168 bool XGUI_OperationMgr::canAbortOperation()
169 {
170   ModuleBase_Operation* anOperation = currentOperation();
171   if(operationsCount() > 1) //in case of nested (sketch) operation no confirmation needed
172     return true;
173   if (anOperation && anOperation->isModified()) {
174     QString aMessage = tr("%1 operation will be aborted.").arg(anOperation->id());
175     int anAnswer = QMessageBox::question(qApp->activeWindow(),
176                                          tr("Abort operation"),
177                                          aMessage,
178                                          QMessageBox::Ok | QMessageBox::Cancel,
179                                          QMessageBox::Cancel);
180     return anAnswer == QMessageBox::Ok;
181   }
182   return true;
183 }
184
185 void XGUI_OperationMgr::onOperationStopped()
186 {
187   ModuleBase_Operation* aSenderOperation = dynamic_cast<ModuleBase_Operation*>(sender());
188   ModuleBase_Operation* anOperation = currentOperation();
189   if (!aSenderOperation || !anOperation || aSenderOperation != anOperation)
190     return;
191
192   myOperations.removeAll(anOperation);
193   anOperation->deleteLater();
194
195   emit operationStopped(anOperation);
196
197   // get last operation which can be resumed
198   ModuleBase_Operation* aResultOp = 0;
199   QListIterator<ModuleBase_Operation*> anIt(myOperations);
200   anIt.toBack();
201   while (anIt.hasPrevious()) {
202     ModuleBase_Operation* anOp = anIt.previous();
203     if (anOp) {
204       aResultOp = anOp;
205       break;
206     }
207   }
208   if (aResultOp) {
209     resumeOperation(aResultOp);
210     onValidateOperation();
211   }
212 }
213
214 void XGUI_OperationMgr::onKeyReleased(QKeyEvent* theEvent)
215 {
216   // Let the manager decide what to do with the given key combination.
217   ModuleBase_Operation* anOperation = currentOperation();
218   if(anOperation) {
219     anOperation->activateNextToCurrentWidget();
220   }
221   bool isRestart = false;
222   switch (theEvent->key()) {
223     case Qt::Key_Escape: {
224       onAbortOperation();
225     }
226       break;
227     case Qt::Key_Return:
228     case Qt::Key_Enter: {
229       commitOperation();
230     }
231       break;
232     default:
233       break;
234   }
235   if(anOperation)
236     anOperation->keyReleased(theEvent->key());
237 }
238
239 void XGUI_OperationMgr::onWidgetActivated(ModuleBase_ModelWidget* theWidget)
240 {
241   ModuleBase_Operation* anOperation = currentOperation();
242   if (anOperation)
243     anOperation->onWidgetActivated(theWidget);
244 }