Salome HOME
Issue #1834: Fix length of lines
[modules/shaper.git] / src / SHAPERGUI / SHAPERGUI.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
2
3
4 #include "SHAPERGUI.h"
5 #include "SHAPERGUI_DataModel.h"
6 #include "SHAPERGUI_OCCSelector.h"
7 #include <SHAPERGUI_NestedButton.h>
8
9 #include <XGUI_Workshop.h>
10 #include <XGUI_PropertyPanel.h>
11 #include <XGUI_ContextMenuMgr.h>
12 #include <XGUI_ObjectsBrowser.h>
13 #include <XGUI_OperationMgr.h>
14 #include <XGUI_Displayer.h>
15 #include <XGUI_MenuMgr.h>
16
17 #include <ModuleBase_Operation.h>
18 #include <ModuleBase_Preferences.h>
19 #include <ModuleBase_ActionInfo.h>
20 #include <ModuleBase_IModule.h>
21
22 #include <LightApp_Application.h>
23 #include <LightApp_SelectionMgr.h>
24 #include <LightApp_OCCSelector.h>
25 #include <LightApp_Study.h>
26 #include <OCCViewer_ViewModel.h>
27
28 #include <SUIT_Selector.h>
29 #include <SUIT_Desktop.h>
30 #include <SUIT_ViewManager.h>
31 #include <SUIT_ResourceMgr.h>
32
33 #include <QtxPopupMgr.h>
34 #include <QtxActionMenuMgr.h>
35 #include <QtxActionToolMgr.h>
36 #include <QtxResourceMgr.h>
37
38 #include <Config_PropManager.h>
39 #include <Config_ModuleReader.h>
40
41 #include <AIS_ListOfInteractive.hxx>
42 #include <AIS_ListIteratorOfListOfInteractive.hxx>
43
44 #include <QDockWidget>
45 #include <QAction>
46 #include <QTimer>
47 #include <QMenu>
48
49
50 extern "C" {
51 SHAPERGUI_EXPORT CAM_Module* createModule()
52 {
53   return new SHAPERGUI();
54 }
55
56 SHAPERGUI_EXPORT char* getModuleVersion()
57 {
58   return (char*)"0.0";
59 }
60 } // extern "C"
61
62 /** 
63 * Class for preferences management
64 */
65 class SHAPERGUI_PrefMgr: public ModuleBase_IPrefMgr
66 {
67 public:
68   /// Constructor
69   /// \param theMgr preferences manager of SALOME
70   /// \param theModName name of the module
71   SHAPERGUI_PrefMgr(LightApp_Preferences* theMgr, const QString& theModName):
72     myMgr(theMgr), myModName(theModName) {}
73
74   virtual int addPreference(const QString& theLbl, int pId, 
75                             SUIT_PreferenceMgr::PrefItemType theType,
76                             const QString& theSection, const QString& theName )
77   {
78     return myMgr->addPreference(myModName, theLbl, pId, theType, theSection, theName);
79   }
80
81   virtual void setItemProperty(const QString& thePropName,
82                                const QVariant& theValue,
83                                const int theId = -1)
84   {
85     myMgr->setItemProperty(thePropName, theValue, theId);
86   }
87
88
89   virtual SUIT_PreferenceMgr* prefMgr() const { return myMgr; }
90
91 private:
92   LightApp_Preferences* myMgr;
93   QString myModName;
94 };
95
96
97
98
99 //******************************************************
100 SHAPERGUI::SHAPERGUI()
101     : LightApp_Module("SHAPER"),
102       mySelector(0), myIsOpened(0), myPopupMgr(0)
103 {
104   myWorkshop = new XGUI_Workshop(this);
105   connect(myWorkshop, SIGNAL(commandStatusUpdated()),
106           this, SLOT(onUpdateCommandStatus()));
107
108   myProxyViewer = new SHAPERGUI_SalomeViewer(this);
109
110   ModuleBase_Preferences::setResourceMgr(application()->resourceMgr());
111   ModuleBase_Preferences::loadCustomProps();
112 }
113
114 //******************************************************
115 SHAPERGUI::~SHAPERGUI()
116 {
117 }
118
119 //******************************************************
120 void SHAPERGUI::initialize(CAM_Application* theApp)
121 {
122   LightApp_Module::initialize(theApp);
123   inspectSalomeModules();
124
125   myWorkshop->startApplication();
126   LightApp_Application* anApp = dynamic_cast<LightApp_Application*>(theApp);
127   if (anApp)
128   {
129     connect(anApp, SIGNAL(preferenceResetToDefaults()), this, SLOT(onDefaultPreferences()));
130   }
131 }
132
133 //******************************************************
134 void SHAPERGUI::windows(QMap<int, int>& theWndMap) const
135 {
136   theWndMap.insert(LightApp_Application::WT_PyConsole, Qt::BottomDockWidgetArea);
137 }
138
139 //******************************************************
140 void SHAPERGUI::viewManagers(QStringList& theList) const
141 {
142   theList.append(OCCViewer_Viewer::Type());
143 }
144
145 //******************************************************
146 void SHAPERGUI::connectToStudy(CAM_Study* theStudy)
147 {
148   // if there are created viewer managers, we should try to create viewer
149   // selector and initialize viewer with it. It sets interactive contect to the 
150   // proxy viewer. If study is opened, CAM application calls this method before the open()
151   // of data model
152   // the SHAPER data model is specific and during open(load) redisplay signals are flushed, so
153   // we need to connect to the viewer before it. Here, it seems the most appropriate place for this
154   // according to SALOME architecture.
155   if (!mySelector) {
156     ViewManagerList OCCViewManagers;
157     application()->viewManagers(OCCViewer_Viewer::Type(), OCCViewManagers);
158     if (OCCViewManagers.size() > 0) {
159       mySelector = createSelector(OCCViewManagers.first());
160     }
161   }
162   LightApp_Module::connectToStudy(theStudy);
163 }
164
165 //******************************************************
166 bool SHAPERGUI::activateModule(SUIT_Study* theStudy)
167 {
168   bool isDone = LightApp_Module::activateModule(theStudy);
169   SHAPERGUI_DataModel* aDataModel = dynamic_cast<SHAPERGUI_DataModel*>(dataModel());
170   aDataModel->initRootObject();
171
172   if (isDone) {
173     setMenuShown(true);
174     setToolShown(true);
175
176     QObject* aObj = myWorkshop->objectBrowser()->parent();
177     QDockWidget* aObjDoc = dynamic_cast<QDockWidget*>(aObj);
178     if (aObjDoc) {
179       QAction* aViewAct = aObjDoc->toggleViewAction();
180       aViewAct->setEnabled(true);
181       myWorkshop->objectBrowser()->setVisible(true);
182       aObjDoc->setVisible(true);
183       desktop()->tabifyDockWidget(aObjDoc, myWorkshop->propertyPanel());
184     }
185
186     if (!mySelector) {
187       ViewManagerList OCCViewManagers;
188       application()->viewManagers(OCCViewer_Viewer::Type(), OCCViewManagers);
189       if (OCCViewManagers.size() > 0) {
190         mySelector = createSelector(OCCViewManagers.first());
191       }
192     }
193     // it should be pefromed after the selector creation in order to have AISContext 
194     myWorkshop->activateModule();
195     //action(myEraseAll)->setEnabled(false);
196
197     if (myIsOpened) {
198       myWorkshop->objectBrowser()->rebuildDataTree();
199       myWorkshop->updateCommandStatus();
200       myIsOpened = false;
201     }
202     else
203       myWorkshop->updateCommandStatus();
204   }
205   SUIT_ResourceMgr* aResMgr = application()->resourceMgr();
206   myIsStorePositions = aResMgr->booleanValue("Study", "store_positions", true);
207   myIsEditEnabled = getApp()->isEditEnabled();
208   getApp()->setEditEnabled(false);
209
210   // this following row is caused by #187 bug.
211   // SALOME saves the dock widget positions before deactivateModule() and
212   // load it after the module activation. So, if the panel is visible before
213   // deactivate, it becomes visible after activate.
214   // In order to avoid the visible property panel, the widget position save is
215   // switch off in this module
216   aResMgr->setValue("Study", "store_positions", false);
217
218   // Synchronize displayed objects
219   Handle(AIS_InteractiveContext) aContext;
220   if (mySelector && mySelector->viewer())
221     aContext = mySelector->viewer()->getAISContext();
222
223   if (!aContext.IsNull()) {
224     XGUI_Displayer* aDisp = myWorkshop->displayer();
225     QObjectPtrList aObjList = aDisp->displayedObjects();
226
227     AIS_ListOfInteractive aList;
228     aContext->DisplayedObjects(aList);
229     AIS_ListIteratorOfListOfInteractive aLIt;
230     Handle(AIS_InteractiveObject) anAISIO;
231     foreach (ObjectPtr aObj, aObjList) {
232       AISObjectPtr aPrs = aDisp->getAISObject(aObj);
233       Handle(AIS_InteractiveObject) aAIS = aPrs->impl<Handle(AIS_InteractiveObject)>();
234       bool aFound = false;
235       for (aLIt.Initialize(aList); aLIt.More(); aLIt.Next()) {
236         anAISIO = aLIt.Value();
237         if (anAISIO.Access() == aAIS.Access()) {
238           aFound = true;
239           break;
240         }
241       }
242       if (!aFound) {
243         aObj->setDisplayed(false);
244         //aDisp->erase(aObj, false);
245       }
246     }
247     Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
248   }
249   myProxyViewer->activateViewer(true);
250   return isDone;
251 }
252
253 //******************************************************
254 bool SHAPERGUI::deactivateModule(SUIT_Study* theStudy)
255 {
256   myProxyViewer->activateViewer(false);
257   setMenuShown(false);
258   setToolShown(false);
259
260   myWorkshop->deactivateModule();
261
262   QObject* aObj = myWorkshop->objectBrowser()->parent();
263   QDockWidget* aObjDoc = dynamic_cast<QDockWidget*>(aObj);
264   if (aObjDoc) {
265     aObjDoc->setVisible(false);
266     myWorkshop->objectBrowser()->setVisible(false);
267     QAction* aViewAct = aObjDoc->toggleViewAction();
268     aViewAct->setEnabled(false);
269   }
270
271   // the active operation should be stopped for the next activation.
272   // There should not be active operation and visualized preview.
273   // Abort operation should be performed before the selection's remove
274   // because the displayed objects should be removed from the viewer, but
275   // the AIS context is obtained from the selector.
276   ModuleBase_Operation* anOperation = myWorkshop->operationMgr()->currentOperation();
277   while (anOperation) {
278     anOperation->abort();
279     anOperation = myWorkshop->operationMgr()->currentOperation();
280   }
281   // Delete selector because it has to be redefined on next activation
282   if (mySelector) {
283     myProxyViewer->setSelector(0);
284     delete mySelector;
285     mySelector = 0;
286   }
287
288   //myWorkshop->contextMenuMgr()->disconnectViewer();
289
290   SUIT_ResourceMgr* aResMgr = application()->resourceMgr();
291   aResMgr->setValue("Study", "store_positions", myIsStorePositions);
292   getApp()->setEditEnabled(myIsEditEnabled);
293
294   return LightApp_Module::deactivateModule(theStudy);
295 }
296
297 //******************************************************
298 void SHAPERGUI::onViewManagerAdded(SUIT_ViewManager* theMgr)
299 {
300   if (!mySelector) {
301     mySelector = createSelector(theMgr);
302     myWorkshop->module()->activateSelectionFilters();
303     myWorkshop->synchronizeViewer();
304   }
305 }
306
307 //******************************************************
308 void SHAPERGUI::onViewManagerRemoved(SUIT_ViewManager* theMgr)
309 {
310   if (mySelector) {
311     if (theMgr->getType() == OCCViewer_Viewer::Type()) {
312       OCCViewer_Viewer* aViewer = static_cast<OCCViewer_Viewer*>(theMgr->getViewModel());
313       if (mySelector->viewer() == aViewer) {
314         XGUI_Displayer* aDisp = myWorkshop->displayer();
315         QObjectPtrList aObjects = aDisp->displayedObjects();
316         foreach(ObjectPtr aObj, aObjects)
317           aObj->setDisplayed(false);
318         Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
319         myProxyViewer->setSelector(0);
320         delete mySelector;
321         mySelector = 0;
322
323         myWorkshop->module()->clearViewer();
324       }
325     }
326   }
327 }
328
329 //******************************************************
330 QtxPopupMgr* SHAPERGUI::popupMgr()
331 {
332   if (!myPopupMgr)
333     myPopupMgr = new QtxPopupMgr( 0, this );
334   return myPopupMgr;
335 }
336
337 //******************************************************
338 void SHAPERGUI::onDefaultPreferences()
339 {
340   // reset main resources
341   ModuleBase_Preferences::resetResourcePreferences(preferences());
342   // reset plugin's resources
343   ModuleBase_Preferences::resetConfigPropPreferences(preferences());
344
345   myWorkshop->displayer()->redisplayObjects();
346 }
347
348 //******************************************************
349 void SHAPERGUI::onUpdateCommandStatus()
350 {
351   getApp()->updateActions();
352 }
353
354 //******************************************************
355 SHAPERGUI_OCCSelector* SHAPERGUI::createSelector(SUIT_ViewManager* theMgr)
356 {
357   if (theMgr->getType() == OCCViewer_Viewer::Type()) {
358     OCCViewer_Viewer* aViewer = static_cast<OCCViewer_Viewer*>(theMgr->getViewModel());
359     SHAPERGUI_OCCSelector* aSelector = new SHAPERGUI_OCCSelector(aViewer,
360                                                                  getApp()->selectionMgr());
361     LightApp_SelectionMgr* aMgr = getApp()->selectionMgr();
362     QList<SUIT_Selector*> aList;
363     aMgr->selectors(aList);
364     foreach(SUIT_Selector* aSel, aList)
365     {
366       aSel->setEnabled(aSel == aSelector);
367     }
368     myProxyViewer->setSelector(aSelector);
369     return aSelector;
370   }
371   return 0;
372 }
373
374 //******************************************************
375 CAM_DataModel* SHAPERGUI::createDataModel()
376 {
377   return new SHAPERGUI_DataModel(this);
378 }
379
380 QAction* SHAPERGUI::addFeature(const QString& theWBName, const ActionInfo& theInfo,
381                                const bool isAddSeparator)
382 {
383   return addFeature(theWBName,
384                     theInfo.id,
385                     theInfo.text,
386                     //Issue #650: in the SALOME mode the tooltip should be same as text
387                     theInfo.text, 
388                     theInfo.icon,
389                     theInfo.shortcut,
390                     theInfo.checkable,
391                     isAddSeparator,
392                     theInfo.toolTip);
393 }
394
395 //******************************************************
396 QAction* SHAPERGUI::addFeature(const QString& theWBName, const QString& theId,
397                                const QString& theTitle, const QString& theTip,
398                                const QIcon& theIcon, const QKeySequence& theKeys,
399                                bool isCheckable, const bool isAddSeparator,
400                                const QString& theStatusTip)
401 {
402   static QString aLastTool = "";
403   static int aNb = 0;
404   if (aLastTool.isEmpty())
405     aLastTool = theWBName;
406   else if (theWBName != aLastTool) {
407     aLastTool = theWBName;
408     if (aNb > 20) {
409       desktop()->addToolBarBreak();
410       aNb = 0;
411     }
412   }
413   aNb++;
414
415   int aId = myActionsList.size();
416   myActionsList.append(theId);
417   SUIT_Desktop* aDesk = application()->desktop();
418   int aKeys = 0;
419   for (unsigned int i = 0; i < theKeys.count(); i++)
420     aKeys += theKeys[i];
421   QAction* aAction = createAction(aId, theTip, theIcon, theTitle, theTip, aKeys, aDesk,
422                                   isCheckable);
423   aAction->setStatusTip(theStatusTip);
424
425   aAction->setData(theId);
426
427   int aWBMenu = createMenu(theWBName, -1, -1, 30/*10-Window, 1000 - Help*/);
428   int aItemId = createMenu(aId, aWBMenu);
429   if (isAddSeparator)
430     createMenu(separator(), aWBMenu);
431
432   int aWBTool = createTool(theWBName, theWBName);
433   int aToolId = createTool(aId, aWBTool);
434   if (isAddSeparator)
435     createTool(separator(), aWBTool);
436
437   return aAction;
438 }
439
440 bool SHAPERGUI::isFeatureOfNested(const QAction* theAction)
441 {
442   return dynamic_cast<const SHAPERGUI_NestedButton*>(theAction);
443 }
444
445 QAction* SHAPERGUI::addFeatureOfNested(const QString& theWBName,
446                                        const ActionInfo& theInfo,
447                                        const QList<QAction*>& theNestedActions)
448 {
449   myActionsList.append(theInfo.id);
450   SUIT_Desktop* aDesk = application()->desktop();
451   SHAPERGUI_NestedButton* anAction = new SHAPERGUI_NestedButton(aDesk, theNestedActions);
452   anAction->setData(theInfo.id);
453   anAction->setCheckable(theInfo.checkable);
454   anAction->setChecked(theInfo.checked);
455   anAction->setEnabled(theInfo.enabled);
456   anAction->setVisible(theInfo.visible);
457   anAction->setIcon(theInfo.icon);
458   anAction->setText(theInfo.text);
459   anAction->setToolTip(theInfo.toolTip);
460   anAction->setShortcut(theInfo.shortcut);
461   anAction->setFont(theInfo.font);
462
463   int aWBMenu = createMenu(theWBName, -1, -1, 30);
464   int aItemId = createMenu(anAction, aWBMenu);
465   createMenu(separator(), aWBMenu); /// nested action is always separated of others
466
467   int aWBTool = createTool(theWBName, theWBName);
468   int aToolId = createTool(anAction, aWBTool);
469   createTool(separator(), aWBTool); /// nested action is always separated of others
470
471   return anAction;
472 }
473
474
475 //******************************************************
476 QAction* SHAPERGUI::addDesktopCommand(const QString& theId, const QString& theTitle,
477                                            const QString& theTip, const QIcon& theIcon,
478                                            const QKeySequence& theKeys, bool isCheckable,
479                                            const char* theMenuSourceText, const int theMenuPosition)
480 {
481   int aMenu = createMenu(tr(theMenuSourceText), -1, -1);
482
483   int aId = myActionsList.size();
484   myActionsList.append(theId);
485   SUIT_Desktop* aDesk = application()->desktop();
486   int aKeys = 0;
487   for (unsigned int i = 0; i < theKeys.count(); i++)
488     aKeys += theKeys[i];
489   QAction* aAction = createAction(aId, theTip, theIcon, theTitle, theTip, aKeys, aDesk,
490                                   isCheckable);
491   aAction->setStatusTip(theTip);
492   aAction->setData(theId);
493   createMenu(aId, aMenu, theMenuPosition);
494   return aAction;
495 }
496
497 //******************************************************
498 void SHAPERGUI::addDesktopMenuSeparator(const char* theMenuSourceText, const int theMenuPosition)
499 {
500   int aMenu = createMenu(tr(theMenuSourceText), -1, -1);
501   createMenu(separator(), aMenu, -1, theMenuPosition);
502 }
503
504 bool SHAPERGUI::addActionInToolbar( QAction* theAction, const QString& theToolBarTitle )
505 {
506   if( !theAction )
507     return false;
508
509   SUIT_Desktop* aDesktop = application()->desktop();
510   if( !aDesktop )
511     return false;
512
513   QtxActionToolMgr* aToolMgr = aDesktop->toolMgr();
514   if( !aToolMgr )
515     return false;
516
517   aToolMgr->append( theAction, theToolBarTitle );
518   return true;
519 }
520
521 //******************************************************
522 QList<QAction*> SHAPERGUI::commandList() const
523 {
524   QList<QAction*> aActions;
525   for (int i = 0; i < myActionsList.size(); i++) {
526     QAction* aCmd = action(i);
527     if (aCmd && myActionsList.contains(aCmd->data().toString()))
528       aActions.append(aCmd);
529   }
530
531   return aActions;
532 }
533
534 //******************************************************
535 QMainWindow* SHAPERGUI::desktop() const
536 {
537   return application()->desktop();
538 }
539
540 void SHAPERGUI::setFeatureInfo(const QString& theFeatureId,
541                                const std::shared_ptr<Config_FeatureMessage>& theMessage)
542 {
543   myFeaturesInfo.insert(theFeatureId, theMessage);
544 }
545
546 std::shared_ptr<Config_FeatureMessage> SHAPERGUI::featureInfo(const QString& theFeatureId)
547 {
548   std::shared_ptr<Config_FeatureMessage> aMessage;
549   if (myFeaturesInfo.contains(theFeatureId))
550     aMessage =  myFeaturesInfo[theFeatureId];
551   return aMessage;
552 }
553
554 //******************************************************
555 void SHAPERGUI::selectionChanged()
556 {
557   LightApp_Module::selectionChanged();
558   myWorkshop->salomeViewerSelectionChanged();
559 }
560
561 //******************************************************
562 void SHAPERGUI::contextMenuPopup(const QString& theClient, QMenu* theMenu, QString& theTitle)
563 {
564   myWorkshop->contextMenuMgr()->updateViewerMenu();
565   myWorkshop->contextMenuMgr()->addViewerMenu(theMenu);
566   LightApp_Module::contextMenuPopup(theClient, theMenu, theTitle);
567 }
568
569
570 //******************************************************
571 void SHAPERGUI::createPreferences()
572 {
573   LightApp_Preferences* pref = preferences();
574   if (!pref)
575     return;
576   ModuleBase_Preferences::updateConfigByResources();
577   QString aModName = moduleName();
578
579   QtxPreferenceItem* item = pref->findItem(aModName, true );
580   if ( item && (!item->isEmpty() )) {
581     item->parentItem()->removeItem(item);
582     delete item;
583   }
584
585   int catId = pref->addPreference(aModName, -1 );
586   if ( catId == -1 )
587     return;
588   SHAPERGUI_PrefMgr aMgr(pref, aModName);
589   ModuleBase_Preferences::createEditContent(&aMgr, catId);
590
591   int viewTab = pref->addItem(tr("Viewer"), catId);
592   // Create other parameters group in viewer tab
593   int otherGroup = pref->addItem(tr("Default selection"), viewTab);
594   pref->setItemProperty("columns", 3, otherGroup);
595   pref->addItem(tr("Faces"), otherGroup, 
596                          SUIT_PreferenceMgr::Bool,
597                          ModuleBase_Preferences::VIEWER_SECTION, "face-selection");
598   pref->addItem(tr("Edges"), otherGroup, 
599                          SUIT_PreferenceMgr::Bool,
600                          ModuleBase_Preferences::VIEWER_SECTION, "edge-selection");
601   pref->addItem(tr("Vertices"), otherGroup, 
602                          SUIT_PreferenceMgr::Bool,
603                          ModuleBase_Preferences::VIEWER_SECTION, "vertex-selection");
604   
605   int sensitivityGroup = pref->addItem(tr("Selection sensitivity"), viewTab);
606   pref->setItemProperty("columns", 2, sensitivityGroup);
607   pref->addItem(tr("Vertex"), sensitivityGroup, SUIT_PreferenceMgr::Double,
608                 ModuleBase_Preferences::VIEWER_SECTION, "point-selection-sensitivity");
609   pref->addItem(tr("Edge"), sensitivityGroup, SUIT_PreferenceMgr::Double,
610                 ModuleBase_Preferences::VIEWER_SECTION, "edge-selection-sensitivity");
611   pref->retrieve();
612 }
613
614 //******************************************************
615 void SHAPERGUI::preferencesChanged(const QString& theSection, const QString& theParam)
616 {
617   SUIT_ResourceMgr* aResMgr = application()->resourceMgr();
618   QString aVal = aResMgr->stringValue(theSection, theParam);
619   Config_Prop* aProp = Config_PropManager::findProp(theSection.toStdString(),
620                                                     theParam.toStdString());
621   std::string aValue = aVal.toStdString();
622   if (aValue.empty()) {
623     aValue = aProp->defaultValue();
624     aResMgr->setValue(theSection, theParam, QString(aValue.c_str()));
625
626     LightApp_Preferences* pref = preferences();
627     if (pref)
628       pref->retrieve();
629   }
630   aProp->setValue(aValue);
631
632   myWorkshop->displayer()->redisplayObjects();
633 }
634
635 void SHAPERGUI::putInfo(const QString& theInfo, const int theMSecs)
636 {
637   application()->putInfo(theInfo, theMSecs);
638 }
639
640 void SHAPERGUI::inspectSalomeModules()
641 {
642   QStringList aModuleNames;
643   getApp()->modules(aModuleNames, false);
644   foreach(QString eachModule, aModuleNames) {
645     Config_ModuleReader::addDependencyModule(eachModule.toStdString());
646   }
647 }
648
649 bool SHAPERGUI::abortAllOperations()
650 {
651   return workshop()->operationMgr()->abortAllOperations();
652 }
653
654 void SHAPERGUI::createFeatureActions()
655 {
656   myWorkshop->menuMgr()->createFeatureActions();
657 }