]> SALOME platform Git repositories - modules/shaper.git/blob - src/XGUI/XGUI_OperationMgr.cpp
Salome HOME
Merge branch 'master' of newgeom:newgeom.git
[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::startOperation(ModuleBase_Operation* theOperation)
52 {
53   if (!canStartOperation(theOperation))
54     return false;
55
56   myOperations.append(theOperation);
57
58   connect(theOperation, SIGNAL(stopped()), this, SLOT(onOperationStopped()));
59   connect(theOperation, SIGNAL(started()), this, SIGNAL(operationStarted()));
60   connect(theOperation, SIGNAL(resumed()), this, SIGNAL(operationResumed()));
61   connect(theOperation, SIGNAL(activateNextWidget(ModuleBase_ModelWidget*)), this,
62           SIGNAL(activateNextWidget(ModuleBase_ModelWidget*)));
63
64   theOperation->start();
65   onValidateOperation();
66   return true;
67 }
68
69 bool XGUI_OperationMgr::abortAllOperations()
70 {
71   if (operationsCount() == 1) {
72     onAbortOperation();
73     return true;
74   }
75   QString aMessage = tr("All active operations will be aborted.");
76   int anAnswer = QMessageBox::question(qApp->activeWindow(),
77                                        tr("Abort operation"),
78                                        aMessage,
79                                        QMessageBox::Ok | QMessageBox::Cancel,
80                                        QMessageBox::Cancel);
81   bool result = anAnswer == QMessageBox::Ok;
82   while(result && hasOperation()) {
83     currentOperation()->abort();
84   }
85   return result;
86 }
87
88 bool XGUI_OperationMgr::validateOperation(ModuleBase_Operation* theOperation)
89 {
90   //Get operation feature to validate
91   FeaturePtr aFeature = theOperation->feature();
92   //Get validators for the Id
93   SessionPtr aMgr = ModelAPI_Session::get();
94   ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();
95
96   bool isValid = aFactory->validate(aFeature);
97   emit operationValidated(isValid);
98   return isValid;
99 }
100
101 void XGUI_OperationMgr::onValidateOperation()
102 {
103   if (!hasOperation())
104     return;
105   ModuleBase_Operation* anOperation = currentOperation();
106   validateOperation(currentOperation());
107 }
108
109 bool XGUI_OperationMgr::eventFilter(QObject *theObject, QEvent *theEvent)
110 {
111   if (theEvent->type() == QEvent::KeyRelease) {
112     QKeyEvent* aKeyEvent = dynamic_cast<QKeyEvent*>(theEvent);
113     // TODO: this is Escape button processing when the property panel has empty content,
114     // but the operation should be stopped by the Enter has been clicked
115     if(aKeyEvent) {
116       onKeyReleased(aKeyEvent);
117       return true;
118     }
119   }
120   return QObject::eventFilter(theObject, theEvent);
121 }
122
123 void XGUI_OperationMgr::commitOperation()
124 {
125   if (validateOperation(currentOperation())) {
126     onCommitOperation();
127   }
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   anOperation->onWidgetActivated(NULL);
158   if (anOperation)
159     anOperation->commit();
160 }
161
162 void XGUI_OperationMgr::onAbortOperation()
163 {
164   if (hasOperation() && canAbortOperation()) {
165     currentOperation()->abort();
166   }
167 }
168
169 bool XGUI_OperationMgr::canAbortOperation()
170 {
171   ModuleBase_Operation* anOperation = currentOperation();
172   if (anOperation && anOperation->isModified()) {
173     QString aMessage = tr("%1 operation will be aborted.").arg(anOperation->id());
174     int anAnswer = QMessageBox::question(qApp->activeWindow(),
175                                          tr("Abort operation"),
176                                          aMessage,
177                                          QMessageBox::Ok | QMessageBox::Cancel,
178                                          QMessageBox::Cancel);
179     return anAnswer == QMessageBox::Ok;
180   }
181   return true;
182 }
183
184 void XGUI_OperationMgr::onOperationStopped()
185 {
186   ModuleBase_Operation* aSenderOperation = dynamic_cast<ModuleBase_Operation*>(sender());
187   ModuleBase_Operation* anOperation = currentOperation();
188   if (!aSenderOperation || !anOperation || aSenderOperation != anOperation)
189     return;
190
191   myOperations.removeAll(anOperation);
192   anOperation->deleteLater();
193
194   emit operationStopped(anOperation);
195
196   // get last operation which can be resumed
197   ModuleBase_Operation* aResultOp = 0;
198   QListIterator<ModuleBase_Operation*> anIt(myOperations);
199   anIt.toBack();
200   while (anIt.hasPrevious()) {
201     ModuleBase_Operation* anOp = anIt.previous();
202     if (anOp) {
203       aResultOp = anOp;
204       break;
205     }
206   }
207   if (aResultOp) {
208     resumeOperation(aResultOp);
209     onValidateOperation();
210   }
211 }
212
213 void XGUI_OperationMgr::onKeyReleased(QKeyEvent* theEvent)
214 {
215   ModuleBase_Operation* anOperation = currentOperation();
216   if (anOperation) {
217     bool isFinished = anOperation->keyReleased(theEvent->key());
218     if(isFinished)
219       return;
220   }
221   // Let the manager decide what to do with the given key combination.
222   switch (theEvent->key()) {
223     case Qt::Key_Escape:
224       onAbortOperation();
225       break;
226     case Qt::Key_Return:
227     case Qt::Key_Enter:
228       commitOperation();
229       break;
230     default:
231       break;
232   }
233 }
234
235 void XGUI_OperationMgr::onWidgetActivated(ModuleBase_ModelWidget* theWidget)
236 {
237   ModuleBase_Operation* anOperation = currentOperation();
238   if (anOperation)
239     anOperation->onWidgetActivated(theWidget);
240 }