Salome HOME
Provide connection of new features in SALOME module
[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
50   theOperation->start();
51   return true;
52 }
53
54 bool XGUI_OperationMgr::abortOperation()
55 {
56   ModuleBase_Operation* aCurrentOp = currentOperation();
57   if (!aCurrentOp || !canStopOperation())
58     return false; 
59
60   aCurrentOp->abort();
61   return true;
62 }
63
64 QStringList XGUI_OperationMgr::operationList()
65 {
66   QStringList result;
67   foreach(ModuleBase_Operation* eachOperation, myOperations) {
68     result << eachOperation->id();
69   }
70   return result;
71 }
72
73 bool XGUI_OperationMgr::eventFilter(QObject *theObject, QEvent *theEvent)
74 {
75   if (theEvent->type() == QEvent::KeyRelease) {
76     QKeyEvent* aKeyEvent = (QKeyEvent*)theEvent;
77     if (aKeyEvent && aKeyEvent->key() == Qt::Key_Escape) {
78       // TODO: this is Escape button processing when the property panel has empty content,
79       // but the operation should be stopped by the Enter has been clicked
80       onKeyReleased("", aKeyEvent);
81       return true;
82     }
83   }
84   return QObject::eventFilter(theObject, theEvent);
85 }
86
87 void XGUI_OperationMgr::resumeOperation(ModuleBase_Operation* theOperation)
88 {
89   theOperation->resume();
90 }
91
92 bool XGUI_OperationMgr::canStartOperation(ModuleBase_Operation* theOperation)
93 {
94   bool aCanStart = true;
95   ModuleBase_Operation* aCurrentOp = currentOperation();
96   if (aCurrentOp && !theOperation->isGranted(aCurrentOp))
97   {
98     if (canStopOperation()) {
99       aCurrentOp->abort();
100     } else {
101       aCanStart = false;
102     }
103   }
104   return aCanStart;
105 }
106
107 bool XGUI_OperationMgr::canStopOperation()
108 {
109   int anAnswer = QMessageBox::question(0, tr("Operation launch"),
110                               tr("Previous operation is not finished and will be aborted"),
111                               QMessageBox::Ok, QMessageBox::Cancel);
112   return anAnswer == QMessageBox::Ok;
113 }
114
115 void XGUI_OperationMgr::onCommitOperation()
116 {
117   ModuleBase_Operation* anOperation = currentOperation();
118   if (anOperation) {
119     if (anOperation->canBeCommitted())
120       anOperation->commit();
121     else
122       anOperation->abort();
123   }
124 }
125
126 void XGUI_OperationMgr::onAbortOperation()
127 {
128   ModuleBase_Operation* anOperation = currentOperation();
129   if (anOperation)
130     anOperation->abort();
131 }
132
133 void XGUI_OperationMgr::onOperationStopped()
134 {
135   ModuleBase_Operation* aSenderOperation = dynamic_cast<ModuleBase_Operation*>(sender());
136   ModuleBase_Operation* anOperation = currentOperation();
137   if (!aSenderOperation || !anOperation || aSenderOperation != anOperation )
138     return;
139
140   myOperations.removeAll(anOperation);
141   anOperation->deleteLater();
142
143   emit operationStopped(anOperation);
144
145   // get last operation which can be resumed
146   ModuleBase_Operation* aResultOp = 0;
147   QListIterator<ModuleBase_Operation*> anIt(myOperations);
148   anIt.toBack();
149   while(anIt.hasPrevious())
150   {
151     ModuleBase_Operation* anOp = anIt.previous();
152     if (anOp) {
153       aResultOp = anOp;
154       break;
155     }
156   }
157   if (aResultOp)
158     resumeOperation(aResultOp);
159 }
160
161 void XGUI_OperationMgr::onKeyReleased(const std::string& theName, QKeyEvent* theEvent)
162 {
163   ModuleBase_Operation* anOperation = currentOperation();
164   if (anOperation)
165     anOperation->keyReleased(theName, theEvent);
166 }