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