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