1 // Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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, or (at your option) any later version.
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.
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
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 // SALOME SALOMEGUI : implementation of desktop and GUI kernel
24 // File : SALOMEGUI_Swig.cxx
25 // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
27 #include "SALOMEGUI_Swig.hxx"
29 #include <SUIT_Session.h>
30 #include <SUIT_Desktop.h>
31 #include <SUIT_ViewWindow.h>
32 #include <SUIT_ViewManager.h>
33 #include <SUIT_DataObjectIterator.h>
34 #include <CAM_DataModel.h>
35 #include <LightApp_Application.h>
36 #include <LightApp_Displayer.h>
37 #include <LightApp_Study.h>
38 #include <LightApp_Module.h>
39 #include <LightApp_DataObject.h>
40 #include <LightApp_SelectionMgr.h>
41 #include <LightApp_DataOwner.h>
42 #include <SALOME_Prs.h>
43 #include <SALOME_Event.h>
45 #ifndef DISABLE_SALOMEOBJECT
46 #include <SALOME_ListIO.hxx>
47 #include <SALOME_InteractiveObject.hxx>
48 #ifndef DISABLE_OCCVIEWER
49 #include <SOCC_ViewModel.h>
50 #include <SOCC_ViewWindow.h>
52 #ifndef DISABLE_VTKVIEWER
53 #include <SVTK_ViewModel.h>
54 #include <SVTK_ViewWindow.h>
56 #ifndef DISABLE_PLOT2DVIEWER
57 #include <SPlot2d_ViewWindow.h>
64 \brief Python interface module for SALOME GUI.
66 This module provides an access to the SALOME GUI implementing set of functions
67 which can be used from Python. This module is implemented using SWIG wrappings
68 for some GUI functionality:
69 - getActiveStudyId(), getActiveStudyName() : get active study identifier and name
70 - updateObjBrowser() : update contents of the Object Browser
71 - SelectedCount() : get number of currently selected items
72 - getSelected() : get entry of the speicified selected item
73 - ClearIObjects() : clear selection
74 - Display(), DisplayOnly(), Erase() : display/erase objects
77 Instance of this class is created every time "import salome" line is typed
78 - in IAPP embedded Python interpretor (SALOME_Session_Server executable)
79 - in inline Python nodes in Supervisor (in SALOME_Container executable)
80 - in stand-alone Python console outside any executable
82 SALOME GUI (desktop and other objects) is only available in SALOME_Session_Server.
83 It means that it can not be accessed from the external Python console.
88 sg = libSALOME_Swig.SALOMEGUI_Swig()
90 selcount = sg.SelectedCount()
92 sg.Erase( sg.getSelected( 0 ) )
98 --- INTERNAL COMMENTS SECTION ---
100 ASV : 03.12.04 : added checking for NULL GUI objects in almost all methods.
101 In the scope of fixing bug PAL6869.
103 VSR : 19.04.05 : Reimplemented for new SALOME GUI (SUIT-based)
104 All methods are implemeted using Event mechanism.
105 Display/Erase methods use SALOME_Prs/SALOME_View mechanism. It is currently
106 implemented only for OCC and VTK viewers.
110 \brief Get active application object
112 \return active application or 0 if there is no any
114 static LightApp_Application* getApplication()
116 if ( SUIT_Session::session() )
117 return dynamic_cast<LightApp_Application*>( SUIT_Session::session()->activeApplication() );
122 \brief Get active study object
124 \return active study or 0 if there is no study opened
126 static LightApp_Study* getActiveStudy()
128 if ( getApplication() )
129 return dynamic_cast<LightApp_Study*>( getApplication()->activeStudy() );
136 SALOMEGUI_Swig::SALOMEGUI_Swig()
143 SALOMEGUI_Swig::~SALOMEGUI_Swig()
148 \fn bool SALOMEGUI_Swig::hasDesktop()
149 \brief Check GUI availability.
150 \return \c true if GUI is available
153 class THasDesktopEvent: public SALOME_Event
156 typedef bool TResult;
158 THasDesktopEvent() : myResult( false ) {}
159 virtual void Execute()
161 myResult = (bool)( getApplication() && getApplication()->desktop() );
164 bool SALOMEGUI_Swig::hasDesktop()
166 return ProcessEvent( new THasDesktopEvent() );
170 \brief Update active study's Object Browser.
171 \param updateSelection this parameter is obsolete
173 void SALOMEGUI_Swig::updateObjBrowser( bool /*updateSelection*/ )
175 class TEvent: public SALOME_Event
179 virtual void Execute()
181 if ( LightApp_Application* anApp = getApplication() ) {
182 anApp->updateObjectBrowser();
183 anApp->updateActions(); //SRN: added in order to update the toolbar
187 ProcessVoidEvent( new TEvent() );
191 \fn int SALOMEGUI_Swig::getActiveStudyId()
192 \brief Get active study identifier
193 \return active study's ID or 0 if there is no active study
196 class TGetActiveStudyIdEvent: public SALOME_Event
201 TGetActiveStudyIdEvent() : myResult( 0 ) {}
202 virtual void Execute()
204 if ( LightApp_Study* aStudy = getActiveStudy() ) {
205 myResult = aStudy->id();
209 int SALOMEGUI_Swig::getActiveStudyId()
211 return ProcessEvent( new TGetActiveStudyIdEvent() );
215 \fn const char* SALOMEGUI_Swig::getActiveStudyName()
216 \brief Get active study name
217 \return active study's name or null string if there is no active study
220 class TGetActiveStudyNameEvent: public SALOME_Event
223 typedef std::string TResult;
225 TGetActiveStudyNameEvent() {}
226 virtual void Execute()
228 if ( LightApp_Study* aStudy = getActiveStudy() ) {
229 myResult = aStudy->studyName().toUtf8().constData();
233 const char* SALOMEGUI_Swig::getActiveStudyName()
235 std::string result = ProcessEvent( new TGetActiveStudyNameEvent() );
236 return result.empty() ? 0 : result.c_str();
240 \fn const char* SALOMEGUI_Swig::getComponentName( const char* componentUserName )
241 \brief Get name of the component by its title (user name)
242 \param componentUserName component title (user name)
243 \return component name or null string if component title is invalid
247 \fn const char* SALOMEGUI_Swig::getComponentUserName( const char* componentName )
248 \brief Get title (user name) of the component by its name
249 \param componentName component name
250 \return component title or null string if component name is invalid
253 class TGetComponentNameEvent: public SALOME_Event
256 typedef QString TResult;
260 TGetComponentNameEvent( const QString& name, bool isUserName )
261 : myName( name ), myIsUserName( isUserName ) {}
262 virtual void Execute()
264 if ( LightApp_Application* app = getApplication() ) {
265 myResult = myIsUserName ? app->moduleTitle( myName ) : app->moduleName( myName );
269 const char* SALOMEGUI_Swig::getComponentName( const char* componentUserName )
271 QString result = ProcessEvent( new TGetComponentNameEvent( componentUserName, false ) );
272 return result.isEmpty() ? 0 : strdup( result.toLatin1().constData() );
274 const char* SALOMEGUI_Swig::getComponentUserName( const char* componentName )
276 QString result = ProcessEvent( new TGetComponentNameEvent( componentName, true ) );
277 return result.isEmpty() ? 0 : strdup( result.toLatin1().constData() );
281 \fn int SALOMEGUI_Swig::SelectedCount()
282 \brief Get number of selected items
283 \return number of selected items in the active study
287 \fn const char* SALOMEGUI_Swig::getSelected( int index )
288 \brief Get entry of the specified selected item
289 \param index selected object index
290 \return selected object entry (null string if index is invalid)
293 class TGetSelectedEvent: public SALOME_Event
296 typedef QStringList TResult;
298 TGetSelectedEvent() {}
299 virtual void Execute()
301 if ( LightApp_Application* anApp = getApplication() ) {
302 LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>( anApp->activeStudy() ); // for sure!
303 LightApp_SelectionMgr* aSelMgr = anApp->selectionMgr();
304 if ( aStudy && aSelMgr ) {
305 SUIT_DataOwnerPtrList aList;
306 aSelMgr->selected( aList );
308 for ( SUIT_DataOwnerPtrList::const_iterator itr = aList.begin();
309 itr != aList.end(); ++itr ) {
310 const LightApp_DataOwner* owner =
311 dynamic_cast<const LightApp_DataOwner*>( (*itr).operator->() );
314 QString entry = owner->entry();
315 if( !myResult.contains( entry ) )
316 myResult.append( entry );
322 int SALOMEGUI_Swig::SelectedCount()
324 QStringList selected = ProcessEvent( new TGetSelectedEvent() );
325 return selected.count();
327 const char* SALOMEGUI_Swig::getSelected( int index )
329 QStringList selected = ProcessEvent( new TGetSelectedEvent() );
330 return index >= 0 && index < selected.count() ?
331 strdup( selected[ index ].toLatin1().constData() ) : 0;
335 \brief Add an object to the current selection.
336 \param theEntry object entry
338 void SALOMEGUI_Swig::AddIObject( const char* theEntry )
340 class TEvent: public SALOME_Event
344 TEvent( const char* theEntry ) : myEntry( theEntry ) {}
345 virtual void Execute()
347 if ( LightApp_Application* anApp = getApplication() ) {
348 LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>( anApp->activeStudy() ); // for sure!
349 LightApp_SelectionMgr* aSelMgr = anApp->selectionMgr();
350 if ( aStudy && aSelMgr ) {
351 SALOME_ListIO anIOList;
352 anIOList.Append( new SALOME_InteractiveObject( myEntry.toLatin1(), "", "" ) );
353 aSelMgr->setSelectedObjects( anIOList, true );
358 ProcessVoidEvent( new TEvent( theEntry ) );
362 \brief Remove the object from the selection.
363 \param theEntry object entry
365 void SALOMEGUI_Swig::RemoveIObject( const char* theEntry )
367 class TEvent: public SALOME_Event
371 TEvent( const char* theEntry ) : myEntry( theEntry ) {}
372 virtual void Execute()
374 if ( LightApp_Application* anApp = getApplication() ) {
375 LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>( anApp->activeStudy() ); // for sure!
376 LightApp_SelectionMgr* aSelMgr = anApp->selectionMgr();
377 if ( aStudy && aSelMgr ) {
378 SALOME_ListIO anIOList;
379 // VSR: temporary solution, until LightApp_SelectionMgr::unsetSelectedObjects() method appears
380 // Lately this should be replaced by the following:
381 // anIOList.Append( new SALOME_InteractiveObject( myEntry, "", "" ) );
382 // aSelMgr->unsetSelectedObjects( anIOList );
383 ///////////////////////////////////////////////
384 aSelMgr->selectedObjects( anIOList );
385 SALOME_ListIteratorOfListIO anIter( anIOList );
386 for( ; anIter.More(); anIter.Next() ) {
387 if ( anIter.Value()->isSame( new SALOME_InteractiveObject( myEntry.toLatin1(), "", "" ) ) ) {
388 anIOList.Remove( anIter );
389 aSelMgr->setSelectedObjects( anIOList, true );
397 ProcessVoidEvent( new TEvent( theEntry ) );
401 \brief Clear selection (unselect all objects).
403 void SALOMEGUI_Swig::ClearIObjects()
405 class TEvent: public SALOME_Event
409 virtual void Execute()
411 if ( LightApp_Application* anApp = getApplication() ) {
412 LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>( anApp->activeStudy() ); // for sure!
413 LightApp_SelectionMgr* aSelMgr = anApp->selectionMgr();
414 if ( aStudy && aSelMgr )
415 aSelMgr->clearSelected();
419 ProcessVoidEvent( new TEvent() );
423 \brief Display an object in the current view window.
425 The presentable object should be previously created and
426 displayed in this viewer.
428 \param theEntry object entry
430 void SALOMEGUI_Swig::Display( const char* theEntry )
432 class TEvent: public SALOME_Event
436 TEvent( const char* theEntry ) : myEntry( theEntry ) {}
437 virtual void Execute() {
438 LightApp_Application* anApp = getApplication();
439 LightApp_Study* aStudy = getActiveStudy();
440 if ( anApp && aStudy ) {
441 QString mname = anApp->moduleTitle( aStudy->componentDataType( myEntry ) );
442 LightApp_Displayer* d = LightApp_Displayer::FindDisplayer( mname, true );
445 if( aStudy->isComponent( myEntry ) )
446 aStudy->children( myEntry, entries );
448 entries.append( myEntry );
449 foreach( QString entry, entries )
450 d->Display( aStudy->referencedToEntry( entry ), false, 0 );
455 ProcessVoidEvent( new TEvent( theEntry ) );
459 \brief Displays an object in the current view window and
460 erases all other ones.
462 The presentable object should be previously created and
463 displayed in this viewer.
465 \param theEntry object entry
467 void SALOMEGUI_Swig::DisplayOnly( const char* theEntry )
469 class TEvent: public SALOME_Event
473 TEvent( const char* theEntry ) : myEntry( theEntry ) {}
474 virtual void Execute()
476 LightApp_Application* anApp = getApplication();
477 LightApp_Study* aStudy = getActiveStudy();
478 if ( anApp && aStudy ) {
480 aStudy->components( comps );
481 foreach( QString comp, comps ) {
482 LightApp_Displayer* d = LightApp_Displayer::FindDisplayer( anApp->moduleTitle( comp ), true );
483 if ( d ) d->EraseAll( false, false, 0 );
486 QString mname = anApp->moduleTitle( aStudy->componentDataType( myEntry ) );
487 LightApp_Displayer* d = LightApp_Displayer::FindDisplayer( mname, true );
490 if( aStudy->isComponent( myEntry ) )
491 aStudy->children( myEntry, entries );
493 entries.append( myEntry );
494 foreach( QString entry, entries )
495 d->Display( aStudy->referencedToEntry( entry ), false, 0 );
500 ProcessVoidEvent( new TEvent( theEntry ) );
504 \brief Erase an object in the current view window.
506 The presentable object should be previously created and
507 displayed in this viewer.
509 \param theEntry object entry
511 void SALOMEGUI_Swig::Erase( const char* theEntry )
513 class TEvent: public SALOME_Event
517 TEvent( const char* theEntry ) : myEntry( theEntry ) {}
518 virtual void Execute()
520 LightApp_Application* anApp = getApplication();
521 LightApp_Study* aStudy = getActiveStudy();
522 if ( anApp && aStudy ) {
523 QString mname = anApp->moduleTitle( aStudy->componentDataType( myEntry ) );
524 LightApp_Displayer* d = LightApp_Displayer::FindDisplayer( mname, true );
527 if( aStudy->isComponent( myEntry ) )
528 aStudy->children( myEntry, entries );
530 entries.append( myEntry );
531 foreach( QString entry, entries )
532 d->Erase( aStudy->referencedToEntry( entry ), false, false, 0 );
537 ProcessVoidEvent( new TEvent( theEntry ) );
541 \brief Display all active module's presentable
542 child objects in the current view window.
544 The presentable objects should be previously created and
545 displayed in this viewer.
547 void SALOMEGUI_Swig::DisplayAll()
549 class TEvent: public SALOME_Event
553 virtual void Execute()
555 LightApp_Application* anApp = getApplication();
556 LightApp_Study* aStudy = getActiveStudy();
557 if ( anApp && aStudy ) {
559 aStudy->components( comps );
560 foreach( QString comp, comps ) {
561 LightApp_Displayer* d = LightApp_Displayer::FindDisplayer( anApp->moduleTitle( comp ), true );
564 aStudy->children( aStudy->centry( comp ), entries );
565 foreach( QString entry, entries )
566 d->Display( aStudy->referencedToEntry( entry ), false, 0 );
572 ProcessVoidEvent( new TEvent() );
576 \brief Erase all objects from the current view window.
578 void SALOMEGUI_Swig::EraseAll()
580 class TEvent: public SALOME_Event
584 virtual void Execute()
586 LightApp_Application* anApp = getApplication();
587 LightApp_Study* aStudy = getActiveStudy();
588 if ( anApp && aStudy ) {
590 aStudy->components( comps );
591 foreach( QString comp, comps ) {
592 LightApp_Displayer* d = LightApp_Displayer::FindDisplayer( anApp->moduleTitle( comp ), true );
593 if ( d ) d->EraseAll( false, false, 0 );
598 ProcessVoidEvent( new TEvent() );
602 \fn bool SALOMEGUI_Swig::IsInCurrentView( const char* theEntry )
603 \brief Check it the object is displayed in the current view window.
605 VSR: For the current moment implemented for OCC and VTK viewers only.
607 \param theEntry object entry
608 \return \c true if the object with given entry is displayed
609 in the current viewer
612 class TIsInViewerEvent: public SALOME_Event
616 typedef bool TResult;
618 TIsInViewerEvent( const char* theEntry ) : myEntry( theEntry ), myResult( false ) {}
619 virtual void Execute()
621 if ( LightApp_Application* anApp = getApplication() ) {
622 SUIT_ViewWindow* window = anApp->desktop()->activeWindow();
624 SALOME_View* view = dynamic_cast<SALOME_View*>( window->getViewManager()->getActiveView() );
626 SALOME_Prs* aPrs = view->CreatePrs( myEntry.toLatin1() );
627 myResult = !aPrs->IsNull();
633 bool SALOMEGUI_Swig::IsInCurrentView( const char* theEntry )
635 return ProcessEvent( new TIsInViewerEvent( theEntry ) );
639 \brief Update (repaint) current view window.
641 void SALOMEGUI_Swig::UpdateView()
643 class TEvent: public SALOME_Event
647 virtual void Execute()
649 if ( LightApp_Application* anApp = getApplication() ) {
650 SUIT_ViewWindow* window = anApp->desktop()->activeWindow();
652 SALOME_View* view = dynamic_cast<SALOME_View*>( window->getViewManager()->getActiveView() );
659 ProcessVoidEvent( new TEvent() );
663 \brief Fit current view window to display all its contents.
665 void SALOMEGUI_Swig::FitAll()
667 class TEvent: public SALOME_Event
671 virtual void Execute()
673 if ( LightApp_Application* anApp = getApplication() ) {
674 SUIT_ViewWindow* window = anApp->desktop()->activeWindow();
676 #ifndef DISABLE_SALOMEOBJECT
677 #ifndef DISABLE_VTKVIEWER
678 if ( dynamic_cast<SVTK_ViewWindow*>( window ) )
679 ( dynamic_cast<SVTK_ViewWindow*>( window ) )->onFitAll();
681 #ifndef DISABLE_PLOT2DVIEWER
682 if ( dynamic_cast<SPlot2d_ViewWindow*>( window ) )
683 ( dynamic_cast<SPlot2d_ViewWindow*>( window ) )->onFitAll();
686 #ifndef DISABLE_OCCVIEWER
687 if ( dynamic_cast<OCCViewer_ViewWindow*>( window ) )
688 ( dynamic_cast<OCCViewer_ViewWindow*>( window ) )->onFitAll();
694 ProcessVoidEvent( new TEvent() );
698 \brief Reset current view window to the default state.
700 void SALOMEGUI_Swig::ResetView()
702 class TEvent: public SALOME_Event
706 virtual void Execute()
708 if ( LightApp_Application* anApp = getApplication() ) {
709 SUIT_ViewWindow* window = anApp->desktop()->activeWindow();
711 #ifndef DISABLE_SALOMEOBJECT
712 #ifndef DISABLE_VTKVIEWER
713 if ( dynamic_cast<SVTK_ViewWindow*>( window ) )
714 (dynamic_cast<SVTK_ViewWindow*>( window ))->onResetView();
716 #ifndef DISABLE_PLOT2DVIEWER
717 if ( dynamic_cast<SPlot2d_ViewWindow*>( window ) )
718 (dynamic_cast<SPlot2d_ViewWindow*>( window ))->onFitAll();
719 // VSR: there is no 'ResetView' functionality for Plot2d viewer,
720 // so we use 'FitAll' instead.
723 #ifndef DISABLE_OCCVIEWER
724 if ( dynamic_cast<OCCViewer_ViewWindow*>( window ) )
725 (dynamic_cast<OCCViewer_ViewWindow*>( window ))->onResetView();
731 ProcessVoidEvent( new TEvent() );
735 \brief View operation type.
739 __ViewTop, //!< view top side
740 __ViewBottom, //!< view bottom side
741 __ViewLeft, //!< view left side
742 __ViewRight, //!< view right side
743 __ViewFront, //!< view front side
744 __ViewBack //!< view back side
748 \brief Change the view of the current view window.
750 \param view view operation type
752 static void setView( int view )
754 class TEvent: public SALOME_Event
759 TEvent( int view ) : myView( view ) {}
760 virtual void Execute()
762 if ( LightApp_Application* anApp = getApplication() ) {
763 SUIT_ViewWindow* window = anApp->desktop()->activeWindow();
765 #ifndef DISABLE_SALOMEOBJECT
766 #ifndef DISABLE_VTKVIEWER
767 if ( dynamic_cast<SVTK_ViewWindow*>( window ) ) {
770 (dynamic_cast<SVTK_ViewWindow*>( window ))->onTopView(); break;
772 (dynamic_cast<SVTK_ViewWindow*>( window ))->onBottomView(); break;
774 (dynamic_cast<SVTK_ViewWindow*>( window ))->onLeftView(); break;
776 (dynamic_cast<SVTK_ViewWindow*>( window ))->onRightView(); break;
778 (dynamic_cast<SVTK_ViewWindow*>( window ))->onFrontView(); break;
780 (dynamic_cast<SVTK_ViewWindow*>( window ))->onBackView(); break;
787 #ifndef DISABLE_OCCVIEWER
788 if ( dynamic_cast<OCCViewer_ViewWindow*>( window ) ) {
791 (dynamic_cast<OCCViewer_ViewWindow*>( window ))->onTopView(); break;
793 (dynamic_cast<OCCViewer_ViewWindow*>( window ))->onBottomView(); break;
795 (dynamic_cast<OCCViewer_ViewWindow*>( window ))->onLeftView(); break;
797 (dynamic_cast<OCCViewer_ViewWindow*>( window ))->onRightView(); break;
799 (dynamic_cast<OCCViewer_ViewWindow*>( window ))->onFrontView(); break;
801 (dynamic_cast<OCCViewer_ViewWindow*>( window ))->onBackView(); break;
811 ProcessVoidEvent( new TEvent( view ) );
815 \brief Switch current view window to show the top view.
817 void SALOMEGUI_Swig::ViewTop()
819 setView( __ViewTop );
823 \brief Switch current view window to show the bottom view
825 void SALOMEGUI_Swig::ViewBottom()
827 setView( __ViewBottom );
831 \brief Switch current view window to show the left view
833 void SALOMEGUI_Swig::ViewLeft()
835 setView( __ViewLeft );
839 \brief Switch current view window to show the right view
841 void SALOMEGUI_Swig::ViewRight()
843 setView( __ViewRight );
847 \brief Switch current view window to show the front view
849 void SALOMEGUI_Swig::ViewFront()
851 setView( __ViewFront );
855 \brief Switch current view window to show the back view
857 void SALOMEGUI_Swig::ViewBack()
859 setView( __ViewBack );