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