Salome HOME
Make property panel as a GUI of an operation
[modules/shaper.git] / src / ModuleBase / ModuleBase_Operation.cpp
1 /*
2  * ModuleBase_Operation.cpp
3  *
4  *  Created on: Apr 2, 2014
5  *      Author: sbh
6  */
7
8 #include "ModuleBase_Operation.h"
9
10 #include "ModuleBase_OperationDescription.h"
11 #include "ModuleBase_ModelWidget.h"
12 #include "ModuleBase_WidgetValueFeature.h"
13 #include "ModuleBase_ViewerPrs.h"
14 #include "ModuleBase_IPropertyPanel.h"
15
16 #include <ModelAPI_AttributeDouble.h>
17 #include <ModelAPI_Document.h>
18 #include <ModelAPI_Feature.h>
19 #include <ModelAPI_Data.h>
20 #include <ModelAPI_Document.h>
21 #include <ModelAPI_Events.h>
22 #include <ModelAPI_Result.h>
23 #include <ModelAPI_Validator.h>
24
25 #include <GeomAPI_Pnt2d.h>
26
27 #include <Events_Loop.h>
28
29 #ifdef _DEBUG
30 #include <QDebug>
31 #endif
32
33 ModuleBase_Operation::ModuleBase_Operation(const QString& theId, QObject* theParent)
34     : QObject(theParent),
35       myIsEditing(false),
36       myIsModified(false),
37       myPropertyPanel(NULL)
38 {
39   myDescription = new ModuleBase_OperationDescription(theId);
40 }
41
42 ModuleBase_Operation::~ModuleBase_Operation()
43 {
44   delete myDescription;
45 }
46
47 QString ModuleBase_Operation::id() const
48 {
49   return getDescription()->operationId();
50 }
51
52 FeaturePtr ModuleBase_Operation::feature() const
53 {
54   return myFeature;
55 }
56
57 bool ModuleBase_Operation::isValid() const
58 {
59   if (!myFeature)
60     return true; // rename operation
61   //Get validators for the Id
62   SessionPtr aMgr = ModelAPI_Session::get();
63   ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();
64   return aFactory->validate(myFeature);
65 }
66
67 bool ModuleBase_Operation::isNestedOperationsEnabled() const
68 {
69   return true;
70 }
71
72 void ModuleBase_Operation::storeCustomValue()
73 {
74   if (!myFeature) {
75 #ifdef _DEBUG
76     qDebug() << "ModuleBase_Operation::storeCustom: " <<
77     "trying to store value without opening a transaction.";
78 #endif
79     return;
80   }
81
82   ModuleBase_ModelWidget* aCustom = dynamic_cast<ModuleBase_ModelWidget*>(sender());
83   if (aCustom)
84     aCustom->storeValue();
85 }
86
87 void ModuleBase_Operation::startOperation()
88 {
89   if (!myIsEditing)
90     createFeature();
91 }
92
93 void ModuleBase_Operation::stopOperation()
94 {
95 }
96
97 void ModuleBase_Operation::abortOperation()
98 {
99 }
100
101 void ModuleBase_Operation::commitOperation()
102 {
103 }
104
105 void ModuleBase_Operation::afterCommitOperation()
106 {
107 }
108
109 bool ModuleBase_Operation::canBeCommitted() const
110 {
111   return true;
112 }
113
114 void ModuleBase_Operation::flushUpdated()
115 {
116   Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
117 }
118
119 void ModuleBase_Operation::flushCreated()
120 {
121   Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED));
122 }
123
124 FeaturePtr ModuleBase_Operation::createFeature(const bool theFlushMessage)
125 {
126   boost::shared_ptr<ModelAPI_Document> aDoc = document();
127   myFeature = aDoc->addFeature(getDescription()->operationId().toStdString());
128   if (myFeature) {  // TODO: generate an error if feature was not created
129     myIsModified = true;
130     // Model update should call "execute" of a feature.
131     //myFeature->execute();
132     // Init default values
133     /*QList<ModuleBase_ModelWidget*> aWidgets = getDescription()->modelWidgets();
134      QList<ModuleBase_ModelWidget*>::const_iterator anIt = aWidgets.begin(), aLast = aWidgets.end();
135      for (; anIt != aLast; anIt++) {
136      (*anIt)->storeValue(aFeature);
137      }*/
138   }
139
140   if (theFlushMessage)
141     flushCreated();
142   return myFeature;
143 }
144
145 void ModuleBase_Operation::setFeature(FeaturePtr theFeature)
146 {
147   myFeature = theFeature;
148   myIsEditing = true;
149 }
150
151 bool ModuleBase_Operation::hasObject(ObjectPtr theObj) const
152 {
153   FeaturePtr aFeature = feature();
154   if (aFeature) {
155     if (aFeature == theObj)
156       return true;
157     std::list<ResultPtr> aResults = aFeature->results();
158     std::list<ResultPtr>::const_iterator aIt;
159     for (aIt = aResults.cbegin(); aIt != aResults.cend(); ++aIt) {
160       if ((*aIt) == theObj)
161         return true;
162     }
163   }
164   return false;
165 }
166
167
168 boost::shared_ptr<ModelAPI_Document> ModuleBase_Operation::document() const
169 {
170   return ModelAPI_Session::get()->moduleDocument();
171 }
172
173
174 void ModuleBase_Operation::start()
175 {
176   ModelAPI_Session::get()->startOperation();
177
178   startOperation();
179   emit started();
180 }
181
182 void ModuleBase_Operation::resume()
183 {
184   if (myPropertyPanel)
185     connect(myPropertyPanel, SIGNAL(widgetActivated(ModuleBase_ModelWidget*)), this,
186             SLOT(onWidgetActivated(ModuleBase_ModelWidget*)));
187   emit resumed();
188 }
189
190 void ModuleBase_Operation::abort()
191 {
192   abortOperation();
193   emit aborted();
194   if (myPropertyPanel)
195     disconnect(myPropertyPanel, 0, this, 0);
196
197   stopOperation();
198
199   ModelAPI_Session::get()->abortOperation();
200   emit stopped();
201 }
202
203 bool ModuleBase_Operation::commit()
204 {
205   if (canBeCommitted()) {
206     commitOperation();
207     emit committed();
208
209   if (myPropertyPanel)
210     disconnect(myPropertyPanel, 0, this, 0);
211
212     stopOperation();
213
214     ModelAPI_Session::get()->finishOperation();
215     emit stopped();
216
217     afterCommitOperation();
218     return true;
219   }
220   return false;
221 }
222
223 void ModuleBase_Operation::setRunning(bool theState)
224 {
225   if (!theState) {
226     abort();
227   }
228 }
229
230 void ModuleBase_Operation::activateByPreselection()
231 {
232   if (!myPropertyPanel)
233     return;
234   ModuleBase_ModelWidget* aActiveWgt = myPropertyPanel->activeWidget();
235   if ((myPreSelection.size() > 0) && aActiveWgt) {
236     const ModuleBase_ViewerPrs& aPrs = myPreSelection.front();
237     ModuleBase_WidgetValueFeature aValue;
238     aValue.setObject(aPrs.object());
239     if (aActiveWgt->setValue(&aValue)) {
240       myPreSelection.remove(aPrs);
241       if(isValid()) {
242         //myActiveWidget = NULL;
243         commit();
244       } else {
245         myPropertyPanel->activateNextWidget();
246         //emit activateNextWidget(myActiveWidget);
247       }
248     }
249     // If preselection is enough to make a valid feature - apply it immediately
250   }
251 }
252
253 void ModuleBase_Operation::initSelection(
254     const std::list<ModuleBase_ViewerPrs>& theSelected,
255     const std::list<ModuleBase_ViewerPrs>& /*theHighlighted*/)
256 {
257   myPreSelection = theSelected;
258 }
259
260 void ModuleBase_Operation::onWidgetActivated(ModuleBase_ModelWidget* theWidget)
261 {
262   activateByPreselection();
263   //if (theWidget && myPropertyPanel) {
264   //  myPropertyPanel->activateNextWidget();
265   ////  //emit activateNextWidget(myActiveWidget);
266   //}
267 }
268
269 bool ModuleBase_Operation::setWidgetValue(ObjectPtr theFeature, double theX, double theY)
270 {
271   ModuleBase_ModelWidget* aActiveWgt = myPropertyPanel->activeWidget();
272   if (!aActiveWgt)
273     return false;
274   ModuleBase_WidgetValueFeature* aValue = new ModuleBase_WidgetValueFeature();
275   aValue->setObject(theFeature);
276   aValue->setPoint(boost::shared_ptr<GeomAPI_Pnt2d>(new GeomAPI_Pnt2d(theX, theY)));
277   bool isApplyed = aActiveWgt->setValue(aValue);
278
279   delete aValue;
280   myIsModified = (myIsModified || isApplyed);
281   return isApplyed;
282 }
283
284
285 void ModuleBase_Operation::setPropertyPanel(ModuleBase_IPropertyPanel* theProp) 
286
287   myPropertyPanel = theProp; 
288   connect(myPropertyPanel, SIGNAL(widgetActivated(ModuleBase_ModelWidget*)), this,
289           SLOT(onWidgetActivated(ModuleBase_ModelWidget*)));
290 }