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