Salome HOME
Merge remote-tracking branch 'remotes/origin/master' into SketchSolver
[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   int anAnswer = QMessageBox::question(0, tr("Operation launch"),
112                               tr("Previous operation is not finished and will be aborted"),
113                               QMessageBox::Ok, QMessageBox::Cancel);
114   return anAnswer == QMessageBox::Ok;
115 }
116
117 void XGUI_OperationMgr::onCommitOperation()
118 {
119   ModuleBase_Operation* anOperation = currentOperation();
120   if (anOperation) {
121     if (anOperation->canBeCommitted())
122       anOperation->commit();
123     else
124       anOperation->abort();
125   }
126 }
127
128 void XGUI_OperationMgr::onAbortOperation()
129 {
130   ModuleBase_Operation* anOperation = currentOperation();
131   if (anOperation)
132     anOperation->abort();
133 }
134
135 void XGUI_OperationMgr::onOperationStopped()
136 {
137   ModuleBase_Operation* aSenderOperation = dynamic_cast<ModuleBase_Operation*>(sender());
138   ModuleBase_Operation* anOperation = currentOperation();
139   if (!aSenderOperation || !anOperation || aSenderOperation != anOperation )
140     return;
141
142   myOperations.removeAll(anOperation);
143   anOperation->deleteLater();
144
145   emit operationStopped(anOperation);
146
147   // get last operation which can be resumed
148   ModuleBase_Operation* aResultOp = 0;
149   QListIterator<ModuleBase_Operation*> anIt(myOperations);
150   anIt.toBack();
151   while(anIt.hasPrevious())
152   {
153     ModuleBase_Operation* anOp = anIt.previous();
154     if (anOp) {
155       aResultOp = anOp;
156       break;
157     }
158   }
159   if (aResultOp)
160     resumeOperation(aResultOp);
161 }
162
163 void XGUI_OperationMgr::onKeyReleased(const std::string& theName, QKeyEvent* theEvent)
164 {
165   ModuleBase_Operation* anOperation = currentOperation();
166   if (anOperation)
167     anOperation->keyReleased(theName, theEvent);
168 }
169
170 void XGUI_OperationMgr::onWidgetActivated(ModuleBase_ModelWidget* theWidget)
171 {
172   ModuleBase_Operation* anOperation = currentOperation();
173   if (anOperation)
174     anOperation->onWidgetActivated(theWidget);
175 }