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