Salome HOME
a569af01598bb1939a8d8caf16033dc602fbc2cd
[modules/shaper.git] / src / NewGeom / NewGeom_Module.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
2
3
4 #include "NewGeom_Module.h"
5 #include "NewGeom_DataModel.h"
6 #include "NewGeom_OCCSelector.h"
7
8 #include <XGUI_Workshop.h>
9 #include <XGUI_PropertyPanel.h>
10 #include <XGUI_ContextMenuMgr.h>
11 #include <XGUI_ObjectsBrowser.h>
12 #include <XGUI_OperationMgr.h>
13 #include <XGUI_Displayer.h>
14
15 #include <ModuleBase_Operation.h>
16 #include <ModuleBase_Preferences.h>
17
18 #include <LightApp_Application.h>
19 #include <LightApp_SelectionMgr.h>
20 #include <LightApp_OCCSelector.h>
21 #include <LightApp_Study.h>
22 #include <OCCViewer_ViewModel.h>
23
24 #include <SUIT_Selector.h>
25 #include <SUIT_Desktop.h>
26 #include <SUIT_ViewManager.h>
27 #include <SUIT_ResourceMgr.h>
28
29 #include <QtxPopupMgr.h>
30 #include <QtxActionMenuMgr.h>
31 #include <QtxResourceMgr.h>
32
33 #include <Config_PropManager.h>
34 #include <Config_ModuleReader.h>
35
36 #include <AIS_ListOfInteractive.hxx>
37 #include <AIS_ListIteratorOfListOfInteractive.hxx>
38
39 #include <QDockWidget>
40 #include <QAction>
41 #include <QTimer>
42
43
44 extern "C" {
45 NewGeom_EXPORT CAM_Module* createModule()
46 {
47   return new NewGeom_Module();
48 }
49
50 NewGeom_EXPORT char* getModuleVersion()
51 {
52   return "0.0";
53 }
54 }
55
56 /** 
57 * Class for preferences management
58 */
59 class NewGeom_PrefMgr: public ModuleBase_IPrefMgr
60 {
61 public:
62   /// Constructor
63   /// \param theMgr preferences manager of SALOME
64   /// \param theModName name of the module
65   NewGeom_PrefMgr(LightApp_Preferences* theMgr, const QString& theModName):myMgr(theMgr), myModName(theModName) {}
66
67   virtual int addPreference(const QString& theLbl, int pId, 
68                             SUIT_PreferenceMgr::PrefItemType theType,
69                             const QString& theSection, const QString& theName )
70   {
71     return myMgr->addPreference(myModName, theLbl, pId, theType, theSection, theName);
72   }
73
74   virtual void setItemProperty(const QString& thePropName,
75                                const QVariant& theValue,
76                                const int theId = -1)
77   {
78     myMgr->setItemProperty(thePropName, theValue, theId);
79   }
80
81
82   virtual SUIT_PreferenceMgr* prefMgr() const { return myMgr; }
83
84 private:
85   LightApp_Preferences* myMgr;
86   QString myModName;
87 };
88
89
90
91
92 //******************************************************
93 NewGeom_Module::NewGeom_Module()
94     : LightApp_Module("NewGeom"),
95       mySelector(0), myIsOpened(0), myPopupMgr(0)
96 {
97   myWorkshop = new XGUI_Workshop(this);
98   connect(myWorkshop, SIGNAL(commandStatusUpdated()),
99           this, SLOT(onUpdateCommandStatus()));
100
101   myProxyViewer = new NewGeom_SalomeViewer(this);
102
103   ModuleBase_Preferences::setResourceMgr(application()->resourceMgr());
104   ModuleBase_Preferences::loadCustomProps();
105 }
106
107 //******************************************************
108 NewGeom_Module::~NewGeom_Module()
109 {
110 }
111
112 //******************************************************
113 void NewGeom_Module::initialize(CAM_Application* theApp)
114 {
115   LightApp_Module::initialize(theApp);
116   inspectSalomeModules();
117
118   myWorkshop->startApplication();
119   LightApp_Application* anApp = dynamic_cast<LightApp_Application*>(theApp);
120   if (anApp)
121     connect(anApp, SIGNAL(preferenceResetToDefaults()), this, SLOT(onDefaultPreferences()));
122 }
123
124 //******************************************************
125 void NewGeom_Module::windows(QMap<int, int>& theWndMap) const
126 {
127   theWndMap.insert(LightApp_Application::WT_PyConsole, Qt::BottomDockWidgetArea);
128 }
129
130 //******************************************************
131 void NewGeom_Module::viewManagers(QStringList& theList) const
132 {
133   theList.append(OCCViewer_Viewer::Type());
134 }
135
136 //******************************************************
137 bool NewGeom_Module::activateModule(SUIT_Study* theStudy)
138 {
139   bool isDone = LightApp_Module::activateModule(theStudy);
140   if (isDone) {
141     setMenuShown(true);
142     setToolShown(true);
143
144     QObject* aObj = myWorkshop->objectBrowser()->parent();
145     QDockWidget* aObjDoc = dynamic_cast<QDockWidget*>(aObj);
146     if (aObjDoc) {
147       QAction* aViewAct = aObjDoc->toggleViewAction();
148       aViewAct->setEnabled(true);
149       myWorkshop->objectBrowser()->setVisible(true);
150       aObjDoc->setVisible(true);
151     }
152
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     //action(myEraseAll)->setEnabled(false);
161
162     if (myIsOpened) {
163       myWorkshop->objectBrowser()->rebuildDataTree();
164       myWorkshop->updateCommandStatus();
165       myIsOpened = false;
166       QTimer::singleShot(1000, myWorkshop, SLOT(displayAllResults()));
167     }
168     else
169       myWorkshop->updateCommandStatus();
170   }
171   SUIT_ResourceMgr* aResMgr = application()->resourceMgr();
172   myIsStorePositions = aResMgr->booleanValue("Study", "store_positions", true);
173   myIsEditEnabled = getApp()->isEditEnabled();
174   getApp()->setEditEnabled(false);
175
176   // this following row is caused by #187 bug.
177   // SALOME saves the dock widget positions before deactivateModule() and
178   // load it after the module activation. So, if the panel is visible before
179   // deactivate, it becomes visible after activate.
180   // In order to avoid the visible property panel, the widget position save is
181   // switch off in this module
182   aResMgr->setValue("Study", "store_positions", false);
183
184   // Synchronize displayed objects
185   if (mySelector && mySelector->viewer()) {
186     Handle(AIS_InteractiveContext) aContext = mySelector->viewer()->getAISContext();
187     XGUI_Displayer* aDisp = myWorkshop->displayer();
188     QObjectPtrList aObjList = aDisp->displayedObjects();
189
190     AIS_ListOfInteractive aList;
191     aContext->DisplayedObjects(aList);
192     AIS_ListIteratorOfListOfInteractive aLIt;
193     Handle(AIS_InteractiveObject) anAISIO;
194     foreach (ObjectPtr aObj, aObjList) {
195       AISObjectPtr aPrs = aDisp->getAISObject(aObj);
196       Handle(AIS_InteractiveObject) aAIS = aPrs->impl<Handle(AIS_InteractiveObject)>();
197       bool aFound = false;
198       for (aLIt.Initialize(aList); aLIt.More(); aLIt.Next()) {
199         anAISIO = aLIt.Value();
200         if (anAISIO.Access() == aAIS.Access()) {
201           aFound = true;
202           break;
203         }
204       }
205       if (!aFound) {
206         aDisp->erase(aObj, false);
207       }
208     }
209   }
210
211   return isDone;
212 }
213
214 //******************************************************
215 bool NewGeom_Module::deactivateModule(SUIT_Study* theStudy)
216 {
217   setMenuShown(false);
218   setToolShown(false);
219
220   QObject* aObj = myWorkshop->objectBrowser()->parent();
221   QDockWidget* aObjDoc = dynamic_cast<QDockWidget*>(aObj);
222   if (aObjDoc) {
223     aObjDoc->setVisible(false);
224     myWorkshop->objectBrowser()->setVisible(false);
225     QAction* aViewAct = aObjDoc->toggleViewAction();
226     aViewAct->setEnabled(false);
227   }
228
229   // the active operation should be stopped for the next activation.
230   // There should not be active operation and visualized preview.
231   // Abort operation should be performed before the selection's remove
232   // because the displayed objects should be removed from the viewer, but
233   // the AIS context is obtained from the selector.
234   ModuleBase_Operation* anOperation = myWorkshop->operationMgr()->currentOperation();
235   while (anOperation) {
236     anOperation->abort();
237     anOperation = myWorkshop->operationMgr()->currentOperation();
238   }
239   // Delete selector because it has to be redefined on next activation
240   if (mySelector) {
241     myProxyViewer->setSelector(0);
242     delete mySelector;
243     mySelector = 0;
244   }
245
246   //myWorkshop->contextMenuMgr()->disconnectViewer();
247
248   SUIT_ResourceMgr* aResMgr = application()->resourceMgr();
249   aResMgr->setValue("Study", "store_positions", myIsStorePositions);
250   getApp()->setEditEnabled(myIsEditEnabled);
251
252   return LightApp_Module::deactivateModule(theStudy);
253 }
254
255 //******************************************************
256 void NewGeom_Module::onViewManagerAdded(SUIT_ViewManager* theMgr)
257 {
258   if (!mySelector) {
259     mySelector = createSelector(theMgr);
260   }
261 }
262
263 //******************************************************
264 void NewGeom_Module::onViewManagerRemoved(SUIT_ViewManager* theMgr)
265 {
266   if (mySelector) {
267     if (theMgr->getType() == OCCViewer_Viewer::Type()) {
268       OCCViewer_Viewer* aViewer = static_cast<OCCViewer_Viewer*>(theMgr->getViewModel());
269       if (mySelector->viewer() == aViewer) {
270         myWorkshop->displayer()->eraseAll(false);
271         myProxyViewer->setSelector(0);
272         delete mySelector;
273         mySelector = 0;
274       }
275     }
276   }
277 }
278
279 //******************************************************
280 QtxPopupMgr* NewGeom_Module::popupMgr()
281 {
282   if (!myPopupMgr)
283     myPopupMgr = new QtxPopupMgr( 0, this );
284   return myPopupMgr;
285 }
286
287 //******************************************************
288 void NewGeom_Module::onDefaultPreferences()
289 {
290   ModuleBase_Preferences::resetConfig();
291   ModuleBase_Preferences::updateResourcesByConfig();
292
293   LightApp_Preferences* pref = preferences();
294   if (pref)
295     pref->retrieve();
296 }
297
298 //******************************************************
299 void NewGeom_Module::onUpdateCommandStatus()
300 {
301   getApp()->updateActions();
302 }
303
304 //******************************************************
305 NewGeom_OCCSelector* NewGeom_Module::createSelector(SUIT_ViewManager* theMgr)
306 {
307   if (theMgr->getType() == OCCViewer_Viewer::Type()) {
308     OCCViewer_Viewer* aViewer = static_cast<OCCViewer_Viewer*>(theMgr->getViewModel());
309     NewGeom_OCCSelector* aSelector = new NewGeom_OCCSelector(aViewer, getApp()->selectionMgr());
310     LightApp_SelectionMgr* aMgr = getApp()->selectionMgr();
311     QList<SUIT_Selector*> aList;
312     aMgr->selectors(aList);
313     foreach(SUIT_Selector* aSel, aList)
314     {
315       aSel->setEnabled(aSel == aSelector);
316     }
317     myProxyViewer->setSelector(aSelector);
318     return aSelector;
319   }
320   return 0;
321 }
322
323 //******************************************************
324 CAM_DataModel* NewGeom_Module::createDataModel()
325 {
326   NewGeom_DataModel* aDataModel = new NewGeom_DataModel(this);
327
328   // Calling addComponent() for persistent functionality work in the SalomeApp_Study
329   LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>(application()->activeStudy() );
330   aStudy->addComponent(aDataModel);
331
332   return aDataModel;
333 }
334
335 //******************************************************
336 QAction* NewGeom_Module::addFeature(const QString& theWBName, const QString& theId,
337                                     const QString& theTitle, const QString& theTip,
338                                     const QIcon& theIcon, const QKeySequence& theKeys,
339                                     bool isCheckable)
340 {
341   int aMenu = createMenu(theWBName, -1, -1, 50);
342   int aTool = createTool(theWBName);
343
344   int aId = myActionsList.size();
345   myActionsList.append(theId);
346   SUIT_Desktop* aDesk = application()->desktop();
347   int aKeys = 0;
348   for (unsigned int i = 0; i < theKeys.count(); i++)
349     aKeys += theKeys[i];
350   QAction* aAction = createAction(aId, theTip, theIcon, theTitle, theTip, aKeys, aDesk,
351                                   isCheckable);
352   aAction->setData(theId);
353   int aItemId = createMenu(aId, aMenu, -1, 10);
354   int aToolId = createTool(aId, aTool);
355   return aAction;
356 }
357
358 QAction* NewGeom_Module::addFeature(const QString& theWBName, const ActionInfo& theInfo)
359 {
360   return addFeature(theWBName,
361                     theInfo.id,
362                     theInfo.text,
363                     theInfo.toolTip,
364                     theInfo.icon,
365                     theInfo.shortcut);
366 }
367
368
369 //******************************************************
370 QAction* NewGeom_Module::addDesktopCommand(const QString& theId, const QString& theTitle,
371                                            const QString& theTip, const QIcon& theIcon,
372                                            const QKeySequence& theKeys, bool isCheckable,
373                                            const char* theMenuSourceText, const int theMenuPosition)
374 {
375   int aMenu = createMenu(tr(theMenuSourceText), -1, -1);
376
377   int aId = myActionsList.size();
378   myActionsList.append(theId);
379   SUIT_Desktop* aDesk = application()->desktop();
380   int aKeys = 0;
381   for (unsigned int i = 0; i < theKeys.count(); i++)
382     aKeys += theKeys[i];
383   QAction* aAction = createAction(aId, theTip, theIcon, theTitle, theTip, aKeys, aDesk,
384                                   isCheckable);
385   aAction->setData(theId);
386   createMenu(aId, aMenu, theMenuPosition);
387   return aAction;
388 }
389
390 //******************************************************
391 void NewGeom_Module::addDesktopMenuSeparator(const char* theMenuSourceText, const int theMenuPosition)
392 {
393   int aMenu = createMenu(tr(theMenuSourceText), -1, -1);
394   createMenu(separator(), aMenu, -1, theMenuPosition);
395 }
396
397 //******************************************************
398 QList<QAction*> NewGeom_Module::commandList() const
399 {
400   QList<QAction*> aActions;
401   for (int i = 0; i < myActionsList.size(); i++)
402     aActions.append(action(i));
403   return aActions;
404 }
405
406 //******************************************************
407 QStringList NewGeom_Module::commandIdList() const
408 {
409   return myActionsList;
410 }
411
412 //******************************************************
413 QMainWindow* NewGeom_Module::desktop() const
414 {
415   return application()->desktop();
416 }
417
418 //******************************************************
419 QString NewGeom_Module::commandId(const QAction* theCmd) const
420 {
421   int aId = actionId(theCmd);
422   if (aId < myActionsList.size())
423     return myActionsList[aId];
424   return QString();
425 }
426
427 //******************************************************
428 QAction* NewGeom_Module::command(const QString& theId) const
429 {
430   int aId = myActionsList.indexOf(theId);
431   if ((aId != -1) && (aId < myActionsList.size())) {
432     return action(aId);
433   }
434   return 0;
435 }
436
437 //******************************************************
438 void NewGeom_Module::setNestedActions(const QString& theId, const QStringList& theActions)
439 {
440   myNestedActions[theId] = theActions;
441 }
442
443 //******************************************************
444 QStringList NewGeom_Module::nestedActions(const QString& theId) const
445 {
446   if (myNestedActions.contains(theId))
447     return myNestedActions[theId];
448   return QStringList();
449 }
450
451 //******************************************************
452 void NewGeom_Module::setDocumentKind(const QString& theId, const QString& theKind)
453 {
454   myDocumentType[theId] = theKind;
455 }
456
457 //******************************************************
458 QString NewGeom_Module::documentKind(const QString& theId) const
459 {
460   if (myDocumentType.contains(theId))
461     return myDocumentType[theId];
462   return QString();
463
464 }
465
466 //******************************************************
467 void NewGeom_Module::selectionChanged()
468 {
469   LightApp_Module::selectionChanged();
470   myWorkshop->salomeViewerSelectionChanged();
471 }
472
473 //******************************************************
474 void NewGeom_Module::contextMenuPopup(const QString& theClient, QMenu* theMenu, QString& theTitle)
475 {
476   myWorkshop->contextMenuMgr()->addViewerItems(theMenu);
477   LightApp_Module::contextMenuPopup(theClient, theMenu, theTitle);
478 }
479
480
481 //******************************************************
482 void NewGeom_Module::createPreferences()
483 {
484   LightApp_Preferences* pref = preferences();
485   if (!pref)
486     return;
487   ModuleBase_Preferences::updateConfigByResources();
488   QString aModName = moduleName();
489
490   QtxPreferenceItem* item = pref->findItem(aModName, true );
491   if ( item && (!item->isEmpty() )) {
492     item->parentItem()->removeItem(item);
493     delete item;
494   }
495
496   int catId = pref->addPreference(aModName, -1 );
497   if ( catId == -1 )
498     return;
499   NewGeom_PrefMgr aMgr(pref, aModName);
500   ModuleBase_Preferences::createEditContent(&aMgr, catId);
501   pref->retrieve();
502 }
503
504 //******************************************************
505 void NewGeom_Module::preferencesChanged(const QString& theSection, const QString& theParam)
506 {
507   SUIT_ResourceMgr* aResMgr = application()->resourceMgr();
508   QString aVal = aResMgr->stringValue(theSection, theParam);
509   Config_Prop* aProp = Config_PropManager::findProp(theSection.toStdString(), theParam.toStdString());
510   std::string aValue = aVal.toStdString();
511   if (aValue.empty()) {
512     aValue = aProp->defaultValue();
513     aResMgr->setValue(theSection, theParam, QString(aValue.c_str()));
514
515     LightApp_Preferences* pref = preferences();
516     if (pref)
517       pref->retrieve();
518   }
519   aProp->setValue(aValue);
520
521 }
522
523 void NewGeom_Module::inspectSalomeModules()
524 {
525   QStringList aModuleNames;
526   getApp()->modules(aModuleNames, false);
527   foreach(QString eachModule, aModuleNames) {
528     Config_ModuleReader::addDependencyModule(eachModule.toStdString());
529   }
530 }