]> SALOME platform Git repositories - modules/shaper.git/blob - src/XGUI/XGUI_WorkshopListener.cpp
Salome HOME
Send information message for translation
[modules/shaper.git] / src / XGUI / XGUI_WorkshopListener.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
2
3 #include "XGUI_WorkshopListener.h"
4 #include "XGUI_Workshop.h"
5 #include "XGUI_Displayer.h"
6 #include "XGUI_ErrorMgr.h"
7 #include "XGUI_OperationMgr.h"
8 #include "XGUI_SalomeConnector.h"
9 #include "XGUI_ActionsMgr.h"
10 #include "XGUI_PropertyPanel.h"
11 #include "XGUI_ModuleConnector.h"
12 #include "XGUI_QtEvents.h"
13
14 #ifndef HAVE_SALOME
15 #include <AppElements_MainWindow.h>
16 #endif
17
18 #include <ModuleBase_IModule.h>
19
20 #include <ModelAPI_Object.h>
21 #include <ModelAPI_Events.h>
22 #include <ModelAPI_Session.h>
23 #include <ModelAPI_Result.h>
24 #include <ModelAPI_Feature.h>
25 #include <ModelAPI_Data.h>
26 #include <ModelAPI_ResultBody.h>
27 #include <ModelAPI_ResultGroup.h>
28 #include <ModelAPI_ResultCompSolid.h>
29 #include <ModelAPI_Tools.h>
30
31 #include <Events_Loop.h>
32 #include <Events_Error.h>
33 #include <Events_LongOp.h>
34
35 #include <ModuleBase_IWorkshop.h>
36
37 #include <ModuleBase_Operation.h>
38 #include <ModuleBase_OperationDescription.h>
39 #include <ModuleBase_OperationFeature.h>
40 #include <ModuleBase_Tools.h>
41 #include <ModuleBase_IViewer.h>
42 #include <ModuleBase_FilterFactory.h>
43
44 #include <Config_FeatureMessage.h>
45 #include <Config_PointerMessage.h>
46 #include <Config_SelectionFilterMessage.h>
47 #include <Config_Keywords.h>
48 #include <Events_InfoMessage.h>
49
50 #include <QApplication>
51 #include <QMainWindow>
52 #include <QThread>
53 #include <QAction>
54
55 #ifdef _DEBUG
56 #include <QDebug>
57 #include <iostream>
58 #endif
59
60 //#define DEBUG_FEATURE_CREATED
61 //#define DEBUG_FEATURE_REDISPLAY
62 //#define DEBUG_FEATURE_UPDATED
63 //#define DEBUG_RESULT_COMPSOLID
64
65 #ifdef DEBUG_FEATURE_REDISPLAY
66 const std::string DebugFeatureKind = "";//"Extrusion";
67 #endif
68
69 XGUI_WorkshopListener::XGUI_WorkshopListener(ModuleBase_IWorkshop* theWorkshop)
70   : myWorkshop(theWorkshop),
71     myUpdatePrefs(false)
72 {
73   XGUI_OperationMgr* anOperationMgr = workshop()->operationMgr();
74 }
75
76 //******************************************************
77 XGUI_WorkshopListener::~XGUI_WorkshopListener(void)
78 {
79 }
80
81 //******************************************************
82 void XGUI_WorkshopListener::initializeEventListening()
83 {
84   //Initialize event listening
85   Events_Loop* aLoop = Events_Loop::loop();
86   //aLoop->registerListener(this, Events_Error::errorID());  //!< Listening application errors.
87   aLoop->registerListener(this, Events_InfoMessage::errorID());  //!< Listening application errors.
88   aLoop->registerListener(this, Events_Loop::eventByName(EVENT_OPERATION_LAUNCHED));
89   aLoop->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
90   aLoop->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_CREATED));
91   aLoop->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
92   aLoop->registerListener(this, Events_LongOp::eventID());
93   aLoop->registerListener(this, Events_Loop::eventByName(EVENT_PLUGIN_LOADED));
94   aLoop->registerListener(this, Events_Loop::eventByName(EVENT_SELFILTER_LOADED));
95
96   aLoop->registerListener(this, Events_Loop::eventByName(EVENT_UPDATE_VIEWER_BLOCKED));
97   aLoop->registerListener(this, Events_Loop::eventByName(EVENT_UPDATE_VIEWER_UNBLOCKED));
98   aLoop->registerListener(this, Events_Loop::eventByName(EVENT_EMPTY_AIS_PRESENTATION));
99 }
100
101 //******************************************************
102 void XGUI_WorkshopListener::processEvent(const std::shared_ptr<Events_Message>& theMessage)
103 {
104   if (QApplication::instance()->thread() != QThread::currentThread()) {
105     #ifdef _DEBUG
106     std::cout << "XGUI_Workshop::processEvent: " << "Working in another thread." << std::endl;
107     #endif
108     SessionPtr aMgr = ModelAPI_Session::get();
109     PostponeMessageQtEvent* aPostponeEvent = new PostponeMessageQtEvent(theMessage);
110     QApplication::postEvent(this, aPostponeEvent);
111     return;
112   }
113
114   // Process creation of Part
115   if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_CREATED)) {
116     std::shared_ptr<ModelAPI_ObjectUpdatedMessage> aUpdMsg =
117         std::dynamic_pointer_cast<ModelAPI_ObjectUpdatedMessage>(theMessage);
118     onFeatureCreatedMsg(aUpdMsg);
119     if (myUpdatePrefs) {
120       XGUI_SalomeConnector* aSalomeConnector = workshop()->salomeConnector();
121       if (aSalomeConnector)
122         aSalomeConnector->createPreferences();
123       myUpdatePrefs = false;
124     }
125   }
126   else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_PLUGIN_LOADED)) {
127     myUpdatePrefs = true;
128   }
129   // Redisplay feature
130   else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY)) {
131     std::shared_ptr<ModelAPI_ObjectUpdatedMessage> aUpdMsg =
132         std::dynamic_pointer_cast<ModelAPI_ObjectUpdatedMessage>(theMessage);
133     onFeatureRedisplayMsg(aUpdMsg);
134   } else if (theMessage->eventID() == Events_Loop::eventByName(EVENT_EMPTY_AIS_PRESENTATION)) {
135     std::shared_ptr<ModelAPI_ObjectUpdatedMessage> aUpdMsg =
136         std::dynamic_pointer_cast<ModelAPI_ObjectUpdatedMessage>(theMessage);
137     onFeatureEmptyPresentationMsg(aUpdMsg);
138   }
139   //Update property panel on corresponding message. If there is no current operation (no
140   //property panel), or received message has different feature to the current - do nothing.
141   else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_UPDATED)) {
142     std::shared_ptr<ModelAPI_ObjectUpdatedMessage> anUpdateMsg =
143         std::dynamic_pointer_cast<ModelAPI_ObjectUpdatedMessage>(theMessage);
144     onFeatureUpdatedMsg(anUpdateMsg);
145   } else if (theMessage->eventID() == Events_LongOp::eventID()) {
146     if (Events_LongOp::isPerformed()) {
147       QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
148     } else {
149       QApplication::restoreOverrideCursor();
150     }
151   }
152   //An operation passed by message. Start it, process and commit.
153   else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OPERATION_LAUNCHED)) {
154     std::shared_ptr<Config_PointerMessage> aPartSetMsg =
155         std::dynamic_pointer_cast<Config_PointerMessage>(theMessage);
156     //myPropertyPanel->cleanContent();
157     ModuleBase_Operation* anOperation = (ModuleBase_Operation*) aPartSetMsg->pointer();
158     XGUI_OperationMgr* anOperationMgr = workshop()->operationMgr();
159
160     if (anOperationMgr->startOperation(anOperation)) {
161       ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>(anOperation);
162       if (aFOperation) {
163         workshop()->propertyPanel()->updateContentWidget(aFOperation->feature());
164         workshop()->propertyPanel()->createContentPanel(aFOperation->feature());
165       }
166       if (!anOperation->getDescription()->hasXmlRepresentation()) {
167         if (anOperation->commit())
168           workshop()->updateCommandStatus();
169       }
170     }
171   } 
172   else if (theMessage->eventID() == Events_Loop::eventByName(EVENT_SELFILTER_LOADED)) {
173     std::shared_ptr<Config_SelectionFilterMessage> aMsg = 
174       std::dynamic_pointer_cast<Config_SelectionFilterMessage>(theMessage);
175     if (aMsg) {
176       ModuleBase_FilterFactory* aFactory = myWorkshop->selectionFilters();
177       if (!aMsg->attributeId().empty()) {
178         aFactory->assignFilter(aMsg->selectionFilterId(), aMsg->featureId(), aMsg->attributeId(),
179                                aMsg->parameters());
180       }
181     }
182   } else if (theMessage->eventID() == Events_Loop::eventByName(EVENT_UPDATE_VIEWER_BLOCKED)) {
183     // the viewer's update context will not happens until viewer updated is emitted
184       workshop()->displayer()->enableUpdateViewer(false);
185   } else if (theMessage->eventID() == Events_Loop::eventByName(EVENT_UPDATE_VIEWER_UNBLOCKED)) {
186     // the viewer's update context is unblocked, the viewer's update works
187     XGUI_Displayer* aDisplayer = workshop()->displayer();
188     aDisplayer->enableUpdateViewer(true);
189   } else {
190     //Show error dialog if error message received.
191     std::shared_ptr<Events_InfoMessage> anIngfoMsg = std::dynamic_pointer_cast<Events_InfoMessage>(theMessage);
192     if (anIngfoMsg) {
193       emit errorOccurred(anIngfoMsg);
194     }
195     return;
196   }
197 #ifndef HAVE_SALOME
198     SessionPtr aMgr = ModelAPI_Session::get();
199     AppElements_MainWindow* aMainWindow = workshop()->mainWindow();
200     if (aMgr->isModified() != aMainWindow->isModifiedState())
201       aMainWindow->setModifiedState(aMgr->isModified());
202 #endif
203 }
204
205 //******************************************************
206 void XGUI_WorkshopListener::onFeatureUpdatedMsg(
207                                      const std::shared_ptr<ModelAPI_ObjectUpdatedMessage>& theMsg)
208 {
209 #ifdef DEBUG_FEATURE_UPDATED
210   std::set<ObjectPtr> anObjects = theMsg->objects();
211   std::set<ObjectPtr>::const_iterator aIt;
212   QStringList anInfo;
213   for (aIt = anObjects.begin(); aIt != anObjects.end(); ++aIt) {
214     anInfo.append(ModuleBase_Tools::objectInfo((*aIt)));
215   }
216   QString anInfoStr = anInfo.join(";\t");
217   qDebug(QString("onFeatureUpdatedMsg: %1, %2").arg(anObjects.size()).arg(anInfoStr).toStdString().c_str());
218 #endif
219   std::set<ObjectPtr> aFeatures = theMsg->objects();
220   XGUI_OperationMgr* anOperationMgr = workshop()->operationMgr();
221   if (anOperationMgr->hasOperation()) {
222     ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
223                                                       (anOperationMgr->currentOperation());
224     if (aFOperation) {
225       FeaturePtr aCurrentFeature = aFOperation->feature();
226       std::set<ObjectPtr>::const_iterator aIt;
227       for (aIt = aFeatures.begin(); aIt != aFeatures.end(); ++aIt) {
228         ObjectPtr aNewFeature = (*aIt);
229         if (aNewFeature == aCurrentFeature) {
230           workshop()->propertyPanel()->updateContentWidget(aCurrentFeature);
231           break;
232         }
233       }
234     }
235   }
236   //anOperationMgr->onValidateOperation();
237
238   //if (myObjectBrowser)
239   //  myObjectBrowser->processEvent(theMsg);
240 }
241
242 //******************************************************
243 void XGUI_WorkshopListener::onFeatureRedisplayMsg(const std::shared_ptr<ModelAPI_ObjectUpdatedMessage>& theMsg)
244 {
245   std::set<ObjectPtr> anObjects = theMsg->objects();
246   std::set<ObjectPtr>::const_iterator aIt;
247
248 #ifdef DEBUG_FEATURE_REDISPLAY
249   QStringList anInfo;
250   for (aIt = anObjects.begin(); aIt != anObjects.end(); ++aIt) {
251     anInfo.append(ModuleBase_Tools::objectInfo((*aIt)));
252   }
253   QString anInfoStr = anInfo.join(";\t");
254   qDebug(QString("onFeatureRedisplayMsg: %1, %2").arg(anObjects.size()).arg(anInfoStr).toStdString().c_str());
255 #endif
256
257   XGUI_Workshop* aWorkshop = workshop();
258   XGUI_Displayer* aDisplayer = aWorkshop->displayer();
259   bool aFirstVisualizedBody = false;
260
261   bool aRedisplayed = false;
262   //std::list<ObjectPtr> aHiddenObjects;
263   for (aIt = anObjects.begin(); aIt != anObjects.end(); ++aIt) {
264     ObjectPtr aObj = (*aIt);
265
266     // Hide the object if it is invalid or concealed one
267     bool aHide = !aObj->data() || !aObj->data()->isValid() || 
268       aObj->isDisabled() || (!aObj->isDisplayed());
269     if (!aHide) { // check that this is not hidden result
270       ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(aObj);
271       aHide = aRes && aRes->isConcealed();
272
273       // Hide the presentation with an empty shape. But isDisplayed state of the object should not
274       // be changed to the object becomes visible when the shape becomes not empty
275       if (!aHide && aRes.get())
276         aHide = !aRes->shape().get() || aRes->shape()->isNull();
277     }
278
279 #ifdef DEBUG_RESULT_COMPSOLID
280     ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(aObj);
281     if (aRes.get()) {
282       ResultCompSolidPtr aCompSolidRes = std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(aRes);
283       if (aCompSolidRes.get()) {
284           qDebug(QString("COMPSOLID, numberOfSubs = %1").arg(aCompSolidRes->numberOfSubs()).toStdString().c_str());
285       }
286       if (ModelAPI_Tools::compSolidOwner(aRes))
287         qDebug("COMPSOLID sub-object");
288     }
289 #endif
290     #ifdef DEBUG_FEATURE_REDISPLAY
291       QString anObjInfo = ModuleBase_Tools::objectInfo((aObj));
292       FeaturePtr aFeature = ModelAPI_Feature::feature(aObj);
293       if (aFeature.get()) {
294         std::string aKind = aFeature->getKind();
295         if (aKind == DebugFeatureKind || DebugFeatureKind.empty()) {
296           qDebug(QString("visible=%1, hide=%2 : display= %2").arg(aDisplayer->isVisible(aObj))
297                                             .arg(aHide).arg(anObjInfo).toStdString().c_str());
298         }
299       }
300     #endif
301     if (aHide) {
302       //we should provide objects which are hidden in the viewer, e.g. sketch always should visualizes
303       // all sub-features, if some features are to be hidden, sould be proposed may be to removed #1223
304       //aHiddenObjects.push_back(aObj);
305       aRedisplayed = aDisplayer->erase(aObj, false) || aRedisplayed;
306       #ifdef DEBUG_FEATURE_REDISPLAY
307         // Redisplay the visible object or the object of the current operation
308         bool isVisibleObject = aDisplayer->isVisible(aObj);
309
310         QString anObjInfo = ModuleBase_Tools::objectInfo((aObj));
311         //qDebug(QString("visible=%1 : erase  = %2").arg(isVisibleObject).arg(anObjInfo).toStdString().c_str());
312       #endif
313     }
314     else {
315       // Redisplay the visible object or the object of the current operation
316       bool isVisibleObject = aDisplayer->isVisible(aObj);
317       #ifdef DEBUG_FEATURE_REDISPLAY
318         QString anObjInfo = ModuleBase_Tools::objectInfo((aObj));
319         //qDebug(QString("visible=%1 : display= %2").arg(isVisibleObject).arg(anObjInfo).toStdString().c_str());
320       #endif
321
322       if (isVisibleObject)  { // redisplay visible object
323         //displayObject(aObj);  // In order to update presentation
324         // in order to avoid the check whether the object can be redisplayed, the exact method
325         // of redisplay is called. This modification is made in order to have the line is updated
326         // by creation of a horizontal constraint on the line by preselection
327         if (ModelAPI_Tools::hasSubResults(std::dynamic_pointer_cast<ModelAPI_Result>(aObj))) {
328           aRedisplayed = aDisplayer->erase(aObj, false) || aRedisplayed;
329         }
330         else {
331           aRedisplayed = aDisplayer->redisplay(aObj, false) || aRedisplayed;
332           // Deactivate object of current operation from selection
333           aWorkshop->deactivateActiveObject(aObj, false);
334         }
335       } else { // display object if the current operation has it
336         if (displayObject(aObj, aFirstVisualizedBody)) {
337           aRedisplayed = true;
338           // Deactivate object of current operation from selection
339           aWorkshop->deactivateActiveObject(aObj, false);
340         }
341       }
342     }
343   }
344   // this processing should be moved in another place in order to do not cause problems in
345   // flush messages chain
346   //if (aHiddenObjects.size() > 0)
347   //  myWorkshop->module()->processHiddenObject(aHiddenObjects);
348
349   bool isCustomized = customizeCurrentObject(anObjects, aRedisplayed);
350   if (aRedisplayed || isCustomized) {
351     Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_EMPTY_AIS_PRESENTATION));
352
353     //VSV FitAll updated viewer by it self
354     if (aFirstVisualizedBody)
355       myWorkshop->viewer()->fitAll();
356     else 
357       aDisplayer->updateViewer();
358   }
359 }
360
361 //******************************************************
362 void XGUI_WorkshopListener::onFeatureCreatedMsg(const std::shared_ptr<ModelAPI_ObjectUpdatedMessage>& theMsg)
363 {
364   std::set<ObjectPtr> anObjects = theMsg->objects();
365   std::set<ObjectPtr>::const_iterator aIt;
366 #ifdef DEBUG_FEATURE_CREATED
367   QStringList anInfo;
368   for (aIt = anObjects.begin(); aIt != anObjects.end(); ++aIt) {
369     anInfo.append(ModuleBase_Tools::objectInfo((*aIt)));
370   }
371   QString anInfoStr = anInfo.join(";\t");
372   qDebug(QString("onFeatureCreatedMsg: %1, %2").arg(anObjects.size()).arg(anInfoStr).toStdString().c_str());
373 #endif
374
375   bool aFirstVisualizedBody = false;
376
377   //bool aHasPart = false;
378   bool aDisplayed = false;
379   for (aIt = anObjects.begin(); aIt != anObjects.end(); ++aIt) {
380     ObjectPtr anObject = *aIt;
381
382 #ifdef DEBUG_RESULT_COMPSOLID
383     ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(anObject);
384     if (aRes.get()) {
385       ResultCompSolidPtr aCompSolidRes = std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(aRes);
386       if (aCompSolidRes.get()) {
387           qDebug(QString("COMPSOLID, numberOfSubs = %1").arg(aCompSolidRes->numberOfSubs()).toStdString().c_str());
388       }
389       if (ModelAPI_Tools::compSolidOwner(aRes))
390         qDebug("COMPSOLID sub-object");
391     }
392 #endif
393     // the validity of the data should be checked here in order to avoid display of the objects,
394     // which were created, then deleted, but flush for the creation event happens after that
395     // we should not display disabled objects
396     bool aHide = !anObject->data()->isValid() || 
397                  anObject->isDisabled() ||
398                  !anObject->isDisplayed();
399     if (!aHide) { // check that this is not hidden result
400       ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(anObject);
401       bool isConcealed = aRes && aRes->isConcealed();
402       aHide = aRes && aRes->isConcealed();
403       // Hide the presentation with an empty shape. But isDisplayed state of the object should not
404       // be changed to the object becomes visible when the shape becomes not empty
405       if (!aHide && aRes.get())
406         aHide = !aRes->shape().get() || aRes->shape()->isNull();
407     }
408     if (!aHide) {
409       // setDisplayed has to be called in order to synchronize internal state of the object 
410       // with list of displayed objects
411       if (myWorkshop->module()->canDisplayObject(anObject)) {
412         anObject->setDisplayed(true);
413         aDisplayed = displayObject(*aIt, aFirstVisualizedBody);
414       } else 
415         anObject->setDisplayed(false);
416     }
417   }
418
419   bool isCustomized = customizeCurrentObject(anObjects, aDisplayed);
420
421   //if (myObjectBrowser)
422   //  myObjectBrowser->processEvent(theMsg);
423   if (aDisplayed) {
424     Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_EMPTY_AIS_PRESENTATION));
425     //VSV FitAll updated viewer by it self
426     if (aFirstVisualizedBody)
427       myWorkshop->viewer()->fitAll();
428     else
429       workshop()->displayer()->updateViewer();
430   }
431   //if (aHasPart) { // TODO: Avoid activate last part on loading of document
432   //  activateLastPart();
433   //}
434 }
435
436 //******************************************************
437 void XGUI_WorkshopListener::onFeatureEmptyPresentationMsg(
438                                       const std::shared_ptr<ModelAPI_ObjectUpdatedMessage>& theMsg)
439 {
440   std::set<ObjectPtr> anObjects = theMsg->objects();
441   std::set<ObjectPtr>::const_iterator aIt;
442 #ifdef DEBUG_FEATURE_CREATED
443   QStringList anInfo;
444   for (aIt = anObjects.begin(); aIt != anObjects.end(); ++aIt) {
445     anInfo.append(ModuleBase_Tools::objectInfo((*aIt)));
446   }
447   QString anInfoStr = anInfo.join(";\t");
448   qDebug(QString("onFeatureEmptyPresentationMsg: %1, %2").arg(anObjects.size()).arg(anInfoStr).toStdString().c_str());
449 #endif
450
451   XGUI_Workshop* aWorkshop = workshop();
452   XGUI_Displayer* aDisplayer = aWorkshop->displayer();
453
454   bool aRedisplayed = false;
455   for (aIt = anObjects.begin(); aIt != anObjects.end(); ++aIt) {
456     ObjectPtr anObject = *aIt;
457     aRedisplayed = aDisplayer->erase(anObject, false) || aRedisplayed;
458   }
459
460   if (aRedisplayed)
461     aDisplayer->updateViewer();
462 }
463
464 bool XGUI_WorkshopListener::event(QEvent * theEvent)
465 {
466   PostponeMessageQtEvent* aPostponedEv = dynamic_cast<PostponeMessageQtEvent*>(theEvent);
467   if (aPostponedEv) {
468     std::shared_ptr<Events_Message> aEventPtr = aPostponedEv->postponedMessage();
469     processEvent(aEventPtr);
470     return true;
471   }
472   return false;
473 }
474
475 //**************************************************************
476 bool XGUI_WorkshopListener::displayObject(ObjectPtr theObj, bool& theFirstVisualizedBody)
477 {
478 #ifdef DEBUG_RESULT_COMPSOLID
479   ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(theObj);
480   if (aRes.get() && (ModelAPI_Tools::hasSubResults(aRes) || ModelAPI_Tools::compSolidOwner(aRes))) {
481     ResultCompSolidPtr aCompSolidRes = std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(aRes);
482     if (aCompSolidRes.get()) {
483       qDebug("COMPSOLID: displayObject");
484     }
485   }
486 #endif
487
488   bool aDisplayed = false;
489   XGUI_Workshop* aWorkshop = workshop();
490   // do not display the object if it has sub objects. They should be displayed separately.
491   if (!aWorkshop->module()->canDisplayObject(theObj) ||
492       ModelAPI_Tools::hasSubResults(std::dynamic_pointer_cast<ModelAPI_Result>(theObj)))
493     return aDisplayed;
494
495   XGUI_Displayer* aDisplayer = aWorkshop->displayer();
496   int aNb = aDisplayer->objectsCount();
497   aDisplayed = aDisplayer->display(theObj, false);
498
499   ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theObj);
500   if (aNb == 0 && aResult.get()) {
501     std::string aResultGroupName = aResult->groupName();
502     if (aResultGroupName == ModelAPI_ResultBody::group() ||
503         aResultGroupName == ModelAPI_ResultGroup::group()) {
504       std::shared_ptr<GeomAPI_Shape> aShapePtr = ModelAPI_Tools::shape(aResult);
505       theFirstVisualizedBody = aShapePtr.get() != NULL;
506     }
507   }
508   return aDisplayed;
509 }
510
511 bool XGUI_WorkshopListener::customizeCurrentObject(const std::set<ObjectPtr>& theObjects,
512                                                    bool theForceRedisplay)
513 {
514   XGUI_OperationMgr* anOperationMgr = workshop()->operationMgr();
515   FeaturePtr aCurrentFeature;
516   if (anOperationMgr->hasOperation()) {
517     ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
518                                                       (anOperationMgr->currentOperation());
519     if (aFOperation) {
520       aCurrentFeature = aFOperation->feature();
521     }
522   }
523
524   bool aCustomized = false;
525   if (aCurrentFeature.get()) {
526     // the customize presentation should be redisplayed if force redislayed is true or
527     // if a list of message objects contains the operation feature for case when
528     // the feature is hidden, but arguments of the feature are modified
529     // e.g. extrusion is hidden(h=0) but sketch is chosen
530     if (theForceRedisplay || theObjects.find(aCurrentFeature) != theObjects.end()) {
531       aCustomized = myWorkshop->module()->customizeObject(aCurrentFeature,
532                                  ModuleBase_IModule::CustomizeArguments, false) || aCustomized;
533       aCustomized = myWorkshop->module()->customizeObject(aCurrentFeature,
534                                    ModuleBase_IModule::CustomizeResults, false) || aCustomized;
535       aCustomized = myWorkshop->module()->customizeObject(aCurrentFeature,
536                         ModuleBase_IModule::CustomizeHighlightedObjects, false) || aCustomized;
537     }
538   }
539   return aCustomized;
540 }
541
542 XGUI_Workshop* XGUI_WorkshopListener::workshop() const
543 {
544   XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(myWorkshop);
545   return aConnector->workshop();
546 }