Salome HOME
f5927a5efc51d44cac9c0efb6ce2ef8c596dc722
[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     // it should be pefromed after the selector creation in order to have AISContext 
163     myWorkshop->activateModule();
164     //action(myEraseAll)->setEnabled(false);
165
166     if (myIsOpened) {
167       myWorkshop->objectBrowser()->rebuildDataTree();
168       myWorkshop->updateCommandStatus();
169       myIsOpened = false;
170       // the display all results is not necessary anymore, it was commented in XGUI_Workshop,
171       // so it should be commented here
172       //QTimer::singleShot(1000, myWorkshop, SLOT(displayAllResults()));
173     }
174     else
175       myWorkshop->updateCommandStatus();
176   }
177   SUIT_ResourceMgr* aResMgr = application()->resourceMgr();
178   myIsStorePositions = aResMgr->booleanValue("Study", "store_positions", true);
179   myIsEditEnabled = getApp()->isEditEnabled();
180   getApp()->setEditEnabled(false);
181
182   // this following row is caused by #187 bug.
183   // SALOME saves the dock widget positions before deactivateModule() and
184   // load it after the module activation. So, if the panel is visible before
185   // deactivate, it becomes visible after activate.
186   // In order to avoid the visible property panel, the widget position save is
187   // switch off in this module
188   aResMgr->setValue("Study", "store_positions", false);
189
190   // Synchronize displayed objects
191   if (mySelector && mySelector->viewer()) {
192     Handle(AIS_InteractiveContext) aContext = mySelector->viewer()->getAISContext();
193     XGUI_Displayer* aDisp = myWorkshop->displayer();
194     QObjectPtrList aObjList = aDisp->displayedObjects();
195
196     AIS_ListOfInteractive aList;
197     aContext->DisplayedObjects(aList);
198     AIS_ListIteratorOfListOfInteractive aLIt;
199     Handle(AIS_InteractiveObject) anAISIO;
200     foreach (ObjectPtr aObj, aObjList) {
201       AISObjectPtr aPrs = aDisp->getAISObject(aObj);
202       Handle(AIS_InteractiveObject) aAIS = aPrs->impl<Handle(AIS_InteractiveObject)>();
203       bool aFound = false;
204       for (aLIt.Initialize(aList); aLIt.More(); aLIt.Next()) {
205         anAISIO = aLIt.Value();
206         if (anAISIO.Access() == aAIS.Access()) {
207           aFound = true;
208           break;
209         }
210       }
211       if (!aFound) {
212         aObj->setDisplayed(false);
213         //aDisp->erase(aObj, false);
214       }
215     }
216     Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
217   }
218
219   return isDone;
220 }
221
222 //******************************************************
223 bool NewGeom_Module::deactivateModule(SUIT_Study* theStudy)
224 {
225   setMenuShown(false);
226   setToolShown(false);
227
228   myWorkshop->deactivateModule();
229
230   QObject* aObj = myWorkshop->objectBrowser()->parent();
231   QDockWidget* aObjDoc = dynamic_cast<QDockWidget*>(aObj);
232   if (aObjDoc) {
233     aObjDoc->setVisible(false);
234     myWorkshop->objectBrowser()->setVisible(false);
235     QAction* aViewAct = aObjDoc->toggleViewAction();
236     aViewAct->setEnabled(false);
237   }
238
239   // the active operation should be stopped for the next activation.
240   // There should not be active operation and visualized preview.
241   // Abort operation should be performed before the selection's remove
242   // because the displayed objects should be removed from the viewer, but
243   // the AIS context is obtained from the selector.
244   ModuleBase_Operation* anOperation = myWorkshop->operationMgr()->currentOperation();
245   while (anOperation) {
246     anOperation->abort();
247     anOperation = myWorkshop->operationMgr()->currentOperation();
248   }
249   // Delete selector because it has to be redefined on next activation
250   if (mySelector) {
251     myProxyViewer->setSelector(0);
252     delete mySelector;
253     mySelector = 0;
254   }
255
256   //myWorkshop->contextMenuMgr()->disconnectViewer();
257
258   SUIT_ResourceMgr* aResMgr = application()->resourceMgr();
259   aResMgr->setValue("Study", "store_positions", myIsStorePositions);
260   getApp()->setEditEnabled(myIsEditEnabled);
261
262   return LightApp_Module::deactivateModule(theStudy);
263 }
264
265 //******************************************************
266 void NewGeom_Module::onViewManagerAdded(SUIT_ViewManager* theMgr)
267 {
268   if (!mySelector) {
269     mySelector = createSelector(theMgr);
270   }
271 }
272
273 //******************************************************
274 void NewGeom_Module::onViewManagerRemoved(SUIT_ViewManager* theMgr)
275 {
276   if (mySelector) {
277     if (theMgr->getType() == OCCViewer_Viewer::Type()) {
278       OCCViewer_Viewer* aViewer = static_cast<OCCViewer_Viewer*>(theMgr->getViewModel());
279       if (mySelector->viewer() == aViewer) {
280         XGUI_Displayer* aDisp = myWorkshop->displayer();
281         QObjectPtrList aObjects = aDisp->displayedObjects();
282         foreach(ObjectPtr aObj, aObjects)
283           aObj->setDisplayed(false);
284         Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
285         myProxyViewer->setSelector(0);
286         delete mySelector;
287         mySelector = 0;
288       }
289     }
290   }
291 }
292
293 //******************************************************
294 QtxPopupMgr* NewGeom_Module::popupMgr()
295 {
296   if (!myPopupMgr)
297     myPopupMgr = new QtxPopupMgr( 0, this );
298   return myPopupMgr;
299 }
300
301 //******************************************************
302 void NewGeom_Module::onDefaultPreferences()
303 {
304   ModuleBase_Preferences::resetConfig();
305   ModuleBase_Preferences::updateResourcesByConfig();
306
307   LightApp_Preferences* pref = preferences();
308   if (pref)
309     pref->retrieve();
310 }
311
312 //******************************************************
313 void NewGeom_Module::onUpdateCommandStatus()
314 {
315   getApp()->updateActions();
316 }
317
318 //******************************************************
319 NewGeom_OCCSelector* NewGeom_Module::createSelector(SUIT_ViewManager* theMgr)
320 {
321   if (theMgr->getType() == OCCViewer_Viewer::Type()) {
322     OCCViewer_Viewer* aViewer = static_cast<OCCViewer_Viewer*>(theMgr->getViewModel());
323     NewGeom_OCCSelector* aSelector = new NewGeom_OCCSelector(aViewer, getApp()->selectionMgr());
324     LightApp_SelectionMgr* aMgr = getApp()->selectionMgr();
325     QList<SUIT_Selector*> aList;
326     aMgr->selectors(aList);
327     foreach(SUIT_Selector* aSel, aList)
328     {
329       aSel->setEnabled(aSel == aSelector);
330     }
331     myProxyViewer->setSelector(aSelector);
332     return aSelector;
333   }
334   return 0;
335 }
336
337 //******************************************************
338 CAM_DataModel* NewGeom_Module::createDataModel()
339 {
340   NewGeom_DataModel* aDataModel = new NewGeom_DataModel(this);
341
342   // Calling addComponent() for persistent functionality work in the SalomeApp_Study
343   LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>(application()->activeStudy() );
344   aStudy->addComponent(aDataModel);
345
346   return aDataModel;
347 }
348
349 QAction* NewGeom_Module::addFeature(const QString& theWBName, const ActionInfo& theInfo)
350 {
351   return addFeature(theWBName,
352                     theInfo.id,
353                     theInfo.text,
354                     theInfo.toolTip,
355                     theInfo.icon,
356                     theInfo.shortcut,
357                     theInfo.checkable);
358 }
359
360 //******************************************************
361 QAction* NewGeom_Module::addFeature(const QString& theWBName, const QString& theId,
362                                     const QString& theTitle, const QString& theTip,
363                                     const QIcon& theIcon, const QKeySequence& theKeys,
364                                     bool isCheckable)
365 {
366   int aMenu = createMenu(theWBName, -1, -1, 50);
367   int aTool = createTool(theWBName);
368
369   int aId = myActionsList.size();
370   myActionsList.append(theId);
371   SUIT_Desktop* aDesk = application()->desktop();
372   int aKeys = 0;
373   for (unsigned int i = 0; i < theKeys.count(); i++)
374     aKeys += theKeys[i];
375   QAction* aAction = createAction(aId, theTip, theIcon, theTitle, theTip, aKeys, aDesk,
376                                   isCheckable);
377   aAction->setData(theId);
378   int aItemId = createMenu(aId, aMenu, -1, 10);
379   int aToolId = createTool(aId, aTool);
380
381   return aAction;
382 }
383
384
385 QAction* NewGeom_Module::addNestedFeature(const QString& theWBName,
386                                           const ActionInfo& theInfo,
387                                           const QList<QAction*>& theNestedActions)
388 {
389   int aMenu = createMenu(theWBName, -1, -1, 50);
390   int aTool = createTool(theWBName);
391
392   int aId = myActionsList.size();
393   myActionsList.append(theInfo.id);
394   SUIT_Desktop* aDesk = application()->desktop();
395   NewGeom_NestedButton* anAction = new NewGeom_NestedButton(aDesk, theNestedActions);
396   anAction->setData(theInfo.id);
397   anAction->setCheckable(theInfo.checkable);
398   anAction->setChecked(theInfo.checked);
399   anAction->setEnabled(theInfo.enabled);
400   anAction->setVisible(theInfo.visible);
401   anAction->setIcon(theInfo.icon);
402   anAction->setText(theInfo.text);
403   anAction->setToolTip(theInfo.toolTip);
404   anAction->setShortcut(theInfo.shortcut);
405   anAction->setFont(theInfo.font);
406
407   //int aItemId = createMenu(aId, aMenu, -1, 10);
408   int aToolId = createTool(anAction, aTool, aId);
409
410   return anAction;
411 }
412
413
414 //******************************************************
415 QAction* NewGeom_Module::addDesktopCommand(const QString& theId, const QString& theTitle,
416                                            const QString& theTip, const QIcon& theIcon,
417                                            const QKeySequence& theKeys, bool isCheckable,
418                                            const char* theMenuSourceText, const int theMenuPosition)
419 {
420   int aMenu = createMenu(tr(theMenuSourceText), -1, -1);
421
422   int aId = myActionsList.size();
423   myActionsList.append(theId);
424   SUIT_Desktop* aDesk = application()->desktop();
425   int aKeys = 0;
426   for (unsigned int i = 0; i < theKeys.count(); i++)
427     aKeys += theKeys[i];
428   QAction* aAction = createAction(aId, theTip, theIcon, theTitle, theTip, aKeys, aDesk,
429                                   isCheckable);
430   aAction->setData(theId);
431   createMenu(aId, aMenu, theMenuPosition);
432   return aAction;
433 }
434
435 //******************************************************
436 void NewGeom_Module::addDesktopMenuSeparator(const char* theMenuSourceText, const int theMenuPosition)
437 {
438   int aMenu = createMenu(tr(theMenuSourceText), -1, -1);
439   createMenu(separator(), aMenu, -1, theMenuPosition);
440 }
441
442 //******************************************************
443 QList<QAction*> NewGeom_Module::commandList() const
444 {
445   QList<QAction*> aActions;
446   for (int i = 0; i < myActionsList.size(); i++)
447     aActions.append(action(i));
448   return aActions;
449 }
450
451 //******************************************************
452 QStringList NewGeom_Module::commandIdList() const
453 {
454   return myActionsList;
455 }
456
457 //******************************************************
458 QMainWindow* NewGeom_Module::desktop() const
459 {
460   return application()->desktop();
461 }
462
463 //******************************************************
464 QString NewGeom_Module::commandId(const QAction* theCmd) const
465 {
466   int aId = actionId(theCmd);
467   if (aId < myActionsList.size())
468     return myActionsList[aId];
469   return QString();
470 }
471
472 //******************************************************
473 QAction* NewGeom_Module::command(const QString& theId) const
474 {
475   int aId = myActionsList.indexOf(theId);
476   if ((aId != -1) && (aId < myActionsList.size())) {
477     return action(aId);
478   }
479   return 0;
480 }
481
482 //******************************************************
483 void NewGeom_Module::setNestedActions(const QString& theId, const QStringList& theActions)
484 {
485   myNestedActions[theId] = theActions;
486 }
487
488 //******************************************************
489 QStringList NewGeom_Module::nestedActions(const QString& theId) const
490 {
491   if (myNestedActions.contains(theId))
492     return myNestedActions[theId];
493   return QStringList();
494 }
495
496 //******************************************************
497 void NewGeom_Module::setDocumentKind(const QString& theId, const QString& theKind)
498 {
499   myDocumentType[theId] = theKind;
500 }
501
502 //******************************************************
503 QString NewGeom_Module::documentKind(const QString& theId) const
504 {
505   if (myDocumentType.contains(theId))
506     return myDocumentType[theId];
507   return QString();
508
509 }
510
511 //******************************************************
512 void NewGeom_Module::selectionChanged()
513 {
514   LightApp_Module::selectionChanged();
515   myWorkshop->salomeViewerSelectionChanged();
516 }
517
518 //******************************************************
519 void NewGeom_Module::contextMenuPopup(const QString& theClient, QMenu* theMenu, QString& theTitle)
520 {
521   myWorkshop->contextMenuMgr()->addViewerMenu(theMenu);
522   LightApp_Module::contextMenuPopup(theClient, theMenu, theTitle);
523 }
524
525
526 //******************************************************
527 void NewGeom_Module::createPreferences()
528 {
529   LightApp_Preferences* pref = preferences();
530   if (!pref)
531     return;
532   ModuleBase_Preferences::updateConfigByResources();
533   QString aModName = moduleName();
534
535   QtxPreferenceItem* item = pref->findItem(aModName, true );
536   if ( item && (!item->isEmpty() )) {
537     item->parentItem()->removeItem(item);
538     delete item;
539   }
540
541   int catId = pref->addPreference(aModName, -1 );
542   if ( catId == -1 )
543     return;
544   NewGeom_PrefMgr aMgr(pref, aModName);
545   ModuleBase_Preferences::createEditContent(&aMgr, catId);
546   pref->retrieve();
547 }
548
549 //******************************************************
550 void NewGeom_Module::preferencesChanged(const QString& theSection, const QString& theParam)
551 {
552   SUIT_ResourceMgr* aResMgr = application()->resourceMgr();
553   QString aVal = aResMgr->stringValue(theSection, theParam);
554   Config_Prop* aProp = Config_PropManager::findProp(theSection.toStdString(), theParam.toStdString());
555   std::string aValue = aVal.toStdString();
556   if (aValue.empty()) {
557     aValue = aProp->defaultValue();
558     aResMgr->setValue(theSection, theParam, QString(aValue.c_str()));
559
560     LightApp_Preferences* pref = preferences();
561     if (pref)
562       pref->retrieve();
563   }
564   aProp->setValue(aValue);
565
566 }
567
568 void NewGeom_Module::inspectSalomeModules()
569 {
570   QStringList aModuleNames;
571   getApp()->modules(aModuleNames, false);
572   foreach(QString eachModule, aModuleNames) {
573     Config_ModuleReader::addDependencyModule(eachModule.toStdString());
574   }
575 }