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 #include <SALOME_ListIteratorOfListIO.hxx>
49 #ifndef DISABLE_OCCVIEWER
50 #include <SOCC_ViewModel.h>
51 #include <SOCC_ViewWindow.h>
53 #ifndef DISABLE_VTKVIEWER
54 #include <SVTK_ViewModel.h>
55 #include <SVTK_ViewWindow.h>
57 #ifndef DISABLE_PLOT2DVIEWER
58 #include <SPlot2d_ViewWindow.h>
65 \brief Python interface module for SALOME GUI.
67 This module provides an access to the SALOME GUI implementing set of functions
68 which can be used from Python. This module is implemented using SWIG wrappings
69 for some GUI functionality:
70 - getActiveStudyId(), getActiveStudyName() : get active study identifier and name
71 - updateObjBrowser() : update contents of the Object Browser
72 - SelectedCount() : get number of currently selected items
73 - getSelected() : get entry of the speicified selected item
74 - ClearIObjects() : clear selection
75 - Display(), DisplayOnly(), Erase() : display/erase objects
78 Instance of this class is created every time "import salome" line is typed
79 - in IAPP embedded Python interpretor (SALOME_Session_Server executable)
80 - in inline Python nodes in Supervisor (in SALOME_Container executable)
81 - in stand-alone Python console outside any executable
83 SALOME GUI (desktop and other objects) is only available in SALOME_Session_Server.
84 It means that it can not be accessed from the external Python console.
89 sg = libSALOME_Swig.SALOMEGUI_Swig()
91 selcount = sg.SelectedCount()
93 sg.Erase( sg.getSelected( 0 ) )
99 --- INTERNAL COMMENTS SECTION ---
101 ASV : 03.12.04 : added checking for NULL GUI objects in almost all methods.
102 In the scope of fixing bug PAL6869.
104 VSR : 19.04.05 : Reimplemented for new SALOME GUI (SUIT-based)
105 All methods are implemeted using Event mechanism.
106 Display/Erase methods use SALOME_Prs/SALOME_View mechanism. It is currently
107 implemented only for OCC and VTK viewers.
111 \brief Get active application object
113 \return active application or 0 if there is no any
115 static LightApp_Application* getApplication()
117 if ( SUIT_Session::session() )
118 return dynamic_cast<LightApp_Application*>( SUIT_Session::session()->activeApplication() );
123 \brief Get active study object
125 \return active study or 0 if there is no study opened
127 static LightApp_Study* getActiveStudy()
129 if ( getApplication() )
130 return dynamic_cast<LightApp_Study*>( getApplication()->activeStudy() );
137 SALOMEGUI_Swig::SALOMEGUI_Swig()
144 SALOMEGUI_Swig::~SALOMEGUI_Swig()
149 \fn bool SALOMEGUI_Swig::hasDesktop()
150 \brief Check GUI availability.
151 \return \c true if GUI is available
154 class THasDesktopEvent: public SALOME_Event
157 typedef bool TResult;
159 THasDesktopEvent() : myResult( false ) {}
160 virtual void Execute()
162 myResult = (bool)( getApplication() && getApplication()->desktop() );
165 bool SALOMEGUI_Swig::hasDesktop()
167 return ProcessEvent( new THasDesktopEvent() );
171 \brief Update active study's Object Browser.
172 \param updateSelection this parameter is obsolete
174 void SALOMEGUI_Swig::updateObjBrowser( bool /*updateSelection*/ )
176 class TEvent: public SALOME_Event
180 virtual void Execute()
182 if ( LightApp_Application* anApp = getApplication() ) {
183 anApp->updateObjectBrowser();
184 anApp->updateActions(); //SRN: added in order to update the toolbar
188 ProcessVoidEvent( new TEvent() );
192 \fn int SALOMEGUI_Swig::getActiveStudyId()
193 \brief Get active study identifier
194 \return active study's ID or 0 if there is no active study
197 class TGetActiveStudyIdEvent: public SALOME_Event
202 TGetActiveStudyIdEvent() : myResult( 0 ) {}
203 virtual void Execute()
205 if ( LightApp_Study* aStudy = getActiveStudy() ) {
206 myResult = aStudy->id();
210 int SALOMEGUI_Swig::getActiveStudyId()
212 return ProcessEvent( new TGetActiveStudyIdEvent() );
216 \fn const char* SALOMEGUI_Swig::getActiveStudyName()
217 \brief Get active study name
218 \return active study's name or null string if there is no active study
221 class TGetActiveStudyNameEvent: public SALOME_Event
224 typedef std::string TResult;
226 TGetActiveStudyNameEvent() {}
227 virtual void Execute()
229 if ( LightApp_Study* aStudy = getActiveStudy() ) {
230 myResult = aStudy->id();
234 const char* SALOMEGUI_Swig::getActiveStudyName()
236 std::string result = ProcessEvent( new TGetActiveStudyNameEvent() );
237 return result.empty() ? 0 : result.c_str();
241 \fn const char* SALOMEGUI_Swig::getComponentName( const char* componentUserName )
242 \brief Get name of the component by its title (user name)
243 \param componentUserName component title (user name)
244 \return component name or null string if component title is invalid
248 \fn const char* SALOMEGUI_Swig::getComponentUserName( const char* componentName )
249 \brief Get title (user name) of the component by its name
250 \param componentName component name
251 \return component title or null string if component name is invalid
254 class TGetComponentNameEvent: public SALOME_Event
257 typedef QString TResult;
261 TGetComponentNameEvent( const QString& name, bool isUserName )
262 : myName( name ), myIsUserName( isUserName ) {}
263 virtual void Execute()
265 if ( LightApp_Application* app = getApplication() ) {
266 myResult = myIsUserName ? app->moduleTitle( myName ) : app->moduleName( myName );
270 const char* SALOMEGUI_Swig::getComponentName( const char* componentUserName )
272 QString result = ProcessEvent( new TGetComponentNameEvent( componentUserName, false ) );
273 return result.isEmpty() ? 0 : strdup( result.toLatin1().constData() );
275 const char* SALOMEGUI_Swig::getComponentUserName( const char* componentName )
277 QString result = ProcessEvent( new TGetComponentNameEvent( componentName, true ) );
278 return result.isEmpty() ? 0 : strdup( result.toLatin1().constData() );
282 \fn int SALOMEGUI_Swig::SelectedCount()
283 \brief Get number of selected items
284 \return number of selected items in the active study
288 \fn const char* SALOMEGUI_Swig::getSelected( int index )
289 \brief Get entry of the specified selected item
290 \param index selected object index
291 \return selected object entry (null string if index is invalid)
294 class TGetSelectedEvent: public SALOME_Event
297 typedef QStringList TResult;
299 TGetSelectedEvent() {}
300 virtual void Execute()
302 if ( LightApp_Application* anApp = getApplication() ) {
303 LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>( anApp->activeStudy() ); // for sure!
304 LightApp_SelectionMgr* aSelMgr = anApp->selectionMgr();
305 if ( aStudy && aSelMgr ) {
306 SUIT_DataOwnerPtrList aList;
307 aSelMgr->selected( aList );
309 for ( SUIT_DataOwnerPtrList::const_iterator itr = aList.begin();
310 itr != aList.end(); ++itr ) {
311 const LightApp_DataOwner* owner =
312 dynamic_cast<const LightApp_DataOwner*>( (*itr).operator->() );
315 QString entry = owner->entry();
316 if( !myResult.contains( entry ) )
317 myResult.append( entry );
323 int SALOMEGUI_Swig::SelectedCount()
325 QStringList selected = ProcessEvent( new TGetSelectedEvent() );
326 return selected.count();
328 const char* SALOMEGUI_Swig::getSelected( int index )
330 QStringList selected = ProcessEvent( new TGetSelectedEvent() );
331 return index >= 0 && index < selected.count() ?
332 strdup( selected[ index ].toLatin1().constData() ) : 0;
336 \brief Add an object to the current selection.
337 \param theEntry object entry
339 void SALOMEGUI_Swig::AddIObject( const char* theEntry )
341 class TEvent: public SALOME_Event
345 TEvent( const char* theEntry ) : myEntry( theEntry ) {}
346 virtual void Execute()
348 if ( LightApp_Application* anApp = getApplication() ) {
349 LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>( anApp->activeStudy() ); // for sure!
350 LightApp_SelectionMgr* aSelMgr = anApp->selectionMgr();
351 if ( aStudy && aSelMgr ) {
352 SALOME_ListIO anIOList;
353 anIOList.Append( new SALOME_InteractiveObject( myEntry.toLatin1(), "", "" ) );
354 aSelMgr->setSelectedObjects( anIOList, true );
359 ProcessVoidEvent( new TEvent( theEntry ) );
363 \brief Remove the object from the selection.
364 \param theEntry object entry
366 void SALOMEGUI_Swig::RemoveIObject( const char* theEntry )
368 class TEvent: public SALOME_Event
372 TEvent( const char* theEntry ) : myEntry( theEntry ) {}
373 virtual void Execute()
375 if ( LightApp_Application* anApp = getApplication() ) {
376 LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>( anApp->activeStudy() ); // for sure!
377 LightApp_SelectionMgr* aSelMgr = anApp->selectionMgr();
378 if ( aStudy && aSelMgr ) {
379 SALOME_ListIO anIOList;
380 // VSR: temporary solution, until LightApp_SelectionMgr::unsetSelectedObjects() method appears
381 // Lately this should be replaced by the following:
382 // anIOList.Append( new SALOME_InteractiveObject( myEntry, "", "" ) );
383 // aSelMgr->unsetSelectedObjects( anIOList );
384 ///////////////////////////////////////////////
385 aSelMgr->selectedObjects( anIOList );
386 SALOME_ListIteratorOfListIO anIter( anIOList );
387 for( ; anIter.More(); anIter.Next() ) {
388 if ( anIter.Value()->isSame( new SALOME_InteractiveObject( myEntry.toLatin1(), "", "" ) ) ) {
389 anIOList.Remove( anIter );
390 aSelMgr->setSelectedObjects( anIOList, true );
398 ProcessVoidEvent( new TEvent( theEntry ) );
402 \brief Clear selection (unselect all objects).
404 void SALOMEGUI_Swig::ClearIObjects()
406 class TEvent: public SALOME_Event
410 virtual void Execute()
412 if ( LightApp_Application* anApp = getApplication() ) {
413 LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>( anApp->activeStudy() ); // for sure!
414 LightApp_SelectionMgr* aSelMgr = anApp->selectionMgr();
415 if ( aStudy && aSelMgr )
416 aSelMgr->clearSelected();
420 ProcessVoidEvent( new TEvent() );
424 \brief Display an object in the current view window.
426 The presentable object should be previously created and
427 displayed in this viewer.
429 \param theEntry object entry
431 void SALOMEGUI_Swig::Display( const char* theEntry )
433 class TEvent: public SALOME_Event
437 TEvent( const char* theEntry ) : myEntry( theEntry ) {}
438 virtual void Execute() {
439 LightApp_Application* anApp = getApplication();
440 LightApp_Study* aStudy = getActiveStudy();
441 if ( anApp && aStudy ) {
442 QString mname = anApp->moduleTitle( aStudy->componentDataType( myEntry ) );
443 LightApp_Displayer* d = LightApp_Displayer::FindDisplayer( mname, true );
446 if( aStudy->isComponent( myEntry ) )
447 aStudy->children( myEntry, entries );
449 entries.append( myEntry );
450 foreach( QString entry, entries )
451 d->Display( aStudy->referencedToEntry( entry ), false, 0 );
456 ProcessVoidEvent( new TEvent( theEntry ) );
460 \brief Displays an object in the current view window and
461 erases all other ones.
463 The presentable object should be previously created and
464 displayed in this viewer.
466 \param theEntry object entry
468 void SALOMEGUI_Swig::DisplayOnly( const char* theEntry )
470 class TEvent: public SALOME_Event
474 TEvent( const char* theEntry ) : myEntry( theEntry ) {}
475 virtual void Execute()
477 LightApp_Application* anApp = getApplication();
478 LightApp_Study* aStudy = getActiveStudy();
479 if ( anApp && aStudy ) {
481 aStudy->components( comps );
482 foreach( QString comp, comps ) {
483 LightApp_Displayer* d = LightApp_Displayer::FindDisplayer( anApp->moduleTitle( comp ), true );
484 if ( d ) d->EraseAll( false, false, 0 );
487 QString mname = anApp->moduleTitle( aStudy->componentDataType( myEntry ) );
488 LightApp_Displayer* d = LightApp_Displayer::FindDisplayer( mname, true );
491 if( aStudy->isComponent( myEntry ) )
492 aStudy->children( myEntry, entries );
494 entries.append( myEntry );
495 foreach( QString entry, entries )
496 d->Display( aStudy->referencedToEntry( entry ), false, 0 );
501 ProcessVoidEvent( new TEvent( theEntry ) );
505 \brief Erase an object in the current view window.
507 The presentable object should be previously created and
508 displayed in this viewer.
510 \param theEntry object entry
512 void SALOMEGUI_Swig::Erase( const char* theEntry )
514 class TEvent: public SALOME_Event
518 TEvent( const char* theEntry ) : myEntry( theEntry ) {}
519 virtual void Execute()
521 LightApp_Application* anApp = getApplication();
522 LightApp_Study* aStudy = getActiveStudy();
523 if ( anApp && aStudy ) {
524 QString mname = anApp->moduleTitle( aStudy->componentDataType( myEntry ) );
525 LightApp_Displayer* d = LightApp_Displayer::FindDisplayer( mname, true );
528 if( aStudy->isComponent( myEntry ) )
529 aStudy->children( myEntry, entries );
531 entries.append( myEntry );
532 foreach( QString entry, entries )
533 d->Erase( aStudy->referencedToEntry( entry ), false, false, 0 );
538 ProcessVoidEvent( new TEvent( theEntry ) );
542 \brief Display all active module's presentable
543 child objects in the current view window.
545 The presentable objects should be previously created and
546 displayed in this viewer.
548 void SALOMEGUI_Swig::DisplayAll()
550 class TEvent: public SALOME_Event
554 virtual void Execute()
556 LightApp_Application* anApp = getApplication();
557 LightApp_Study* aStudy = getActiveStudy();
558 if ( anApp && aStudy ) {
560 aStudy->components( comps );
561 foreach( QString comp, comps ) {
562 LightApp_Displayer* d = LightApp_Displayer::FindDisplayer( anApp->moduleTitle( comp ), true );
565 aStudy->children( aStudy->centry( comp ), entries );
566 foreach( QString entry, entries )
567 d->Display( aStudy->referencedToEntry( entry ), false, 0 );
573 ProcessVoidEvent( new TEvent() );
577 \brief Erase all objects from the current view window.
579 void SALOMEGUI_Swig::EraseAll()
581 class TEvent: public SALOME_Event
585 virtual void Execute()
587 LightApp_Application* anApp = getApplication();
588 LightApp_Study* aStudy = getActiveStudy();
589 if ( anApp && aStudy ) {
591 aStudy->components( comps );
592 foreach( QString comp, comps ) {
593 LightApp_Displayer* d = LightApp_Displayer::FindDisplayer( anApp->moduleTitle( comp ), true );
594 if ( d ) d->EraseAll( false, false, 0 );
599 ProcessVoidEvent( new TEvent() );
603 \fn bool SALOMEGUI_Swig::IsInCurrentView( const char* theEntry )
604 \brief Check it the object is displayed in the current view window.
606 VSR: For the current moment implemented for OCC and VTK viewers only.
608 \param theEntry object entry
609 \return \c true if the object with given entry is displayed
610 in the current viewer
613 class TIsInViewerEvent: public SALOME_Event
617 typedef bool TResult;
619 TIsInViewerEvent( const char* theEntry ) : myEntry( theEntry ), myResult( false ) {}
620 virtual void Execute()
622 if ( LightApp_Application* anApp = getApplication() ) {
623 SUIT_ViewWindow* window = anApp->desktop()->activeWindow();
625 SALOME_View* view = dynamic_cast<SALOME_View*>( window->getViewManager()->getActiveView() );
627 SALOME_Prs* aPrs = view->CreatePrs( myEntry.toLatin1() );
628 myResult = !aPrs->IsNull();
634 bool SALOMEGUI_Swig::IsInCurrentView( const char* theEntry )
636 return ProcessEvent( new TIsInViewerEvent( theEntry ) );
640 \brief Update (repaint) current view window.
642 void SALOMEGUI_Swig::UpdateView()
644 class TEvent: public SALOME_Event
648 virtual void Execute()
650 if ( LightApp_Application* anApp = getApplication() ) {
651 SUIT_ViewWindow* window = anApp->desktop()->activeWindow();
653 SALOME_View* view = dynamic_cast<SALOME_View*>( window->getViewManager()->getActiveView() );
660 ProcessVoidEvent( new TEvent() );
664 \brief Fit current view window to display all its contents.
666 void SALOMEGUI_Swig::FitAll()
668 class TEvent: public SALOME_Event
672 virtual void Execute()
674 if ( LightApp_Application* anApp = getApplication() ) {
675 SUIT_ViewWindow* window = anApp->desktop()->activeWindow();
677 #ifndef DISABLE_SALOMEOBJECT
678 #ifndef DISABLE_VTKVIEWER
679 if ( dynamic_cast<SVTK_ViewWindow*>( window ) )
680 ( dynamic_cast<SVTK_ViewWindow*>( window ) )->onFitAll();
682 #ifndef DISABLE_PLOT2DVIEWER
683 if ( dynamic_cast<SPlot2d_ViewWindow*>( window ) )
684 ( dynamic_cast<SPlot2d_ViewWindow*>( window ) )->onFitAll();
687 #ifndef DISABLE_OCCVIEWER
688 if ( dynamic_cast<OCCViewer_ViewWindow*>( window ) )
689 ( dynamic_cast<OCCViewer_ViewWindow*>( window ) )->onFitAll();
695 ProcessVoidEvent( new TEvent() );
699 \brief Reset current view window to the default state.
701 void SALOMEGUI_Swig::ResetView()
703 class TEvent: public SALOME_Event
707 virtual void Execute()
709 if ( LightApp_Application* anApp = getApplication() ) {
710 SUIT_ViewWindow* window = anApp->desktop()->activeWindow();
712 #ifndef DISABLE_SALOMEOBJECT
713 #ifndef DISABLE_VTKVIEWER
714 if ( dynamic_cast<SVTK_ViewWindow*>( window ) )
715 (dynamic_cast<SVTK_ViewWindow*>( window ))->onResetView();
717 #ifndef DISABLE_PLOT2DVIEWER
718 if ( dynamic_cast<SPlot2d_ViewWindow*>( window ) )
719 (dynamic_cast<SPlot2d_ViewWindow*>( window ))->onFitAll();
720 // VSR: there is no 'ResetView' functionality for Plot2d viewer,
721 // so we use 'FitAll' instead.
724 #ifndef DISABLE_OCCVIEWER
725 if ( dynamic_cast<OCCViewer_ViewWindow*>( window ) )
726 (dynamic_cast<OCCViewer_ViewWindow*>( window ))->onResetView();
732 ProcessVoidEvent( new TEvent() );
736 \brief View operation type.
740 __ViewTop, //!< view top side
741 __ViewBottom, //!< view bottom side
742 __ViewLeft, //!< view left side
743 __ViewRight, //!< view right side
744 __ViewFront, //!< view front side
745 __ViewBack //!< view back side
749 \brief Change the view of the current view window.
751 \param view view operation type
753 static void setView( int view )
755 class TEvent: public SALOME_Event
760 TEvent( int view ) : myView( view ) {}
761 virtual void Execute()
763 if ( LightApp_Application* anApp = getApplication() ) {
764 SUIT_ViewWindow* window = anApp->desktop()->activeWindow();
766 #ifndef DISABLE_SALOMEOBJECT
767 #ifndef DISABLE_VTKVIEWER
768 if ( dynamic_cast<SVTK_ViewWindow*>( window ) ) {
771 (dynamic_cast<SVTK_ViewWindow*>( window ))->onTopView(); break;
773 (dynamic_cast<SVTK_ViewWindow*>( window ))->onBottomView(); break;
775 (dynamic_cast<SVTK_ViewWindow*>( window ))->onLeftView(); break;
777 (dynamic_cast<SVTK_ViewWindow*>( window ))->onRightView(); break;
779 (dynamic_cast<SVTK_ViewWindow*>( window ))->onFrontView(); break;
781 (dynamic_cast<SVTK_ViewWindow*>( window ))->onBackView(); break;
788 #ifndef DISABLE_OCCVIEWER
789 if ( dynamic_cast<OCCViewer_ViewWindow*>( window ) ) {
792 (dynamic_cast<OCCViewer_ViewWindow*>( window ))->onTopView(); break;
794 (dynamic_cast<OCCViewer_ViewWindow*>( window ))->onBottomView(); break;
796 (dynamic_cast<OCCViewer_ViewWindow*>( window ))->onLeftView(); break;
798 (dynamic_cast<OCCViewer_ViewWindow*>( window ))->onRightView(); break;
800 (dynamic_cast<OCCViewer_ViewWindow*>( window ))->onFrontView(); break;
802 (dynamic_cast<OCCViewer_ViewWindow*>( window ))->onBackView(); break;
812 ProcessVoidEvent( new TEvent( view ) );
816 \brief Switch current view window to show the top view.
818 void SALOMEGUI_Swig::ViewTop()
820 setView( __ViewTop );
824 \brief Switch current view window to show the bottom view
826 void SALOMEGUI_Swig::ViewBottom()
828 setView( __ViewBottom );
832 \brief Switch current view window to show the left view
834 void SALOMEGUI_Swig::ViewLeft()
836 setView( __ViewLeft );
840 \brief Switch current view window to show the right view
842 void SALOMEGUI_Swig::ViewRight()
844 setView( __ViewRight );
848 \brief Switch current view window to show the front view
850 void SALOMEGUI_Swig::ViewFront()
852 setView( __ViewFront );
856 \brief Switch current view window to show the back view
858 void SALOMEGUI_Swig::ViewBack()
860 setView( __ViewBack );