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