Salome HOME
Add method updateObjectBrowser() for the SalomeApp_Application
[modules/gui.git] / src / SALOME_SWIG / SALOMEGUI_Swig.cxx
1 //  SALOME SALOMEGUI : implementation of desktop and GUI kernel
2 //
3 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
5 // 
6 //  This library is free software; you can redistribute it and/or 
7 //  modify it under the terms of the GNU Lesser General Public 
8 //  License as published by the Free Software Foundation; either 
9 //  version 2.1 of the License. 
10 // 
11 //  This library is distributed in the hope that it will be useful, 
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of 
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
14 //  Lesser General Public License for more details. 
15 // 
16 //  You should have received a copy of the GNU Lesser General Public 
17 //  License along with this library; if not, write to the Free Software 
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
19 // 
20 //  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
21 //
22 //
23 //
24 //  File   : SALOMEGUI_Swig.cxx
25 //  Author : Vadim SANDLER
26 //  Module : SALOME
27 //  $Header$
28
29 #include "SALOMEGUI_Swig.hxx"
30
31 #include "SUIT_Session.h"
32 #include "SUIT_Desktop.h"
33 #include "SUIT_DataObjectIterator.h"
34 #include "OB_Browser.h"
35 #include "SalomeApp_Application.h"
36 #include "SalomeApp_Study.h"
37 #include "SalomeApp_Module.h"
38 #include "SalomeApp_DataObject.h"
39 #include "SalomeApp_SelectionMgr.h"
40 #include "SALOME_Prs.h"
41 #include "SOCC_ViewModel.h"
42 #include "SVTK_ViewModel.h"
43
44 #include "SALOME_Event.hxx"
45 #include "SALOME_ListIO.hxx"
46 #include "SALOME_InteractiveObject.hxx"
47 #include "SALOME_ListIteratorOfListIO.hxx"
48
49 //#include "utilities.h"
50
51 #include <SALOMEconfig.h>
52 #include CORBA_CLIENT_HEADER(SALOME_ModuleCatalog)
53
54 using namespace std;
55
56 //////////////////////////////////////////////////////////////////////////////
57 // asv : 3.12.04 : added checking for NULL GUI objects in almost all methods.
58 // In the scope of fixing bug PAL6869.
59 //////////////////////////////////////////////////////////////////////////////
60 // (PR : modify comments)
61 // Instance of this class is created every time "import salome" line is typed 
62 // - in IAPP embedded Python interpretor  (SALOME_Session_Server executable),
63 // - in inline Python nodes in Supervisor (in SALOME_Container executable),
64 // - in stand-alone Python console outside any executable.
65 // SALOME GUI(desktop and other objects) is only available in SALOME_Session_Server
66 //////////////////////////////////////////////////////////////////////////////
67 // VSR : 19.04.05 : Reimplemented for new SALOME GUI (SUIT-based)
68 // All methods are implemeted using Event mechanism.
69 // Display/Erase methods use SALOME_Prs/SALOME_View mechanism. It is currently
70 // implemented only for OCC and VTK viewers.
71 //////////////////////////////////////////////////////////////////////////////
72
73 /*!
74   getApplication()
75   Returns active application object [ static ]
76 */
77 static SalomeApp_Application* getApplication() {
78   if ( SUIT_Session::session() )
79     return dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
80   return NULL;
81 }
82
83 /*!
84   getActiveStudy()
85   Gets active study or 0 if there is no study opened [ static ]
86 */
87 static SalomeApp_Study* getActiveStudy()
88 {
89   if ( getApplication() )
90     return dynamic_cast<SalomeApp_Study*>( getApplication()->activeStudy() );
91   return 0;
92 }
93
94 /*!
95   SALOMEGUI_Swig::SALOMEGUI_Swig
96   Constructor
97 */
98 SALOMEGUI_Swig::SALOMEGUI_Swig()
99 {
100 }
101
102 /*!
103   SALOMEGUI_Swig::~SALOMEGUI_Swig
104   Destructor
105 */
106 SALOMEGUI_Swig::~SALOMEGUI_Swig()
107 {
108 }
109
110 /*!
111   SALOMEGUI_Swig::hasDesktop
112   Returns TRUE if GUI is available.
113 */
114 class THasDesktopEvent: public SALOME_Event {
115 public:
116   typedef bool TResult;
117   TResult myResult;
118   THasDesktopEvent() : myResult( false ) {}
119   virtual void Execute() {
120     myResult = (bool)( getApplication() && getApplication()->desktop() );
121   }
122 };
123 bool SALOMEGUI_Swig::hasDesktop()
124 {
125   return ProcessEvent( new THasDesktopEvent() );
126 }
127
128 /*!
129   SALOMEGUI_Swig::updateObjBrowser
130   Updates active study's Object Browser.
131   VSR: updateSelection parameter is currently not used. Will be implemented or removed lately.
132 */
133 void SALOMEGUI_Swig::updateObjBrowser( bool /*updateSelection*/ )
134 {
135   class TEvent: public SALOME_Event {
136   public:
137     TEvent() {}
138     virtual void Execute() {
139       if ( SalomeApp_Application* anApp = getApplication() ) {
140         anApp->updateObjectBrowser();
141       }
142     }
143   };
144   ProcessVoidEvent( new TEvent() );
145 }
146
147 /*!
148   SALOMEGUI_Swig::getActiveStudyId
149   Returns active study's ID or 0 if there is no active study.
150 */
151 class TGetActiveStudyIdEvent: public SALOME_Event {
152 public:
153   typedef int TResult;
154   TResult myResult;
155   TGetActiveStudyIdEvent() : myResult( 0 ) {}
156   virtual void Execute() {
157     if ( SalomeApp_Study* aStudy = getActiveStudy() ) {
158       myResult = aStudy->studyDS()->StudyId();
159     }
160   }
161 };
162 int SALOMEGUI_Swig::getActiveStudyId()
163 {
164   return ProcessEvent( new TGetActiveStudyIdEvent() );
165 }
166
167 /*!
168   SALOMEGUI_Swig::getActiveStudyName
169   Returns active study's name or NULL if there is no active study.
170 */
171 class TGetActiveStudyNameEvent: public SALOME_Event {
172 public:
173   typedef string TResult;
174   TResult myResult;
175   TGetActiveStudyNameEvent() {}
176   virtual void Execute() {
177     if ( SalomeApp_Study* aStudy = getActiveStudy() ) {
178       myResult = aStudy->studyDS()->Name();
179     }
180   }
181 };
182 const char* SALOMEGUI_Swig::getActiveStudyName()
183 {
184   string result = ProcessEvent( new TGetActiveStudyNameEvent() );
185   return result.empty() ? NULL : result.c_str();
186 }
187
188 /*!
189   SALOMEGUI_Swig::getComponentName
190   Returns the name of the component by its user name.
191 */
192 const char* SALOMEGUI_Swig::getComponentName( const char* componentUserName )
193 {
194   if ( SalomeApp_Application* anApp = getApplication() ) { 
195     CORBA::Object_var anObject = anApp->namingService()->Resolve("/Kernel/ModulCatalog");
196     if ( !CORBA::is_nil( anObject ) ) {
197       SALOME_ModuleCatalog::ModuleCatalog_var aCatalogue = SALOME_ModuleCatalog::ModuleCatalog::_narrow( anObject );
198       SALOME_ModuleCatalog::ListOfIAPP_Affich_var aModules = aCatalogue->GetComponentIconeList();
199       for ( unsigned int ind = 0; ind < aModules->length(); ind++ ) {
200         string aModuleName     = CORBA::string_dup( aModules[ ind ].modulename ) ;
201         string aModuleUserName = CORBA::string_dup( aModules[ ind ].moduleusername ) ;
202         if ( componentUserName == aModuleUserName )
203           return aModuleName.c_str();
204       }
205     }
206   }
207   return 0;
208 }
209
210 /*!
211   SALOMEGUI_Swig::getComponentUserName
212   Returns the user name of the component by its name.
213 */
214 const char* SALOMEGUI_Swig::getComponentUserName( const char* componentName )
215 {
216   if ( SalomeApp_Application* anApp = getApplication() ) { 
217     CORBA::Object_var anObject = anApp->namingService()->Resolve("/Kernel/ModulCatalog");
218     if ( !CORBA::is_nil( anObject ) ) {
219       SALOME_ModuleCatalog::ModuleCatalog_var aCatalogue = SALOME_ModuleCatalog::ModuleCatalog::_narrow( anObject );
220       SALOME_ModuleCatalog::ListOfIAPP_Affich_var aModules = aCatalogue->GetComponentIconeList();
221       for ( unsigned int ind = 0; ind < aModules->length(); ind++ ) {
222         string aModuleName     = CORBA::string_dup( aModules[ ind ].modulename ) ;
223         string aModuleUserName = CORBA::string_dup( aModules[ ind ].moduleusername ) ;
224         if ( componentName == aModuleName )
225           return aModuleUserName.c_str();
226       }
227     }
228   }
229   return 0;
230 }
231
232 /*!
233   SALOMEGUI_Swig::SelectedCount
234   Returns the number of selected objects.
235 */
236 class TSelectedCountEvent: public SALOME_Event {
237 public:
238   typedef int TResult;
239   TResult myResult;
240   TSelectedCountEvent() : myResult( 0 ) {}
241   virtual void Execute() {
242     if ( SalomeApp_Application* anApp = getApplication() ) {
243       SalomeApp_Study*        aStudy  = dynamic_cast<SalomeApp_Study*>( anApp->activeStudy() ); // for sure!
244       SalomeApp_SelectionMgr* aSelMgr = anApp->selectionMgr(); 
245       if ( aStudy && aSelMgr ) {
246         SALOME_ListIO anIOList;
247         aSelMgr->selectedObjects( anIOList );
248         myResult = anIOList.Extent();
249       }
250     }
251   }
252 };
253 int SALOMEGUI_Swig::SelectedCount()
254 {
255   return ProcessEvent( new TSelectedCountEvent() );
256 }
257
258 /*!
259   SALOMEGUI_Swig::getSelected
260   Returns the selected object entry by the given index.
261 */
262 class TGetSelectedEvent: public SALOME_Event {
263 public:
264   typedef QString TResult;
265   TResult myResult;
266   int     myIndex;
267   TGetSelectedEvent( int theIndex ) : myIndex( theIndex ) {}
268   virtual void Execute() {
269     if ( SalomeApp_Application* anApp = getApplication() ) {
270       SalomeApp_Study*        aStudy  = dynamic_cast<SalomeApp_Study*>( anApp->activeStudy() ); // for sure!
271       SalomeApp_SelectionMgr* aSelMgr = anApp->selectionMgr(); 
272       if ( aStudy && aSelMgr ) {
273         SALOME_ListIO anIOList;
274         aSelMgr->selectedObjects( anIOList );
275         if ( myIndex < anIOList.Extent() ) {
276           int index = 0;
277           SALOME_ListIteratorOfListIO anIter( anIOList );
278           for( ; anIter.More(); anIter.Next(), index++ ) {
279             Handle(SALOME_InteractiveObject) anIO = anIter.Value();
280             if ( myIndex == index ) {
281               myResult = anIO->getEntry();
282               return;
283             }
284           }
285         }
286       }
287     }
288   }
289 };
290 const char* SALOMEGUI_Swig::getSelected( int index )
291 {
292   QString result = ProcessEvent( new TGetSelectedEvent( index ) );
293   return result.isEmpty() ? NULL : result.latin1();
294 }
295
296 /*!
297   Adds an object with the given entry to the selection.
298 */
299 void SALOMEGUI_Swig::AddIObject( const char* theEntry )
300 {
301   class TEvent: public SALOME_Event {
302   public:
303     QString myEntry;
304     TEvent( const char* theEntry ) : myEntry( theEntry ) {}
305     virtual void Execute() {
306       if ( SalomeApp_Application* anApp = getApplication() ) {
307         SalomeApp_Study*        aStudy  = dynamic_cast<SalomeApp_Study*>( anApp->activeStudy() ); // for sure!
308         SalomeApp_SelectionMgr* aSelMgr = anApp->selectionMgr(); 
309         if ( aStudy && aSelMgr ) {
310           SALOME_ListIO anIOList;
311           anIOList.Append( new SALOME_InteractiveObject( myEntry, "", "" ) );
312           aSelMgr->setSelectedObjects( anIOList, true );
313         }
314       }
315     }
316   };
317   ProcessVoidEvent( new TEvent( theEntry ) );
318 }
319
320 /*!
321   Removes the object with the given entry from the selection.
322 */
323 void SALOMEGUI_Swig::RemoveIObject( const char* theEntry )
324 {
325   class TEvent: public SALOME_Event {
326   public:
327     QString myEntry;
328     TEvent( const char* theEntry ) : myEntry( theEntry ) {}
329     virtual void Execute() {
330       if ( SalomeApp_Application* anApp = getApplication() ) {
331         SalomeApp_Study*        aStudy  = dynamic_cast<SalomeApp_Study*>( anApp->activeStudy() ); // for sure!
332         SalomeApp_SelectionMgr* aSelMgr = anApp->selectionMgr(); 
333         if ( aStudy && aSelMgr ) {
334           SALOME_ListIO anIOList;
335           // VSR: temporary solution, until SalomeApp_SelectionMgr::unsetSelectedObjects() method appears
336           // Lately this should be replaced by the following:
337           // anIOList.Append( new SALOME_InteractiveObject( myEntry, "", "" ) );
338           // aSelMgr->unsetSelectedObjects( anIOList );
339           ///////////////////////////////////////////////
340           aSelMgr->selectedObjects( anIOList );
341           SALOME_ListIteratorOfListIO anIter( anIOList );
342           for( ; anIter.More(); anIter.Next() ) {
343             if ( anIter.Value()->isSame( new SALOME_InteractiveObject( myEntry, "", "" ) ) ) { 
344               anIOList.Remove( anIter );
345               aSelMgr->setSelectedObjects( anIOList, true );
346               return;
347             }
348           }
349         }
350       }
351     }
352   };
353   ProcessVoidEvent( new TEvent( theEntry ) );
354 }
355
356 /*!
357   Clears selection.
358 */
359 void SALOMEGUI_Swig::ClearIObjects()
360 {
361   class TEvent: public SALOME_Event {
362   public:
363     TEvent() {}
364     virtual void Execute() {
365       if ( SalomeApp_Application* anApp = getApplication() ) {
366         SalomeApp_Study*        aStudy  = dynamic_cast<SalomeApp_Study*>( anApp->activeStudy() ); // for sure!
367         SalomeApp_SelectionMgr* aSelMgr = anApp->selectionMgr(); 
368         if ( aStudy && aSelMgr )
369           aSelMgr->clearSelected();
370       }
371     }
372   };
373   ProcessVoidEvent( new TEvent() );
374 }
375
376 /*!
377   Displays an object in the current view window
378   (the presentable object should be previously created and displayed in this viewer).
379   VSR: For the current moment implemented for OCC and VTK viewers only.
380 */              
381 void SALOMEGUI_Swig::Display( const char* theEntry )
382 {
383   class TEvent: public SALOME_Event {
384     QString myEntry;
385   public:
386     TEvent( const char* theEntry ) : myEntry( theEntry ) {}
387     virtual void Execute() {
388       if ( SalomeApp_Application* anApp = getApplication() ) {
389         SUIT_ViewWindow* window = anApp->desktop()->activeWindow();
390         if ( window ) {
391           SALOME_View* view = dynamic_cast<SALOME_View*>( window->getViewManager()->getViewModel() );
392           if ( view )
393             view->Display( view->CreatePrs( myEntry ) );
394         }
395       }
396     }
397   };
398   ProcessVoidEvent( new TEvent( theEntry ) );
399 }
400
401 /*!
402   Displays an object in the current view window and erases all other
403   (the presentable object should be previously created and displayed in this viewer).
404   VSR: For the current moment implemented for OCC and VTK viewers only.
405 */
406 void SALOMEGUI_Swig::DisplayOnly( const char* theEntry )
407 {
408   class TEvent: public SALOME_Event {
409     QString myEntry;
410   public:
411     TEvent( const char* theEntry ) : myEntry( theEntry ) {}
412     virtual void Execute() {
413       if ( SalomeApp_Application* anApp = getApplication() ) {
414         SUIT_ViewWindow* window = anApp->desktop()->activeWindow();
415         if ( window ) {
416           SALOME_View* view = dynamic_cast<SALOME_View*>( window->getViewManager()->getViewModel() );
417           if ( view ) {
418             view->EraseAll( false );
419             view->Display( view->CreatePrs( myEntry ) );
420           }
421         }
422       }
423     }
424   };
425   ProcessVoidEvent( new TEvent( theEntry ) );
426 }
427
428 /*!
429   Erases an object in the current view window
430   (the presentable object should be previously created and displayed in this viewer).
431   VSR: For the current moment implemented for OCC and VTK viewers only.
432 */              
433 void SALOMEGUI_Swig::Erase( const char* theEntry )
434 {
435   class TEvent: public SALOME_Event {
436     QString myEntry;
437   public:
438     TEvent( const char* theEntry ) : myEntry( theEntry ) {}
439     virtual void Execute() {
440       if ( SalomeApp_Application* anApp = getApplication() ) {
441         SUIT_ViewWindow* window = anApp->desktop()->activeWindow();
442         if ( window ) {
443           SALOME_View* view = dynamic_cast<SALOME_View*>( window->getViewManager()->getViewModel() );
444           if ( view )
445             view->Erase( view->CreatePrs( myEntry ) );
446         }
447       }
448     }
449   };
450   ProcessVoidEvent( new TEvent( theEntry ) );
451 }
452
453 /*!
454   Displays all active module's child objects in the current view window
455   (the presentable objects should be previously created and displayed in this viewer).
456   VSR: For the current moment implemented for OCC and VTK viewers only.
457 */
458 void SALOMEGUI_Swig::DisplayAll()
459 {
460   class TEvent: public SALOME_Event {
461   public:
462     TEvent() {}
463     virtual void Execute() {
464       if ( SalomeApp_Application* anApp = getApplication() ) {
465         SalomeApp_Study*  study        = dynamic_cast<SalomeApp_Study*>( anApp->activeStudy() ); // for sure!
466         SUIT_ViewWindow*  window       = anApp->desktop()->activeWindow();
467         SalomeApp_Module* activeModule = dynamic_cast<SalomeApp_Module*>( anApp->activeModule() );
468         if ( study && window && activeModule ) {
469           SALOME_View* view = dynamic_cast<SALOME_View*>( window->getViewManager()->getViewModel() );
470           if ( view ) {
471             for ( SUIT_DataObjectIterator it( activeModule->dataModel()->root(), SUIT_DataObjectIterator::DepthLeft ); it.current(); ++it ) {
472               SalomeApp_DataObject* obj = dynamic_cast<SalomeApp_DataObject*>( it.current() );
473               if ( obj && !obj->entry().isEmpty() )
474                 view->Display( view->CreatePrs( obj->entry() ) );
475             }
476           }
477         }
478       }
479     }
480   };
481   ProcessVoidEvent( new TEvent() );
482 }
483
484 /*!
485   Erases all objects from the current view window
486   VSR: For the current moment implemented for OCC and VTK viewers only.
487 */
488 void SALOMEGUI_Swig::EraseAll()
489 {
490   class TEvent: public SALOME_Event {
491   public:
492     TEvent() {}
493     virtual void Execute() {
494       if ( SalomeApp_Application* anApp = getApplication() ) {
495         SUIT_ViewWindow* window = anApp->desktop()->activeWindow();
496         if ( window ) {
497           SALOME_View* view = dynamic_cast<SALOME_View*>( window->getViewManager()->getViewModel() );
498           if ( view )
499             view->EraseAll( false );
500         }
501       }
502     }
503   };
504   ProcessVoidEvent( new TEvent() );
505 }
506
507 /*!
508   Returns TRUE if the object with given entry is in the current viewer.
509   VSR: For the current moment implemented for OCC and VTK viewers only.
510 */
511 class TIsInViewerEvent: public SALOME_Event {
512   QString myEntry;
513 public:
514   typedef bool TResult;
515   TResult myResult;
516   TIsInViewerEvent( const char* theEntry ) : myEntry( theEntry ), myResult( false ) {}
517   virtual void Execute() {
518     if ( SalomeApp_Application* anApp = getApplication() ) {
519       SUIT_ViewWindow* window = anApp->desktop()->activeWindow();
520       if ( window ) {
521         SALOME_View* view = dynamic_cast<SALOME_View*>( window->getViewManager()->getViewModel() );
522         if ( view ) {
523           SALOME_Prs* aPrs = view->CreatePrs( myEntry );
524           myResult = aPrs->IsNull();
525         }
526       }
527     }
528   }
529 };
530 bool SALOMEGUI_Swig::IsInCurrentView( const char* theEntry )
531 {
532   return ProcessEvent( new TIsInViewerEvent( theEntry ) );
533 }