Salome HOME
Merge from V6_main_20120808 08Aug12
[modules/yacs.git] / src / salomegui / Yacsgui.cxx
1 // Copyright (C) 2006-2012  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.
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.hxx>
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   LightApp_Module( "YACS" )
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()->objectBrowser()->treeView(),
102                SIGNAL( doubleClicked(const QModelIndex&) ), 
103                this,
104                SLOT  ( onDblClick(const QModelIndex&) ) );
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   if (createSComponent()) updateObjBrowser();
117
118   // Load SALOME module catalogs
119   QStringList appModules;
120   app->modules(appModules,false);
121   for ( QStringList::const_iterator it = appModules.begin(); it != appModules.end(); ++it )
122     {
123       QString aModule=*it;
124       QString modName = app->moduleName( aModule );                    // module name
125       if ( modName.isEmpty() ) modName = aModule;             
126       QString rootDir = QString( "%1_ROOT_DIR" ).arg( modName );       // module root dir variable
127       QString modDir  = getenv( rootDir.toLatin1().constData() );      // module root dir
128       if ( !modDir.isEmpty() ) 
129         {
130           QStringList cataLst = QStringList() << modDir << "share" << "salome" << "resources" << modName.toLower() << modName+"SchemaCatalog.xml";
131           QString cataFile = cataLst.join( QDir::separator() );          // YACS module catalog
132           if ( QFile::exists( cataFile ) ) 
133             _genericGui->getCatalogWidget()->addCatalogFromFile(cataFile.toStdString());
134         }
135     }
136 }
137
138 void Yacsgui::viewManagers( QStringList& list ) const
139 {
140   DEBTRACE("Yacsgui::viewManagers");
141   list.append( QxScene_Viewer::Type() );
142 }
143
144 bool Yacsgui::activateModule( SUIT_Study* theStudy )
145 {
146   DEBTRACE("Yacsgui::activateModule");
147   bool bOk = SalomeApp_Module::activateModule( theStudy );
148
149   QMainWindow* parent = application()->desktop();
150   if(Resource::dockWidgetPriority)
151     {
152       parent->setCorner(Qt::TopLeftCorner, Qt::LeftDockWidgetArea);
153       parent->setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea);
154       parent->setCorner(Qt::TopRightCorner, Qt::RightDockWidgetArea);
155       parent->setCorner(Qt::BottomRightCorner, Qt::RightDockWidgetArea);
156     }
157   setMenuShown( true );
158   setToolShown( true );
159   _genericGui->showDockWidgets(true);
160
161   // import Python module that manages YACS plugins (need to be here because SalomePyQt API uses active module)
162   PyGILState_STATE gstate = PyGILState_Ensure();
163   PyObject* pluginsmanager=PyImport_ImportModule((char*)"salome_pluginsmanager");
164   if(pluginsmanager==NULL)
165     PyErr_Print();
166   else
167     {
168       PyObject* result=PyObject_CallMethod( pluginsmanager, (char*)"initialize", (char*)"isss",1,"yacs","YACS",tr("YACS_PLUGINS").toStdString().c_str());
169       if(result==NULL)
170         PyErr_Print();
171       Py_XDECREF(result);
172     }
173   PyGILState_Release(gstate);
174   // end of YACS plugins loading
175
176   if (_currentSVW)
177     onWindowActivated(_currentSVW);
178
179   return bOk;
180 }
181
182 bool Yacsgui::deactivateModule( SUIT_Study* theStudy )
183 {
184   DEBTRACE("Yacsgui::deactivateModule");
185
186   QMainWindow* parent = application()->desktop();
187   parent->setCorner(Qt::TopLeftCorner, Qt::TopDockWidgetArea);
188   parent->setCorner(Qt::BottomLeftCorner, Qt::BottomDockWidgetArea);
189   parent->setCorner(Qt::TopRightCorner, Qt::TopDockWidgetArea);
190   parent->setCorner(Qt::BottomRightCorner, Qt::BottomDockWidgetArea);
191
192   setMenuShown( false );
193   setToolShown( false );
194   _genericGui->showDockWidgets(false);
195   QtGuiContext *context = QtGuiContext::getQtCurrent();
196   _studyContextMap[theStudy->id()] = context;
197   DEBTRACE("_studyContextMap[theStudy] " << theStudy << " " << context);
198   return SalomeApp_Module::deactivateModule( theStudy );
199 }
200
201 // --- Default windows
202
203 void Yacsgui::windows( QMap<int, int>& theMap ) const
204 {
205   DEBTRACE("Yacsgui::windows");
206   theMap.clear();
207   theMap.insert( SalomeApp_Application::WT_ObjectBrowser, Qt::LeftDockWidgetArea );
208 //   theMap.insert( SalomeApp_Application::WT_PyConsole,     Qt::BottomDockWidgetArea );
209 }
210
211 QString  Yacsgui::engineIOR() const
212 {
213   DEBTRACE("Yacsgui::engineIOR");
214   QString anEngineIOR = SalomeApp_Engine_i::EngineIORForComponent( "YACS", true ).c_str();
215   return anEngineIOR;
216 }
217
218 void Yacsgui::onDblClick(const QModelIndex& index)
219 {
220   DEBTRACE("Yacsgui::onDblClick");
221   DataObjectList dol =getApp()->objectBrowser()->getSelected();
222   if (dol.isEmpty()) return;
223
224   SalomeApp_DataObject* item = dynamic_cast<SalomeApp_DataObject*>(dol[0]);
225   if (!item) return;
226
227   DEBTRACE(item->name().toStdString());
228   SalomeWrap_DataModel *model = dynamic_cast<SalomeWrap_DataModel*>(dataModel());
229   if (!model) return;
230   DEBTRACE(item->entry().toStdString());
231   QWidget * viewWindow = model->getViewWindow(item->entry().toStdString());
232   if (!_genericGui) return;
233   if (!viewWindow) return;
234   DEBTRACE("--- " << viewWindow << " "  << item->entry().toStdString());
235   if (getApp()->activeModule()->moduleName().compare("YACS") != 0)
236     getApp()->activateModule("YACS");
237
238   _selectFromTree = true;
239   viewWindow->setFocus();
240   _selectFromTree = false;
241 }
242
243 void Yacsgui::onWindowActivated( SUIT_ViewWindow* svw)
244 {
245   DEBTRACE("Yacsgui::onWindowActivated");
246   QxScene_ViewWindow* viewWindow = dynamic_cast<QxScene_ViewWindow*>(svw);
247   _currentSVW = svw;
248   if (!viewWindow)
249     {
250       _currentSVW = 0; // switch to another module
251       return;
252     }
253   DEBTRACE("viewWindow " << viewWindow);
254   DEBTRACE("activeModule()->moduleName() " << (getApp()->activeModule() ? getApp()->activeModule()->moduleName().toStdString() : "") );
255   if (!getApp()->activeModule() || getApp()->activeModule()->moduleName() != "YACS")
256     if ( !getApp()->activateModule("YACS") ) return;
257
258   disconnect(viewWindow, SIGNAL( tryClose( bool&, QxScene_ViewWindow* ) ),
259              this, SLOT(onTryClose( bool&, QxScene_ViewWindow* )) );
260   disconnect(viewWindow->getViewManager(), SIGNAL( deleteView( SUIT_ViewWindow* ) ),
261              this, SLOT(onWindowClosed( SUIT_ViewWindow* )) );
262   connect(viewWindow, SIGNAL( tryClose( bool&, QxScene_ViewWindow* ) ),
263           this, SLOT(onTryClose( bool&, QxScene_ViewWindow* )) );
264   connect(viewWindow->getViewManager(), SIGNAL( deleteView( SUIT_ViewWindow* ) ),
265           this, SLOT(onWindowClosed( SUIT_ViewWindow* )) );
266
267   YASSERT(_genericGui);
268   _genericGui->switchContext(viewWindow);
269   _studyContextMap[getApp()->activeStudy()->id()] = QtGuiContext::getQtCurrent();
270   
271   if (_selectFromTree) return;
272   SalomeWrap_DataModel *model = dynamic_cast<SalomeWrap_DataModel*>(dataModel());
273   if (!model) return;
274   model->setSelected(svw);
275 }
276
277 void Yacsgui::onWindowClosed( SUIT_ViewWindow* svw)
278 {
279   DEBTRACE("Yacsgui::onWindowClosed");
280   if ( svw && svw == _currentSVW )
281     _currentSVW = 0;
282 }
283
284 void Yacsgui::onTryClose(bool &isClosed, QxScene_ViewWindow* window)
285 {
286   DEBTRACE("Yacsgui::onTryClose");
287   YASSERT(_genericGui);
288   isClosed = _genericGui->closeContext(window);
289 }
290
291 CAM_DataModel* Yacsgui::createDataModel()
292 {
293   return new Yacsgui_DataModel(this);
294 }
295
296 bool Yacsgui::createSComponent()
297 {
298   DEBTRACE("Yacsgui::createSComponent");
299   _PTR(Study)            aStudy = (( SalomeApp_Study* )(getApp()->activeStudy()))->studyDS();
300   _PTR(StudyBuilder)     aBuilder (aStudy->NewBuilder());
301   _PTR(GenericAttribute) anAttr;
302   _PTR(AttributeName)    aName;
303
304   // --- Find or create "YACS" SComponent in the study
305
306   _PTR(SComponent) aComponent = aStudy->FindComponent("YACS");
307   if ( !aComponent )
308     {
309       aComponent = aBuilder->NewComponent("YACS");
310       anAttr = aBuilder->FindOrCreateAttribute(aComponent, "AttributeName");
311       aName = _PTR(AttributeName) (anAttr);
312       aName->SetValue(getApp()->moduleTitle("YACS").toStdString());
313       
314       anAttr = aBuilder->FindOrCreateAttribute(aComponent, "AttributePixMap");
315       _PTR(AttributePixMap) aPixmap(anAttr);
316       aPixmap->SetPixMap("ModuleYacs.png");
317       
318       aBuilder->DefineComponentInstance(aComponent, engineIOR().toLatin1().constData());
319
320       return true;
321     }
322   return false;
323 }
324
325 void Yacsgui::setResource(SUIT_ResourceMgr* r) 
326 {
327   DEBTRACE("Yacsgui::setResource");
328   _myresource = new Yacsgui_Resource(r);
329   _myresource->preferencesChanged();
330 }
331
332 void Yacsgui::createPreferences() 
333 {
334   DEBTRACE("Yacsgui::createPreferences");
335   _myresource->createPreferences(this);
336 }
337
338 void Yacsgui::preferencesChanged( const QString& sect, const QString& name ) 
339 {
340   DEBTRACE("Yacsgui::preferencesChanged");
341   _myresource->preferencesChanged(sect, name);
342   if(name=="userCatalog")
343     {
344       _genericGui->getCatalogWidget()->addCatalogFromFile(Resource::userCatalog.toStdString());
345     }
346 }
347
348 void Yacsgui::studyActivated()
349 {
350   int newStudyId = getApp()->activeStudy()->id();
351   DEBTRACE("Yacsgui::studyActivated " << _oldStudyId << " " << newStudyId);
352   
353   if (_oldStudyId != -1)
354     {
355       _studyContextMap[_oldStudyId] = QtGuiContext::getQtCurrent();      
356       if (_studyContextMap.count(newStudyId))
357         {
358           DEBTRACE("switch to valid context " << QtGuiContext::getQtCurrent() << " " << _studyContextMap[newStudyId]);
359           QtGuiContext::setQtCurrent(_studyContextMap[newStudyId]);
360         }
361       else
362         {
363           DEBTRACE("no switch to null context");
364         }
365     }
366   _oldStudyId = newStudyId;
367 }
368
369 void Yacsgui::loadSchema(const std::string& filename,bool edit, bool arrangeLocalNodes)
370 {
371   _genericGui->loadSchema(filename,edit,arrangeLocalNodes);
372 }
373
374 void Yacsgui::onCleanOnExit()
375 {
376   if ( _genericGui )
377     _genericGui->onCleanOnExit();
378   _currentSVW = 0;
379 }
380
381 // --- Export the module
382
383 extern "C"
384 {
385   YACS_EXPORT CAM_Module* createModule()
386   {
387     return new Yacsgui();
388   }
389 }