Salome HOME
9d040d07cbea2538c3420c70e07a73e4adcedecf
[modules/yacs.git] / src / salomegui / Yacsgui.cxx
1 // Copyright (C) 2006-2015  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 <Python.h>
21 #include "YACSExport.hxx"
22 #include "Yacsgui.hxx"
23 #include "Yacsgui_DataModel.hxx"
24 #include "Yacsgui_Resource.hxx"
25
26 #include <SUIT_MessageBox.h>
27 #include <SUIT_ResourceMgr.h>
28 #include <SUIT_Desktop.h>
29 #include <SUIT_ViewManager.h>
30 #include <SUIT_ViewWindow.h>
31 #include <SalomeApp_Application.h>
32 #include <SalomeApp_Engine_i.h>
33 #include <QxScene_ViewManager.h>
34 #include <QxScene_ViewModel.h>
35 #include <QxScene_ViewWindow.h>
36
37 #include <SalomeApp_DataObject.h>
38 #include <SalomeApp_Study.h>
39 #include <SalomeApp_Module.h>
40 #include <SUIT_DataBrowser.h>
41 #include <QtxTreeView.h>
42 #include <SUIT_DataObject.h>
43
44 #include <SALOME_LifeCycleCORBA.hxx>
45 #include <QInputDialog>
46 #include <QIcon>
47 #include <cassert>
48
49 #include "GenericGui.hxx"
50 #include "CatalogWidget.hxx"
51 #include "Resource.hxx"
52 #include "QtGuiContext.hxx"
53
54 //#define _DEVDEBUG_
55 #include "YacsTrace.hxx"
56
57 using namespace std;
58 using namespace YACS::HMI;
59
60 int  Yacsgui::_oldStudyId = -1;
61
62 Yacsgui::Yacsgui() :
63   SalomeWrap_Module( "YACS" ) // default name
64 {
65   DEBTRACE("Yacsgui::Yacsgui");
66   _wrapper = 0;
67   _genericGui = 0;
68   _selectFromTree = false;
69   _studyContextMap.clear();
70 }
71
72 Yacsgui::~Yacsgui()
73 {
74   if ( getApp() )
75     disconnect( getApp(), SIGNAL(studyClosed()), this, SLOT  (onCleanOnExit()));
76   delete _wrapper;
77   delete _genericGui;
78 }
79
80 void Yacsgui::initialize( CAM_Application* app )
81 {
82   DEBTRACE("Yacsgui::initialize");
83   _currentSVW = 0;
84   SalomeApp_Module::initialize( app );
85
86   QWidget* aParent = application()->desktop();
87   DEBTRACE(app << "  " << application() << " " << application()->desktop() << " " << aParent);
88
89   SUIT_ResourceMgr* aResourceMgr = app->resourceMgr();
90   setResource(aResourceMgr);
91
92   _wrapper = new SuitWrapper(this);
93   _genericGui = new GenericGui(_wrapper, app->desktop());
94
95   if ( app && app->desktop() )
96     {
97       connect( app->desktop(), SIGNAL( windowActivated( SUIT_ViewWindow* ) ),
98                this, SLOT(onWindowActivated( SUIT_ViewWindow* )) );
99
100       connect( getApp()->objectBrowser()->treeView(),
101                SIGNAL( doubleClicked(const QModelIndex&) ), 
102                this,
103                SLOT  ( onDblClick(const QModelIndex&) ) );
104
105       connect( getApp(),
106                SIGNAL(studyClosed()),
107                this,
108                SLOT  (onCleanOnExit()));
109     }
110   _genericGui->createActions();
111   _genericGui->createMenus();
112   _genericGui->createTools();
113   this->studyActivated();
114
115   // VSR 23/10/2014: note that this is not a good way to create SComponent from this point
116   // as initialize() method can be potentially called when there's no yet open study;
117   // this is better to do in activateModule()
118   SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( app->activeStudy() );
119   if ( aStudy ) {
120     bool aLocked = (_PTR(AttributeStudyProperties)(aStudy->studyDS()->GetProperties()))->IsLocked();
121     if ( aLocked ) {
122       SUIT_MessageBox::warning ( app->desktop(), QObject::tr("WRN_WARNING"), QObject::tr("WRN_STUDY_LOCKED") );
123     }
124     else  {
125       if (createSComponent()) updateObjBrowser();
126     }
127   }
128
129   // Load SALOME module catalogs
130   QStringList appModules;
131   app->modules(appModules,false);
132   for ( QStringList::const_iterator it = appModules.begin(); it != appModules.end(); ++it )
133     {
134       QString aModule=*it;
135       QString modName = app->moduleName( aModule );                    // module name
136       if ( modName.isEmpty() ) modName = aModule;             
137       QString rootDir = QString( "%1_ROOT_DIR" ).arg( modName );       // module root dir variable
138       QString modDir  = getenv( rootDir.toLatin1().constData() );      // module root dir
139       if ( !modDir.isEmpty() ) 
140         {
141           QStringList cataLst = QStringList() << modDir << "share" << "salome" << "resources" << modName.toLower() << modName+"SchemaCatalog.xml";
142           QString cataFile = cataLst.join( QDir::separator() );          // YACS module catalog
143           if ( QFile::exists( cataFile ) ) 
144             _genericGui->getCatalogWidget()->addCatalogFromFile(cataFile.toStdString());
145         }
146     }
147 }
148
149 void Yacsgui::viewManagers( QStringList& list ) const
150 {
151   DEBTRACE("Yacsgui::viewManagers");
152   list.append( QxScene_Viewer::Type() );
153 }
154
155 bool Yacsgui::activateModule( SUIT_Study* theStudy )
156 {
157   DEBTRACE("Yacsgui::activateModule");
158   bool bOk = SalomeApp_Module::activateModule( theStudy );
159
160   QMainWindow* parent = application()->desktop();
161   if(Resource::dockWidgetPriority)
162     {
163       parent->setCorner(Qt::TopLeftCorner, Qt::LeftDockWidgetArea);
164       parent->setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea);
165       parent->setCorner(Qt::TopRightCorner, Qt::RightDockWidgetArea);
166       parent->setCorner(Qt::BottomRightCorner, Qt::RightDockWidgetArea);
167     }
168   setMenuShown( true );
169   setToolShown( true );
170   _genericGui->showDockWidgets(true);
171
172   // import Python module that manages YACS plugins (need to be here because SalomePyQt API uses active module)
173   PyGILState_STATE gstate = PyGILState_Ensure();
174   PyObject* pluginsmanager=PyImport_ImportModule((char*)"salome_pluginsmanager");
175   if(pluginsmanager==NULL)
176     PyErr_Print();
177   else
178     {
179       PyObject* result=PyObject_CallMethod( pluginsmanager, (char*)"initialize", (char*)"isss",1,"yacs","YACS",tr("YACS_PLUGINS").toStdString().c_str());
180       if(result==NULL)
181         PyErr_Print();
182       Py_XDECREF(result);
183     }
184   Py_XDECREF(pluginsmanager);
185
186   PyGILState_Release(gstate);
187   // end of YACS plugins loading
188
189   if (_currentSVW)
190     onWindowActivated(_currentSVW);
191
192   return bOk;
193 }
194
195 bool Yacsgui::deactivateModule( SUIT_Study* theStudy )
196 {
197   DEBTRACE("Yacsgui::deactivateModule");
198
199   QMainWindow* parent = application()->desktop();
200   parent->setCorner(Qt::TopLeftCorner, Qt::TopDockWidgetArea);
201   parent->setCorner(Qt::BottomLeftCorner, Qt::BottomDockWidgetArea);
202   parent->setCorner(Qt::TopRightCorner, Qt::TopDockWidgetArea);
203   parent->setCorner(Qt::BottomRightCorner, Qt::BottomDockWidgetArea);
204
205   setMenuShown( false );
206   setToolShown( false );
207   _genericGui->showDockWidgets(false);
208   QtGuiContext *context = QtGuiContext::getQtCurrent();
209   _studyContextMap[theStudy->id()] = context;
210   DEBTRACE("_studyContextMap[theStudy] " << theStudy << " " << context);
211   return SalomeApp_Module::deactivateModule( theStudy );
212 }
213
214 // --- Default windows
215
216 void Yacsgui::windows( QMap<int, int>& theMap ) const
217 {
218   DEBTRACE("Yacsgui::windows");
219   theMap.clear();
220   theMap.insert( SalomeApp_Application::WT_ObjectBrowser, Qt::LeftDockWidgetArea );
221   theMap.insert( SalomeApp_Application::WT_PyConsole,     Qt::BottomDockWidgetArea );
222 }
223
224 QString  Yacsgui::engineIOR() const
225 {
226   DEBTRACE("Yacsgui::engineIOR");
227   QString anEngineIOR = SalomeApp_Engine_i::EngineIORForComponent( "YACS", true ).c_str();
228   return anEngineIOR;
229 }
230
231 void Yacsgui::onDblClick(const QModelIndex& index)
232 {
233   DEBTRACE("Yacsgui::onDblClick");
234   DataObjectList dol =getApp()->objectBrowser()->getSelected();
235   if (dol.isEmpty()) return;
236
237   SalomeApp_DataObject* item = dynamic_cast<SalomeApp_DataObject*>(dol[0]);
238   if (!item) return;
239
240   DEBTRACE(item->name().toStdString());
241   SalomeWrap_DataModel *model = dynamic_cast<SalomeWrap_DataModel*>(dataModel());
242   if (!model) return;
243   DEBTRACE(item->entry().toStdString());
244   QWidget * viewWindow = model->getViewWindow(item->entry().toStdString());
245   if (!_genericGui) return;
246   if (!viewWindow) return;
247   DEBTRACE("--- " << viewWindow << " "  << item->entry().toStdString());
248   if (getApp()->activeModule()->moduleName().compare("YACS") != 0)
249     getApp()->activateModule("YACS");
250
251   _selectFromTree = true;
252   viewWindow->setFocus();
253   _selectFromTree = false;
254 }
255
256 void Yacsgui::onWindowActivated( SUIT_ViewWindow* svw)
257 {
258   DEBTRACE("Yacsgui::onWindowActivated");
259   QxScene_ViewWindow* viewWindow = dynamic_cast<QxScene_ViewWindow*>(svw);
260   _currentSVW = svw;
261   if (!viewWindow)
262     {
263       _currentSVW = 0; // switch to another module
264       return;
265     }
266   DEBTRACE("viewWindow " << viewWindow);
267   DEBTRACE("activeModule()->moduleName() " << (getApp()->activeModule() ? getApp()->activeModule()->moduleName().toStdString() : "") );
268   if (!getApp()->activeModule() || getApp()->activeModule()->moduleName() != "YACS")
269     if ( !getApp()->activateModule("YACS") ) return;
270
271   disconnect(viewWindow, SIGNAL( tryClose( bool&, QxScene_ViewWindow* ) ),
272              this, SLOT(onTryClose( bool&, QxScene_ViewWindow* )) );
273   disconnect(viewWindow->getViewManager(), SIGNAL( deleteView( SUIT_ViewWindow* ) ),
274              this, SLOT(onWindowClosed( SUIT_ViewWindow* )) );
275   connect(viewWindow, SIGNAL( tryClose( bool&, QxScene_ViewWindow* ) ),
276           this, SLOT(onTryClose( bool&, QxScene_ViewWindow* )) );
277   connect(viewWindow->getViewManager(), SIGNAL( deleteView( SUIT_ViewWindow* ) ),
278           this, SLOT(onWindowClosed( SUIT_ViewWindow* )) );
279
280   YASSERT(_genericGui);
281   _genericGui->switchContext(viewWindow);
282   _studyContextMap[getApp()->activeStudy()->id()] = QtGuiContext::getQtCurrent();
283   
284   if (_selectFromTree) return;
285   SalomeWrap_DataModel *model = dynamic_cast<SalomeWrap_DataModel*>(dataModel());
286   if (!model) return;
287   model->setSelected(svw);
288 }
289
290 void Yacsgui::onWindowClosed( SUIT_ViewWindow* svw)
291 {
292   DEBTRACE("Yacsgui::onWindowClosed");
293   if ( svw && svw == _currentSVW )
294     _currentSVW = 0;
295 }
296
297 void Yacsgui::onTryClose(bool &isClosed, QxScene_ViewWindow* window)
298 {
299   DEBTRACE("Yacsgui::onTryClose");
300   YASSERT(_genericGui);
301   isClosed = _genericGui->closeContext(window);
302 }
303
304 CAM_DataModel* Yacsgui::createDataModel()
305 {
306   return new Yacsgui_DataModel(this);
307 }
308
309 bool Yacsgui::createSComponent()
310 {
311   DEBTRACE("Yacsgui::createSComponent");
312   _PTR(Study)            aStudy = (( SalomeApp_Study* )(getApp()->activeStudy()))->studyDS();
313   _PTR(StudyBuilder)     aBuilder (aStudy->NewBuilder());
314   _PTR(GenericAttribute) anAttr;
315   _PTR(AttributeName)    aName;
316
317   // --- Find or create "YACS" SComponent in the study
318
319   _PTR(SComponent) aComponent = aStudy->FindComponent("YACS");
320   if ( !aComponent )
321     {
322       aComponent = aBuilder->NewComponent("YACS");
323       anAttr = aBuilder->FindOrCreateAttribute(aComponent, "AttributeName");
324       aName = _PTR(AttributeName) (anAttr);
325       aName->SetValue(getApp()->moduleTitle("YACS").toStdString());
326       
327       anAttr = aBuilder->FindOrCreateAttribute(aComponent, "AttributePixMap");
328       _PTR(AttributePixMap) aPixmap(anAttr);
329       aPixmap->SetPixMap("ModuleYacs.png");
330       
331       aBuilder->DefineComponentInstance(aComponent, engineIOR().toLatin1().constData());
332
333       return true;
334     }
335   return false;
336 }
337
338 void Yacsgui::setResource(SUIT_ResourceMgr* r) 
339 {
340   DEBTRACE("Yacsgui::setResource");
341   _myresource = new Yacsgui_Resource(r);
342   _myresource->preferencesChanged();
343 }
344
345 void Yacsgui::createPreferences() 
346 {
347   DEBTRACE("Yacsgui::createPreferences");
348   _myresource->createPreferences(this);
349 }
350
351 void Yacsgui::preferencesChanged( const QString& sect, const QString& name ) 
352 {
353   DEBTRACE("Yacsgui::preferencesChanged");
354   _myresource->preferencesChanged(sect, name);
355   if(name=="userCatalog")
356     {
357       _genericGui->getCatalogWidget()->addCatalogFromFile(Resource::userCatalog.toStdString());
358     }
359 }
360
361 void Yacsgui::studyActivated()
362 {
363   int newStudyId = getApp()->activeStudy()->id();
364   DEBTRACE("Yacsgui::studyActivated " << _oldStudyId << " " << newStudyId);
365   
366   if (_oldStudyId != -1)
367     {
368       _studyContextMap[_oldStudyId] = QtGuiContext::getQtCurrent();      
369       if (_studyContextMap.count(newStudyId))
370         {
371           DEBTRACE("switch to valid context " << QtGuiContext::getQtCurrent() << " " << _studyContextMap[newStudyId]);
372           QtGuiContext::setQtCurrent(_studyContextMap[newStudyId]);
373         }
374       else
375         {
376           DEBTRACE("no switch to null context");
377         }
378     }
379   _oldStudyId = newStudyId;
380 }
381
382 void Yacsgui::loadSchema(const std::string& filename,bool edit, bool arrangeLocalNodes)
383 {
384   _genericGui->loadSchema(filename,edit,arrangeLocalNodes);
385 }
386
387 void Yacsgui::onCleanOnExit()
388 {
389   if ( _genericGui )
390     _genericGui->onCleanOnExit();
391   _currentSVW = 0;
392 }
393
394 // --- Export the module
395
396 extern "C"
397 {
398   YACS_EXPORT CAM_Module* createModule()
399   {
400     return new Yacsgui();
401   }
402 }