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