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