1 // Copyright (C) 2007-2013 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.
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 <SOCC_ViewModel.h>
44 #include <SVTK_ViewModel.h>
45 #include <SVTK_ViewWindow.h>
46 #include <SOCC_ViewWindow.h>
47 #include <SPlot2d_ViewWindow.h>
49 #include <SALOME_Event.h>
50 #include <SALOME_ListIO.hxx>
51 #include <SALOME_InteractiveObject.hxx>
52 #include <SALOME_ListIteratorOfListIO.hxx>
56 \brief Python interface module for SALOME GUI.
58 This module provides an access to the SALOME GUI implementing set of functions
59 which can be used from Python. This module is implemented using SWIG wrappings
60 for some GUI functionality:
61 - getActiveStudyId(), getActiveStudyName() : get active study identifier and name
62 - updateObjBrowser() : update contents of the Object Browser
63 - SelectedCount() : get number of currently selected items
64 - getSelected() : get entry of the speicified selected item
65 - ClearIObjects() : clear selection
66 - Display(), DisplayOnly(), Erase() : display/erase objects
69 Instance of this class is created every time "import salome" line is typed
70 - in IAPP embedded Python interpretor (SALOME_Session_Server executable)
71 - in inline Python nodes in Supervisor (in SALOME_Container executable)
72 - in stand-alone Python console outside any executable
74 SALOME GUI (desktop and other objects) is only available in SALOME_Session_Server.
75 It means that it can not be accessed from the external Python console.
80 sg = libSALOME_Swig.SALOMEGUI_Swig()
82 selcount = sg.SelectedCount()
84 sg.Erase( sg.getSelected( 0 ) )
90 --- INTERNAL COMMENTS SECTION ---
92 ASV : 03.12.04 : added checking for NULL GUI objects in almost all methods.
93 In the scope of fixing bug PAL6869.
95 VSR : 19.04.05 : Reimplemented for new SALOME GUI (SUIT-based)
96 All methods are implemeted using Event mechanism.
97 Display/Erase methods use SALOME_Prs/SALOME_View mechanism. It is currently
98 implemented only for OCC and VTK viewers.
102 \brief Get active application object
104 \return active application or 0 if there is no any
106 static LightApp_Application* getApplication()
108 if ( SUIT_Session::session() )
109 return dynamic_cast<LightApp_Application*>( SUIT_Session::session()->activeApplication() );
114 \brief Get active study object
116 \return active study or 0 if there is no study opened
118 static LightApp_Study* getActiveStudy()
120 if ( getApplication() )
121 return dynamic_cast<LightApp_Study*>( getApplication()->activeStudy() );
128 SALOMEGUI_Swig::SALOMEGUI_Swig()
135 SALOMEGUI_Swig::~SALOMEGUI_Swig()
140 \fn bool SALOMEGUI_Swig::hasDesktop()
141 \brief Check GUI availability.
142 \return \c true if GUI is available
145 class THasDesktopEvent: public SALOME_Event
148 typedef bool TResult;
150 THasDesktopEvent() : myResult( false ) {}
151 virtual void Execute()
153 myResult = (bool)( getApplication() && getApplication()->desktop() );
156 bool SALOMEGUI_Swig::hasDesktop()
158 return ProcessEvent( new THasDesktopEvent() );
162 \brief Update active study's Object Browser.
163 \param updateSelection this parameter is obsolete
165 void SALOMEGUI_Swig::updateObjBrowser( bool /*updateSelection*/ )
167 class TEvent: public SALOME_Event
171 virtual void Execute()
173 if ( LightApp_Application* anApp = getApplication() ) {
174 anApp->updateObjectBrowser();
175 anApp->updateActions(); //SRN: added in order to update the toolbar
179 ProcessVoidEvent( new TEvent() );
183 \fn int SALOMEGUI_Swig::getActiveStudyId()
184 \brief Get active study identifier
185 \return active study's ID or 0 if there is no active study
188 class TGetActiveStudyIdEvent: public SALOME_Event
193 TGetActiveStudyIdEvent() : myResult( 0 ) {}
194 virtual void Execute()
196 if ( LightApp_Study* aStudy = getActiveStudy() ) {
197 myResult = aStudy->id();
201 int SALOMEGUI_Swig::getActiveStudyId()
203 return ProcessEvent( new TGetActiveStudyIdEvent() );
207 \fn const char* SALOMEGUI_Swig::getActiveStudyName()
208 \brief Get active study name
209 \return active study's name or null string if there is no active study
212 class TGetActiveStudyNameEvent: public SALOME_Event
215 typedef std::string TResult;
217 TGetActiveStudyNameEvent() {}
218 virtual void Execute()
220 if ( LightApp_Study* aStudy = getActiveStudy() ) {
221 myResult = aStudy->id();
225 const char* SALOMEGUI_Swig::getActiveStudyName()
227 std::string result = ProcessEvent( new TGetActiveStudyNameEvent() );
228 return result.empty() ? 0 : result.c_str();
232 \fn const char* SALOMEGUI_Swig::getComponentName( const char* componentUserName )
233 \brief Get name of the component by its title (user name)
234 \param componentUserName component title (user name)
235 \return component name or null string if component title is invalid
239 \fn const char* SALOMEGUI_Swig::getComponentUserName( const char* componentName )
240 \brief Get title (user name) of the component by its name
241 \param componentName component name
242 \return component title or null string if component name is invalid
245 class TGetComponentNameEvent: public SALOME_Event
248 typedef QString TResult;
252 TGetComponentNameEvent( const QString& name, bool isUserName )
253 : myName( name ), myIsUserName( isUserName ) {}
254 virtual void Execute()
256 if ( LightApp_Application* app = getApplication() ) {
257 myResult = myIsUserName ? app->moduleTitle( myName ) : app->moduleName( myName );
261 const char* SALOMEGUI_Swig::getComponentName( const char* componentUserName )
263 QString result = ProcessEvent( new TGetComponentNameEvent( componentUserName, false ) );
264 return result.isEmpty() ? 0 : strdup( result.toLatin1().constData() );
266 const char* SALOMEGUI_Swig::getComponentUserName( const char* componentName )
268 QString result = ProcessEvent( new TGetComponentNameEvent( componentName, true ) );
269 return result.isEmpty() ? 0 : strdup( result.toLatin1().constData() );
273 \fn int SALOMEGUI_Swig::SelectedCount()
274 \brief Get number of selected items
275 \return number of selected items in the active study
279 \fn const char* SALOMEGUI_Swig::getSelected( int index )
280 \brief Get entry of the specified selected item
281 \param index selected object index
282 \return selected object entry (null string if index is invalid)
285 class TGetSelectedEvent: public SALOME_Event
288 typedef QStringList TResult;
290 TGetSelectedEvent() {}
291 virtual void Execute()
293 if ( LightApp_Application* anApp = getApplication() ) {
294 LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>( anApp->activeStudy() ); // for sure!
295 LightApp_SelectionMgr* aSelMgr = anApp->selectionMgr();
296 if ( aStudy && aSelMgr ) {
297 SUIT_DataOwnerPtrList aList;
298 aSelMgr->selected( aList );
300 for ( SUIT_DataOwnerPtrList::const_iterator itr = aList.begin();
301 itr != aList.end(); ++itr ) {
302 const LightApp_DataOwner* owner =
303 dynamic_cast<const LightApp_DataOwner*>( (*itr).operator->() );
306 QString entry = owner->entry();
307 if( !myResult.contains( entry ) )
308 myResult.append( entry );
314 int SALOMEGUI_Swig::SelectedCount()
316 QStringList selected = ProcessEvent( new TGetSelectedEvent() );
317 return selected.count();
319 const char* SALOMEGUI_Swig::getSelected( int index )
321 QStringList selected = ProcessEvent( new TGetSelectedEvent() );
322 return index >= 0 && index < selected.count() ?
323 strdup( selected[ index ].toLatin1().constData() ) : 0;
327 \brief Add an object to the current selection.
328 \param theEntry object entry
330 void SALOMEGUI_Swig::AddIObject( const char* theEntry )
332 class TEvent: public SALOME_Event
336 TEvent( const char* theEntry ) : myEntry( theEntry ) {}
337 virtual void Execute()
339 if ( LightApp_Application* anApp = getApplication() ) {
340 LightApp_Study* aStudy = dynamic_cast<LightApp_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.toLatin1(), "", "" ) );
345 aSelMgr->setSelectedObjects( anIOList, true );
350 ProcessVoidEvent( new TEvent( theEntry ) );
354 \brief Remove the object from the selection.
355 \param theEntry object entry
357 void SALOMEGUI_Swig::RemoveIObject( const char* theEntry )
359 class TEvent: public SALOME_Event
363 TEvent( const char* theEntry ) : myEntry( theEntry ) {}
364 virtual void Execute()
366 if ( LightApp_Application* anApp = getApplication() ) {
367 LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>( anApp->activeStudy() ); // for sure!
368 LightApp_SelectionMgr* aSelMgr = anApp->selectionMgr();
369 if ( aStudy && aSelMgr ) {
370 SALOME_ListIO anIOList;
371 // VSR: temporary solution, until LightApp_SelectionMgr::unsetSelectedObjects() method appears
372 // Lately this should be replaced by the following:
373 // anIOList.Append( new SALOME_InteractiveObject( myEntry, "", "" ) );
374 // aSelMgr->unsetSelectedObjects( anIOList );
375 ///////////////////////////////////////////////
376 aSelMgr->selectedObjects( anIOList );
377 SALOME_ListIteratorOfListIO anIter( anIOList );
378 for( ; anIter.More(); anIter.Next() ) {
379 if ( anIter.Value()->isSame( new SALOME_InteractiveObject( myEntry.toLatin1(), "", "" ) ) ) {
380 anIOList.Remove( anIter );
381 aSelMgr->setSelectedObjects( anIOList, true );
389 ProcessVoidEvent( new TEvent( theEntry ) );
393 \brief Clear selection (unselect all objects).
395 void SALOMEGUI_Swig::ClearIObjects()
397 class TEvent: public SALOME_Event
401 virtual void Execute()
403 if ( LightApp_Application* anApp = getApplication() ) {
404 LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>( anApp->activeStudy() ); // for sure!
405 LightApp_SelectionMgr* aSelMgr = anApp->selectionMgr();
406 if ( aStudy && aSelMgr )
407 aSelMgr->clearSelected();
411 ProcessVoidEvent( new TEvent() );
415 \brief Display an object in the current view window.
417 The presentable object should be previously created and
418 displayed in this viewer.
420 \param theEntry object entry
422 void SALOMEGUI_Swig::Display( const char* theEntry )
424 class TEvent: public SALOME_Event
428 TEvent( const char* theEntry ) : myEntry( theEntry ) {}
429 virtual void Execute() {
430 LightApp_Application* anApp = getApplication();
431 LightApp_Study* aStudy = getActiveStudy();
432 if ( anApp && aStudy ) {
433 QString mname = anApp->moduleTitle( aStudy->componentDataType( myEntry ) );
434 LightApp_Displayer* d = LightApp_Displayer::FindDisplayer( mname, true );
437 if( aStudy->isComponent( myEntry ) )
438 aStudy->children( myEntry, entries );
440 entries.append( myEntry );
441 foreach( QString entry, entries )
442 d->Display( aStudy->referencedToEntry( entry ), false, 0 );
447 ProcessVoidEvent( new TEvent( theEntry ) );
451 \brief Displays an object in the current view window and
452 erases all other ones.
454 The presentable object should be previously created and
455 displayed in this viewer.
457 \param theEntry object entry
459 void SALOMEGUI_Swig::DisplayOnly( const char* theEntry )
461 class TEvent: public SALOME_Event
465 TEvent( const char* theEntry ) : myEntry( theEntry ) {}
466 virtual void Execute()
468 LightApp_Application* anApp = getApplication();
469 LightApp_Study* aStudy = getActiveStudy();
470 if ( anApp && aStudy ) {
472 aStudy->components( comps );
473 foreach( QString comp, comps ) {
474 LightApp_Displayer* d = LightApp_Displayer::FindDisplayer( anApp->moduleTitle( comp ), true );
475 if ( d ) d->EraseAll( false, false, 0 );
478 QString mname = anApp->moduleTitle( aStudy->componentDataType( myEntry ) );
479 LightApp_Displayer* d = LightApp_Displayer::FindDisplayer( mname, true );
482 if( aStudy->isComponent( myEntry ) )
483 aStudy->children( myEntry, entries );
485 entries.append( myEntry );
486 foreach( QString entry, entries )
487 d->Display( aStudy->referencedToEntry( entry ), false, 0 );
492 ProcessVoidEvent( new TEvent( theEntry ) );
496 \brief Erase an object in the current view window.
498 The presentable object should be previously created and
499 displayed in this viewer.
501 \param theEntry object entry
503 void SALOMEGUI_Swig::Erase( const char* theEntry )
505 class TEvent: public SALOME_Event
509 TEvent( const char* theEntry ) : myEntry( theEntry ) {}
510 virtual void Execute()
512 LightApp_Application* anApp = getApplication();
513 LightApp_Study* aStudy = getActiveStudy();
514 if ( anApp && aStudy ) {
515 QString mname = anApp->moduleTitle( aStudy->componentDataType( myEntry ) );
516 LightApp_Displayer* d = LightApp_Displayer::FindDisplayer( mname, true );
519 if( aStudy->isComponent( myEntry ) )
520 aStudy->children( myEntry, entries );
522 entries.append( myEntry );
523 foreach( QString entry, entries )
524 d->Erase( aStudy->referencedToEntry( entry ), false, false, 0 );
529 ProcessVoidEvent( new TEvent( theEntry ) );
533 \brief Display all active module's presentable
534 child objects in the current view window.
536 The presentable objects should be previously created and
537 displayed in this viewer.
539 void SALOMEGUI_Swig::DisplayAll()
541 class TEvent: public SALOME_Event
545 virtual void Execute()
547 LightApp_Application* anApp = getApplication();
548 LightApp_Study* aStudy = getActiveStudy();
549 if ( anApp && aStudy ) {
551 aStudy->components( comps );
552 foreach( QString comp, comps ) {
553 LightApp_Displayer* d = LightApp_Displayer::FindDisplayer( anApp->moduleTitle( comp ), true );
556 aStudy->children( aStudy->centry( comp ), entries );
557 foreach( QString entry, entries )
558 d->Display( aStudy->referencedToEntry( entry ), false, 0 );
564 ProcessVoidEvent( new TEvent() );
568 \brief Erase all objects from the current view window.
570 void SALOMEGUI_Swig::EraseAll()
572 class TEvent: public SALOME_Event
576 virtual void Execute()
578 LightApp_Application* anApp = getApplication();
579 LightApp_Study* aStudy = getActiveStudy();
580 if ( anApp && aStudy ) {
582 aStudy->components( comps );
583 foreach( QString comp, comps ) {
584 LightApp_Displayer* d = LightApp_Displayer::FindDisplayer( anApp->moduleTitle( comp ), true );
585 if ( d ) d->EraseAll( false, false, 0 );
590 ProcessVoidEvent( new TEvent() );
594 \fn bool SALOMEGUI_Swig::IsInCurrentView( const char* theEntry )
595 \brief Check it the object is displayed in the current view window.
597 VSR: For the current moment implemented for OCC and VTK viewers only.
599 \param theEntry object entry
600 \return \c true if the object with given entry is displayed
601 in the current viewer
604 class TIsInViewerEvent: public SALOME_Event
608 typedef bool TResult;
610 TIsInViewerEvent( const char* theEntry ) : myEntry( theEntry ), myResult( false ) {}
611 virtual void Execute()
613 if ( LightApp_Application* anApp = getApplication() ) {
614 SUIT_ViewWindow* window = anApp->desktop()->activeWindow();
616 SALOME_View* view = dynamic_cast<SALOME_View*>( window->getViewManager()->getViewModel() );
618 SALOME_Prs* aPrs = view->CreatePrs( myEntry.toLatin1() );
619 myResult = !aPrs->IsNull();
625 bool SALOMEGUI_Swig::IsInCurrentView( const char* theEntry )
627 return ProcessEvent( new TIsInViewerEvent( theEntry ) );
631 \brief Update (repaint) current view window.
633 void SALOMEGUI_Swig::UpdateView()
635 class TEvent: public SALOME_Event
639 virtual void Execute()
641 if ( LightApp_Application* anApp = getApplication() ) {
642 SUIT_ViewWindow* window = anApp->desktop()->activeWindow();
644 SALOME_View* view = dynamic_cast<SALOME_View*>( window->getViewManager()->getViewModel() );
651 ProcessVoidEvent( new TEvent() );
655 \brief Fit current view window to display all its contents.
657 void SALOMEGUI_Swig::FitAll()
659 class TEvent: public SALOME_Event
663 virtual void Execute()
665 if ( LightApp_Application* anApp = getApplication() ) {
666 SUIT_ViewWindow* window = anApp->desktop()->activeWindow();
668 if ( dynamic_cast<SVTK_ViewWindow*>( window ) )
669 ( dynamic_cast<SVTK_ViewWindow*>( window ) )->onFitAll();
670 else if ( dynamic_cast<OCCViewer_ViewWindow*>( window ) )
671 ( dynamic_cast<OCCViewer_ViewWindow*>( window ) )->onFitAll();
672 else if ( dynamic_cast<SPlot2d_ViewWindow*>( window ) )
673 ( dynamic_cast<SPlot2d_ViewWindow*>( window ) )->onFitAll();
678 ProcessVoidEvent( new TEvent() );
682 \brief Reset current view window to the default state.
684 void SALOMEGUI_Swig::ResetView()
686 class TEvent: public SALOME_Event
690 virtual void Execute()
692 if ( LightApp_Application* anApp = getApplication() ) {
693 SUIT_ViewWindow* window = anApp->desktop()->activeWindow();
695 if ( dynamic_cast<SVTK_ViewWindow*>( window ) )
696 (dynamic_cast<SVTK_ViewWindow*>( window ))->onResetView();
697 else if ( dynamic_cast<OCCViewer_ViewWindow*>( window ) )
698 (dynamic_cast<OCCViewer_ViewWindow*>( window ))->onResetView();
699 else if ( dynamic_cast<SPlot2d_ViewWindow*>( window ) )
700 (dynamic_cast<SPlot2d_ViewWindow*>( window ))->onFitAll();
701 // VSR: there is no 'ResetView' functionality for Plot2d viewer,
702 // so we use 'FitAll' instead.
707 ProcessVoidEvent( new TEvent() );
711 \brief View operation type.
715 __ViewTop, //!< view top side
716 __ViewBottom, //!< view bottom side
717 __ViewLeft, //!< view left side
718 __ViewRight, //!< view right side
719 __ViewFront, //!< view front side
720 __ViewBack //!< view back side
724 \brief Change the view of the current view window.
726 \param view view operation type
728 static void setView( int view )
730 class TEvent: public SALOME_Event
735 TEvent( int view ) : myView( view ) {}
736 virtual void Execute()
738 if ( LightApp_Application* anApp = getApplication() ) {
739 SUIT_ViewWindow* window = anApp->desktop()->activeWindow();
741 if ( dynamic_cast<SVTK_ViewWindow*>( window ) ) {
744 (dynamic_cast<SVTK_ViewWindow*>( window ))->onTopView(); break;
746 (dynamic_cast<SVTK_ViewWindow*>( window ))->onBottomView(); break;
748 (dynamic_cast<SVTK_ViewWindow*>( window ))->onLeftView(); break;
750 (dynamic_cast<SVTK_ViewWindow*>( window ))->onRightView(); break;
752 (dynamic_cast<SVTK_ViewWindow*>( window ))->onFrontView(); break;
754 (dynamic_cast<SVTK_ViewWindow*>( window ))->onBackView(); break;
759 else if ( dynamic_cast<OCCViewer_ViewWindow*>( window ) ) {
762 (dynamic_cast<OCCViewer_ViewWindow*>( window ))->onTopView(); break;
764 (dynamic_cast<OCCViewer_ViewWindow*>( window ))->onBottomView(); break;
766 (dynamic_cast<OCCViewer_ViewWindow*>( window ))->onLeftView(); break;
768 (dynamic_cast<OCCViewer_ViewWindow*>( window ))->onRightView(); break;
770 (dynamic_cast<OCCViewer_ViewWindow*>( window ))->onFrontView(); break;
772 (dynamic_cast<OCCViewer_ViewWindow*>( window ))->onBackView(); break;
781 ProcessVoidEvent( new TEvent( view ) );
785 \brief Switch current view window to show the top view.
787 void SALOMEGUI_Swig::ViewTop()
789 setView( __ViewTop );
793 \brief Switch current view window to show the bottom view
795 void SALOMEGUI_Swig::ViewBottom()
797 setView( __ViewBottom );
801 \brief Switch current view window to show the left view
803 void SALOMEGUI_Swig::ViewLeft()
805 setView( __ViewLeft );
809 \brief Switch current view window to show the right view
811 void SALOMEGUI_Swig::ViewRight()
813 setView( __ViewRight );
817 \brief Switch current view window to show the front view
819 void SALOMEGUI_Swig::ViewFront()
821 setView( __ViewFront );
825 \brief Switch current view window to show the back view
827 void SALOMEGUI_Swig::ViewBack()
829 setView( __ViewBack );