Salome HOME
Property "isOpen" property added.
[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         OB_Browser* browser = anApp->objectBrowser();
141         if ( browser )
142           browser->updateTree();
143       }
144     }
145   };
146   ProcessVoidEvent( new TEvent() );
147 }
148
149 /*!
150   SALOMEGUI_Swig::getActiveStudyId
151   Returns active study's ID or 0 if there is no active study.
152 */
153 class TGetActiveStudyIdEvent: public SALOME_Event {
154 public:
155   typedef int TResult;
156   TResult myResult;
157   TGetActiveStudyIdEvent() : myResult( 0 ) {}
158   virtual void Execute() {
159     if ( SalomeApp_Study* aStudy = getActiveStudy() ) {
160       myResult = aStudy->studyDS()->StudyId();
161     }
162   }
163 };
164 int SALOMEGUI_Swig::getActiveStudyId()
165 {
166   return ProcessEvent( new TGetActiveStudyIdEvent() );
167 }
168
169 /*!
170   SALOMEGUI_Swig::getActiveStudyName
171   Returns active study's name or NULL if there is no active study.
172 */
173 class TGetActiveStudyNameEvent: public SALOME_Event {
174 public:
175   typedef string TResult;
176   TResult myResult;
177   TGetActiveStudyNameEvent() {}
178   virtual void Execute() {
179     if ( SalomeApp_Study* aStudy = getActiveStudy() ) {
180       myResult = aStudy->studyDS()->Name();
181     }
182   }
183 };
184 const char* SALOMEGUI_Swig::getActiveStudyName()
185 {
186   string result = ProcessEvent( new TGetActiveStudyNameEvent() );
187   return result.empty() ? NULL : result.c_str();
188 }
189
190 /*!
191   SALOMEGUI_Swig::getComponentName
192   Returns the name of the component by its user name.
193 */
194 const char* SALOMEGUI_Swig::getComponentName( const char* componentUserName )
195 {
196   if ( SalomeApp_Application* anApp = getApplication() ) { 
197     CORBA::Object_var anObject = anApp->namingService()->Resolve("/Kernel/ModulCatalog");
198     if ( !CORBA::is_nil( anObject ) ) {
199       SALOME_ModuleCatalog::ModuleCatalog_var aCatalogue = SALOME_ModuleCatalog::ModuleCatalog::_narrow( anObject );
200       SALOME_ModuleCatalog::ListOfIAPP_Affich_var aModules = aCatalogue->GetComponentIconeList();
201       for ( unsigned int ind = 0; ind < aModules->length(); ind++ ) {
202         string aModuleName     = CORBA::string_dup( aModules[ ind ].modulename ) ;
203         string aModuleUserName = CORBA::string_dup( aModules[ ind ].moduleusername ) ;
204         if ( componentUserName == aModuleUserName )
205           return aModuleName.c_str();
206       }
207     }
208   }
209   return 0;
210 }
211
212 /*!
213   SALOMEGUI_Swig::getComponentUserName
214   Returns the user name of the component by its name.
215 */
216 const char* SALOMEGUI_Swig::getComponentUserName( const char* componentName )
217 {
218   if ( SalomeApp_Application* anApp = getApplication() ) { 
219     CORBA::Object_var anObject = anApp->namingService()->Resolve("/Kernel/ModulCatalog");
220     if ( !CORBA::is_nil( anObject ) ) {
221       SALOME_ModuleCatalog::ModuleCatalog_var aCatalogue = SALOME_ModuleCatalog::ModuleCatalog::_narrow( anObject );
222       SALOME_ModuleCatalog::ListOfIAPP_Affich_var aModules = aCatalogue->GetComponentIconeList();
223       for ( unsigned int ind = 0; ind < aModules->length(); ind++ ) {
224         string aModuleName     = CORBA::string_dup( aModules[ ind ].modulename ) ;
225         string aModuleUserName = CORBA::string_dup( aModules[ ind ].moduleusername ) ;
226         if ( componentName == aModuleName )
227           return aModuleUserName.c_str();
228       }
229     }
230   }
231   return 0;
232 }
233
234 /*!
235   SALOMEGUI_Swig::SelectedCount
236   Returns the number of selected objects.
237 */
238 class TSelectedCountEvent: public SALOME_Event {
239 public:
240   typedef int TResult;
241   TResult myResult;
242   TSelectedCountEvent() : myResult( 0 ) {}
243   virtual void Execute() {
244     if ( SalomeApp_Application* anApp = getApplication() ) {
245       SalomeApp_Study*        aStudy  = dynamic_cast<SalomeApp_Study*>( anApp->activeStudy() ); // for sure!
246       SalomeApp_SelectionMgr* aSelMgr = anApp->selectionMgr(); 
247       if ( aStudy && aSelMgr ) {
248         SALOME_ListIO anIOList;
249         aSelMgr->selectedObjects( anIOList );
250         myResult = anIOList.Extent();
251       }
252     }
253   }
254 };
255 int SALOMEGUI_Swig::SelectedCount()
256 {
257   return ProcessEvent( new TSelectedCountEvent() );
258 }
259
260 /*!
261   SALOMEGUI_Swig::getSelected
262   Returns the selected object entry by the given index.
263 */
264 class TGetSelectedEvent: public SALOME_Event {
265 public:
266   typedef QString TResult;
267   TResult myResult;
268   int     myIndex;
269   TGetSelectedEvent( int theIndex ) : myIndex( theIndex ) {}
270   virtual void Execute() {
271     if ( SalomeApp_Application* anApp = getApplication() ) {
272       SalomeApp_Study*        aStudy  = dynamic_cast<SalomeApp_Study*>( anApp->activeStudy() ); // for sure!
273       SalomeApp_SelectionMgr* aSelMgr = anApp->selectionMgr(); 
274       if ( aStudy && aSelMgr ) {
275         SALOME_ListIO anIOList;
276         aSelMgr->selectedObjects( anIOList );
277         if ( myIndex < anIOList.Extent() ) {
278           int index = 0;
279           SALOME_ListIteratorOfListIO anIter( anIOList );
280           for( ; anIter.More(); anIter.Next(), index++ ) {
281             Handle(SALOME_InteractiveObject) anIO = anIter.Value();
282             if ( myIndex == index ) {
283               myResult = anIO->getEntry();
284               return;
285             }
286           }
287         }
288       }
289     }
290   }
291 };
292 const char* SALOMEGUI_Swig::getSelected( int index )
293 {
294   QString result = ProcessEvent( new TGetSelectedEvent( index ) );
295   return result.isEmpty() ? NULL : result.latin1();
296 }
297
298 /*!
299   Adds an object with the given entry to the selection.
300 */
301 void SALOMEGUI_Swig::AddIObject( const char* theEntry )
302 {
303   class TEvent: public SALOME_Event {
304   public:
305     QString myEntry;
306     TEvent( const char* theEntry ) : myEntry( theEntry ) {}
307     virtual void Execute() {
308       if ( SalomeApp_Application* anApp = getApplication() ) {
309         SalomeApp_Study*        aStudy  = dynamic_cast<SalomeApp_Study*>( anApp->activeStudy() ); // for sure!
310         SalomeApp_SelectionMgr* aSelMgr = anApp->selectionMgr(); 
311         if ( aStudy && aSelMgr ) {
312           SALOME_ListIO anIOList;
313           anIOList.Append( new SALOME_InteractiveObject( myEntry, "", "" ) );
314           aSelMgr->setSelectedObjects( anIOList, true );
315         }
316       }
317     }
318   };
319   ProcessVoidEvent( new TEvent( theEntry ) );
320 }
321
322 /*!
323   Removes the object with the given entry from the selection.
324 */
325 void SALOMEGUI_Swig::RemoveIObject( const char* theEntry )
326 {
327   class TEvent: public SALOME_Event {
328   public:
329     QString myEntry;
330     TEvent( const char* theEntry ) : myEntry( theEntry ) {}
331     virtual void Execute() {
332       if ( SalomeApp_Application* anApp = getApplication() ) {
333         SalomeApp_Study*        aStudy  = dynamic_cast<SalomeApp_Study*>( anApp->activeStudy() ); // for sure!
334         SalomeApp_SelectionMgr* aSelMgr = anApp->selectionMgr(); 
335         if ( aStudy && aSelMgr ) {
336           SALOME_ListIO anIOList;
337           // VSR: temporary solution, until SalomeApp_SelectionMgr::unsetSelectedObjects() method appears
338           // Lately this should be replaced by the following:
339           // anIOList.Append( new SALOME_InteractiveObject( myEntry, "", "" ) );
340           // aSelMgr->unsetSelectedObjects( anIOList );
341           ///////////////////////////////////////////////
342           aSelMgr->selectedObjects( anIOList );
343           SALOME_ListIteratorOfListIO anIter( anIOList );
344           for( ; anIter.More(); anIter.Next() ) {
345             if ( anIter.Value()->isSame( new SALOME_InteractiveObject( myEntry, "", "" ) ) ) { 
346               anIOList.Remove( anIter );
347               aSelMgr->setSelectedObjects( anIOList, true );
348               return;
349             }
350           }
351         }
352       }
353     }
354   };
355   ProcessVoidEvent( new TEvent( theEntry ) );
356 }
357
358 /*!
359   Clears selection.
360 */
361 void SALOMEGUI_Swig::ClearIObjects()
362 {
363   class TEvent: public SALOME_Event {
364   public:
365     TEvent() {}
366     virtual void Execute() {
367       if ( SalomeApp_Application* anApp = getApplication() ) {
368         SalomeApp_Study*        aStudy  = dynamic_cast<SalomeApp_Study*>( anApp->activeStudy() ); // for sure!
369         SalomeApp_SelectionMgr* aSelMgr = anApp->selectionMgr(); 
370         if ( aStudy && aSelMgr )
371           aSelMgr->clearSelected();
372       }
373     }
374   };
375   ProcessVoidEvent( new TEvent() );
376 }
377
378 /*!
379   Displays an object in the current view window
380   (the presentable object should be previously created and displayed in this viewer).
381   VSR: For the current moment implemented for OCC and VTK viewers only.
382 */              
383 void SALOMEGUI_Swig::Display( const char* theEntry )
384 {
385   class TEvent: public SALOME_Event {
386     QString myEntry;
387   public:
388     TEvent( const char* theEntry ) : myEntry( theEntry ) {}
389     virtual void Execute() {
390       if ( SalomeApp_Application* anApp = getApplication() ) {
391         SUIT_ViewWindow* window = anApp->desktop()->activeWindow();
392         if ( window ) {
393           SALOME_View* view = dynamic_cast<SALOME_View*>( window->getViewManager()->getViewModel() );
394           if ( view )
395             view->Display( view->CreatePrs( myEntry ) );
396         }
397       }
398     }
399   };
400   ProcessVoidEvent( new TEvent( theEntry ) );
401 }
402
403 /*!
404   Displays an object in the current view window and erases all other
405   (the presentable object should be previously created and displayed in this viewer).
406   VSR: For the current moment implemented for OCC and VTK viewers only.
407 */
408 void SALOMEGUI_Swig::DisplayOnly( const char* theEntry )
409 {
410   class TEvent: public SALOME_Event {
411     QString myEntry;
412   public:
413     TEvent( const char* theEntry ) : myEntry( theEntry ) {}
414     virtual void Execute() {
415       if ( SalomeApp_Application* anApp = getApplication() ) {
416         SUIT_ViewWindow* window = anApp->desktop()->activeWindow();
417         if ( window ) {
418           SALOME_View* view = dynamic_cast<SALOME_View*>( window->getViewManager()->getViewModel() );
419           if ( view ) {
420             view->EraseAll( false );
421             view->Display( view->CreatePrs( myEntry ) );
422           }
423         }
424       }
425     }
426   };
427   ProcessVoidEvent( new TEvent( theEntry ) );
428 }
429
430 /*!
431   Erases an object in the current view window
432   (the presentable object should be previously created and displayed in this viewer).
433   VSR: For the current moment implemented for OCC and VTK viewers only.
434 */              
435 void SALOMEGUI_Swig::Erase( const char* theEntry )
436 {
437   class TEvent: public SALOME_Event {
438     QString myEntry;
439   public:
440     TEvent( const char* theEntry ) : myEntry( theEntry ) {}
441     virtual void Execute() {
442       if ( SalomeApp_Application* anApp = getApplication() ) {
443         SUIT_ViewWindow* window = anApp->desktop()->activeWindow();
444         if ( window ) {
445           SALOME_View* view = dynamic_cast<SALOME_View*>( window->getViewManager()->getViewModel() );
446           if ( view )
447             view->Erase( view->CreatePrs( myEntry ) );
448         }
449       }
450     }
451   };
452   ProcessVoidEvent( new TEvent( theEntry ) );
453 }
454
455 /*!
456   Displays all active module's child objects in the current view window
457   (the presentable objects should be previously created and displayed in this viewer).
458   VSR: For the current moment implemented for OCC and VTK viewers only.
459 */
460 void SALOMEGUI_Swig::DisplayAll()
461 {
462   class TEvent: public SALOME_Event {
463   public:
464     TEvent() {}
465     virtual void Execute() {
466       if ( SalomeApp_Application* anApp = getApplication() ) {
467         SalomeApp_Study*  study        = dynamic_cast<SalomeApp_Study*>( anApp->activeStudy() ); // for sure!
468         SUIT_ViewWindow*  window       = anApp->desktop()->activeWindow();
469         SalomeApp_Module* activeModule = dynamic_cast<SalomeApp_Module*>( anApp->activeModule() );
470         if ( study && window && activeModule ) {
471           SALOME_View* view = dynamic_cast<SALOME_View*>( window->getViewManager()->getViewModel() );
472           if ( view ) {
473             for ( SUIT_DataObjectIterator it( activeModule->dataModel()->root(), SUIT_DataObjectIterator::DepthLeft ); it.current(); ++it ) {
474               SalomeApp_DataObject* obj = dynamic_cast<SalomeApp_DataObject*>( it.current() );
475               if ( obj && !obj->entry().isEmpty() )
476                 view->Display( view->CreatePrs( obj->entry() ) );
477             }
478           }
479         }
480       }
481     }
482   };
483   ProcessVoidEvent( new TEvent() );
484 }
485
486 /*!
487   Erases all objects from the current view window
488   VSR: For the current moment implemented for OCC and VTK viewers only.
489 */
490 void SALOMEGUI_Swig::EraseAll()
491 {
492   class TEvent: public SALOME_Event {
493   public:
494     TEvent() {}
495     virtual void Execute() {
496       if ( SalomeApp_Application* anApp = getApplication() ) {
497         SUIT_ViewWindow* window = anApp->desktop()->activeWindow();
498         if ( window ) {
499           SALOME_View* view = dynamic_cast<SALOME_View*>( window->getViewManager()->getViewModel() );
500           if ( view )
501             view->EraseAll( false );
502         }
503       }
504     }
505   };
506   ProcessVoidEvent( new TEvent() );
507 }
508
509 /*!
510   Returns TRUE if the object with given entry is in the current viewer.
511   VSR: For the current moment implemented for OCC and VTK viewers only.
512 */
513 class TIsInViewerEvent: public SALOME_Event {
514   QString myEntry;
515 public:
516   typedef bool TResult;
517   TResult myResult;
518   TIsInViewerEvent( const char* theEntry ) : myEntry( theEntry ), myResult( false ) {}
519   virtual void Execute() {
520     if ( SalomeApp_Application* anApp = getApplication() ) {
521       SUIT_ViewWindow* window = anApp->desktop()->activeWindow();
522       if ( window ) {
523         SALOME_View* view = dynamic_cast<SALOME_View*>( window->getViewManager()->getViewModel() );
524         if ( view ) {
525           SALOME_Prs* aPrs = view->CreatePrs( myEntry );
526           myResult = aPrs->IsNull();
527         }
528       }
529     }
530   }
531 };
532 bool SALOMEGUI_Swig::IsInCurrentView( const char* theEntry )
533 {
534   return ProcessEvent( new TIsInViewerEvent( theEntry ) );
535 }