]> SALOME platform Git repositories - modules/gui.git/blobdiff - src/LightApp/LightApp_Application.cxx
Salome HOME
bos #19960: [CEA 19958] Show/Hide SHAPERSTUDY objects
[modules/gui.git] / src / LightApp / LightApp_Application.cxx
index f33201e5b046166fb6557b7906f44e21a8b67ae7..249ce2fd1a3f12f2a58ff382335163dbd5bc750c 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2019  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2020  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
@@ -88,6 +88,7 @@
 #include <QtxFontEdit.h>
 #include <QtxToolBar.h>
 #include <QtxTreeView.h>
+#include <QtxInfoPanel.h>
 #include <QtxMRUAction.h>
 #include <QtxDockAction.h>
 #include <QtxDockWidget.h>
@@ -260,7 +261,7 @@ namespace
     int inputLen = input.length();
     QDataStream anInputData( &input, QIODevice::ReadOnly );
     while ( tmp < inputLen ) {
-      tmp = input.indexOf( QToolBarMarker, tmp + 1 );
+      tmp = input.indexOf( (uchar)QToolBarMarker, tmp + 1 );
       if ( tmp < 0 )
         break;
       anInputData.device()->seek( tmp );
@@ -464,7 +465,7 @@ void LightApp_Application::closeApplication()
 #ifndef DISABLE_QTXWEBBROWSER
   QProcess::startDetached( "HelpBrowser",
                            QStringList() << QString( "--remove=%1" ).arg( QApplication::instance()->applicationPid() ) );
-#endif  
+#endif
   CAM_Application::closeApplication();
 }
 
@@ -526,6 +527,9 @@ bool LightApp_Application::activateModule( const QString& modName )
 
   saveDockWindowsState();
 
+  if ( infoPanel() )
+    infoPanel()->clear();
+
   bool status = CAM_Application::activateModule( modName );
 
   updateModuleActions();
@@ -539,7 +543,7 @@ bool LightApp_Application::activateModule( const QString& modName )
   updateViewManagers();
 
   if ( activeStudy() && activeStudy()->root() && objectBrowser() ) {
-    if ( objectBrowser()->root() != activeStudy()->root() ) 
+    if ( objectBrowser()->root() != activeStudy()->root() )
       objectBrowser()->setRoot( activeStudy()->root() );
     updateObjectBrowser( true );
   }
@@ -594,33 +598,31 @@ void LightApp_Application::createActions()
   // Help menu
 
   int helpMenu = createMenu( tr( "MEN_DESK_HELP" ), -1, -1, 1000 );
-  
+
   int id = LightApp_Application::UserID + FIRST_HELP_ID;
 
   // a) Link to web site
   QString url = resMgr->stringValue("GUI", "site_url");
   if ( !url.isEmpty() ) {
     QString title = tr ( "SALOME_SITE" );
-    QAction* as = createAction( id, title,
+    QAction* as = createAction( WebSiteId, title,
                                resMgr->loadPixmap( "LightApp", tr( "ICON_WWW" ), false ),
                                title, title,
                                0, desk, false, this, SLOT( onHelpContentsModule() ) );
     as->setData( url );
     createMenu( as, helpMenu, -1, 0 );
-    id++;
   }
 
   // b) Link to Forum
   url = resMgr->stringValue("GUI", "forum_url");
   if ( !url.isEmpty() ) {
     QString title = tr ( "SALOME_FORUM" );
-    QAction* af = createAction( helpMenu, title,
+    QAction* af = createAction( ForumId, title,
                                resMgr->loadPixmap( "LightApp", tr( "ICON_WWW" ), false ),
                                title, title,
                                0, desk, false, this, SLOT( onHelpContentsModule() ) );
     af->setData( url );
     createMenu( af, helpMenu, -1, 0 );
-    id++;
   }
 
   // c) Link to YouTube channel
@@ -628,16 +630,28 @@ void LightApp_Application::createActions()
   if ( !url.isEmpty() ) {
     createMenu( separator(), helpMenu, -1, 0 );
     QString title = tr ( "SALOME_VIDEO_TUTORIALS" );
-    QAction* av = createAction( helpMenu, title,
+    QAction* av = createAction( VideosId, title,
                                resMgr->loadPixmap( "LightApp", tr( "ICON_LIFE_RIGN" ), false ),
-                               title, title,
+                               title, tr( "PRP_SALOME_VIDEO_TUTORIALS" ),
                                0, desk, false, this, SLOT( onHelpContentsModule() ) );
     av->setData( url );
     createMenu( av, helpMenu, -1, 0 );
-    id++;
   }
 
-  // d) Help for modules
+  // d) Link to Tutorials
+
+  url = resMgr->stringValue("GUI", "tutorials_url");
+  if ( !url.isEmpty() ) {
+    QString title = tr ( "SALOME_TUTORIALS" );
+    QAction* as = createAction( TutorialsId, title,
+                               resMgr->loadPixmap( "LightApp", tr( "ICON_WWW" ), false ),
+                               title, tr( "PRP_SALOME_TUTORIALS" ),
+                               0, desk, false, this, SLOT( onHelpContentsModule() ) );
+    as->setData( url );
+    createMenu( as, helpMenu, -1, 0 );
+  }
+
+  // e) Help for modules
 
   // - First create top-level menus to preserve correct order
   QString userGuide = "User's Guide";
@@ -705,7 +719,7 @@ void LightApp_Application::createActions()
     IMapConstIterator<QString, QString > fileIt;
     for ( fileIt = helpData.begin(); fileIt != helpData.end(); fileIt++ ) {
       QString helpItemPath = fileIt.key();
-      // remove all '//' occurances 
+      // remove all '//' occurances
       while ( helpItemPath.contains( "//" ) )
         helpItemPath.replace( "//", "" );
       // obtain submenus hierarchy if given
@@ -719,7 +733,7 @@ void LightApp_Application::createActions()
        if ( total.count() == 1 && smenus.count() > 0 )
          helpItemPath = smenus.takeLast();
       }
-      QPixmap helpIcon = fileIt.value().startsWith( "http", Qt::CaseInsensitive ) ? 
+      QPixmap helpIcon = fileIt.value().startsWith( "http", Qt::CaseInsensitive ) ?
         resMgr->loadPixmap( "STD", tr( "ICON_WWW" ), false ) : resMgr->loadPixmap( "STD", tr( "ICON_HELP" ), false );
       QAction* a = createAction( id, helpItemPath, helpIcon, helpItemPath, helpItemPath,
                                  0, desk, false, this, SLOT( onHelpContentsModule() ) );
@@ -745,9 +759,9 @@ void LightApp_Application::createActions()
     QString valueStr = resMgr->stringValue( "add_help", paramName );
     if ( !valueStr.isEmpty() ) {
       QStringList valueItems = valueStr.split( ";;", QString::SkipEmptyParts );
-      foreach( QString item, valueItems ) { 
+      foreach( QString item, valueItems ) {
         if ( item.startsWith( "http", Qt::CaseInsensitive ) || QFile::exists( item ) ) {
-          QPixmap helpIcon = item.startsWith( "http", Qt::CaseInsensitive ) ? 
+          QPixmap helpIcon = item.startsWith( "http", Qt::CaseInsensitive ) ?
             resMgr->loadPixmap( "STD", tr( "ICON_WWW" ), false ) : resMgr->loadPixmap( "STD", tr( "ICON_HELP" ), false );
           QAction* a = createAction( id++, paramName, helpIcon, paramName, paramName,
                                      0, desk, false, this, SLOT( onHelpContentsModule() ) );
@@ -790,9 +804,6 @@ void LightApp_Application::createActions()
     QStringList::Iterator it;
     for ( it = modList.begin(); it != modList.end(); ++it )
     {
-      if ( !isModuleAccessible( *it ) )
-        continue;
-
       QString modName = moduleName( *it );
 
       QString iconName;
@@ -1009,7 +1020,7 @@ void LightApp_Application::onNewDoc()
 
   //asl: fix for 0020515
   saveDockWindowsState();
-  
+
   CAM_Application::onNewDoc();
 }
 
@@ -1027,7 +1038,6 @@ void LightApp_Application::onOpenDoc()
   if ( aName.isNull() ) //Cancel
     return;
   
-  closeDoc(false);
   onOpenDoc( aName );
   
   if ( !study ) // new study will be create in THIS application
@@ -1037,12 +1047,30 @@ void LightApp_Application::onOpenDoc()
   }
 }
 
+bool LightApp_Application::canOpenDoc( const QString& )
+{
+  return true;
+}
+
 /*!
   SLOT: Opens new document.
   \param aName - name of file
 */
 bool LightApp_Application::onOpenDoc( const QString& aName )
 {
+  if ( !canOpenDoc(aName)) {
+    bool showError = !property("open_study_from_command_line").isValid() ||
+      !property("open_study_from_command_line").toBool();
+
+    putInfo( tr("OPEN_DOCUMENT_PROBLEM") );
+    if ( showError )
+      SUIT_MessageBox::critical( desktop(), tr("ERR_ERROR"), tr("OPEN_DOCUMENT_PROBLEM"));
+
+    return false;
+  }
+
+  closeDoc(false);
+
   if ( !checkExistingDoc() )
     return false;
 
@@ -1050,7 +1078,7 @@ bool LightApp_Application::onOpenDoc( const QString& aName )
 
   // We should take mru action first because this application instance can be deleted later.
   QtxMRUAction* mru = ::qobject_cast<QtxMRUAction*>( action( MRUId ) );
-  
+
   bool res = CAM_Application::onOpenDoc( aName );
 
   if ( mru )
@@ -1192,12 +1220,17 @@ protected:
   {
     if ( !myBrowser.isEmpty() && !myUrl.isEmpty() )
     {
+      QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
 #ifdef WIN32
       QString cmdLine = QString( "\"%1\" %2 \"%3\"" ).arg( myBrowser, myParameters, myUrl );
 #else
       QString cmdLine = QString( "%1 %2 \"%3\"" ).arg( myBrowser, myParameters, myUrl );
+      // remove LD_LIBRARY_PATH from the environement before starting launcher to avoid bad interactions.
+      // (especially in the case of universal binaries) 
+      env.remove("LD_LIBRARY_PATH");
 #endif
       QProcess* proc = new QProcess();
+      proc->setProcessEnvironment(env);
       proc->start( cmdLine );
       if ( !proc->waitForStarted() )
       {
@@ -1222,7 +1255,7 @@ void LightApp_Application::showHelp( const QString& path )
 
 #if DISABLE_QTXWEBBROWSER
   bool useExternalBrowser = true;
-#else  
+#else
   bool useExternalBrowser = resMgr->booleanValue("ExternalBrowser", "use_external_browser", false );
 #endif
 
@@ -1234,7 +1267,7 @@ void LightApp_Application::showHelp( const QString& path )
     QString browser = resMgr->stringValue( "ExternalBrowser", "application" );
 #endif
     QString parameters = resMgr->stringValue("ExternalBrowser", "parameters");
-  
+
     if ( !browser.isEmpty() )
     {
       RunBrowser::execute( this, browser, parameters, path );
@@ -1244,8 +1277,12 @@ void LightApp_Application::showHelp( const QString& path )
       if ( SUIT_MessageBox::question( desktop(), tr( "WRN_WARNING" ), tr( "DEFINE_EXTERNAL_BROWSER" ),
                                       SUIT_MessageBox::Yes | SUIT_MessageBox::No,
                                       SUIT_MessageBox::Yes ) == SUIT_MessageBox::Yes )
-
-        showPreferences( tr( "PREF_APP" ) );
+      {
+        QStringList path;
+        path << tr( "PREF_CATEGORY_SALOME" ) << tr( "PREF_TAB_GENERAL" )
+             << tr( "PREF_GROUP_EXT_BROWSER" ) << tr( "PREF_APP" );
+        showPreferences( path );
+      }
     }
   }
   else
@@ -1351,9 +1388,18 @@ void LightApp_Application::insertDockWindow( const int id, QWidget* wid )
   myWin.insert( id, wid );
 
   QtxDockWidget* dock = new QtxDockWidget( true, desktop() );
+  if ( id == WT_InfoPanel ) {
+    // Info panel's position is strongly limited to the right area;
+    // It is not movable and not floatable.
+    dock->setAllowedAreas( Qt::RightDockWidgetArea );
+    dock->setFeatures( QDockWidget::DockWidgetClosable );
+    connect( dock, SIGNAL( aboutToShow()), this, SLOT( onInfoPanelShown() ) );
+  }
+  else {
+    dock->setFeatures( QDockWidget::AllDockWidgetFeatures );
+  }
   connect( dock, SIGNAL(  destroyed( QObject* ) ), this, SLOT( onWCDestroyed( QObject* ) ) );
 
-  dock->setFeatures( QDockWidget::AllDockWidgetFeatures );
   dock->setObjectName( wid->objectName().isEmpty() ? QString( "window_%1" ).arg( id ) :
                        QString( "%1Dock" ).arg( wid->objectName() ) );
   dock->setWidget( wid );
@@ -1423,6 +1469,11 @@ SUIT_DataBrowser* LightApp_Application::objectBrowser()
   return qobject_cast<SUIT_DataBrowser*>( dockWindow( WT_ObjectBrowser ) );
 }
 
+QtxInfoPanel* LightApp_Application::infoPanel()
+{
+  return qobject_cast<QtxInfoPanel *>( dockWindow( WT_InfoPanel ));
+}
+
 /*!
   \return Log Window
 */
@@ -1437,7 +1488,7 @@ LogWindow* LightApp_Application::logWindow()
   when you request the python console, this function could return
   null. Then the optional parameter force (default to false) can be
   set to force the creation of the python console if it is not done
-  already. 
+  already.
   \param force - if true, the pythonConsole is created if it does not exist yet
   \return Python Console
 */
@@ -1632,6 +1683,7 @@ SUIT_ViewManager* LightApp_Application::createViewManager( const QString& vmType
                                resMgr->doubleValue( "OCCViewer", "focus_value", vm->stereographicFocusValue() ));
     vm->setInterocularDistance( resMgr->integerValue( "OCCViewer", "iod_type", vm->interocularDistanceType() ),
                                 resMgr->doubleValue( "OCCViewer", "iod_value", vm->interocularDistanceValue() ));
+    vm->setSelectionStyle((OCCViewer_ViewWindow::SelectionStyle) resMgr->integerValue( "OCCViewer", "adv_selection_mode", vm->selectionStyle() ) );
 
     vm->setReverseStereo( resMgr->booleanValue( "OCCViewer", "reverse_stereo", vm->isReverseStereo() ) );
     vm->setVSync( resMgr->booleanValue( "OCCViewer", "enable_vsync", vm->isVSync() ) );
@@ -1774,6 +1826,7 @@ void LightApp_Application::onStudyCreated( SUIT_Study* theStudy )
   }
 
   getWindow( WT_ObjectBrowser );
+  getWindow( WT_InfoPanel );
 
   loadDockWindowsState();
 
@@ -1805,6 +1858,7 @@ void LightApp_Application::onStudyOpened( SUIT_Study* theStudy )
   }
 
   getWindow( WT_ObjectBrowser );
+  getWindow( WT_InfoPanel );
 
   loadDockWindowsState();
 
@@ -1835,7 +1889,7 @@ void LightApp_Application::onStudySaved( SUIT_Study* s )
 }
 
 /*!Protected SLOT. On study closed.*/
-void LightApp_Application::onStudyClosed( SUIT_Study* s )
+void LightApp_Application::onStudyClosed( SUIT_Study* /*s*/ )
 {
   /*
   disconnect( this, SIGNAL( viewManagerRemoved( SUIT_ViewManager* ) ),
@@ -1975,7 +2029,12 @@ void LightApp_Application::onPreferences()
 }
 
 /*!Private SLOT. On preferences.*/
-void LightApp_Application::showPreferences( const QString& itemText )
+void LightApp_Application::showPreferences( const QString& path )
+{
+  showPreferences( QStringList() << path );
+}
+
+void LightApp_Application::showPreferences( const QStringList& path )
 {
   QApplication::setOverrideCursor( Qt::WaitCursor );
 
@@ -1986,7 +2045,7 @@ void LightApp_Application::showPreferences( const QString& itemText )
   if ( !prefDlg )
     return;
 
-  preferences()->activateItem( itemText );
+  preferences()->activateItem( path );
 
   if ( ( prefDlg->exec() == QDialog::Accepted || prefDlg->isSaved() ) &&  resourceMgr() )
   {
@@ -2098,17 +2157,20 @@ QWidget* LightApp_Application::createWindow( const int flag )
 
     // Create OBSelector
     new LightApp_OBSelector( ob, mySelMgr );
-#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
-    ob->treeView()->header()->setResizeMode(SUIT_DataObject::VisibilityId, QHeaderView::Fixed);
-#else
     ob->treeView()->header()->setSectionResizeMode(SUIT_DataObject::VisibilityId, QHeaderView::Fixed);
-#endif
     ob->treeView()->header()->moveSection(SUIT_DataObject::NameId,SUIT_DataObject::VisibilityId);
     ob->treeView()->setColumnWidth(SUIT_DataObject::VisibilityId, VISIBILITY_COLUMN_WIDTH);
     ob->setProperty( "shortcut", QKeySequence( "Alt+Shift+O" ) );
     wid = ob;
     ob->connectPopupRequest( this, SLOT( onConnectPopupRequest( SUIT_PopupClient*, QContextMenuEvent* ) ) );
   }
+  else if ( flag == WT_InfoPanel)
+  {
+    QtxInfoPanel* ipanel = new QtxInfoPanel( desktop() );
+    ipanel->setObjectName( "infoPanel" );
+    ipanel->setWindowTitle( tr( "INFO_PANEL" ) );
+    wid = ipanel;
+  }
 #ifndef DISABLE_PYCONSOLE
   else  if ( flag == WT_PyConsole )
   {
@@ -2146,6 +2208,7 @@ void LightApp_Application::defaultWindows( QMap<int, int>& aMap ) const
 #endif
   if ( activeStudy() ) {
     aMap.insert( WT_ObjectBrowser, Qt::LeftDockWidgetArea );
+    aMap.insert( WT_InfoPanel, Qt::RightDockWidgetArea );
     //  aMap.insert( WT_LogWindow, Qt::DockBottom );
   }
 }
@@ -2194,42 +2257,48 @@ LightApp_Preferences* LightApp_Application::preferences( const bool crt ) const
     if ( !app )
       continue;
 
-    QStringList modNameList;
-    app->modules( modNameList, false );
+    // all modules available in current session
+    QStringList names;
+    app->modules( names, false );
 
-    QMap<QString, QString> iconMap;
-    app->moduleIconNames( iconMap );
+    // icons of modules
+    QMap<QString, QString> icons;
+    app->moduleIconNames( icons );
 
-    for ( QStringList::const_iterator it = modNameList.begin(); it != modNameList.end(); ++it )
+    // step 1: iterate through list of all available modules
+    // and add empty preferences page
+    for ( QStringList::const_iterator it = names.begin(); it != names.end(); ++it )
     {
-      if ( !app->isModuleAccessible( *it ) || _prefs_->hasModule( *it ) )
-        continue;
-
-      int modId = _prefs_->addPreference( *it );
-      if ( iconMap.contains( *it ) )
-        _prefs_->setItemIcon( modId, Qtx::scaleIcon( resMgr->loadPixmap( moduleName( *it ), iconMap[*it], false ), 20 ) );
+      if ( !_prefs_->hasModule( *it ) ) // prevent possible duplications
+      {
+        int modId = _prefs_->addPreference( *it ); // add empty page
+        if ( icons.contains( *it ) )               // set icon
+          _prefs_->setItemIcon( modId, Qtx::scaleIcon( resMgr->loadPixmap( moduleName( *it ),
+                                                                           icons[*it], false ), 20 ) );
+      }
     }
 
-    ModuleList modList;
-    app->modules( modList );
-    QListIterator<CAM_Module*> itr( modList );
+    // step 2: iterate through list of all loaded modules
+    // and initialize their preferences
+    ModuleList loadedModules;
+    app->modules( loadedModules );
+    QListIterator<CAM_Module*> itr( loadedModules );
     while ( itr.hasNext() )
     {
-      LightApp_Module* mod = 0;
-
-      CAM_Module* anItem = itr.next();
-      if ( anItem->inherits( "LightApp_Module" ) )
-        mod = (LightApp_Module*)anItem;
+      LightApp_Module* module = 0;
+      CAM_Module* m = itr.next();
+      if ( m->inherits( "LightApp_Module" ) )
+        module = (LightApp_Module*)m;
 
-      if ( mod && !_prefs_->hasModule( mod->moduleName() ) )
+      if ( module && !_prefs_->hasModule( module->moduleName() ) )
       {
-        _prefs_->addPreference( mod->moduleName() );
-        mod->createPreferences();
-        that->emptyPreferences( mod->moduleName() );
+        _prefs_->addPreference( module->moduleName() ); // add page (for sure, had to be done at step 1)
+        module->createPreferences();                    // initialize preferences
+        that->emptyPreferences( module->moduleName() ); // show dummy page if module does not export any preferences
       }
     }
   }
-  _prefs_->setItemProperty( "info", tr( "PREFERENCES_NOT_LOADED" ) );
+  _prefs_->setItemProperty( "info", tr( "PREFERENCES_NOT_LOADED" ) ); // dummy page for modules which are not loaded yet
 
   return myPrefs;
 }
@@ -2319,7 +2388,7 @@ void LightApp_Application::createPreferences( LightApp_Preferences* pref )
   pref->addPreference( tr( "PREF_SHOW_SPLASH" ), lookGroup, LightApp_Preferences::Bool, "launch", "splash" );
   // .... -> opaque resize
   pref->addPreference( tr( "PREF_OPAQUE_RESIZE" ), lookGroup, LightApp_Preferences::Bool, "desktop", "opaque_resize" );
-  // .... -> drop-down buttons 
+  // .... -> drop-down buttons
   pref->addPreference( tr( "PREF_DROP_DOWN_BUTTONS" ), lookGroup, LightApp_Preferences::Bool, "viewers", "drop_down_buttons" );
   // .... -> Notification timeout
   int delay = pref->addPreference( tr( "PREF_NOTIFY_TIMEOUT" ), lookGroup, LightApp_Preferences::IntSpin, "notification", "timeout" );
@@ -2588,13 +2657,22 @@ void LightApp_Application::createPreferences( LightApp_Preferences* pref )
 
   // ... "Selection" group <<start>>
   int occSelectionGroup = pref->addPreference( tr( "PREF_GROUP_SELECTION" ), occGroup );
-  pref->setItemProperty( "columns", 2, occSelectionGroup );
+  pref->setItemProperty( "columns", 3, occSelectionGroup );
   // .... -> enable preselection
   pref->addPreference( tr( "PREF_ENABLE_PRESELECTION" ), occSelectionGroup,
                        LightApp_Preferences::Bool, "OCCViewer", "enable_preselection" );
   // .... -> enable selection
   pref->addPreference( tr( "PREF_ENABLE_SELECTION" ), occSelectionGroup,
                        LightApp_Preferences::Bool, "OCCViewer", "enable_selection" );
+  // .... -> selection style
+  int aSeleStyle = pref->addPreference( tr( "PREF_SELECTION_STYLE" ), occSelectionGroup,
+                       LightApp_Preferences::Selector, "OCCViewer", "adv_selection_mode" );
+  aValuesList.clear();
+  anIndicesList.clear();
+  aValuesList   << tr("PREF_POLYGON_SELECTION") << tr("PREF_CIRCLE_SELECTION");
+  anIndicesList << 0 << 1;
+  pref->setItemProperty( "strings", aValuesList, aSeleStyle);
+  pref->setItemProperty( "indexes", anIndicesList, aSeleStyle);
   // ... "Selection" group <<end>>
 
   // ... "Clipping" group <<start>>
@@ -3305,6 +3383,27 @@ void LightApp_Application::preferencesChanged( const QString& sec, const QString
   }
 #endif
 
+
+#ifndef DISABLE_OCCVIEWER
+  if (sec == QString("OCCViewer") && param == QString("adv_selection_mode"))
+  {
+    int mode = resMgr->integerValue("OCCViewer", "adv_selection_mode", 0);
+    QList<SUIT_ViewManager*> lst;
+    viewManagers(OCCViewer_Viewer::Type(), lst);
+    QListIterator<SUIT_ViewManager*> it(lst);
+    while (it.hasNext())
+    {
+      SUIT_ViewModel* vm = it.next()->getViewModel();
+      if (!vm || !vm->inherits("OCCViewer_Viewer"))
+        continue;
+
+      OCCViewer_Viewer* occVM = (OCCViewer_Viewer*)vm;
+      occVM->setSelectionStyle((OCCViewer_ViewWindow::SelectionStyle)mode);
+    }
+  }
+#endif
+
+
 #ifndef DISABLE_OCCVIEWER
   if ( sec == QString( "OCCViewer" ) && param == QString( "stereo_type" ) )
   {
@@ -3929,17 +4028,8 @@ void LightApp_Application::afterCloseDoc()
 void LightApp_Application::updateModuleActions()
 {
   QString modName;
-  if ( activeModule() ) {
+  if ( activeModule() )
     modName = activeModule()->moduleName();
-    if ( !isModuleAccessible( modName ) ) {
-      QList<SUIT_Application*> apps = SUIT_Session::session()->applications();
-      foreach( SUIT_Application* app, apps ) {
-        LightApp_Application* lapp = dynamic_cast<LightApp_Application*>( app );
-        if ( lapp && lapp != this )
-          lapp->removeModuleAction( modName );
-      }
-    }
-  }
 
   LightApp_ModuleAction* moduleAction =
     qobject_cast<LightApp_ModuleAction*>( action( ModulesListId ) );
@@ -3997,8 +4087,11 @@ bool LightApp_Application::checkModule( const QString& title )
   if ( isPyModule )
   {
     QString pyModule = QString( "%1GUI.py" ).arg( name );
-    paths = QString( ::getenv( "PYTHONPATH" ) ).split( ":", QString::SkipEmptyParts );
-
+#if defined(WIN32)
+    paths = QString( Qtx::getenv( "PYTHONPATH" ) ).split( ";", QString::SkipEmptyParts );
+#else
+    paths = QString( Qtx::getenv( "PYTHONPATH" ) ).split( ":", QString::SkipEmptyParts );
+#endif
     isFound = false;
     for ( it = paths.begin(); it != paths.end() && !isFound; ++it )
     {
@@ -4065,13 +4158,45 @@ void LightApp_Application::updateWindows()
   for ( WinMap::ConstIterator it = myWin.begin(); it != myWin.end(); ++it )
   {
     QWidget* wid = it.value();
+    if ( !wid )
+      continue;
     if ( winMap.contains( it.key() ) )
       wid->setVisible( true );
-    else
+    else if ( !activeStudy() )
       delete wid;
+    else
+      wid->setVisible( false );
   }
 
   loadDockWindowsState();
+
+  if ( !activeModule() && infoPanel() )
+  {
+    infoPanel()->clear();
+    infoPanel()->setTitle( tr( "INFO_WELCOME_TO_SALOME" ) );
+
+    int grp = infoPanel()->addGroup( tr( "INFO_GETTING_STARTED" ) );
+    infoPanel()->addAction( action( FileNewId ), grp );
+    infoPanel()->addLabel( action( FileNewId )->statusTip(), grp );
+    infoPanel()->addAction( action( FileOpenId ), grp );
+    infoPanel()->addLabel( action( FileOpenId )->statusTip(), grp );
+    infoPanel()->addAction( action( TutorialsId ), grp );
+    infoPanel()->addLabel( action( TutorialsId )->statusTip(), grp );
+    infoPanel()->addAction( action( VideosId ), grp );
+    infoPanel()->addLabel( action( VideosId )->statusTip(), grp );
+
+    LightApp_ModuleAction* ma = qobject_cast<LightApp_ModuleAction*>(action(ModulesListId));
+    if ( ma && ma->count() > 0 )
+    {
+      grp = infoPanel()->addGroup( tr( "INFO_AVAILABLE_MODULES" ) );
+      foreach ( QString mname, ma->modules() )
+      {
+        infoPanel()->addAction( ma->moduleAction( mname ), grp );
+        if ( !moduleDescription( mname ).isEmpty() )
+          infoPanel()->addLabel( moduleDescription( mname ), grp );
+      }
+    }
+  }
 }
 
 /*!
@@ -4611,7 +4736,12 @@ bool LightApp_Application::event( QEvent* e )
                                   d ? *d : "",
                                   SUIT_MessageBox::Yes | SUIT_MessageBox::No,
                                   SUIT_MessageBox::Yes ) == SUIT_MessageBox::Yes )
-      showPreferences( tr( "PREF_APP" ) );
+    {
+      QStringList path;
+      path << tr( "PREF_CATEGORY_SALOME" ) << tr( "PREF_TAB_GENERAL" )
+           << tr( "PREF_GROUP_EXT_BROWSER" ) << tr( "PREF_APP" );
+      showPreferences( path );
+    }
     if( d )
       delete d;
     return true;
@@ -4878,7 +5008,7 @@ bool LightApp_Application::renameAllowed( const QString& /*entry*/) const {
   \param name new name of the object
   \brief Return \c true if rename operation finished successfully, \c false otherwise.
 */
-bool LightApp_Application::renameObject( const QString& entry, const QString& ) {
+bool LightApp_Application::renameObject( const QString& /*entry*/, const QString& /*name*/ ) {
   return false;
 }
 
@@ -4897,6 +5027,34 @@ void LightApp_Application::onDesktopMessage( const QString& message )
     if ( !vtype.isEmpty() )
       getViewManager( vtype, true );
   }
+  else if ( message.toLower().startsWith("register_module_in_study" ) ) {
+    QString moduleName = message.split( sectionSeparator ).last();
+    // Check name of current activating module name in order to avoid ciclik 
+    // call because of messages
+    if (!property("activateModule").toBool()) {
+      CAM_Module* mod = module(moduleName);
+      if (!mod)
+        mod = module(moduleTitle(moduleName));
+      if (!mod) {
+        mod = loadModule(moduleName);
+        if (!mod)
+          mod = loadModule(moduleTitle(moduleName));
+        if (mod) {
+          addModule(mod);
+        }
+      }
+      if (mod) {
+        CAM_Study* anActiveStudy = dynamic_cast<CAM_Study*>(activeStudy());
+        if (anActiveStudy) {
+          mod->connectToStudy(anActiveStudy);
+          LightApp_DataModel* aDM = dynamic_cast<LightApp_DataModel*>(mod->dataModel());
+          if(aDM) {
+            aDM->initRootObject();
+          }
+        }
+      }
+    }
+  }
   else {
     QStringList data = message.split( sectionSeparator );
     if ( data.count() > 1 ) {
@@ -4927,6 +5085,12 @@ void LightApp_Application::onDesktopMessage( const QString& message )
   }
 }
 
+void LightApp_Application::onInfoPanelShown()
+{
+  if ( activeModule() && activeModule()->inherits( "LightApp_Module" ) )
+    ((LightApp_Module*)activeModule())->updateInfoPanel();
+}
+
 /*!
   Internal method. 
   Returns all top level toolbars.
@@ -4990,7 +5154,7 @@ QByteArray LightApp_Application::processState(QByteArray& input,
       return aRes;
     QDataStream anInputData(&input, QIODevice::ReadOnly);
 
-    int toolBarMarkerIndexDef;
+    int toolBarMarkerIndexDef = 0;
     if(hasDefaultState) {
       toolBarMarkerIndexDef = getToolbarMarkerIndex(defaultState, aNames);
       if(toolBarMarkerIndexDef < 0)
@@ -5094,7 +5258,7 @@ void LightApp_Application::emitOperationFinished( const QString& theModuleName,
   Update visibility state of given objects
 */
 void LightApp_Application::updateVisibilityState( DataObjectList& theList,
-                                                  SUIT_ViewModel*  theViewModel )
+                                                  SUIT_ViewModel* theViewModel )
 {
   if ( !theViewModel || theList.isEmpty() ) return;
 
@@ -5109,18 +5273,66 @@ void LightApp_Application::updateVisibilityState( DataObjectList& theList,
     if ( !obj || aStudy->isComponent( obj->entry() ) )
       continue;
 
-    LightApp_Module* anObjModule = dynamic_cast<LightApp_Module*>(obj->module());
-    if ( anObjModule ) {
-      LightApp_Displayer* aDisplayer = anObjModule->displayer();
-      if ( aDisplayer ) {
-        Qtx::VisibilityState anObjState = Qtx::UnpresentableState;
-        if ( aDisplayer->canBeDisplayed( obj->entry(), theViewModel->getType() ) ) {
-          if ( aView && aDisplayer->IsDisplayed( obj->entry(), aView ) )
-            anObjState = Qtx::ShownState;
-          else
-            anObjState = Qtx::HiddenState;
+    QString mname = aStudy->componentDataType(obj->entry());
+    LightApp_Displayer* aDisplayer = LightApp_Displayer::FindDisplayer(mname, false);
+    if ( aDisplayer ) {
+      Qtx::VisibilityState anObjState = Qtx::UnpresentableState;
+      if ( aDisplayer->canBeDisplayed( obj->entry(), theViewModel->getType() ) ) {
+        if ( aView && aDisplayer->IsDisplayed( obj->entry(), aView ) )
+          anObjState = Qtx::ShownState;
+        else
+          anObjState = Qtx::HiddenState;
+      }
+      aStudy->setVisibilityState( obj->entry(), anObjState );
+    }
+  }
+}
+
+/*!
+  Update presentations of all displayed objects of theComponent in specified viewers
+*/
+void LightApp_Application::updatePresentations( const QString& theComponent,
+                                                const QStringList& theViewManagerTypes )
+{
+  LightApp_Displayer* aDisplayer = LightApp_Displayer::FindDisplayer(theComponent, false);
+  if ( aDisplayer ) {
+    LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>(activeStudy());
+    DataObjectList aComps;
+    bool isFound = false;
+    aStudy->root()->children( aComps );
+    DataObjectList::const_iterator aCompsIt = aComps.begin();
+    for ( ; aCompsIt != aComps.end() && !isFound; aCompsIt++ ) {
+      LightApp_DataObject* aComp = dynamic_cast<LightApp_DataObject*>( *aCompsIt );
+      if ( aComp && aComp->componentDataType() ==  theComponent) {
+        isFound = true;
+        DataObjectList anObjs;
+        aComp->children(anObjs, true);
+
+        QList<SUIT_ViewManager*> aViewMgrs;
+        QStringList::const_iterator itVMTypes = theViewManagerTypes.begin();
+        for ( ; itVMTypes != theViewManagerTypes.end(); ++itVMTypes )
+          viewManagers( *itVMTypes, aViewMgrs );
+
+        DataObjectList::const_iterator itObjs = anObjs.begin();
+        for ( ; itObjs != anObjs.end(); itObjs++ ) {
+          LightApp_DataObject* anObj = dynamic_cast<LightApp_DataObject*>( *itObjs );
+          QString anEntry = anObj->entry();
+
+          QListIterator<SUIT_ViewManager*> itViewMgrs( aViewMgrs );
+          while ( itViewMgrs.hasNext()) {
+            SUIT_ViewModel* aVM = itViewMgrs.next()->getViewModel();
+            if ( aVM ) {
+              SALOME_View* aView = dynamic_cast<SALOME_View*>(aVM);
+              if ( aView ) {
+                bool isDisp = aDisplayer->IsDisplayed( anEntry, aView );
+                aDisplayer->Erase( anEntry, true, false, aView );
+                if ( isDisp ) {
+                  aDisplayer->Display( anEntry, false, aView );
+                }
+              }
+            }
+          }
         }
-        aStudy->setVisibilityState( obj->entry(), anObjState );
       }
     }
   }