]> SALOME platform Git repositories - modules/shaper.git/blob - src/XGUI/XGUI_OperationMgr.cpp
Salome HOME
Implementation of the Feature Validator
[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*)),
52           this, 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     result << eachOperation->id();
74   }
75   return result;
76 }
77
78 void XGUI_OperationMgr::validateOperation(ModuleBase_Operation* theOperation)
79 {
80   //Get operation Id and feature to validate
81   QString anOperationId = theOperation->id();
82   FeaturePtr aFeature = theOperation->feature();
83   //Get validators for the Id
84   PluginManagerPtr aMgr = ModelAPI_PluginManager::get();
85   ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();
86   std::list<ModelAPI_Validator*> aValidators;
87   aFactory->validators(anOperationId.toStdString(), aValidators);
88   //
89   std::list<ModelAPI_Validator*>::iterator it = aValidators.begin();
90   bool isValid = true;
91   for(; it != aValidators.end(); it++) {
92     const ModelAPI_FeatureValidator* aFeatureValidator =
93         dynamic_cast<const ModelAPI_FeatureValidator*>(*it);
94     if (!aFeatureValidator) continue;
95     if (!aFeatureValidator->isValid(aFeature)) {
96       isValid = false;
97       break;
98     }
99   }
100   emit operationValidated(isValid);
101 }
102
103 void XGUI_OperationMgr::validateCurrentOperation()
104 {
105   if(!hasOperation())
106     return;
107   ModuleBase_Operation* anOperation = currentOperation();
108   validateOperation(currentOperation());
109 }
110
111 bool XGUI_OperationMgr::eventFilter(QObject *theObject, QEvent *theEvent)
112 {
113   if (theEvent->type() == QEvent::KeyRelease) {
114     QKeyEvent* aKeyEvent = (QKeyEvent*)theEvent;
115     if (aKeyEvent && aKeyEvent->key() == Qt::Key_Escape) {
116       // TODO: this is Escape button processing when the property panel has empty content,
117       // but the operation should be stopped by the Enter has been clicked
118       onKeyReleased("", aKeyEvent);
119       return true;
120     }
121   }
122   return QObject::eventFilter(theObject, theEvent);
123 }
124
125 void XGUI_OperationMgr::resumeOperation(ModuleBase_Operation* theOperation)
126 {
127   theOperation->resume();
128 }
129
130 bool XGUI_OperationMgr::canStartOperation(ModuleBase_Operation* theOperation)
131 {
132   bool aCanStart = true;
133   ModuleBase_Operation* aCurrentOp = currentOperation();
134   if (aCurrentOp && !theOperation->isGranted(aCurrentOp))
135   {
136     if (canStopOperation()) {
137       aCurrentOp->abort();
138     } else {
139       aCanStart = false;
140     }
141   }
142   return aCanStart;
143 }
144
145 bool XGUI_OperationMgr::canStopOperation()
146 {
147   ModuleBase_Operation* anOperation = currentOperation();
148   if (anOperation) {
149     if (anOperation->isModified()) {
150       int anAnswer = QMessageBox::question(qApp->activeWindow(), tr("Operation launch"),
151                                   tr("Previous operation is not finished and will be aborted"),
152                                   QMessageBox::Ok, QMessageBox::Cancel);
153       return anAnswer == QMessageBox::Ok;
154     }
155   }
156   return true;
157 }
158
159 void XGUI_OperationMgr::onCommitOperation()
160 {
161   ModuleBase_Operation* anOperation = currentOperation();
162   if (anOperation)
163     anOperation->commit();
164 }
165
166 void XGUI_OperationMgr::onAbortOperation()
167 {
168   ModuleBase_Operation* anOperation = currentOperation();
169   if (anOperation && canAbortOperation())
170     anOperation->abort();
171 }
172
173 bool XGUI_OperationMgr::canAbortOperation()
174 {
175   ModuleBase_Operation* anOperation = currentOperation();
176   if (anOperation && anOperation->isModified()) {
177       int anAnswer = QMessageBox::question(qApp->activeWindow(), tr("Cancel operation"),
178                                   tr("Operation %1 will be cancelled. Continue?").arg(anOperation->id()),
179                                   QMessageBox::Yes, QMessageBox::No);
180       return anAnswer == QMessageBox::Yes;
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   {
203     ModuleBase_Operation* anOp = anIt.previous();
204     if (anOp) {
205       aResultOp = anOp;
206       break;
207     }
208   }
209   if (aResultOp)
210     resumeOperation(aResultOp);
211 }
212
213 void XGUI_OperationMgr::onKeyReleased(const std::string& theName, QKeyEvent* theEvent)
214 {
215   ModuleBase_Operation* anOperation = currentOperation();
216   if (anOperation)
217     anOperation->keyReleased(theName, theEvent);
218 }
219
220 void XGUI_OperationMgr::onWidgetActivated(ModuleBase_ModelWidget* theWidget)
221 {
222   ModuleBase_Operation* anOperation = currentOperation();
223   if (anOperation)
224     anOperation->onWidgetActivated(theWidget);
225 }