]> SALOME platform Git repositories - modules/gui.git/commitdiff
Salome HOME
Improve help items management
authorvsr <vsr@opencascade.com>
Thu, 1 Nov 2018 11:40:54 +0000 (14:40 +0300)
committervsr <vsr@opencascade.com>
Thu, 1 Nov 2018 11:40:54 +0000 (14:40 +0300)
- Unify help invokation methods (to work with local and remote urls)
- Introduce help items fallback support
+ Suppress some Qt warnings at app start-up

src/LightApp/LightApp_Application.cxx
src/LightApp/LightApp_Application.h
src/LightApp/resources/LightApp.xml

index c240120a6ade672eb6b022bea21ab3845029c75a..6fbc2c7a8894b4c3bb6fd28a2e208e798c3467d0 100644 (file)
@@ -604,7 +604,7 @@ void LightApp_Application::createActions()
     QAction* as = createAction( id, title,
                                resMgr->loadPixmap( "LightApp", tr( "ICON_WWW" ), false ),
                                title, title,
-                               0, desk, false, this, SLOT( onHelpOnline() ) );
+                               0, desk, false, this, SLOT( onHelpContentsModule() ) );
     as->setData( url );
     createMenu( as, helpMenu, -1, 0 );
     id++;
@@ -617,7 +617,7 @@ void LightApp_Application::createActions()
     QAction* af = createAction( helpMenu, title,
                                resMgr->loadPixmap( "LightApp", tr( "ICON_WWW" ), false ),
                                title, title,
-                               0, desk, false, this, SLOT( onHelpOnline() ) );
+                               0, desk, false, this, SLOT( onHelpContentsModule() ) );
     af->setData( url );
     createMenu( af, helpMenu, -1, 0 );
     id++;
@@ -631,7 +631,7 @@ void LightApp_Application::createActions()
     QAction* av = createAction( helpMenu, title,
                                resMgr->loadPixmap( "LightApp", tr( "ICON_LIFE_RIGN" ), false ),
                                title, title,
-                               0, desk, false, this, SLOT( onHelpOnline() ) );
+                               0, desk, false, this, SLOT( onHelpContentsModule() ) );
     av->setData( url );
     createMenu( av, helpMenu, -1, 0 );
     id++;
@@ -659,23 +659,38 @@ void LightApp_Application::createActions()
     QString modName = moduleName( aModule );                         // module name
     if ( modName.isEmpty() ) modName = aModule;                      // for KERNEL and GUI
     QString rootDir = QString( "%1_ROOT_DIR" ).arg( modName );       // module root dir env variable
-    QString modDir  = getenv( rootDir.toUtf8().constData() );      // module root dir path
+    QString modDir  = getenv( rootDir.toUtf8().constData() );        // module root dir path
     QString docSection;
     if (resMgr->hasValue( modName, "documentation" ) )
       docSection = resMgr->stringValue(modName, "documentation");
     else if ( resMgr->hasSection( modName + "_documentation" ) )
       docSection = modName + "_documentation";
     if ( !docSection.isEmpty() ) {
-      helpSubMenu = resMgr->stringValue( docSection, "sub_menu", "" ).arg( aModule );
+      helpSubMenu = resMgr->stringValue( docSection, "sub_menu", "" );
+      if ( helpSubMenu.contains( "%1" ) )
+        helpSubMenu = helpSubMenu.arg( aModule );
       QStringList listOfParam = resMgr->parameters( docSection );
       foreach( QString paramName, listOfParam ) {
         QString valueStr = resMgr->stringValue( docSection, paramName );
         if ( !valueStr.isEmpty() ) {
-          QFileInfo fi( valueStr );
-          if ( fi.isRelative() && !modDir.isEmpty() )
-            valueStr = Qtx::addSlash( modDir ) + valueStr;
-          if ( QFile::exists( valueStr ) )
-            helpData.insert( paramName.arg( aModule ), valueStr );
+          QStringList valueItems = valueStr.split( ";;", QString::SkipEmptyParts );
+          foreach( QString item, valueItems ) {
+            if ( item.startsWith( "http", Qt::CaseInsensitive ) ) {
+              QString key = paramName.contains( "%1" ) ? paramName.arg( aModule ) : paramName;
+              helpData.insert( key, item );
+              break;
+            }
+            else {
+              QFileInfo fi( item );
+              if ( fi.isRelative() && !modDir.isEmpty() )
+                item = Qtx::addSlash( modDir ) + item;
+              if ( QFile::exists( item ) ) {
+                QString key = paramName.contains( "%1" ) ? paramName.arg( aModule ) : paramName;
+                helpData.insert( key, item );
+                break;
+              }
+            }
+          }
         }
       }
     }
@@ -689,24 +704,24 @@ void LightApp_Application::createActions()
 
     IMapConstIterator<QString, QString > fileIt;
     for ( fileIt = helpData.begin(); fileIt != helpData.end(); fileIt++ ) {
-      QString helpFileName = fileIt.key();
+      QString helpItemPath = fileIt.key();
       // remove all '//' occurances 
-      while ( helpFileName.contains( "//" ) )
-        helpFileName.replace( "//", "" );
+      while ( helpItemPath.contains( "//" ) )
+        helpItemPath.replace( "//", "" );
       // obtain submenus hierarchy if given
-      QStringList smenus = helpFileName.split( "/" );
-      helpFileName = smenus.takeLast();
+      QStringList smenus = helpItemPath.split( "/" );
+      helpItemPath = smenus.takeLast();
       // workaround for User's Guide and Developer's Guide to avoid having single item in module's submenu.
-      if ( helpFileName == userGuide || helpFileName == devGuide ) {
+      if ( helpItemPath == userGuide || helpItemPath == devGuide ) {
        QString menuPath = smenus.join( "/" );
        QStringList allKeys = helpData.keys();
        QStringList total = allKeys.filter( QRegExp( QString( "^%1" ).arg( menuPath ) ) );
        if ( total.count() == 1 && smenus.count() > 0 )
-         helpFileName = smenus.takeLast();
+         helpItemPath = smenus.takeLast();
       }
-      QAction* a = createAction( id, helpFileName,
-                                 resMgr->loadPixmap( "STD", tr( "ICON_HELP" ), false ),
-                                 helpFileName, helpFileName,
+      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() ) );
       a->setData( fileIt.value() );
       if ( !helpSubMenu.isEmpty() ) {
@@ -716,7 +731,7 @@ void LightApp_Application::createActions()
       int menuId = helpMenu;
       foreach ( QString subMenu, smenus )
         menuId = createMenu( subMenu, menuId, -1, 5 );
-      createMenu( a, menuId, -1, ( menuId != helpMenu && (helpFileName == userGuide || helpFileName == devGuide) ) ? 0 : 5 );
+      createMenu( a, menuId, -1, ( menuId != helpMenu && (helpItemPath == userGuide || helpItemPath == devGuide) ) ? 0 : 5 );
       id++;
     }
   }
@@ -726,16 +741,21 @@ void LightApp_Application::createActions()
   createMenu( separator(), helpMenu, -1, 10 );
 
   QStringList addHelpItems = resMgr->parameters( "add_help" );
-  foreach ( QString addHelpItem, addHelpItems ) {
-    QString valueStr = resMgr->stringValue( "add_help", addHelpItem );
-    if ( !valueStr.isEmpty() && QFile::exists( valueStr ) ) {
-      QAction* a = createAction( id, addHelpItem,
-                                 resMgr->loadPixmap( "STD", tr( "ICON_HELP" ), false ),
-                                 addHelpItem, addHelpItem,
-                                 0, desk, false, this, SLOT( onHelpContentsModule() ) );
-      a->setData( valueStr );
-      createMenu( a, helpMenu, -1, 10 );
-      id++;
+  foreach ( QString paramName, addHelpItems ) {
+    QString valueStr = resMgr->stringValue( "add_help", paramName );
+    if ( !valueStr.isEmpty() ) {
+      QStringList valueItems = valueStr.split( ";;", QString::SkipEmptyParts );
+      foreach( QString item, valueItems ) { 
+        if ( item.startsWith( "http", Qt::CaseInsensitive ) || QFile::exists( item ) ) {
+          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() ) );
+          a->setData( item );
+          createMenu( a, helpMenu, -1, 10 );
+          break;
+        }
+      }
     }
   }
 
@@ -1133,230 +1153,143 @@ void LightApp_Application::updateCommandsStatus()
 class RunBrowser: public QThread
 {
 public:
-  RunBrowser( LightApp_Application* app,
-              const QString&        theApp,
-              const QString&        theParams,
-              const QString&        theHelpFile,
-              const QString&        theContext = QString(),
-             //For the external browser always specify 'file://' protocol,
-             //because some WEB browsers (for example Mozilla Firefox) can't open local file without protocol.
-             const QString&        theProtocol = QString("file://"),
-             const bool            isFile = true)
-    : myApp( theApp ),
-      myParams( theParams ),
-      myContext( theContext ),
-      myStatus(0),
-      myLApp( app )
+  static void execute( LightApp_Application* application,
+                       const QString& browser,
+                       const QString& parameters,
+                       const QString& url )
+  {
+    (new RunBrowser( application, browser, parameters, url ))->start();
+  }
+
+protected:
+  RunBrowser( LightApp_Application* application,
+              const QString&        browser,
+              const QString&        parameters,
+              const QString&        url)
+    : myApplication( application ),
+      myBrowser( browser ),
+      myParameters( parameters ),
+      myUrl( url )
   {
-    QString path_begin = theProtocol+"%1";
-    QString path_end = theHelpFile;
-    if( isFile ) {
-      path_end = QFileInfo( theHelpFile ).canonicalFilePath();
+    if ( !myUrl.startsWith( "http", Qt::CaseInsensitive ) )
+    {
+      // normalize path
+      if ( myUrl.startsWith( "file://", Qt::CaseInsensitive ) )
+       myUrl = myUrl.remove( 0, QString( "file://" ).count() );
+      // For the external browser we always specify 'file://' protocol,
+      // because some web browsers (e.g. Mozilla Firefox) can't open local file without protocol.
+      myUrl = myUrl.prepend( "file://" );
     }
-    myHelpFile = path_begin.arg( path_end );
+    connect(this, SIGNAL(finished()), SLOT(deleteLater()));
   }
 
   virtual void run()
   {
-    if ( !myApp.isEmpty() && !myHelpFile.isEmpty()) {
-      QString aCommand = QString( "%1 %2 \"%3%4\"" ).arg( myApp, myParams, myHelpFile, myContext.isEmpty() ? QString("") : QString( "#%1" ).arg( myContext ) );
-
+    if ( !myBrowser.isEmpty() && !myUrl.isEmpty() )
+    {
+#ifdef WIN32
+      QString cmdLine = QString( "\"%1\" %2 \"%3\"" ).arg( myBrowser, myParameters, myUrl );
+#else
+      QString cmdLine = QString( "%1 %2 \"%3\"" ).arg( myBrowser, myParameters, myUrl );
+#endif
       QProcess* proc = new QProcess();
-
-      proc->start( aCommand );
-      if ( !proc->waitForStarted() ) {
+      proc->start( cmdLine );
+      if ( !proc->waitForStarted() )
+      {
         SALOME_CustomEvent* ce2000 = new SALOME_CustomEvent( 2000 );
-        QString* msg = new QString( QObject::tr( "EXTERNAL_BROWSER_CANNOT_SHOW_PAGE" ).arg( myApp, myHelpFile ) );
+        QString* msg = new QString( QObject::tr( "EXTERNAL_BROWSER_CANNOT_SHOW_PAGE" ).arg( myBrowser, myUrl ) );
         ce2000->setData( msg );
-        QApplication::postEvent( myLApp, ce2000 );
+        QApplication::postEvent( myApplication, ce2000 );
       }
     }
   }
 
 private:
-  QString               myApp;
-  QString               myParams;
-  QString               myHelpFile;
-  QString               myContext;
-  int                   myStatus;
-  LightApp_Application* myLApp;
+  LightApp_Application* myApplication;
+  QString               myBrowser;
+  QString               myParameters;
+  QString               myUrl;
 };
 
-/*!
-  SLOT: Displays help contents for choosen module
-*/
-void LightApp_Application::onHelpContentsModule()
+void LightApp_Application::showHelp( const QString& path )
 {
-  const QAction* a = (QAction*) sender();
-  QString helpFile = a->data().toString();
-  if ( helpFile.isEmpty() ) return;
-
   SUIT_ResourceMgr* resMgr = resourceMgr();
-  QString platform;
-#ifdef WIN32
-  platform = "winapplication";
-#else
-  platform = "application";
-#endif
-  QString anApp = resMgr->stringValue("ExternalBrowser", platform);
-#ifdef WIN32
-  QString quote("\"");
-  anApp.prepend( quote );
-  anApp.append( quote );
-#endif
-  QString aParams = resMgr->stringValue("ExternalBrowser", "parameters");
+
 #if DISABLE_QTXWEBBROWSER
-  bool useExtBrowser = true;
+  bool useExternalBrowser = true;
 #else  
-  bool useExtBrowser = resMgr->booleanValue("ExternalBrowser", "use_external_browser", false );
+  bool useExternalBrowser = resMgr->booleanValue("ExternalBrowser", "use_external_browser", false );
 #endif
-  
-  if( useExtBrowser ) {
-    if ( !anApp.isEmpty() ) {
-      RunBrowser* rs = new RunBrowser( this, anApp, aParams, helpFile );
-      rs->start();
-    }
-    else {
-      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" ) );
-    }
-  }
-  else {
-    QStringList parameters;
-    parameters << QString( "--language=%1" ).arg( resMgr->stringValue( "language", "language" ) );
-    parameters << QString( "--add=%1" ).arg( QApplication::instance()->applicationPid() );
-    parameters << helpFile;
-    QProcess::startDetached( "HelpBrowser", parameters );
-  }
-}
-
-/*!
-  SLOT: Displays help contents for choosen dialog
-*/
-void LightApp_Application::onHelpContextModule( const QString& theComponentName,
-                                                const QString& theFileName,
-                                                const QString& theContext )
-{
-  QString fileName = theFileName;
-  QString context  = theContext;
-  if ( !QFile::exists( fileName ) && theContext.isEmpty() ) {
-    // context might be passed within theFileName argument
-    QStringList comps = fileName.split("#");
-    if ( comps.count() > 1 ) {
-      context = comps.last();
-      comps.removeLast();
-      fileName = comps.join("#");
-    }
-  }
-
-  QString homeDir = "";
-  if ( !theComponentName.isEmpty() ) {
-    QString dir = getenv( ( theComponentName + "_ROOT_DIR" ).toLatin1().constData() );
-    if ( !dir.isEmpty() )
-      homeDir = Qtx::addSlash( Qtx::addSlash( dir )      +
-                               Qtx::addSlash( "share" )  +
-                               Qtx::addSlash( "doc" )    +
-                               Qtx::addSlash( "salome" ) +
-                               Qtx::addSlash( "gui" )    +
-                               Qtx::addSlash( theComponentName ) );
-  }
 
-  QString helpFile = QFileInfo( homeDir + fileName ).absoluteFilePath();
-  SUIT_ResourceMgr* resMgr = resourceMgr();
-        QString platform;
+  if ( useExternalBrowser )
+  {
 #ifdef WIN32
-        platform = "winapplication";
+    QString browser = resMgr->stringValue( "ExternalBrowser", "winapplication" ) ;
 #else
-        platform = "application";
+    QString browser = resMgr->stringValue( "ExternalBrowser", "application" );
 #endif
-        QString anApp = resMgr->stringValue("ExternalBrowser", platform);
-#ifdef WIN32
-        QString quote("\"");
-        anApp.prepend( quote );
-        anApp.append( quote );
-#endif
-
-#if DISABLE_QTXWEBBROWSER
-  bool useExtBrowser = true;
-#else  
-  bool useExtBrowser = resMgr->booleanValue("ExternalBrowser", "use_external_browser", false );
-#endif
-
-  if(useExtBrowser) {
-    QString aParams = resMgr->stringValue("ExternalBrowser", "parameters");
-
-    if ( !anApp.isEmpty() ) {
-      RunBrowser* rs = new RunBrowser( this, anApp, aParams, helpFile, context );
-      rs->start();
+    QString parameters = resMgr->stringValue("ExternalBrowser", "parameters");
+  
+    if ( !browser.isEmpty() )
+    {
+      RunBrowser::execute( this, browser, parameters, path );
     }
-    else {
+    else
+    {
       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" ) );
     }
   }
-  else {
-    QStringList parameters;
-    parameters << QString( "--language=%1" ).arg( resMgr->stringValue( "language", "language" ) );
-    parameters << QString( "--add=%1" ).arg( QApplication::instance()->applicationPid() );
-    parameters << QString( "%1#%2" ).arg( helpFile ).arg( context );
-    QProcess::startDetached( "HelpBrowser", parameters );
+  else
+  {
+    QStringList cmdLine;
+    cmdLine << QString( "--language=%1" ).arg( resMgr->stringValue( "language", "language" ) );
+    cmdLine << QString( "--add=%1" ).arg( QApplication::instance()->applicationPid() );
+    cmdLine << path;
+    QProcess::startDetached( "HelpBrowser", cmdLine );
   }
 }
 
 /*!
   SLOT: Displays help contents for choosen module
 */
-void LightApp_Application::onHelpOnline()
+void LightApp_Application::onHelpContentsModule()
 {
   const QAction* a = (QAction*) sender();
-  QString url = a->data().toString();
-  if ( url.isEmpty() ) return;
-
-  SUIT_ResourceMgr* resMgr = resourceMgr();
-  QString platform;
-#ifdef WIN32
-  platform = "winapplication";
-#else
-  platform = "application";
-#endif
-  QString anApp = resMgr->stringValue("ExternalBrowser", platform);
-#ifdef WIN32
-  QString quote("\"");
-  anApp.prepend( quote );
-  anApp.append( quote );
-#endif
-  QString aParams = resMgr->stringValue("ExternalBrowser", "parameters");
-#if DISABLE_QTXWEBBROWSER
-  bool useExtBrowser = true;
-#else  
-  bool useExtBrowser = resMgr->booleanValue("ExternalBrowser", "use_external_browser", false );
-#endif
-  
-  if( useExtBrowser ) {
-    if ( !anApp.isEmpty() ) {
-      RunBrowser* rs = new RunBrowser( this, anApp, aParams, url, "", "http://", false );
-      rs->start();
-    }
-    else {
-      if ( SUIT_MessageBox::question( desktop(), tr( "WRN_WARNING" ), tr( "DEFINE_EXTERNAL_BROWSER" ),
-                                      SUIT_MessageBox::Yes | SUIT_MessageBox::No,
-                                      SUIT_MessageBox::Yes ) == SUIT_MessageBox::Yes )
+  QString helpFile = a->data().toString();
+  if ( !helpFile.isEmpty() )
+    showHelp( helpFile );
+}
 
-        showPreferences( tr( "PREF_APP" ) );
+/*!
+  SLOT: Displays contextual help (e.g. for choosen dialog)
+*/
+void LightApp_Application::onHelpContextModule( const QString& component,
+                                                const QString& url,
+                                                const QString& context )
+{
+  QString path = url;
+  if ( !url.startsWith( "http", Qt::CaseInsensitive ) )
+  {
+    // local file path
+    QFileInfo fi( url );
+    if ( fi.isRelative() && !component.isEmpty() )
+    {
+      QString rootDir = getenv( (component + "_ROOT_DIR").toLatin1().constData() );
+      if ( !rootDir.isEmpty() )
+      {
+       path = (QStringList() << rootDir << "share" << "doc" << "salome" << "gui" << component << url).join( QDir::separator() );
+      }
     }
   }
-  else {
-    QStringList parameters;
-    parameters << QString( "--language=%1" ).arg( resMgr->stringValue( "language", "language" ) );
-    parameters << QString( "--add=%1" ).arg( QApplication::instance()->applicationPid() );
-    parameters << "http://" + url;
-    QProcess::startDetached( "HelpBrowser", parameters );
+  if ( !context.isEmpty() )
+  {
+    path += QString( "#%1" ).arg( context );
   }
+  showHelp( path );
 }
 
 /*!
@@ -2320,8 +2253,6 @@ void LightApp_Application::emptyPreferences( const QString& modName )
   if ( !item || !item->isEmpty() )
     return;
 
-  //  printf( "---------------------> Modify for empty module.\n" );
-
   QtxPagePrefFrameItem* frm = new QtxPagePrefFrameItem( item->title(), item->parentItem() );
   frm->setIcon( item->icon() );
   frm->setStretch( false );
index 8e402d9fa00dfd9ab6a9c66de3c31f0d06b6ec18..f32fd38a4cff1f3a9b23a01726f320f7f4d66cd7 100644 (file)
@@ -196,7 +196,6 @@ signals:
 
 public slots:
   virtual void                        onHelpContentsModule();
-  virtual void                        onHelpOnline();
   virtual void                        onHelpContextModule( const QString&, const QString&, const QString& = QString() );
   virtual void                        onNewDoc();
   virtual void                        onOpenDoc();
@@ -209,6 +208,7 @@ public slots:
   virtual void                        onDockWindowVisibilityChanged( bool );
 
 protected:
+  void                                showHelp( const QString& );
   virtual void                        createActions();
   virtual void                        createActionForViewer( const int id,
                                                              const int parentId,
index 7adc8b93d34977d98172729ff39bb7b867f72202..c03a8edeee3abfb3f2fb241f53f5a923b2c7949d 100644 (file)
   </section>
   <section name="GUI" >
     <parameter name="documentation"     value="gui_help"/>
-    <parameter name="site_url"          value="www.salome-platform.org"/>
-    <parameter name="forum_url"         value="www.salome-platform.org/forum"/>
-    <parameter name="channel_url"       value="www.youtube.com/playlist?list=PLgvBxFyGVRbZZz4wVvP36xXQL-S81RZsc&amp;disable_polymer=true"/>
+    <parameter name="site_url"          value="http://www.salome-platform.org"/>
+    <parameter name="forum_url"         value="http://www.salome-platform.org/forum"/>
+    <parameter name="channel_url"       value="https://www.youtube.com/playlist?list=PLgvBxFyGVRbZZz4wVvP36xXQL-S81RZsc&amp;disable_polymer=true"/>
   </section>
   <section name="KERNEL" >
     <parameter name="documentation"     value="kernel_help"/>
   </section>
   <section name="gui_help" >
-    <parameter name="User's Guide/GUI module"      value="${GUI_ROOT_DIR}/share/doc/salome/gui/GUI/index.html"/>
-    <parameter name="Developer's Guide/GUI module" value="${GUI_ROOT_DIR}/share/doc/salome/tui/GUI/index.html"/>
+    <parameter name="User's Guide/GUI module"      value="${GUI_ROOT_DIR}/share/doc/salome/gui/GUI/index.html;;http://docs.salome-platform.org/latest/gui/GUI/index.html"/>
+    <parameter name="Developer's Guide/GUI module" value="${GUI_ROOT_DIR}/share/doc/salome/tui/GUI/index.html;;http://docs.salome-platform.org/latest/tui/GUI/index.html"/>
   </section>
   <section name="kernel_help" >
-    <parameter name="Developer's Guide/KERNEL module" value="${KERNEL_ROOT_DIR}/share/doc/salome/tui/KERNEL/index.html"/>
+    <parameter name="Developer's Guide/KERNEL module" value="${KERNEL_ROOT_DIR}/share/doc/salome/tui/KERNEL/index.html;;http://docs.salome-platform.org/latest/tui/KERNEL/index.html"/>
   </section>
   <section name="notification" >
     <parameter name="timeout" value="10"/>
   </section>
   <section name="add_help">
     <!-- Additional help resources -->
-    <parameter name="Developer resources"  value="${DOCUMENTATION_ROOT_DIR}/index.html" />
+    <parameter name="Developer resources"  value="${DOCUMENTATION_ROOT_DIR}/index.html;;http://docs.salome-platform.org/latest/index.html" />
   </section>
  <section name="windows_geometry">
   <parameter name="nomodule" value="#00 #00 #00 #FF #00 #00 #00 #00 #FD #00 #00 #00 #02 #00 #00 #00 #00 #00 #00 #01 #00 #00 #00 #02 #8D #FC #02 #00 #00 #00 #01 #FB #00 #00 #00 #22 #00 #6F #00 #62 #00 #6A #00 #65 #00 #63 #00 #74 #00 #42 #00 #72 #00 #6F #00 #77 #00 #73 #00 #65 #00 #72 #00 #44 #00 #6F #00 #63 #00 #6B #01 #00 #00 #00 #37 #00 #00 #02 #8D #00 #00 #00 #53 #00 #FF #FF #FF #00 #00 #00 #03 #00 #00 #05 #40 #00 #00 #00 #53 #FC #01 #00 #00 #00 #01 #FB #00 #00 #00 #22 #00 #70 #00 #79 #00 #74 #00 #68 #00 #6F #00 #6E #00 #43 #00 #6F #00 #6E #00 #73 #00 #6F #00 #6C #00 #65 #00 #44 #00 #6F #00 #63 #00 #6B #01 #00 #00 #00 #00 #00 #00 #05 #40 #00 #00 #00 #46 #00 #FF #FF #FF #00 #00 #04 #38 #00 #00 #02 #8D #00 #00 #00 #04 #00 #00 #00 #04 #00 #00 #00 #08 #00 #00 #00 #08 #FC #00 #00 #00 #01 #00 #00 #00 #02 #00 #00 #00 #02 #00 #00 #00 #1C #00 #53 #00 #61 #00 #6C #00 #6F #00 #6D #00 #65 #00 #53 #00 #74 #00 #61 #00 #6E #00 #64 #00 #61 #00 #72 #00 #64 #01 #00 #00 #00 #00 #FF #FF #FF #FF #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #1A #00 #53 #00 #61 #00 #6C #00 #6F #00 #6D #00 #65 #00 #4D #00 #6F #00 #64 #00 #75 #00 #6C #00 #65 #00 #73 #01 #00 #00 #00 #CE #FF #FF #FF #FF #00 #00 #00 #00 #00 #00 #00 #00" />