Salome HOME
0023238: [CEA 1738] OCC Viewer outside SALOME window
[modules/gui.git] / src / SALOME_PYQT / SalomePyQt / SalomePyQt.cxx
1 // Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  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, or (at your option) any later version.
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 // File   : SalomePyQt.cxx
24 // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
25
26 #ifdef WIN32
27 // E.A. : On windows with python 2.6, there is a conflict
28 // E.A. : between pymath.h and Standard_math.h which define
29 // E.A. : some same symbols : acosh, asinh, ...
30 #include <Standard_math.hxx>
31 #include <pymath.h>
32 #endif
33
34 #include "SALOME_PYQT_ModuleLight.h" // this include must be first!!!
35 #include "SALOME_PYQT_DataModelLight.h"
36 #include "SALOME_PYQT_PyModule.h"
37 #include "SalomePyQt.h"
38
39 #include "LightApp_SelectionMgr.h"
40 #include "LogWindow.h"
41 #ifndef DISABLE_OCCVIEWER
42 #include "OCCViewer_ViewWindow.h"
43 #include "OCCViewer_ViewFrame.h"
44 #endif // DISABLE_OCCVIEWER
45 #ifndef DISABLE_PLOT2DVIEWER
46 #include "Plot2d_ViewManager.h"
47 #include "Plot2d_ViewWindow.h"
48 #endif // DISABLE_PLOT2DVIEWER
49 #ifndef DISABLE_PVVIEWER
50 #include "PVViewer_ViewManager.h"
51 #include "PVViewer_ViewModel.h"
52 #endif // DISABLE_PVVIEWER
53 #include "QtxActionMenuMgr.h"
54 #include "QtxWorkstack.h"
55 #include "QtxTreeView.h"
56 #include "SALOME_Event.h"
57 #include "STD_TabDesktop.h"
58 #include "SUIT_DataBrowser.h"
59 #include "SUIT_ResourceMgr.h"
60 #include "SUIT_Session.h"
61 #include "SUIT_Tools.h"
62 #include "SUIT_ViewManager.h"
63 #include "SUIT_ViewWindow.h"
64 #include "PyConsole_Console.h"
65
66 #include <QAction>
67 #include <QApplication>
68 #include <QPaintEvent>
69 #include <QCoreApplication>
70
71 namespace
72 {
73   /*!
74     \brief Get the currently active application.
75     \internal
76     \return active application object or 0 if there is no any
77   */
78   LightApp_Application* getApplication()
79   {
80     if ( SUIT_Session::session() )
81       return dynamic_cast<LightApp_Application*>( SUIT_Session::session()->activeApplication() );
82     return 0;
83   }
84   
85   /*!
86     \brief Get the currently active study.
87     \internal
88     \return active study or 0 if there is no study opened
89   */
90   LightApp_Study* getActiveStudy()
91   {
92     if ( getApplication() )
93       return dynamic_cast<LightApp_Study*>( getApplication()->activeStudy() );
94     return 0;
95   }
96
97   /*!
98     \brief Get the currently active module.
99     \internal
100     This function returns correct result only if Python-based
101     module is currently active. Otherwize, 0 is returned.
102   */
103   LightApp_Module* getActiveModule()
104   {
105     LightApp_Module* module = 0;
106     if ( LightApp_Application* anApp = getApplication() ) {
107       module = PyModuleHelper::getInitModule();
108       if ( !module )
109         module = dynamic_cast<LightApp_Module*>( anApp->activeModule() );
110     }
111     return module;
112   }
113   
114   /*!
115     \brief Get the currently active Python module's helper.
116     \internal
117     This function returns correct result only if Python-based
118     module is currently active. Otherwize, 0 is returned.
119   */
120   PyModuleHelper* getPythonHelper()
121   {
122     LightApp_Module* module = getActiveModule();
123     PyModuleHelper* helper = module ? module->findChild<PyModuleHelper*>( "python_module_helper" ) : 0;
124     return helper;
125   }
126   
127   /*!
128     \brief Get SALOME verbose level
129     \internal
130     \return \c true if SALOME debug output is allowed or \c false otherwise
131   */
132   bool verbose()
133   {
134     bool isVerbose = false;
135     if ( getenv( "SALOME_VERBOSE" ) ) {
136       QString envVar = getenv( "SALOME_VERBOSE" );
137       bool ok;
138       int value = envVar.toInt( &ok );
139       isVerbose = ok && value != 0;
140     }
141     return isVerbose;
142   }
143
144   /*!
145     \brief Get menu item title
146     \internal
147     \param menuId menu identifier
148     \return menu title (localized)
149   */
150   QString getMenuName( const QString& menuId )
151   {
152     QStringList contexts;
153     contexts << "SalomeApp_Application" << "LightApp_Application" << "STD_TabDesktop" <<
154       "STD_MDIDesktop" << "STD_Application" << "SUIT_Application" << "";
155     QString menuName = menuId;
156     for ( int i = 0; i < contexts.count() && menuName == menuId; i++ )
157       menuName = QApplication::translate( contexts[i].toLatin1().data(), menuId.toLatin1().data() );
158     return menuName;
159   }
160
161   /*!
162     \brief Load module icon
163     \internal
164     \param module module name
165     \param fileName path to the icon file
166     \return icon
167   */
168   QIcon loadIconInternal( const QString& module, const QString& fileName )
169   {
170     QIcon icon;
171     
172     LightApp_Application* app = getApplication();
173     
174     if ( app && !fileName.isEmpty() ) {
175       QPixmap pixmap = app->resourceMgr()->loadPixmap( module, 
176                                                        QApplication::translate( module.toLatin1().data(), 
177                                                                                 fileName.toLatin1().data() ) );
178       if ( !pixmap.isNull() )
179         icon = QIcon( pixmap );
180     }
181     return icon;
182   }
183
184   /*!
185     \brief Gets window with specified identifier 
186     \internal
187     \param id window identifier 
188     \return pointer on the window
189   */
190   SUIT_ViewWindow* getWnd( const int id )
191   {
192     SUIT_ViewWindow* resWnd = 0;
193     
194     LightApp_Application* app = getApplication();
195     if ( app ) {
196       ViewManagerList vmlist = app->viewManagers();
197       foreach( SUIT_ViewManager* vm, vmlist ) {
198         QVector<SUIT_ViewWindow*> vwlist = vm->getViews();
199         foreach ( SUIT_ViewWindow* vw, vwlist ) {
200           if ( id == vw->getId() ) {
201             resWnd = vw;
202             break;
203           }
204         }
205       }
206     }
207     return resWnd;
208   }
209
210   /*!
211     \brief Map of created selection objects.
212     \internal
213   */
214   QMap<LightApp_Application*, SALOME_Selection*> SelMap;
215
216   /*!
217     \brief Default resource file section name.
218     \internal
219   */
220   const char* DEFAULT_SECTION = "SalomePyQt";
221 }
222
223 /*!
224   \class SALOME_Selection
225   \brief The class represents selection which can be used in Python.
226 */
227
228 /*!
229   \brief Get the selection object for the specified application.
230
231   Finds or creates the selection object (one per study).
232
233   \param app application object
234   \return selection object or 0 if \a app is invalid
235 */
236 SALOME_Selection* SALOME_Selection::GetSelection( LightApp_Application* app )
237 {
238   SALOME_Selection* sel = 0;
239   if ( app && SelMap.find( app ) != SelMap.end() )
240     sel = SelMap[ app ];
241   else 
242     sel = SelMap[ app ] = new SALOME_Selection( app );
243   return sel;
244 }
245
246 /*!
247   \brief Constructor.
248   \param p parent object
249 */
250 SALOME_Selection::SALOME_Selection( QObject* p ) : QObject( 0 ), mySelMgr( 0 )
251 {
252   LightApp_Application* app = dynamic_cast<LightApp_Application*>( p );
253   if ( app ) {
254     mySelMgr = app->selectionMgr();
255     connect( mySelMgr, SIGNAL( selectionChanged() ), this, SIGNAL( currentSelectionChanged() ) );
256     connect( mySelMgr, SIGNAL( destroyed() ),        this, SLOT  ( onSelMgrDestroyed() ) );
257   }
258 }
259
260 /*!
261   \brief Destructor.
262 */
263 SALOME_Selection::~SALOME_Selection()
264 {
265   LightApp_Application* app = 0;
266   QMap<LightApp_Application*, SALOME_Selection*>::Iterator it;
267   for ( it = SelMap.begin(); it != SelMap.end() && !app; ++it ) {
268     if ( it.value() == this ) app = it.key();
269   }
270   if ( app ) SelMap.remove( app );
271 }
272
273 /*!
274   \brief Called when selection manager is destroyed (usually 
275   when the study is closed).
276 */
277 void SALOME_Selection::onSelMgrDestroyed()
278 {
279   mySelMgr = 0;
280 }
281
282 /*!
283   \brief Clear the selection.
284 */
285 void SALOME_Selection::Clear()
286 {
287   class TEvent: public SALOME_Event
288   {
289     LightApp_SelectionMgr* mySelMgr;
290   public:
291     TEvent( LightApp_SelectionMgr* selMgr ) 
292       : mySelMgr( selMgr ) {}
293     virtual void Execute() 
294     {
295       if ( mySelMgr )
296         mySelMgr->clearSelected();
297     }
298   };
299   ProcessVoidEvent( new TEvent( mySelMgr ) );
300 }
301
302 /*!
303   \brief Clear the selection.
304 */
305 void SALOME_Selection::ClearIObjects()
306 {
307   Clear();
308 }
309
310 /*!
311   Removes all selection filters.
312 */
313 void SALOME_Selection::ClearFilters()
314 {
315   class TEvent: public SALOME_Event 
316   {
317     LightApp_SelectionMgr* mySelMgr;
318   public:
319     TEvent( LightApp_SelectionMgr* selMgr ) 
320       : mySelMgr( selMgr ) {}
321     virtual void Execute() 
322     {
323       if ( mySelMgr )
324         mySelMgr->clearFilters();
325     }
326   };
327   ProcessVoidEvent( new TEvent( mySelMgr ) );
328 }
329
330 /*!
331   \class SalomePyQt
332   \brief The class provides utility functions which can be used in the Python
333   to operate with the SALOME GUI.
334
335   All the functionality of this class is implemented as static methods, so they
336   can be called with the class name prefixed or via creation of the class instance.
337   For example, next both ways of SalomePyQt class usage are legal:
338   \code
339   from SalomePyQt import *
340   sg = SalomePyQt()
341   # using SalomePyQt class instance
342   desktop = sg.getDesktop()
343   # using SalomePyQt class directly
344   menubar = SalomePyQt.getMainMenuBar()
345   \endcode
346 */
347
348 /*!
349   \fn QWidget* SalomePyQt::getDesktop();
350   \brief Get the active application's desktop window.
351   \return desktop window or 0 if there is no any
352 */
353
354 class TGetDesktopEvent: public SALOME_Event 
355 {
356 public:
357   typedef QWidget* TResult;
358   TResult myResult;
359   TGetDesktopEvent() : myResult( 0 ) {}
360   virtual void Execute()
361   {
362     if ( getApplication() )
363       myResult = (QWidget*)( getApplication()->desktop() );
364   }
365 };
366 QWidget* SalomePyQt::getDesktop()
367 {
368   return ProcessEvent( new TGetDesktopEvent() );
369 }
370
371 /*!
372   \fn QWidget* SalomePyQt::getMainFrame();
373   \brief Get current application's main frame widget [obsolete].
374
375   Main frame widget is an internal widget of the application 
376   desktop window (workspace).
377
378   \return workspace widget (0 on any error)
379 */
380
381 class TGetMainFrameEvent: public SALOME_Event
382 {
383 public:
384   typedef QWidget* TResult;
385   TResult myResult;
386   TGetMainFrameEvent() : myResult( 0 ) {}
387   virtual void Execute()
388   {
389     if ( getApplication() ) {
390       SUIT_Desktop* aDesktop = getApplication()->desktop();
391       myResult = (QWidget*)( aDesktop->centralWidget() );
392     }
393   }
394 };
395 QWidget* SalomePyQt::getMainFrame()
396 {
397   return ProcessEvent( new TGetMainFrameEvent() );
398 }
399
400 /*!
401   \fn QMenuBar* SalomePyQt::getMainMenuBar();
402   \brief Get current application desktop's main menu.
403   \return main menu object (0 on any error)
404 */
405
406 class TGetMainMenuBarEvent: public SALOME_Event
407 {
408 public:
409   typedef QMenuBar* TResult;
410   TResult myResult;
411   TGetMainMenuBarEvent() : myResult( 0 ) {}
412   virtual void Execute()
413   {
414     if ( LightApp_Application* anApp = getApplication() ) {
415       myResult = anApp->desktop()->menuBar();
416     }
417   }
418 };
419 QMenuBar* SalomePyQt::getMainMenuBar() 
420 {
421   return ProcessEvent( new TGetMainMenuBarEvent() );
422 }
423
424 /*!
425   \fn QMenu* SalomePyQt::getPopupMenu( const MenuName menu );
426   \brief Get main menu's child popup submenu by its identifier.
427   
428   This function is obsolete. 
429   Use QMenu* SalomePyQt::getPopupMenu( const QString& menu ) instead.
430
431   \param menu menu identifier
432   \return popup submenu object or 0 if it does not exist
433 */
434
435 /*!
436   \fn QMenu* SalomePyQt::getPopupMenu( const QString& menu );
437   \brief Get main menu's child popup submenu by its name.
438   
439   The function creates menu if it does not exist.
440
441   \param menu menu name
442   \return popup submenu object (0 on any error)
443 */
444
445 class TGetPopupMenuEvent: public SALOME_Event
446 {
447 public:
448   typedef QMenu* TResult;
449   TResult myResult;
450   QString myMenuName;
451   TGetPopupMenuEvent( const QString& menu ) : myResult( 0 ), myMenuName( menu ) {}
452   virtual void Execute()
453   {
454     LightApp_Application* anApp = getApplication();
455     if ( anApp && !myMenuName.isEmpty() ) {
456       QtxActionMenuMgr* mgr = anApp->desktop()->menuMgr();
457       myResult = mgr->findMenu( myMenuName, -1, false ); // search only top menu
458     }
459   }
460 };
461
462 QMenu* SalomePyQt::getPopupMenu( const MenuName menu )
463 {
464   QString menuName;
465   switch( menu ) {
466   case File:
467     menuName = getMenuName( "MEN_DESK_FILE" );        break;
468   case View:
469     menuName = getMenuName( "MEN_DESK_VIEW" );        break;
470   case Edit:
471     menuName = getMenuName( "MEN_DESK_EDIT" );        break;
472   case Preferences:
473     menuName = getMenuName( "MEN_DESK_PREFERENCES" ); break;
474   case Tools:
475     menuName = getMenuName( "MEN_DESK_TOOLS" );       break;
476   case Window:
477     menuName = getMenuName( "MEN_DESK_WINDOW" );      break;
478   case Help:
479     menuName = getMenuName( "MEN_DESK_HELP" );        break;
480   }
481   return ProcessEvent( new TGetPopupMenuEvent( menuName ) );
482 }
483 QMenu* SalomePyQt::getPopupMenu( const QString& menu )
484 {
485   return ProcessEvent( new TGetPopupMenuEvent( menu ) );
486 }
487
488 /*!
489   \fn QTreeView* SalomePyQt::getObjectBrowser();
490   \brief Get object browser
491   \return object browser for the active study or 0 in case of error
492 */
493
494 class TGetObjectBrowserEvent: public SALOME_Event
495 {
496 public:
497   typedef QTreeView* TResult;
498   TResult myResult;
499   TGetObjectBrowserEvent() : myResult( 0 ) {}
500   virtual void Execute()
501   {
502     LightApp_Application* anApp = getApplication();
503     if ( anApp && anApp->objectBrowser() ) {
504       myResult = anApp->objectBrowser()->treeView();
505     }
506   }
507 };
508 QTreeView* SalomePyQt::getObjectBrowser()
509 {
510   return ProcessEvent( new TGetObjectBrowserEvent() );
511 }
512
513 /*!
514   \fn int SalomePyQt::getStudyId();
515   \brief Get active study's identifier.
516   \return active study ID or 0 if there is no active study
517 */
518
519 class TGetStudyIdEvent: public SALOME_Event
520 {
521 public:
522   typedef int TResult;
523   TResult myResult;
524   TGetStudyIdEvent() : myResult( 0 ) {}
525   virtual void Execute()
526   {
527     if ( LightApp_Study* aStudy = getActiveStudy() ) {
528       myResult = aStudy->id();
529     }
530   }
531 };
532 int SalomePyQt::getStudyId()
533 {
534   return ProcessEvent( new TGetStudyIdEvent() );
535 }
536
537 /*!
538   \fn SALOME_Selection* SalomePyQt::getSelection();
539   \brief Get the selection object for the current study.
540
541   Creates a Selection object if it has not been created yet.
542
543   \return selection object (0 on error)
544 */
545
546 class TGetSelectionEvent: public SALOME_Event 
547 {
548 public:
549   typedef SALOME_Selection* TResult;
550   TResult myResult;
551   TGetSelectionEvent() : myResult( 0 ) {}
552   virtual void Execute() 
553   {
554     myResult = SALOME_Selection::GetSelection( getApplication() );
555   }
556 };
557 SALOME_Selection* SalomePyQt::getSelection()
558 {
559   return ProcessEvent( new TGetSelectionEvent() );
560 }
561
562 /*!
563   \fn void SalomePyQt::putInfo( const QString& msg, const int sec );
564   \brief Put an information message to the current application's 
565   desktop status bar.
566
567   Optional second delay parameter (\a sec) can be used to specify
568   time of the message diplaying in seconds. If this parameter is less
569   or equal to zero, the constant message will be put.
570
571   \param msg message text 
572   \param sec message displaying time in seconds
573 */
574
575 class TPutInfoEvent: public SALOME_Event
576 {
577   QString myMsg;
578   int     mySecs;
579 public:
580   TPutInfoEvent( const QString& msg, const int sec = 0 ) : myMsg( msg ), mySecs( sec ) {}
581   virtual void Execute()
582   {
583     if ( LightApp_Application* anApp = getApplication() ) {
584       anApp->putInfo( myMsg, mySecs * 1000 );
585     }
586   }
587 };
588 void SalomePyQt::putInfo( const QString& msg, const int sec )
589 {
590   ProcessVoidEvent( new TPutInfoEvent( msg, sec ) );
591 }
592
593 /*!
594   \fn const QString SalomePyQt::getActiveComponent();
595   \brief Get the currently active module name (for the current study).
596   \return active module name or empty string if there is no active module
597 */
598
599 class TGetActiveComponentEvent: public SALOME_Event
600 {
601 public:
602   typedef QString TResult;
603   TResult myResult;
604   TGetActiveComponentEvent() {}
605   virtual void Execute() 
606   {
607     if ( LightApp_Application* anApp = getApplication() ) {
608       if ( CAM_Module* mod = anApp->activeModule() ) {
609         myResult = mod->name();
610       }
611     }
612   }
613 };
614 const QString SalomePyQt::getActiveComponent()
615 {
616   return ProcessEvent( new TGetActiveComponentEvent() );
617 }
618
619 /*!
620   \fn PyObject* SalomePyQt::getActivePythonModule();
621   \brief Access to Python module object currently loaded into SALOME_PYQT_ModuleLight container.
622   \return Python module object currently loaded into SALOME_PYQT_ModuleLight container
623 */
624
625 class TGetActivePyModuleEvent: public SALOME_Event
626 {
627 public:
628   typedef PyObject* TResult;
629   TResult myResult;
630   TGetActivePyModuleEvent() : myResult( Py_None ) {}
631   virtual void Execute() 
632   {
633     PyModuleHelper* helper = getPythonHelper();
634     if ( helper )
635       myResult = (PyObject*)helper->pythonModule();
636   }
637 };
638 PyObject* SalomePyQt::getActivePythonModule()
639 {
640   return ProcessEvent( new TGetActivePyModuleEvent() );
641 }
642
643 /*!
644   \fn bool SalomePyQt::activateModule( const QString& modName );
645   \brief Activates SALOME module with the given name
646   \return True if the module has been activated and False otherwise.
647 */
648
649 class TActivateModuleEvent: public SALOME_Event
650 {
651 public:
652   typedef bool TResult;
653   TResult myResult;
654   QString myModuleName;
655   TActivateModuleEvent( const QString& modName ) 
656   : myResult( false ), myModuleName( modName ) {}
657   virtual void Execute() 
658   {
659     if ( LightApp_Application* anApp = getApplication() ) {
660       myResult = anApp->activateModule( myModuleName );
661     }
662   }
663 };
664 bool SalomePyQt::activateModule( const QString& modName )
665 {
666   return ProcessEvent( new TActivateModuleEvent( modName ) );
667 }
668
669 /*!
670   \brief Update an Object Browser of the specified (by identifier) study.
671
672   If \a studyId <= 0 the active study's object browser is updated.
673   The \a updateSelection parameter is obsolete and currently is not used. 
674   This parameter will be removed in future, so try to avoid its usage in 
675   your code.
676
677   \brief studyId study identifier
678   \brief updateSelection update selection flag (not used)
679   \sa getActiveStudy()
680 */
681 void SalomePyQt::updateObjBrowser( const int studyId, bool updateSelection )
682 {  
683   class TEvent: public SALOME_Event
684   {
685     int  myStudyId;
686     bool myUpdateSelection;
687   public:
688     TEvent( const int studyId, bool updateSelection ) 
689       : myStudyId( studyId ), myUpdateSelection( updateSelection ) {}
690     virtual void Execute()
691     {
692       if ( SUIT_Session::session() ) {
693         if ( getActiveStudy() && myStudyId <= 0 )
694           myStudyId = getActiveStudy()->id();
695         if ( myStudyId > 0 ) {
696           QList<SUIT_Application*> apps = SUIT_Session::session()->applications();
697           QList<SUIT_Application*>::Iterator it;
698           for( it = apps.begin(); it != apps.end(); ++it ) {
699             LightApp_Application* anApp = dynamic_cast<LightApp_Application*>( *it );
700             if ( anApp && anApp->activeStudy() && anApp->activeStudy()->id() == myStudyId ) {
701               anApp->updateObjectBrowser();
702               return;
703             }
704           }
705         }
706       }
707     }
708   };
709   ProcessVoidEvent( new TEvent( studyId, updateSelection ) );
710 }
711
712
713 /*!
714   SalomePyQt::isModified()
715   \return The modification status of the data model
716   for the currently active Python module
717   \note This function is supported for "light" Python-based SALOME modules only.
718   \sa setModified()
719 */
720 class TIsModifiedEvent: public SALOME_Event
721 {
722 public:
723   typedef bool TResult;
724   TResult myResult;
725   TIsModifiedEvent() : myResult( false ) {}
726   virtual void Execute() 
727   {
728     LightApp_Module* module = getActiveModule();
729     if ( !module )
730       return;
731     
732     SALOME_PYQT_DataModelLight* aModel =
733       dynamic_cast<SALOME_PYQT_DataModelLight*>( module->dataModel() );
734     if ( aModel ) {
735       myResult = aModel->isModified();
736     }
737     else {
738       if ( verbose() ) printf( "SalomePyQt.isModified() function is not supported for the current module.\n" );
739     }
740   }
741 };
742 bool SalomePyQt::isModified()
743 {
744   return ProcessEvent(new TIsModifiedEvent());
745 }
746
747 /*!
748   SalomePyQt::setModified()
749
750   Sets the modification status of the data model for 
751   the currently active Python module. This method should be used
752   by the Python code in order to enable/disable "Save" operation
753   depending on the module's data state.
754
755   \note This function is supported for "light" Python-based SALOME modules only.
756
757   \param New modification status of the data model
758
759   \sa isModified()
760 */
761 void SalomePyQt::setModified( bool flag )
762 {  
763   class TEvent: public SALOME_Event
764   {
765     bool myFlag;
766   public:
767     TEvent( bool flag ) 
768       : myFlag( flag ) {}
769     virtual void Execute()
770     {
771       LightApp_Module* module = getActiveModule();
772       if ( !module )
773         return;
774
775       SALOME_PYQT_DataModelLight* model =
776         dynamic_cast<SALOME_PYQT_DataModelLight*>( module->dataModel() );
777
778       LightApp_Application* app = module->getApp();
779
780       if ( model && app ) {
781         model->setModified( myFlag );
782         app->updateActions();
783       }
784       else {
785         if ( verbose() ) printf( "SalomePyQt.setModified() function is not supported for the current module.\n" );
786       }
787     }
788   };
789   ProcessVoidEvent( new TEvent( flag ) );
790 }
791
792 /*!
793   \brief Add string setting to the application preferences.
794
795   The parameter \a autoValue is obsolete parameter and currently is not used.
796   This parameter will be removed in future, so try to avoid its usage in 
797   your code.
798
799   This function is obsolete. Use one of addSetting() instead.
800
801   \param name setting name (it should be of kind <section:setting> where
802   \c section is resources section name and \c setting is setting name)
803   \param value new setting value
804   \param autoValue (not used)
805 */
806 void SalomePyQt::addStringSetting( const QString& name, const QString& value, bool autoValue )
807 {
808   class TEvent: public SALOME_Event
809   {
810     QString myName;
811     QString myValue;
812     bool    myAutoValue;
813   public:
814     TEvent( const QString& name, const QString& value, bool autoValue ) 
815       : myName( name ), myValue( value ), myAutoValue( autoValue ) {}
816     virtual void Execute()
817     {
818       if ( SUIT_Session::session() ) {
819         SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
820         QStringList sl = myName.split( ":", QString::SkipEmptyParts );
821         QString _sec = sl.count() > 1 ? sl[ 0 ].trimmed() : QString( DEFAULT_SECTION );
822         QString _nam = sl.count() > 1 ? sl[ 1 ].trimmed() : sl.count() > 0 ? sl[ 0 ].trimmed() : QString( "" );
823         if ( !_sec.isEmpty() && !_nam.isEmpty() )
824           resMgr->setValue( _sec, _nam, myValue );
825       }
826     }
827   };
828   ProcessVoidEvent( new TEvent( name, value, autoValue ) );
829 }
830
831 /*!
832   \brief Add integer setting to the application preferences.
833
834   The parameter \a autoValue is obsolete parameter and currently is not used.
835   This parameter will be removed in future, so try to avoid its usage in 
836   your code.
837
838   This function is obsolete. Use one of addSetting() instead.
839
840   \param name setting name (it should be of kind <section:setting> where
841   \c section is resources section name and \c setting is setting name)
842   \param value new setting value
843   \param autoValue (not used)
844 */
845 void SalomePyQt::addIntSetting( const QString& name, const int value, bool autoValue)
846 {
847   class TEvent: public SALOME_Event 
848   {
849     QString myName;
850     int     myValue;
851     bool    myAutoValue;
852   public:
853     TEvent( const QString& name, const int value, bool autoValue ) 
854       : myName( name ), myValue( value ), myAutoValue( autoValue ) {}
855     virtual void Execute()
856     {
857       if ( SUIT_Session::session() ) {
858         SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
859         QStringList sl = myName.split( ":", QString::SkipEmptyParts );
860         QString _sec = sl.count() > 1 ? sl[ 0 ].trimmed() : QString( DEFAULT_SECTION );
861         QString _nam = sl.count() > 1 ? sl[ 1 ].trimmed() : sl.count() > 0 ? sl[ 0 ].trimmed() : QString( "" );
862         if ( !_sec.isEmpty() && !_nam.isEmpty() )
863           resMgr->setValue( _sec, _nam, myValue );
864       }
865     }
866   };
867   ProcessVoidEvent( new TEvent( name, value, autoValue ) );
868 }
869
870 /*!
871   \brief Add double setting to the application preferences.
872
873   The parameter \a autoValue is obsolete parameter and currently is not used.
874   This parameter will be removed in future, so try to avoid its usage in 
875   your code.
876
877   This function is obsolete. Use one of addSetting() instead.
878
879   \param name setting name (it should be of kind <section:setting> where
880   \c section is resources section name and \c setting is setting name)
881   \param value new setting value
882   \param autoValue (not used)
883 */
884 void SalomePyQt::addDoubleSetting( const QString& name, const double value, bool autoValue )
885 {
886   class TEvent: public SALOME_Event 
887   {
888     QString myName;
889     double  myValue;
890     bool    myAutoValue;
891   public:
892     TEvent( const QString& name, const double value, bool autoValue ) 
893       : myName( name ), myValue( value ), myAutoValue( autoValue ) {}
894     virtual void Execute() 
895     {
896       if ( SUIT_Session::session() ) {
897         SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
898         QStringList sl = myName.split( ":", QString::SkipEmptyParts );
899         QString _sec = sl.count() > 1 ? sl[ 0 ].trimmed() : QString( DEFAULT_SECTION );
900         QString _nam = sl.count() > 1 ? sl[ 1 ].trimmed() : sl.count() > 0 ? sl[ 0 ].trimmed() : QString( "" );
901         if ( !_sec.isEmpty() && !_nam.isEmpty() )
902           resMgr->setValue( _sec, _nam, myValue );
903       }
904     }
905   };
906   ProcessVoidEvent( new TEvent( name, value, autoValue ) );
907 }
908
909 /*!
910   \brief Add boolean setting to the application preferences.
911
912   The parameter \a autoValue is obsolete parameter and currently is not used.
913   This parameter will be removed in future, so try to avoid its usage in 
914   your code.
915
916   This function is obsolete. Use one of addSetting() instead.
917
918   \param name setting name (it should be of kind <section:setting> where
919   \c section is resources section name and \c setting is setting name)
920   \param value new setting value
921   \param autoValue (not used)
922 */
923 void SalomePyQt::addBoolSetting( const QString& name, const bool value, bool autoValue )
924 {
925   class TEvent: public SALOME_Event 
926   {
927     QString myName;
928     bool    myValue;
929     bool    myAutoValue;
930   public:
931     TEvent( const QString& name, const bool value, bool autoValue ) 
932       : myName( name ), myValue( value ), myAutoValue( autoValue ) {}
933     virtual void Execute() 
934     {
935       if ( SUIT_Session::session() ) {
936         SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
937         QStringList sl = myName.split( ":", QString::SkipEmptyParts );
938         QString _sec = sl.count() > 1 ? sl[ 0 ].trimmed() : QString( DEFAULT_SECTION );
939         QString _nam = sl.count() > 1 ? sl[ 1 ].trimmed() : sl.count() > 0 ? sl[ 0 ].trimmed() : QString( "" );
940         if ( !_sec.isEmpty() && !_nam.isEmpty() )
941           resMgr->setValue( _sec, _nam, myValue );
942       }
943     }
944   };
945   ProcessVoidEvent( new TEvent( name, value, autoValue ) );
946 }
947
948 /*!
949   \brief Remove setting from the application preferences.
950
951   This function is obsolete. Use removeSetting() instead.
952
953   \param name setting name (it should be of kind <section:setting> where
954   \c section is resources section name and \c setting is setting name)
955 */
956 void SalomePyQt::removeSettings( const QString& name )
957 {
958   class TEvent: public SALOME_Event
959   {
960     QString myName;
961   public:
962     TEvent( const QString& name ) : myName( name ) {}
963     virtual void Execute()
964     {
965       if ( SUIT_Session::session() ) {
966         SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
967         QStringList sl = myName.split( ":", QString::SkipEmptyParts );
968         QString _sec = sl.count() > 1 ? sl[ 0 ].trimmed() : QString( DEFAULT_SECTION );
969         QString _nam = sl.count() > 1 ? sl[ 1 ].trimmed() : sl.count() > 0 ? sl[ 0 ].trimmed() : QString( "" );
970         if ( !_sec.isEmpty() && !_nam.isEmpty() )
971           resMgr->remove( _sec, _nam );
972       }
973     }
974   };
975   ProcessVoidEvent( new TEvent( name ) );
976 }
977
978 /*!
979   \fn QString SalomePyQt::getSetting( const QString& name );
980   \brief Get application setting value (as string represenation).
981
982   This function is obsolete. Use stringSetting(), integerSetting(), 
983   boolSetting(), stringSetting() or colorSetting() instead.
984
985   \param name setting name (it should be of kind <section:setting> where
986   \c section is resources section name and \c setting is setting name)
987   \return setting name (empty string if setting name is invalid)
988 */
989
990 class TGetSettingEvent: public SALOME_Event 
991 {
992 public:
993   typedef QString TResult;
994   TResult myResult;
995   QString myName;
996   TGetSettingEvent( const QString& name ) : myName( name ) {}
997   virtual void Execute() 
998   {
999     if ( SUIT_Session::session() ) {
1000       SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
1001       QStringList sl = myName.split( ":", QString::SkipEmptyParts );
1002       QString _sec = sl.count() > 1 ? sl[ 0 ].trimmed() : QString( DEFAULT_SECTION );
1003       QString _nam = sl.count() > 1 ? sl[ 1 ].trimmed() : sl.count() > 0 ? sl[ 0 ].trimmed() : QString( "" );
1004       myResult = ( !_sec.isEmpty() && !_nam.isEmpty() ) ? resMgr->stringValue( _sec, _nam, "" ) : QString( "" );
1005     }
1006   }
1007 };
1008 QString SalomePyQt::getSetting( const QString& name )
1009 {
1010   return ProcessEvent( new TGetSettingEvent( name ) );
1011 }
1012
1013 /*!
1014   \brief Add double setting to the application preferences.
1015   \param section resources file section name 
1016   \param name setting name
1017   \param value new setting value
1018 */
1019 void SalomePyQt::addSetting( const QString& section, const QString& name, const double value )
1020 {
1021   class TEvent: public SALOME_Event 
1022   {
1023     QString mySection;
1024     QString myName;
1025     double  myValue;
1026   public:
1027     TEvent( const QString& section, const QString& name, double value ) 
1028       : mySection( section ), myName( name ), myValue( value ) {}
1029     virtual void Execute() 
1030     {
1031       if ( SUIT_Session::session() ) {
1032         SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
1033         if ( !mySection.isEmpty() && !myName.isEmpty() )
1034           resMgr->setValue( mySection, myName, myValue );
1035       }
1036     }
1037   };
1038   ProcessVoidEvent( new TEvent( section, name, value ) );
1039 }
1040
1041 /*!
1042   \brief Add integer setting to the application preferences.
1043   \param section resources file section name 
1044   \param name setting name
1045   \param value new setting value
1046 */
1047 void SalomePyQt::addSetting( const QString& section, const QString& name, const int value )
1048 {
1049   class TEvent: public SALOME_Event 
1050   {
1051     QString mySection;
1052     QString myName;
1053     int     myValue;
1054   public:
1055     TEvent( const QString& section, const QString& name, int value ) 
1056       : mySection( section ), myName( name ), myValue( value ) {}
1057     virtual void Execute() 
1058     {
1059       if ( SUIT_Session::session() ) {
1060         SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
1061         if ( !mySection.isEmpty() && !myName.isEmpty() )
1062           resMgr->setValue( mySection, myName, myValue );
1063       }
1064     }
1065   };
1066   ProcessVoidEvent( new TEvent( section, name, value ) );
1067 }
1068
1069 /*!
1070   \brief Add boolean setting to the application preferences.
1071   \param section resources file section name 
1072   \param name setting name
1073   \param value new setting value
1074   \param dumb this parameter is used in order to avoid sip compilation error 
1075   because of conflicting int and bool types
1076 */
1077 void SalomePyQt::addSetting( const QString& section, const QString& name, const bool value, const int /*dumb*/ )
1078 {
1079   class TEvent: public SALOME_Event 
1080   {
1081     QString mySection;
1082     QString myName;
1083     bool    myValue;
1084   public:
1085     TEvent( const QString& section, const QString& name, bool value ) 
1086       : mySection( section ), myName( name ), myValue( value ) {}
1087     virtual void Execute() 
1088     {
1089       if ( SUIT_Session::session() ) {
1090         SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
1091         if ( !mySection.isEmpty() && !myName.isEmpty() )
1092           resMgr->setValue( mySection, myName, myValue );
1093       }
1094     }
1095   };
1096   ProcessVoidEvent( new TEvent( section, name, value ) );
1097 }
1098
1099 /*!
1100   \brief Add string setting to the application preferences.
1101   \param section resources file section name 
1102   \param name setting name
1103   \param value new setting value
1104 */
1105 void SalomePyQt::addSetting( const QString& section, const QString& name, const QString& value )
1106 {
1107   class TEvent: public SALOME_Event 
1108   {
1109     QString mySection;
1110     QString myName;
1111     QString myValue;
1112   public:
1113     TEvent( const QString& section, const QString& name, const QString& value ) 
1114       : mySection( section ), myName( name ), myValue( value ) {}
1115     virtual void Execute() 
1116     {
1117       if ( SUIT_Session::session() ) {
1118         SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
1119         if ( !mySection.isEmpty() && !myName.isEmpty() )
1120           resMgr->setValue( mySection, myName, myValue );
1121       }
1122     }
1123   };
1124   ProcessVoidEvent( new TEvent( section, name, value ) );
1125 }
1126
1127 /*!
1128   \brief Add color setting to the application preferences.
1129   \param section resources file section name 
1130   \param name setting name
1131   \param value new setting value
1132 */
1133 void SalomePyQt::addSetting( const QString& section, const QString& name, const QColor& value )
1134 {
1135   class TEvent: public SALOME_Event 
1136   {
1137     QString mySection;
1138     QString myName;
1139     QColor  myValue;
1140   public:
1141     TEvent( const QString& section, const QString& name, const QColor& value ) 
1142       : mySection( section ), myName( name ), myValue( value ) {}
1143     virtual void Execute() 
1144     {
1145       if ( SUIT_Session::session() ) {
1146         SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
1147         if ( !mySection.isEmpty() && !myName.isEmpty() )
1148           resMgr->setValue( mySection, myName, myValue );
1149       }
1150     }
1151   };
1152   ProcessVoidEvent( new TEvent( section, name, value ) );
1153 }
1154
1155 /*!
1156   \fn int SalomePyQt::integerSetting( const QString& section, 
1157                                       const QString& name, 
1158                                       const int def );
1159   \brief Get integer setting from the application preferences.
1160   \param section resources file section name 
1161   \param name setting name
1162   \param def default value which is returned if the setting is not found
1163   \return setting value
1164 */
1165
1166 class TGetIntSettingEvent: public SALOME_Event 
1167 {
1168 public:
1169   typedef int TResult;
1170   TResult myResult;
1171   QString mySection;
1172   QString myName;
1173   TResult myDefault;
1174   TGetIntSettingEvent( const QString& section, const QString& name, const int def ) 
1175     : mySection( section ), myName( name ), myDefault( def ) {}
1176   virtual void Execute() 
1177   {
1178     if ( SUIT_Session::session() ) {
1179       SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
1180       myResult = ( !mySection.isEmpty() && !myName.isEmpty() ) ? resMgr->integerValue( mySection, myName, myDefault ) : myDefault;
1181     }
1182   }
1183 };
1184 int SalomePyQt::integerSetting( const QString& section, const QString& name, const int def )
1185 {
1186   return ProcessEvent( new TGetIntSettingEvent( section, name, def ) );
1187 }
1188
1189 /*!
1190   \fn double SalomePyQt::doubleSetting( const QString& section, 
1191                                         const QString& name, 
1192                                         const double def );
1193   \brief Get double setting from the application preferences.
1194   \param section resources file section name 
1195   \param name setting name
1196   \param def default value which is returned if the setting is not found
1197   \return setting value
1198 */
1199
1200 class TGetDblSettingEvent: public SALOME_Event 
1201 {
1202 public:
1203   typedef double TResult;
1204   TResult myResult;
1205   QString mySection;
1206   QString myName;
1207   TResult myDefault;
1208   TGetDblSettingEvent( const QString& section, const QString& name, const double def ) 
1209     : mySection( section ), myName( name ), myDefault( def ) {}
1210   virtual void Execute() 
1211   {
1212     if ( SUIT_Session::session() ) {
1213       SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
1214       myResult = ( !mySection.isEmpty() && !myName.isEmpty() ) ? resMgr->doubleValue( mySection, myName, myDefault ) : myDefault;
1215     }
1216   }
1217 };
1218 double SalomePyQt::doubleSetting( const QString& section, const QString& name, const double def )
1219 {
1220   return ProcessEvent( new TGetDblSettingEvent( section, name, def ) );
1221 }
1222
1223 /*!
1224   \fn bool SalomePyQt::boolSetting( const QString& section, 
1225                                     const QString& name, 
1226                                     const bool def );
1227   \brief Get boolean setting from the application preferences.
1228   \param section resources file section name 
1229   \param name setting name
1230   \param def default value which is returned if the setting is not found
1231   \return setting value
1232 */
1233
1234 class TGetBoolSettingEvent: public SALOME_Event 
1235 {
1236 public:
1237   typedef bool TResult;
1238   TResult myResult;
1239   QString mySection;
1240   QString myName;
1241   TResult myDefault;
1242   TGetBoolSettingEvent( const QString& section, const QString& name, const bool def ) 
1243     : mySection( section ), myName( name ), myDefault( def ) {}
1244   virtual void Execute() 
1245   {
1246     if ( SUIT_Session::session() ) {
1247       SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
1248       myResult = ( !mySection.isEmpty() && !myName.isEmpty() ) ? resMgr->booleanValue( mySection, myName, myDefault ) : myDefault;
1249     }
1250   }
1251 };
1252 bool SalomePyQt::boolSetting( const QString& section, const QString& name, const bool def )
1253 {
1254   return ProcessEvent( new TGetBoolSettingEvent( section, name, def ) );
1255 }
1256
1257 /*!
1258   \fn QString SalomePyQt::stringSetting( const QString& section, 
1259                                          const QString& name, 
1260                                          const QString& def );
1261   \brief Get string setting from the application preferences.
1262   \param section resources file section name 
1263   \param name setting name
1264   \param def default value which is returned if the setting is not found
1265   \return setting value
1266 */
1267
1268 class TGetStrSettingEvent: public SALOME_Event
1269 {
1270 public:
1271   typedef QString TResult;
1272   TResult myResult;
1273   QString mySection;
1274   QString myName;
1275   TResult myDefault;
1276   TGetStrSettingEvent( const QString& section, const QString& name, const QString& def ) 
1277     : mySection( section ), myName( name ), myDefault( def ) {}
1278   virtual void Execute() 
1279   {
1280     if ( SUIT_Session::session() ) {
1281       SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
1282       myResult = ( !mySection.isEmpty() && !myName.isEmpty() ) ? resMgr->stringValue( mySection, myName, myDefault ) : myDefault;
1283     }
1284   }
1285 };
1286 QString SalomePyQt::stringSetting( const QString& section, const QString& name, const QString& def )
1287 {
1288   return ProcessEvent( new TGetStrSettingEvent( section, name, def ) );
1289 }
1290
1291 /*!
1292   \fn QColor SalomePyQt::colorSetting( const QString& section, 
1293                                        const QString& name, 
1294                                        const QColor def );
1295   \brief Get color setting from the application preferences.
1296   \param section resources file section name 
1297   \param name setting name
1298   \param def default value which is returned if the setting is not found
1299   \return setting value
1300 */
1301
1302 class TGetColorSettingEvent: public SALOME_Event 
1303 {
1304 public:
1305   typedef QColor TResult;
1306   TResult myResult;
1307   QString mySection;
1308   QString myName;
1309   TResult myDefault;
1310   TGetColorSettingEvent( const QString& section, const QString& name, const QColor& def ) 
1311     : mySection( section ), myName( name ), myDefault( def ) {}
1312   virtual void Execute() 
1313   {
1314     if ( SUIT_Session::session() ) {
1315       SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
1316       myResult = ( !mySection.isEmpty() && !myName.isEmpty() ) ? resMgr->colorValue( mySection, myName, myDefault ) : myDefault;
1317     }
1318   }
1319 };
1320 QColor SalomePyQt::colorSetting ( const QString& section, const QString& name, const QColor& def )
1321 {
1322   return ProcessEvent( new TGetColorSettingEvent( section, name, def ) );
1323 }
1324
1325 /*!
1326   \brief Remove setting from the application preferences.
1327   \param section resources file section name 
1328   \param name setting name
1329 */
1330 void SalomePyQt::removeSetting( const QString& section, const QString& name )
1331 {
1332   class TEvent: public SALOME_Event 
1333   {
1334     QString mySection;
1335     QString myName;
1336   public:
1337     TEvent( const QString& section, const QString& name ) : mySection( section ), myName( name ) {}
1338     virtual void Execute() 
1339     {
1340       if ( SUIT_Session::session() ) {
1341         SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
1342         if ( !mySection.isEmpty() && !myName.isEmpty() )
1343           resMgr->remove( mySection, myName );
1344       }
1345     }
1346   };
1347   ProcessVoidEvent( new TEvent( section, name ) );
1348 }
1349
1350 /*!
1351   \fn bool SalomePyQt::hasSetting( const QString& section, const QString& name );
1352   \brief Check setting existence in the application preferences.
1353   \param section resources file section name 
1354   \param name setting name
1355   \return \c true if setting exists
1356 */
1357
1358 class THasColorSettingEvent: public SALOME_Event 
1359 {
1360 public:
1361   typedef bool TResult;
1362   TResult myResult;
1363   QString mySection;
1364   QString myName;
1365   THasColorSettingEvent( const QString& section, const QString& name ) 
1366     : mySection( section ), myName( name ) {}
1367   virtual void Execute() 
1368   {
1369     if ( SUIT_Session::session() ) {
1370       SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
1371       myResult = resMgr->hasValue( mySection, myName );
1372     }
1373   }
1374 };
1375 bool SalomePyQt::hasSetting( const QString& section, const QString& name )
1376 {
1377   return ProcessEvent( new THasColorSettingEvent( section, name ) );
1378 }
1379
1380 /*!
1381   \fn QString SalomePyQt::getFileName( QWidget*           parent, 
1382                                        const QString&     initial, 
1383                                        const QStringList& filters, 
1384                                        const QString&     caption,
1385                                        bool               open );
1386   \brief Show 'Open/Save file' dialog box for file selection 
1387          and return a user's choice (selected file name).
1388   \param parent parent widget
1389   \param initial initial directory the dialog box to be opened in
1390   \param filters list of files filters (wildcards)
1391   \param caption dialog box title
1392   \param open if \c true, "Open File" dialog box is shown; 
1393          otherwise "Save File" dialog box is shown
1394   \return selected file name (null string if user cancels operation)
1395 */
1396
1397 class TGetFileNameEvent: public SALOME_Event 
1398 {
1399 public:
1400   typedef QString TResult;
1401   TResult     myResult;
1402   QWidget*    myParent;
1403   QString     myInitial;
1404   QStringList myFilters;
1405   QString     myCaption;
1406   bool        myOpen;
1407   TGetFileNameEvent( QWidget*           parent, 
1408                      const QString&     initial, 
1409                      const QStringList& filters, 
1410                      const QString&     caption,
1411                      bool               open ) 
1412     : myParent ( parent ), 
1413       myInitial( initial ), 
1414       myFilters( filters ), 
1415       myCaption( caption ), 
1416       myOpen ( open ) {}
1417   virtual void Execute() 
1418   {
1419     if ( LightApp_Application* anApp = getApplication() ) {
1420       myResult = anApp->getFileName( myOpen, myInitial, myFilters.join(";;"), 
1421                                      myCaption, myParent );
1422     }
1423   }
1424 };
1425 QString SalomePyQt::getFileName( QWidget*           parent, 
1426                                  const QString&     initial, 
1427                                  const QStringList& filters, 
1428                                  const QString&     caption,
1429                                  bool               open )
1430 {
1431   return ProcessEvent( new TGetFileNameEvent( parent, initial, filters, caption, open ) );
1432 }
1433
1434 /*!
1435   \fn QStringList SalomePyQt::getOpenFileNames( QWidget*           parent, 
1436                                                 const QString&     initial, 
1437                                                 const QStringList& filters, 
1438                                                 const QString&     caption );
1439   \brief Show 'Open files' dialog box for multiple files selection
1440          and return a user's choice (selected file names list).
1441   \param parent parent widget
1442   \param initial initial directory the dialog box to be opened in
1443   \param filters list of files filters (wildcards)
1444   \param caption dialog box title
1445   \return selected file names list (empty list if user cancels operation)
1446 */
1447
1448 class TGetOpenFileNamesEvent: public SALOME_Event 
1449 {
1450 public:
1451   typedef QStringList TResult;
1452   TResult     myResult;
1453   QWidget*    myParent;
1454   QString     myInitial;
1455   QStringList myFilters;
1456   QString     myCaption;
1457   TGetOpenFileNamesEvent( QWidget*           parent, 
1458                           const QString&     initial, 
1459                           const QStringList& filters, 
1460                           const QString&     caption ) 
1461     : myParent ( parent ), 
1462       myInitial( initial ), 
1463       myFilters( filters ), 
1464       myCaption( caption ) {}
1465   virtual void Execute() 
1466   {
1467     if ( LightApp_Application* anApp = getApplication() ) {
1468       myResult = anApp->getOpenFileNames( myInitial, myFilters.join(";;"), myCaption, myParent );
1469     }
1470   }
1471 };
1472 QStringList SalomePyQt::getOpenFileNames( QWidget*           parent, 
1473                                           const QString&     initial, 
1474                                           const QStringList& filters, 
1475                                           const QString&     caption )
1476 {
1477   return ProcessEvent( new TGetOpenFileNamesEvent( parent, initial, filters, caption ) );
1478 }
1479
1480 /*!
1481   \fn QString SalomePyQt::getExistingDirectory( QWidget*       parent,
1482                                                 const QString& initial,
1483                                                 const QString& caption );
1484   \brief Show 'Get Directory' dialog box for the directory selection
1485          and return a user's choice (selected directory name).
1486   \param parent parent widget
1487   \param initial initial directory the dialog box to be opened in
1488   \param caption dialog box title
1489   \return selected directory name (null string if user cancels operation)
1490 */
1491
1492 class TGetExistingDirectoryEvent: public SALOME_Event 
1493 {
1494 public:
1495   typedef QString TResult;
1496   TResult     myResult;
1497   QWidget*    myParent;
1498   QString     myInitial;
1499   QString     myCaption;
1500   TGetExistingDirectoryEvent( QWidget*           parent, 
1501                               const QString&     initial, 
1502                               const QString&     caption ) 
1503     : myParent ( parent ), 
1504       myInitial( initial ), 
1505       myCaption( caption ) {}
1506   virtual void Execute() 
1507   {
1508     if ( LightApp_Application* anApp = getApplication() ) {
1509       myResult = anApp->getDirectory( myInitial, myCaption, myParent );
1510     }
1511   }
1512 };
1513 QString SalomePyQt::getExistingDirectory( QWidget*       parent,
1514                                           const QString& initial,
1515                                           const QString& caption )
1516 {
1517   return ProcessEvent( new TGetExistingDirectoryEvent( parent, initial, caption ) );
1518 }
1519
1520 /*!
1521   \fn QString SalomePyQt::loadIcon( const QString& filename );
1522   \brief Load an icon from the module resources by the specified file name.
1523   \param fileName icon file name
1524   \return icon object
1525 */
1526
1527 class TLoadIconEvent: public SALOME_Event 
1528 {
1529 public:
1530   typedef QIcon TResult;
1531   TResult     myResult;
1532   QString     myModule;
1533   QString     myFileName;
1534   TLoadIconEvent( const QString& module, const QString& filename ) 
1535     : myModule( module ), 
1536       myFileName ( filename ) {}
1537   virtual void Execute() 
1538   {
1539     myResult = loadIconInternal( myModule, myFileName );
1540   }
1541 };
1542 QIcon SalomePyQt::loadIcon( const QString& module, const QString& filename )
1543 {
1544   return ProcessEvent( new TLoadIconEvent( module, filename ) );
1545 }
1546
1547 /*!
1548   \brief Open external browser to display context help information.
1549   \todo
1550
1551   Current implementation does nothing.
1552
1553   \param source documentation (HTML) file name
1554   \param context context (for example, HTML ancor name)
1555 */
1556 void SalomePyQt::helpContext( const QString& source, const QString& context ) 
1557 {
1558   class TEvent: public SALOME_Event 
1559   {
1560     QString mySource;
1561     QString myContext;
1562   public:
1563     TEvent( const QString& source, const QString& context ) 
1564       : mySource( source ), myContext( context ) {}
1565     virtual void Execute() 
1566     {
1567       if ( LightApp_Application* anApp = getApplication() ) {
1568         anApp->onHelpContextModule( "", mySource, myContext );
1569       }
1570     }
1571   };
1572   ProcessVoidEvent( new TEvent( source, context ) );
1573 }
1574
1575 /*!
1576   \fn int SalomePyQt::defaultMenuGroup();
1577   \brief Get detault menu group identifier which can be used when 
1578   creating menus (insert custom menu commands).
1579   \return default menu group ID
1580 */
1581
1582 class TDefMenuGroupEvent: public SALOME_Event 
1583 {
1584 public:
1585   typedef int TResult;
1586   TResult myResult;
1587   TDefMenuGroupEvent() : myResult( -1 ) {}
1588   virtual void Execute() 
1589   {
1590     myResult = PyModuleHelper::defaultMenuGroup();
1591   }
1592 };
1593 int SalomePyQt::defaultMenuGroup()
1594 {
1595   return ProcessEvent( new TDefMenuGroupEvent() );
1596 }
1597
1598 class CrTool
1599 {
1600 public:
1601   CrTool( const QString& tBar, const QString& nBar ) 
1602     : myCase( 0 ), myTbTitle( tBar ), myTbName( nBar)  {}
1603   CrTool( const int id, const int tBar, const int idx ) 
1604     : myCase( 1 ), myId( id ), myTbId( tBar ), myIndex( idx ) {}
1605   CrTool( const int id, const QString& tBar, const int idx )
1606     : myCase( 2 ), myId( id ), myTbTitle( tBar ), myIndex( idx ) {}
1607   CrTool( QAction* action, const int tbId, const int id, const int idx )
1608     : myCase( 3 ), myAction( action ), myTbId( tbId ), myId( id ), myIndex( idx ) {}
1609   CrTool( QAction* action, const QString& tBar, const int id, const int idx )
1610     : myCase( 4 ), myAction( action ), myTbTitle( tBar ), myId( id ), myIndex( idx ) {}
1611
1612   int execute( LightApp_Module* module ) const
1613   {
1614     if ( module ) {
1615       switch ( myCase ) {
1616       case 0:
1617         return module->createTool( myTbTitle, myTbName );
1618       case 1:
1619         return module->createTool( myId, myTbId, myIndex );
1620       case 2:
1621         return module->createTool( myId, myTbTitle, myIndex );
1622       case 3:
1623         return module->createTool( myAction, myTbId, myId, myIndex );
1624       case 4:
1625         return module->createTool( myAction, myTbTitle, myId, myIndex );
1626       }
1627     }
1628     return -1;
1629   }
1630 private:
1631    int        myCase;
1632    QString    myTbTitle;
1633    QString    myTbName;
1634    int        myTbId;
1635    QAction*   myAction;
1636    int        myId;
1637    int        myIndex;
1638 };
1639
1640 class TCreateToolEvent: public SALOME_Event 
1641 {
1642 public:
1643   typedef int TResult;
1644   TResult myResult;
1645   const CrTool& myCrTool;
1646   TCreateToolEvent( const CrTool& crTool ) 
1647     : myResult( -1 ), myCrTool( crTool ) {}
1648   virtual void Execute() 
1649   {
1650     LightApp_Module* module = getActiveModule();
1651     if ( module )
1652       myResult = myCrTool.execute( module );
1653   }
1654 };
1655
1656 /*!
1657   \brief Create toolbar with specified name.
1658   \param tBar toolbar title (language-dependent)
1659   \param nBar toolbar name (language-independent) [optional]
1660   \return toolbar ID or -1 if toolbar creation is failed
1661 */
1662 int SalomePyQt::createTool( const QString& tBar, const QString& nBar )
1663 {
1664   return ProcessEvent( new TCreateToolEvent( CrTool( tBar, nBar ) ) );
1665 }
1666
1667 /*! 
1668   \brief Insert action with specified \a id to the toolbar.
1669   \param id action ID
1670   \param tBar toolbar ID
1671   \param idx required index in the toolbar
1672   \return action ID or -1 if action could not be added
1673 */
1674 int SalomePyQt::createTool( const int id, const int tBar, const int idx )
1675 {
1676   return ProcessEvent( new TCreateToolEvent( CrTool( id, tBar, idx ) ) );
1677 }
1678
1679 /*!
1680   \brief Insert action with specified \a id to the toolbar.
1681   \param id action ID
1682   \param tBar toolbar name
1683   \param idx required index in the toolbar
1684   \return action ID or -1 if action could not be added
1685 */
1686 int SalomePyQt::createTool( const int id, const QString& tBar, const int idx )
1687 {
1688   return ProcessEvent( new TCreateToolEvent( CrTool( id, tBar, idx ) ) );
1689 }
1690
1691 /*!
1692   \brief Insert action to the toolbar.
1693   \param a action
1694   \param tBar toolbar ID
1695   \param id required action ID
1696   \param idx required index in the toolbar
1697   \return action ID or -1 if action could not be added
1698 */
1699 int SalomePyQt::createTool( QAction* a, const int tBar, const int id, const int idx )
1700 {
1701   return ProcessEvent( new TCreateToolEvent( CrTool( a, tBar, id, idx ) ) );
1702 }
1703
1704 /*!
1705   \brief Insert action to the toolbar.
1706   \param a action
1707   \param tBar toolbar name
1708   \param id required action ID
1709   \param idx required index in the toolbar
1710   \return action ID or -1 if action could not be added
1711 */
1712 int SalomePyQt::createTool( QAction* a, const QString& tBar, const int id, const int idx )
1713 {
1714   return ProcessEvent( new TCreateToolEvent( CrTool( a, tBar, id, idx ) ) );
1715 }
1716
1717 class CrMenu
1718 {
1719 public:
1720   CrMenu( const QString& subMenu, const int menu, const int id, const int group, const int idx ) 
1721     : myCase( 0 ), mySubMenuName( subMenu ), myMenuId( menu ), myId( id ), myGroup( group ), myIndex( idx ) {}
1722   CrMenu( const QString& subMenu, const QString& menu, const int id, const int group, const int idx ) 
1723     : myCase( 1 ), mySubMenuName( subMenu ), myMenuName( menu ), myId( id ), myGroup( group ), myIndex( idx ) {}
1724   CrMenu( const int id, const int menu, const int group, const int idx ) 
1725     : myCase( 2 ), myId( id ), myMenuId( menu ), myGroup( group ), myIndex( idx ) {}
1726   CrMenu( const int id, const QString& menu, const int group, const int idx ) 
1727     : myCase( 3 ), myId( id ), myMenuName( menu ), myGroup( group ), myIndex( idx ) {}
1728   CrMenu( QAction* action, const int menu, const int id, const int group, const int idx ) 
1729     : myCase( 4 ), myAction( action ), myMenuId( menu ), myId( id ), myGroup( group ), myIndex( idx ) {}
1730   CrMenu( QAction* action, const QString& menu, const int id, const int group, const int idx ) 
1731     : myCase( 5 ), myAction( action ), myMenuName( menu ), myId( id ), myGroup( group ), myIndex( idx ) {}
1732
1733   int execute( LightApp_Module* module ) const
1734   {
1735     if ( module ) {
1736       switch ( myCase ) {
1737       case 0:
1738         return module->createMenu( mySubMenuName, myMenuId, myId, myGroup, myIndex );
1739       case 1:
1740         return module->createMenu( mySubMenuName, myMenuName, myId, myGroup, myIndex );
1741       case 2:
1742         return module->createMenu( myId, myMenuId, myGroup, myIndex );
1743       case 3:
1744         return module->createMenu( myId, myMenuName, myGroup, myIndex );
1745       case 4:
1746         return module->createMenu( myAction, myMenuId, myId, myGroup, myIndex );
1747       case 5:
1748         return module->createMenu( myAction, myMenuName, myId, myGroup, myIndex );
1749       }
1750     }
1751     return -1;
1752   }
1753 private:
1754    int        myCase;
1755    QString    myMenuName;
1756    int        myMenuId;
1757    QString    mySubMenuName;
1758    int        myGroup;
1759    QAction*   myAction;
1760    int        myId;
1761    int        myIndex;
1762 };
1763
1764 class TCreateMenuEvent: public SALOME_Event
1765 {
1766 public:
1767   typedef int TResult;
1768   TResult myResult;
1769   const CrMenu& myCrMenu;
1770   TCreateMenuEvent( const CrMenu& crMenu ) 
1771     : myResult( -1 ), myCrMenu( crMenu ) {}
1772   virtual void Execute()
1773   {
1774     LightApp_Module* module = getActiveModule();
1775     if ( module )
1776       myResult = myCrMenu.execute( module );
1777   }
1778 };
1779
1780 /*!
1781   \brief Create main menu.
1782   \param subMenu menu name
1783   \param menu parent menu ID
1784   \param id required menu ID
1785   \param group menu group ID
1786   \param idx required index in the menu
1787   \return menu ID or -1 if menu could not be added
1788 */
1789 int SalomePyQt::createMenu( const QString& subMenu, const int menu, const int id, const int group, const int idx )
1790 {
1791   return ProcessEvent( new TCreateMenuEvent( CrMenu( subMenu, menu, id, group, idx ) ) );
1792 }
1793
1794 /*!
1795   \brief Create main menu.
1796   \param subMenu menu name
1797   \param menu parent menu name (list of menu names separated by "|")
1798   \param id required menu ID
1799   \param group menu group ID
1800   \param idx required index in the menu
1801   \return menu ID or -1 if menu could not be added
1802 */
1803 int SalomePyQt::createMenu( const QString& subMenu, const QString& menu, const int id, const int group, const int idx )
1804 {
1805   return ProcessEvent( new TCreateMenuEvent( CrMenu( subMenu, menu, id, group, idx ) ) );
1806 }
1807
1808 /*!
1809   \brief Insert action to the main menu.
1810   \param id action ID
1811   \param menu parent menu ID
1812   \param group menu group ID
1813   \param idx required index in the menu
1814   \return action ID or -1 if action could not be added
1815 */
1816 int SalomePyQt::createMenu( const int id, const int menu, const int group, const int idx )
1817 {
1818   return ProcessEvent( new TCreateMenuEvent( CrMenu( id, menu, group, idx ) ) );
1819 }
1820
1821 /*!
1822   \brief Insert action to the main menu.
1823   \param id action ID
1824   \param menu parent menu name (list of menu names separated by "|")
1825   \param group menu group ID
1826   \param idx required index in the menu
1827   \return action ID or -1 if action could not be added
1828 */
1829 int SalomePyQt::createMenu( const int id, const QString& menu, const int group, const int idx )
1830 {
1831   return ProcessEvent( new TCreateMenuEvent( CrMenu( id, menu, group, idx ) ) );
1832 }
1833
1834 /*!
1835   \brief Insert action to the main menu.
1836   \param a action
1837   \param menu parent menu ID
1838   \param group menu group ID
1839   \param idx required index in the menu
1840   \return action ID or -1 if action could not be added
1841 */
1842 int SalomePyQt::createMenu( QAction* a, const int menu, const int id, const int group, const int idx )
1843 {
1844   return ProcessEvent( new TCreateMenuEvent( CrMenu( a, menu, id, group, idx ) ) );
1845 }
1846
1847 /*!
1848   \brief Insert action to the main menu.
1849   \param a action
1850   \param menu parent menu name (list of menu names separated by "|")
1851   \param group menu group ID
1852   \param idx required index in the menu
1853   \return action ID or -1 if action could not be added
1854 */
1855 int SalomePyQt::createMenu( QAction* a, const QString& menu, const int id, const int group, const int idx )
1856 {
1857   return ProcessEvent( new TCreateMenuEvent( CrMenu( a, menu, id, group, idx ) ) );
1858 }
1859
1860 /*!
1861   \fn QAction* SalomePyQt::createSeparator();
1862   \brief Create separator action which can be used in the menu or toolbar.
1863   \return new separator action
1864 */
1865
1866 class TCreateSepEvent: public SALOME_Event 
1867 {
1868 public:
1869   typedef QAction* TResult;
1870   TResult myResult;
1871   TCreateSepEvent() 
1872     : myResult( 0 ) {}
1873   virtual void Execute() 
1874   {
1875     LightApp_Module* module = getActiveModule();
1876     if ( module )
1877       myResult = (QAction*)module->separator();
1878   }
1879 };
1880 QAction* SalomePyQt::createSeparator()
1881 {
1882   return ProcessEvent( new TCreateSepEvent() );
1883 }
1884
1885 /*!
1886   \fn QAction* SalomePyQt::createAction( const int      id,
1887                                          const QString& menuText, 
1888                                          const QString& tipText, 
1889                                          const QString& statusText, 
1890                                          const QString& icon,
1891                                          const int      key, 
1892                                          const bool     toggle );
1893   \brief Create an action which can be then used in the menu or toolbar.
1894   \param id the unique id action to be registered to
1895   \param menuText action text which should appear in menu
1896   \param tipText text which should appear in the tooltip
1897   \param statusText text which should appear in the status bar when action is activated
1898   \param icon the name of the icon file (the actual icon file name can be coded in the translation files)
1899   \param key the key accelrator for the action
1900   \param toggle if \c true the action is checkable
1901 */
1902
1903 class TCreateActionEvent: public SALOME_Event 
1904 {
1905 public:
1906   typedef QAction* TResult;
1907   TResult myResult;
1908   int     myId;
1909   QString myMenuText;
1910   QString myTipText;
1911   QString myStatusText;
1912   QString myIcon;
1913   int     myKey;
1914   bool    myToggle;
1915   TCreateActionEvent( const int id, const QString& menuText, const QString& tipText, 
1916                       const QString& statusText, const QString& icon, const int key, const bool toggle ) 
1917     : myResult( 0 ), myId( id ), myMenuText( menuText ), myTipText( tipText ),
1918       myStatusText( statusText ), myIcon( icon ), myKey( key ), myToggle( toggle ) {}
1919   virtual void Execute()
1920   {
1921     LightApp_Module* module = getActiveModule();
1922     if ( module ) {
1923       QIcon icon = loadIconInternal( module->name(), myIcon );
1924       myResult = (QAction*)module->action( myId );
1925       if ( myResult ) {
1926         if ( myResult->toolTip().isEmpty() && !myTipText.isEmpty() ) 
1927           myResult->setToolTip( myTipText );
1928         if ( myResult->text().isEmpty() && !myMenuText.isEmpty() )
1929           myResult->setText( myMenuText );
1930         if ( myResult->icon().isNull() && !icon.isNull() ) 
1931           myResult->setIcon( icon );
1932         if ( myResult->statusTip().isEmpty() && !myStatusText.isEmpty() )
1933           myResult->setStatusTip( myStatusText );
1934         if ( myResult->shortcut().isEmpty() && myKey )
1935           myResult->setShortcut( myKey );
1936         if ( myResult->isCheckable() != myToggle )
1937           myResult->setCheckable( myToggle );
1938       }
1939       else {
1940         myResult = (QAction*)module->createAction( myId, myTipText, icon, myMenuText, myStatusText, myKey, module, myToggle );
1941       }
1942       // for Python module, automatically connect action to callback slot
1943       PyModuleHelper* helper = module->findChild<PyModuleHelper*>( "python_module_helper" );
1944       if ( helper ) helper->connectAction( myResult );
1945     }
1946   }
1947 };
1948 QAction* SalomePyQt::createAction( const int id,           const QString& menuText, 
1949                                    const QString& tipText, const QString& statusText, 
1950                                    const QString& icon,    const int key, const bool toggle )
1951 {
1952   return ProcessEvent( new TCreateActionEvent( id, menuText, tipText, statusText, icon, key, toggle ) );
1953 }
1954
1955 /*!
1956   \fn QtxActionGroup* SalomePyQt::createActionGroup( const int id, const bool exclusive );
1957   \brief Create an action group which can be then used in the menu or toolbar
1958   \param id         : the unique id action group to be registered to
1959   \param exclusive  : if \c true the action group does exclusive toggling
1960 */
1961
1962 struct TCreateActionGroupEvent: public SALOME_Event 
1963 {
1964   typedef QtxActionGroup* TResult;
1965   TResult myResult;
1966   int     myId;
1967   bool    myExclusive;
1968   TCreateActionGroupEvent( const int id, const bool exclusive )
1969     : myId( id ), myExclusive( exclusive ) {}
1970   virtual void Execute()
1971   {
1972     LightApp_Module* module = getActiveModule();
1973     if ( module )
1974       myResult = module->createActionGroup( myId, myExclusive );
1975   }
1976 };
1977 QtxActionGroup* SalomePyQt::createActionGroup( const int id, const bool exclusive )
1978 {
1979   return ProcessEvent( new TCreateActionGroupEvent( id, exclusive ) );
1980 }
1981
1982 /*!
1983   \fn QAction* SalomePyQt::action( const int id );
1984   \brief Get action by specified identifier.
1985   \return action or 0 if action is not registered
1986 */
1987
1988 class TActionEvent: public SALOME_Event 
1989 {
1990 public:
1991   typedef QAction* TResult;
1992   TResult myResult;
1993   int     myId;
1994   TActionEvent( const int id )
1995     : myResult( 0 ), myId( id ) {}
1996   virtual void Execute()
1997   {
1998     LightApp_Module* module = getActiveModule();
1999     if ( module )
2000       myResult = (QAction*)module->action( myId );
2001   }
2002 };
2003 QAction* SalomePyQt::action( const int id )
2004 {
2005   return ProcessEvent( new TActionEvent( id ) );
2006 }
2007
2008 /*!
2009   \fn int SalomePyQt::actionId( const QAction* a );
2010   \brief Get an action identifier. 
2011   \return action ID or -1 if action is not registered
2012 */
2013
2014 class TActionIdEvent: public SALOME_Event 
2015 {
2016 public:
2017   typedef  int TResult;
2018   TResult  myResult;
2019   const QAction* myAction;
2020   TActionIdEvent( const QAction* action )
2021     : myResult( -1 ), myAction( action ) {}
2022   virtual void Execute()
2023   {
2024     LightApp_Module* module = getActiveModule();
2025     if ( module )
2026       myResult = module->actionId( myAction );
2027   }
2028 };
2029 int SalomePyQt::actionId( const QAction* a )
2030 {
2031   return ProcessEvent( new TActionIdEvent( a ) );
2032 }
2033
2034 /*!
2035   \fn int SalomePyQt::addGlobalPreference( const QString& label );
2036   \brief Add global (not module-related) preferences group.
2037   \param label global preferences group name
2038   \return preferences group identifier
2039 */
2040
2041 class TAddGlobalPrefEvent: public SALOME_Event
2042 {
2043 public:
2044   typedef int TResult;
2045   TResult myResult;
2046   QString myLabel;
2047   TAddGlobalPrefEvent( const QString& label )
2048     : myResult( -1 ), myLabel( label ) {}
2049   virtual void Execute() 
2050   {
2051     LightApp_Module* module = getActiveModule();
2052     if ( module ) {
2053       LightApp_Preferences* pref = module->getApp()->preferences();
2054       if ( pref )
2055         myResult = pref->addPreference( myLabel, -1 );
2056     }
2057   }
2058 };
2059 int SalomePyQt::addGlobalPreference( const QString& label )
2060 {
2061   return ProcessEvent( new TAddGlobalPrefEvent( label ) );
2062 }
2063
2064 /*!
2065   \fn int SalomePyQt::addPreference( const QString& label );
2066   \brief Add module-related preferences group.
2067   \param label preferences group name
2068   \return preferences group identifier
2069 */
2070
2071 class TAddPrefEvent: public SALOME_Event 
2072 {
2073 public:
2074   typedef int TResult;
2075   TResult myResult;
2076   QString myLabel;
2077   TAddPrefEvent( const QString& label )
2078     : myResult( -1 ), myLabel( label ) {}
2079   virtual void Execute() 
2080   {
2081     LightApp_Module* module = getActiveModule();
2082     if ( module ) {
2083       LightApp_Preferences* pref = module->getApp()->preferences();
2084       if ( pref ) {
2085         int cId = pref->addPreference( module->moduleName(), -1 );
2086         if ( cId != -1 )
2087           myResult = pref->addPreference( myLabel, cId );
2088       }
2089     }
2090   }
2091 };
2092 int SalomePyQt::addPreference( const QString& label )
2093 {
2094   return ProcessEvent( new TAddPrefEvent( label ) );
2095 }
2096
2097 /*!
2098   \fn int SalomePyQt::addPreference( const QString& label, const int pId, const int type,
2099                                      const QString& section, const QString& param );
2100   \brief Add module-related preferences.
2101   \param label preferences group name
2102   \param pId parent preferences group id
2103   \param type preferences type
2104   \param section resources file section name
2105   \param param resources file setting name
2106   \return preferences identifier
2107 */
2108
2109 class TAddPrefParamEvent: public SALOME_Event
2110 {
2111 public:
2112   typedef int TResult;
2113   TResult myResult;
2114   QString myLabel;
2115   int     myPId;
2116   int     myType;
2117   QString mySection;
2118   QString myParam;
2119   TAddPrefParamEvent( const QString& label, 
2120                       const int pId, const int type,
2121                       const QString& section, 
2122                       const QString& param )
2123     : myResult( -1 ),
2124       myLabel( label ), myPId( pId ), myType( type ), 
2125       mySection( section ), myParam ( param ) {}
2126   virtual void Execute()
2127   {
2128     LightApp_Module* module = getActiveModule();
2129     if ( module ) {
2130       LightApp_Preferences* pref = module->getApp()->preferences();
2131       if ( pref )
2132         myResult = pref->addPreference( module->moduleName(), myLabel, myPId, myType, mySection, myParam );
2133     }
2134   }
2135 };
2136 int SalomePyQt::addPreference( const QString& label, const int pId, const int type,
2137                                const QString& section, const QString& param )
2138 {
2139   return ProcessEvent( new TAddPrefParamEvent( label, pId, type, section, param ) );
2140 }
2141
2142 /*!
2143   \fn QVariant SalomePyQt::preferenceProperty( const int id, const QString& prop );
2144   \brief Get the preferences property.
2145   \param id preferences identifier
2146   \param prop preferences property name
2147   \return preferences property value or null QVariant if property is not set
2148 */
2149
2150 class TPrefPropEvent: public SALOME_Event
2151 {
2152 public:
2153   typedef QVariant TResult;
2154   TResult myResult;
2155   int     myId;
2156   QString myProp;
2157   TPrefPropEvent( const int id, const QString& prop )
2158     : myId( id ), myProp( prop ) {}
2159   virtual void Execute()
2160   {
2161     LightApp_Module* module = getActiveModule();
2162     if ( module ) {
2163       LightApp_Preferences* pref = module->getApp()->preferences();
2164       if ( pref )
2165         myResult = pref->itemProperty( myProp, myId );
2166     }
2167   }
2168 };
2169 QVariant SalomePyQt::preferenceProperty( const int id, const QString& prop )
2170 {
2171   return ProcessEvent( new TPrefPropEvent( id, prop ) );
2172 }
2173
2174 /*!
2175   \brief Set the preferences property.
2176   \param id preferences identifier
2177   \param prop preferences property name
2178   \param var preferences property value
2179 */
2180 void SalomePyQt::setPreferenceProperty( const int id, 
2181                                         const QString& prop,
2182                                         const QVariant& var )
2183 {
2184   class TEvent: public SALOME_Event
2185   {
2186     int      myId;
2187     QString  myProp;
2188     QVariant myVar;
2189   public:
2190     TEvent( const int id, const QString& prop, const QVariant& var ) 
2191       : myId( id ), myProp( prop ), myVar( var ) {}
2192     virtual void Execute() 
2193     {
2194       LightApp_Module* module = getActiveModule();
2195       if ( module ) {
2196         LightApp_Preferences* pref = module->getApp()->preferences();
2197         if ( pref )
2198           pref->setItemProperty( myProp, myVar, myId );
2199       }
2200     }
2201   };
2202   ProcessVoidEvent( new TEvent( id, prop, var) );
2203 }
2204
2205 /*!
2206   \brief Add the property value to the list of values.
2207
2208   This method allows creating properties which are QList<QVariant>
2209   - there is no way to pass such values directly to QVariant parameter with PyQt.
2210
2211   \param id preferences identifier
2212   \param prop preferences property name
2213   \param idx preferences property index
2214   \param var preferences property value for the index \a idx
2215 */
2216 void SalomePyQt::addPreferenceProperty( const int id, 
2217                                         const QString& prop,
2218                                         const int idx, 
2219                                         const QVariant& var )
2220 {
2221   class TEvent: public SALOME_Event
2222   {
2223     int      myId;
2224     QString  myProp;
2225     int      myIdx;
2226     QVariant myVar;
2227   public:
2228     TEvent( const int id, const QString& prop, const int idx, const QVariant& var ) 
2229       : myId( id ), myProp( prop ), myIdx( idx), myVar( var ) {}
2230     virtual void Execute()
2231     {
2232       LightApp_Module* module = getActiveModule();
2233       if ( module ) {
2234         LightApp_Preferences* pref = module->getApp()->preferences();
2235         if ( pref ) {
2236           QVariant var =  pref->itemProperty( myProp, myId );
2237           if ( var.isValid() ) {
2238             if ( var.type() == QVariant::StringList ) {
2239               QStringList sl = var.toStringList();
2240               if ( myIdx >= 0 && myIdx < sl.count() ) 
2241                 sl[myIdx] = myVar.toString();
2242               else
2243                 sl.append( myVar.toString() );
2244               pref->setItemProperty( myProp, sl, myId );
2245             }
2246             else if ( var.type() == QVariant::List ) {
2247               QList<QVariant> vl = var.toList();
2248               if ( myIdx >= 0 && myIdx < vl.count() ) 
2249                 vl[myIdx] = myVar;
2250               else
2251                 vl.append( myVar );
2252               pref->setItemProperty( myProp, vl, myId );
2253             }
2254           }
2255           else {
2256             QList<QVariant> vl;
2257             vl.append( myVar );
2258             pref->setItemProperty( myProp, vl, myId );
2259           }
2260         }
2261       }
2262     }
2263   };
2264   ProcessVoidEvent( new TEvent( id, prop, idx, var) );
2265 }
2266
2267 /*!
2268   \brief Put the message to the Log messages output window
2269   \param msg message text (it can be of simple rich text format)
2270   \param addSeparator boolean flag which specifies if it is necessary 
2271          to separate the message with predefined separator
2272 */
2273 void SalomePyQt::message( const QString& msg, bool addSeparator )
2274 {
2275   class TEvent: public SALOME_Event
2276   {
2277     QString  myMsg;
2278     bool     myAddSep;
2279   public:
2280     TEvent( const QString& msg, bool addSeparator ) 
2281       : myMsg( msg ), myAddSep( addSeparator ) {}
2282     virtual void Execute()
2283     {
2284       if ( LightApp_Application* anApp = getApplication() ) {
2285         LogWindow* lw = anApp->logWindow();
2286         if ( lw )
2287           lw->putMessage( myMsg, myAddSep );
2288       }
2289     }
2290   };
2291   ProcessVoidEvent( new TEvent( msg, addSeparator ) );
2292 }
2293
2294 /*!
2295   \brief Remove all the messages from the Log messages output window.
2296 */
2297 void SalomePyQt::clearMessages()
2298 {
2299   class TEvent: public SALOME_Event
2300   {
2301   public:
2302     TEvent() {}
2303     virtual void Execute()
2304     {
2305       if ( LightApp_Application* anApp = getApplication() ) {
2306         LogWindow* lw = anApp->logWindow();
2307         if ( lw )
2308           lw->clear();
2309       }
2310     }
2311   };
2312   ProcessVoidEvent( new TEvent() );
2313 }
2314
2315 /*!
2316   \fn bool SalomePyQt::dumpView( const QString& filename, const int id = 0 );
2317   \brief Dump the contents of the id view window. If id is 0 then current active view is processed. 
2318   to the image file in the specified format.
2319
2320   For the current moment JPEG, PNG and BMP images formats are supported.
2321   The image format is defined automatically by the file name extension.
2322   By default, BMP format is used.
2323
2324   \param filename image file name
2325   \return operation status (\c true on success)
2326 */
2327
2328 class TDumpViewEvent: public SALOME_Event 
2329 {
2330 public:
2331   typedef bool TResult;
2332   TResult myResult;
2333   QString myFileName;
2334   int myWndId;
2335   TDumpViewEvent( const QString& filename, const int id ) 
2336     : myResult ( false ), myFileName( filename ), myWndId( id ) {}
2337   virtual void Execute() 
2338   {
2339     SUIT_ViewWindow* wnd = 0;
2340     if ( !myWndId ) {
2341       if ( LightApp_Application* anApp = getApplication() ) {
2342         SUIT_ViewManager* vm = anApp->activeViewManager();
2343         if ( vm )
2344           wnd = vm->getActiveView();
2345       }
2346       myWndId = wnd->getId();
2347     }
2348     else {
2349       wnd = dynamic_cast<SUIT_ViewWindow*>( getWnd( myWndId ) );
2350     }
2351     if ( wnd ) {
2352       QString fmt = SUIT_Tools::extension( myFileName ).toUpper();
2353 #ifndef DISABLE_PLOT2DVIEWER
2354       Plot2d_ViewWindow* wnd2D = dynamic_cast<Plot2d_ViewWindow*>( wnd );
2355       if ( wnd2D ) {
2356         qApp->postEvent( wnd2D->getViewFrame(), new QPaintEvent( QRect( 0, 0, wnd2D->getViewFrame()->width(), wnd2D->getViewFrame()->height() ) ) );
2357         qApp->postEvent( wnd2D, new QPaintEvent( QRect( 0, 0, wnd2D->width(), wnd2D->height() ) ) );
2358         qApp->processEvents();
2359         if ( fmt == "PS" || fmt == "EPS" || fmt == "PDF" ) {
2360           myResult = wnd2D->getViewFrame()->print( myFileName, fmt );
2361           return;
2362         }
2363       }
2364 #endif // DISABLE_PLOT2DVIEWER
2365       QImage im = wnd->dumpView();
2366       if ( !im.isNull() && !myFileName.isEmpty() ) {
2367         if ( fmt.isEmpty() ) fmt = QString( "BMP" ); // default format
2368         if ( fmt == "JPG" )  fmt = "JPEG";
2369         myResult = im.save( myFileName, fmt.toLatin1() );
2370       }
2371     }
2372   }
2373 };
2374 bool SalomePyQt::dumpView( const QString& filename, const int id )
2375 {
2376   return ProcessEvent( new TDumpViewEvent( filename, id ) );
2377 }
2378
2379 /*!
2380   \fn QList<int> SalomePyQt::getViews();
2381   \brief Get list of integer identifiers of all the currently opened views
2382   \return list of integer identifiers of all the currently opened views
2383 */
2384
2385 class TGetViews: public SALOME_Event
2386 {
2387 public:
2388   typedef QList<int> TResult;
2389   TResult myResult;
2390   TGetViews() {}
2391   virtual void Execute() 
2392   {
2393     myResult.clear();
2394     LightApp_Application* app  = getApplication();
2395     if ( app ) {
2396       STD_TabDesktop* tabDesk = dynamic_cast<STD_TabDesktop*>( app->desktop() );
2397       if ( tabDesk ) {
2398         QList<SUIT_ViewWindow*> wndlist = tabDesk->windows();
2399         SUIT_ViewWindow* wnd;
2400         foreach ( wnd, wndlist )
2401           myResult.append( wnd->getId() );
2402       }
2403     }
2404   }
2405 };
2406 QList<int> SalomePyQt::getViews()
2407 {
2408   return ProcessEvent( new TGetViews() );
2409 }
2410
2411 /*!
2412   \fn int SalomePyQt::getActiveView();
2413   \brief Get integer identifier of the currently active view
2414   \return integer identifier of the currently active view
2415 */
2416
2417 class TGetActiveView: public SALOME_Event
2418 {
2419 public:
2420   typedef int TResult;
2421   TResult myResult;
2422   TGetActiveView()
2423     : myResult( -1 ) {}
2424   virtual void Execute() 
2425   {
2426     LightApp_Application* app = getApplication();
2427     if ( app ) {
2428       SUIT_ViewManager* viewMgr = app->activeViewManager();
2429       if ( viewMgr ) {
2430         SUIT_ViewWindow* wnd = viewMgr->getActiveView();
2431         if ( wnd )
2432           myResult = wnd->getId();
2433       }
2434     }
2435   }
2436 };
2437 int SalomePyQt::getActiveView()
2438 {
2439   return ProcessEvent( new TGetActiveView() );
2440 }
2441
2442 /*!                      
2443   \fn QString SalomePyQt::getViewType( const int id );
2444   \brief Get type of the specified view, e.g. "OCCViewer"
2445   \param id window identifier
2446   \return view type
2447 */ 
2448
2449 class TGetViewType: public SALOME_Event
2450 {
2451 public:
2452   typedef QString TResult;
2453   TResult myResult;
2454   int myWndId;
2455   TGetViewType( const int id )
2456     : myWndId( id ) {}
2457   virtual void Execute() 
2458   {
2459     SUIT_ViewWindow* wnd = getWnd( myWndId );
2460     if ( wnd ) {
2461       SUIT_ViewManager* viewMgr = wnd->getViewManager();
2462       if ( viewMgr )
2463         myResult = viewMgr->getType();
2464     }
2465   }
2466 };
2467 QString SalomePyQt::getViewType( const int id )
2468 {
2469   return ProcessEvent( new TGetViewType( id ) );
2470 }
2471
2472 /*!
2473   \fn bool SalomePyQt::setViewTitle( const int id, const QString& title );
2474   \brief Change view caption  
2475   \param id window identifier
2476   \param title new window title
2477   \return \c true if operation is completed successfully and \c false otherwise 
2478 */
2479
2480 class TSetViewTitle: public SALOME_Event
2481 {
2482 public:
2483   typedef bool TResult;
2484   TResult myResult;
2485   int myWndId;
2486   QString myTitle;
2487   TSetViewTitle( const int id, const QString& title )
2488     : myResult( false ),
2489       myWndId( id ),
2490       myTitle( title ) {}
2491   virtual void Execute() 
2492   {
2493     SUIT_ViewWindow* wnd = getWnd( myWndId );
2494     if ( wnd ) {
2495       wnd->setWindowTitle( myTitle );
2496       myResult = true;
2497     }
2498   }
2499 };
2500 bool SalomePyQt::setViewTitle( const int id, const QString& title )
2501 {
2502   return ProcessEvent( new TSetViewTitle( id, title ) );
2503 }
2504
2505 /*!
2506   \fn bool SalomePyQt::setViewSize( const int w, const int h, const int id );
2507   \brief Set view size
2508   \param w window width
2509   \param h window height
2510   \param id window identifier
2511   \return \c true if operation is completed successfully and \c false otherwise 
2512 */
2513
2514 class TSetViewSize: public SALOME_Event
2515 {
2516 public:
2517   typedef bool TResult;
2518   TResult myResult;
2519   int myWndWidth;
2520   int myWndHeight;
2521   int myWndId;
2522   TSetViewSize( const int w, const int h, const int id )
2523     : myResult( false ),
2524       myWndWidth( w ),
2525       myWndHeight( h ),
2526       myWndId( id ) {}
2527   virtual void Execute() 
2528   {
2529     SUIT_ViewWindow* wnd = 0;
2530     if ( !myWndId ) {
2531       if ( LightApp_Application* anApp = getApplication() ) {
2532         SUIT_ViewManager* vm = anApp->activeViewManager();
2533         if ( vm )
2534           wnd = vm->getActiveView();
2535       }
2536     }
2537     else {
2538       wnd = dynamic_cast<SUIT_ViewWindow*>( getWnd( myWndId ) );
2539     }
2540     if ( wnd ) {
2541       SUIT_ViewManager* viewMgr = wnd->getViewManager();
2542       if ( viewMgr ) {
2543         QString type = viewMgr->getType();
2544         if ( type == "OCCViewer") {
2545 #ifndef DISABLE_OCCVIEWER
2546           // specific processing for OCC viewer:
2547           // OCC view can embed up to 4 sub-views, split according to the specified layout;
2548           // - if there is only one sub-view active; it will be resized;
2549           // - if there are several sub-views, each of them will be resized.
2550           OCCViewer_ViewWindow* occView = qobject_cast<OCCViewer_ViewWindow*>( wnd );
2551           for ( int i = OCCViewer_ViewFrame::BOTTOM_RIGHT; i <= OCCViewer_ViewFrame::TOP_RIGHT; i++ ) {
2552             if ( occView && occView->getView( i ) ) {
2553               occView->getView( i )->centralWidget()->resize( myWndWidth, myWndHeight );
2554               myResult = true;
2555             }
2556           }
2557 #endif // DISABLE_OCCVIEWER
2558         }
2559         else if ( type == "ParaView") {
2560 #ifndef DISABLE_PVVIEWER
2561           // specific processing for ParaView viewer:
2562           // hierarchy of ParaView viewer is much complex than for usual view;
2563           // we look for sub-widget named "Viewport"
2564           QList<QWidget*> lst = wnd->findChildren<QWidget*>( "Viewport" );
2565           if ( !lst.isEmpty() ) {
2566             lst[0]->resize( myWndWidth, myWndHeight );
2567             myResult = true;
2568           }
2569 #endif // DISABLE_PVVIEWER
2570         }
2571         else {
2572           if ( wnd->centralWidget() ) {
2573             wnd->centralWidget()->resize( myWndWidth, myWndHeight );
2574             myResult = true;
2575           }
2576         }
2577       }
2578     }
2579   }
2580 };
2581 bool SalomePyQt::setViewSize( const int w, const int h, const int id )
2582 {
2583   return ProcessEvent( new TSetViewSize( w, h, id ) );
2584 }
2585
2586 /*!
2587   \fn QString SalomePyQt::getViewTitle( const int id );
2588   \brief Get view caption  
2589   \param id window identifier
2590   \return view caption  
2591 */
2592
2593 class TGetViewTitle: public SALOME_Event
2594 {
2595 public:
2596   typedef QString TResult;
2597   TResult myResult;
2598   int myWndId;
2599   TGetViewTitle( const int id )
2600     : myWndId( id ) {}
2601   virtual void Execute() 
2602   {
2603     SUIT_ViewWindow* wnd = getWnd( myWndId );
2604     if ( wnd )
2605       myResult = wnd->windowTitle();
2606   }
2607 };
2608 QString SalomePyQt::getViewTitle( const int id )
2609 {
2610   return ProcessEvent( new TGetViewTitle( id ) );
2611 }
2612
2613 /*!
2614   \fn QList<int> SalomePyQt::findViews( const QString& type );
2615   \brief Get list of integer identifiers of all the 
2616          currently opened views of the specified type
2617   \param type viewer type
2618   \return list of integer identifiers 
2619 */
2620
2621 class TFindViews: public SALOME_Event
2622 {
2623 public:
2624   typedef QList<int> TResult;
2625   TResult myResult;
2626   QString myType;
2627   TFindViews( const QString& type )
2628     : myType( type ) {}
2629   virtual void Execute() 
2630   {
2631     myResult.clear();
2632     LightApp_Application* app  = getApplication();
2633     if ( app ) {
2634       ViewManagerList vmList;
2635       app->viewManagers( myType, vmList );
2636       SUIT_ViewManager* viewMgr;
2637       foreach ( viewMgr, vmList ) {
2638         QVector<SUIT_ViewWindow*> vec = viewMgr->getViews();
2639         for ( int i = 0, n = vec.size(); i < n; i++ ) {
2640           SUIT_ViewWindow* wnd = vec[ i ];
2641           if ( wnd )
2642             myResult.append( wnd->getId() );
2643         }
2644       }
2645     }
2646   }
2647 };
2648 QList<int> SalomePyQt::findViews( const QString& type )
2649 {
2650   return ProcessEvent( new TFindViews( type ) );
2651 }
2652
2653 /*!
2654   \fn bool SalomePyQt::activateView( const int id );
2655   \brief Activate view
2656   \param id window identifier
2657   \return \c true if operation is completed successfully and \c false otherwise 
2658 */
2659
2660 class TActivateView: public SALOME_Event
2661 {
2662 public:
2663   typedef bool TResult;
2664   TResult myResult;
2665   int myWndId;
2666   TActivateView( const int id )
2667     : myResult( false ),
2668       myWndId( id ) {}
2669   virtual void Execute() 
2670   {
2671     SUIT_ViewWindow* wnd = getWnd( myWndId );
2672     if ( wnd ) {
2673       wnd->setFocus();
2674       myResult = true;
2675     }
2676   }
2677 };
2678 bool SalomePyQt::activateView( const int id )
2679 {
2680   return ProcessEvent( new TActivateView( id ) );
2681 }
2682
2683 /*!
2684   \fn int SalomePyQt::createView( const QString& type, bool visible = true, const int width = 0, const int height = 0 );
2685   \brief Create new view and activate it
2686   \param type viewer type
2687   \param visible
2688   \param width
2689   \param height
2690   \return integer identifier of created view (or -1 if view could not be created)
2691 */
2692
2693 class TCreateView: public SALOME_Event
2694 {
2695 public:
2696   typedef int TResult;
2697   TResult myResult;
2698   QString myType;
2699   bool myVisible;
2700   int myWidth;
2701   int myHeight;
2702   TCreateView( const QString& theType, bool visible, const int width, const int height )
2703     : myResult( -1 ),
2704       myType( theType ),
2705       myVisible(visible),
2706       myWidth(width),
2707       myHeight(height) {}
2708   virtual void Execute() 
2709   {
2710     LightApp_Application* app  = getApplication();
2711     if ( app ) {
2712       SUIT_ViewManager* viewMgr = app->createViewManager( myType );
2713       if ( viewMgr ) {
2714         QWidget* wnd = viewMgr->getActiveView();
2715         myResult = viewMgr->getActiveView()->getId();
2716         if ( wnd ) {
2717           if ( !myVisible )
2718             wnd->setVisible(false);
2719           if ( !myVisible && myWidth == 0 && myHeight == 0 ) {
2720             myWidth = 1024;
2721             myHeight = 768;
2722           }
2723           if (myWidth > 0 && myHeight > 0) {
2724 #ifndef DISABLE_PLOT2DVIEWER
2725             Plot2d_ViewWindow* wnd2D = dynamic_cast<Plot2d_ViewWindow*>( wnd );
2726             if ( wnd2D ) wnd = wnd2D->getViewFrame();
2727 #endif // DISABLE_PLOT2DVIEWER
2728             wnd->setGeometry( 0, 0, myWidth, myHeight );
2729           }
2730         }
2731       }
2732     }
2733   }
2734 };
2735 int SalomePyQt::createView( const QString& type, bool visible, const int width, const int height )
2736 {
2737   int ret = ProcessEvent( new TCreateView( type, visible, width, height ) );
2738   QCoreApplication::processEvents();
2739   return ret;
2740 }
2741
2742 /*!
2743   \fn int SalomePyQt::createView( const QString& type, QWidget* w );
2744   \brief Create new view with custom widget embedded and activate it
2745   \param type viewer type
2746   \param w custom widget
2747   \return integer identifier of created view (or -1 if view could not be created)
2748 */
2749
2750 class TCreateViewWg: public SALOME_Event
2751 {
2752 public:
2753   typedef int TResult;
2754   TResult myResult;
2755   QString myType;
2756   QWidget* myWidget;
2757   TCreateViewWg( const QString& theType, QWidget* w )
2758     : myResult( -1 ),
2759       myType( theType ),
2760       myWidget( w ) {}
2761   virtual void Execute() 
2762   {
2763     LightApp_Application* app  = getApplication();
2764     if ( app ) {
2765       SUIT_ViewManager* viewMgr = app->createViewManager( myType, myWidget );
2766       if ( viewMgr ) {
2767         SUIT_ViewWindow* wnd = viewMgr->getActiveView();
2768         if ( wnd )
2769           myResult = wnd->getId();
2770       }
2771     }
2772   }
2773 };
2774 int SalomePyQt::createView( const QString& type, QWidget* w )
2775 {
2776   int ret = ProcessEvent( new TCreateViewWg( type, w ) );
2777   QCoreApplication::processEvents();
2778   return ret;
2779 }
2780
2781 /*!
2782   \fn bool SalomePyQt::closeView( const int id );
2783   \brief Close view
2784   \param id window identifier
2785   \return \c true if operation is completed successfully and \c false otherwise 
2786 */
2787
2788 class TCloseView: public SALOME_Event
2789 {
2790 public:
2791   typedef bool TResult;
2792   TResult myResult;
2793   int myWndId;
2794   TCloseView( const int id )
2795     : myResult( false ),
2796       myWndId( id ) {}
2797   virtual void Execute() 
2798   {
2799     SUIT_ViewWindow* wnd = getWnd( myWndId );
2800     if ( wnd ) {
2801       SUIT_ViewManager* viewMgr = wnd->getViewManager();
2802       if ( viewMgr ) {
2803         wnd->close();
2804         myResult = true;
2805       }
2806     }
2807   }
2808 };
2809 bool SalomePyQt::closeView( const int id )
2810 {
2811   return ProcessEvent( new TCloseView( id ) );
2812 }
2813
2814 /*!
2815   \fn int SalomePyQt::cloneView( const int id );
2816   \brief Clone view (if this operation is supported for specified view type)
2817   \param id window identifier
2818   \return integer identifier of the cloned view or -1 or operation could not be performed
2819 */
2820
2821 class TCloneView: public SALOME_Event
2822 {
2823 public:
2824   typedef int TResult;
2825   TResult myResult;
2826   int myWndId;
2827   TCloneView( const int id )
2828     : myResult( -1 ),
2829       myWndId( id ) {}
2830   virtual void Execute() 
2831   {
2832     SUIT_ViewWindow* wnd = getWnd( myWndId );
2833     if ( wnd ) {
2834       SUIT_ViewManager* viewMgr = wnd->getViewManager();
2835       if ( viewMgr ) {
2836 #ifndef DISABLE_OCCVIEWER
2837         if ( wnd->inherits( "OCCViewer_ViewWindow" ) ) {
2838           OCCViewer_ViewWindow* occView = (OCCViewer_ViewWindow*)( wnd );
2839           occView->onCloneView();
2840           wnd = viewMgr->getActiveView();
2841           if ( wnd )
2842             myResult = wnd->getId();
2843         }
2844 #endif // DISABLE_OCCVIEWER
2845 #ifndef DISABLE_PLOT2DVIEWER
2846         if ( wnd->inherits( "Plot2d_ViewWindow" ) ) {
2847           Plot2d_ViewManager* viewMgr2d = dynamic_cast<Plot2d_ViewManager*>( viewMgr );
2848           Plot2d_ViewWindow* srcWnd2d = dynamic_cast<Plot2d_ViewWindow*>( wnd );
2849           if ( viewMgr2d && srcWnd2d ) {
2850             Plot2d_ViewWindow* resWnd = viewMgr2d->cloneView( srcWnd2d );
2851             myResult = resWnd->getId();
2852           }
2853         }
2854 #endif // DISABLE_OCCVIEWER
2855       }
2856     }
2857   }
2858 };
2859 int SalomePyQt::cloneView( const int id )
2860 {
2861   return ProcessEvent( new TCloneView( id ) );
2862 }
2863
2864 /*!
2865   \fn bool SalomePyQt::setViewVisible( const int id, const bool visible )
2866   \brief Set view visibility.
2867   \param id window identifier
2868   \param visible new visiblity
2869 */
2870
2871 void SalomePyQt::setViewVisible( const int id, const bool visible )
2872 {
2873   class TEvent: public SALOME_Event
2874   {
2875     int myWndId;
2876     bool myVisible;
2877   public:
2878     TEvent( const int id, const bool visible )
2879       : myWndId( id ), myVisible( visible ) {}
2880     virtual void Execute()
2881     {
2882       SUIT_ViewWindow* wnd = getWnd( myWndId );
2883       if ( wnd ) wnd->setVisible( myVisible );
2884     }
2885   };
2886   ProcessVoidEvent( new TEvent( id, visible ) );
2887 }
2888
2889 /*!
2890   \fn bool SalomePyQt::isViewVisible( const int id );
2891   \brief Check whether view is visible ( i.e. it is on the top of the views stack)
2892   \param id window identifier
2893   \return \c true if view is visible and \c false otherwise 
2894 */
2895
2896 class TIsViewVisible: public SALOME_Event
2897 {
2898 public:
2899   typedef bool TResult;
2900   TResult myResult;
2901   int myWndId;
2902   TIsViewVisible( const int id )
2903     : myResult( false ),
2904       myWndId( id ) {}
2905   virtual void Execute() 
2906   {
2907     SUIT_ViewWindow* wnd = getWnd( myWndId );
2908     if ( wnd )
2909     {
2910       QWidget* p = wnd->parentWidget();
2911       myResult = ( p && p->isVisibleTo( p->parentWidget() ) );
2912     }
2913   }
2914 };
2915 bool SalomePyQt::isViewVisible( const int id )
2916 {
2917   return ProcessEvent( new TIsViewVisible( id ) );
2918 }
2919   
2920 /*!
2921   \fn bool SalomePyQt::setViewClosable( const int id, const bool on );
2922   \brief Set / clear view's "closable" option. By default any view is closable
2923         (i.e. can be closed by the user).
2924   \param id window identifier
2925   \param on new "closable" option's value
2926 */
2927
2928 void SalomePyQt::setViewClosable( const int id, const bool on )
2929 {
2930   class TEvent: public SALOME_Event
2931   {
2932     int myWndId;
2933     bool myOn;
2934   public:
2935     TEvent( const int id, const bool on )
2936       : myWndId( id ), myOn( on ) {}
2937     virtual void Execute()
2938     {
2939       SUIT_ViewWindow* wnd = getWnd( myWndId );
2940       if ( wnd ) wnd->setClosable( myOn );
2941     }
2942   };
2943   ProcessVoidEvent( new TEvent( id, on ) );
2944 }
2945
2946 /*!
2947   \fn bool SalomePyQt::isViewClosable( const int id );
2948   \brief Check whether view is closable (i.e. can be closed by the user)
2949   \param id window identifier
2950   \return \c true if view is closable or \c false otherwise 
2951 */
2952
2953 class TIsViewClosable: public SALOME_Event
2954 {
2955 public:
2956   typedef bool TResult;
2957   TResult myResult;
2958   int myWndId;
2959   TIsViewClosable( const int id )
2960     : myResult( true ),
2961       myWndId( id ) {}
2962   virtual void Execute() 
2963   {
2964     SUIT_ViewWindow* wnd = getWnd( myWndId );
2965     if ( wnd )
2966       myResult = wnd->closable();
2967   }
2968 };
2969
2970 bool SalomePyQt::isViewClosable( const int id )
2971 {
2972   return ProcessEvent( new TIsViewClosable( id ) );
2973 }
2974
2975 /*!
2976   \fn bool SalomePyQt::groupAllViews();
2977   \brief Group all views to the single tab area
2978   \return \c true if operation is completed successfully and \c false otherwise 
2979 */
2980
2981 class TGroupAllViews: public SALOME_Event
2982 {
2983 public:
2984   typedef bool TResult;
2985   TResult myResult;
2986   TGroupAllViews()
2987     : myResult( false ) {}
2988   virtual void Execute() 
2989   {
2990     LightApp_Application* app  = getApplication();
2991     if ( app ) {
2992       STD_TabDesktop* tabDesk = dynamic_cast<STD_TabDesktop*>( app->desktop() );
2993       if ( tabDesk ) {
2994         QtxWorkstack* wStack = tabDesk->workstack();
2995         if ( wStack ) {
2996           wStack->stack();
2997           myResult = true;
2998         }
2999       }
3000     }
3001   }
3002 };
3003 bool SalomePyQt::groupAllViews()
3004 {
3005   return ProcessEvent( new TGroupAllViews() );
3006 }
3007
3008 /*!
3009   \fn bool SalomePyQt::splitView( const int id, const Orientation ori, const Action action );
3010   \brief Split tab area to which view with identifier belongs to
3011   \param id window identifier
3012   \param ori orientation of split operation
3013   \param action action to be performed
3014   \return \c true if operation is completed successfully \c false otherwise 
3015 */
3016
3017 class TSplitView: public SALOME_Event
3018 {
3019 public:
3020   typedef bool TResult;
3021   TResult myResult;
3022   int myWndId;
3023   Orientation myOri;
3024   Action myAction;
3025   TSplitView( const int id, 
3026               const Orientation ori, 
3027               const Action action )
3028     : myResult( false ),
3029       myWndId( id ),
3030       myOri( ori ),
3031       myAction( action ) {}
3032   virtual void Execute() 
3033   {
3034     SUIT_ViewWindow* wnd = getWnd( myWndId );
3035     if ( wnd ) {
3036       // activate view
3037       // wnd->setFocus(); ???
3038
3039       // split workstack
3040       if ( getApplication() ) {
3041         STD_TabDesktop* desk = 
3042           dynamic_cast<STD_TabDesktop*>( getApplication()->desktop() );
3043         if ( desk ) {
3044           QtxWorkstack* wStack = desk->workstack();
3045           if ( wStack ) {
3046             Qt::Orientation qtOri = 
3047               ( myOri == Horizontal ) ? Qt::Horizontal : Qt::Vertical;
3048
3049             QtxWorkstack::SplitType sType;
3050             if ( myAction == MoveWidget )
3051               sType = QtxWorkstack::SplitMove;
3052             else if ( myAction == LeaveWidget )
3053               sType = QtxWorkstack::SplitStay;
3054             else 
3055               sType = QtxWorkstack::SplitAt;
3056
3057             wStack->Split( wnd, qtOri, sType );
3058             myResult = true;
3059           }
3060         }
3061       }
3062     }
3063   }
3064 };
3065 bool SalomePyQt::splitView( const int id, const Orientation ori, const Action action )
3066 {
3067   return ProcessEvent( new TSplitView( id, ori, action ) );
3068 }
3069
3070 /*!
3071   \fn bool SalomePyQt::moveView( const int id, const int id_to, const bool before );
3072   \brief Move view with the first identifier to the same area which 
3073          another view with the second identifier belongs to
3074   \param id source window identifier
3075   \param id_to destination window identifier  
3076   param before specifies whether the first viewt has to be moved before or after 
3077         the second view
3078   \return \c true if operation is completed successfully and \c false otherwise 
3079 */
3080
3081 class TMoveView: public SALOME_Event
3082 {
3083 public:
3084   typedef bool TResult;
3085   TResult myResult;
3086   int myWndId;
3087   int myWndToId;
3088   bool myIsBefore;
3089   TMoveView( const int id, const int id_to, const bool before )
3090     : myResult( false ),
3091     myWndId( id ),
3092     myWndToId( id_to ),
3093     myIsBefore( before ) {}
3094   virtual void Execute() 
3095   {
3096     SUIT_ViewWindow* wnd = getWnd( myWndId );
3097     SUIT_ViewWindow* wnd_to = getWnd( myWndToId );
3098     if ( wnd && wnd_to ) {
3099       QtxWorkstack* wStack = dynamic_cast<STD_TabDesktop*>( 
3100         getApplication()->desktop() )->workstack();
3101       if ( wStack )
3102         myResult = wStack->move( wnd, wnd_to, myIsBefore );
3103     }
3104   }
3105 };
3106 bool SalomePyQt::moveView( const int id, const int id_to, const bool before )
3107 {
3108   return ProcessEvent( new TMoveView( id, id_to, before ) );
3109 }
3110
3111 /*!
3112   \fn QList<int> SalomePyQt::neighbourViews( const int id );
3113   \brief Get list of views identifiers that belongs to the same area as 
3114          specified view (excluding it)
3115   \param id window identifier
3116   \return list of views identifiers
3117 */
3118
3119 class TNeighbourViews: public SALOME_Event
3120 {
3121 public:
3122   typedef QList<int> TResult;
3123   TResult myResult;
3124   int myWndId;
3125   TNeighbourViews( const int id )
3126     : myWndId( id ) {}
3127   virtual void Execute() 
3128   {
3129     myResult.clear();
3130     SUIT_ViewWindow* wnd = getWnd( myWndId );
3131     if ( wnd ) {
3132       QtxWorkstack* wStack = dynamic_cast<STD_TabDesktop*>( 
3133         getApplication()->desktop() )->workstack();
3134       if ( wStack ) {
3135         QWidgetList wgList = wStack->windowList( wnd );
3136         QWidget* wg;
3137         foreach ( wg, wgList ) {
3138           SUIT_ViewWindow* tmpWnd = dynamic_cast<SUIT_ViewWindow*>( wg );
3139           if ( tmpWnd && tmpWnd != wnd )
3140             myResult.append( tmpWnd->getId() );
3141         }
3142       }
3143     }
3144   }
3145 };
3146 QList<int> SalomePyQt::neighbourViews( const int id )
3147 {
3148   return ProcessEvent( new TNeighbourViews( id ) );
3149 }
3150
3151
3152 /*!
3153   \fn QString SalomePyQt::createObject( const QString& parent );
3154   \brief Create empty data object
3155   \param parent entry of parent data object
3156   \return entry of created data object
3157 */
3158
3159 class TCreateEmptyObjectEvent: public SALOME_Event
3160 {
3161 public:
3162   typedef QString TResult;
3163   TResult  myResult;
3164   QString  myParent;
3165   TCreateEmptyObjectEvent( const QString& parent )
3166     : myParent( parent ) {}
3167   virtual void Execute() 
3168   {
3169     SALOME_PYQT_ModuleLight* module = dynamic_cast<SALOME_PYQT_ModuleLight*>( getActiveModule() );
3170     if ( module ) {
3171        myResult = module->createObject( myParent );
3172     }
3173     else {
3174       if ( verbose() ) printf( "SalomePyQt.createObject() function is not supported for the current module.\n" );
3175     }
3176   }
3177 };
3178 QString SalomePyQt::createObject( const QString& parent )
3179 {
3180   return ProcessEvent( new TCreateEmptyObjectEvent( parent ) );
3181 }
3182
3183 /*!
3184   \fn QString SalomePyQt::createObject( const QString& name, const QString& icon,
3185                                         const QString& tooltip,const QString& parent );
3186   \brief Create new data object with specified name, icon and tooltip
3187   \param name data object name
3188   \param icon data object icon
3189   \param toolTip data object tooltip
3190   \param parent entry of parent data object
3191   \return entry of created data object
3192 */
3193
3194 class TCreateObjectEvent: public SALOME_Event 
3195 {
3196 public:
3197   typedef QString TResult;
3198   TResult myResult;
3199   QString myParent;
3200   QString myName;
3201   QString myIcon;
3202   QString myToolTip;
3203   TCreateObjectEvent( const QString& name,
3204                       const QString& icon,
3205                       const QString& tooltip,
3206                       const QString& parent )
3207     : myName( name ),
3208       myIcon( icon ),
3209       myToolTip( tooltip ),
3210       myParent( parent ) {}
3211   virtual void Execute()
3212   {
3213     SALOME_PYQT_ModuleLight* module = dynamic_cast<SALOME_PYQT_ModuleLight*>( getActiveModule() );
3214     if ( module ) {
3215       myResult = module->createObject( myName, myIcon, myToolTip, myParent );
3216     }
3217     else {
3218       if ( verbose() ) printf( "SalomePyQt.createObject() function is not supported for the current module.\n" );
3219     }
3220   }
3221 };
3222 QString SalomePyQt::createObject( const QString& name,
3223                                   const QString& icon,
3224                                   const QString& toolTip,
3225                                   const QString& parent )
3226 {
3227   return ProcessEvent( new TCreateObjectEvent( name, icon, toolTip, parent ) );
3228 }
3229
3230
3231 /*!
3232   \fn void SalomePyQt::setName( const QString& entry, const QString& name );
3233   \brief Set data object name
3234   \param entry data object entry
3235   \param name data object name
3236 */
3237 class TSetNameEvent: public SALOME_Event
3238 {
3239 public:
3240   QString myEntry;
3241   QString myName;
3242   TSetNameEvent( const QString& entry,
3243                  const QString& name )
3244   : myEntry( entry ),
3245     myName( name ) {}
3246   virtual void Execute()
3247   {
3248     SALOME_PYQT_ModuleLight* module = dynamic_cast<SALOME_PYQT_ModuleLight*>( getActiveModule() );
3249     if ( module ) {
3250       module->setName( myEntry, myName );
3251     }
3252     else {
3253       if ( verbose() ) printf( "SalomePyQt.setName() function is not supported for the current module.\n" );
3254     }
3255   }
3256 };
3257 void SalomePyQt::setName( const QString& entry, const QString& name )
3258 {
3259   ProcessVoidEvent( new TSetNameEvent( entry, name ) );
3260 }
3261
3262 /*!
3263   \fn void SalomePyQt::setIcon( const QString& entry, const QString& icon );
3264   \brief Set data object icon
3265   \param entry data object entry
3266   \param icon data object icon file name (icon is loaded from module resources)
3267 */
3268
3269 class TSetIconEvent: public SALOME_Event
3270 {
3271 public:
3272   QString myEntry;
3273   QString myIcon;
3274   TSetIconEvent( const QString& entry,
3275                  const QString& icon )
3276   : myEntry( entry ),
3277     myIcon( icon ) {}
3278   virtual void Execute()
3279   {
3280     SALOME_PYQT_ModuleLight* module = dynamic_cast<SALOME_PYQT_ModuleLight*>( getActiveModule() );
3281     if ( module ) {
3282       module->setIcon( myEntry, myIcon );
3283     }
3284     else {
3285       if ( verbose() ) printf( "SalomePyQt.setIcon() function is not supported for the current module.\n" );
3286     }
3287   }
3288 };
3289
3290 void SalomePyQt::setIcon( const QString& entry, const QString& icon )
3291 {
3292   ProcessVoidEvent( new TSetIconEvent( entry, icon ) );
3293 }
3294
3295 /*!
3296   \fn void SalomePyQt::setToolTip( const QString& entry, const QString& toolTip );
3297   \brief Set data object tooltip
3298   \param entry data object entry
3299   \param toolTip data object tooltip
3300 */
3301
3302 class TSetToolTipEvent: public SALOME_Event
3303 {
3304 public:
3305   QString myEntry;
3306   QString myToolTip;
3307   TSetToolTipEvent( const QString& entry,
3308                     const QString& toolTip )
3309     : myEntry( entry ),
3310       myToolTip( toolTip ) {}
3311   virtual void Execute()
3312   {
3313     SALOME_PYQT_ModuleLight* module = dynamic_cast<SALOME_PYQT_ModuleLight*>( getActiveModule() );
3314     if ( module ) {
3315       module->setToolTip( myEntry, myToolTip );
3316     }
3317     else {
3318       if ( verbose() ) printf( "SalomePyQt.setToolTip() function is not supported for the current module.\n" );
3319     }
3320   }
3321 };
3322 void SalomePyQt::setToolTip( const QString& entry, const QString& toolTip )
3323 {
3324   ProcessVoidEvent( new TSetToolTipEvent( entry, toolTip ) );
3325 }
3326
3327 /*!
3328   \fn void SalomePyQt::setReference( const QString& entry, const QString& refEntry );
3329   \brief Set reference to another data object
3330   \param entry data object entry
3331   \param refEntry referenced data object entry
3332 */
3333
3334 class TSetRefEvent: public SALOME_Event
3335 {
3336 public:
3337   QString myEntry;
3338   QString myRefEntry;
3339   TSetRefEvent( const QString& entry,
3340                 const QString& refEntry )
3341     : myEntry( entry ),
3342       myRefEntry( refEntry ) {}
3343   virtual void Execute()
3344   {
3345     SALOME_PYQT_ModuleLight* module = dynamic_cast<SALOME_PYQT_ModuleLight*>( getActiveModule() );
3346     if ( module ) {
3347       module->setReference( myEntry, myRefEntry );
3348     }
3349     else {
3350       if ( verbose() ) printf( "SalomePyQt.setReference() function is not supported for the current module.\n" );
3351     }
3352   }
3353 };
3354 void SalomePyQt::setReference( const QString& entry, const QString& refEntry )
3355 {
3356   ProcessVoidEvent( new TSetRefEvent( entry, refEntry ) );
3357 }
3358
3359 /*!
3360   \fn void SalomePyQt::setColor( const QString& entry, const QColor& color );
3361   \brief Set data object color
3362   \param entry data object entry
3363   \param color data object color
3364  */
3365
3366 class TSetColorEvent: public SALOME_Event
3367 {
3368 public:
3369   QString myEntry;
3370   QColor  myColor;
3371   TSetColorEvent( const QString& entry,
3372                   const QColor& color )
3373     : myEntry( entry ),
3374       myColor( color ) {}
3375   virtual void Execute()
3376   {
3377     SALOME_PYQT_ModuleLight* module = dynamic_cast<SALOME_PYQT_ModuleLight*>( getActiveModule() );
3378     if ( module ) {
3379       module->setColor( myEntry, myColor );
3380     }
3381     else {
3382       if ( verbose() ) printf( "SalomePyQt.setColor() function is not supported for the current module.\n" );
3383     }
3384   }
3385 };
3386 void SalomePyQt::setColor( const QString& entry, const QColor& color )
3387 {
3388   ProcessVoidEvent( new TSetColorEvent( entry, color ) );
3389 }
3390
3391 /*!
3392   \fn QString SalomePyQt::getName( const QString& entry );
3393   \brief Get data object name
3394   \param entry data object entry
3395   \return data object name
3396 */
3397
3398 class TGetNameEvent: public SALOME_Event
3399 {
3400 public:
3401   typedef QString TResult;
3402   TResult myResult;
3403   QString myEntry;
3404   TGetNameEvent( const QString& entry )
3405     : myEntry( entry ) {}
3406   virtual void Execute()
3407   {
3408     SALOME_PYQT_ModuleLight* module = dynamic_cast<SALOME_PYQT_ModuleLight*>( getActiveModule() );
3409     if ( module ) {
3410       myResult = module->getName( myEntry );
3411     }
3412     else {
3413       if ( verbose() ) printf( "SalomePyQt.getName() function is not supported for the current module.\n" );
3414     }
3415   }
3416 };
3417 QString SalomePyQt::getName( const QString& entry )
3418 {
3419   return ProcessEvent( new TGetNameEvent( entry ) );
3420 }
3421
3422 /*!
3423   \fn QString SalomePyQt::getToolTip( const QString& entry );
3424   \brief Get data object tooltip
3425   \param entry data object entry
3426   \return data object tooltip
3427 */
3428
3429 class TGetToolTipEvent: public SALOME_Event
3430 {
3431 public:
3432   typedef QString TResult;
3433   TResult myResult;
3434   QString myEntry;
3435   TGetToolTipEvent( const QString& entry )
3436   : myEntry( entry ) {}
3437   virtual void Execute()
3438   {
3439     SALOME_PYQT_ModuleLight* module = dynamic_cast<SALOME_PYQT_ModuleLight*>( getActiveModule() );
3440     if ( module ) {
3441       myResult = module->getToolTip( myEntry );
3442     }
3443     else {
3444       if ( verbose() ) printf( "SalomePyQt.getToolTip() function is not supported for the current module.\n" );
3445     }
3446   }
3447 };
3448 QString SalomePyQt::getToolTip( const QString& entry )
3449 {
3450   return ProcessEvent( new TGetToolTipEvent( entry ) );
3451 }
3452
3453 /*
3454   \fn QString SalomePyQt::getReference( const QString& entry );
3455   \brief Get entry of the referenced object (if there's any)
3456   \param entry data object entry
3457   \return referenced data object entry
3458 */
3459
3460 class TGetRefEvent: public SALOME_Event
3461 {
3462 public:
3463   typedef QString TResult;
3464   TResult myResult;
3465   QString myEntry;
3466   TGetRefEvent( const QString& entry )
3467   : myEntry( entry ) {}
3468   virtual void Execute()
3469   {
3470     SALOME_PYQT_ModuleLight* module = dynamic_cast<SALOME_PYQT_ModuleLight*>( getActiveModule() );
3471     if ( module ) {
3472       myResult = module->getReference( myEntry );
3473     }
3474     else {
3475       if ( verbose() ) printf( "SalomePyQt.getReference() function is not supported for the current module.\n" );
3476     }
3477   }
3478 };
3479 QString SalomePyQt::getReference( const QString& entry )
3480 {
3481   return ProcessEvent( new TGetRefEvent( entry ) );
3482 }
3483
3484 /*!
3485   \fn QColor SalomePyQt::getColor( const QString& entry );
3486   \brief Get data object color
3487   \param entry data object entry
3488   \return data object color
3489 */
3490
3491 class TGetColorEvent: public SALOME_Event
3492 {
3493 public:
3494   typedef QColor TResult;
3495   TResult myResult;
3496   QString myEntry;
3497   TGetColorEvent( const QString& entry )
3498   : myEntry( entry ) {}
3499   virtual void Execute()
3500   {
3501     SALOME_PYQT_ModuleLight* module = dynamic_cast<SALOME_PYQT_ModuleLight*>( getActiveModule() );
3502     if ( module ) {
3503       myResult = module->getColor( myEntry );
3504     }
3505     else {
3506       if ( verbose() ) printf( "SalomePyQt.getColor() function is not supported for the current module.\n" );
3507     }
3508   }
3509 };
3510 QColor SalomePyQt::getColor( const QString& entry )
3511 {
3512   return ProcessEvent( new TGetColorEvent( entry ) );
3513 }
3514
3515 /*!
3516   \fn void SalomePyQt::removeChildren( const QString& entry );
3517   \brief Remove all child data objects from specified data object
3518   \param entry data object entry
3519 */
3520
3521 class TRemoveChildEvent: public SALOME_Event
3522 {
3523 public:
3524   QString myEntry;
3525   TRemoveChildEvent( const QString& entry )
3526   : myEntry( entry ) {}
3527   virtual void Execute()
3528   {
3529     SALOME_PYQT_ModuleLight* module = dynamic_cast<SALOME_PYQT_ModuleLight*>( getActiveModule() );
3530     if ( module ) {
3531       module->removeChildren( myEntry );
3532     }
3533     else {
3534       if ( verbose() ) printf( "SalomePyQt.removeChildren() function is not supported for the current module.\n" );
3535     }
3536   }
3537 };
3538 void SalomePyQt::removeChildren( const QString& entry )
3539 {
3540   ProcessVoidEvent( new TRemoveChildEvent( entry ) );
3541 }
3542 void SalomePyQt::removeChild( const QString& entry )
3543 {
3544   if ( verbose() ) printf( "SalomePyQt.removeChild() function is obsolete. Use SalomePyQt.removeChildren() instead." );
3545   removeChildren( entry );
3546 }
3547
3548 /*!
3549   \fn void SalomePyQt::removeObject( const QString& entry );
3550   \brief Remove object by entry
3551   \param entry data object entry
3552 */
3553
3554 class TRemoveObjectEvent: public SALOME_Event
3555 {
3556 public:
3557   QString myEntry;
3558   
3559   TRemoveObjectEvent( const QString& entry )
3560   : myEntry( entry ) {}
3561   virtual void Execute()
3562   {
3563     SALOME_PYQT_ModuleLight* module = dynamic_cast<SALOME_PYQT_ModuleLight*>( getActiveModule() );
3564     if ( module ) {
3565       module->removeObject( myEntry );
3566     }
3567     else {
3568       if ( verbose() ) printf( "SalomePyQt.removeObject() function is not supported for the current module.\n" );
3569     }
3570   }
3571 };
3572 void SalomePyQt::removeObject( const QString& entry )
3573 {
3574   ProcessVoidEvent( new TRemoveObjectEvent( entry ) );
3575 }
3576
3577 /*!
3578   \fn QStringList SalomePyQt::getChildren( const QString& entry, const bool recursive );
3579   \brief Get entries of all child data objects of specified data object
3580   \param entry data object entry
3581   \param recursive \c true for recursive processing
3582 */
3583
3584 class TGetChildrenEvent: public SALOME_Event
3585 {
3586 public:
3587   typedef QStringList TResult;
3588   TResult myResult;
3589   QString myEntry;
3590   bool    myRecursive; 
3591   TGetChildrenEvent( const QString& entry, const bool recursive )
3592     : myEntry( entry ),
3593       myRecursive( recursive ) {}
3594   virtual void Execute()
3595   {
3596     SALOME_PYQT_ModuleLight* module = dynamic_cast<SALOME_PYQT_ModuleLight*>( getActiveModule() );
3597     if ( module ) {
3598       myResult = module->getChildren( myEntry, myRecursive );
3599     }
3600     else {
3601       if ( verbose() ) printf( "SalomePyQt.getChildren() function is not supported for the current module.\n" );
3602     }
3603   }
3604 };
3605 QStringList SalomePyQt::getChildren( const QString& entry, const bool recursive )
3606 {
3607   return ProcessEvent( new TGetChildrenEvent( entry, recursive ) ); 
3608 }
3609
3610 #ifndef DISABLE_PLOT2DVIEWER
3611 // Next set of methods relates to the Plot2d viewer functionality
3612
3613 /*!
3614   \fn void SalomePyQt::displayCurve( const int id, Plot2d_Curve* theCurve )
3615   \brief Display theCurve in view
3616   \param id window identifier
3617   \param theCurve curve to display
3618 */
3619
3620 class TDisplayCurve: public SALOME_Event
3621 {
3622 public:
3623   int myWndId;
3624   Plot2d_Curve* myCurve;
3625   TDisplayCurve( const int id, Plot2d_Curve* theCurve ) : myWndId( id ), myCurve( theCurve ) {}
3626   virtual void Execute() {
3627     Plot2d_ViewWindow* wnd = dynamic_cast<Plot2d_ViewWindow*>( getWnd( myWndId ) );
3628     if ( wnd )
3629       wnd->getViewFrame()->displayCurve( myCurve );
3630   }
3631 };
3632 void SalomePyQt::displayCurve( const int id, Plot2d_Curve* theCurve )
3633 {
3634   ProcessVoidEvent( new TDisplayCurve( id, theCurve ) ); 
3635 }
3636
3637 /*!
3638   \fn void SalomePyQt::eraseCurve( const int id, Plot2d_Curve* theCurve )
3639   \brief Erase theCurve in view
3640   \param id window identifier
3641   \param theCurve curve to erase
3642 */
3643
3644 class TEraseCurve: public SALOME_Event
3645 {
3646 public:
3647   int myWndId;
3648   Plot2d_Curve* myCurve;
3649   TEraseCurve( const int id, Plot2d_Curve* theCurve ) : myWndId( id ), myCurve( theCurve ) {}
3650   virtual void Execute() {
3651     Plot2d_ViewWindow* wnd = dynamic_cast<Plot2d_ViewWindow*>( getWnd( myWndId ) );
3652     wnd->getViewFrame()->eraseCurve( myCurve );
3653   }
3654 };
3655 void SalomePyQt::eraseCurve( const int id, Plot2d_Curve* theCurve )
3656 {
3657   ProcessVoidEvent( new TEraseCurve( id, theCurve ) ); 
3658 }
3659
3660 /*!
3661   \fn void SalomePyQt::deleteCurve( Plot2d_Curve* theCurve )
3662   \brief Delete theCurve from all views
3663   \param theCurve curve to delete
3664 */
3665
3666 class TDeleteCurve: public SALOME_Event
3667 {
3668 public:
3669   Plot2d_Curve* myCurve;
3670   TDeleteCurve( Plot2d_Curve* theCurve ) : myCurve( theCurve ) {}
3671   virtual void Execute() {
3672     LightApp_Application* app  = getApplication();
3673     if ( app ) {
3674       STD_TabDesktop* tabDesk = dynamic_cast<STD_TabDesktop*>( app->desktop() );
3675       if ( tabDesk ) {
3676         QList<SUIT_ViewWindow*> wndlist = tabDesk->windows();
3677         SUIT_ViewWindow* wnd;
3678         foreach ( wnd, wndlist ) {
3679           Plot2d_ViewWindow* aP2d = dynamic_cast<Plot2d_ViewWindow*>( wnd );
3680           if ( aP2d )
3681             aP2d->getViewFrame()->eraseObject( myCurve );
3682         }
3683       }
3684     }
3685   }
3686 };
3687 void SalomePyQt::eraseCurve( Plot2d_Curve* theCurve )
3688 {
3689   ProcessVoidEvent( new TDeleteCurve( theCurve ) );
3690 }
3691
3692 /*!
3693   \brief updateCurves (repaint) curves in view window.
3694 */
3695 void SalomePyQt::updateCurves( const int id )
3696 {
3697   class TEvent: public SALOME_Event
3698   {
3699   public:
3700     int myWndId;
3701     TEvent( const int id ) : myWndId( id ) {}
3702     virtual void Execute()
3703     {
3704       Plot2d_ViewWindow* wnd = dynamic_cast<Plot2d_ViewWindow*>( getWnd( myWndId ) );
3705       if ( wnd )
3706         wnd->getViewFrame()->DisplayAll();
3707     }
3708   };
3709   ProcessVoidEvent( new TEvent( id ) );
3710 }
3711
3712 /*!
3713   \fn QString SalomePyQt::getPlot2dTitle( const int id, ObjectType type = MainTitle )
3714   \brief Get title of corresponding type
3715   \param id window identifier
3716   \param type is type of title
3717   \return title of corresponding type
3718 */
3719
3720 class TGetPlot2dTitle: public SALOME_Event
3721 {
3722 public:
3723   typedef QString TResult;
3724   TResult myResult;
3725   int myWndId;
3726   ObjectType myType;
3727   TGetPlot2dTitle(const int id, ObjectType type) :
3728     myWndId( id ),
3729     myType( type ) {}
3730   virtual void Execute() {
3731     Plot2d_ViewWindow* wnd = dynamic_cast<Plot2d_ViewWindow*>( getWnd( myWndId ) );
3732     if ( wnd )
3733       myResult = wnd->getViewFrame()->getTitle( (Plot2d_ViewFrame::ObjectType)myType );
3734   }
3735 };
3736 QString SalomePyQt::getPlot2dTitle( const int id, ObjectType type )
3737 {
3738   return ProcessEvent( new TGetPlot2dTitle( id, type ) ); 
3739 }
3740
3741
3742 /*!
3743   \fn void SalomePyQt::setPlot2dTitle( const int id, const QString& title, ObjectType type = MainTitle, bool show = true )
3744   \brief Set title of corresponding type
3745   \param id window identifier
3746   \param title
3747   \param type is type of title
3748   \param show
3749 */
3750
3751 class TSetPlot2dTitle: public SALOME_Event
3752 {
3753 public:
3754   int myWndId;
3755   Plot2d_Curve* myCurve;
3756   QString myTitle;
3757   ObjectType myType;
3758   bool myShow;
3759   TSetPlot2dTitle( const int id, const QString& title, ObjectType type, bool show ) :
3760     myWndId( id ),
3761     myTitle( title ),
3762     myType( type ),
3763     myShow( show ) {}
3764   virtual void Execute() {
3765     Plot2d_ViewWindow* wnd = dynamic_cast<Plot2d_ViewWindow*>( getWnd( myWndId ) );
3766     wnd->getViewFrame()->setTitle( myShow, myTitle, (Plot2d_ViewFrame::ObjectType)myType, false );
3767   }
3768 };
3769 void SalomePyQt::setPlot2dTitle( const int id, const QString& title, ObjectType type, bool show )
3770 {
3771   ProcessVoidEvent( new TSetPlot2dTitle( id, title, type, show ) ); 
3772 }
3773
3774 /*!
3775   \fn QList<int> SalomePyQt::getPlot2dFitRangeByCurves( const int id )
3776   \brief Get list of Plot2d view ranges
3777   \param id window identifier
3778   \return list of view ranges (XMin, XMax, YMin, YMax)
3779 */
3780
3781 class TFitRangeByCurves: public SALOME_Event
3782 {
3783 public:
3784   typedef QList<double> TResult;
3785   TResult myResult;
3786   int myWndId;
3787   TFitRangeByCurves( const int id )
3788     : myWndId( id ) {}
3789   virtual void Execute() 
3790   {
3791     myResult.clear();
3792     Plot2d_ViewWindow* wnd = dynamic_cast<Plot2d_ViewWindow*>( getWnd( myWndId ) );
3793     if ( wnd ) {
3794       double XMin, XMax, YMin, YMax, Y2Min, Y2Max;
3795       wnd->getViewFrame()->getFitRangeByCurves( XMin, XMax, YMin, YMax, Y2Min, Y2Max );
3796       myResult.append( XMin );
3797       myResult.append( XMax );
3798       myResult.append( YMin );
3799       myResult.append( YMax );
3800     }
3801   }
3802 };
3803 QList<double> SalomePyQt::getPlot2dFitRangeByCurves( const int id )
3804 {
3805   return ProcessEvent( new TFitRangeByCurves( id ) );
3806 }
3807
3808 /*!
3809   \fn QList<int> SalomePyQt::getPlot2dFitRangeCurrent( const int id )
3810   \brief Get list of current Plot2d view ranges
3811   \param id window identifier
3812   \return list of view ranges (XMin, XMax, YMin, YMax)
3813 */
3814
3815 class TFitRangeCurrent: public SALOME_Event
3816 {
3817 public:
3818   typedef QList<double> TResult;
3819   TResult myResult;
3820   int myWndId;
3821   TFitRangeCurrent( const int id )
3822     : myWndId( id ) {}
3823   virtual void Execute() 
3824   {
3825     myResult.clear();
3826     Plot2d_ViewWindow* wnd = dynamic_cast<Plot2d_ViewWindow*>( getWnd( myWndId ) );
3827     if ( wnd ) {
3828       double XMin, XMax, YMin, YMax, Y2Min, Y2Max;
3829       wnd->getViewFrame()->getFitRanges( XMin, XMax, YMin, YMax, Y2Min, Y2Max );
3830       myResult.append( XMin );
3831       myResult.append( XMax );
3832       myResult.append( YMin );
3833       myResult.append( YMax );
3834     }
3835   }
3836 };
3837 QList<double> SalomePyQt::getPlot2dFitRangeCurrent( const int id )
3838 {
3839   return ProcessEvent( new TFitRangeCurrent( id ) );
3840 }
3841
3842 /*!
3843   \fn void SalomePyQt::setPlot2dFitRange( const int id, const double XMin, const double XMax, const double YMin, const double YMax )
3844   \brief Set range of Plot2d view
3845   \param id window identifier
3846   \param XMin
3847   \param XMax
3848   \param YMin
3849   \param YMax
3850 */
3851
3852 class TPlot2dFitRange: public SALOME_Event
3853 {
3854 public:
3855   int myWndId;
3856   double myXMin;
3857   double myXMax;
3858   double myYMin;
3859   double myYMax;
3860   TPlot2dFitRange( const int id, const double XMin, const double XMax, const double YMin, const double YMax ) :
3861     myWndId( id ),
3862     myXMin( XMin ),
3863     myXMax( XMax ),
3864     myYMin( YMin ),
3865     myYMax( YMax ) {}
3866   virtual void Execute() {
3867     Plot2d_ViewWindow* wnd = dynamic_cast<Plot2d_ViewWindow*>( getWnd( myWndId ) );
3868     if ( wnd )
3869       wnd->getViewFrame()->fitData( 0, myXMin, myXMax, myYMin, myYMax );
3870   }
3871 };
3872 void SalomePyQt::setPlot2dFitRange( const int id, const double XMin, const double XMax, const double YMin, const double YMax )
3873 {
3874   ProcessVoidEvent( new TPlot2dFitRange( id, XMin, XMax, YMin, YMax ) ); 
3875 }
3876
3877 // End of methods related to the Plot2d viewer functionality
3878 #endif // DISABLE_PLOT2DVIEWER
3879
3880 /*!
3881   \brief Process Qt event loop
3882 */
3883 void SalomePyQt::processEvents()
3884 {
3885   QCoreApplication::processEvents();
3886 }
3887
3888 /*!
3889   \brief Set visibility state for given object
3890   \param theEntry study ID of the object
3891   \param theState visibility state
3892 */
3893 void SalomePyQt::setVisibilityState( const QString& theEntry, VisibilityState theState )
3894 {
3895   class TEvent: public SALOME_Event
3896   {
3897     QString myEntry;
3898     int myState;
3899   public:
3900     TEvent( const QString& theEntry, int theState ):
3901       myEntry( theEntry ), myState( theState ) {}
3902     virtual void Execute() 
3903     {
3904       LightApp_Study* aStudy = getActiveStudy();
3905       if ( !aStudy )
3906         return;
3907       aStudy->setVisibilityState( myEntry, (Qtx::VisibilityState)myState );
3908     }
3909   };
3910   ProcessVoidEvent( new TEvent( theEntry, theState ) );
3911 }
3912
3913 /*!
3914   \fn VisibilityState SalomePyQt::getVisibilityState( const QString& theEntry )
3915   \brief Get visibility state for given object
3916   \param theEntry study ID of the object
3917   \return visibility state
3918 */
3919
3920 class TGetVisibilityStateEvent: public SALOME_Event 
3921 {
3922 public:
3923   typedef int TResult;
3924   TResult myResult;
3925   QString myEntry;
3926   TGetVisibilityStateEvent( const QString& theEntry ) : myResult( 0 ), myEntry( theEntry ) {}
3927   virtual void Execute()
3928   {
3929     LightApp_Study* aStudy = getActiveStudy();
3930     if ( aStudy )
3931       myResult = aStudy->visibilityState( myEntry );
3932   }
3933 };
3934 VisibilityState SalomePyQt::getVisibilityState( const QString& theEntry )
3935 {
3936   return (VisibilityState) ProcessEvent( new TGetVisibilityStateEvent( theEntry ) );
3937 }
3938
3939 /*!
3940   \brief Set position of given object in the tree
3941   \param theEntry study ID of the object
3942   \param thePos position
3943 */
3944 void SalomePyQt::setObjectPosition( const QString& theEntry, int thePos )
3945 {
3946   class TEvent: public SALOME_Event
3947   {
3948     QString myEntry;
3949     int myPos;
3950   public:
3951     TEvent( const QString& theEntry, int thePos ):
3952       myEntry( theEntry ), myPos( thePos ) {}
3953     virtual void Execute() 
3954     {
3955       SALOME_PYQT_ModuleLight* module = dynamic_cast<SALOME_PYQT_ModuleLight*>( getActiveModule() );
3956       if ( module )
3957         module->setObjectPosition( myEntry, myPos );
3958     }
3959   };
3960   ProcessVoidEvent( new TEvent( theEntry, thePos ) );
3961 }
3962
3963 /*!
3964   \fn int SalomePyQt::getObjectPosition( const QString& theEntry )
3965   \brief Get position of given object in the tree
3966   \param theEntry study ID of the object
3967   \return position
3968 */
3969
3970 class TGetObjectPositionEvent: public SALOME_Event 
3971 {
3972 public:
3973   typedef int TResult;
3974   TResult myResult;
3975   QString myEntry;
3976   TGetObjectPositionEvent( const QString& theEntry ) : myResult( 0 ), myEntry( theEntry ) {}
3977   virtual void Execute()
3978   {
3979     SALOME_PYQT_ModuleLight* module = dynamic_cast<SALOME_PYQT_ModuleLight*>( getActiveModule() );
3980     if ( module )
3981       myResult = module->getObjectPosition( myEntry );
3982   }
3983 };
3984 int SalomePyQt::getObjectPosition( const QString& theEntry )
3985 {
3986   return ProcessEvent( new TGetObjectPositionEvent( theEntry ) );
3987 }
3988
3989 /*!
3990   \brief Start recordind a log of Python commands from embedded console
3991   \param theFileName output lof file name
3992 */
3993 void SalomePyQt::startPyLog( const QString& theFileName )
3994 {
3995   class TEvent: public SALOME_Event
3996   {
3997     QString myFileName;
3998   public:
3999     TEvent( const QString& theFileName ):
4000       myFileName( theFileName ) {}
4001     virtual void Execute() 
4002     {
4003       if ( getApplication() ) {
4004         PyConsole_Console* pyConsole = getApplication()->pythonConsole( false );
4005         if ( pyConsole ) pyConsole->startLog( myFileName );
4006       }
4007     }
4008   };
4009   ProcessVoidEvent( new TEvent( theFileName ) );
4010 }
4011
4012 /*!
4013   \brief Stop recordind a log of Python commands from embedded console
4014 */
4015 void SalomePyQt::stopPyLog()
4016 {
4017   class TEvent: public SALOME_Event
4018   {
4019   public:
4020     TEvent() {}
4021     virtual void Execute() 
4022     {
4023       if ( getApplication() ) {
4024         PyConsole_Console* pyConsole = getApplication()->pythonConsole( false );
4025         if ( pyConsole ) pyConsole->stopLog();
4026       }
4027     }
4028   };
4029   ProcessVoidEvent( new TEvent() );
4030 }