]> SALOME platform Git repositories - modules/shaper.git/blob - src/PartSet/PartSet_Module.cpp
Salome HOME
#refs 76 - reported by Hervé Legrand: Edit Sketch as Constructions child - crash
[modules/shaper.git] / src / PartSet / PartSet_Module.cpp
1 #include <PartSet_Module.h>
2 #include <PartSet_OperationSketch.h>
3 #include <PartSet_OperationSketchLine.h>
4 #include <PartSet_OperationEditLine.h>
5 #include <ModuleBase_Operation.h>
6 #include <ModuleBase_OperationDescription.h>
7 #include <PartSet_Listener.h>
8 #include <PartSet_TestOCC.h>
9
10 #include <ModuleBase_Operation.h>
11 #include <ModelAPI_Object.h>
12
13 #include <XGUI_MainWindow.h>
14 #include <XGUI_Displayer.h>
15 #include <XGUI_Viewer.h>
16 #include <XGUI_Workshop.h>
17 #include <XGUI_OperationMgr.h>
18 #include <XGUI_SelectionMgr.h>
19 #include <XGUI_ViewPort.h>
20 #include <XGUI_ActionsMgr.h>
21 #include <XGUI_ViewerProxy.h>
22 #include <XGUI_ContextMenuMgr.h>
23 #include <XGUI_PropertyPanel.h>
24 #include <XGUI_Tools.h>
25
26 #include <Config_PointerMessage.h>
27 #include <Config_ModuleReader.h>
28 #include <Config_WidgetReader.h>
29 #include <Events_Loop.h>
30 #include <Events_Message.h>
31 #include <Events_Error.h>
32
33 #include <GeomAPI_Shape.h>
34
35 #include <AIS_ListOfInteractive.hxx>
36
37 #include <QObject>
38 #include <QMouseEvent>
39 #include <QString>
40
41 #ifdef _DEBUG
42 #include <QDebug>
43 #endif
44
45 /*!Create and return new instance of XGUI_Module*/
46 extern "C" PARTSET_EXPORT XGUI_Module* createModule(XGUI_Workshop* theWshop)
47 {
48   return new PartSet_Module(theWshop);
49 }
50
51 PartSet_Module::PartSet_Module(XGUI_Workshop* theWshop)
52 {
53   myWorkshop = theWshop;
54   myListener = new PartSet_Listener(this);
55
56   XGUI_OperationMgr* anOperationMgr = myWorkshop->operationMgr();
57
58   connect(anOperationMgr, SIGNAL(operationStarted()),
59           this, SLOT(onOperationStarted()));
60
61   connect(anOperationMgr, SIGNAL(operationStopped(ModuleBase_Operation*)),
62           this, SLOT(onOperationStopped(ModuleBase_Operation*)));
63
64   XGUI_ContextMenuMgr* aContextMenuMgr = myWorkshop->contextMenuMgr();
65   connect(aContextMenuMgr, SIGNAL(actionTriggered(const QString&, bool)), 
66           this, SLOT(onContextMenuCommand(const QString&, bool)));
67
68   connect(myWorkshop->viewer(), SIGNAL(mousePress(QMouseEvent*)),
69           this, SLOT(onMousePressed(QMouseEvent*)));
70   connect(myWorkshop->viewer(), SIGNAL(mouseRelease(QMouseEvent*)),
71           this, SLOT(onMouseReleased(QMouseEvent*)));
72   connect(myWorkshop->viewer(), SIGNAL(mouseMove(QMouseEvent*)),
73           this, SLOT(onMouseMoved(QMouseEvent*)));
74   connect(myWorkshop->viewer(), SIGNAL(keyRelease(QKeyEvent*)),
75           this, SLOT(onKeyRelease(QKeyEvent*)));
76 }
77
78 PartSet_Module::~PartSet_Module()
79 {
80 }
81
82 XGUI_Workshop* PartSet_Module::workshop() const
83 {
84   return myWorkshop;
85 }
86
87 void PartSet_Module::createFeatures()
88 {
89   Config_ModuleReader aXMLReader = Config_ModuleReader();
90   aXMLReader.readAll();
91   myFeaturesInFiles = aXMLReader.featuresInFiles();
92 }
93
94 void PartSet_Module::featureCreated(QAction* theFeature)
95 {
96   connect(theFeature, SIGNAL(triggered(bool)), this, SLOT(onFeatureTriggered()));
97 }
98
99 QStringList PartSet_Module::nestedFeatures(QString)
100 {
101   return QStringList();
102 }
103
104 std::string PartSet_Module::featureFile(const std::string& theFeatureId)
105 {
106   return myFeaturesInFiles[theFeatureId];
107 }
108
109 /*
110  *
111  */
112 void PartSet_Module::onFeatureTriggered()
113 {
114   //PartSet_TestOCC::local_selection_change_shape(myWorkshop->viewer()->AISContext(),
115   //                                   myWorkshop->viewer()->activeView());
116
117   //PartSet_TestOCC::local_selection_erase(myWorkshop->viewer()->AISContext(),
118   //                                       myWorkshop->viewer()->activeView());
119   QAction* aCmd = dynamic_cast<QAction*>(sender());
120   //Do nothing on uncheck
121   if(aCmd->isCheckable() && !aCmd->isChecked())
122     return;
123   launchOperation(aCmd->data().toString());
124 }
125   
126 void PartSet_Module::launchOperation(const QString& theCmdId)
127 {
128   ModuleBase_Operation* anOperation = createOperation(theCmdId.toStdString());
129   sendOperation(anOperation);
130 }
131
132 void PartSet_Module::onOperationStarted()
133 {
134   PartSet_OperationSketchBase* aPreviewOp = dynamic_cast<PartSet_OperationSketchBase*>(
135                                        myWorkshop->operationMgr()->currentOperation());
136   if (aPreviewOp) {
137     XGUI_PropertyPanel* aPropPanel = myWorkshop->propertyPanel();
138     connect(aPreviewOp, SIGNAL(focusActivated(const std::string&)),
139             aPropPanel, SLOT(onFocusActivated(const std::string&)));
140   }
141 }
142
143 void PartSet_Module::onOperationStopped(ModuleBase_Operation* theOperation)
144 {
145   if (!theOperation)
146     return;
147   PartSet_OperationSketchBase* aPreviewOp = dynamic_cast<PartSet_OperationSketchBase*>(theOperation);
148   if (aPreviewOp) {
149     XGUI_PropertyPanel* aPropPanel = myWorkshop->propertyPanel();
150     disconnect(aPreviewOp, SIGNAL(focusActivated(const std::string&)),
151                aPropPanel, SLOT(onFocusActivated(const std::string&)));
152   }
153 }
154
155 void PartSet_Module::onContextMenuCommand(const QString& theId, bool isChecked)
156 {
157   QFeatureList aFeatures = myWorkshop->selector()->selectedFeatures();
158   if (theId == "EDIT_CMD" && (aFeatures.size() > 0)) {
159     editFeature(aFeatures.first());
160   }
161 }
162
163 void PartSet_Module::onMousePressed(QMouseEvent* theEvent)
164 {
165   PartSet_OperationSketchBase* aPreviewOp = dynamic_cast<PartSet_OperationSketchBase*>(
166                                        myWorkshop->operationMgr()->currentOperation());
167   if (aPreviewOp)
168   {
169     XGUI_Displayer* aDisplayer = myWorkshop->displayer();
170     std::list<XGUI_ViewerPrs> aSelected = aDisplayer->GetSelected();
171     std::list<XGUI_ViewerPrs> aHighlighted = aDisplayer->GetHighlighted();
172
173     aPreviewOp->mousePressed(theEvent, myWorkshop->viewer()->activeView(), aSelected, aHighlighted);
174   }
175 }
176
177 void PartSet_Module::onMouseReleased(QMouseEvent* theEvent)
178 {
179   PartSet_OperationSketchBase* aPreviewOp = dynamic_cast<PartSet_OperationSketchBase*>(
180                                        myWorkshop->operationMgr()->currentOperation());
181   if (aPreviewOp)
182   {
183     XGUI_Displayer* aDisplayer = myWorkshop->displayer();
184     std::list<XGUI_ViewerPrs> aSelected = aDisplayer->GetSelected();
185     std::list<XGUI_ViewerPrs> aHighlighted = aDisplayer->GetHighlighted();
186
187     aPreviewOp->mouseReleased(theEvent, myWorkshop->viewer()->activeView(), aSelected, aHighlighted);
188   }
189 }
190
191 void PartSet_Module::onMouseMoved(QMouseEvent* theEvent)
192 {
193   PartSet_OperationSketchBase* aPreviewOp = dynamic_cast<PartSet_OperationSketchBase*>(
194                                        myWorkshop->operationMgr()->currentOperation());
195   if (aPreviewOp)
196     aPreviewOp->mouseMoved(theEvent, myWorkshop->viewer()->activeView());
197 }
198
199 void PartSet_Module::onKeyRelease(QKeyEvent* theEvent)
200 {
201   ModuleBase_Operation* anOperation = myWorkshop->operationMgr()->currentOperation();
202   PartSet_OperationSketchBase* aPreviewOp = dynamic_cast<PartSet_OperationSketchBase*>(anOperation);
203   if (aPreviewOp) {
204     aPreviewOp->keyReleased(theEvent->key());
205   }
206 }
207
208 void PartSet_Module::onPlaneSelected(double theX, double theY, double theZ)
209 {
210   myWorkshop->viewer()->setViewProjection(theX, theY, theZ);
211   myWorkshop->actionsMgr()->update();
212
213   //PartSet_TestOCC::testSelection(myWorkshop);
214 }
215
216 void PartSet_Module::onLaunchOperation(std::string theName, boost::shared_ptr<ModelAPI_Feature> theFeature)
217 {
218   ModuleBase_Operation* anOperation = createOperation(theName.c_str());
219   PartSet_OperationSketchBase* aPreviewOp = dynamic_cast<PartSet_OperationSketchBase*>(anOperation);
220   if (aPreviewOp)
221   {
222     XGUI_Displayer* aDisplayer = myWorkshop->displayer();
223       // refill the features list with avoiding of the features, obtained only by vertex shape (TODO)
224     std::list<XGUI_ViewerPrs> aSelected = aDisplayer->GetSelected(TopAbs_VERTEX);
225     std::list<XGUI_ViewerPrs> aHighlighted = aDisplayer->GetHighlighted(TopAbs_VERTEX);
226     aPreviewOp->init(theFeature, aSelected, aHighlighted);
227   }
228   sendOperation(anOperation);
229   myWorkshop->actionsMgr()->updateCheckState();
230 }
231
232 void PartSet_Module::onMultiSelectionEnabled(bool theEnabled)
233 {
234   XGUI_ViewerProxy* aViewer = myWorkshop->viewer();
235   aViewer->enableMultiselection(theEnabled);
236 }
237
238 void PartSet_Module::onStopSelection(const std::list<XGUI_ViewerPrs>& theFeatures, const bool isStop)
239 {
240   XGUI_Displayer* aDisplayer = myWorkshop->displayer();
241   if (!isStop) {
242     std::list<XGUI_ViewerPrs>::const_iterator anIt = theFeatures.begin(), aLast = theFeatures.end();
243     boost::shared_ptr<ModelAPI_Feature> aFeature;
244     for (; anIt != aLast; anIt++) {
245       activateFeature((*anIt).feature(), false);
246     }
247   }
248   aDisplayer->StopSelection(theFeatures, isStop, false);
249
250   XGUI_ViewerProxy* aViewer = myWorkshop->viewer();
251   aViewer->enableSelection(!isStop);
252
253   aDisplayer->UpdateViewer();
254 }
255
256 void PartSet_Module::onSetSelection(const std::list<XGUI_ViewerPrs>& theFeatures)
257 {
258   XGUI_Displayer* aDisplayer = myWorkshop->displayer();
259   aDisplayer->SetSelected(theFeatures, false);
260   aDisplayer->UpdateViewer();
261 }
262
263 void PartSet_Module::onCloseLocalContext()
264 {
265   XGUI_Displayer* aDisplayer = myWorkshop->displayer();
266   aDisplayer->CloseLocalContexts();
267 }
268
269 void PartSet_Module::onFeatureConstructed(boost::shared_ptr<ModelAPI_Feature> theFeature,
270                                           int theMode)
271 {
272   bool isDisplay = theMode != PartSet_OperationSketchBase::FM_Hide;
273   visualizePreview(theFeature, isDisplay, false);
274   if (!isDisplay) {
275     ModuleBase_Operation* aCurOperation = myWorkshop->operationMgr()->currentOperation();
276     boost::shared_ptr<ModelAPI_Feature> aSketch;
277     PartSet_OperationSketchBase* aPrevOp = dynamic_cast<PartSet_OperationSketchBase*>(aCurOperation);
278     if (aPrevOp) {
279       std::map<boost::shared_ptr<ModelAPI_Feature>, boost::shared_ptr<GeomAPI_Shape> >
280                                                                          aList = aPrevOp->subPreview();
281       XGUI_Displayer* aDisplayer = myWorkshop->displayer();
282       std::list<int> aModes = aPrevOp->getSelectionModes(aPrevOp->feature());
283
284       std::map<boost::shared_ptr<ModelAPI_Feature>, boost::shared_ptr<GeomAPI_Shape> >::const_iterator
285                                                              anIt = aList.begin(), aLast = aList.end();
286       for (; anIt != aLast; anIt++) {
287         boost::shared_ptr<ModelAPI_Feature> aFeature = (*anIt).first;
288         visualizePreview(aFeature, false, false);
289       }
290       aDisplayer->UpdateViewer();
291     }
292   }
293
294   if (theMode == PartSet_OperationSketchBase::FM_Activation ||
295       theMode == PartSet_OperationSketchBase::FM_Deactivation)
296     activateFeature(theFeature, true);
297 }
298
299 ModuleBase_Operation* PartSet_Module::createOperation(const std::string& theCmdId)
300 {
301   // get operation xml description
302   std::string aStdCmdId = theCmdId;
303   if (aStdCmdId == PartSet_OperationEditLine::Type())
304     aStdCmdId = PartSet_OperationSketchLine::Type();
305   std::string aPluginFileName = featureFile(aStdCmdId);
306   Config_WidgetReader aWdgReader = Config_WidgetReader(aPluginFileName);
307   aWdgReader.readAll();
308   std::string aXmlCfg = aWdgReader.featureWidgetCfg(aStdCmdId);
309   std::string aDescription = aWdgReader.featureDescription(aStdCmdId);
310
311   // create the operation
312   ModuleBase_Operation* anOperation;
313   if (theCmdId == PartSet_OperationSketch::Type()) {
314     anOperation = new PartSet_OperationSketch(theCmdId.c_str(), this);
315   }
316   else if(theCmdId == PartSet_OperationSketchLine::Type() ||
317           theCmdId == PartSet_OperationEditLine::Type()) {
318     ModuleBase_Operation* aCurOperation = myWorkshop->operationMgr()->currentOperation();
319     boost::shared_ptr<ModelAPI_Feature> aSketch;
320     PartSet_OperationSketchBase* aPrevOp = dynamic_cast<PartSet_OperationSketchBase*>(aCurOperation);
321     if (aPrevOp)
322       aSketch = aPrevOp->sketch();
323     if (theCmdId == PartSet_OperationSketchLine::Type())
324       anOperation = new PartSet_OperationSketchLine(theCmdId.c_str(), this, aSketch);
325     else
326       anOperation = new PartSet_OperationEditLine(theCmdId.c_str(), this, aSketch);
327   }
328   else {
329     anOperation = new ModuleBase_Operation(theCmdId.c_str(), this);
330   }
331   anOperation->getDescription()->setXmlRepresentation(QString::fromStdString(aXmlCfg));
332   anOperation->getDescription()->setDescription(QString::fromStdString(aDescription));
333
334   // connect the operation
335   PartSet_OperationSketchBase* aPreviewOp = dynamic_cast<PartSet_OperationSketchBase*>(anOperation);
336   if (aPreviewOp) {
337     connect(aPreviewOp, SIGNAL(featureConstructed(boost::shared_ptr<ModelAPI_Feature>, int)),
338             this, SLOT(onFeatureConstructed(boost::shared_ptr<ModelAPI_Feature>, int)));
339     connect(aPreviewOp, SIGNAL(launchOperation(std::string, boost::shared_ptr<ModelAPI_Feature>)),
340             this, SLOT(onLaunchOperation(std::string, boost::shared_ptr<ModelAPI_Feature>)));
341     connect(aPreviewOp, SIGNAL(multiSelectionEnabled(bool)),
342             this, SLOT(onMultiSelectionEnabled(bool)));
343
344     connect(aPreviewOp, SIGNAL(multiSelectionEnabled(bool)),
345             this, SLOT(onMultiSelectionEnabled(bool)));
346     connect(aPreviewOp, SIGNAL(stopSelection(const std::list<XGUI_ViewerPrs>&, const bool)),
347             this, SLOT(onStopSelection(const std::list<XGUI_ViewerPrs>&, const bool)));
348     connect(aPreviewOp, SIGNAL(setSelection(const std::list<XGUI_ViewerPrs>&)),
349             this, SLOT(onSetSelection(const std::list<XGUI_ViewerPrs>&)));
350
351      connect(aPreviewOp, SIGNAL(closeLocalContext()),
352              this, SLOT(onCloseLocalContext()));
353
354     PartSet_OperationSketch* aSketchOp = dynamic_cast<PartSet_OperationSketch*>(aPreviewOp);
355     if (aSketchOp) {
356       connect(aSketchOp, SIGNAL(planeSelected(double, double, double)),
357               this, SLOT(onPlaneSelected(double, double, double)));
358     }
359   }
360
361   return anOperation;
362 }
363
364 void PartSet_Module::sendOperation(ModuleBase_Operation* theOperation)
365 {
366   //TODO(sbh): Implement static method to extract event id [SEID]
367   static Events_ID aModuleEvent = Events_Loop::eventByName("PartSetModuleEvent");
368   Config_PointerMessage aMessage(aModuleEvent, this);
369   aMessage.setPointer(theOperation);
370   Events_Loop::loop()->send(aMessage);
371 }
372
373 void PartSet_Module::visualizePreview(boost::shared_ptr<ModelAPI_Feature> theFeature, bool isDisplay,
374                                       const bool isUpdateViewer)
375 {
376   ModuleBase_Operation* anOperation = myWorkshop->operationMgr()->currentOperation();
377   if (!anOperation)
378     return;
379
380   PartSet_OperationSketchBase* aPreviewOp = dynamic_cast<PartSet_OperationSketchBase*>(anOperation);
381   if (!aPreviewOp)
382     return;
383
384   XGUI_Displayer* aDisplayer = myWorkshop->displayer();
385   if (isDisplay) {
386     boost::shared_ptr<GeomAPI_Shape> aPreview = aPreviewOp->preview(theFeature);
387     aDisplayer->Redisplay(theFeature,
388                           aPreview ? aPreview->impl<TopoDS_Shape>() : TopoDS_Shape(), false);
389   }
390   else
391     aDisplayer->Erase(theFeature, false);
392
393   if (isUpdateViewer)
394     aDisplayer->UpdateViewer();
395 }
396
397 void PartSet_Module::activateFeature(boost::shared_ptr<ModelAPI_Feature> theFeature,
398                                      const bool isUpdateViewer)
399 {
400   ModuleBase_Operation* anOperation = myWorkshop->operationMgr()->currentOperation();
401   PartSet_OperationSketchBase* aPreviewOp = dynamic_cast<PartSet_OperationSketchBase*>(anOperation);
402   if (aPreviewOp) {
403     XGUI_Displayer* aDisplayer = myWorkshop->displayer();
404     aDisplayer->ActivateInLocalContext(theFeature, aPreviewOp->getSelectionModes(theFeature),
405                                        isUpdateViewer);
406   }
407 }
408
409 void PartSet_Module::updateCurrentPreview(const std::string& theCmdId)
410 {
411   ModuleBase_Operation* anOperation = myWorkshop->operationMgr()->currentOperation();
412   if (!anOperation)
413     return;
414
415   PartSet_OperationSketchBase* aPreviewOp = dynamic_cast<PartSet_OperationSketchBase*>(anOperation);
416   if (!aPreviewOp)
417     return;
418
419   boost::shared_ptr<ModelAPI_Feature> aFeature = aPreviewOp->feature();
420   if (!aFeature || aFeature->getKind() != theCmdId)
421     return;
422
423   std::map<boost::shared_ptr<ModelAPI_Feature>, boost::shared_ptr<GeomAPI_Shape> >
424                                                                      aList = aPreviewOp->subPreview();
425   XGUI_Displayer* aDisplayer = myWorkshop->displayer();
426   std::list<int> aModes = aPreviewOp->getSelectionModes(aPreviewOp->feature());
427
428   std::map<boost::shared_ptr<ModelAPI_Feature>, boost::shared_ptr<GeomAPI_Shape> >::const_iterator
429                                                          anIt = aList.begin(), aLast = aList.end();
430   for (; anIt != aLast; anIt++) {
431     boost::shared_ptr<ModelAPI_Feature> aFeature = (*anIt).first;
432     boost::shared_ptr<GeomAPI_Shape> aPreview = (*anIt).second;
433     aDisplayer->Redisplay(aFeature,
434                           aPreview ? aPreview->impl<TopoDS_Shape>() : TopoDS_Shape(), false);
435     aDisplayer->ActivateInLocalContext(aFeature, aModes, false);
436   }
437   aDisplayer->UpdateViewer();
438 }
439
440 void PartSet_Module::editFeature(FeaturePtr theFeature)
441 {
442   if (!theFeature)
443     return;
444
445   if (theFeature->getKind() == "Sketch") {
446     FeaturePtr aFeature = theFeature;
447     if (XGUI_Tools::isModelObject(aFeature)) {
448       ObjectPtr aObject = boost::dynamic_pointer_cast<ModelAPI_Object>(aFeature);
449       aFeature = aObject->featureRef();
450     }
451
452     if (aFeature) {
453       onLaunchOperation(aFeature->getKind(), aFeature);
454       updateCurrentPreview(aFeature->getKind());
455     }
456   }
457 }