]> SALOME platform Git repositories - modules/shaper.git/blob - src/SHAPERGUI/SHAPERGUI.cpp
Salome HOME
Merge branch 'V9_5_BR'
[modules/shaper.git] / src / SHAPERGUI / SHAPERGUI.cpp
1 // Copyright (C) 2014-2020  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #include "SHAPERGUI.h"
21 #include "SHAPERGUI_DataModel.h"
22 #include "SHAPERGUI_OCCSelector.h"
23 #include "SHAPERGUI_NestedButton.h"
24 #include "SHAPERGUI_ToolbarsMgr.h"
25
26 #include <XGUI_Workshop.h>
27 #include <XGUI_PropertyPanel.h>
28 #include <XGUI_ContextMenuMgr.h>
29 #include <XGUI_ObjectsBrowser.h>
30 #include <XGUI_OperationMgr.h>
31 #include <XGUI_Displayer.h>
32 #include <XGUI_MenuMgr.h>
33 #include <XGUI_FacesPanel.h>
34 #include <XGUI_SelectionActivate.h>
35 #include <XGUI_InspectionPanel.h>
36 #include <XGUI_ViewerProxy.h>
37
38 #include <ModuleBase_Operation.h>
39 #include <ModuleBase_Preferences.h>
40 #include <ModuleBase_ActionInfo.h>
41 #include <ModuleBase_IModule.h>
42
43 #include <ModelAPI_Tools.h>
44
45 #include <LightApp_Application.h>
46 #include <LightApp_SelectionMgr.h>
47 #include <LightApp_OCCSelector.h>
48 #include <LightApp_Study.h>
49
50 #include <OCCViewer_ViewModel.h>
51 #include <OCCViewer_ViewPort3d.h>
52
53 #include <SUIT_Selector.h>
54 #include <SUIT_Desktop.h>
55 #include <SUIT_ViewManager.h>
56 #include <SUIT_ViewWindow.h>
57 #include <SUIT_ResourceMgr.h>
58 #include <SUIT_DataBrowser.h>
59
60 #include <QtxPopupMgr.h>
61 #include <QtxActionMenuMgr.h>
62 #include <QtxActionToolMgr.h>
63 #include <QtxResourceMgr.h>
64
65 #include <Config_PropManager.h>
66 #include <Config_ModuleReader.h>
67
68 #include <AIS_ListOfInteractive.hxx>
69 #include <AIS_ListIteratorOfListOfInteractive.hxx>
70
71 #include <QDockWidget>
72 #include <QAction>
73 #include <QTimer>
74 #include <QMenu>
75 #include <QToolBar>
76
77 #include <ModelAPI_Session.h>
78
79 #if OCC_VERSION_HEX < 0x070400
80   #define SALOME_PATCH_FOR_CTRL_WHEEL
81 #endif
82
83 extern "C" {
84 SHAPERGUI_EXPORT CAM_Module* createModule()
85 {
86   return new SHAPERGUI();
87 }
88
89 SHAPERGUI_EXPORT char* getModuleVersion()
90 {
91   return (char*)"0.0";
92 }
93 } // extern "C"
94
95
96 static const QString ToolbarsSection("SHAPER_Toolbars");
97 static const QString FreeCommandsParam("OutOFToolbars");
98
99
100 /** 
101 * Class for preferences management
102 */
103 class SHAPERGUI_PrefMgr: public ModuleBase_IPrefMgr
104 {
105 public:
106   /// Constructor
107   /// \param theMgr preferences manager of SALOME
108   /// \param theModName name of the module
109   SHAPERGUI_PrefMgr(LightApp_Preferences* theMgr, const QString& theModName):
110     myMgr(theMgr), myModName(theModName) {}
111
112   virtual int addPreference(const QString& theLbl, int pId,
113                             SUIT_PreferenceMgr::PrefItemType theType,
114                             const QString& theSection, const QString& theName )
115   {
116     return myMgr->addPreference(myModName, theLbl, pId, theType, theSection, theName);
117   }
118
119   virtual void setItemProperty(const QString& thePropName,
120                                const QVariant& theValue,
121                                const int theId = -1)
122   {
123     myMgr->setItemProperty(thePropName, theValue, theId);
124   }
125
126
127   virtual SUIT_PreferenceMgr* prefMgr() const { return myMgr; }
128
129 private:
130   LightApp_Preferences* myMgr;
131   QString myModName;
132 };
133
134
135
136
137 //******************************************************
138 SHAPERGUI::SHAPERGUI()
139     : LightApp_Module("SHAPER"),
140       mySelector(0), myIsOpened(0), myPopupMgr(0), myIsInspectionVisible(false),
141   myInspectionPanel(0), myIsFacesPanelVisible(false), myIsToolbarsModified(false)
142 {
143   myWorkshop = new XGUI_Workshop(this);
144   connect(myWorkshop, SIGNAL(commandStatusUpdated()),
145           this, SLOT(onUpdateCommandStatus()));
146
147   myProxyViewer = new SHAPERGUI_SalomeViewer(this);
148
149   ModuleBase_Preferences::setResourceMgr(application()->resourceMgr());
150
151   // It will be called in XGUI_Workshop::startApplication
152   // ModuleBase_Preferences::loadCustomProps();
153 }
154
155 //******************************************************
156 SHAPERGUI::~SHAPERGUI()
157 {
158   delete myWorkshop;
159   delete myProxyViewer;
160 }
161
162 //******************************************************
163 void SHAPERGUI::initialize(CAM_Application* theApp)
164 {
165   LightApp_Module::initialize(theApp);
166
167   myWorkshop->startApplication();
168   LightApp_Application* anApp = dynamic_cast<LightApp_Application*>(theApp);
169   if (anApp)
170   {
171     connect(anApp, SIGNAL(preferenceResetToDefaults()), this, SLOT(onDefaultPreferences()));
172   }
173
174   int aMenu = createMenu(tr("Inspection"), -1, -1, 30);
175   int aSubMenu = createMenu(tr("Information"), aMenu, -1, -1, 0);
176
177   int aId = getNextCommandId();
178   myActionsList.append(aId);
179   SUIT_Desktop* aDesk = application()->desktop();
180   QString aTip = tr("Show inspection window");
181   myWhatIsAction = createAction(aId, aTip, QIcon(":pictures/whatis.png"), tr("What Is"),
182     aTip, QKeySequence(), aDesk, true, this, SLOT(onWhatIs(bool)));
183   myWhatIsAction->setStatusTip(aTip);
184   myWhatIsAction->setData("INSPECTION_CMD");
185   createMenu(aId, aSubMenu, 0);
186
187   QString aToolName = tr("Inspection");
188   int aTool = createTool(aToolName);
189 #ifdef _DEBUG
190   int aToolId =
191 #endif
192     createTool(myWhatIsAction, aTool);
193   registerCommandToolbar(aToolName, aId);
194
195   // Define Edit toolbars command
196   aId = getNextCommandId();
197   //myActionsList.append(aId); Do not use it for editing of toolbars
198   aTip = tr("Edit toolbars of the module");
199 #ifdef _DEBUG
200   QAction* aAction =
201 #endif
202     createAction(aId, aTip, QIcon(":pictures/configure_toolbars.png"),
203     tr("Edit toolbars..."), aTip, QKeySequence(), aDesk, false, this, SLOT(onEditToolbars()));
204   int aEditMenu = createMenu(tr("MEN_DESK_EDIT"), -1, -1, 30);
205 #ifdef _DEBUG
206   int aEditItem =
207 #endif
208     createMenu(aId, aEditMenu);
209
210   if (!myInspectionPanel) {
211     myInspectionPanel = myWorkshop->inspectionPanel();
212     connect(myInspectionPanel->toggleViewAction(), SIGNAL(toggled(bool)),
213       this, SLOT(onWhatIs(bool)));
214   }
215   hideInternalWindows();
216
217   // Initialize viewer proxy if OCC viewer is already exist
218   ViewManagerList aOCCViewManagers;
219   application()->viewManagers(OCCViewer_Viewer::Type(), aOCCViewManagers);
220   if (aOCCViewManagers.size() > 0) {
221     SUIT_ViewManager* aMgr = aOCCViewManagers.first();
222     SUIT_ViewWindow* aWnd = aMgr->getActiveView();
223     if (aWnd) {
224       OCCViewer_ViewWindow* aOccWnd = static_cast<OCCViewer_ViewWindow*>(aWnd);
225       OCCViewer_ViewPort3d* aViewPort = aOccWnd->getViewPort();
226       if (aViewPort) {
227         XGUI_ViewerProxy* aViewer = myWorkshop->viewer();
228         aViewPort->installEventFilter(aViewer);
229         Handle(V3d_View) aView = aViewPort->getView();
230         aViewer->SetScale(aView, aView->Camera()->Scale());
231         // We can not create selector here because other modules will be deactivated later
232         //onViewManagerAdded(aMgr);
233       }
234     }
235   }
236   SHAPERGUI_DataModel* aDataModel = dynamic_cast<SHAPERGUI_DataModel*>(dataModel());
237   aDataModel->initRootObject();
238 }
239
240 //******************************************************
241 void SHAPERGUI::windows(QMap<int, int>& theWndMap) const
242 {
243   theWndMap.insert(LightApp_Application::WT_PyConsole, Qt::BottomDockWidgetArea);
244 }
245
246 //******************************************************
247 void SHAPERGUI::viewManagers(QStringList& theList) const
248 {
249   theList.append(OCCViewer_Viewer::Type());
250 }
251
252 //******************************************************
253 // We can not create selector in this method because it can be called when
254 // SHAPER module is not active. Take into account that creation of our selector
255 // leads to switching OFF all other selectors
256 //void SHAPERGUI::connectToStudy(CAM_Study* theStudy)
257 //{
258 //  // if there are created viewer managers, we should try to create viewer
259 //  // selector and initialize viewer with it. It sets interactive context to the
260 //  // proxy viewer. If study is opened, CAM application calls this method before the open()
261 //  // of data model
262 //  // the SHAPER data model is specific and during open(load) redisplay signals are flushed, so
263 //  // we need to connect to the viewer before it. Here,
264 //  // it seems the most appropriate place for this
265 //  // according to SALOME architecture.
266 //  if (!mySelector) {
267 //    ViewManagerList OCCViewManagers;
268 //    application()->viewManagers(OCCViewer_Viewer::Type(), OCCViewManagers);
269 //    if (OCCViewManagers.size() > 0) {
270 //      mySelector = createSelector(OCCViewManagers.first());
271 //    }
272 //  }
273 //  LightApp_Module::connectToStudy(theStudy);
274 //}
275
276 //******************************************************
277 bool SHAPERGUI::activateModule(SUIT_Study* theStudy)
278 {
279   ModelAPI_Session::get()->moduleDocument(); // initialize a root document if not done yet
280
281   // this must be done in the initialization and in activation (on the second activation
282   // initialization in not called, so SComponent must be added anyway
283   SHAPERGUI_DataModel* aDataModel = dynamic_cast<SHAPERGUI_DataModel*>(dataModel());
284   aDataModel->initRootObject();
285
286
287   bool isDone = LightApp_Module::activateModule(theStudy);
288   loadToolbarsConfig();
289
290   if (isDone) {
291     setMenuShown(true);
292     setToolShown(true);
293
294     QObject* aObj = myWorkshop->objectBrowser()->parent();
295     QDockWidget* aObjDoc = dynamic_cast<QDockWidget*>(aObj);
296     if (aObjDoc) {
297       myWorkshop->objectBrowser()->setVisible(true);
298       aObjDoc->setVisible(true);
299       desktop()->tabifyDockWidget(aObjDoc, myWorkshop->propertyPanel());
300       aObjDoc->toggleViewAction()->setVisible(true);
301     }
302
303     myInspectionPanel->toggleViewAction()->setVisible(true);
304
305     myWorkshop->facesPanel()->toggleViewAction()->setVisible(true);
306     if (myIsFacesPanelVisible)
307       myWorkshop->facesPanel()->show();
308     myWorkshop->propertyPanel()->toggleViewAction()->setVisible(true);
309
310     if (!mySelector) {
311       ViewManagerList OCCViewManagers;
312       application()->viewManagers(OCCViewer_Viewer::Type(), OCCViewManagers);
313       if (OCCViewManagers.size() > 0) {
314         onViewManagerAdded(OCCViewManagers.first());
315       }
316     }
317     // it should be performed after the selector creation in order to have AISContext
318     myWorkshop->activateModule();
319     //action(myEraseAll)->setEnabled(false);
320
321     if (myIsOpened) {
322       myWorkshop->objectBrowser()->rebuildDataTree();
323       myWorkshop->updateCommandStatus();
324       myIsOpened = false;
325     }
326     else
327       myWorkshop->updateCommandStatus();
328   }
329   SUIT_ResourceMgr* aResMgr = application()->resourceMgr();
330   myIsStorePositions = aResMgr->booleanValue("Study", "store_positions", true);
331   myIsEditEnabled = getApp()->isEditEnabled();
332   getApp()->setEditEnabled(false);
333
334   // this following row is caused by #187 bug.
335   // SALOME saves the dock widget positions before deactivateModule() and
336   // load it after the module activation. So, if the panel is visible before
337   // deactivate, it becomes visible after activate.
338   // In order to avoid the visible property panel, the widget position save is
339   // switch off in this module
340   aResMgr->setValue("Study", "store_positions", false);
341
342   // Synchronize displayed objects
343   Handle(AIS_InteractiveContext) aContext;
344   if (mySelector && mySelector->viewer())
345     aContext = mySelector->viewer()->getAISContext();
346
347   if (!aContext.IsNull()) {
348     XGUI_Displayer* aDisp = myWorkshop->displayer();
349     QObjectPtrList aObjList = aDisp->displayedObjects();
350
351     //if (myHighlightPointAspect.IsNull()) {
352     //  Handle(AIS_Trihedron) aTrihedron = mySelector->viewer()->getTrihedron();
353     //  myHighlightPointAspect =
354     //    new Graphic3d_AspectMarker3d(aTrihedron->getHighlightPointAspect()->Aspect().operator*());
355     //}
356     if (myOldSelectionColor.size() == 0)
357       myOldSelectionColor = aDisp->selectionColor();
358
359     AIS_ListOfInteractive aList;
360     aContext->DisplayedObjects(aList);
361     AIS_ListIteratorOfListOfInteractive aLIt;
362     Handle(AIS_InteractiveObject) anAISIO;
363     foreach (ObjectPtr aObj, aObjList) {
364       AISObjectPtr aPrs = aDisp->getAISObject(aObj);
365       Handle(AIS_InteractiveObject) aAIS = aPrs->impl<Handle(AIS_InteractiveObject)>();
366       bool aFound = false;
367       for (aLIt.Initialize(aList); aLIt.More(); aLIt.Next()) {
368         anAISIO = aLIt.Value();
369         if (anAISIO.get() == aAIS.get()) {
370           aFound = true;
371           break;
372         }
373       }
374       if (!aFound) {
375         aObj->setDisplayed(false);
376         //aDisp->erase(aObj, false);
377       }
378     }
379     Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
380   }
381   myProxyViewer->activateViewer(true);
382
383   // Post-processing for LoadScriptId to remove created(if it was created) SALOME Object Browser
384   connect(getApp()->action(LightApp_Application::UserID+1), SIGNAL(triggered(bool)),
385           this, SLOT(onScriptLoaded()));
386
387   disconnect(getApp()->action(LightApp_Application::FileSaveId), SIGNAL(triggered(bool)),
388              getApp(), SLOT(onSaveDoc()));
389   disconnect(getApp()->action(LightApp_Application::FileSaveAsId), SIGNAL(triggered(bool)),
390              getApp(), SLOT(onSaveAsDoc()));
391
392   connect(getApp()->action(LightApp_Application::FileSaveId), SIGNAL(triggered(bool)),
393           this, SLOT(onSaveDocByShaper()));
394   connect(getApp()->action(LightApp_Application::FileSaveAsId), SIGNAL(triggered(bool)),
395           this, SLOT(onSaveAsDocByShaper()));
396
397   return isDone;
398 }
399
400 //******************************************************
401 void SHAPERGUI::hideInternalWindows()
402 {
403   myProxyViewer->activateViewer(false);
404   setMenuShown(false);
405   setToolShown(false);
406
407   QObject* aObj = myWorkshop->objectBrowser()->parent();
408   QDockWidget* aObjDoc = dynamic_cast<QDockWidget*>(aObj);
409   if (aObjDoc) {
410     aObjDoc->setVisible(false);
411     myWorkshop->objectBrowser()->setVisible(false);
412     aObjDoc->toggleViewAction()->setVisible(false);
413   }
414
415   myInspectionPanel->hide();
416   myInspectionPanel->toggleViewAction()->setVisible(false);
417
418   myWorkshop->facesPanel()->hide();
419   myWorkshop->facesPanel()->toggleViewAction()->setVisible(false);
420
421   myWorkshop->propertyPanel()->hide();
422   myWorkshop->propertyPanel()->toggleViewAction()->setVisible(false);
423
424   myWorkshop->hidePanel(myWorkshop->facesPanel());
425 }
426
427
428 //******************************************************
429 bool SHAPERGUI::deactivateModule(SUIT_Study* theStudy)
430 {
431   saveToolbarsConfig();
432   myWorkshop->deactivateModule();
433
434   myIsInspectionVisible = myInspectionPanel->isVisible();
435   myIsFacesPanelVisible = myWorkshop->facesPanel()->isVisible();
436   hideInternalWindows();
437
438
439   // the active operation should be stopped for the next activation.
440   // There should not be active operation and visualized preview.
441   // Abort operation should be performed before the selection's remove
442   // because the displayed objects should be removed from the viewer, but
443   // the AIS context is obtained from the selector.
444   ModuleBase_Operation* anOperation = myWorkshop->operationMgr()->currentOperation();
445   while (anOperation) {
446     anOperation->abort();
447     anOperation = myWorkshop->operationMgr()->currentOperation();
448   }
449   // Delete selector because it has to be redefined on next activation
450   if (mySelector) {
451     //if (!myHighlightPointAspect.IsNull()) {
452     //  Handle(AIS_Trihedron) aTrihedron = mySelector->viewer()->getTrihedron();
453     //  aTrihedron->getHighlightPointAspect()->SetAspect(myHighlightPointAspect);
454     //  myHighlightPointAspect.Nullify();
455     //}
456     myWorkshop->displayer()->setSelectionColor(myOldSelectionColor);
457     myProxyViewer->setSelector(0);
458
459     LightApp_SelectionMgr* aMgr = getApp()->selectionMgr();
460     QList<SUIT_Selector*> aList;
461     aMgr->selectors(aList);
462     foreach(SUIT_Selector* aSel, aList) {
463       aSel->setEnabled(aSel != mySelector);
464     }
465
466     delete mySelector;
467     mySelector = 0;
468   }
469
470   //myWorkshop->contextMenuMgr()->disconnectViewer();
471
472   SUIT_ResourceMgr* aResMgr = application()->resourceMgr();
473   aResMgr->setValue("Study", "store_positions", myIsStorePositions);
474   getApp()->setEditEnabled(myIsEditEnabled);
475
476   myOldSelectionColor.clear();
477
478   // Post-processing for LoadScriptId to remove created(if it was created) SALOME Object Browser
479   disconnect(getApp()->action(LightApp_Application::UserID+1), SIGNAL(triggered(bool)),
480              this, SLOT(onScriptLoaded()));
481
482   disconnect(getApp()->action(LightApp_Application::FileSaveId), SIGNAL(triggered(bool)),
483              this, SLOT(onSaveDocByShaper()));
484   disconnect(getApp()->action(LightApp_Application::FileSaveAsId), SIGNAL(triggered(bool)),
485              this, SLOT(onSaveAsDocByShaper()));
486
487   connect(getApp()->action(LightApp_Application::FileSaveId), SIGNAL(triggered(bool)),
488           getApp(), SLOT(onSaveDoc()));
489   connect(getApp()->action(LightApp_Application::FileSaveAsId), SIGNAL(triggered(bool)),
490           getApp(), SLOT(onSaveAsDoc()));
491
492   publishToStudy();
493
494   return LightApp_Module::deactivateModule(theStudy);
495 }
496
497 //******************************************************
498 void SHAPERGUI::onViewManagerAdded(SUIT_ViewManager* theMgr)
499 {
500   if (!mySelector) {
501     mySelector = createSelector(theMgr);
502     myWorkshop->selectionActivate()->updateSelectionFilters();
503     myWorkshop->selectionActivate()->updateSelectionModes();
504     myWorkshop->synchronizeViewer();
505   }
506 }
507
508 //******************************************************
509 void SHAPERGUI::onViewManagerRemoved(SUIT_ViewManager* theMgr)
510 {
511   if (mySelector) {
512     if (theMgr->getType() == OCCViewer_Viewer::Type()) {
513       OCCViewer_Viewer* aViewer = static_cast<OCCViewer_Viewer*>(theMgr->getViewModel());
514       if (mySelector->viewer() == aViewer) {
515         XGUI_Displayer* aDisp = myWorkshop->displayer();
516         QObjectPtrList aObjects = aDisp->displayedObjects();
517         ResultPtr aRes;
518         foreach(ObjectPtr aObj, aObjects) {
519           aObj->setDisplayed(false);
520           aRes = std::dynamic_pointer_cast<ModelAPI_Result>(aObj);
521           if (aRes.get()) {
522             while (aRes = ModelAPI_Tools::bodyOwner(aRes)) {
523               aRes->setDisplayed(false);
524             }
525           }
526         }
527         Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
528         myProxyViewer->setSelector(0);
529         delete mySelector;
530         mySelector = 0;
531
532         myWorkshop->module()->clearViewer();
533       }
534     }
535   }
536 }
537
538 //******************************************************
539 QtxPopupMgr* SHAPERGUI::popupMgr()
540 {
541   if (!myPopupMgr)
542     myPopupMgr = new QtxPopupMgr( 0, this );
543   return myPopupMgr;
544 }
545
546 //******************************************************
547 void SHAPERGUI::onDefaultPreferences()
548 {
549   // reset main resources
550   ModuleBase_Preferences::resetResourcePreferences(preferences());
551   // reset plugin's resources
552   ModuleBase_Preferences::resetConfigPropPreferences(preferences());
553
554   myWorkshop->displayer()->redisplayObjects();
555 }
556
557 //******************************************************
558 void SHAPERGUI::onScriptLoaded()
559 {
560   // this slot is called after processing of the LoadScriptId action of SalomeApp Application
561   // Each dumped script contains updateObjBrowser() that creates a new instance of Object
562   // Browser. When SHAPER module is active, this browser should not be used. It might be removed
563   // as hidden by means of updateWindows() of SalomeApp_Application or to remove
564   // it manually (because this method of application is protected)
565   SUIT_DataBrowser* aBrowser = getApp()->objectBrowser();
566   if (aBrowser)
567     delete aBrowser;
568   myWorkshop->displayer()->updateViewer();
569   myWorkshop->updateCommandStatus();
570 }
571
572 //******************************************************
573 void SHAPERGUI::onSaveDocByShaper()
574 {
575   if(!workshop()->operationMgr()->abortAllOperations(XGUI_OperationMgr::XGUI_InformationMessage))
576     return;
577
578   getApp()->onSaveDoc();
579 }
580
581 //******************************************************
582 void SHAPERGUI::onSaveAsDocByShaper()
583 {
584   if(!workshop()->operationMgr()->abortAllOperations(XGUI_OperationMgr::XGUI_InformationMessage))
585     return;
586
587   getApp()->onSaveAsDoc();
588 }
589
590 //******************************************************
591 void SHAPERGUI::onUpdateCommandStatus()
592 {
593   getApp()->updateActions();
594 }
595
596 //******************************************************
597 SHAPERGUI_OCCSelector* SHAPERGUI::createSelector(SUIT_ViewManager* theMgr)
598 {
599   if (theMgr->getType() == OCCViewer_Viewer::Type()) {
600     OCCViewer_Viewer* aViewer = static_cast<OCCViewer_Viewer*>(theMgr->getViewModel());
601
602     //if (myHighlightPointAspect.IsNull()) {
603     //  Handle(AIS_Trihedron) aTrihedron = aViewer->getTrihedron();
604     //  myHighlightPointAspect =
605     //    new Graphic3d_AspectMarker3d(aTrihedron->getHighlightPointAspect()->Aspect().operator*());
606     //}
607     SHAPERGUI_OCCSelector* aSelector = new SHAPERGUI_OCCSelector(aViewer,
608                                                                  getApp()->selectionMgr());
609 #ifdef SALOME_PATCH_FOR_CTRL_WHEEL
610     aViewer->setUseLocalSelection(true);
611 #endif
612     LightApp_SelectionMgr* aMgr = getApp()->selectionMgr();
613     QList<SUIT_Selector*> aList;
614     aMgr->selectors(aList);
615     foreach(SUIT_Selector* aSel, aList)
616     {
617       aSel->setEnabled(aSel == aSelector);
618     }
619     myProxyViewer->setSelector(aSelector);
620
621     if (myOldSelectionColor.size() == 0)
622       myOldSelectionColor = myWorkshop->displayer()->selectionColor();
623
624     std::vector<int> aColor = Config_PropManager::color("Visualization", "selection_color");
625     myWorkshop->displayer()->setSelectionColor(aColor);
626     return aSelector;
627   }
628   return 0;
629 }
630
631 //******************************************************
632 CAM_DataModel* SHAPERGUI::createDataModel()
633 {
634   return new SHAPERGUI_DataModel(this);
635 }
636
637 QAction* SHAPERGUI::addFeature(const QString& theWBName, const ActionInfo& theInfo,
638                                const bool isAddSeparator)
639 {
640   return addFeature(theWBName,
641                     theInfo.toolBar,
642                     theInfo.id,
643                     theInfo.text,
644                     //Issue #650: in the SALOME mode the tooltip should be same as text
645                     theInfo.text,
646                     theInfo.icon,
647                     theInfo.shortcut,
648                     theInfo.checkable,
649                     isAddSeparator,
650                     theInfo.toolTip);
651 }
652
653 //******************************************************
654 QAction* SHAPERGUI::addFeature(const QString& theWBName, const QString& theTBName,
655                                const QString& theId, const QString& theTitle, const QString& theTip,
656                                const QIcon& theIcon, const QKeySequence& theKeys,
657                                bool isCheckable, const bool isAddSeparator,
658                                const QString& theStatusTip)
659 {
660   static QString aLastTool = "";
661   static int aNb = 0;
662   if (aLastTool.isEmpty())
663     aLastTool = theWBName;
664   else if (theWBName != aLastTool) {
665     aLastTool = theWBName;
666     if (aNb > 20) {
667       desktop()->addToolBarBreak();
668       aNb = 0;
669     }
670   }
671   aNb++;
672
673   int aId = getNextCommandId();
674   myActionsList.append(aId);
675   SUIT_Desktop* aDesk = application()->desktop();
676   int aKeys = 0;
677   for (int i = 0; i < theKeys.count(); i++)
678     aKeys += theKeys[i];
679   QAction* aAction = createAction(aId, theTip, theIcon, theTitle, theTip, aKeys, aDesk,
680                                   isCheckable);
681   aAction->setStatusTip(theStatusTip);
682
683   aAction->setData(theId);
684
685   int aWBMenu = createMenu(theWBName, -1, -1, 30/*10-Window, 1000 - Help*/);
686 #ifdef _DEBUG
687   int aItemId =
688 #endif
689     createMenu(aId, aWBMenu);
690   if (isAddSeparator)
691     createMenu(separator(), aWBMenu);
692
693   int aWBTool = createTool(theTBName, theTBName);
694 #ifdef _DEBUG
695   int aToolId =
696 #endif
697     createTool(aId, aWBTool);
698   registerCommandToolbar(theTBName, aId);
699   if (isAddSeparator) {
700     createTool(separator(), aWBTool);
701     registerCommandToolbar(theTBName, -1);
702   }
703   return aAction;
704 }
705
706 bool SHAPERGUI::isFeatureOfNested(const QAction* theAction)
707 {
708   return dynamic_cast<const SHAPERGUI_NestedButton*>(theAction);
709 }
710
711 QAction* SHAPERGUI::addFeatureOfNested(const QString& theWBName,
712                                        const ActionInfo& theInfo,
713                                        const QList<QAction*>& theNestedActions)
714 {
715   SUIT_Desktop* aDesk = application()->desktop();
716   SHAPERGUI_NestedButton* anAction = new SHAPERGUI_NestedButton(aDesk, theNestedActions);
717   anAction->setData(theInfo.id);
718   anAction->setCheckable(theInfo.checkable);
719   anAction->setChecked(theInfo.checked);
720   anAction->setEnabled(theInfo.enabled);
721   anAction->setVisible(theInfo.visible);
722   anAction->setIcon(theInfo.icon);
723   anAction->setText(theInfo.text);
724   anAction->setToolTip(theInfo.toolTip);
725   anAction->setShortcut(theInfo.shortcut);
726   anAction->setFont(theInfo.font);
727
728   int aWBMenu = createMenu(theWBName, -1, -1, 30);
729   int aItemId = createMenu(anAction, aWBMenu);
730   myActionsList.append(aItemId);
731   createMenu(separator(), aWBMenu); /// nested action is always separated of others
732
733   int aWBTool = createTool(theWBName, theWBName);
734 #ifdef _DEBUG
735   int aToolId =
736 #endif
737     createTool(anAction, aWBTool);
738   registerCommandToolbar(theWBName, aItemId);
739   createTool(separator(), aWBTool); /// nested action is always separated of others
740   registerCommandToolbar(theWBName, -1);
741
742   return anAction;
743 }
744
745
746 //******************************************************
747 QAction* SHAPERGUI::addDesktopCommand(const QString& theId, const QString& theTitle,
748                                            const QString& theTip, const QIcon& theIcon,
749                                            const QKeySequence& theKeys, bool isCheckable,
750                                            const char* theMenuSourceText,
751                                            const QString& theSubMenu,
752                                            const int theMenuPosition,
753                                            const int theSuibMenuPosition)
754 {
755   int aMenu = createMenu(tr(theMenuSourceText), -1, -1);
756   if (!theSubMenu.isNull())
757     aMenu = createMenu(theSubMenu, aMenu, -1, theSuibMenuPosition);
758
759   int aId = getNextCommandId();
760   myActionsList.append(aId);
761   SUIT_Desktop* aDesk = application()->desktop();
762   int aKeys = 0;
763   for (int i = 0; i < theKeys.count(); i++)
764     aKeys += theKeys[i];
765   QAction* aAction = createAction(aId, theTip, theIcon, theTitle, theTip, aKeys, aDesk,
766                                   isCheckable);
767   aAction->setStatusTip(theTip);
768   aAction->setData(theId);
769   createMenu(aId, aMenu, theMenuPosition);
770   return aAction;
771 }
772
773 //******************************************************
774 void SHAPERGUI::addDesktopMenuSeparator(const char* theMenuSourceText, const int theMenuPosition)
775 {
776   int aMenu = createMenu(tr(theMenuSourceText), -1, -1);
777   createMenu(separator(), aMenu, -1, theMenuPosition);
778 }
779
780 //******************************************************
781 bool SHAPERGUI::addActionInToolbar( QAction* theAction, const QString& theToolBarTitle )
782 {
783   if( !theAction )
784     return false;
785
786   SUIT_Desktop* aDesktop = application()->desktop();
787   if( !aDesktop )
788     return false;
789
790   QtxActionToolMgr* aToolMgr = aDesktop->toolMgr();
791   if( !aToolMgr )
792     return false;
793
794   aToolMgr->append( theAction, theToolBarTitle );
795   return true;
796 }
797
798 //******************************************************
799 QList<QAction*> SHAPERGUI::commandList() const
800 {
801   QList<QAction*> aActions;
802   foreach (int aId, myActionsList) {
803     QAction* aCmd = action(aId);
804     if (aCmd)
805       aActions.append(aCmd);
806   }
807
808   return aActions;
809 }
810
811 //******************************************************
812 QMainWindow* SHAPERGUI::desktop() const
813 {
814   return application()->desktop();
815 }
816
817 void SHAPERGUI::setFeatureInfo(const QString& theFeatureId,
818                                const std::shared_ptr<Config_FeatureMessage>& theMessage)
819 {
820   myFeaturesInfo.insert(theFeatureId, theMessage);
821 }
822
823 std::shared_ptr<Config_FeatureMessage> SHAPERGUI::featureInfo(const QString& theFeatureId)
824 {
825   std::shared_ptr<Config_FeatureMessage> aMessage;
826   if (myFeaturesInfo.contains(theFeatureId))
827     aMessage =  myFeaturesInfo[theFeatureId];
828   return aMessage;
829 }
830
831 //******************************************************
832 void SHAPERGUI::selectionChanged()
833 {
834   LightApp_Module::selectionChanged();
835   myWorkshop->salomeViewerSelectionChanged();
836 }
837
838 //******************************************************
839 void SHAPERGUI::contextMenuPopup(const QString& theClient, QMenu* theMenu, QString& theTitle)
840 {
841   myWorkshop->contextMenuMgr()->updateViewerMenu();
842   myWorkshop->contextMenuMgr()->addViewerMenu(theMenu);
843   LightApp_Module::contextMenuPopup(theClient, theMenu, theTitle);
844 }
845
846
847 //******************************************************
848 void SHAPERGUI::createPreferences()
849 {
850   LightApp_Preferences* pref = preferences();
851   if (!pref)
852     return;
853   ModuleBase_Preferences::updateConfigByResources();
854   QString aModName = moduleName();
855
856   QtxPreferenceItem* item = pref->findItem(aModName, true );
857   if ( item && (!item->isEmpty() )) {
858     item->parentItem()->removeItem(item);
859     delete item;
860   }
861
862   int catId = pref->addPreference(aModName, -1 );
863   if ( catId == -1 )
864     return;
865   SHAPERGUI_PrefMgr aMgr(pref, aModName);
866   ModuleBase_Preferences::createEditContent(&aMgr, catId);
867
868   int viewTab = pref->addItem(tr("Viewer"), catId);
869   // Create other parameters group in viewer tab
870   int otherGroup = pref->addItem(tr("Default selection"), viewTab);
871   pref->setItemProperty("columns", 3, otherGroup);
872   pref->addItem(tr("Faces"), otherGroup,
873                          SUIT_PreferenceMgr::Bool,
874                          ModuleBase_Preferences::VIEWER_SECTION, "face-selection");
875   pref->addItem(tr("Edges"), otherGroup,
876                          SUIT_PreferenceMgr::Bool,
877                          ModuleBase_Preferences::VIEWER_SECTION, "edge-selection");
878   pref->addItem(tr("Vertices"), otherGroup,
879                          SUIT_PreferenceMgr::Bool,
880                          ModuleBase_Preferences::VIEWER_SECTION, "vertex-selection");
881
882   int sensitivityGroup = pref->addItem(tr("Selection sensitivity"), viewTab);
883   pref->setItemProperty("columns", 2, sensitivityGroup);
884   pref->addItem(tr("Vertex"), sensitivityGroup, SUIT_PreferenceMgr::DblSpin,
885                 ModuleBase_Preferences::VIEWER_SECTION, "point-selection-sensitivity");
886   pref->addItem(tr("Edge"), sensitivityGroup, SUIT_PreferenceMgr::DblSpin,
887                 ModuleBase_Preferences::VIEWER_SECTION, "edge-selection-sensitivity");
888
889   int highlightGroup = pref->addItem(tr("Additional highlighting"), viewTab);
890   pref->setItemProperty("columns", 2, highlightGroup);
891   pref->addItem(tr("In 3d mode"), highlightGroup,
892     SUIT_PreferenceMgr::Bool, ModuleBase_Preferences::VIEWER_SECTION, "highlighting-3d");
893   pref->addItem(tr("In 2d mode"), highlightGroup,
894     SUIT_PreferenceMgr::Bool, ModuleBase_Preferences::VIEWER_SECTION, "highlighting-2d");
895
896   int colorScaleGroup = pref->addItem(tr("Color scale"), viewTab);
897   pref->setItemProperty("columns", 4, colorScaleGroup);
898   int aItem = aMgr.addPreference(tr("X position"), colorScaleGroup,
899     SUIT_PreferenceMgr::Double, ModuleBase_Preferences::VIEWER_SECTION, "scalar_bar_x_position");
900   pref->setItemProperty("min", 0, aItem);
901   pref->setItemProperty("max", 1, aItem);
902
903   aItem = aMgr.addPreference(tr("Y position"), colorScaleGroup,
904     SUIT_PreferenceMgr::Double, ModuleBase_Preferences::VIEWER_SECTION, "scalar_bar_y_position");
905   pref->setItemProperty("min", 0, aItem);
906   pref->setItemProperty("max", 1, aItem);
907
908   aItem = aMgr.addPreference(tr("Width"), colorScaleGroup,
909     SUIT_PreferenceMgr::Double, ModuleBase_Preferences::VIEWER_SECTION, "scalar_bar_width");
910   pref->setItemProperty("min", 0, aItem);
911   pref->setItemProperty("max", 1, aItem);
912
913   aItem = aMgr.addPreference(tr("Height"), colorScaleGroup,
914     SUIT_PreferenceMgr::Double, ModuleBase_Preferences::VIEWER_SECTION, "scalar_bar_height");
915   pref->setItemProperty("min", 0, aItem);
916   pref->setItemProperty("max", 1, aItem);
917
918   aItem = aMgr.addPreference(tr("Intervals number"), colorScaleGroup,
919     SUIT_PreferenceMgr::Integer, ModuleBase_Preferences::VIEWER_SECTION, "scalar_bar_nb_intervals");
920   pref->setItemProperty("min", 0, aItem);
921   pref->setItemProperty("max", 100, aItem);
922
923   aItem = aMgr.addPreference(tr("Text height"), colorScaleGroup,
924     SUIT_PreferenceMgr::Integer, ModuleBase_Preferences::VIEWER_SECTION, "scalar_bar_text_height");
925   pref->setItemProperty("min", 0, aItem);
926   pref->setItemProperty("max", 100, aItem);
927
928   aItem = aMgr.addPreference(tr("Text color"), colorScaleGroup,
929     SUIT_PreferenceMgr::Color, ModuleBase_Preferences::VIEWER_SECTION, "scalar_bar_text_color");
930
931   pref->retrieve();
932 }
933
934 //******************************************************
935 void SHAPERGUI::preferencesChanged(const QString& theSection, const QString& theParam)
936 {
937   SUIT_ResourceMgr* aResMgr = application()->resourceMgr();
938   QString aVal = aResMgr->stringValue(theSection, theParam);
939   Config_Prop* aProp = Config_PropManager::findProp(theSection.toStdString(),
940                                                     theParam.toStdString());
941   std::string aValue = aVal.toStdString();
942   if (aValue.empty()) {
943     aValue = aProp->defaultValue();
944     aResMgr->setValue(theSection, theParam, QString(aValue.c_str()));
945
946     LightApp_Preferences* pref = preferences();
947     if (pref)
948       pref->retrieve();
949   }
950   aProp->setValue(aValue);
951
952   if ((theSection == "Visualization") && (theParam == "selection_color")) {
953     std::vector<int> aColor = Config_PropManager::color("Visualization", "selection_color");
954     myWorkshop->displayer()->setSelectionColor(aColor);
955   }
956
957   myWorkshop->displayer()->redisplayObjects();
958 }
959
960 void SHAPERGUI::putInfo(const QString& theInfo, const int theMSecs)
961 {
962   application()->putInfo(theInfo, theMSecs);
963 }
964
965 bool SHAPERGUI::abortAllOperations()
966 {
967   return workshop()->operationMgr()->abortAllOperations();
968 }
969
970 void SHAPERGUI::createFeatureActions()
971 {
972   myWorkshop->menuMgr()->createFeatureActions();
973 }
974
975 void SHAPERGUI::onWhatIs(bool isToggled)
976 {
977   if (sender() == myWhatIsAction) {
978     QAction* aViewAct = myInspectionPanel->toggleViewAction();
979     aViewAct->blockSignals(true);
980     aViewAct->setChecked(isToggled);
981     aViewAct->blockSignals(false);
982     myInspectionPanel->setVisible(isToggled);
983   }
984   else {
985     myWhatIsAction->blockSignals(true);
986     myWhatIsAction->setChecked(isToggled);
987     myWhatIsAction->blockSignals(false);
988     myInspectionPanel->setVisible(isToggled);
989   }
990 }
991
992 void SHAPERGUI::updateModuleVisibilityState()
993 {
994   LightApp_Module::updateModuleVisibilityState();
995   onWhatIs(myIsInspectionVisible);
996 }
997
998 void SHAPERGUI::onEditToolbars()
999 {
1000   SHAPERGUI_ToolbarsDlg aDlg(this);
1001   if (aDlg.exec() == QDialog::Accepted) {
1002     if (aDlg.isReset())
1003       resetToolbars();
1004     else
1005       updateToolbars(aDlg.result());
1006   }
1007 }
1008
1009 void SHAPERGUI::registerCommandToolbar(const QString& theToolName, int theCommandId)
1010 {
1011   if (!myToolbars.contains(theToolName))
1012     myToolbars[theToolName] = QList<int>();
1013   myToolbars[theToolName].append(theCommandId);
1014 }
1015
1016 int SHAPERGUI::getNextCommandId() const
1017 {
1018   QtxActionMenuMgr* aMenuMgr = menuMgr();
1019   QIntList aIds = aMenuMgr->idList();
1020   int aId = aIds.count();
1021   while (action(aId) || myActionsList.contains(aId))
1022     aId++;
1023   return aId;
1024 }
1025
1026 void SHAPERGUI::updateToolbars(const QMap<QString, QIntList>& theNewToolbars)
1027 {
1028   // Store default toolbars
1029   if (myDefaultToolbars.size() == 0)
1030     myDefaultToolbars = myToolbars;
1031
1032   QtxActionToolMgr* aMgr = toolMgr();
1033   QStringList aToolbars = theNewToolbars.keys();
1034   QIntList aCommands, aOldCmd;
1035   int aToolbarId;
1036   QAction* aAction;
1037   int aActionId;
1038   foreach(QString aName, aToolbars) {
1039     aCommands = theNewToolbars[aName];
1040     // Find or create toolbar
1041     if (aMgr->hasToolBar(aName)) {
1042       aToolbarId = aMgr->find(aMgr->toolBar(aName));
1043       aOldCmd = myToolbars[aName];
1044     }
1045     else {
1046       aToolbarId = aMgr->createToolBar(aName);
1047     }
1048     int aPos = 0;
1049     foreach(int aCmd, aCommands) {
1050       // Find action
1051       if (aCmd == -1)
1052         aAction = separator();
1053       else
1054         aAction = action(aCmd);
1055       aActionId = aMgr->actionId(aAction);
1056       if (aActionId == -1) {
1057         // Add new action
1058         aMgr->insert(aAction, aToolbarId, aPos);
1059       }
1060       else {
1061         // Change position of action
1062         if (aMgr->index(aActionId, aToolbarId) != aPos) {
1063           if (aMgr->containsAction(aActionId, aToolbarId))
1064             aMgr->remove(aActionId, aToolbarId);
1065           aMgr->insert(aActionId, aToolbarId, aPos);
1066         }
1067       }
1068       aOldCmd.removeAll(aCmd);
1069       aPos++;
1070     }
1071     // remove extra actions
1072     foreach(int aCmd, aOldCmd) {
1073       aAction = action(aCmd);
1074       aActionId = aMgr->actionId(aAction);
1075       aMgr->remove(aActionId, aToolbarId);
1076     }
1077     myToolbars.remove(aName);
1078   }
1079   // Remove extra toolbars
1080   aToolbars = myToolbars.keys();
1081   foreach(QString aName, aToolbars) {
1082     aMgr->removeToolBar(aName);
1083   }
1084   // Set new toolbars structure
1085   myToolbars = theNewToolbars;
1086   myIsToolbarsModified = true;
1087 }
1088
1089 void SHAPERGUI::saveToolbarsConfig()
1090 {
1091   if (!myIsToolbarsModified)
1092     return;
1093   // Save toolbars configuration into map
1094   QMap<QString, QStringList> aToolbarsConfig;
1095 #ifdef _DEBUG
1096   QtxActionToolMgr* aMgr =
1097 #endif
1098     toolMgr();
1099   QStringList aToolbars = myToolbars.keys();
1100   QIntList aActionsIds;
1101   foreach(QString aName, aToolbars) {
1102     aActionsIds = myToolbars[aName];
1103     QStringList aContent;
1104     foreach(int aId, aActionsIds) {
1105       if (aId == -1)
1106         aContent.append("");
1107       else
1108         aContent.append(action(aId)->data().toString());
1109     }
1110     aToolbarsConfig[aName] = aContent;
1111   }
1112   // Store the configuration into resources
1113   SUIT_ResourceMgr* aResMgr = application()->resourceMgr();
1114   QStringList aNames = aToolbarsConfig.keys();
1115   QStringList aValues;
1116   foreach(QString aToolbar, aNames) {
1117     aResMgr->setValue(ToolbarsSection, aToolbar, aToolbarsConfig[aToolbar].join(","));
1118   }
1119   // Remove obsolete parameters from resources
1120   QStringList aOldParams = aResMgr->parameters(ToolbarsSection);
1121   foreach(QString aName, aOldParams) {
1122     if (!aToolbars.contains(aName))
1123       aResMgr->remove(ToolbarsSection, aName);
1124   }
1125   // Store current list of free commands
1126   QIntList aFreeCommands = getFreeCommands();
1127   QStringList aFreeList;
1128   foreach(int aId, aFreeCommands) {
1129     aFreeList.append(action(aId)->data().toString());
1130   }
1131   if (aFreeList.size() > 0)
1132     aResMgr->setValue(ToolbarsSection, FreeCommandsParam, aFreeList.join(","));
1133
1134   myIsToolbarsModified = false;
1135 }
1136
1137 void SHAPERGUI::loadToolbarsConfig()
1138 {
1139   SUIT_ResourceMgr* aResMgr = application()->resourceMgr();
1140   QStringList aToolbarNames = aResMgr->parameters(ToolbarsSection);
1141   if (aToolbarNames.size() == 0)
1142     return;
1143
1144   // Create commands map
1145   QMap<QString, int> aCommandsMap;
1146   QString aCmdIdStr;
1147   foreach(int aId, myActionsList) {
1148     aCmdIdStr = action(aId)->data().toString();
1149     aCommandsMap[aCmdIdStr] = aId;
1150   }
1151
1152   // Create new toolbars structure
1153   QMap<QString, QIntList> aToolbars;
1154   QStringList aCommands;
1155   QIntList aKnownCommands;
1156   QList<QAction*> aActions;
1157   foreach(QString aName, aToolbarNames) {
1158     aCommands = aResMgr->stringValue(ToolbarsSection, aName).split(",");
1159     if (aName == FreeCommandsParam) {
1160       // The value is a list of free commands
1161       foreach(QString aCommand, aCommands) {
1162         aKnownCommands.append(aCommandsMap[aCommand]);
1163       }
1164     }
1165     else {
1166       aToolbars[aName] = QIntList();
1167       if (aCommands.size() > 0) {
1168         foreach(QString aCommand, aCommands) {
1169           if (aCommand.isEmpty())
1170             aToolbars[aName].append(-1);
1171           else if (aCommandsMap.contains(aCommand)) {
1172             int aId = aCommandsMap[aCommand];
1173             aToolbars[aName].append(aId);
1174             aKnownCommands.append(aId);
1175           }
1176         }
1177       }
1178     }
1179   }
1180   // Find new and obsolete commands
1181   QIntList aNewCommands = myActionsList;
1182   foreach(int aId, myActionsList) {
1183     if (aKnownCommands.contains(aId)) {
1184       aKnownCommands.removeAll(aId);
1185       aNewCommands.removeAll(aId);
1186     }
1187   }
1188   if (aNewCommands.size() > 0) {
1189     // Add new commands to toolbars structure
1190     QStringList aKeys = myToolbars.keys();
1191     foreach(int aNewId, aNewCommands) {
1192       foreach(QString aName, aKeys) {
1193         if (myToolbars[aName].contains(aNewId)) {
1194           if (!aToolbars.contains(aName)) {
1195             aToolbars[aName] = QIntList();
1196           }
1197           aToolbars[aName].append(aNewId);
1198         }
1199       }
1200     }
1201   }
1202   if (aKnownCommands.size() > 0) {
1203     // Remove obsolete commands from the toolbars structure
1204     QStringList aKeys = aToolbars.keys();
1205     foreach(int aOldId, aKnownCommands) {
1206       foreach(QString aName, aKeys) {
1207         if (aToolbars[aName].contains(aOldId)) {
1208           aToolbars[aName].removeAll(aOldId);
1209           if (aToolbars[aName].size() == 0)
1210             aToolbars.remove(aName);
1211         }
1212       }
1213     }
1214   }
1215   updateToolbars(aToolbars);
1216   myIsToolbarsModified = false;
1217 }
1218
1219
1220 QIntList SHAPERGUI::getFreeCommands() const
1221 {
1222   QIntList aFreeCommands;
1223   QtxActionToolMgr* aMgr = toolMgr();
1224   QAction* anAction;
1225   int aId;
1226   QMap<QString, QIntList>::const_iterator aIt;
1227   QIntList aShaperActions = shaperActions();
1228   foreach(int aCmd, aShaperActions) {
1229     anAction = action(aCmd);
1230     aId = aMgr->actionId(anAction);
1231     if (!aMgr->containsAction(aId))
1232       aFreeCommands.append(aCmd);
1233   }
1234   return aFreeCommands;
1235 }
1236
1237 void SHAPERGUI::resetToolbars()
1238 {
1239   if (!myDefaultToolbars.isEmpty())
1240     updateToolbars(myDefaultToolbars);
1241   myIsToolbarsModified = false;
1242   SUIT_ResourceMgr* aResMgr = application()->resourceMgr();
1243   aResMgr->remove(ToolbarsSection);
1244 }
1245
1246 void SHAPERGUI::publishToStudy()
1247 {
1248   if (isActiveModule() && ModelAPI_Session::get()->hasModuleDocument())
1249     myWorkshop->module()->launchOperation("PublishToStudy", false);
1250 }