Salome HOME
Copyright update 2022
[modules/gui.git] / src / SALOME_PYQT / SALOME_PYQT_GUILight / SALOME_PYQT_PyModule.cxx
index 914c5c45a71872e751634b9d255db848ac17a5e4..2451a727f1e41759bf8c0240f4c09a1b6a515e20 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2022  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
@@ -65,6 +65,9 @@ const int DEFAULT_GROUP = 40;
 */
 QMutex myInitMutex;
 
+/*! DEBUG mode */
+const bool theDEBUG = false;
+
 /*!
   \var IsCallOldMethods
   \brief Allow calling obsolete callback methods.
@@ -75,7 +78,7 @@ QMutex myInitMutex;
   etc. is blocked.
 
   CALL_OLD_METHODS macro can be defined, for example, by adding 
-  -DCALL_OLD_METHODS compilation option to the Makefile.
+  -DCALL_OLD_METHODS compilation option to the CMakeLists.txt.
 */
 #ifdef CALL_OLD_METHODS
 const bool IsCallOldMethods = true;
@@ -165,15 +168,19 @@ public:
   FuncMsg( const QString& funcName )
   {
     myName = funcName;
-    MESSAGE( qPrintable( myName ) << " [ begin ]" );
+    if ( theDEBUG )
+      MESSAGE( qPrintable( myName ) << " [ begin ]" );
   }
   ~FuncMsg()
   {
-    MESSAGE( qPrintable( myName ) << " [ end ]" );
+    if ( theDEBUG )
+      MESSAGE( qPrintable( myName ) << " [ end ]" );
   }
   void message( const QString& msg )
   {
-    MESSAGE( qPrintable( myName ) << " : " << qPrintable( msg ) );
+    (void)msg; // unused in debug mode
+    if ( theDEBUG )
+      MESSAGE( qPrintable( myName ) << " : " << qPrintable( msg ) );
   }
 private:
   QString myName;
@@ -228,9 +235,9 @@ public:
   XmlHandler( PyModuleHelper* helper, const QString& fileName );
   void             createActions();
   void             createPopup( QMenu* menu,
-                               const QString& context,
-                               const QString& parent,
-                               const QString& object );
+                                const QString& context,
+                                const QString& parent,
+                                const QString& object );
   void             activateMenus( bool );
 
 private:
@@ -238,11 +245,11 @@ private:
   QIcon            loadIcon( const QString& fileName );
 
   void             createMenu( QDomNode& parentNode,
-                              const int parentMenuId = -1,
-                              QMenu* parentPopup = 0 );
+                               const int parentMenuId = -1,
+                               QMenu* parentPopup = 0 );
   void             createToolBar( QDomNode& parentNode );
   void             insertPopupItems( QDomNode& parentNode,
-                                    QMenu* menu );
+                                     QMenu* menu );
 
 private:
   PyModuleHelper*  myHelper;
@@ -258,7 +265,7 @@ private:
   \param fileName path to the XML menu description file 
 */
 PyModuleHelper::XmlHandler::XmlHandler( PyModuleHelper*  helper,
-                                       const QString&   fileName )
+                                        const QString&   fileName )
 : myHelper( helper )
 {
   if ( !fileName.isEmpty() ) { 
@@ -305,9 +312,9 @@ void PyModuleHelper::XmlHandler::createActions()
   \param context popup menu object name
 */
 void PyModuleHelper::XmlHandler::createPopup( QMenu*         menu,
-                                             const QString& context,
-                                             const QString& parent,
-                                             const QString& object )
+                                              const QString& context,
+                                              const QString& parent,
+                                              const QString& object )
 {
   // get document element
   QDomElement aDocElem = myDoc.documentElement();
@@ -364,10 +371,10 @@ QIcon PyModuleHelper::XmlHandler::loadIcon( const QString& fileName )
   if ( module() && !fileName.isEmpty() ) {
       SUIT_ResourceMgr* resMgr = module()->getApp()->resourceMgr();
       QPixmap pixmap = resMgr->loadPixmap( module()->name(),
-                                          QApplication::translate( module()->name().toLatin1().data(), 
-                                                                   fileName.toLatin1().data() ) );
-    if ( !pixmap.isNull() )
-      icon = QIcon( pixmap );
+          QApplication::translate( module()->name().toLatin1().data(),
+                                   fileName.toUtf8().data() ) );
+      if ( !pixmap.isNull() )
+        icon = QIcon( pixmap );
   }
 
   return icon;
@@ -381,8 +388,8 @@ QIcon PyModuleHelper::XmlHandler::loadIcon( const QString& fileName )
   \param parentPopup parent popup menu (0 for top-level menu)
 */
 void PyModuleHelper::XmlHandler::createMenu( QDomNode& parentNode, 
-                                            const int parentMenuId, 
-                                            QMenu*    parentPopup )
+                                             const int parentMenuId,
+                                             QMenu*    /*parentPopup*/ )
 {
   if ( !module() || parentNode.isNull() )
     return;
@@ -425,14 +432,14 @@ void PyModuleHelper::XmlHandler::createMenu( QDomNode& parentNode,
             if ( id != -1 ) {
               // create menu action
               QAction* action = module()->createAction( id,                     // ID
-                                                       tooltip,                // tooltip
-                                                       icon,                   // icon
-                                                       label,                  // menu text
-                                                       tooltip,                // status-bar text
-                                                       QKeySequence( accel ),  // keyboard accelerator
-                                                       module(),               // action owner
-                                                       toggle );               // toogled action
-             myHelper->connectAction( action );
+                                                        tooltip,                // tooltip
+                                                        icon,                   // icon
+                                                        label,                  // menu text
+                                                        tooltip,                // status-bar text
+                                                        QKeySequence( accel ),  // keyboard accelerator
+                                                        module(),               // action owner
+                                                        toggle );               // toogled action
+              myHelper->connectAction( action );
               module()->createMenu( action,   // action
                                     menuId,   // parent menu ID
                                     id,       // ID (same as for createAction())
@@ -476,9 +483,10 @@ void PyModuleHelper::XmlHandler::createToolBar( QDomNode& parentNode )
   QDomElement parentElement = parentNode.toElement();
   if ( !parentElement.isNull() ) {
     QString aLabel = attribute( parentElement, "label-id" );
+    QString aName  = attribute( parentElement, "name-id" );
     if ( !aLabel.isEmpty() ) {
       // create toolbar
-      int tbId = module()->createTool( aLabel );
+      int tbId = module()->createTool( aLabel, aName );
       QDomNode node = parentNode.firstChild();
       while ( !node.isNull() ) {
         if ( node.isElement() ) {
@@ -496,17 +504,17 @@ void PyModuleHelper::XmlHandler::createToolBar( QDomNode& parentNode )
             // -1 action ID is not allowed : it means that <item-id> attribute is missed in the XML file!
             // also check if the action with given ID is already created
             if ( id != -1 ) {
-              // create toolbar action
-              QAction* action = module()->createAction( id,                     // ID
-                                                       tooltip,                // tooltip
-                                                       icon,                   // icon
-                                                       label,                  // menu text
-                                                       tooltip,                // status-bar text
-                                                       QKeySequence( accel ),  // keyboard accelerator
-                                                       module(),               // action owner
-                                                       toggle );               // toogled action
-             myHelper->connectAction( action );
-              module()->createTool( action, tbId, -1, pos );
+                // create toolbar action
+                QAction* action = module()->createAction( id,                     // ID
+                                                          tooltip,                // tooltip
+                                                          icon,                   // icon
+                                                          label,                  // menu text
+                                                          tooltip,                // status-bar text
+                                                          QKeySequence( accel ),  // keyboard accelerator
+                                                          module(),               // action owner
+                                                          toggle );               // toogled action
+                myHelper->connectAction( action );
+                module()->createTool( action, tbId, -1, pos );
             }
           }
           else if ( aTagName == "separatorTB" || aTagName == "separator" ) {
@@ -552,15 +560,15 @@ void PyModuleHelper::XmlHandler::insertPopupItems( QDomNode& parentNode, QMenu*
         // -1 action ID is not allowed : it means that <item-id> attribute is missed in the XML file!
         // also check if the action with given ID is already created
         if ( id != -1 ) {
-         QAction* action = module()->createAction( id,                     // ID
-                                                   tooltip,                // tooltip
-                                                   icon,                   // icon
-                                                   label,                  // menu text
-                                                   tooltip,                // status-bar text
-                                                   QKeySequence( accel ),  // keyboard accelerator
-                                                   module(),               // action owner
-                                                   toggle );               // toogled action
-         myHelper->connectAction( action );
+          QAction* action = module()->createAction( id,                     // ID
+                                                    tooltip,                // tooltip
+                                                    icon,                   // icon
+                                                    label,                  // menu text
+                                                    tooltip,                // status-bar text
+                                                    QKeySequence( accel ),  // keyboard accelerator
+                                                    module(),               // action owner
+                                                    toggle );               // toogled action
+          myHelper->connectAction( action );
           QAction* before = ( pos >= 0 && pos < actions.count() ) ? actions[ pos ] : 0;
           menu->insertAction( before, action );
         }
@@ -602,7 +610,6 @@ void PyModuleHelper::XmlHandler::insertPopupItems( QDomNode& parentNode, QMenu*
   SALOME GUI modules.
 */
 
-PyModuleHelper::InterpMap PyModuleHelper::myInterpMap;
 LightApp_Module*          PyModuleHelper::myInitModule = 0;
 
 /*!
@@ -627,7 +634,7 @@ PyModuleHelper::~PyModuleHelper()
 {
   delete myXmlHandler;
   if ( myInterp && myPyModule ) {
-    PyLockWrapper aLock = myInterp->GetLockWrapper();
+    PyLockWrapper aLock; // Acquire GIL
     Py_XDECREF( myPyModule );
   }
 }
@@ -691,8 +698,8 @@ void PyModuleHelper::connectAction( QAction* a )
 {
   if ( myModule && a )
     QObject::connect( a, SIGNAL( triggered( bool ) ), 
-                     this, SLOT( actionActivated() ),
-                     Qt::UniqueConnection );
+                      this, SLOT( actionActivated() ),
+                      Qt::UniqueConnection );
 }
 
 /*!
@@ -747,11 +754,11 @@ QStringList PyModuleHelper::viewManagers() const
   \brief Initialization of the Python-based SALOME module.
   
   This method can be used for creation of the menus, toolbars and 
-  other such staff.
+  other such stuff.
   
   There are two ways to do this:
-  1) for obsolete modules implementatino this method first tries to read
-  <module>_<language>.xml resource file which contains a menu,
+  1) for obsolete modules, the implementation of this method first tries to read
+  the <module>_<language>.xml resource file which contains a menu,
   toolbars and popup menus description;
   2) new modules can create menus by direct calling of the
   corresponding methods of SalomePyQt Python API in the Python
@@ -759,7 +766,7 @@ QStringList PyModuleHelper::viewManagers() const
 
   \note SALOME supports two modes of modules loading:
   - immediate (all the modules are created and initialized 
-  immediately when the application object is created;
+  immediately when the application object is created);
   - postponed modules loading (used currently); in this mode
   the module is loaded only by explicit request.
   If postponed modules loading is not used, the active
@@ -798,10 +805,10 @@ void PyModuleHelper::initialize( CAM_Application* app )
   {
   public:
     InitializeReq( PyModuleHelper*  _helper,
-                  CAM_Application* _app )
+                   CAM_Application* _app )
       : PyInterp_Request( 0, true ), // this request should be processed synchronously (sync == true)
         myHelper( _helper ),
-       myApp( _app )
+        myApp( _app )
     {}
   protected:
     virtual void execute()
@@ -841,21 +848,21 @@ bool PyModuleHelper::activate( SUIT_Study* study )
   {
   public:
     ActivateReq( PyModuleHelper* _helper,
-                SUIT_Study*     _study,
-                bool            _customize )
-      : PyInterp_Request( 0, true ), // this request should be processed synchronously (sync == true)
-       myHelper( _helper ),
-        myStudy ( _study ),
-       myCustomize( _customize )
-    {}
+                 SUIT_Study*     _study,
+                 bool            _customize )
+  : PyInterp_Request( 0, true ), // this request should be processed synchronously (sync == true)
+    myHelper( _helper ),
+    myStudy ( _study ),
+    myCustomize( _customize )
+  {}
   protected:
     virtual void execute()
-    {
-      if ( !myCustomize )
-       myHelper->internalActivate( myStudy );  // first activation stage
-      else
-       myHelper->internalCustomize( myStudy ); // second activation stage
-    }
+      {
+        if ( !myCustomize )
+          myHelper->internalActivate( myStudy );  // first activation stage
+        else
+          myHelper->internalCustomize( myStudy ); // second activation stage
+      }
   private:
     PyModuleHelper* myHelper;
     SUIT_Study*     myStudy;
@@ -881,12 +888,12 @@ bool PyModuleHelper::activate( SUIT_Study* study )
     if ( myLastActivateStatus ) {
       // connect preferences changing signal
       connect( myModule->getApp(), SIGNAL( preferenceChanged( const QString&, const QString&, const QString& ) ),
-              this,               SLOT(   preferenceChanged( const QString&, const QString&, const QString& ) ) );
+               this,               SLOT(   preferenceChanged( const QString&, const QString&, const QString& ) ) );
       
       // connect active view change signal
       SUIT_Desktop* d = study->application()->desktop();
       connect( d,     SIGNAL( windowActivated( SUIT_ViewWindow* ) ),
-              this,  SLOT( activeViewChanged( SUIT_ViewWindow* ) ) );
+               this,  SLOT( activeViewChanged( SUIT_ViewWindow* ) ) );
       // if active window exists, call activeViewChanged() function;
       // temporary solution: if a getActiveView() in SalomePyQt available
       // we no longer need this 
@@ -924,11 +931,11 @@ bool PyModuleHelper::deactivate( SUIT_Study* study )
   {
   public:
     DeactivateReq( PyInterp_Interp* _py_interp,
-                  PyModuleHelper*  _helper,
+                   PyModuleHelper*  _helper,
                    SUIT_Study*      _study )
       : PyInterp_LockRequest( _py_interp, 0, true ), // this request should be processed synchronously (sync == true)
         myHelper( _helper ),
-       myStudy ( _study )
+        myStudy ( _study )
     {}
   protected:
     virtual void execute()
@@ -950,7 +957,7 @@ bool PyModuleHelper::deactivate( SUIT_Study* study )
   // disconnect the SUIT_Desktop signal windowActivated()
   SUIT_Desktop* d = study->application()->desktop();
   disconnect( d,     SIGNAL( windowActivated( SUIT_ViewWindow* ) ),
-             this,  SLOT( activeViewChanged( SUIT_ViewWindow* ) ) );
+              this,  SLOT( activeViewChanged( SUIT_ViewWindow* ) ) );
 
   // deactivate menus, toolbars, etc
   if ( myXmlHandler ) myXmlHandler->activateMenus( false );
@@ -1023,7 +1030,7 @@ void PyModuleHelper::modelClosed( SUIT_Study* study )
   \param parameter preference resources parameter name
 */
 void PyModuleHelper::preferencesChanged( const QString& section, 
-                                        const QString& parameter )
+                                         const QString& parameter )
 {
   FuncMsg fmsg( "PyModuleHelper::preferencesChanged()" );
 
@@ -1031,9 +1038,9 @@ void PyModuleHelper::preferencesChanged( const QString& section,
   {
   public:
     PrefChangeReq( PyInterp_Interp* _py_interp,
-                  PyModuleHelper*  _helper,
-                  const QString&   _section,
-                  const QString&   _parameter )
+                   PyModuleHelper*  _helper,
+                   const QString&   _section,
+                   const QString&   _parameter )
       : PyInterp_LockRequest( _py_interp, 0, true ), // this request should be processed synchronously (sync == true)
         myHelper ( _helper ),
         mySection( _section ),
@@ -1065,8 +1072,8 @@ void PyModuleHelper::preferencesChanged( const QString& section,
   \param parameter preference resources parameter name
 */
 void PyModuleHelper::preferenceChanged( const QString& module, 
-                                       const QString& section, 
-                                       const QString& parameter )
+                                        const QString& section,
+                                        const QString& parameter )
 {
   FuncMsg fmsg( "PyModuleHelper::preferenceChanged()" );
 
@@ -1094,10 +1101,10 @@ void PyModuleHelper::studyActivated( SUIT_Study* study )
   {
   public:
     StudyChangedReq( PyModuleHelper* _helper,
-                    SUIT_Study*     _study )
-      : PyInterp_Request( 0, true ), // this request should be processed synchronously (sync == true)
+                     SUIT_Study*     _study )
+      : PyInterp_Request(0, true ), // this request should be processed synchronously (sync == true)
         myHelper( _helper ), 
-       myStudy ( _study )
+        myStudy ( _study )
     {}
   protected:
     virtual void execute()
@@ -1130,8 +1137,8 @@ void PyModuleHelper::actionActivated()
   {
   public:
     ActionReq( PyInterp_Interp* _py_interp,
-              PyModuleHelper*  _helper,
-              int              _id )
+               PyModuleHelper*  _helper,
+               int              _id )
       : PyInterp_LockRequest( _py_interp, 0, true ), // this request should be processed synchronously (sync == true)
         myHelper( _helper ),
         myId    ( _id  )
@@ -1155,6 +1162,44 @@ void PyModuleHelper::actionActivated()
   PyInterp_Dispatcher::Get()->Exec( new ActionReq( myInterp, this, myModule->actionId( action ) ) );
 }
 
+/*!
+  \brief update selection from other views or modules.
+
+  Called when selection is modified outside.
+*/
+void PyModuleHelper::selectionUpdated(const QStringList& entries)
+{
+  FuncMsg fmsg( "PyModuleHelper::selectionUpdated()" );
+  MESSAGE("selectionUpdated");
+
+  // perform synchronous request to Python event dispatcher
+  class SelectionReq : public PyInterp_LockRequest
+  {
+  public:
+    SelectionReq( PyInterp_Interp* _py_interp,
+                  PyModuleHelper*  _helper,
+                  const QStringList& _entries )
+      : PyInterp_LockRequest( _py_interp, 0, true ), // this request should be processed synchronously (sync == true)
+        myHelper( _helper ),
+        myEntries( _entries  )
+    {
+      MESSAGE("SelectionReq");
+    }
+  protected:
+    virtual void execute()
+    {
+      MESSAGE("execute");
+      myHelper->internalSelectionUpdated( myEntries );
+    }
+  private:
+    PyModuleHelper* myHelper;
+    const QStringList& myEntries;
+  };
+
+  // post request
+  PyInterp_Dispatcher::Get()->Exec( new SelectionReq( myInterp, this, entries ) );
+}
+
 /*!
   \brief Process context popup menu request.
   
@@ -1176,7 +1221,7 @@ void PyModuleHelper::contextMenu( const QString& context, QMenu* menu )
                     const QString&   _context,
                     QMenu*           _menu )
       : PyInterp_LockRequest( _py_interp, 0, true ), // this request should be processed synchronously (sync == true)
-       myHelper ( _helper ),
+        myHelper ( _helper ),
         myContext( _context ),
         myMenu   ( _menu )
     {}
@@ -1214,7 +1259,7 @@ void PyModuleHelper::createPreferences()
   {
   public:
     CreatePrefReq( PyInterp_Interp* _py_interp,
-                  PyModuleHelper*  _helper )
+                   PyModuleHelper*  _helper )
       : PyInterp_LockRequest( _py_interp, 0, true ), // this request should be processed synchronously (sync == true)
         myHelper( _helper )
     {}
@@ -1249,11 +1294,11 @@ void PyModuleHelper::activeViewChanged( SUIT_ViewWindow* view )
   {
   public:
     ActiveViewChangeReq( PyInterp_Interp* _py_interp,
-                        PyModuleHelper*  _helper, 
-                        SUIT_ViewWindow* _view )
+                         PyModuleHelper*  _helper,
+                         SUIT_ViewWindow* _view )
       : PyInterp_LockRequest( _py_interp, 0, true ),
         myHelper( _helper ),
-       myView( _view )
+        myView( _view )
     {}
   protected:
     virtual void execute()
@@ -1283,11 +1328,11 @@ void PyModuleHelper::tryCloseView( SUIT_ViewWindow* view )
   {
   public:
     TryCloseViewReq( PyInterp_Interp* _py_interp,
-                    PyModuleHelper*  _helper, 
-                    SUIT_ViewWindow* _view )
+                     PyModuleHelper*  _helper,
+                     SUIT_ViewWindow* _view )
       : PyInterp_LockRequest( _py_interp, 0, true ),
         myHelper( _helper ), 
-       myView( _view )
+        myView( _view )
     {}
   protected:
     virtual void execute()
@@ -1314,8 +1359,8 @@ void PyModuleHelper::closeView( SUIT_ViewWindow* view )
   {
   public:
     CloseViewReq( PyInterp_Interp* _py_interp,
-                 PyModuleHelper*  _helper, 
-                 SUIT_ViewWindow* _view )
+                  PyModuleHelper*  _helper,
+                  SUIT_ViewWindow* _view )
       : PyInterp_LockRequest( _py_interp, 0, true ),
         myHelper( _helper ),
        myView( _view )
@@ -1345,11 +1390,11 @@ void PyModuleHelper::cloneView( SUIT_ViewWindow* view )
   {
   public:
     CloneViewReq( PyInterp_Interp* _py_interp,
-                 PyModuleHelper*  _helper, 
-                 SUIT_ViewWindow* _view )
+                  PyModuleHelper*  _helper,
+                  SUIT_ViewWindow* _view )
       : PyInterp_LockRequest( _py_interp, 0, true ),
         myHelper( _helper ),
-       myView( _view )
+        myView( _view )
     {}
   protected:
     virtual void execute()
@@ -1367,8 +1412,9 @@ void PyModuleHelper::cloneView( SUIT_ViewWindow* view )
 /*!
   \brief Save module data. Called when user saves study.
   \param files output list of files where module stores data
+  \param url study URL
 */
-void PyModuleHelper::save( QStringList& files )
+void PyModuleHelper::save( QStringList& files, const QString& url )
 {
   FuncMsg fmsg( "PyModuleHelper::save()" );
 
@@ -1383,34 +1429,39 @@ void PyModuleHelper::save( QStringList& files )
   {
   public:     
     SaveReq( PyInterp_Interp* _py_interp,
-            PyModuleHelper*  _helper,
-            QStringList&     _files )
+             PyModuleHelper*  _helper,
+             QStringList&     _files,
+             const QString&   _url )
       : PyInterp_LockRequest( _py_interp, 0, true ), // this request should be processed synchronously (sync == true)
         myHelper( _helper ) ,
-        myFiles( _files )
+        myFiles( _files ),
+        myUrl( _url )
     {}
   protected:
     virtual void execute()
     {
-      myHelper->internalSave( myFiles );
+      myHelper->internalSave( myFiles, myUrl );
     }
   private:
     PyModuleHelper* myHelper;
     QStringList&    myFiles;
+    QString         myUrl;
   };
   
   // Posting the request only if dispatcher is not busy!
   // Executing the request synchronously
   if ( !PyInterp_Dispatcher::Get()->IsBusy() )
-    PyInterp_Dispatcher::Get()->Exec( new SaveReq( myInterp, this, files ) );
+    PyInterp_Dispatcher::Get()->Exec( new SaveReq( myInterp, this, files, url ) );
 }
 
 /*
- \brief Load module data. Called when user opens study 
- and activates module.
- \param files list of files where module data is stored
+  \brief Load module data. Called when user opens study 
+  and activates module.
+  \param files list of files where module data is stored
+  \param url study URL
+  \return \c true if loading has been finished successfully or \c false otherwise
 */
-bool PyModuleHelper::load( const QStringList& files )
+bool PyModuleHelper::load( const QStringList& files, const QString& url )
 {
   FuncMsg fmsg( "PyModuleHelper::load()" );
 
@@ -1420,29 +1471,32 @@ bool PyModuleHelper::load( const QStringList& files )
   {
   public:
     LoadReq( PyInterp_Interp* _py_interp,
-            PyModuleHelper*  _helper,
-            QStringList      _files,
-            bool&            _loaded )
+             PyModuleHelper*  _helper,
+             QStringList      _files,
+             const QString&   _url,
+             bool&            _loaded )
       : PyInterp_LockRequest( _py_interp, 0, true ), // this request should be processed synchronously (sync == true)
         myHelper( _helper ) ,
         myFiles( _files ),
+        myUrl( _url ),
         myLoaded( _loaded )
     {}
   protected:
     virtual void execute()
     {
-      myHelper->internalLoad( myFiles, myLoaded );
+      myHelper->internalLoad( myFiles, myUrl, myLoaded );
     }
   private:
     PyModuleHelper* myHelper;
     QStringList     myFiles;
+    QString         myUrl;
     bool&           myLoaded;
   };
   
   // Posting the request only if dispatcher is not busy!
   // Executing the request synchronously
   if ( !PyInterp_Dispatcher::Get()->IsBusy() )
-    PyInterp_Dispatcher::Get()->Exec( new LoadReq( myInterp, this, files, loaded ) );
+    PyInterp_Dispatcher::Get()->Exec( new LoadReq( myInterp, this, files, url, loaded ) );
 
   return loaded;
 }
@@ -1466,8 +1520,8 @@ void PyModuleHelper::dumpPython( QStringList& files )
   {
   public:     
     DumpPythonReq( PyInterp_Interp* _py_interp,
-                  PyModuleHelper*  _helper,
-                  QStringList&     _files )
+                   PyModuleHelper*  _helper,
+                   QStringList&     _files )
       : PyInterp_LockRequest( _py_interp, 0, true ), // this request should be processed synchronously (sync == true)
         myHelper( _helper ) ,
         myFiles( _files )
@@ -1504,9 +1558,9 @@ bool PyModuleHelper::isDraggable( const SUIT_DataObject* what ) const
   {
   public:
     IsDraggableReq( PyInterp_Interp*     _py_interp,
-                   PyModuleHelper*      _helper,
-                   LightApp_DataObject* _data_object,
-                   bool&                _is_draggable )
+                    PyModuleHelper*      _helper,
+                    LightApp_DataObject* _data_object,
+                    bool&                _is_draggable )
       : PyInterp_LockRequest( _py_interp, 0, true ), // this request should be processed synchronously (sync == true)
         myHelper( _helper ) ,
         myDataObject( _data_object ),
@@ -1529,9 +1583,9 @@ bool PyModuleHelper::isDraggable( const SUIT_DataObject* what ) const
     // Executing the request synchronously
     if ( !PyInterp_Dispatcher::Get()->IsBusy() )
       PyInterp_Dispatcher::Get()->Exec( new IsDraggableReq( myInterp,
-                                                           const_cast<PyModuleHelper*>( this ),
-                                                           const_cast<LightApp_DataObject*>( data_object ),
-                                                           draggable ) );
+                                        const_cast<PyModuleHelper*>( this ),
+                                        const_cast<LightApp_DataObject*>( data_object ),
+                                        draggable ) );
   }
   
   return draggable;
@@ -1553,9 +1607,9 @@ bool PyModuleHelper::isDropAccepted( const SUIT_DataObject* where ) const
   {
   public:
     IsDropAcceptedReq( PyInterp_Interp*     _py_interp,
-                      PyModuleHelper*      _helper,
-                      LightApp_DataObject* _data_object,
-                      bool&                _is_drop_accepted )
+                       PyModuleHelper*      _helper,
+                       LightApp_DataObject* _data_object,
+                       bool&                _is_drop_accepted )
       : PyInterp_LockRequest( _py_interp, 0, true ), // this request should be processed synchronously (sync == true)
         myHelper( _helper ) ,
         myDataObject( _data_object ),
@@ -1578,9 +1632,9 @@ bool PyModuleHelper::isDropAccepted( const SUIT_DataObject* where ) const
     // Executing the request synchronously
     if ( !PyInterp_Dispatcher::Get()->IsBusy() )
       PyInterp_Dispatcher::Get()->Exec( new IsDropAcceptedReq( myInterp,
-                                                              const_cast<PyModuleHelper*>( this ),
-                                                              const_cast<LightApp_DataObject*>( data_object ),
-                                                              dropAccepted ) );
+                                         const_cast<PyModuleHelper*>( this ),
+                                         const_cast<LightApp_DataObject*>( data_object ),
+                                         dropAccepted ) );
   }
 
   return dropAccepted;
@@ -1594,7 +1648,7 @@ bool PyModuleHelper::isDropAccepted( const SUIT_DataObject* where ) const
   \param action current drop action (copy or move)
 */
 void PyModuleHelper::dropObjects( const DataObjectList& what, SUIT_DataObject* where,
-                                 const int row, Qt::DropAction action )
+                                  const int row, Qt::DropAction action )
 {
   FuncMsg fmsg( "PyModuleHelper::dropObjects()" );
 
@@ -1603,17 +1657,17 @@ void PyModuleHelper::dropObjects( const DataObjectList& what, SUIT_DataObject* w
   {
   public:
     DropObjectsReq( PyInterp_Interp*      _py_interp,
-                   PyModuleHelper*       _helper,
-                   const DataObjectList& _what,
-                   SUIT_DataObject*      _where,
-                   const int             _row,
-                   Qt::DropAction        _action )
+                    PyModuleHelper*       _helper,
+                    const DataObjectList& _what,
+                    SUIT_DataObject*      _where,
+                    const int             _row,
+                    Qt::DropAction        _action )
       : PyInterp_LockRequest( _py_interp, 0, true ), // this request should be processed synchronously (sync == true)
         myHelper( _helper ) ,
         myWhat( _what ),
-       myWhere( _where ),
-       myRow( _row ),
-       myAction ( _action )
+        myWhere( _where ),
+        myRow( _row ),
+        myAction ( _action )
     {}
   protected:
     virtual void execute()
@@ -1647,10 +1701,10 @@ QString PyModuleHelper::engineIOR() const
   public:
     EngineIORReq( PyInterp_Interp* _py_interp,
                   PyModuleHelper*  _helper,
-                 QString&         _ior )
+                  QString&         _ior )
       : PyInterp_LockRequest( _py_interp, 0, true ), // this request should be processed synchronously (sync == true)
         myHelper( _helper ),
-       myIOR( _ior )
+        myIOR( _ior )
     {}
   protected:
     virtual void execute()
@@ -1662,53 +1716,33 @@ QString PyModuleHelper::engineIOR() const
     QString&        myIOR;
   };
 
-  static QString anIOR;
-
-  if ( anIOR.isEmpty() ) {
-    // post request
-    PyInterp_Dispatcher::Get()->Exec( new EngineIORReq( myInterp, 
-                                                       const_cast<PyModuleHelper*>( this ),
-                                                       anIOR ) );
-  }
-
+  QString anIOR;
+  // post request
+  PyInterp_Dispatcher::Get()->Exec( new EngineIORReq( myInterp, 
+                                                     const_cast<PyModuleHelper*>( this ),
+                                                     anIOR ) );
   return anIOR;
 }
 
 /*!
   \brief Initialize python subinterpreter (one per study).
   \internal
-  \param studyId study ID
 */
-void PyModuleHelper::initInterp( int studyId )
+void PyModuleHelper::initInterp()
 {
   FuncMsg fmsg( "--- PyModuleHelper::initInterp()" );
 
-  // check study Id
-  if ( !studyId ) {
-    // Error! Study Id must not be 0!
-    myInterp = 0;
-    return;
-  }
-
   QMutexLocker ml( &myInitMutex );
 
-  // try to find the subinterpreter
-  if ( myInterpMap.contains( studyId ) ) {
-    // found!
-    myInterp = myInterpMap[ studyId ];
-    return;
-  }
-
   myInterp = new SALOME_PYQT_PyInterp();
   myInterp->initialize();
-  myInterpMap[ studyId ] = myInterp;
   
 #ifndef GUI_DISABLE_CORBA
   if ( !SUIT_PYTHON::initialized ) {
     // import 'salome' module and call 'salome_init' method;
     // do it only once on interpreter creation
     // ... first get python lock
-    PyLockWrapper aLock = myInterp->GetLockWrapper();
+    PyLockWrapper aLock; // Acquire GIL
     // ... then import a module
     PyObjWrapper aMod = PyImport_ImportModule( "salome" );
     if ( !aMod ) {
@@ -1718,7 +1752,7 @@ void PyModuleHelper::initInterp( int studyId )
     }
     // ... then call a method
     int embedded = 1;
-    PyObjWrapper aRes( PyObject_CallMethod( aMod, (char*)"salome_init", (char*)"ii", studyId, embedded ) );
+    PyObjWrapper aRes( PyObject_CallMethod( aMod, (char*)"salome_init", (char*)"si", NULL, embedded ) );
     if ( !aRes ) {
       // Error!
       PyErr_Print();
@@ -1732,7 +1766,7 @@ void PyModuleHelper::initInterp( int studyId )
   \brief Import Python GUI module and store reference to the module.
   \internal
 
-  Attention! initInterp() should be called first!!!
+  Warning! initInterp() should be called first!!!
 */
 void PyModuleHelper::importModule()
 {
@@ -1747,7 +1781,7 @@ void PyModuleHelper::importModule()
 
   // import Python GUI module and put it in <myPyModule> attribute
   // ... first get python lock
-  PyLockWrapper aLock = myInterp->GetLockWrapper();
+  PyLockWrapper aLock; // Acquire GIL
   // ... then import a module
   QString aMod = QString( "%1GUI" ).arg( myModule->name() );
   try {
@@ -1787,7 +1821,7 @@ void PyModuleHelper::setWorkSpace()
 
   // call setWorkSpace() method
   // ... first get python lock
-  PyLockWrapper aLock = myInterp->GetLockWrapper();
+  PyLockWrapper aLock; // Acquire GIL
 
   // ... then try to import SalomePyQt module. If it's not possible don't go on.
   PyObjWrapper aQtModule( PyImport_ImportModule( "SalomePyQt" ) );
@@ -1809,11 +1843,12 @@ void PyModuleHelper::setWorkSpace()
     if ( d )
       aWorkspace = d->workstack();
   }
-#if SIP_VERSION < 0x040800
-  PyObjWrapper pyws( sipBuildResult( 0, "M", aWorkspace, sipClass_QWidget) );
-#else
-  PyObjWrapper pyws( sipBuildResult( 0, "D", aWorkspace, sipType_QWidget , NULL) );
+#if SIP_VERSION >= 0x041300
+  static const sipTypeDef *sipType_QWidget = 0;
+  if (!sipType_QWidget)
+    sipType_QWidget = sipFindType("QWidget");
 #endif
+  PyObjWrapper pyws( sipBuildResult( 0, "D", aWorkspace, sipType_QWidget , NULL) );
   // ... and finally call Python module's setWorkSpace() method (obsolete)
   if ( PyObject_HasAttrString( myPyModule, (char*)"setWorkSpace" ) ) {
     PyObjWrapper res( PyObject_CallMethod( myPyModule, (char*)"setWorkSpace", (char*)"O", pyws.get() ) );
@@ -1851,10 +1886,9 @@ void PyModuleHelper::internalInitialize( CAM_Application* app )
   LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>( app->activeStudy() );
   if ( !aStudy )
     return;
-  int aStudyId = aStudy ? aStudy->id() : 0;
 
   // initialize Python subinterpreter (on per study) and put it in <myInterp> variable
-  initInterp( aStudyId );
+  initInterp();
   if ( !myInterp )
     return; // Error
 
@@ -1865,7 +1899,7 @@ void PyModuleHelper::internalInitialize( CAM_Application* app )
 
   // then call Python module's initialize() method
   // ... first get python lock
-  PyLockWrapper aLock = myInterp->GetLockWrapper();
+  PyLockWrapper aLock; // Acquire GIL
 
   // ... (the Python module is already imported)
   // ... finally call Python module's initialize() method
@@ -1898,9 +1932,9 @@ void PyModuleHelper::internalInitialize( CAM_Application* app )
           // parse the return value
           // it should be a map: {integer:integer}
           int aKey, aValue;
-          if( key && PyInt_Check( key ) && value && PyInt_Check( value ) ) {
-            aKey   = PyInt_AsLong( key );
-            aValue = PyInt_AsLong( value );
+          if( key && PyLong_Check( key ) && value && PyLong_Check( value ) ) {
+            aKey   = PyLong_AsLong( key );
+            aValue = PyLong_AsLong( value );
             myWindowsMap[ aKey ] = aValue;
           }
         }
@@ -1918,16 +1952,16 @@ void PyModuleHelper::internalInitialize( CAM_Application* app )
     else {
       // parse the return value
       // result can be one string...
-      if ( PyString_Check( res2 ) ) {
-        myViewMgrList.append( PyString_AsString( res2 ) );
+      if ( PyUnicode_Check( res2 ) ) {
+        myViewMgrList.append( PyUnicode_AsUTF8( res2 ) );
       }
       // ... or list of strings
       else if ( PyList_Check( res2 ) ) {
         int size = PyList_Size( res2 );
         for ( int i = 0; i < size; i++ ) {
           PyObject* value = PyList_GetItem( res2, i );
-          if( value && PyString_Check( value ) ) {
-            myViewMgrList.append( PyString_AsString( value ) );
+          if( value && PyUnicode_Check( value ) ) {
+            myViewMgrList.append( PyUnicode_AsUTF8( value ) );
           }
         }
       }
@@ -1952,10 +1986,11 @@ void PyModuleHelper::internalActivate( SUIT_Study* study )
 
   // get study Id
   LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>( study );
-  int aStudyId = aStudy ? aStudy->id() : 0;
+  if ( !aStudy )
+    return;
 
   // initialize Python subinterpreter (on per study) and put it in <myInterp> variable
-  initInterp( aStudyId );
+  initInterp();
   if ( !myInterp ) {
     myLastActivateStatus = false;
     return; // Error
@@ -1969,7 +2004,7 @@ void PyModuleHelper::internalActivate( SUIT_Study* study )
   }
 
   // get python lock
-  PyLockWrapper aLock = myInterp->GetLockWrapper();
+  PyLockWrapper aLock; // Acquire GIL
 
   // call Python module's activate() method (for the new modules)
   if ( PyObject_HasAttrString( myPyModule , (char*)"activate" ) ) {
@@ -2004,10 +2039,11 @@ void PyModuleHelper::internalCustomize( SUIT_Study* study )
 
   // get study Id
   LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>( study );
-  int aStudyId = aStudy ? aStudy->id() : 0;
+  if ( !aStudy )
+    return;
 
   // initialize Python subinterpreter (on per study) and put it in <myInterp> variable
-  initInterp( aStudyId );
+  initInterp();
   if ( !myInterp ) {
     myLastActivateStatus = false;
     return; // Error
@@ -2024,7 +2060,7 @@ void PyModuleHelper::internalCustomize( SUIT_Study* study )
   setWorkSpace();
 
   // get python lock
-  PyLockWrapper aLock = myInterp->GetLockWrapper();
+  PyLockWrapper aLock; // Acquire GIL
 
   if ( IsCallOldMethods ) {
     // call Python module's setSettings() method (obsolete)
@@ -2047,7 +2083,7 @@ void PyModuleHelper::internalCustomize( SUIT_Study* study )
 
   \param study parent study
 */
-void PyModuleHelper::internalDeactivate( SUIT_Study* study )
+void PyModuleHelper::internalDeactivate( SUIT_Study* /*study*/ )
 {
   FuncMsg fmsg( "--- PyModuleHelper::internalDeactivate()" );
 
@@ -2080,7 +2116,8 @@ void PyModuleHelper::internalClosedStudy( SUIT_Study* theStudy )
   // Get study Id
   // get study Id
   LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>( theStudy );
-  int aStudyId = aStudy ? aStudy->id() : 0;
+  if ( !aStudy )
+    return;
 
   // check that Python subinterpreter is initialized and Python module is imported
   if ( !myInterp || !myPyModule ) {
@@ -2089,7 +2126,7 @@ void PyModuleHelper::internalClosedStudy( SUIT_Study* theStudy )
   }
   // then call Python module's deactivate() method
   if ( PyObject_HasAttrString( myPyModule , (char*)"closeStudy" ) ) {
-    PyObjWrapper res( PyObject_CallMethod( myPyModule, (char*)"closeStudy", (char*)"i", aStudyId ) );
+    PyObjWrapper res( PyObject_CallMethod( myPyModule, (char*)"closeStudy", (char*)"" ) );
     if( !res ) {
       PyErr_Print();
     }
@@ -2122,8 +2159,8 @@ void PyModuleHelper::internalPreferencesChanged( const QString& section, const Q
     PyObjWrapper res( PyObject_CallMethod( myPyModule,
                                            (char*)"preferenceChanged", 
                                            (char*)"ss", 
-                                           section.toLatin1().constData(), 
-                                           setting.toLatin1().constData() ) );
+                                           section.toUtf8().constData(), 
+                                           setting.toUtf8().constData() ) );
     if( !res ) {
       PyErr_Print();
     }
@@ -2148,12 +2185,11 @@ void PyModuleHelper::internalStudyChanged( SUIT_Study* study )
 
   // get study Id
   LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>( study );
-  int id = aStudy ? aStudy->id() : 0;
-
-  fmsg.message( QString( "study id = %1" ).arg( id ) );
+  if ( !aStudy )
+    return;
 
   // initialize Python subinterpreter (on per study) and put it in <myInterp> variable
-  initInterp( id );
+  initInterp();
   if ( !myInterp )
     return; // Error
 
@@ -2166,11 +2202,11 @@ void PyModuleHelper::internalStudyChanged( SUIT_Study* study )
   setWorkSpace();
 
   // get python lock
-  PyLockWrapper aLock = myInterp->GetLockWrapper();
+  PyLockWrapper aLock; // Acquire GIL
 
   // call Python module's activeStudyChanged() method
   if ( PyObject_HasAttrString( myPyModule, (char*)"activeStudyChanged" ) ) {
-    PyObjWrapper res( PyObject_CallMethod( myPyModule, (char*)"activeStudyChanged", (char*)"i", id ) );
+    PyObjWrapper res( PyObject_CallMethod( myPyModule, (char*)"activeStudyChanged", (char*)"" ) );
     if( !res ) {
       PyErr_Print();
     }
@@ -2204,6 +2240,44 @@ void PyModuleHelper::internalActionActivated( int id )
   }
 }
 
+/*!
+  \brief update selection from other views or modules
+  \internal
+
+  Performs the following actions:
+  - calls Python module's onSelectionpdated(entries) method
+
+  \param list of entries
+*/
+void PyModuleHelper::internalSelectionUpdated(const QStringList& entries)
+{
+  FuncMsg fmsg("--- PyModuleHelper::internalSelectionUpdated()");
+  MESSAGE("internalSelectionUpdated");
+
+  // Python interpreter should be initialized and Python module should be imported first
+  if (!myInterp || !myPyModule)
+    return; // Error
+
+  QStringList* theList = new QStringList(entries);
+
+#if SIP_VERSION >= 0x041300
+  static const sipTypeDef *sipType_QStringList = 0;
+  if (!sipType_QStringList)
+    sipType_QStringList = sipFindType("QStringList");
+#endif
+  PyObjWrapper sipList( sipBuildResult( 0, "D", theList, sipType_QStringList, NULL ) );
+  if (PyObject_HasAttrString(myPyModule, (char*) "onSelectionUpdated"))
+    {
+      MESSAGE("call onSelectionUpdated");
+      PyObjWrapper res(PyObject_CallMethod(myPyModule, (char*) "onSelectionUpdated", (char*) "O", sipList.get()));
+
+      if (!res)
+        {
+          PyErr_Print();
+        }
+    }
+}
+
 /*!
   \brief Context popup menu handling callback function
   \internal
@@ -2238,9 +2312,9 @@ void PyModuleHelper::internalContextMenu( const QString& context, QMenu* menu )
     PyObjWrapper res( PyObject_CallMethod( myPyModule,
                                            (char*)"definePopup",
                                            (char*)"sss",
-                                           context.toLatin1().constData(),
-                                           aObject.toLatin1().constData(),
-                                           aParent.toLatin1().constData() ) );
+                                           context.toUtf8().constData(),
+                                           aObject.toUtf8().constData(),
+                                           aParent.toUtf8().constData() ) );
     if( !res ) {
       PyErr_Print();
     }
@@ -2260,11 +2334,12 @@ void PyModuleHelper::internalContextMenu( const QString& context, QMenu* menu )
   if ( myXmlHandler )
     myXmlHandler->createPopup( menu, aContext, aParent, aObject );
 
-#if SIP_VERSION < 0x040800
-  PyObjWrapper sipPopup( sipBuildResult( 0, "M", menu, sipClass_QMenu ) );
-#else
-  PyObjWrapper sipPopup( sipBuildResult( 0, "D", menu, sipType_QMenu, NULL ) );
+#if SIP_VERSION >= 0x041300
+  static const sipTypeDef *sipType_QMenu = 0;
+  if (!sipType_QMenu)
+    sipType_QMenu = sipFindType("QMenu");
 #endif
+  PyObjWrapper sipPopup( sipBuildResult( 0, "D", menu, sipType_QMenu, NULL ) );
 
   // then call Python module's createPopupMenu() method (for new modules)
   if ( PyObject_HasAttrString( myPyModule, (char*)"createPopupMenu" ) ) {
@@ -2272,7 +2347,7 @@ void PyModuleHelper::internalContextMenu( const QString& context, QMenu* menu )
                                             (char*)"createPopupMenu",
                                             (char*)"Os",
                                             sipPopup.get(),
-                                            context.toLatin1().constData() ) );
+                                            context.toUtf8().constData() ) );
     if( !res1 ) {
       PyErr_Print();
     }
@@ -2285,9 +2360,9 @@ void PyModuleHelper::internalContextMenu( const QString& context, QMenu* menu )
                                             (char*)"customPopup",
                                             (char*)"Osss",
                                             sipPopup.get(),
-                                            aContext.toLatin1().constData(),
-                                            aObject.toLatin1().constData(),
-                                            aParent.toLatin1().constData() ) );
+                                            aContext.toUtf8().constData(),
+                                            aObject.toUtf8().constData(),
+                                            aParent.toUtf8().constData() ) );
     if( !res2 ) {
       PyErr_Print();
     }
@@ -2414,8 +2489,9 @@ void PyModuleHelper::internalCloneView( SUIT_ViewWindow* view )
   \brief Module data saving callback function.
   \internal
   \param files output list of files where module stores data
+  \param url study URL
 */
-void PyModuleHelper::internalSave( QStringList& files )
+void PyModuleHelper::internalSave( QStringList& files, const QString& url )
 {
   FuncMsg fmsg( "--- PyModuleHelper::internalSave()" );
 
@@ -2427,17 +2503,24 @@ void PyModuleHelper::internalSave( QStringList& files )
 
   if ( PyObject_HasAttrString(myPyModule, (char*)"saveFiles") ) {
 
+    // try with two parameters (new syntax)
     PyObjWrapper res( PyObject_CallMethod( myPyModule, (char*)"saveFiles",
-                                           (char*)"s", files.first().toLatin1().constData() ) );
-
+                                           (char*)"ss",
+                                           files.first().toUtf8().constData(),
+                                           url.toUtf8().constData() ) );
+    if ( !res )
+      // try with single parameter (old syntax)
+      res = PyObject_CallMethod( myPyModule, (char*)"saveFiles",
+                                 (char*)"s", files.first().toUtf8().constData() );
+    
     if ( !res ) {
       PyErr_Print();
     }
     else {
       // parse the return value
       // result can be one string...
-      if ( PyString_Check( res ) ) {
-        QString astr = PyString_AsString( res );
+      if ( PyUnicode_Check( res ) ) {
+        QString astr = PyUnicode_AsUTF8( res );
         files.append( astr );
       }
       //also result can be a list...
@@ -2445,8 +2528,8 @@ void PyModuleHelper::internalSave( QStringList& files )
         int size = PyList_Size( res );
         for ( int i = 0; i < size; i++ ) {
           PyObject* value = PyList_GetItem( res, i );
-          if ( value && PyString_Check( value ) ) {
-            files.append( PyString_AsString( value ) );
+          if ( value && PyUnicode_Check( value ) ) {
+            files.append( PyUnicode_AsUTF8( value ) );
           }
         }
       }
@@ -2458,9 +2541,10 @@ void PyModuleHelper::internalSave( QStringList& files )
   \brief Module data loading callback function.
   \internal
   \param files list of files where module data is stored
+  \param url study URL
   \param opened output success flag
 */
-void PyModuleHelper::internalLoad( const QStringList& files, bool& opened )
+void PyModuleHelper::internalLoad( const QStringList& files, const QString& url, bool& opened )
 {
   FuncMsg fmsg( "--- PyModuleHelper::internalLoad()" );
 
@@ -2471,19 +2555,29 @@ void PyModuleHelper::internalLoad( const QStringList& files, bool& opened )
 
   QStringList* theList = new QStringList( files );
 
-#if SIP_VERSION < 0x040800
-  PyObjWrapper sipList( sipBuildResult( 0, "M", theList, sipClass_QStringList ) );
-#else
-  PyObjWrapper sipList( sipBuildResult( 0, "D", theList, sipType_QStringList, NULL ) );
+#if SIP_VERSION >= 0x041300
+  static const sipTypeDef *sipType_QStringList = 0;
+  if (!sipType_QStringList)
+    sipType_QStringList = sipFindType("QStringList");
 #endif
+  PyObjWrapper sipList( sipBuildResult( 0, "D", theList, sipType_QStringList, NULL ) );
   if ( PyObject_HasAttrString(myPyModule , (char*)"openFiles") ) {
+
+    // try with two parameters (new syntax)
     PyObjWrapper res( PyObject_CallMethod( myPyModule, (char*)"openFiles",
-                                           (char*)"O", sipList.get()));
-    if( !res || !PyBool_Check( res )) {
+                                           (char*)"Os", sipList.get(),
+                                           url.toUtf8().constData() ) );
+
+    if ( !res )
+      // try with single parameter (old syntax)
+      res = PyObject_CallMethod( myPyModule, (char*)"openFiles",
+                                 (char*)"O", sipList.get() );
+
+    if ( !res || !PyBool_Check( res ) ) {
       PyErr_Print();
       opened = false;
     }
-    else{
+    else {
       opened = PyObject_IsTrue( res );
     }
   }
@@ -2506,7 +2600,7 @@ void PyModuleHelper::internalDumpPython( QStringList& files )
 
   if ( PyObject_HasAttrString(myPyModule, (char*)"dumpStudy") ) {
     PyObjWrapper res( PyObject_CallMethod( myPyModule, (char*)"dumpStudy",
-                                           (char*)"s", files.first().toLatin1().constData()));
+                                           (char*)"s", files.first().toUtf8().constData()));
 
     if ( !res ) {
       PyErr_Print();
@@ -2514,8 +2608,8 @@ void PyModuleHelper::internalDumpPython( QStringList& files )
     else {
       // parse the return value
       // result can be one string...
-      if ( PyString_Check( res ) ) {
-        QString astr = PyString_AsString( res );
+      if ( PyUnicode_Check( res ) ) {
+        QString astr = PyUnicode_AsUTF8( res );
         //SCRUTE(astr);
         files.append(astr);
       }
@@ -2524,8 +2618,8 @@ void PyModuleHelper::internalDumpPython( QStringList& files )
         int size = PyList_Size( res );
         for ( int i = 0; i < size; i++ ) {
           PyObject* value = PyList_GetItem( res, i );
-          if( value && PyString_Check( value ) ) {
-            files.append( PyString_AsString( value ) );
+          if( value && PyUnicode_Check( value ) ) {
+            files.append( PyUnicode_AsUTF8( value ) );
           }
         }
       }
@@ -2552,7 +2646,7 @@ bool PyModuleHelper::internalIsDraggable( LightApp_DataObject* what )
 
   if ( PyObject_HasAttrString(myPyModule , (char*)"isDraggable") ) {
     PyObjWrapper res( PyObject_CallMethod( myPyModule, (char*)"isDraggable",
-                                          (char*)"s", what->entry().toLatin1().constData() ) );
+                      (char*)"s", what->entry().toUtf8().constData() ) );
     if( !res || !PyBool_Check( res )) {
       PyErr_Print();
       draggable = false;
@@ -2584,7 +2678,7 @@ bool PyModuleHelper::internalIsDropAccepted( LightApp_DataObject* where )
 
   if ( PyObject_HasAttrString(myPyModule , (char*)"isDropAccepted") ) {
     PyObjWrapper res( PyObject_CallMethod( myPyModule, (char*)"isDropAccepted",
-                                          (char*)"s", where->entry().toLatin1().constData() ) );
+                      (char*)"s", where->entry().toUtf8().constData() ) );
     if( !res || !PyBool_Check( res )) {
       PyErr_Print();
       dropAccepted = false;
@@ -2606,7 +2700,7 @@ bool PyModuleHelper::internalIsDropAccepted( LightApp_DataObject* where )
   \param action current drop action (copy or move)
 */
 void PyModuleHelper::internalDropObjects( const DataObjectList& what, SUIT_DataObject* where,
-                                         const int row, Qt::DropAction action )
+                                          const int row, Qt::DropAction action )
 {
   FuncMsg fmsg( "--- PyModuleHelper::internalDropObjects()" );
 
@@ -2625,16 +2719,17 @@ void PyModuleHelper::internalDropObjects( const DataObjectList& what, SUIT_DataO
     if ( dataObject ) theList->append( dataObject->entry() );
   }
 
-#if SIP_VERSION < 0x040800
-  PyObjWrapper sipList( sipBuildResult( 0, "M", theList, sipClass_QStringList) );
-#else
-  PyObjWrapper sipList( sipBuildResult( 0, "D", theList, sipType_QStringList, NULL) );
+#if SIP_VERSION >= 0x041300
+  static const sipTypeDef *sipType_QStringList = 0;
+  if (!sipType_QStringList)
+    sipType_QStringList = sipFindType("QStringList");
 #endif
+  PyObjWrapper sipList( sipBuildResult( 0, "D", theList, sipType_QStringList, NULL) );
   if ( PyObject_HasAttrString(myPyModule, (char*)"dropObjects") ) {
-    PyObjWrapper res( PyObject_CallMethod( myPyModule, (char*)"dropObjects", (char*)"Osii",
-                                          sipList.get(),
-                                          whereObject->entry().toLatin1().constData(),
-                                          row, action ) );
+      PyObjWrapper res( PyObject_CallMethod( myPyModule, (char*)"dropObjects", (char*)"Osii",
+                        sipList.get(),
+                        whereObject->entry().toUtf8().constData(),
+                        row, action ) );
     
     if( !res ) {
       PyErr_Print();
@@ -2663,13 +2758,13 @@ QString PyModuleHelper::internalEngineIOR() const
     if ( PyObject_HasAttrString( myPyModule , "engineIOR" ) ) {
       PyObjWrapper res( PyObject_CallMethod( myPyModule, (char*)"engineIOR", (char*)"" ) );
       if ( !res ) {
-       PyErr_Print();
+          PyErr_Print();
       }
       else {
-       // parse the return value, result chould be string
-       if ( PyString_Check( res ) ) {
-         ior = PyString_AsString( res );
-       }
+        // parse the return value, result chould be string
+        if ( PyUnicode_Check( res ) ) {
+          ior = PyUnicode_AsUTF8( res );
+        }
       }
     }
   }
@@ -2688,24 +2783,24 @@ void PyModuleHelper::connectView( SUIT_ViewWindow* view )
   // Connect tryCloseView() and deleteView() signals
   if ( viewMgr ) {
     connect( viewMgr, SIGNAL( tryCloseView( SUIT_ViewWindow* ) ),
-            this, SLOT( tryCloseView( SUIT_ViewWindow* ) ),
-            Qt::UniqueConnection );
+             this, SLOT( tryCloseView( SUIT_ViewWindow* ) ),
+             Qt::UniqueConnection );
     connect( viewMgr, SIGNAL( deleteView( SUIT_ViewWindow* ) ),
              this, SLOT( closeView( SUIT_ViewWindow* ) ),
-            Qt::UniqueConnection );
+             Qt::UniqueConnection );
   }
   
   // Connect cloneView() signal of an OCC View
   if ( view->inherits( "OCCViewer_ViewWindow" ) ) {
     connect( view, SIGNAL( viewCloned( SUIT_ViewWindow* ) ), 
              this, SLOT( cloneView( SUIT_ViewWindow* ) ),
-            Qt::UniqueConnection );
+             Qt::UniqueConnection );
   }
   // Connect cloneView() signal of Plot2d View 
   else if ( viewModel && viewModel->inherits( "Plot2d_Viewer" ) ) {
     connect( viewModel, SIGNAL( viewCloned( SUIT_ViewWindow* ) ), 
              this, SLOT( cloneView( SUIT_ViewWindow* ) ),
-            Qt::UniqueConnection );
+             Qt::UniqueConnection );
   }
 }
 
@@ -2721,7 +2816,7 @@ void PyModuleHelper::internalOBClickedPython( const QString& theObj, int theColu
     return; // Error
 
   if ( PyObject_HasAttrString( myPyModule, (char*)"onObjectBrowserClicked" ) ) {
-    PyObjWrapper res( PyObject_CallMethod( myPyModule, (char*)"onObjectBrowserClicked", (char*)"si", theObj.toLatin1().constData(), theColumn ) );
+    PyObjWrapper res( PyObject_CallMethod( myPyModule, (char*)"onObjectBrowserClicked", (char*)"si", theObj.toUtf8().constData(), theColumn ) );
     if( !res ) {
       PyErr_Print();
     }
@@ -2759,8 +2854,8 @@ void PyModuleHelper::onObjectBrowserClicked(SUIT_DataObject* theObj, int theColu
     }
   private:
     PyModuleHelper* myHelper;
-    int    myColumn;
     QString myEntry;
+    int myColumn;
   };
   
   // Posting the request only if dispatcher is not busy!