Salome HOME
Unicode support: correct handling of unicode on GUI level
[modules/gui.git] / src / SALOME_PYQT / SalomePyQt / SalomePyQt.cxx
index e50f65e24e2c1f1b984a60495d43eae00f0a4e47..6b2eb96a08170e97da444888e37d96bcf814f7b9 100644 (file)
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 //
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2.1 of the License.
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
 //
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
 //
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
-//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // File   : SalomePyQt.cxx
 // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
-//
-#include <SALOME_PYQT_Module.h> // this include must be first!!!
+
+#ifdef WIN32
+// E.A. : On windows with python 2.6, there is a conflict
+// E.A. : between pymath.h and Standard_math.h which define
+// E.A. : some same symbols : acosh, asinh, ...
+#include <Standard_math.hxx>
+#include <pymath.h>
+#endif
+
+#include "SALOME_PYQT_ModuleLight.h" // this include must be first!!!
+#include "SALOME_PYQT_DataModelLight.h"
+#include "SALOME_PYQT_PyModule.h"
 #include "SalomePyQt.h"
 
-#include <QApplication>
-#include <QMenuBar>
-#include <QMenu>
-#include <QImage>
-#include <QStringList>
+#include "LightApp_SelectionMgr.h"
+#include "LogWindow.h"
+#ifndef DISABLE_OCCVIEWER
+#include "OCCViewer_ViewWindow.h"
+#include "OCCViewer_ViewFrame.h"
+#endif // DISABLE_OCCVIEWER
+#ifndef DISABLE_PLOT2DVIEWER
+#include "Plot2d_ViewManager.h"
+#include "Plot2d_ViewWindow.h"
+#endif // DISABLE_PLOT2DVIEWER
+#ifndef DISABLE_PVVIEWER
+#include "PVViewer_ViewManager.h"
+#include "PVViewer_ViewModel.h"
+#endif // DISABLE_PVVIEWER
+#include "QtxActionMenuMgr.h"
+#include "QtxWorkstack.h"
+#include "QtxTreeView.h"
+#include "SALOME_Event.h"
+#include "STD_TabDesktop.h"
+#include "SUIT_DataBrowser.h"
+#include "SUIT_ResourceMgr.h"
+#include "SUIT_Session.h"
+#include "SUIT_Tools.h"
+#include "SUIT_ViewManager.h"
+#include "SUIT_ViewWindow.h"
+#include "PyConsole_Console.h"
+
 #include <QAction>
+#include <QApplication>
+#include <QPaintEvent>
+#include <QCoreApplication>
+#include <QVBoxLayout>
 
-#include <SALOME_Event.h>
-
-#include <QtxActionMenuMgr.h>
-#include <QtxActionGroup.h>
-#include <QtxWorkstack.h>
-#include <SUIT_Session.h>
-#include <SUIT_Desktop.h>
-#include <SUIT_ResourceMgr.h>
-#include <SUIT_Tools.h>
-#include <SUIT_ViewManager.h>
-#include <SUIT_ViewWindow.h>
-#include <STD_TabDesktop.h>
-#include <SalomeApp_Application.h>
-#include <SalomeApp_Study.h>
-#include <LightApp_SelectionMgr.h>
-#include <LogWindow.h>
-#include <OCCViewer_ViewWindow.h>
-#include <Plot2d_ViewManager.h>
-#include <Plot2d_ViewWindow.h>
-
-/*!
-  \brief Get the currently active application.
-  \internal
-  \return active application object or 0 if there is no any
-*/
-static SalomeApp_Application* getApplication()
-{
-  if ( SUIT_Session::session() )
-    return dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
-  return 0;
-}
+#include <utilities.h>
 
-/*!
-  \brief Get the currently active study.
-  \internal
-  \return active study or 0 if there is no study opened
-*/
-static SalomeApp_Study* getActiveStudy()
+namespace
 {
-  if ( getApplication() )
-    return dynamic_cast<SalomeApp_Study*>( getApplication()->activeStudy() );
-  return 0;
-}
+  /*!
+    \brief Get the currently active application.
+    \internal
+    \return active application object or 0 if there is no any
+  */
+  LightApp_Application* getApplication()
+  {
+    if ( SUIT_Session::session() )
+      return dynamic_cast<LightApp_Application*>( SUIT_Session::session()->activeApplication() );
+    return 0;
+  }
+  
+  /*!
+    \brief Get the currently active study.
+    \internal
+    \return active study or 0 if there is no study opened
+  */
+  LightApp_Study* getActiveStudy()
+  {
+    if ( getApplication() )
+      return dynamic_cast<LightApp_Study*>( getApplication()->activeStudy() );
+    return 0;
+  }
 
-/*!
-  \brief Get the currently active module.
-  \internal
-  This function returns correct result only if Python-based
-  module is currently active. Otherwize, 0 is returned.
-*/
-static SALOME_PYQT_Module* getActiveModule()
-{
-  SALOME_PYQT_Module* module = 0;
-  if ( SalomeApp_Application* anApp = getApplication() ) {
-    module = SALOME_PYQT_Module::getInitModule();
-    if ( !module )
-      module = dynamic_cast<SALOME_PYQT_Module*>( anApp->activeModule() );
+  /*!
+    \brief Get the currently active module.
+    \internal
+    This function returns correct result only if Python-based
+    module is currently active. Otherwize, 0 is returned.
+  */
+  LightApp_Module* getActiveModule()
+  {
+    LightApp_Module* module = 0;
+    if ( LightApp_Application* anApp = getApplication() ) {
+      module = PyModuleHelper::getInitModule();
+      if ( !module )
+        module = dynamic_cast<LightApp_Module*>( anApp->activeModule() );
+    }
+    return module;
+  }
+  
+  /*!
+    \brief Get the currently active Python module's helper.
+    \internal
+    This function returns correct result only if Python-based
+    module is currently active. Otherwize, 0 is returned.
+  */
+  PyModuleHelper* getPythonHelper()
+  {
+    LightApp_Module* module = getActiveModule();
+    PyModuleHelper* helper = module ? module->findChild<PyModuleHelper*>( "python_module_helper" ) : 0;
+    return helper;
+  }
+  
+  /*!
+    \brief Get SALOME verbose level
+    \internal
+    \return \c true if SALOME debug output is allowed or \c false otherwise
+  */
+  bool verbose()
+  {
+    bool isVerbose = false;
+    if ( getenv( "SALOME_VERBOSE" ) ) {
+      QString envVar = getenv( "SALOME_VERBOSE" );
+      bool ok;
+      int value = envVar.toInt( &ok );
+      isVerbose = ok && value != 0;
+    }
+    return isVerbose;
+  }
+
+  /*!
+    \brief Get menu item title
+    \internal
+    \param menuId menu identifier
+    \return menu title (localized)
+  */
+  QString getMenuName( const QString& menuId )
+  {
+    QStringList contexts;
+    contexts << "SalomeApp_Application" << "LightApp_Application" << "STD_TabDesktop" <<
+      "STD_MDIDesktop" << "STD_Application" << "SUIT_Application" << "";
+    QString menuName = menuId;
+    for ( int i = 0; i < contexts.count() && menuName == menuId; i++ )
+      menuName = QApplication::translate( contexts[i].toLatin1().data(), menuId.toLatin1().data() );
+    return menuName;
+  }
+
+  /*!
+    \brief Load module icon
+    \internal
+    \param module module name
+    \param fileName path to the icon file
+    \return icon
+  */
+  QIcon loadIconInternal( const QString& module, const QString& fileName )
+  {
+    QIcon icon;
+    
+    LightApp_Application* app = getApplication();
+    
+    if ( app && !fileName.isEmpty() ) {
+      QPixmap pixmap = app->resourceMgr()->loadPixmap( module, 
+                                                       QApplication::translate( module.toLatin1().data(), 
+                                                                                fileName.toUtf8().data() ) );
+      if ( !pixmap.isNull() )
+        icon = QIcon( pixmap );
+    }
+    return icon;
+  }
+
+  /*!
+    \brief Gets window with specified identifier 
+    \internal
+    \param id window identifier 
+    \return pointer on the window
+  */
+  SUIT_ViewWindow* getWnd( const int id )
+  {
+    SUIT_ViewWindow* resWnd = 0;
+    
+    LightApp_Application* app = getApplication();
+    if ( app ) {
+      ViewManagerList vmlist = app->viewManagers();
+      foreach( SUIT_ViewManager* vm, vmlist ) {
+        QVector<SUIT_ViewWindow*> vwlist = vm->getViews();
+        foreach ( SUIT_ViewWindow* vw, vwlist ) {
+          if ( id == vw->getId() ) {
+            resWnd = vw;
+            break;
+          }
+        }
+      }
+    }
+    return resWnd;
   }
-  return module;
+
+  /*!
+    \brief Map of created selection objects.
+    \internal
+  */
+  QMap<LightApp_Application*, SALOME_Selection*> SelMap;
+
+  /*!
+    \brief Default resource file section name.
+    \internal
+  */
+  const char* DEFAULT_SECTION = "SalomePyQt";
 }
 
 /*!
@@ -98,12 +228,6 @@ static SALOME_PYQT_Module* getActiveModule()
   \brief The class represents selection which can be used in Python.
 */
 
-/*!
-  \brief Map of created selection objects.
-  \internal
-*/
-static QMap<SalomeApp_Application*, SALOME_Selection*> SelMap;
-
 /*!
   \brief Get the selection object for the specified application.
 
@@ -112,7 +236,7 @@ static QMap<SalomeApp_Application*, SALOME_Selection*> SelMap;
   \param app application object
   \return selection object or 0 if \a app is invalid
 */
-SALOME_Selection* SALOME_Selection::GetSelection( SalomeApp_Application* app )
+SALOME_Selection* SALOME_Selection::GetSelection( LightApp_Application* app )
 {
   SALOME_Selection* sel = 0;
   if ( app && SelMap.find( app ) != SelMap.end() )
@@ -122,27 +246,32 @@ SALOME_Selection* SALOME_Selection::GetSelection( SalomeApp_Application* app )
   return sel;
 }
 
+
 /*!
   \brief Constructor.
   \param p parent object
 */
-SALOME_Selection::SALOME_Selection( QObject* p ) : QObject( p ), mySelMgr( 0 )
+SALOME_Selection::SALOME_Selection( QObject* p ) : QObject( 0 ), mySelMgr( 0 )
 {
-  SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( p );
+  LightApp_Application* app = dynamic_cast<LightApp_Application*>( p );
   if ( app ) {
     mySelMgr = app->selectionMgr();
     connect( mySelMgr, SIGNAL( selectionChanged() ), this, SIGNAL( currentSelectionChanged() ) );
     connect( mySelMgr, SIGNAL( destroyed() ),        this, SLOT  ( onSelMgrDestroyed() ) );
   }
 }
+
 /*!
   \brief Destructor.
 */
 SALOME_Selection::~SALOME_Selection()
 {
-  SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( parent() );
-  if ( app && SelMap.find( app ) != SelMap.end() )
-    SelMap.remove( app );
+  LightApp_Application* app = 0;
+  QMap<LightApp_Application*, SALOME_Selection*>::Iterator it;
+  for ( it = SelMap.begin(); it != SelMap.end() && !app; ++it ) {
+    if ( it.value() == this ) app = it.key();
+  }
+  if ( app ) SelMap.remove( app );
 }
 
 /*!
@@ -159,12 +288,14 @@ void SALOME_Selection::onSelMgrDestroyed()
 */
 void SALOME_Selection::Clear()
 {
-  class TEvent: public SALOME_Event {
+  class TEvent: public SALOME_Event
+  {
     LightApp_SelectionMgr* mySelMgr;
   public:
     TEvent( LightApp_SelectionMgr* selMgr ) 
       : mySelMgr( selMgr ) {}
-    virtual void Execute() {
+    virtual void Execute() 
+    {
       if ( mySelMgr )
         mySelMgr->clearSelected();
     }
@@ -185,12 +316,14 @@ void SALOME_Selection::ClearIObjects()
 */
 void SALOME_Selection::ClearFilters()
 {
-  class TEvent: public SALOME_Event {
+  class TEvent: public SALOME_Event 
+  {
     LightApp_SelectionMgr* mySelMgr;
   public:
     TEvent( LightApp_SelectionMgr* selMgr ) 
       : mySelMgr( selMgr ) {}
-    virtual void Execute() {
+    virtual void Execute() 
+    {
       if ( mySelMgr )
         mySelMgr->clearFilters();
     }
@@ -198,6 +331,90 @@ void SALOME_Selection::ClearFilters()
   ProcessVoidEvent( new TEvent( mySelMgr ) );
 }
 
+/*!
+  \class UserDefinedContent
+  \brief The class represents base class for user defined widget that
+  can be inserted to the Preferences dialog.
+*/
+
+/*!
+  \brief Constructor
+*/
+UserDefinedContent::UserDefinedContent()
+  : QWidget()
+{
+}
+
+/*!
+  \brief Called from Preferences dialog to store settings to the resource file.
+*/
+void UserDefinedContent::store()
+{
+}
+
+/*!
+  \brief Called from Preferences dialog to restore settings from the resource file.
+*/
+void UserDefinedContent::retrieve()
+{
+}
+
+/*!
+  \class SgPyQtUserDefinedContent
+  \brief A Wrapper for UserDefinedContent class.
+  \internal
+*/
+class SgPyQtUserDefinedContent: public QtxUserDefinedContent
+{
+public:
+  SgPyQtUserDefinedContent(UserDefinedContent*);
+  virtual ~SgPyQtUserDefinedContent();
+
+  void store( QtxResourceMgr*, QtxPreferenceMgr* );
+  void retrieve( QtxResourceMgr*, QtxPreferenceMgr* );
+
+private:
+  UserDefinedContent* myContent;
+};
+
+/*!
+  \brief Create custom item for Preferences dialog wrapping widget passed from Python.
+  \internal
+*/
+SgPyQtUserDefinedContent::SgPyQtUserDefinedContent(UserDefinedContent* content)
+  : QtxUserDefinedContent( 0 ), myContent( content )
+{
+  QVBoxLayout* l = new QVBoxLayout( this );
+  l->setContentsMargins( 0, 0, 0, 0 );
+  l->addWidget( myContent );
+}
+
+/*!
+  \brief Destructor.
+  \internal
+*/
+SgPyQtUserDefinedContent::~SgPyQtUserDefinedContent()
+{
+}
+
+/*!
+  \brief Called from Preferences dialog to store settings to the resource file.
+  \internal
+*/
+void SgPyQtUserDefinedContent::store( QtxResourceMgr*, QtxPreferenceMgr* )
+{
+  myContent->store();
+}
+
+/*!
+  \brief Called from Preferences dialog to restore settings from the resource file.
+  \internal
+*/
+void SgPyQtUserDefinedContent::retrieve( QtxResourceMgr*, QtxPreferenceMgr* )
+{
+  myContent->retrieve();
+}
+
 /*!
   \class SalomePyQt
   \brief The class provides utility functions which can be used in the Python
@@ -282,7 +499,7 @@ public:
   TGetMainMenuBarEvent() : myResult( 0 ) {}
   virtual void Execute()
   {
-    if ( SalomeApp_Application* anApp = getApplication() ) {
+    if ( LightApp_Application* anApp = getApplication() ) {
       myResult = anApp->desktop()->menuBar();
     }
   }
@@ -293,7 +510,7 @@ QMenuBar* SalomePyQt::getMainMenuBar()
 }
 
 /*!
-  QMenu* SalomePyQt::getPopupMenu( const MenuName menu );
+  \fn QMenu* SalomePyQt::getPopupMenu( const MenuName menu );
   \brief Get main menu's child popup submenu by its identifier.
   
   This function is obsolete. 
@@ -304,7 +521,7 @@ QMenuBar* SalomePyQt::getMainMenuBar()
 */
 
 /*!
-  QMenu* SalomePyQt::getPopupMenu( const QString& menu );
+  \fn QMenu* SalomePyQt::getPopupMenu( const QString& menu );
   \brief Get main menu's child popup submenu by its name.
   
   The function creates menu if it does not exist.
@@ -322,7 +539,7 @@ public:
   TGetPopupMenuEvent( const QString& menu ) : myResult( 0 ), myMenuName( menu ) {}
   virtual void Execute()
   {
-    SalomeApp_Application* anApp = getApplication();
+    LightApp_Application* anApp = getApplication();
     if ( anApp && !myMenuName.isEmpty() ) {
       QtxActionMenuMgr* mgr = anApp->desktop()->menuMgr();
       myResult = mgr->findMenu( myMenuName, -1, false ); // search only top menu
@@ -330,17 +547,6 @@ public:
   }
 };
 
-static QString getMenuName( const QString& menuId )
-{
-  QStringList contexts;
-  contexts << "SalomeApp_Application" << "LightApp_Application" << "STD_TabDesktop" <<
-    "STD_MDIDesktop" << "STD_Application" << "SUIT_Application" << "";
-  QString menuName = menuId;
-  for ( int i = 0; i < contexts.count() && menuName == menuId; i++ )
-    menuName = QApplication::translate( contexts[i].toLatin1().data(), menuId.toLatin1().data() );
-  return menuName;
-}
-
 QMenu* SalomePyQt::getPopupMenu( const MenuName menu )
 {
   QString menuName;
@@ -368,31 +574,32 @@ QMenu* SalomePyQt::getPopupMenu( const QString& menu )
 }
 
 /*!
-  \fn int SalomePyQt::getStudyId();
-  \brief Get active study's identifier.
-  \return active study ID or 0 if there is no active study
+  \fn QTreeView* SalomePyQt::getObjectBrowser();
+  \brief Get object browser
+  \return object browser for the active study or 0 in case of error
 */
 
-class TGetStudyIdEvent: public SALOME_Event
+class TGetObjectBrowserEvent: public SALOME_Event
 {
 public:
-  typedef int TResult;
+  typedef QTreeView* TResult;
   TResult myResult;
-  TGetStudyIdEvent() : myResult( 0 ) {}
+  TGetObjectBrowserEvent() : myResult( 0 ) {}
   virtual void Execute()
   {
-    if ( SalomeApp_Study* aStudy = getActiveStudy() ) {
-      myResult = aStudy->studyDS()->StudyId();
+    LightApp_Application* anApp = getApplication();
+    if ( anApp && anApp->objectBrowser() ) {
+      myResult = anApp->objectBrowser()->treeView();
     }
   }
 };
-int SalomePyQt::getStudyId()
+QTreeView* SalomePyQt::getObjectBrowser()
 {
-  return ProcessEvent( new TGetStudyIdEvent() );
+  return ProcessEvent( new TGetObjectBrowserEvent() );
 }
 
 /*!
-  \fn SALOME_Selection* SalomePyQt::getSelection()
+  \fn SALOME_Selection* SalomePyQt::getSelection();
   \brief Get the selection object for the current study.
 
   Creates a Selection object if it has not been created yet.
@@ -417,7 +624,76 @@ SALOME_Selection* SalomePyQt::getSelection()
 }
 
 /*!
-  \fn void SalomePyQt::putInfo( const QString& msg, const int sec )
+  \fn QStringList* SalomePyQt::setSelection(const QStringList& );
+  \brief Send local selection for notification.
+
+  The list of locally selected objects (study entries) is sent for notification of
+  other listening entities (modules, viewers...).
+*/
+
+class TSetSelectionEvent: public SALOME_Event
+{
+  QStringList myEntryList;
+public:
+  TSetSelectionEvent(const QStringList& entryList) : myEntryList(entryList) {}
+  virtual void Execute()
+  {
+       SALOME_PYQT_ModuleLight* module = dynamic_cast<SALOME_PYQT_ModuleLight*>( getActiveModule() );
+       if ( !module ) return;
+       module->setLocalSelected(myEntryList);
+  }
+};
+void SalomePyQt::setSelection( const QStringList& entryList)
+{
+  return ProcessVoidEvent( new TSetSelectionEvent(entryList) );
+}
+
+/*!
+  \fn void SalomePyQt::enableSelector();
+  \brief enable PyQt_Selector (on module activation, for instance)
+*/
+
+class TEnableSelectorEvent: public SALOME_Event
+{
+public:
+       TEnableSelectorEvent() {}
+  virtual void Execute()
+  {
+       SALOME_PYQT_ModuleLight* module = dynamic_cast<SALOME_PYQT_ModuleLight*>( getActiveModule() );
+       if ( !module ) return;
+       module->enableSelector();
+  }
+};
+void SalomePyQt::enableSelector()
+{
+  return ProcessVoidEvent( new TEnableSelectorEvent() );
+}
+
+
+/*!
+  \fn void SalomePyQt::disableSelector();
+  \brief disable PyQt_Selector (on module activation, for instance)
+*/
+
+class TdisableSelectorEvent: public SALOME_Event
+{
+public:
+       TdisableSelectorEvent() {}
+  virtual void Execute()
+  {
+       SALOME_PYQT_ModuleLight* module = dynamic_cast<SALOME_PYQT_ModuleLight*>( getActiveModule() );
+       if ( !module ) return;
+       module->disableSelector();
+  }
+};
+void SalomePyQt::disableSelector()
+{
+  return ProcessVoidEvent( new TdisableSelectorEvent() );
+}
+
+
+/*!
+  \fn void SalomePyQt::putInfo( const QString& msg, const int sec );
   \brief Put an information message to the current application's 
   desktop status bar.
 
@@ -437,7 +713,7 @@ public:
   TPutInfoEvent( const QString& msg, const int sec = 0 ) : myMsg( msg ), mySecs( sec ) {}
   virtual void Execute()
   {
-    if ( SalomeApp_Application* anApp = getApplication() ) {
+    if ( LightApp_Application* anApp = getApplication() ) {
       anApp->putInfo( myMsg, mySecs * 1000 );
     }
   }
@@ -461,7 +737,7 @@ public:
   TGetActiveComponentEvent() {}
   virtual void Execute() 
   {
-    if ( SalomeApp_Application* anApp = getApplication() ) {
+    if ( LightApp_Application* anApp = getApplication() ) {
       if ( CAM_Module* mod = anApp->activeModule() ) {
         myResult = mod->name();
       }
@@ -474,53 +750,163 @@ const QString SalomePyQt::getActiveComponent()
 }
 
 /*!
-  \brief Update an Object Browser of the specified (by identifier) study.
+  \fn PyObject* SalomePyQt::getActivePythonModule();
+  \brief Access to Python module object currently loaded into SALOME_PYQT_ModuleLight container.
+  \return Python module object currently loaded into SALOME_PYQT_ModuleLight container
+*/
 
-  If \a studyId <= 0 the active study's object browser is updated.
-  The \a updateSelection parameter is obsolete and currently is not used. 
-  This parameter will be removed in future, so try to avoid its usage in 
-  your code.
+class TGetActivePyModuleEvent: public SALOME_Event
+{
+public:
+  typedef PyObject* TResult;
+  TResult myResult;
+  TGetActivePyModuleEvent() : myResult( Py_None ) {}
+  virtual void Execute() 
+  {
+    PyModuleHelper* helper = getPythonHelper();
+    if ( helper )
+      myResult = (PyObject*)helper->pythonModule();
+  }
+};
+PyObject* SalomePyQt::getActivePythonModule()
+{
+  return ProcessEvent( new TGetActivePyModuleEvent() );
+}
+
+/*!
+  \fn bool SalomePyQt::activateModule( const QString& modName );
+  \brief Activates SALOME module with the given name
+  \return True if the module has been activated and False otherwise.
+*/
 
-  \brief studyId study identifier
-  \brief updateSelection update selection flag (not used)
-  \sa getActiveStudy()
+class TActivateModuleEvent: public SALOME_Event
+{
+public:
+  typedef bool TResult;
+  TResult myResult;
+  QString myModuleName;
+  TActivateModuleEvent( const QString& modName ) 
+  : myResult( false ), myModuleName( modName ) {}
+  virtual void Execute() 
+  {
+    if ( LightApp_Application* anApp = getApplication() ) {
+      myResult = anApp->activateModule( myModuleName );
+    }
+  }
+};
+bool SalomePyQt::activateModule( const QString& modName )
+{
+  return ProcessEvent( new TActivateModuleEvent( modName ) );
+}
+
+/*!
+  \brief Update an Object Browser of the study.
 */
-void SalomePyQt::updateObjBrowser( const int studyId, bool updateSelection )
+void SalomePyQt::updateObjBrowser()
 {  
   class TEvent: public SALOME_Event
   {
-    int  myStudyId;
-    bool myUpdateSelection;
   public:
-    TEvent( const int studyId, bool updateSelection ) 
-      : myStudyId( studyId ), myUpdateSelection( updateSelection ) {}
+    TEvent() {}
     virtual void Execute()
     {
       if ( SUIT_Session::session() ) {
-        if ( getActiveStudy() && myStudyId <= 0 )
-          myStudyId = getActiveStudy()->id();
-       if ( myStudyId > 0 ) {
+        if ( getActiveStudy() ) {
           QList<SUIT_Application*> apps = SUIT_Session::session()->applications();
           QList<SUIT_Application*>::Iterator it;
-         for( it = apps.begin(); it != apps.end(); ++it ) {
-            SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>( *it );
-            if ( anApp && anApp->activeStudy() && anApp->activeStudy()->id() == myStudyId ) {
-             anApp->updateObjectBrowser();
-             return;
-           }
+          for( it = apps.begin(); it != apps.end(); ++it ) {
+            LightApp_Application* anApp = dynamic_cast<LightApp_Application*>( *it );
+            if ( anApp && anApp->activeStudy() ) {
+              anApp->updateObjectBrowser();
+              return;
+            }
           }
         }
       }
     }
   };
-  ProcessVoidEvent( new TEvent( studyId, updateSelection ) );
+  ProcessVoidEvent( new TEvent() );
 }
 
+
 /*!
-  \brief Default resource file section name.
-  \internal
+  SalomePyQt::isModified()
+  \return The modification status of the data model
+  for the currently active Python module
+  \note This function is supported for "light" Python-based SALOME modules only.
+  \sa setModified()
+*/
+class TIsModifiedEvent: public SALOME_Event
+{
+public:
+  typedef bool TResult;
+  TResult myResult;
+  TIsModifiedEvent() : myResult( false ) {}
+  virtual void Execute() 
+  {
+    LightApp_Module* module = getActiveModule();
+    if ( !module )
+      return;
+    
+    SALOME_PYQT_DataModelLight* aModel =
+      dynamic_cast<SALOME_PYQT_DataModelLight*>( module->dataModel() );
+    if ( aModel ) {
+      myResult = aModel->isModified();
+    }
+    else {
+      if ( verbose() ) printf( "SalomePyQt.isModified() function is not supported for the current module.\n" );
+    }
+  }
+};
+bool SalomePyQt::isModified()
+{
+  return ProcessEvent(new TIsModifiedEvent());
+}
+
+/*!
+  SalomePyQt::setModified()
+
+  Sets the modification status of the data model for 
+  the currently active Python module. This method should be used
+  by the Python code in order to enable/disable "Save" operation
+  depending on the module's data state.
+
+  \note This function is supported for "light" Python-based SALOME modules only.
+
+  \param New modification status of the data model
+
+  \sa isModified()
 */
-static const char* DEFAULT_SECTION = "SalomePyQt";
+void SalomePyQt::setModified( bool flag )
+{  
+  class TEvent: public SALOME_Event
+  {
+    bool myFlag;
+  public:
+    TEvent( bool flag ) 
+      : myFlag( flag ) {}
+    virtual void Execute()
+    {
+      LightApp_Module* module = getActiveModule();
+      if ( !module )
+       return;
+
+      SALOME_PYQT_DataModelLight* model =
+       dynamic_cast<SALOME_PYQT_DataModelLight*>( module->dataModel() );
+
+      LightApp_Application* app = module->getApp();
+
+      if ( model && app ) {
+       model->setModified( myFlag );
+       app->updateActions();
+      }
+      else {
+       if ( verbose() ) printf( "SalomePyQt.setModified() function is not supported for the current module.\n" );
+      }
+    }
+  };
+  ProcessVoidEvent( new TEvent( flag ) );
+}
 
 /*!
   \brief Add string setting to the application preferences.
@@ -546,13 +932,14 @@ void SalomePyQt::addStringSetting( const QString& name, const QString& value, bo
   public:
     TEvent( const QString& name, const QString& value, bool autoValue ) 
       : myName( name ), myValue( value ), myAutoValue( autoValue ) {}
-    virtual void Execute() {
+    virtual void Execute()
+    {
       if ( SUIT_Session::session() ) {
         SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
-       QStringList sl = myName.split( ":", QString::SkipEmptyParts );
-       QString _sec = sl.count() > 1 ? sl[ 0 ].trimmed() : QString( DEFAULT_SECTION );
-       QString _nam = sl.count() > 1 ? sl[ 1 ].trimmed() : sl.count() > 0 ? sl[ 0 ].trimmed() : QString( "" );
-       if ( !_sec.isEmpty() && !_nam.isEmpty() )
+        QStringList sl = myName.split( ":", QString::SkipEmptyParts );
+        QString _sec = sl.count() > 1 ? sl[ 0 ].trimmed() : QString( DEFAULT_SECTION );
+        QString _nam = sl.count() > 1 ? sl[ 1 ].trimmed() : sl.count() > 0 ? sl[ 0 ].trimmed() : QString( "" );
+        if ( !_sec.isEmpty() && !_nam.isEmpty() )
           resMgr->setValue( _sec, _nam, myValue );
       }
     }
@@ -588,10 +975,10 @@ void SalomePyQt::addIntSetting( const QString& name, const int value, bool autoV
     {
       if ( SUIT_Session::session() ) {
         SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
-       QStringList sl = myName.split( ":", QString::SkipEmptyParts );
-       QString _sec = sl.count() > 1 ? sl[ 0 ].trimmed() : QString( DEFAULT_SECTION );
-       QString _nam = sl.count() > 1 ? sl[ 1 ].trimmed() : sl.count() > 0 ? sl[ 0 ].trimmed() : QString( "" );
-       if ( !_sec.isEmpty() && !_nam.isEmpty() )
+        QStringList sl = myName.split( ":", QString::SkipEmptyParts );
+        QString _sec = sl.count() > 1 ? sl[ 0 ].trimmed() : QString( DEFAULT_SECTION );
+        QString _nam = sl.count() > 1 ? sl[ 1 ].trimmed() : sl.count() > 0 ? sl[ 0 ].trimmed() : QString( "" );
+        if ( !_sec.isEmpty() && !_nam.isEmpty() )
           resMgr->setValue( _sec, _nam, myValue );
       }
     }
@@ -627,10 +1014,10 @@ void SalomePyQt::addDoubleSetting( const QString& name, const double value, bool
     {
       if ( SUIT_Session::session() ) {
         SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
-       QStringList sl = myName.split( ":", QString::SkipEmptyParts );
-       QString _sec = sl.count() > 1 ? sl[ 0 ].trimmed() : QString( DEFAULT_SECTION );
-       QString _nam = sl.count() > 1 ? sl[ 1 ].trimmed() : sl.count() > 0 ? sl[ 0 ].trimmed() : QString( "" );
-       if ( !_sec.isEmpty() && !_nam.isEmpty() )
+        QStringList sl = myName.split( ":", QString::SkipEmptyParts );
+        QString _sec = sl.count() > 1 ? sl[ 0 ].trimmed() : QString( DEFAULT_SECTION );
+        QString _nam = sl.count() > 1 ? sl[ 1 ].trimmed() : sl.count() > 0 ? sl[ 0 ].trimmed() : QString( "" );
+        if ( !_sec.isEmpty() && !_nam.isEmpty() )
           resMgr->setValue( _sec, _nam, myValue );
       }
     }
@@ -666,10 +1053,10 @@ void SalomePyQt::addBoolSetting( const QString& name, const bool value, bool aut
     {
       if ( SUIT_Session::session() ) {
         SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
-       QStringList sl = myName.split( ":", QString::SkipEmptyParts );
-       QString _sec = sl.count() > 1 ? sl[ 0 ].trimmed() : QString( DEFAULT_SECTION );
-       QString _nam = sl.count() > 1 ? sl[ 1 ].trimmed() : sl.count() > 0 ? sl[ 0 ].trimmed() : QString( "" );
-       if ( !_sec.isEmpty() && !_nam.isEmpty() )
+        QStringList sl = myName.split( ":", QString::SkipEmptyParts );
+        QString _sec = sl.count() > 1 ? sl[ 0 ].trimmed() : QString( DEFAULT_SECTION );
+        QString _nam = sl.count() > 1 ? sl[ 1 ].trimmed() : sl.count() > 0 ? sl[ 0 ].trimmed() : QString( "" );
+        if ( !_sec.isEmpty() && !_nam.isEmpty() )
           resMgr->setValue( _sec, _nam, myValue );
       }
     }
@@ -687,17 +1074,19 @@ void SalomePyQt::addBoolSetting( const QString& name, const bool value, bool aut
 */
 void SalomePyQt::removeSettings( const QString& name )
 {
-  class TEvent: public SALOME_Event {
+  class TEvent: public SALOME_Event
+  {
     QString myName;
   public:
     TEvent( const QString& name ) : myName( name ) {}
-    virtual void Execute() {
+    virtual void Execute()
+    {
       if ( SUIT_Session::session() ) {
         SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
-       QStringList sl = myName.split( ":", QString::SkipEmptyParts );
-       QString _sec = sl.count() > 1 ? sl[ 0 ].trimmed() : QString( DEFAULT_SECTION );
-       QString _nam = sl.count() > 1 ? sl[ 1 ].trimmed() : sl.count() > 0 ? sl[ 0 ].trimmed() : QString( "" );
-       if ( !_sec.isEmpty() && !_nam.isEmpty() )
+        QStringList sl = myName.split( ":", QString::SkipEmptyParts );
+        QString _sec = sl.count() > 1 ? sl[ 0 ].trimmed() : QString( DEFAULT_SECTION );
+        QString _nam = sl.count() > 1 ? sl[ 1 ].trimmed() : sl.count() > 0 ? sl[ 0 ].trimmed() : QString( "" );
+        if ( !_sec.isEmpty() && !_nam.isEmpty() )
           resMgr->remove( _sec, _nam );
       }
     }
@@ -741,26 +1130,87 @@ QString SalomePyQt::getSetting( const QString& name )
 }
 
 /*!
-  \brief Add double setting to the application preferences.
-  \param section resources file section name 
-  \param name setting name
-  \param value new setting value
+  \fn QString SalomePyQt::constant( const QString& name );
+  \brief Get constant's value from application's resource manager.
+
+  \param name name of the constant 
+  \return value of the constant
+
+  \sa setConstant()
 */
-void SalomePyQt::addSetting( const QString& section, const QString& name, const double value )
+
+class TGetConstantEvent: public SALOME_Event 
 {
-  class TEvent: public SALOME_Event 
+public:
+  typedef QString TResult;
+  TResult myResult;
+  QString myName;
+  TGetConstantEvent( const QString& name ) : myName( name ) {}
+  virtual void Execute() 
   {
-    QString mySection;
-    QString myName;
-    double  myValue;
-  public:
-    TEvent( const QString& section, const QString& name, double value ) 
-      : mySection( section ), myName( name ), myValue( value ) {}
-    virtual void Execute() 
-    {
+    if ( SUIT_Session::session() )
+      myResult = SUIT_Session::session()->resourceMgr()->constant( myName );
+  }
+};
+QString SalomePyQt::constant( const QString& name )
+{
+  return ProcessEvent( new TGetConstantEvent( name ) );
+}
+
+/*!
+  \brief Add constant to the application's resource manager.
+
+  This function is useful to specify programmatically specific
+  variables that are referenced in the resource setting.
+
+  For example, some resource value can be set as "$(myroot)/data/files".
+  Then, "mypath" constant can be set programmatically by the application
+  depending on run-time requirements.
+  
+  \param section resources file section name 
+  \param name name of the constant 
+  \param value value of the constant 
+
+  \sa constant()
+*/
+void SalomePyQt::setConstant( const QString& name, const QString& value )
+{
+  class TEvent: public SALOME_Event 
+  {
+    QString myName, myValue;
+  public:
+    TEvent( const QString& name, const QString& value ) 
+      : myName( name ), myValue( value ) {}
+    virtual void Execute() 
+    {
+      if ( SUIT_Session::session() )
+        SUIT_Session::session()->resourceMgr()->setConstant( myName, myValue );
+    }
+  };
+  ProcessVoidEvent( new TEvent( name, value ) );
+}
+
+/*!
+  \brief Add double setting to the application preferences.
+  \param section resources file section name 
+  \param name setting name
+  \param value new setting value
+*/
+void SalomePyQt::addSetting( const QString& section, const QString& name, const double value )
+{
+  class TEvent: public SALOME_Event 
+  {
+    QString mySection;
+    QString myName;
+    double  myValue;
+  public:
+    TEvent( const QString& section, const QString& name, double value ) 
+      : mySection( section ), myName( name ), myValue( value ) {}
+    virtual void Execute() 
+    {
       if ( SUIT_Session::session() ) {
         SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
-       if ( !mySection.isEmpty() && !myName.isEmpty() )
+        if ( !mySection.isEmpty() && !myName.isEmpty() )
           resMgr->setValue( mySection, myName, myValue );
       }
     }
@@ -788,7 +1238,7 @@ void SalomePyQt::addSetting( const QString& section, const QString& name, const
     {
       if ( SUIT_Session::session() ) {
         SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
-       if ( !mySection.isEmpty() && !myName.isEmpty() )
+        if ( !mySection.isEmpty() && !myName.isEmpty() )
           resMgr->setValue( mySection, myName, myValue );
       }
     }
@@ -818,7 +1268,7 @@ void SalomePyQt::addSetting( const QString& section, const QString& name, const
     {
       if ( SUIT_Session::session() ) {
         SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
-       if ( !mySection.isEmpty() && !myName.isEmpty() )
+        if ( !mySection.isEmpty() && !myName.isEmpty() )
           resMgr->setValue( mySection, myName, myValue );
       }
     }
@@ -846,7 +1296,7 @@ void SalomePyQt::addSetting( const QString& section, const QString& name, const
     {
       if ( SUIT_Session::session() ) {
         SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
-       if ( !mySection.isEmpty() && !myName.isEmpty() )
+        if ( !mySection.isEmpty() && !myName.isEmpty() )
           resMgr->setValue( mySection, myName, myValue );
       }
     }
@@ -874,7 +1324,63 @@ void SalomePyQt::addSetting( const QString& section, const QString& name, const
     {
       if ( SUIT_Session::session() ) {
         SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
-       if ( !mySection.isEmpty() && !myName.isEmpty() )
+        if ( !mySection.isEmpty() && !myName.isEmpty() )
+          resMgr->setValue( mySection, myName, myValue );
+      }
+    }
+  };
+  ProcessVoidEvent( new TEvent( section, name, value ) );
+}
+
+/*!
+  \brief Add byte array setting to the application preferences.
+  \param section resources file section name 
+  \param name setting name
+  \param value new setting value
+*/
+void SalomePyQt::addSetting( const QString& section, const QString& name, const QByteArray& value )
+{
+  class TEvent: public SALOME_Event 
+  {
+    QString    mySection;
+    QString    myName;
+    QByteArray myValue;
+  public:
+    TEvent( const QString& section, const QString& name, const QByteArray& value ) 
+      : mySection( section ), myName( name ), myValue( value ) {}
+    virtual void Execute() 
+    {
+      if ( SUIT_Session::session() ) {
+        SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
+        if ( !mySection.isEmpty() && !myName.isEmpty() )
+          resMgr->setValue( mySection, myName, myValue );
+      }
+    }
+  };
+  ProcessVoidEvent( new TEvent( section, name, value ) );
+}
+
+/*!
+  \brief Add font setting to the application preferences.
+  \param section resources file section name 
+  \param name setting name
+  \param value new setting value
+*/
+void SalomePyQt::addSetting( const QString& section, const QString& name, const QFont& value )
+{
+  class TEvent: public SALOME_Event 
+  {
+    QString    mySection;
+    QString    myName;
+    QFont      myValue;
+  public:
+    TEvent( const QString& section, const QString& name, const QFont& value ) 
+      : mySection( section ), myName( name ), myValue( value ) {}
+    virtual void Execute() 
+    {
+      if ( SUIT_Session::session() ) {
+        SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
+        if ( !mySection.isEmpty() && !myName.isEmpty() )
           resMgr->setValue( mySection, myName, myValue );
       }
     }
@@ -885,7 +1391,7 @@ void SalomePyQt::addSetting( const QString& section, const QString& name, const
 /*!
   \fn int SalomePyQt::integerSetting( const QString& section, 
                                       const QString& name, 
-                                     const int def );
+                                      const int def );
   \brief Get integer setting from the application preferences.
   \param section resources file section name 
   \param name setting name
@@ -919,7 +1425,7 @@ int SalomePyQt::integerSetting( const QString& section, const QString& name, con
 /*!
   \fn double SalomePyQt::doubleSetting( const QString& section, 
                                         const QString& name, 
-                                       const double def );
+                                        const double def );
   \brief Get double setting from the application preferences.
   \param section resources file section name 
   \param name setting name
@@ -953,7 +1459,7 @@ double SalomePyQt::doubleSetting( const QString& section, const QString& name, c
 /*!
   \fn bool SalomePyQt::boolSetting( const QString& section, 
                                     const QString& name, 
-                                   const bool def );
+                                    const bool def );
   \brief Get boolean setting from the application preferences.
   \param section resources file section name 
   \param name setting name
@@ -987,11 +1493,13 @@ bool SalomePyQt::boolSetting( const QString& section, const QString& name, const
 /*!
   \fn QString SalomePyQt::stringSetting( const QString& section, 
                                          const QString& name, 
-                                        const QString& def );
+                                         const QString& def, 
+                                         const bool subst );
   \brief Get string setting from the application preferences.
   \param section resources file section name 
   \param name setting name
   \param def default value which is returned if the setting is not found
+  \param subst \c true to make substitution, \c false to get "raw" value
   \return setting value
 */
 
@@ -1002,26 +1510,27 @@ public:
   TResult myResult;
   QString mySection;
   QString myName;
+  bool mySubst;
   TResult myDefault;
-  TGetStrSettingEvent( const QString& section, const QString& name, const QString& def ) 
-    : mySection( section ), myName( name ), myDefault( def ) {}
+  TGetStrSettingEvent( const QString& section, const QString& name, const QString& def, const bool subst ) 
+    : mySection( section ), myName( name ), myDefault( def ), mySubst( subst ) {}
   virtual void Execute() 
   {
     if ( SUIT_Session::session() ) {
       SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
-      myResult = ( !mySection.isEmpty() && !myName.isEmpty() ) ? resMgr->stringValue( mySection, myName, myDefault ) : myDefault;
+      myResult = ( !mySection.isEmpty() && !myName.isEmpty() ) ? resMgr->stringValue( mySection, myName, myDefault, mySubst ) : myDefault;
     }
   }
 };
-QString SalomePyQt::stringSetting( const QString& section, const QString& name, const QString& def )
+QString SalomePyQt::stringSetting( const QString& section, const QString& name, const QString& def, const bool subst )
 {
-  return ProcessEvent( new TGetStrSettingEvent( section, name, def ) );
+  return ProcessEvent( new TGetStrSettingEvent( section, name, def, subst ) );
 }
 
 /*!
   \fn QColor SalomePyQt::colorSetting( const QString& section, 
                                        const QString& name, 
-                                      const QColor def );
+                                       const QColor def );
   \brief Get color setting from the application preferences.
   \param section resources file section name 
   \param name setting name
@@ -1052,6 +1561,74 @@ QColor SalomePyQt::colorSetting ( const QString& section, const QString& name, c
   return ProcessEvent( new TGetColorSettingEvent( section, name, def ) );
 }
 
+/*!
+  \fn QByteArray SalomePyQt::byteArraySetting( const QString& section, 
+                                               const QString& name, 
+                                               const QByteArray& def );
+  \brief Get byte array setting from the application preferences.
+  \param section resources file section name 
+  \param name setting name
+  \param def default value which is returned if the setting is not found
+  \return setting value
+*/
+
+class TGetByteArraySettingEvent: public SALOME_Event 
+{
+public:
+  typedef QByteArray TResult;
+  TResult myResult;
+  QString mySection;
+  QString myName;
+  TResult myDefault;
+  TGetByteArraySettingEvent( const QString& section, const QString& name, const QByteArray& def ) 
+    : mySection( section ), myName( name ), myDefault( def ) {}
+  virtual void Execute() 
+  {
+    if ( SUIT_Session::session() ) {
+      SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
+      myResult = ( !mySection.isEmpty() && !myName.isEmpty() ) ? resMgr->byteArrayValue( mySection, myName, myDefault ) : myDefault;
+    }
+  }
+};
+QByteArray SalomePyQt::byteArraySetting ( const QString& section, const QString& name, const QByteArray& def )
+{
+  return ProcessEvent( new TGetByteArraySettingEvent( section, name, def ) );
+}
+
+/*!
+  \fn QByteArray SalomePyQt::fontSetting( const QString& section, 
+                                          const QString& name, 
+                                          const QFont& def );
+  \brief Get font setting from the application preferences.
+  \param section resources file section name 
+  \param name setting name
+  \param def default value which is returned if the setting is not found
+  \return setting value
+*/
+
+class TGetFontSettingEvent: public SALOME_Event 
+{
+public:
+  typedef QFont TResult;
+  TResult myResult;
+  QString mySection;
+  QString myName;
+  TResult myDefault;
+  TGetFontSettingEvent( const QString& section, const QString& name, const QFont& def ) 
+    : mySection( section ), myName( name ), myDefault( def ) {}
+  virtual void Execute() 
+  {
+    if ( SUIT_Session::session() ) {
+      SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
+      myResult = ( !mySection.isEmpty() && !myName.isEmpty() ) ? resMgr->fontValue( mySection, myName, myDefault ) : myDefault;
+    }
+  }
+};
+QFont SalomePyQt::fontSetting ( const QString& section, const QString& name, const QFont& def )
+{
+  return ProcessEvent( new TGetFontSettingEvent( section, name, def ) );
+}
+
 /*!
   \brief Remove setting from the application preferences.
   \param section resources file section name 
@@ -1069,7 +1646,7 @@ void SalomePyQt::removeSetting( const QString& section, const QString& name )
     {
       if ( SUIT_Session::session() ) {
         SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
-       if ( !mySection.isEmpty() && !myName.isEmpty() )
+        if ( !mySection.isEmpty() && !myName.isEmpty() )
           resMgr->remove( mySection, myName );
       }
     }
@@ -1085,14 +1662,14 @@ void SalomePyQt::removeSetting( const QString& section, const QString& name )
   \return \c true if setting exists
 */
 
-class THasColorSettingEvent: public SALOME_Event 
+class THasSettingEvent: public SALOME_Event 
 {
 public:
   typedef bool TResult;
   TResult myResult;
   QString mySection;
   QString myName;
-  THasColorSettingEvent( const QString& section, const QString& name ) 
+  THasSettingEvent( const QString& section, const QString& name ) 
     : mySection( section ), myName( name ) {}
   virtual void Execute() 
   {
@@ -1104,15 +1681,59 @@ public:
 };
 bool SalomePyQt::hasSetting( const QString& section, const QString& name )
 {
-  return ProcessEvent( new THasColorSettingEvent( section, name ) );
+  return ProcessEvent( new THasSettingEvent( section, name ) );
+}
+
+/*!
+  \fn QStringList SalomePyQt::parameters( const QString& section );
+  \brief Get names of preference items stored within the given section.
+  \param section resources file section's name 
+  \return \c list of preferences items
+*/
+
+/*!
+  \fn QStringList SalomePyQt::parameters( const QStringList& section );
+  \brief Get names of preference items stored within the given section.
+  \param section resources file section's name 
+  \return \c list of preferences items
+*/
+
+class TParametersEvent: public SALOME_Event 
+{
+public:
+  typedef QStringList TResult;
+  TResult myResult;
+  QStringList mySection;
+  TParametersEvent( const QString& section ) 
+  {
+    mySection << section;
+  }
+  TParametersEvent( const QStringList& section ) 
+    : mySection( section )
+  {}
+  virtual void Execute() 
+  {
+    if ( SUIT_Session::session() ) {
+      SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
+      myResult = resMgr->parameters( mySection );
+    }
+  }
+};
+QStringList SalomePyQt::parameters( const QString& section )
+{
+  return ProcessEvent( new TParametersEvent( section ) );
+}
+QStringList SalomePyQt::parameters( const QStringList& section )
+{
+  return ProcessEvent( new TParametersEvent( section ) );
 }
 
 /*!
   \fn QString SalomePyQt::getFileName( QWidget*           parent, 
-                                      const QString&     initial, 
-                                      const QStringList& filters, 
-                                      const QString&     caption,
-                                      bool               open );
+                                       const QString&     initial, 
+                                       const QStringList& filters, 
+                                       const QString&     caption,
+                                       bool               open );
   \brief Show 'Open/Save file' dialog box for file selection 
          and return a user's choice (selected file name).
   \param parent parent widget
@@ -1135,10 +1756,10 @@ public:
   QString     myCaption;
   bool        myOpen;
   TGetFileNameEvent( QWidget*           parent, 
-                    const QString&     initial, 
-                    const QStringList& filters, 
-                    const QString&     caption,
-                    bool               open ) 
+                     const QString&     initial, 
+                     const QStringList& filters, 
+                     const QString&     caption,
+                     bool               open ) 
     : myParent ( parent ), 
       myInitial( initial ), 
       myFilters( filters ), 
@@ -1146,26 +1767,26 @@ public:
       myOpen ( open ) {}
   virtual void Execute() 
   {
-    if ( SalomeApp_Application* anApp = getApplication() ) {
+    if ( LightApp_Application* anApp = getApplication() ) {
       myResult = anApp->getFileName( myOpen, myInitial, myFilters.join(";;"), 
-                                    myCaption, myParent );
+                                     myCaption, myParent );
     }
   }
 };
 QString SalomePyQt::getFileName( QWidget*           parent, 
-                                const QString&     initial, 
-                                const QStringList& filters, 
-                                const QString&     caption,
-                                bool               open )
+                                 const QString&     initial, 
+                                 const QStringList& filters, 
+                                 const QString&     caption,
+                                 bool               open )
 {
   return ProcessEvent( new TGetFileNameEvent( parent, initial, filters, caption, open ) );
 }
 
 /*!
   \fn QStringList SalomePyQt::getOpenFileNames( QWidget*           parent, 
-                                               const QString&     initial, 
-                                               const QStringList& filters, 
-                                               const QString&     caption );
+                                                const QString&     initial, 
+                                                const QStringList& filters, 
+                                                const QString&     caption );
   \brief Show 'Open files' dialog box for multiple files selection
          and return a user's choice (selected file names list).
   \param parent parent widget
@@ -1185,32 +1806,32 @@ public:
   QStringList myFilters;
   QString     myCaption;
   TGetOpenFileNamesEvent( QWidget*           parent, 
-                         const QString&     initial, 
-                         const QStringList& filters, 
-                         const QString&     caption ) 
+                          const QString&     initial, 
+                          const QStringList& filters, 
+                          const QString&     caption ) 
     : myParent ( parent ), 
       myInitial( initial ), 
       myFilters( filters ), 
       myCaption( caption ) {}
   virtual void Execute() 
   {
-    if ( SalomeApp_Application* anApp = getApplication() ) {
+    if ( LightApp_Application* anApp = getApplication() ) {
       myResult = anApp->getOpenFileNames( myInitial, myFilters.join(";;"), myCaption, myParent );
     }
   }
 };
 QStringList SalomePyQt::getOpenFileNames( QWidget*           parent, 
-                                         const QString&     initial, 
-                                         const QStringList& filters, 
-                                         const QString&     caption )
+                                          const QString&     initial, 
+                                          const QStringList& filters, 
+                                          const QString&     caption )
 {
   return ProcessEvent( new TGetOpenFileNamesEvent( parent, initial, filters, caption ) );
 }
 
 /*!
   \fn QString SalomePyQt::getExistingDirectory( QWidget*       parent,
-                                               const QString& initial,
-                                               const QString& caption );
+                                                const QString& initial,
+                                                const QString& caption );
   \brief Show 'Get Directory' dialog box for the directory selection
          and return a user's choice (selected directory name).
   \param parent parent widget
@@ -1228,25 +1849,52 @@ public:
   QString     myInitial;
   QString     myCaption;
   TGetExistingDirectoryEvent( QWidget*           parent, 
-                             const QString&     initial, 
-                             const QString&     caption ) 
+                              const QString&     initial, 
+                              const QString&     caption ) 
     : myParent ( parent ), 
       myInitial( initial ), 
       myCaption( caption ) {}
   virtual void Execute() 
   {
-    if ( SalomeApp_Application* anApp = getApplication() ) {
+    if ( LightApp_Application* anApp = getApplication() ) {
       myResult = anApp->getDirectory( myInitial, myCaption, myParent );
     }
   }
 };
 QString SalomePyQt::getExistingDirectory( QWidget*       parent,
-                                         const QString& initial,
-                                         const QString& caption )
+                                          const QString& initial,
+                                          const QString& caption )
 {
   return ProcessEvent( new TGetExistingDirectoryEvent( parent, initial, caption ) );
 }
 
+/*!
+  \fn QString SalomePyQt::loadIcon( const QString& filename );
+  \brief Load an icon from the module resources by the specified file name.
+  \param fileName icon file name
+  \return icon object
+*/
+
+class TLoadIconEvent: public SALOME_Event 
+{
+public:
+  typedef QIcon TResult;
+  TResult     myResult;
+  QString     myModule;
+  QString     myFileName;
+  TLoadIconEvent( const QString& module, const QString& filename ) 
+    : myModule( module ), 
+      myFileName ( filename ) {}
+  virtual void Execute() 
+  {
+    myResult = loadIconInternal( myModule, myFileName );
+  }
+};
+QIcon SalomePyQt::loadIcon( const QString& module, const QString& filename )
+{
+  return ProcessEvent( new TLoadIconEvent( module, filename ) );
+}
+
 /*!
   \brief Open external browser to display context help information.
   \todo
@@ -1267,7 +1915,7 @@ void SalomePyQt::helpContext( const QString& source, const QString& context )
       : mySource( source ), myContext( context ) {}
     virtual void Execute() 
     {
-      if ( SalomeApp_Application* anApp = getApplication() ) {
+      if ( LightApp_Application* anApp = getApplication() ) {
         anApp->onHelpContextModule( "", mySource, myContext );
       }
     }
@@ -1275,51 +1923,6 @@ void SalomePyQt::helpContext( const QString& source, const QString& context )
   ProcessVoidEvent( new TEvent( source, context ) );
 }
 
-/*!
-  \fn bool SalomePyQt::dumpView( const QString& filename );
-  \brief Dump the contents of the currently active view window 
-  to the image file in the specified format.
-
-  For the current moment JPEG, PNG and BMP images formats are supported.
-  The image format is defined automatically by the file name extension.
-  By default, BMP format is used.
-
-  \param filename image file name
-  \return operation status (\c true on success)
-*/
-
-class TDumpViewEvent: public SALOME_Event 
-{
-public:
-  typedef bool TResult;
-  TResult myResult;
-  QString myFileName;
-  TDumpViewEvent( const QString& filename ) 
-    : myResult ( false ), myFileName( filename ) {}
-  virtual void Execute() 
-  {
-    if ( SalomeApp_Application* anApp = getApplication() ) {
-      SUIT_ViewManager* vm = anApp->activeViewManager();
-      if ( vm ) { 
-        SUIT_ViewWindow* vw = vm->getActiveView();
-       if ( vw ) {
-          QImage im = vw->dumpView();
-         if ( !im.isNull() && !myFileName.isEmpty() ) {
-            QString fmt = SUIT_Tools::extension( myFileName ).toUpper();
-           if ( fmt.isEmpty() ) fmt = QString( "BMP" ); // default format
-           if ( fmt == "JPG" )  fmt = "JPEG";
-           myResult = im.save( myFileName, fmt.toLatin1() );
-          }
-       }
-      }
-    }
-  }
-};
-bool SalomePyQt::dumpView( const QString& filename )
-{
-  return ProcessEvent( new TDumpViewEvent( filename ) );
-}
-
 /*!
   \fn int SalomePyQt::defaultMenuGroup();
   \brief Get detault menu group identifier which can be used when 
@@ -1335,7 +1938,7 @@ public:
   TDefMenuGroupEvent() : myResult( -1 ) {}
   virtual void Execute() 
   {
-    myResult = SALOME_PYQT_Module::defaultMenuGroup();
+    myResult = PyModuleHelper::defaultMenuGroup();
   }
 };
 int SalomePyQt::defaultMenuGroup()
@@ -1346,37 +1949,38 @@ int SalomePyQt::defaultMenuGroup()
 class CrTool
 {
 public:
-  CrTool( const QString& tBar ) 
-    : myCase( 0 ), myTbName( tBar ) {}
+  CrTool( const QString& tBar, const QString& nBar ) 
+    : myCase( 0 ), myTbTitle( tBar ), myTbName( nBar)  {}
   CrTool( const int id, const int tBar, const int idx ) 
     : myCase( 1 ), myId( id ), myTbId( tBar ), myIndex( idx ) {}
   CrTool( const int id, const QString& tBar, const int idx )
-    : myCase( 2 ), myId( id ), myTbName( tBar ), myIndex( idx ) {}
+    : myCase( 2 ), myId( id ), myTbTitle( tBar ), myIndex( idx ) {}
   CrTool( QAction* action, const int tbId, const int id, const int idx )
     : myCase( 3 ), myAction( action ), myTbId( tbId ), myId( id ), myIndex( idx ) {}
   CrTool( QAction* action, const QString& tBar, const int id, const int idx )
-    : myCase( 4 ), myAction( action ), myTbName( tBar ), myId( id ), myIndex( idx ) {}
+    : myCase( 4 ), myAction( action ), myTbTitle( tBar ), myId( id ), myIndex( idx ) {}
 
-  int execute( SALOME_PYQT_Module* module ) const
+  int execute( LightApp_Module* module ) const
   {
     if ( module ) {
       switch ( myCase ) {
       case 0:
-        return module->createTool( myTbName );
+        return module->createTool( myTbTitle, myTbName );
       case 1:
         return module->createTool( myId, myTbId, myIndex );
       case 2:
-        return module->createTool( myId, myTbName, myIndex );
+        return module->createTool( myId, myTbTitle, myIndex );
       case 3:
         return module->createTool( myAction, myTbId, myId, myIndex );
       case 4:
-        return module->createTool( myAction, myTbName, myId, myIndex );
+        return module->createTool( myAction, myTbTitle, myId, myIndex );
       }
     }
     return -1;
   }
 private:
    int        myCase;
+   QString    myTbTitle;
    QString    myTbName;
    int        myTbId;
    QAction*   myAction;
@@ -1394,7 +1998,7 @@ public:
     : myResult( -1 ), myCrTool( crTool ) {}
   virtual void Execute() 
   {
-    SALOME_PYQT_Module* module = getActiveModule();
+    LightApp_Module* module = getActiveModule();
     if ( module )
       myResult = myCrTool.execute( module );
   }
@@ -1402,12 +2006,13 @@ public:
 
 /*!
   \brief Create toolbar with specified name.
-  \param tBar toolbar name
+  \param tBar toolbar title (language-dependent)
+  \param nBar toolbar name (language-independent) [optional]
   \return toolbar ID or -1 if toolbar creation is failed
 */
-int SalomePyQt::createTool( const QString& tBar )
+int SalomePyQt::createTool( const QString& tBar, const QString& nBar )
 {
-  return ProcessEvent( new TCreateToolEvent( CrTool( tBar ) ) );
+  return ProcessEvent( new TCreateToolEvent( CrTool( tBar, nBar ) ) );
 }
 
 /*! 
@@ -1476,7 +2081,7 @@ public:
   CrMenu( QAction* action, const QString& menu, const int id, const int group, const int idx ) 
     : myCase( 5 ), myAction( action ), myMenuName( menu ), myId( id ), myGroup( group ), myIndex( idx ) {}
 
-  int execute( SALOME_PYQT_Module* module ) const
+  int execute( LightApp_Module* module ) const
   {
     if ( module ) {
       switch ( myCase ) {
@@ -1517,7 +2122,7 @@ public:
     : myResult( -1 ), myCrMenu( crMenu ) {}
   virtual void Execute()
   {
-    SALOME_PYQT_Module* module = getActiveModule();
+    LightApp_Module* module = getActiveModule();
     if ( module )
       myResult = myCrMenu.execute( module );
   }
@@ -1618,7 +2223,7 @@ public:
     : myResult( 0 ) {}
   virtual void Execute() 
   {
-    SALOME_PYQT_Module* module = getActiveModule();
+    LightApp_Module* module = getActiveModule();
     if ( module )
       myResult = (QAction*)module->separator();
   }
@@ -1630,12 +2235,12 @@ QAction* SalomePyQt::createSeparator()
 
 /*!
   \fn QAction* SalomePyQt::createAction( const int      id,
-                                           const QString& menuText, 
-                                          const QString& tipText, 
-                                          const QString& statusText, 
-                                          const QString& icon,
-                                          const int      key, 
-                                          const bool     toggle )
+                                         const QString& menuText, 
+                                         const QString& tipText, 
+                                         const QString& statusText, 
+                                         const QString& icon,
+                                         const int      key, 
+                                         const bool     toggle );
   \brief Create an action which can be then used in the menu or toolbar.
   \param id the unique id action to be registered to
   \param menuText action text which should appear in menu
@@ -1659,51 +2264,74 @@ public:
   int     myKey;
   bool    myToggle;
   TCreateActionEvent( const int id, const QString& menuText, const QString& tipText, 
-                     const QString& statusText, const QString& icon, const int key, const bool toggle ) 
+                      const QString& statusText, const QString& icon, const int key, const bool toggle ) 
     : myResult( 0 ), myId( id ), myMenuText( menuText ), myTipText( tipText ),
       myStatusText( statusText ), myIcon( icon ), myKey( key ), myToggle( toggle ) {}
   virtual void Execute()
   {
-    SALOME_PYQT_Module* module = getActiveModule();
-    if ( module )
-      myResult = (QAction*)module->createAction( myId, myTipText, myIcon, myMenuText, myStatusText, myKey, myToggle );
+    LightApp_Module* module = getActiveModule();
+    if ( module ) {
+      QIcon icon = loadIconInternal( module->name(), myIcon );
+      myResult = (QAction*)module->action( myId );
+      if ( myResult ) {
+       if ( myResult->toolTip().isEmpty() && !myTipText.isEmpty() ) 
+         myResult->setToolTip( myTipText );
+       if ( myResult->text().isEmpty() && !myMenuText.isEmpty() )
+         myResult->setText( myMenuText );
+       if ( myResult->icon().isNull() && !icon.isNull() ) 
+         myResult->setIcon( icon );
+       if ( myResult->statusTip().isEmpty() && !myStatusText.isEmpty() )
+         myResult->setStatusTip( myStatusText );
+       if ( myResult->shortcut().isEmpty() && myKey )
+         myResult->setShortcut( myKey );
+       if ( myResult->isCheckable() != myToggle )
+         myResult->setCheckable( myToggle );
+      }
+      else {
+       myResult = (QAction*)module->createAction( myId, myTipText, icon, myMenuText, myStatusText, myKey, module, myToggle );
+      }
+      // for Python module, automatically connect action to callback slot
+      PyModuleHelper* helper = module->findChild<PyModuleHelper*>( "python_module_helper" );
+      if ( helper ) helper->connectAction( myResult );
+    }
   }
 };
 QAction* SalomePyQt::createAction( const int id,           const QString& menuText, 
-                                    const QString& tipText, const QString& statusText, 
-                                    const QString& icon,    const int key, const bool toggle )
+                                  const QString& tipText, const QString& statusText, 
+                                  const QString& icon,    const int key, const bool toggle )
 {
   return ProcessEvent( new TCreateActionEvent( id, menuText, tipText, statusText, icon, key, toggle ) );
 }
 
 /*!
-  \fn QtxActionGroup* SalomePyQt::createActionGroup( const int id, const bool exclusive )
+  \fn QtxActionGroup* SalomePyQt::createActionGroup( const int id, const bool exclusive );
   \brief Create an action group which can be then used in the menu or toolbar
   \param id         : the unique id action group to be registered to
   \param exclusive  : if \c true the action group does exclusive toggling
 */
 
-struct TcreateActionGroupEvent: public SALOME_Event {
+struct TCreateActionGroupEvent: public SALOME_Event 
+{
   typedef QtxActionGroup* TResult;
   TResult myResult;
   int     myId;
   bool    myExclusive;
-  TcreateActionGroupEvent( const int id, const bool exclusive )
+  TCreateActionGroupEvent( const int id, const bool exclusive )
     : myId( id ), myExclusive( exclusive ) {}
   virtual void Execute()
   {
-    SALOME_PYQT_Module* module = getActiveModule();
+    LightApp_Module* module = getActiveModule();
     if ( module )
       myResult = module->createActionGroup( myId, myExclusive );
   }
 };
-QtxActionGroup* SalomePyQt::createActionGroup(const int id, const bool exclusive)
+QtxActionGroup* SalomePyQt::createActionGroup( const int id, const bool exclusive )
 {
-  return ProcessEvent( new TcreateActionGroupEvent( id, exclusive ) );
+  return ProcessEvent( new TCreateActionGroupEvent( id, exclusive ) );
 }
 
 /*!
-  \fn QAction* SalomePyQt::action( const int id )
+  \fn QAction* SalomePyQt::action( const int id );
   \brief Get action by specified identifier.
   \return action or 0 if action is not registered
 */
@@ -1718,7 +2346,7 @@ public:
     : myResult( 0 ), myId( id ) {}
   virtual void Execute()
   {
-    SALOME_PYQT_Module* module = getActiveModule();
+    LightApp_Module* module = getActiveModule();
     if ( module )
       myResult = (QAction*)module->action( myId );
   }
@@ -1744,7 +2372,7 @@ public:
     : myResult( -1 ), myAction( action ) {}
   virtual void Execute()
   {
-    SALOME_PYQT_Module* module = getActiveModule();
+    LightApp_Module* module = getActiveModule();
     if ( module )
       myResult = module->actionId( myAction );
   }
@@ -1771,9 +2399,12 @@ public:
     : myResult( -1 ), myLabel( label ) {}
   virtual void Execute() 
   {
-    SALOME_PYQT_Module* module = getActiveModule();
-    if ( module )
-      myResult = module->addGlobalPreference( myLabel );
+    LightApp_Module* module = getActiveModule();
+    if ( module ) {
+      LightApp_Preferences* pref = module->getApp()->preferences();
+      if ( pref )
+       myResult = pref->addPreference( myLabel, -1 );
+    }
   }
 };
 int SalomePyQt::addGlobalPreference( const QString& label )
@@ -1798,9 +2429,15 @@ public:
     : myResult( -1 ), myLabel( label ) {}
   virtual void Execute() 
   {
-    SALOME_PYQT_Module* module = getActiveModule();
-    if ( module )
-      myResult = module->addPreference( myLabel );
+    LightApp_Module* module = getActiveModule();
+    if ( module ) {
+      LightApp_Preferences* pref = module->getApp()->preferences();
+      if ( pref ) {
+       int cId = pref->addPreference( module->moduleName(), -1 );
+       if ( cId != -1 )
+         myResult = pref->addPreference( myLabel, cId );
+      }
+    }
   }
 };
 int SalomePyQt::addPreference( const QString& label )
@@ -1810,7 +2447,7 @@ int SalomePyQt::addPreference( const QString& label )
 
 /*!
   \fn int SalomePyQt::addPreference( const QString& label, const int pId, const int type,
-                                    const QString& section, const QString& param );
+                                     const QString& section, const QString& param );
   \brief Add module-related preferences.
   \param label preferences group name
   \param pId parent preferences group id
@@ -1831,21 +2468,24 @@ public:
   QString mySection;
   QString myParam;
   TAddPrefParamEvent( const QString& label, 
-                     const int pId, const int type,
-                     const QString& section, 
-                     const QString& param )
+                      const int pId, const int type,
+                      const QString& section, 
+                      const QString& param )
     : myResult( -1 ),
       myLabel( label ), myPId( pId ), myType( type ), 
       mySection( section ), myParam ( param ) {}
   virtual void Execute()
   {
-    SALOME_PYQT_Module* module = getActiveModule();
-    if ( module )
-      myResult = module->addPreference( myLabel, myPId, myType, mySection, myParam );
+    LightApp_Module* module = getActiveModule();
+    if ( module ) {
+      LightApp_Preferences* pref = module->getApp()->preferences();
+      if ( pref )
+       myResult = pref->addPreference( module->moduleName(), myLabel, myPId, myType, mySection, myParam );
+    }
   }
 };
 int SalomePyQt::addPreference( const QString& label, const int pId, const int type,
-                              const QString& section, const QString& param )
+                               const QString& section, const QString& param )
 {
   return ProcessEvent( new TAddPrefParamEvent( label, pId, type, section, param ) );
 }
@@ -1869,9 +2509,12 @@ public:
     : myId( id ), myProp( prop ) {}
   virtual void Execute()
   {
-    SALOME_PYQT_Module* module = getActiveModule();
-    if ( module )
-      myResult = module->preferenceProperty( myId, myProp );
+    LightApp_Module* module = getActiveModule();
+    if ( module ) {
+      LightApp_Preferences* pref = module->getApp()->preferences();
+      if ( pref )
+       myResult = pref->itemProperty( myProp, myId );
+    }
   }
 };
 QVariant SalomePyQt::preferenceProperty( const int id, const QString& prop )
@@ -1886,8 +2529,8 @@ QVariant SalomePyQt::preferenceProperty( const int id, const QString& prop )
   \param var preferences property value
 */
 void SalomePyQt::setPreferenceProperty( const int id, 
-                                       const QString& prop,
-                                       const QVariant& var )
+                                        const QString& prop,
+                                        const QVariant& var )
 {
   class TEvent: public SALOME_Event
   {
@@ -1899,12 +2542,47 @@ void SalomePyQt::setPreferenceProperty( const int id,
       : myId( id ), myProp( prop ), myVar( var ) {}
     virtual void Execute() 
     {
-      SALOME_PYQT_Module* module = getActiveModule();
-      if ( module )
-       module->setPreferenceProperty( myId, myProp, myVar );
+      LightApp_Module* module = getActiveModule();
+      if ( module ) {
+       LightApp_Preferences* pref = module->getApp()->preferences();
+       if ( pref )
+         pref->setItemProperty( myProp, myVar, myId );
+      }
+    }
+  };
+  ProcessVoidEvent( new TEvent( id, prop, var ) );
+}
+
+/*!
+  \brief Set specific widget as a custom preferences item.
+  \param id preferences identifier
+  \param prop preferences property name
+  \param widget custom widget
+*/
+void SalomePyQt::setPreferencePropertyWg( const int id, 
+                                          const QString& prop,
+                                          UserDefinedContent* widget )
+{
+  class TEvent: public SALOME_Event
+  {
+    int      myId;
+    QString  myProp;
+    UserDefinedContent* myWidget;
+  public:
+    TEvent( const int id, const QString& prop, UserDefinedContent* widget ) 
+      : myId( id ), myProp( prop ), myWidget( widget ) {}
+    virtual void Execute() 
+    {
+      LightApp_Module* module = getActiveModule();
+      if ( module ) {
+       LightApp_Preferences* pref = module->getApp()->preferences();
+       if ( pref ) {
+         pref->setItemProperty( myProp, (qint64) new SgPyQtUserDefinedContent( myWidget ), myId );
+        }
+      }
     }
   };
-  ProcessVoidEvent( new TEvent( id, prop, var) );
+  ProcessVoidEvent( new TEvent( id, prop, widget ) );
 }
 
 /*!
@@ -1919,9 +2597,9 @@ void SalomePyQt::setPreferenceProperty( const int id,
   \param var preferences property value for the index \a idx
 */
 void SalomePyQt::addPreferenceProperty( const int id, 
-                                       const QString& prop,
-                                       const int idx, 
-                                       const QVariant& var )
+                                        const QString& prop,
+                                        const int idx, 
+                                        const QVariant& var )
 {
   class TEvent: public SALOME_Event
   {
@@ -1934,32 +2612,35 @@ void SalomePyQt::addPreferenceProperty( const int id,
       : myId( id ), myProp( prop ), myIdx( idx), myVar( var ) {}
     virtual void Execute()
     {
-      SALOME_PYQT_Module* module = getActiveModule();
+      LightApp_Module* module = getActiveModule();
       if ( module ) {
-       QVariant var =  module->preferenceProperty( myId, myProp );
-       if ( var.isValid() ) {
-         if ( var.type() == QVariant::StringList ) {
-           QStringList sl = var.toStringList();
-           if ( myIdx >= 0 && myIdx < sl.count() ) 
-             sl[myIdx] = myVar.toString();
-           else
-             sl.append( myVar.toString() );
-           module->setPreferenceProperty( myId, myProp, sl );
+       LightApp_Preferences* pref = module->getApp()->preferences();
+       if ( pref ) {
+         QVariant var =  pref->itemProperty( myProp, myId );
+         if ( var.isValid() ) {
+           if ( var.type() == QVariant::StringList ) {
+             QStringList sl = var.toStringList();
+             if ( myIdx >= 0 && myIdx < sl.count() ) 
+               sl[myIdx] = myVar.toString();
+             else
+               sl.append( myVar.toString() );
+             pref->setItemProperty( myProp, sl, myId );
+           }
+           else if ( var.type() == QVariant::List ) {
+             QList<QVariant> vl = var.toList();
+             if ( myIdx >= 0 && myIdx < vl.count() ) 
+               vl[myIdx] = myVar;
+             else
+               vl.append( myVar );
+             pref->setItemProperty( myProp, vl, myId );
+           }
          }
-         else if ( var.type() == QVariant::List ) {
-           QList<QVariant> vl = var.toList();
-           if ( myIdx >= 0 && myIdx < vl.count() ) 
-             vl[myIdx] = myVar;
-           else
-             vl.append( myVar );
-           module->setPreferenceProperty( myId, myProp, vl );
+         else {
+           QList<QVariant> vl;
+           vl.append( myVar );
+           pref->setItemProperty( myProp, vl, myId );
          }
        }
-       else {
-         QList<QVariant> vl;
-         vl.append( myVar );
-         module->setPreferenceProperty( myId, myProp, vl );
-       }
       }
     }
   };
@@ -1983,10 +2664,10 @@ void SalomePyQt::message( const QString& msg, bool addSeparator )
       : myMsg( msg ), myAddSep( addSeparator ) {}
     virtual void Execute()
     {
-      if ( SalomeApp_Application* anApp = getApplication() ) {
-       LogWindow* lw = anApp->logWindow();
-       if ( lw )
-         lw->putMessage( myMsg, myAddSep );
+      if ( LightApp_Application* anApp = getApplication() ) {
+        LogWindow* lw = anApp->logWindow();
+        if ( lw )
+          lw->putMessage( myMsg, myAddSep );
       }
     }
   };
@@ -2004,10 +2685,10 @@ void SalomePyQt::clearMessages()
     TEvent() {}
     virtual void Execute()
     {
-      if ( SalomeApp_Application* anApp = getApplication() ) {
-       LogWindow* lw = anApp->logWindow();
-       if ( lw )
-         lw->clear();
+      if ( LightApp_Application* anApp = getApplication() ) {
+        LogWindow* lw = anApp->logWindow();
+        if ( lw )
+          lw->clear();
       }
     }
   };
@@ -2015,39 +2696,71 @@ void SalomePyQt::clearMessages()
 }
 
 /*!
-  \brief Gets window with specified identifier 
-  \internal
-  \param id window identifier 
-  \return pointer on the window
-*/
-static SUIT_ViewWindow* getWnd( const int id )
-{
-  SUIT_ViewWindow* resWnd = 0;
+  \fn bool SalomePyQt::dumpView( const QString& filename, const int id = 0 );
+  \brief Dump the contents of the id view window. If id is 0 then current active view is processed. 
+  to the image file in the specified format.
 
-  SalomeApp_Application* app  = getApplication();
-  if ( app )
-  {
-    STD_TabDesktop* tabDesk = dynamic_cast<STD_TabDesktop*>( app->desktop() );
-    if ( tabDesk )
-    {
-      QList<SUIT_ViewWindow*> wndlist = tabDesk->windows();
-      SUIT_ViewWindow* wnd;
-      foreach ( wnd, wndlist )
-      {
-        if ( id == wnd->getId() )
-        {
-          resWnd = wnd;
-          break;
-        }
-      }
-    }
-  }
+  For the current moment JPEG, PNG and BMP images formats are supported.
+  The image format is defined automatically by the file name extension.
+  By default, BMP format is used.
 
-  return resWnd;
+  \param filename image file name
+  \return operation status (\c true on success)
+*/
+
+class TDumpViewEvent: public SALOME_Event 
+{
+public:
+  typedef bool TResult;
+  TResult myResult;
+  QString myFileName;
+  int myWndId;
+  TDumpViewEvent( const QString& filename, const int id ) 
+    : myResult ( false ), myFileName( filename ), myWndId( id ) {}
+  virtual void Execute() 
+  {
+    SUIT_ViewWindow* wnd = 0;
+    if ( !myWndId ) {
+      if ( LightApp_Application* anApp = getApplication() ) {
+        SUIT_ViewManager* vm = anApp->activeViewManager();
+        if ( vm )
+          wnd = vm->getActiveView();
+      }
+      myWndId = wnd->getId();
+    }
+    else {
+      wnd = dynamic_cast<SUIT_ViewWindow*>( getWnd( myWndId ) );
+    }
+    if ( wnd ) {
+      QString fmt = SUIT_Tools::extension( myFileName ).toUpper();
+#ifndef DISABLE_PLOT2DVIEWER
+      Plot2d_ViewWindow* wnd2D = dynamic_cast<Plot2d_ViewWindow*>( wnd );
+      if ( wnd2D ) {
+        qApp->postEvent( wnd2D->getViewFrame(), new QPaintEvent( QRect( 0, 0, wnd2D->getViewFrame()->width(), wnd2D->getViewFrame()->height() ) ) );
+        qApp->postEvent( wnd2D, new QPaintEvent( QRect( 0, 0, wnd2D->width(), wnd2D->height() ) ) );
+        qApp->processEvents();
+        if ( fmt == "PS" || fmt == "EPS" || fmt == "PDF" ) {
+         myResult = wnd2D->getViewFrame()->print( myFileName, fmt );
+          return;
+        }
+      }
+#endif // DISABLE_PLOT2DVIEWER
+      QImage im = wnd->dumpView();
+      if ( !im.isNull() && !myFileName.isEmpty() ) {
+        if ( fmt.isEmpty() ) fmt = QString( "BMP" ); // default format
+        if ( fmt == "JPG" )  fmt = "JPEG";
+        myResult = im.save( myFileName, fmt.toLatin1() );
+      }
+    }
+  }
+};
+bool SalomePyQt::dumpView( const QString& filename, const int id )
+{
+  return ProcessEvent( new TDumpViewEvent( filename, id ) );
 }
 
 /*!
-  \fn QList<int> SalomePyQt::getViews()
+  \fn QList<int> SalomePyQt::getViews();
   \brief Get list of integer identifiers of all the currently opened views
   \return list of integer identifiers of all the currently opened views
 */
@@ -2061,12 +2774,10 @@ public:
   virtual void Execute() 
   {
     myResult.clear();
-    SalomeApp_Application* app  = getApplication();
-    if ( app )
-    {
+    LightApp_Application* app  = getApplication();
+    if ( app ) {
       STD_TabDesktop* tabDesk = dynamic_cast<STD_TabDesktop*>( app->desktop() );
-      if ( tabDesk )
-      {
+      if ( tabDesk ) {
         QList<SUIT_ViewWindow*> wndlist = tabDesk->windows();
         SUIT_ViewWindow* wnd;
         foreach ( wnd, wndlist )
@@ -2081,7 +2792,7 @@ QList<int> SalomePyQt::getViews()
 }
 
 /*!
-  \fn int SalomePyQt::getActiveView()
+  \fn int SalomePyQt::getActiveView();
   \brief Get integer identifier of the currently active view
   \return integer identifier of the currently active view
 */
@@ -2095,12 +2806,10 @@ public:
     : myResult( -1 ) {}
   virtual void Execute() 
   {
-    SalomeApp_Application* app = getApplication();
-    if ( app )
-    {
+    LightApp_Application* app = getApplication();
+    if ( app ) {
       SUIT_ViewManager* viewMgr = app->activeViewManager();
-      if ( viewMgr )
-      {
+      if ( viewMgr ) {
         SUIT_ViewWindow* wnd = viewMgr->getActiveView();
         if ( wnd )
           myResult = wnd->getId();
@@ -2114,7 +2823,7 @@ int SalomePyQt::getActiveView()
 }
 
 /*!                      
-  \fn QString SalomePyQt::getViewType( const int id )
+  \fn QString SalomePyQt::getViewType( const int id );
   \brief Get type of the specified view, e.g. "OCCViewer"
   \param id window identifier
   \return view type
@@ -2131,8 +2840,7 @@ public:
   virtual void Execute() 
   {
     SUIT_ViewWindow* wnd = getWnd( myWndId );
-    if ( wnd )
-    {
+    if ( wnd ) {
       SUIT_ViewManager* viewMgr = wnd->getViewManager();
       if ( viewMgr )
         myResult = viewMgr->getType();
@@ -2145,7 +2853,7 @@ QString SalomePyQt::getViewType( const int id )
 }
 
 /*!
-  \fn bool SalomePyQt::setViewTitle( const int id, const QString& title )
+  \fn bool SalomePyQt::setViewTitle( const int id, const QString& title );
   \brief Change view caption  
   \param id window identifier
   \param title new window title
@@ -2166,8 +2874,7 @@ public:
   virtual void Execute() 
   {
     SUIT_ViewWindow* wnd = getWnd( myWndId );
-    if ( wnd )
-    {
+    if ( wnd ) {
       wnd->setWindowTitle( myTitle );
       myResult = true;
     }
@@ -2178,9 +2885,89 @@ bool SalomePyQt::setViewTitle( const int id, const QString& title )
   return ProcessEvent( new TSetViewTitle( id, title ) );
 }
 
+/*!
+  \fn bool SalomePyQt::setViewSize( const int w, const int h, const int id );
+  \brief Set view size
+  \param w window width
+  \param h window height
+  \param id window identifier
+  \return \c true if operation is completed successfully and \c false otherwise 
+*/
+
+class TSetViewSize: public SALOME_Event
+{
+public:
+  typedef bool TResult;
+  TResult myResult;
+  int myWndWidth;
+  int myWndHeight;
+  int myWndId;
+  TSetViewSize( const int w, const int h, const int id )
+    : myResult( false ),
+      myWndWidth( w ),
+      myWndHeight( h ),
+      myWndId( id ) {}
+  virtual void Execute() 
+  {
+    SUIT_ViewWindow* wnd = 0;
+    if ( !myWndId ) {
+      if ( LightApp_Application* anApp = getApplication() ) {
+        SUIT_ViewManager* vm = anApp->activeViewManager();
+        if ( vm )
+          wnd = vm->getActiveView();
+      }
+    }
+    else {
+      wnd = dynamic_cast<SUIT_ViewWindow*>( getWnd( myWndId ) );
+    }
+    if ( wnd ) {
+      SUIT_ViewManager* viewMgr = wnd->getViewManager();
+      if ( viewMgr ) {
+        QString type = viewMgr->getType();
+        if ( type == "OCCViewer") {
+#ifndef DISABLE_OCCVIEWER
+          // specific processing for OCC viewer:
+          // OCC view can embed up to 4 sub-views, split according to the specified layout;
+          // - if there is only one sub-view active; it will be resized;
+          // - if there are several sub-views, each of them will be resized.
+          OCCViewer_ViewWindow* occView = qobject_cast<OCCViewer_ViewWindow*>( wnd );
+          for ( int i = OCCViewer_ViewFrame::BOTTOM_RIGHT; i <= OCCViewer_ViewFrame::TOP_RIGHT; i++ ) {
+            if ( occView && occView->getView( i ) ) {
+              occView->getView( i )->centralWidget()->resize( myWndWidth, myWndHeight );
+              myResult = true;
+            }
+          }
+#endif // DISABLE_OCCVIEWER
+        }
+        else if ( type == "ParaView") {
+#ifndef DISABLE_PVVIEWER
+          // specific processing for ParaView viewer:
+          // hierarchy of ParaView viewer is much complex than for usual view;
+          // we look for sub-widget named "Viewport"
+          QList<QWidget*> lst = wnd->findChildren<QWidget*>( "Viewport" );
+          if ( !lst.isEmpty() ) {
+            lst[0]->resize( myWndWidth, myWndHeight );
+            myResult = true;
+          }
+#endif // DISABLE_PVVIEWER
+        }
+        else {
+          if ( wnd->centralWidget() ) {
+            wnd->centralWidget()->resize( myWndWidth, myWndHeight );
+            myResult = true;
+          }
+        }
+      }
+    }
+  }
+};
+bool SalomePyQt::setViewSize( const int w, const int h, const int id )
+{
+  return ProcessEvent( new TSetViewSize( w, h, id ) );
+}
 
 /*!
-  \fn QString SalomePyQt::getViewTitle( const int id )
+  \fn QString SalomePyQt::getViewTitle( const int id );
   \brief Get view caption  
   \param id window identifier
   \return view caption  
@@ -2207,7 +2994,7 @@ QString SalomePyQt::getViewTitle( const int id )
 }
 
 /*!
-  \fn QList<int> SalomePyQt::findViews( const QString& type )
+  \fn QList<int> SalomePyQt::findViews( const QString& type );
   \brief Get list of integer identifiers of all the 
          currently opened views of the specified type
   \param type viewer type
@@ -2225,20 +3012,20 @@ public:
   virtual void Execute() 
   {
     myResult.clear();
-    SalomeApp_Application* app  = getApplication();
-    if ( app )
-    {
+    LightApp_Application* app  = getApplication();
+    if ( app ) {
       ViewManagerList vmList;
       app->viewManagers( myType, vmList );
       SUIT_ViewManager* viewMgr;
-      foreach ( viewMgr, vmList )
-      {
+      foreach ( viewMgr, vmList ) {
         QVector<SUIT_ViewWindow*> vec = viewMgr->getViews();
-        for ( int i = 0, n = vec.size(); i < n; i++ )
-        {
+        for ( int i = 0, n = vec.size(); i < n; i++ ) {
           SUIT_ViewWindow* wnd = vec[ i ];
           if ( wnd )
-            myResult.append( wnd->getId() );
+            {
+              MESSAGE("SUIT_ViewWindow*: "<< wnd << " id: " << wnd->getId());
+              myResult.append( wnd->getId() );
+            }
         }
       }
     }
@@ -2250,7 +3037,7 @@ QList<int> SalomePyQt::findViews( const QString& type )
 }
 
 /*!
-  \fn bool SalomePyQt::activateView( const int id )
+  \fn bool SalomePyQt::activateView( const int id );
   \brief Activate view
   \param id window identifier
   \return \c true if operation is completed successfully and \c false otherwise 
@@ -2268,8 +3055,8 @@ public:
   virtual void Execute() 
   {
     SUIT_ViewWindow* wnd = getWnd( myWndId );
-    if ( wnd )
-    {
+    MESSAGE("window id:" << myWndId << " SUIT_ViewWindow*: " << wnd);
+    if ( wnd ) {
       wnd->setFocus();
       myResult = true;
     }
@@ -2281,9 +3068,73 @@ bool SalomePyQt::activateView( const int id )
 }
 
 /*!
-  \fn int SalomePyQt::createView( const QString& type )
+  \fn bool SalomePyQt::activateManagerAndView( const int id );
+  \brief Activate view manager and view: useful for a view embedded in a module main Window
+  \param id window identifier
+  \return \c true if operation is completed successfully and \c false otherwise
+ */
+
+class TActivateViewManagerAndView: public SALOME_Event
+{
+public:
+  typedef bool TResult;
+  TResult myResult;
+  int myWndId;
+  TActivateViewManagerAndView( const int id )
+    : myResult( false ),
+      myWndId( id ) {}
+  virtual void Execute()
+  {
+    SUIT_ViewWindow* wnd = getWnd( myWndId );
+    MESSAGE("window id:" << myWndId << " SUIT_ViewWindow*: " << wnd);
+    if ( wnd )
+      {
+        LightApp_Application* app  = getApplication();
+        app->desktop()->windowActivated(wnd); // equivalent to app->setActiveViewManager(wnd->getViewManager())
+        wnd->setFocus();
+        myResult = true;
+      }
+  }
+};
+bool SalomePyQt::activateViewManagerAndView( const int id )
+{
+  return ProcessEvent( new TActivateViewManagerAndView( id ) );
+}
+
+/*!
+ *
+ */
+
+class TGetViewWidget: public SALOME_Event
+{
+public:
+  typedef QWidget* TResult;
+  TResult myResult;
+  int myWndId;
+  TGetViewWidget( const int id )
+    : myResult( 0 ),
+      myWndId( id ) {}
+  virtual void Execute()
+  {
+    SUIT_ViewWindow* wnd = getWnd( myWndId );
+    if ( wnd ) {
+        myResult = (QWidget*)wnd;
+    }
+  }
+};
+QWidget* SalomePyQt::getViewWidget( const int id)
+{
+  return ProcessEvent( new TGetViewWidget( id ) );
+}
+
+
+/*!
+  \fn int SalomePyQt::createView( const QString& type, bool visible = true, const int width = 0, const int height = 0 );
   \brief Create new view and activate it
   \param type viewer type
+  \param visible
+  \param width
+  \param height
   \return integer identifier of created view (or -1 if view could not be created)
 */
 
@@ -2293,17 +3144,76 @@ public:
   typedef int TResult;
   TResult myResult;
   QString myType;
-  TCreateView( const QString& theType )
+  bool myVisible;
+  int myWidth;
+  int myHeight;
+  bool myDetached;
+  TCreateView( const QString& theType, bool visible, const int width, const int height, bool detached )
     : myResult( -1 ),
-      myType( theType ) {}
+      myType( theType ),
+      myVisible(visible),
+      myWidth(width),
+      myHeight(height),
+      myDetached(detached) {}
   virtual void Execute() 
   {
-    SalomeApp_Application* app  = getApplication();
-    if ( app )
-    {
-      SUIT_ViewManager* viewMgr = app->createViewManager( myType );
-      if ( viewMgr )
-      {
+    LightApp_Application* app  = getApplication();
+    if ( app ) {
+      SUIT_ViewManager* viewMgr = app->createViewManager( myType, myDetached );
+      if ( viewMgr ) {
+        QWidget* wnd = viewMgr->getActiveView();
+        myResult = viewMgr->getActiveView()->getId();
+        if ( wnd ) {
+          if ( !myVisible )
+            wnd->setVisible(false);
+          if ( !myVisible && myWidth == 0 && myHeight == 0 ) {
+            myWidth = 1024;
+            myHeight = 768;
+          }
+          if (myWidth > 0 && myHeight > 0) {
+#ifndef DISABLE_PLOT2DVIEWER
+            Plot2d_ViewWindow* wnd2D = dynamic_cast<Plot2d_ViewWindow*>( wnd );
+            if ( wnd2D ) wnd = wnd2D->getViewFrame();
+#endif // DISABLE_PLOT2DVIEWER
+            wnd->setGeometry( 0, 0, myWidth, myHeight );
+          }
+        }
+      }
+    }
+  }
+};
+int SalomePyQt::createView( const QString& type, bool visible, const int width, const int height, bool detached )
+{
+  int ret = ProcessEvent( new TCreateView( type, visible, width, height, detached ) );
+  QCoreApplication::processEvents();
+  return ret;
+}
+
+/*!
+  \fn int SalomePyQt::createView( const QString& type, QWidget* w );
+  \brief Create new view with custom widget embedded and activate it
+  \param type viewer type
+  \param w custom widget
+  \return integer identifier of created view (or -1 if view could not be created)
+*/
+
+class TCreateViewWg: public SALOME_Event
+{
+public:
+  typedef int TResult;
+  TResult myResult;
+  QString myType;
+  QWidget* myWidget;
+  TCreateViewWg( const QString& theType, QWidget* w )
+    : myResult( -1 ),
+      myType( theType ),
+      myWidget( w ) {}
+  virtual void Execute() 
+  {
+    LightApp_Application* app  = getApplication();
+    if ( app ) {
+      SUIT_ViewManager* viewMgr = app->createViewManager( myType, myWidget );
+      if ( viewMgr ) {
         SUIT_ViewWindow* wnd = viewMgr->getActiveView();
         if ( wnd )
           myResult = wnd->getId();
@@ -2311,13 +3221,15 @@ public:
     }
   }
 };
-int SalomePyQt::createView( const QString& type )
+int SalomePyQt::createView( const QString& type, QWidget* w )
 {
-  return ProcessEvent( new TCreateView( type ) );
+  int ret = ProcessEvent( new TCreateViewWg( type, w ) );
+  QCoreApplication::processEvents();
+  return ret;
 }
 
 /*!
-  \fn bool SalomePyQt::closeView( const int id )
+  \fn bool SalomePyQt::closeView( const int id );
   \brief Close view
   \param id window identifier
   \return \c true if operation is completed successfully and \c false otherwise 
@@ -2335,11 +3247,9 @@ public:
   virtual void Execute() 
   {
     SUIT_ViewWindow* wnd = getWnd( myWndId );
-    if ( wnd )
-    {
+    if ( wnd ) {
       SUIT_ViewManager* viewMgr = wnd->getViewManager();
-      if ( viewMgr )
-      {
+      if ( viewMgr ) {
         wnd->close();
         myResult = true;
       }
@@ -2352,7 +3262,7 @@ bool SalomePyQt::closeView( const int id )
 }
 
 /*!
-  \fn int SalomePyQt::cloneView( const int id )
+  \fn int SalomePyQt::cloneView( const int id );
   \brief Clone view (if this operation is supported for specified view type)
   \param id window identifier
   \return integer identifier of the cloned view or -1 or operation could not be performed
@@ -2370,30 +3280,28 @@ public:
   virtual void Execute() 
   {
     SUIT_ViewWindow* wnd = getWnd( myWndId );
-    if ( wnd )
-    {
+    if ( wnd ) {
       SUIT_ViewManager* viewMgr = wnd->getViewManager();
-      if ( viewMgr )
-      {
-        if ( wnd->inherits( "OCCViewer_ViewWindow" ) )
-        {
+      if ( viewMgr ) {
+#ifndef DISABLE_OCCVIEWER
+        if ( wnd->inherits( "OCCViewer_ViewWindow" ) ) {
           OCCViewer_ViewWindow* occView = (OCCViewer_ViewWindow*)( wnd );
           occView->onCloneView();
-
           wnd = viewMgr->getActiveView();
           if ( wnd )
             myResult = wnd->getId();
         }
-        else if ( wnd->inherits( "Plot2d_ViewWindow" ) ) 
-        {
+#endif // DISABLE_OCCVIEWER
+#ifndef DISABLE_PLOT2DVIEWER
+        if ( wnd->inherits( "Plot2d_ViewWindow" ) ) {
           Plot2d_ViewManager* viewMgr2d = dynamic_cast<Plot2d_ViewManager*>( viewMgr );
           Plot2d_ViewWindow* srcWnd2d = dynamic_cast<Plot2d_ViewWindow*>( wnd );
-          if ( viewMgr2d && srcWnd2d )
-          {
+          if ( viewMgr2d && srcWnd2d ) {
             Plot2d_ViewWindow* resWnd = viewMgr2d->cloneView( srcWnd2d );
             myResult = resWnd->getId();
           }
         }
+#endif // DISABLE_OCCVIEWER
       }
     }
   }
@@ -2404,7 +3312,32 @@ int SalomePyQt::cloneView( const int id )
 }
 
 /*!
-  \fn bool SalomePyQt::isViewVisible( const int id )
+  \fn bool SalomePyQt::setViewVisible( const int id, const bool visible )
+  \brief Set view visibility.
+  \param id window identifier
+  \param visible new visiblity
+*/
+
+void SalomePyQt::setViewVisible( const int id, const bool visible )
+{
+  class TEvent: public SALOME_Event
+  {
+    int myWndId;
+    bool myVisible;
+  public:
+    TEvent( const int id, const bool visible )
+      : myWndId( id ), myVisible( visible ) {}
+    virtual void Execute()
+    {
+      SUIT_ViewWindow* wnd = getWnd( myWndId );
+      if ( wnd ) wnd->setVisible( myVisible );
+    }
+  };
+  ProcessVoidEvent( new TEvent( id, visible ) );
+}
+
+/*!
+  \fn bool SalomePyQt::isViewVisible( const int id );
   \brief Check whether view is visible ( i.e. it is on the top of the views stack)
   \param id window identifier
   \return \c true if view is visible and \c false otherwise 
@@ -2435,7 +3368,62 @@ bool SalomePyQt::isViewVisible( const int id )
 }
   
 /*!
-  \fn bool SalomePyQt::groupAllViews()
+  \fn bool SalomePyQt::setViewClosable( const int id, const bool on );
+  \brief Set / clear view's "closable" option. By default any view is closable
+        (i.e. can be closed by the user).
+  \param id window identifier
+  \param on new "closable" option's value
+*/
+
+void SalomePyQt::setViewClosable( const int id, const bool on )
+{
+  class TEvent: public SALOME_Event
+  {
+    int myWndId;
+    bool myOn;
+  public:
+    TEvent( const int id, const bool on )
+      : myWndId( id ), myOn( on ) {}
+    virtual void Execute()
+    {
+      SUIT_ViewWindow* wnd = getWnd( myWndId );
+      if ( wnd ) wnd->setClosable( myOn );
+    }
+  };
+  ProcessVoidEvent( new TEvent( id, on ) );
+}
+
+/*!
+  \fn bool SalomePyQt::isViewClosable( const int id );
+  \brief Check whether view is closable (i.e. can be closed by the user)
+  \param id window identifier
+  \return \c true if view is closable or \c false otherwise 
+*/
+
+class TIsViewClosable: public SALOME_Event
+{
+public:
+  typedef bool TResult;
+  TResult myResult;
+  int myWndId;
+  TIsViewClosable( const int id )
+    : myResult( true ),
+      myWndId( id ) {}
+  virtual void Execute() 
+  {
+    SUIT_ViewWindow* wnd = getWnd( myWndId );
+    if ( wnd )
+      myResult = wnd->closable();
+  }
+};
+
+bool SalomePyQt::isViewClosable( const int id )
+{
+  return ProcessEvent( new TIsViewClosable( id ) );
+}
+
+/*!
+  \fn bool SalomePyQt::groupAllViews();
   \brief Group all views to the single tab area
   \return \c true if operation is completed successfully and \c false otherwise 
 */
@@ -2449,15 +3437,12 @@ public:
     : myResult( false ) {}
   virtual void Execute() 
   {
-    SalomeApp_Application* app  = getApplication();
-    if ( app )
-    {
+    LightApp_Application* app  = getApplication();
+    if ( app ) {
       STD_TabDesktop* tabDesk = dynamic_cast<STD_TabDesktop*>( app->desktop() );
-      if ( tabDesk )
-      {
+      if ( tabDesk ) {
         QtxWorkstack* wStack = tabDesk->workstack();
-        if ( wStack )
-        {
+        if ( wStack ) {
           wStack->stack();
           myResult = true;
         }
@@ -2471,7 +3456,7 @@ bool SalomePyQt::groupAllViews()
 }
 
 /*!
-  \fn bool SalomePyQt::splitView( const int id, const Orientation ori, const Action action )
+  \fn bool SalomePyQt::splitView( const int id, const Orientation ori, const Action action );
   \brief Split tab area to which view with identifier belongs to
   \param id window identifier
   \param ori orientation of split operation
@@ -2497,21 +3482,17 @@ public:
   virtual void Execute() 
   {
     SUIT_ViewWindow* wnd = getWnd( myWndId );
-    if ( wnd )
-    {
+    if ( wnd ) {
       // activate view
       // wnd->setFocus(); ???
 
       // split workstack
-      if ( getApplication() )
-      {
+      if ( getApplication() ) {
         STD_TabDesktop* desk = 
           dynamic_cast<STD_TabDesktop*>( getApplication()->desktop() );
-        if ( desk )
-        {
+        if ( desk ) {
           QtxWorkstack* wStack = desk->workstack();
-          if ( wStack )
-          {
+          if ( wStack ) {
             Qt::Orientation qtOri = 
               ( myOri == Horizontal ) ? Qt::Horizontal : Qt::Vertical;
 
@@ -2537,7 +3518,7 @@ bool SalomePyQt::splitView( const int id, const Orientation ori, const Action ac
 }
 
 /*!
-  \fn bool SalomePyQt::moveView( const int id, const int id_to, const bool before )
+  \fn bool SalomePyQt::moveView( const int id, const int id_to, const bool before );
   \brief Move view with the first identifier to the same area which 
          another view with the second identifier belongs to
   \param id source window identifier
@@ -2564,8 +3545,7 @@ public:
   {
     SUIT_ViewWindow* wnd = getWnd( myWndId );
     SUIT_ViewWindow* wnd_to = getWnd( myWndToId );
-    if ( wnd && wnd_to )
-    {
+    if ( wnd && wnd_to ) {
       QtxWorkstack* wStack = dynamic_cast<STD_TabDesktop*>( 
         getApplication()->desktop() )->workstack();
       if ( wStack )
@@ -2579,7 +3559,7 @@ bool SalomePyQt::moveView( const int id, const int id_to, const bool before )
 }
 
 /*!
-  \fn QList<int> SalomePyQt::neighbourViews( const int id )
+  \fn QList<int> SalomePyQt::neighbourViews( const int id );
   \brief Get list of views identifiers that belongs to the same area as 
          specified view (excluding it)
   \param id window identifier
@@ -2598,16 +3578,13 @@ public:
   {
     myResult.clear();
     SUIT_ViewWindow* wnd = getWnd( myWndId );
-    if ( wnd )
-    {
+    if ( wnd ) {
       QtxWorkstack* wStack = dynamic_cast<STD_TabDesktop*>( 
         getApplication()->desktop() )->workstack();
-      if ( wStack )
-      {
+      if ( wStack ) {
         QWidgetList wgList = wStack->windowList( wnd );
         QWidget* wg;
-        foreach ( wg, wgList )
-        {
+        foreach ( wg, wgList ) {
           SUIT_ViewWindow* tmpWnd = dynamic_cast<SUIT_ViewWindow*>( wg );
           if ( tmpWnd && tmpWnd != wnd )
             myResult.append( tmpWnd->getId() );
@@ -2620,3 +3597,914 @@ QList<int> SalomePyQt::neighbourViews( const int id )
 {
   return ProcessEvent( new TNeighbourViews( id ) );
 }
+
+
+/*!
+  \fn void SalomePyQt::createRoot();
+  \brief Initialize root data object.
+
+  Does nothing if root is already initialized.
+*/
+
+void SalomePyQt::createRoot()
+{
+  class TEvent: public SALOME_Event
+  {
+  public:
+    TEvent() {}
+    virtual void Execute() 
+    {
+      SALOME_PYQT_ModuleLight* module = dynamic_cast<SALOME_PYQT_ModuleLight*>( getActiveModule() );
+      if ( module ) {
+        SALOME_PYQT_DataModelLight* dm =
+          dynamic_cast<SALOME_PYQT_DataModelLight*>( module->dataModel() );
+        if ( dm )
+          dm->getRoot();
+      }
+      else {
+        if ( verbose() ) printf( "SalomePyQt.createRoot() function is not supported for the current module.\n" );
+      }
+    }
+  };
+  ProcessVoidEvent( new TEvent() );
+}
+
+/*!
+  \fn QString SalomePyQt::createObject( const QString& parent );
+  \brief Create empty data object
+  \param parent entry of parent data object
+  \return entry of created data object
+*/
+
+class TCreateEmptyObjectEvent: public SALOME_Event
+{
+public:
+  typedef QString TResult;
+  TResult  myResult;
+  QString  myParent;
+  TCreateEmptyObjectEvent( const QString& parent )
+    : myParent( parent ) {}
+  virtual void Execute() 
+  {
+    SALOME_PYQT_ModuleLight* module = dynamic_cast<SALOME_PYQT_ModuleLight*>( getActiveModule() );
+    if ( module ) {
+       myResult = module->createObject( myParent );
+    }
+    else {
+      if ( verbose() ) printf( "SalomePyQt.createObject() function is not supported for the current module.\n" );
+    }
+  }
+};
+QString SalomePyQt::createObject( const QString& parent )
+{
+  return ProcessEvent( new TCreateEmptyObjectEvent( parent ) );
+}
+
+/*!
+  \fn QString SalomePyQt::createObject( const QString& name, const QString& icon,
+                                        const QString& tooltip,const QString& parent );
+  \brief Create new data object with specified name, icon and tooltip
+  \param name data object name
+  \param icon data object icon
+  \param toolTip data object tooltip
+  \param parent entry of parent data object
+  \return entry of created data object
+*/
+
+class TCreateObjectEvent: public SALOME_Event 
+{
+public:
+  typedef QString TResult;
+  TResult myResult;
+  QString myParent;
+  QString myName;
+  QString myIcon;
+  QString myToolTip;
+  TCreateObjectEvent( const QString& name,
+                     const QString& icon,
+                     const QString& tooltip,
+                     const QString& parent )
+    : myName( name ),
+      myIcon( icon ),
+      myToolTip( tooltip ),
+      myParent( parent ) {}
+  virtual void Execute()
+  {
+    SALOME_PYQT_ModuleLight* module = dynamic_cast<SALOME_PYQT_ModuleLight*>( getActiveModule() );
+    if ( module ) {
+      myResult = module->createObject( myName, myIcon, myToolTip, myParent );
+    }
+    else {
+      if ( verbose() ) printf( "SalomePyQt.createObject() function is not supported for the current module.\n" );
+    }
+  }
+};
+QString SalomePyQt::createObject( const QString& name,
+                                 const QString& icon,
+                                 const QString& toolTip,
+                                 const QString& parent )
+{
+  return ProcessEvent( new TCreateObjectEvent( name, icon, toolTip, parent ) );
+}
+
+
+/*!
+  \fn void SalomePyQt::setName( const QString& entry, const QString& name );
+  \brief Set data object name
+  \param entry data object entry
+  \param name data object name
+*/
+class TSetNameEvent: public SALOME_Event
+{
+public:
+  QString myEntry;
+  QString myName;
+  TSetNameEvent( const QString& entry,
+                 const QString& name )
+  : myEntry( entry ),
+    myName( name ) {}
+  virtual void Execute()
+  {
+    SALOME_PYQT_ModuleLight* module = dynamic_cast<SALOME_PYQT_ModuleLight*>( getActiveModule() );
+    if ( module ) {
+      module->setName( myEntry, myName );
+    }
+    else {
+      if ( verbose() ) printf( "SalomePyQt.setName() function is not supported for the current module.\n" );
+    }
+  }
+};
+void SalomePyQt::setName( const QString& entry, const QString& name )
+{
+  ProcessVoidEvent( new TSetNameEvent( entry, name ) );
+}
+
+/*!
+  \fn void SalomePyQt::setIcon( const QString& entry, const QString& icon );
+  \brief Set data object icon
+  \param entry data object entry
+  \param icon data object icon file name (icon is loaded from module resources)
+*/
+
+class TSetIconEvent: public SALOME_Event
+{
+public:
+  QString myEntry;
+  QString myIcon;
+  TSetIconEvent( const QString& entry,
+                 const QString& icon )
+  : myEntry( entry ),
+    myIcon( icon ) {}
+  virtual void Execute()
+  {
+    SALOME_PYQT_ModuleLight* module = dynamic_cast<SALOME_PYQT_ModuleLight*>( getActiveModule() );
+    if ( module ) {
+      module->setIcon( myEntry, myIcon );
+    }
+    else {
+      if ( verbose() ) printf( "SalomePyQt.setIcon() function is not supported for the current module.\n" );
+    }
+  }
+};
+
+void SalomePyQt::setIcon( const QString& entry, const QString& icon )
+{
+  ProcessVoidEvent( new TSetIconEvent( entry, icon ) );
+}
+
+/*!
+  \fn void SalomePyQt::setToolTip( const QString& entry, const QString& toolTip );
+  \brief Set data object tooltip
+  \param entry data object entry
+  \param toolTip data object tooltip
+*/
+
+class TSetToolTipEvent: public SALOME_Event
+{
+public:
+  QString myEntry;
+  QString myToolTip;
+  TSetToolTipEvent( const QString& entry,
+                    const QString& toolTip )
+    : myEntry( entry ),
+      myToolTip( toolTip ) {}
+  virtual void Execute()
+  {
+    SALOME_PYQT_ModuleLight* module = dynamic_cast<SALOME_PYQT_ModuleLight*>( getActiveModule() );
+    if ( module ) {
+      module->setToolTip( myEntry, myToolTip );
+    }
+    else {
+      if ( verbose() ) printf( "SalomePyQt.setToolTip() function is not supported for the current module.\n" );
+    }
+  }
+};
+void SalomePyQt::setToolTip( const QString& entry, const QString& toolTip )
+{
+  ProcessVoidEvent( new TSetToolTipEvent( entry, toolTip ) );
+}
+
+/*!
+  \fn void SalomePyQt::setReference( const QString& entry, const QString& refEntry );
+  \brief Set reference to another data object
+  \param entry data object entry
+  \param refEntry referenced data object entry
+*/
+
+class TSetRefEvent: public SALOME_Event
+{
+public:
+  QString myEntry;
+  QString myRefEntry;
+  TSetRefEvent( const QString& entry,
+               const QString& refEntry )
+    : myEntry( entry ),
+      myRefEntry( refEntry ) {}
+  virtual void Execute()
+  {
+    SALOME_PYQT_ModuleLight* module = dynamic_cast<SALOME_PYQT_ModuleLight*>( getActiveModule() );
+    if ( module ) {
+      module->setReference( myEntry, myRefEntry );
+    }
+    else {
+      if ( verbose() ) printf( "SalomePyQt.setReference() function is not supported for the current module.\n" );
+    }
+  }
+};
+void SalomePyQt::setReference( const QString& entry, const QString& refEntry )
+{
+  ProcessVoidEvent( new TSetRefEvent( entry, refEntry ) );
+}
+
+/*!
+  \fn void SalomePyQt::setColor( const QString& entry, const QColor& color );
+  \brief Set data object color
+  \param entry data object entry
+  \param color data object color
+ */
+
+class TSetColorEvent: public SALOME_Event
+{
+public:
+  QString myEntry;
+  QColor  myColor;
+  TSetColorEvent( const QString& entry,
+                 const QColor& color )
+    : myEntry( entry ),
+      myColor( color ) {}
+  virtual void Execute()
+  {
+    SALOME_PYQT_ModuleLight* module = dynamic_cast<SALOME_PYQT_ModuleLight*>( getActiveModule() );
+    if ( module ) {
+      module->setColor( myEntry, myColor );
+    }
+    else {
+      if ( verbose() ) printf( "SalomePyQt.setColor() function is not supported for the current module.\n" );
+    }
+  }
+};
+void SalomePyQt::setColor( const QString& entry, const QColor& color )
+{
+  ProcessVoidEvent( new TSetColorEvent( entry, color ) );
+}
+
+/*!
+  \fn QString SalomePyQt::getName( const QString& entry );
+  \brief Get data object name
+  \param entry data object entry
+  \return data object name
+*/
+
+class TGetNameEvent: public SALOME_Event
+{
+public:
+  typedef QString TResult;
+  TResult myResult;
+  QString myEntry;
+  TGetNameEvent( const QString& entry )
+    : myEntry( entry ) {}
+  virtual void Execute()
+  {
+    SALOME_PYQT_ModuleLight* module = dynamic_cast<SALOME_PYQT_ModuleLight*>( getActiveModule() );
+    if ( module ) {
+      myResult = module->getName( myEntry );
+    }
+    else {
+      if ( verbose() ) printf( "SalomePyQt.getName() function is not supported for the current module.\n" );
+    }
+  }
+};
+QString SalomePyQt::getName( const QString& entry )
+{
+  return ProcessEvent( new TGetNameEvent( entry ) );
+}
+
+/*!
+  \fn QString SalomePyQt::getToolTip( const QString& entry );
+  \brief Get data object tooltip
+  \param entry data object entry
+  \return data object tooltip
+*/
+
+class TGetToolTipEvent: public SALOME_Event
+{
+public:
+  typedef QString TResult;
+  TResult myResult;
+  QString myEntry;
+  TGetToolTipEvent( const QString& entry )
+  : myEntry( entry ) {}
+  virtual void Execute()
+  {
+    SALOME_PYQT_ModuleLight* module = dynamic_cast<SALOME_PYQT_ModuleLight*>( getActiveModule() );
+    if ( module ) {
+      myResult = module->getToolTip( myEntry );
+    }
+    else {
+      if ( verbose() ) printf( "SalomePyQt.getToolTip() function is not supported for the current module.\n" );
+    }
+  }
+};
+QString SalomePyQt::getToolTip( const QString& entry )
+{
+  return ProcessEvent( new TGetToolTipEvent( entry ) );
+}
+
+/*
+  \fn QString SalomePyQt::getReference( const QString& entry );
+  \brief Get entry of the referenced object (if there's any)
+  \param entry data object entry
+  \return referenced data object entry
+*/
+
+class TGetRefEvent: public SALOME_Event
+{
+public:
+  typedef QString TResult;
+  TResult myResult;
+  QString myEntry;
+  TGetRefEvent( const QString& entry )
+  : myEntry( entry ) {}
+  virtual void Execute()
+  {
+    SALOME_PYQT_ModuleLight* module = dynamic_cast<SALOME_PYQT_ModuleLight*>( getActiveModule() );
+    if ( module ) {
+      myResult = module->getReference( myEntry );
+    }
+    else {
+      if ( verbose() ) printf( "SalomePyQt.getReference() function is not supported for the current module.\n" );
+    }
+  }
+};
+QString SalomePyQt::getReference( const QString& entry )
+{
+  return ProcessEvent( new TGetRefEvent( entry ) );
+}
+
+/*!
+  \fn QColor SalomePyQt::getColor( const QString& entry );
+  \brief Get data object color
+  \param entry data object entry
+  \return data object color
+*/
+
+class TGetColorEvent: public SALOME_Event
+{
+public:
+  typedef QColor TResult;
+  TResult myResult;
+  QString myEntry;
+  TGetColorEvent( const QString& entry )
+  : myEntry( entry ) {}
+  virtual void Execute()
+  {
+    SALOME_PYQT_ModuleLight* module = dynamic_cast<SALOME_PYQT_ModuleLight*>( getActiveModule() );
+    if ( module ) {
+      myResult = module->getColor( myEntry );
+    }
+    else {
+      if ( verbose() ) printf( "SalomePyQt.getColor() function is not supported for the current module.\n" );
+    }
+  }
+};
+QColor SalomePyQt::getColor( const QString& entry )
+{
+  return ProcessEvent( new TGetColorEvent( entry ) );
+}
+
+/*!
+  \fn void SalomePyQt::removeChildren( const QString& entry );
+  \brief Remove all child data objects from specified data object
+  \param entry data object entry
+*/
+
+class TRemoveChildEvent: public SALOME_Event
+{
+public:
+  QString myEntry;
+  TRemoveChildEvent( const QString& entry )
+  : myEntry( entry ) {}
+  virtual void Execute()
+  {
+    SALOME_PYQT_ModuleLight* module = dynamic_cast<SALOME_PYQT_ModuleLight*>( getActiveModule() );
+    if ( module ) {
+      module->removeChildren( myEntry );
+    }
+    else {
+      if ( verbose() ) printf( "SalomePyQt.removeChildren() function is not supported for the current module.\n" );
+    }
+  }
+};
+void SalomePyQt::removeChildren( const QString& entry )
+{
+  ProcessVoidEvent( new TRemoveChildEvent( entry ) );
+}
+void SalomePyQt::removeChild( const QString& entry )
+{
+  if ( verbose() ) printf( "SalomePyQt.removeChild() function is obsolete. Use SalomePyQt.removeChildren() instead." );
+  removeChildren( entry );
+}
+
+/*!
+  \fn void SalomePyQt::removeObject( const QString& entry );
+  \brief Remove object by entry
+  \param entry data object entry
+*/
+
+class TRemoveObjectEvent: public SALOME_Event
+{
+public:
+  QString myEntry;
+  
+  TRemoveObjectEvent( const QString& entry )
+  : myEntry( entry ) {}
+  virtual void Execute()
+  {
+    SALOME_PYQT_ModuleLight* module = dynamic_cast<SALOME_PYQT_ModuleLight*>( getActiveModule() );
+    if ( module ) {
+      module->removeObject( myEntry );
+    }
+    else {
+      if ( verbose() ) printf( "SalomePyQt.removeObject() function is not supported for the current module.\n" );
+    }
+  }
+};
+void SalomePyQt::removeObject( const QString& entry )
+{
+  ProcessVoidEvent( new TRemoveObjectEvent( entry ) );
+}
+
+/*!
+  \fn QStringList SalomePyQt::getChildren( const QString& entry, const bool recursive );
+  \brief Get entries of all child data objects of specified data object
+  \param entry data object entry
+  \param recursive \c true for recursive processing
+*/
+
+class TGetChildrenEvent: public SALOME_Event
+{
+public:
+  typedef QStringList TResult;
+  TResult myResult;
+  QString myEntry;
+  bool    myRecursive; 
+  TGetChildrenEvent( const QString& entry, const bool recursive )
+    : myEntry( entry ),
+      myRecursive( recursive ) {}
+  virtual void Execute()
+  {
+    SALOME_PYQT_ModuleLight* module = dynamic_cast<SALOME_PYQT_ModuleLight*>( getActiveModule() );
+    if ( module ) {
+      myResult = module->getChildren( myEntry, myRecursive );
+    }
+    else {
+      if ( verbose() ) printf( "SalomePyQt.getChildren() function is not supported for the current module.\n" );
+    }
+  }
+};
+QStringList SalomePyQt::getChildren( const QString& entry, const bool recursive )
+{
+  return ProcessEvent( new TGetChildrenEvent( entry, recursive ) ); 
+}
+
+#ifndef DISABLE_PLOT2DVIEWER
+// Next set of methods relates to the Plot2d viewer functionality
+
+/*!
+  \fn void SalomePyQt::displayCurve( const int id, Plot2d_Curve* theCurve )
+  \brief Display theCurve in view
+  \param id window identifier
+  \param theCurve curve to display
+*/
+
+class TDisplayCurve: public SALOME_Event
+{
+public:
+  int myWndId;
+  Plot2d_Curve* myCurve;
+  TDisplayCurve( const int id, Plot2d_Curve* theCurve ) : myWndId( id ), myCurve( theCurve ) {}
+  virtual void Execute() {
+    Plot2d_ViewWindow* wnd = dynamic_cast<Plot2d_ViewWindow*>( getWnd( myWndId ) );
+    if ( wnd )
+      wnd->getViewFrame()->displayCurve( myCurve );
+  }
+};
+void SalomePyQt::displayCurve( const int id, Plot2d_Curve* theCurve )
+{
+  ProcessVoidEvent( new TDisplayCurve( id, theCurve ) ); 
+}
+
+/*!
+  \fn void SalomePyQt::eraseCurve( const int id, Plot2d_Curve* theCurve )
+  \brief Erase theCurve in view
+  \param id window identifier
+  \param theCurve curve to erase
+*/
+
+class TEraseCurve: public SALOME_Event
+{
+public:
+  int myWndId;
+  Plot2d_Curve* myCurve;
+  TEraseCurve( const int id, Plot2d_Curve* theCurve ) : myWndId( id ), myCurve( theCurve ) {}
+  virtual void Execute() {
+    Plot2d_ViewWindow* wnd = dynamic_cast<Plot2d_ViewWindow*>( getWnd( myWndId ) );
+    wnd->getViewFrame()->eraseCurve( myCurve );
+  }
+};
+void SalomePyQt::eraseCurve( const int id, Plot2d_Curve* theCurve )
+{
+  ProcessVoidEvent( new TEraseCurve( id, theCurve ) ); 
+}
+
+/*!
+  \fn void SalomePyQt::deleteCurve( Plot2d_Curve* theCurve )
+  \brief Delete theCurve from all views
+  \param theCurve curve to delete
+*/
+
+class TDeleteCurve: public SALOME_Event
+{
+public:
+  Plot2d_Curve* myCurve;
+  TDeleteCurve( Plot2d_Curve* theCurve ) : myCurve( theCurve ) {}
+  virtual void Execute() {
+    LightApp_Application* app  = getApplication();
+    if ( app ) {
+      STD_TabDesktop* tabDesk = dynamic_cast<STD_TabDesktop*>( app->desktop() );
+      if ( tabDesk ) {
+        QList<SUIT_ViewWindow*> wndlist = tabDesk->windows();
+        SUIT_ViewWindow* wnd;
+        foreach ( wnd, wndlist ) {
+          Plot2d_ViewWindow* aP2d = dynamic_cast<Plot2d_ViewWindow*>( wnd );
+          if ( aP2d )
+            aP2d->getViewFrame()->eraseObject( myCurve );
+        }
+      }
+    }
+  }
+};
+void SalomePyQt::eraseCurve( Plot2d_Curve* theCurve )
+{
+  ProcessVoidEvent( new TDeleteCurve( theCurve ) );
+}
+
+/*!
+  \brief updateCurves (repaint) curves in view window.
+*/
+void SalomePyQt::updateCurves( const int id )
+{
+  class TEvent: public SALOME_Event
+  {
+  public:
+    int myWndId;
+    TEvent( const int id ) : myWndId( id ) {}
+    virtual void Execute()
+    {
+      Plot2d_ViewWindow* wnd = dynamic_cast<Plot2d_ViewWindow*>( getWnd( myWndId ) );
+      if ( wnd )
+       wnd->getViewFrame()->DisplayAll();
+    }
+  };
+  ProcessVoidEvent( new TEvent( id ) );
+}
+
+/*!
+  \fn QString SalomePyQt::getPlot2dTitle( const int id, ObjectType type = MainTitle )
+  \brief Get title of corresponding type
+  \param id window identifier
+  \param type is type of title
+  \return title of corresponding type
+*/
+
+class TGetPlot2dTitle: public SALOME_Event
+{
+public:
+  typedef QString TResult;
+  TResult myResult;
+  int myWndId;
+  ObjectType myType;
+  TGetPlot2dTitle(const int id, ObjectType type) :
+    myWndId( id ),
+    myType( type ) {}
+  virtual void Execute() {
+    Plot2d_ViewWindow* wnd = dynamic_cast<Plot2d_ViewWindow*>( getWnd( myWndId ) );
+    if ( wnd )
+      myResult = wnd->getViewFrame()->getTitle( (Plot2d_ViewFrame::ObjectType)myType );
+  }
+};
+QString SalomePyQt::getPlot2dTitle( const int id, ObjectType type )
+{
+  return ProcessEvent( new TGetPlot2dTitle( id, type ) ); 
+}
+
+
+/*!
+  \fn void SalomePyQt::setPlot2dTitle( const int id, const QString& title, ObjectType type = MainTitle, bool show = true )
+  \brief Set title of corresponding type
+  \param id window identifier
+  \param title
+  \param type is type of title
+  \param show
+*/
+
+class TSetPlot2dTitle: public SALOME_Event
+{
+public:
+  int myWndId;
+  Plot2d_Curve* myCurve;
+  QString myTitle;
+  ObjectType myType;
+  bool myShow;
+  TSetPlot2dTitle( const int id, const QString& title, ObjectType type, bool show ) :
+    myWndId( id ),
+    myTitle( title ),
+    myType( type ),
+    myShow( show ) {}
+  virtual void Execute() {
+    Plot2d_ViewWindow* wnd = dynamic_cast<Plot2d_ViewWindow*>( getWnd( myWndId ) );
+    wnd->getViewFrame()->setTitle( myShow, myTitle, (Plot2d_ViewFrame::ObjectType)myType, false );
+  }
+};
+void SalomePyQt::setPlot2dTitle( const int id, const QString& title, ObjectType type, bool show )
+{
+  ProcessVoidEvent( new TSetPlot2dTitle( id, title, type, show ) ); 
+}
+
+/*!
+  \fn QList<int> SalomePyQt::getPlot2dFitRangeByCurves( const int id )
+  \brief Get list of Plot2d view ranges
+  \param id window identifier
+  \return list of view ranges (XMin, XMax, YMin, YMax)
+*/
+
+class TFitRangeByCurves: public SALOME_Event
+{
+public:
+  typedef QList<double> TResult;
+  TResult myResult;
+  int myWndId;
+  TFitRangeByCurves( const int id )
+    : myWndId( id ) {}
+  virtual void Execute() 
+  {
+    myResult.clear();
+    Plot2d_ViewWindow* wnd = dynamic_cast<Plot2d_ViewWindow*>( getWnd( myWndId ) );
+    if ( wnd ) {
+      double XMin, XMax, YMin, YMax, Y2Min, Y2Max;
+      wnd->getViewFrame()->getFitRangeByCurves( XMin, XMax, YMin, YMax, Y2Min, Y2Max );
+      myResult.append( XMin );
+      myResult.append( XMax );
+      myResult.append( YMin );
+      myResult.append( YMax );
+    }
+  }
+};
+QList<double> SalomePyQt::getPlot2dFitRangeByCurves( const int id )
+{
+  return ProcessEvent( new TFitRangeByCurves( id ) );
+}
+
+/*!
+  \fn QList<int> SalomePyQt::getPlot2dFitRangeCurrent( const int id )
+  \brief Get list of current Plot2d view ranges
+  \param id window identifier
+  \return list of view ranges (XMin, XMax, YMin, YMax)
+*/
+
+class TFitRangeCurrent: public SALOME_Event
+{
+public:
+  typedef QList<double> TResult;
+  TResult myResult;
+  int myWndId;
+  TFitRangeCurrent( const int id )
+    : myWndId( id ) {}
+  virtual void Execute() 
+  {
+    myResult.clear();
+    Plot2d_ViewWindow* wnd = dynamic_cast<Plot2d_ViewWindow*>( getWnd( myWndId ) );
+    if ( wnd ) {
+      double XMin, XMax, YMin, YMax, Y2Min, Y2Max;
+      wnd->getViewFrame()->getFitRanges( XMin, XMax, YMin, YMax, Y2Min, Y2Max );
+      myResult.append( XMin );
+      myResult.append( XMax );
+      myResult.append( YMin );
+      myResult.append( YMax );
+    }
+  }
+};
+QList<double> SalomePyQt::getPlot2dFitRangeCurrent( const int id )
+{
+  return ProcessEvent( new TFitRangeCurrent( id ) );
+}
+
+/*!
+  \fn void SalomePyQt::setPlot2dFitRange( const int id, const double XMin, const double XMax, const double YMin, const double YMax )
+  \brief Set range of Plot2d view
+  \param id window identifier
+  \param XMin
+  \param XMax
+  \param YMin
+  \param YMax
+*/
+
+class TPlot2dFitRange: public SALOME_Event
+{
+public:
+  int myWndId;
+  double myXMin;
+  double myXMax;
+  double myYMin;
+  double myYMax;
+  TPlot2dFitRange( const int id, const double XMin, const double XMax, const double YMin, const double YMax ) :
+    myWndId( id ),
+    myXMin( XMin ),
+    myXMax( XMax ),
+    myYMin( YMin ),
+    myYMax( YMax ) {}
+  virtual void Execute() {
+    Plot2d_ViewWindow* wnd = dynamic_cast<Plot2d_ViewWindow*>( getWnd( myWndId ) );
+    if ( wnd )
+      wnd->getViewFrame()->fitData( 0, myXMin, myXMax, myYMin, myYMax );
+  }
+};
+void SalomePyQt::setPlot2dFitRange( const int id, const double XMin, const double XMax, const double YMin, const double YMax )
+{
+  ProcessVoidEvent( new TPlot2dFitRange( id, XMin, XMax, YMin, YMax ) ); 
+}
+
+// End of methods related to the Plot2d viewer functionality
+#endif // DISABLE_PLOT2DVIEWER
+
+/*!
+  \brief Process Qt event loop
+*/
+void SalomePyQt::processEvents()
+{
+  QCoreApplication::processEvents();
+}
+
+/*!
+  \brief Set visibility state for given object
+  \param theEntry study ID of the object
+  \param theState visibility state
+*/
+void SalomePyQt::setVisibilityState( const QString& theEntry, VisibilityState theState )
+{
+  class TEvent: public SALOME_Event
+  {
+    QString myEntry;
+    int myState;
+  public:
+    TEvent( const QString& theEntry, int theState ):
+      myEntry( theEntry ), myState( theState ) {}
+    virtual void Execute() 
+    {
+      LightApp_Study* aStudy = getActiveStudy();
+      if ( !aStudy )
+        return;
+      aStudy->setVisibilityState( myEntry, (Qtx::VisibilityState)myState );
+    }
+  };
+  ProcessVoidEvent( new TEvent( theEntry, theState ) );
+}
+
+/*!
+  \fn VisibilityState SalomePyQt::getVisibilityState( const QString& theEntry )
+  \brief Get visibility state for given object
+  \param theEntry study ID of the object
+  \return visibility state
+*/
+
+class TGetVisibilityStateEvent: public SALOME_Event 
+{
+public:
+  typedef int TResult;
+  TResult myResult;
+  QString myEntry;
+  TGetVisibilityStateEvent( const QString& theEntry ) : myResult( 0 ), myEntry( theEntry ) {}
+  virtual void Execute()
+  {
+    LightApp_Study* aStudy = getActiveStudy();
+    if ( aStudy )
+      myResult = aStudy->visibilityState( myEntry );
+  }
+};
+VisibilityState SalomePyQt::getVisibilityState( const QString& theEntry )
+{
+  return (VisibilityState) ProcessEvent( new TGetVisibilityStateEvent( theEntry ) );
+}
+
+/*!
+  \brief Set position of given object in the tree
+  \param theEntry study ID of the object
+  \param thePos position
+*/
+void SalomePyQt::setObjectPosition( const QString& theEntry, int thePos )
+{
+  class TEvent: public SALOME_Event
+  {
+    QString myEntry;
+    int myPos;
+  public:
+    TEvent( const QString& theEntry, int thePos ):
+      myEntry( theEntry ), myPos( thePos ) {}
+    virtual void Execute() 
+    {
+      SALOME_PYQT_ModuleLight* module = dynamic_cast<SALOME_PYQT_ModuleLight*>( getActiveModule() );
+      if ( module )
+        module->setObjectPosition( myEntry, myPos );
+    }
+  };
+  ProcessVoidEvent( new TEvent( theEntry, thePos ) );
+}
+
+/*!
+  \fn int SalomePyQt::getObjectPosition( const QString& theEntry )
+  \brief Get position of given object in the tree
+  \param theEntry study ID of the object
+  \return position
+*/
+
+class TGetObjectPositionEvent: public SALOME_Event 
+{
+public:
+  typedef int TResult;
+  TResult myResult;
+  QString myEntry;
+  TGetObjectPositionEvent( const QString& theEntry ) : myResult( 0 ), myEntry( theEntry ) {}
+  virtual void Execute()
+  {
+    SALOME_PYQT_ModuleLight* module = dynamic_cast<SALOME_PYQT_ModuleLight*>( getActiveModule() );
+    if ( module )
+      myResult = module->getObjectPosition( myEntry );
+  }
+};
+int SalomePyQt::getObjectPosition( const QString& theEntry )
+{
+  return ProcessEvent( new TGetObjectPositionEvent( theEntry ) );
+}
+
+/*!
+  \brief Start recordind a log of Python commands from embedded console
+  \param theFileName output lof file name
+*/
+void SalomePyQt::startPyLog( const QString& theFileName )
+{
+  class TEvent: public SALOME_Event
+  {
+    QString myFileName;
+  public:
+    TEvent( const QString& theFileName ):
+      myFileName( theFileName ) {}
+    virtual void Execute() 
+    {
+      if ( getApplication() ) {
+       PyConsole_Console* pyConsole = getApplication()->pythonConsole( false );
+       if ( pyConsole ) pyConsole->startLog( myFileName );
+      }
+    }
+  };
+  ProcessVoidEvent( new TEvent( theFileName ) );
+}
+
+/*!
+  \brief Stop recordind a log of Python commands from embedded console
+*/
+void SalomePyQt::stopPyLog()
+{
+  class TEvent: public SALOME_Event
+  {
+  public:
+    TEvent() {}
+    virtual void Execute() 
+    {
+      if ( getApplication() ) {
+       PyConsole_Console* pyConsole = getApplication()->pythonConsole( false );
+       if ( pyConsole ) pyConsole->stopLog();
+      }
+    }
+  };
+  ProcessVoidEvent( new TEvent() );
+}