]> SALOME platform Git repositories - modules/gui.git/commitdiff
Salome HOME
bos #20215 Help panels into SALOME for new users
authorViktor UZLOV <vuzlov@debian10-01.nnov.opencascade.com>
Wed, 18 Nov 2020 08:02:22 +0000 (11:02 +0300)
committervsr <vsr@opencascade.com>
Thu, 24 Dec 2020 12:02:26 +0000 (15:02 +0300)
25 files changed:
doc/salome/gui/images/help_panel.png [new file with mode: 0644]
doc/salome/gui/input/howtos_and_best_practives.rst
doc/salome/gui/input/using_help_panel.rst [new file with mode: 0644]
doc/salome/tui/doxyfile.in
src/CAM/CAM_Application.cxx
src/CAM/CAM_Application.h
src/LightApp/LightApp_Application.cxx
src/LightApp/LightApp_Application.h
src/LightApp/LightApp_Module.cxx
src/LightApp/LightApp_Module.h
src/LightApp/LightApp_ModuleAction.cxx
src/LightApp/LightApp_ModuleAction.h
src/LightApp/resources/LightApp.xml
src/LightApp/resources/LightApp_msg_en.ts
src/LightApp/resources/LightApp_msg_fr.ts
src/LightApp/resources/LightApp_msg_ja.ts
src/Qtx/CMakeLists.txt
src/Qtx/QtxDockWidget.cxx
src/Qtx/QtxDockWidget.h
src/Qtx/QtxInfoPanel.cxx [new file with mode: 0644]
src/Qtx/QtxInfoPanel.h [new file with mode: 0644]
src/SALOME_PYQT/SalomePyQt/SalomePyQt.cxx
src/SALOME_PYQT/SalomePyQt/SalomePyQt.h
src/SALOME_PYQT/SalomePyQt/SalomePyQt.sip
src/STD/resources/STD_msg_en.ts

diff --git a/doc/salome/gui/images/help_panel.png b/doc/salome/gui/images/help_panel.png
new file mode 100644 (file)
index 0000000..859dcd0
Binary files /dev/null and b/doc/salome/gui/images/help_panel.png differ
index b8463fb89ca226f9446d287cb9f1a787fecb3f41..d281d87c3e692d43585111b71e4c8b19fd388844 100644 (file)
@@ -7,14 +7,10 @@ How-To's and Best Practices
 These documents provide guidelines and best practices explaining different aspects
 and usage examples of SALOME platform.
 
-* :ref:`use_case_builder`:
-* :ref:`drag_and_drop`
-* :ref:`using_pluginsmanager`
-
-
 .. toctree::
        
        use_case_builder.rst
        drag_and_drop.rst
        using_pluginsmanager.rst
+       using_help_panel.rst
 
diff --git a/doc/salome/gui/input/using_help_panel.rst b/doc/salome/gui/input/using_help_panel.rst
new file mode 100644 (file)
index 0000000..9321a3d
--- /dev/null
@@ -0,0 +1,176 @@
+.. _using_help_panel: 
+
+****************
+Using Help Panel
+****************
+
+.. contents:: Table of Contents
+
+In SALOME, each module can show introduction information and/or context help
+in the **Help panel**. This panel is shown in the right dock area of the
+SALOME GUI desktop.
+
+.. figure:: ../images/help_panel.png
+   :align: center
+   :alt: Help panel
+
+.. _hp_show_help_panel:
+
+Show help panel
+===============
+
+In order to show *Help panel*, the module must request it in the standard way, in
+the ``windows()`` method, for example:
+
+.. code-block:: c++
+   :emphasize-lines: 4
+
+    void GeometryGUI::windows(QMap<int, int>& map) const
+    {
+      map.insert(SalomeApp_Application::WT_ObjectBrowser, Qt::LeftDockWidgetArea);
+      map.insert(SalomeApp_Application::WT_InfoPanel, Qt::RightDockWidgetArea);
+      map.insert(SalomeApp_Application::WT_NoteBook, Qt::LeftDockWidgetArea);
+      map.insert(SalomeApp_Application::WT_PyConsole, Qt::BottomDockWidgetArea);
+    }
+
+.. note:: The dock area position flag is ignored for the *Help panel*.
+
+.. _hp_module_description:
+
+Module description
+==================
+
+To display short annotation of the module in the desktop in the application's
+*neutral point* (when there's no active module, see figure above),
+add the ``<description>`` parameter to the main module's section in the configuration
+file - ``LightApp.xml`` or ``SalomeApp.xml``, for example:
+
+.. code-block:: xml
+   :emphasize-lines: 6
+
+    <document>
+      <section name="SMESH">
+        <parameter name="name" value="Mesh"/>
+        <parameter name="icon" value="ModuleMesh.png"/>
+        <parameter name="version" value="9.6.0"/>
+        <parameter name="description" value="Generate mesh from CAD model or import mesh"/>
+      </section>
+    </document>
+
+Also, provide a translation of the module description to other languages in the
+corresponding translation files (``*.ts``).
+
+.. _hp_api:
+
+API of Help panel
+=================
+
+.. _hp_api_cpp:
+
+C++
+---
+
+Help panel is implemented in SALOME GUI module, via the ``QtxInfoPanel`` class.
+To obtain a reference to the Help panel, use method ``infoPanel()`` of the
+``LightApp_Application`` or ``SalomeApp_Application`` class:
+
+.. code-block:: c++
+
+    #include <QtxInfoPanel.h>
+    ...
+    SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>(application());
+    QtxInfoPanel* ip = app->infoPanel();
+
+The class ``QtxInfoPanel`` provides several methods which can be used to manage
+content of the *Help panel*. It is possible to add text labels and actions (these latter
+are presented as buttons). The items can be arranged into the logical blocks - groups;
+groups can contain other groups. All methods creating content items return unique
+identifier which can be later used to change item's visibility, enable/disable it
+(actions can be also enabled/disable directly), remove it or clear its contents
+(for groups). Top level container has identifier ``-1``.
+
+.. code-block:: c++
+
+    // Set panel's title (put empty string to hide title)
+    ip->setTitle("Welcome to my module");
+
+    // Create group box        
+    int gb = ip->addGroup("General features");
+
+    // Add action to the group box
+    QAction* action = new QAction("My feature");
+    int id1 = ip->addAction(action, gb);
+
+    // Add informative label to the group box
+    int id2 = ip->addLabel("My cool feature", gb);
+
+    // Add another label, right-aligned, to the top-level container
+    int id3 = ip->addLabel("Some information", Qt::AlignRight);
+
+    // Change visibility of given item
+    ip->setVisible(id3, false);
+
+    // Enable/disable given item
+    ip->setEnabled(gb, false);
+
+    // Remove given item
+    ip->remove(id1);
+
+    // Remove all content of group
+    ip->clear(gb);
+
+    // Clear Help panel
+    ip->clear();
+
+.. _hp_api_python:
+
+Python
+------
+
+For Python modules, *Help panel* can be accessed via the ``SalomePyQt`` Python module.
+
+.. code-block:: python
+
+    from PyQt5 import Qt as Q
+    from SalomePyQt import SalomePyQt as sg
+
+    # Set panel's title (put empty string to hide title)
+    sg.infoSetTitle("Welcome to my module")
+
+    # Create group box 
+    gb = sg.infoAddGroup("General features")
+
+    # Add action to the group box
+    action = Q.QAction("My feature")
+    id1 = sg.infoAddAction(action, gb)
+
+    # Add informative label to the group box
+    id2 = sg.infoAddLabel("My cool feature", gb)
+
+    # Add another label, right-aligned, to the top-level container
+    # Note: -1 is used explicitly as group identifier
+    id3 = sg.infoAddLabel("Some information", Q.Qt.AlignRight, -1)
+
+    # Change visibility of given item
+    sg.infoSetVisible(id3, False)
+
+    # Enable/disable given item
+    sg.infoSetEnabled(gb, False)
+
+    # Remove given item
+    sg.infoRemove(id1)
+
+    # Remove all content of group
+    sg.infoClear(gb)
+
+    # Clear Help panel
+    sg.infoClear()
+
+.. _hp_update_panel
+
+Notifications
+=============
+
+Each time when *Help panel* is shown, currently active module is informed via
+the virtual method ``updateInfoPanel()``. This method can be used to properly
+update the contents of the *Help panel*, depending on the current context.
index a0ee40194bafd3c85cc4e35f14d73070a3c11be5..732ada6f6cb8df5c73afd3bd799fc1ab9d33c3b1 100644 (file)
@@ -8,7 +8,7 @@ CREATE_SUBDIRS         = NO
 OUTPUT_LANGUAGE        = English
 USE_WINDOWS_ENCODING   = NO
 BRIEF_MEMBER_DESC      = YES
-REPEAT_BRIEF           = NO
+REPEAT_BRIEF           = YES
 ABBREVIATE_BRIEF       = 
 ALWAYS_DETAILED_SEC    = YES
 INLINE_INHERITED_MEMB  = NO
index ae731cee51f48a1906f062719fbea145e5af7cf3..ac598983034b7c2ae40b0c84d9d2eeb6753a5a79 100644 (file)
@@ -640,7 +640,7 @@ QString CAM_Application::moduleTitle( const QString& name )
 
 /*!
   \brief Get module icon name.
-  \param name module name
+  \param name module name or title
   \return module icon or null QString if module is not found
 */
 QString CAM_Application::moduleIcon( const QString& name )
@@ -648,24 +648,40 @@ QString CAM_Application::moduleIcon( const QString& name )
   QString res;
   for ( ModuleInfoList::const_iterator it = myInfoList.begin(); it != myInfoList.end() && res.isNull(); ++it )
   {
-    if ( (*it).name == name )
+    if ( (*it).name == name || (*it).title == name )
       res = (*it).icon;
   }
   return res;
 }
 
+/*!
+  \brief Get module description.
+  \param name module name or title
+  \return module description or null QString if description is not provided in config file.
+*/
+QString CAM_Application::moduleDescription( const QString& name )
+{
+  QString res;
+  for ( ModuleInfoList::const_iterator it = myInfoList.begin(); it != myInfoList.end() && res.isNull(); ++it )
+  {
+    if ( (*it).name == name || (*it).title == name )
+      res = tr((*it).description.toUtf8());
+  }
+  return res;
+}
+
 /*!
   \brief Get module library name by its title (user name).
-  \param title module title (user name)
+  \param title module name or title
   \param full if \c true, return full library name, otherwise return its internal name
   \return module library name or null QString if module is not found
  */
-QString CAM_Application::moduleLibrary( const QString& title, const bool full )
+QString CAM_Application::moduleLibrary( const QString& name, const bool full )
 {
   QString res;
   for ( ModuleInfoList::const_iterator it = myInfoList.begin(); it != myInfoList.end() && res.isEmpty(); ++it )
   {
-    if ( (*it).title == title )
+    if ( (*it).name == name || (*it).title == name )
       res = (*it).library;
   }
   if ( !res.isEmpty() && full )
@@ -771,6 +787,8 @@ void CAM_Application::readModuleList()
 
     QString modIcon = resMgr->stringValue( *it, "icon", QString() );
 
+    QString modDescription = resMgr->stringValue( *it, "description", QString() );
+
     QString modLibrary = resMgr->stringValue( *it, "library", QString() ).trimmed();
     if ( !modLibrary.isEmpty() )
     {
@@ -801,6 +819,7 @@ void CAM_Application::readModuleList()
     inf.status = hasGui ? stUnknown : stNoGui;
     if ( hasGui ) inf.library = modLibrary;
     inf.icon = modIcon;
+    inf.description = modDescription;
     inf.version = version;
     myInfoList.append( inf );
   }
index b0b69d3f6423aba76ae753b6dc49e3514272a724..a11669897c504317043ac1d23e914df7cb1bef8d 100644 (file)
@@ -74,6 +74,7 @@ public:
   static QString      moduleName( const QString& );
   static QString      moduleTitle( const QString& );
   static QString      moduleIcon( const QString& );
+  static QString      moduleDescription( const QString& );
   static QString      moduleLibrary( const QString&, const bool = true );
 
   virtual void        createEmptyStudy();
@@ -100,7 +101,7 @@ private:
 private:
   enum { stUnknown = 0, stNoGui, stInaccessible, stReady };
   typedef struct { 
-    QString name, title, icon, library, version;
+    QString name, title, icon, library, version, description;
     int status;
   } ModuleInfo;
   typedef QList<ModuleInfo> ModuleInfoList;
index 1aa01cf53bf075d186cc28c3843646a311ebe0a4..d9379a40acc3b64d9c470d541c307e98ac8985e4 100644 (file)
@@ -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>
@@ -526,6 +527,9 @@ bool LightApp_Application::activateModule( const QString& modName )
 
   saveDockWindowsState();
 
+  if ( infoPanel() )
+    infoPanel()->clear();
+
   bool status = CAM_Application::activateModule( modName );
 
   updateModuleActions();
@@ -601,26 +605,24 @@ void LightApp_Application::createActions()
   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";
@@ -1369,9 +1383,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 );
@@ -1441,6 +1464,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
 */
@@ -1793,6 +1821,7 @@ void LightApp_Application::onStudyCreated( SUIT_Study* theStudy )
   }
 
   getWindow( WT_ObjectBrowser );
+  getWindow( WT_InfoPanel );
 
   loadDockWindowsState();
 
@@ -1824,6 +1853,7 @@ void LightApp_Application::onStudyOpened( SUIT_Study* theStudy )
   }
 
   getWindow( WT_ObjectBrowser );
+  getWindow( WT_InfoPanel );
 
   loadDockWindowsState();
 
@@ -2129,6 +2159,13 @@ QWidget* LightApp_Application::createWindow( const int flag )
     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 )
   {
@@ -2166,6 +2203,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 );
   }
 }
@@ -4126,6 +4164,34 @@ void LightApp_Application::updateWindows()
   }
 
   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 );
+      }
+    }
+  }
 }
 
 /*!
@@ -5014,6 +5080,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.
index 4482948671091088759ebe3209f0df1d4f63428b..da8ffc266784632ec2c2b127d5b9f031a4c14576 100644 (file)
@@ -40,6 +40,7 @@
 #include <QStringList>
 
 class LogWindow;
+class QtxInfoPanel;
 #ifndef DISABLE_PYCONSOLE
 class PyConsole_Console;
 class PyConsole_Interp;
@@ -75,6 +76,7 @@ class LIGHTAPP_EXPORT LightApp_Application : public CAM_Application, public SUIT
 
 public:
   typedef enum { WT_ObjectBrowser,
+                WT_InfoPanel,
 #ifndef DISABLE_PYCONSOLE
                  WT_PyConsole,
 #endif
@@ -89,6 +91,7 @@ public:
          PreferencesId, MRUId, ModulesListId,
          NewGLViewId, NewPlot2dId, NewOCCViewId, NewVTKViewId,
          NewQxSceneViewId, NewGraphicsViewId, NewPVViewId, NewPyViewerId, StyleId, FullScreenId,
+         WebSiteId, ForumId, VideosId, TutorialsId,
          UserID };
 
 protected:
@@ -110,6 +113,7 @@ public:
 
   LogWindow*                          logWindow();
   SUIT_DataBrowser*                   objectBrowser();
+  QtxInfoPanel*                       infoPanel();
 #ifndef DISABLE_PYCONSOLE
   PyConsole_Console*                  pythonConsole(const bool force = false);
 #endif
@@ -266,6 +270,8 @@ protected slots:
 
   virtual void                        onDesktopMessage( const QString& );
 
+  virtual void                        onInfoPanelShown();
+
 private slots:
   void                                onSelection();
   void                                onRefresh();
index ff19dc9c4f078bdcb447307aad8055b6e3728b6e..ee0b2e5054fdc602326bba8b919841bf43d62d7f 100644 (file)
@@ -315,6 +315,11 @@ void LightApp_Module::MenuItem()
 {
 }
 
+/*!NOT IMPLEMENTED*/
+void LightApp_Module::updateInfoPanel()
+{
+}
+
 /*!NOT IMPLEMENTED*/
 void LightApp_Module::createPreferences()
 {
index 31222c6154858498b9b65715219d35787684ab79..94fd9396fccf8456d4084659ee444a216785e61e 100644 (file)
@@ -117,6 +117,8 @@ public slots:
 
   void                                MenuItem();
 
+  virtual void                        updateInfoPanel();
+
 protected slots:
   virtual void                        onModelSaved();
   virtual void                        onModelOpened();
index fa9a8c6953ce059aee0e1f79d407e2af0f7f084e..9431ec346630067710ece247ea3bad8f697bc76c 100644 (file)
@@ -271,6 +271,15 @@ LightApp_ModuleAction::~LightApp_ModuleAction()
 {
 }
 
+/*!
+  \brief Get number of registered modules.
+  \return modules count
+*/
+int LightApp_ModuleAction::count() const
+{
+  return modules().count();
+}
+
 /*!
   \brief Get list of modules.
   \return modules names list
@@ -314,6 +323,15 @@ void LightApp_ModuleAction::setModuleIcon( const QString& name, const QIcon& ico
   update();
 }
 
+/*!
+  \brief Get module action.
+  \param name module name
+*/
+QAction* LightApp_ModuleAction::moduleAction( const QString& name ) const
+{
+  return mySet->moduleAction( name );
+}
+
 /*!
   \brief Add module into the list.
   \param name module name
index c5e6da61c8c207c8cf3a111aa02b2060cfdd9bc1..1048e8b4c496a24e0ebc1d6bf84da2f1e459a988 100644 (file)
@@ -50,11 +50,14 @@ public:
   LightApp_ModuleAction( const QString&, const QIcon&, QObject* = 0 );
   virtual ~LightApp_ModuleAction();
 
+  int              count() const;
   QStringList      modules() const;
 
   QIcon            moduleIcon( const QString& ) const;
   void             setModuleIcon( const QString&, const QIcon& );
 
+  QAction*         moduleAction( const QString& ) const;
+
   void             insertModule( const QString&, const QIcon&, const int = -1 );
   void             removeModule( const QString& );
 
index 3371eec9fe27945f8af42a277f89ad08673e5e07..aed32a11ab4848a742437fc646502b905a793017 100644 (file)
   <section name="GUI" >
     <parameter name="documentation"     value="gui_help"/>
     <parameter name="site_url"          value="http://www.salome-platform.org"/>
+    <parameter name="tutorials_url"     value="https://www.salome-platform.org/user-section/salome-tutorials"/>
     <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>
     <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" />
-  <parameter name=""         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 #00 #00 #00 #00 #00 #00 #00 #00 #03 #00 #00 #05 #40 #00 #00 #00 #74 #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 #05 #40 #00 #00 #02 #6C #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" />
+  <parameter name="nomodule" value="#00 #00 #00 #FF #00 #00 #00 #00 #FD #00 #00 #00 #03 #00 #00 #00 #00 #00 #00 #01 #00 #00 #00 #02 #62 #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 #3B #00 #00 #02 #62 #00 #00 #00 #59 #00 #FF #FF #FF #00 #00 #00 #01 #00 #00 #00 #DC #00 #00 #02 #62 #FC #02 #00 #00 #00 #01 #FB #00 #00 #00 #1A #00 #69 #00 #6E #00 #66 #00 #6F #00 #50 #00 #61 #00 #6E #00 #65 #00 #6C #00 #44 #00 #6F #00 #63 #00 #6B #01 #00 #00 #00 #3B #00 #00 #02 #62 #00 #00 #02 #62 #00 #FF #FF #FF #00 #00 #00 #03 #00 #00 #04 #C3 #00 #00 #00 #59 #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 #04 #C3 #00 #00 #00 #46 #00 #FF #FF #FF #00 #00 #02 #DB #00 #00 #02 #62 #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 #03 #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 #BC #FF #FF #FF #FF #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #0E #00 #50 #00 #6C #00 #75 #00 #67 #00 #69 #00 #6E #00 #73 #00 #00 #00 #00 #22 #FF #FF #FF #FF #00 #00 #00 #00 #00 #00 #00 #00"/>
+  <parameter name="" 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 #00 #00 #00 #00 #00 #00 #00 #00 #03 #00 #00 #04 #C3 #00 #00 #00 #74 #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 #04 #C3 #00 #00 #00 #46 #00 #FF #FF #FF #00 #00 #04 #C3 #00 #00 #02 #5E #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 #03 #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 #11 #FF #FF #FF #FF #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #00 #0E #00 #50 #00 #6C #00 #75 #00 #67 #00 #69 #00 #6E #00 #73 #01 #00 #00 #00 #22 #FF #FF #FF #FF #00 #00 #00 #00 #00 #00 #00 #00"/>
  </section>
  <section name="windows_visibility">
-  <parameter name="nomodule" value="#00 #00 #00 #00 #04 #00 #00 #00 #0E #00 #4D #00 #6F #00 #64 #00 #75 #00 #6C #00 #65 #00 #73 #01 #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 #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 #10 #00 #53 #00 #74 #00 #61 #00 #6E #00 #64 #00 #61 #00 #72 #00 #64 #01 #01 #00 #00 #00 #05 #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 #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 #10 #00 #77 #00 #69 #00 #6E #00 #64 #00 #6F #00 #77 #00 #5F #00 #30 #01 #00 #00 #00 #10 #00 #77 #00 #69 #00 #6E #00 #64 #00 #6F #00 #77 #00 #5F #00 #31 #01 #00 #00 #00 #10 #00 #77 #00 #69 #00 #6E #00 #64 #00 #6F #00 #77 #00 #5F #00 #33 #01" />
-  <parameter name=""         value="#00 #00 #00 #00 #04 #00 #00 #00 #0E #00 #4D #00 #6F #00 #64 #00 #75 #00 #6C #00 #65 #00 #73 #01 #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 #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 #10 #00 #53 #00 #74 #00 #61 #00 #6E #00 #64 #00 #61 #00 #72 #00 #64 #01 #01 #00 #00 #00 #05 #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 #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 #10 #00 #77 #00 #69 #00 #6E #00 #64 #00 #6F #00 #77 #00 #5F #00 #30 #01 #00 #00 #00 #10 #00 #77 #00 #69 #00 #6E #00 #64 #00 #6F #00 #77 #00 #5F #00 #31 #01 #00 #00 #00 #10 #00 #77 #00 #69 #00 #6E #00 #64 #00 #6F #00 #77 #00 #5F #00 #33 #01" />
+  <parameter name="" value="#00 #00 #00 #00 #05 #00 #00 #00 #0E #00 #4D #00 #6F #00 #64 #00 #75 #00 #6C #00 #65 #00 #73 #01 #00 #00 #00 #0E #00 #50 #00 #6C #00 #75 #00 #67 #00 #69 #00 #6E #00 #73 #01 #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 #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 #10 #00 #53 #00 #74 #00 #61 #00 #6E #00 #64 #00 #61 #00 #72 #00 #64 #01 #01 #00 #00 #00 #05 #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 #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 #10 #00 #77 #00 #69 #00 #6E #00 #64 #00 #6F #00 #77 #00 #5F #00 #30 #01 #00 #00 #00 #10 #00 #77 #00 #69 #00 #6E #00 #64 #00 #6F #00 #77 #00 #5F #00 #31 #01 #00 #00 #00 #10 #00 #77 #00 #69 #00 #6E #00 #64 #00 #6F #00 #77 #00 #5F #00 #33 #01"/>
+  <parameter name="nomodule" value="#00 #00 #00 #00 #05 #00 #00 #00 #0E #00 #4D #00 #6F #00 #64 #00 #75 #00 #6C #00 #65 #00 #73 #01 #00 #00 #00 #0E #00 #50 #00 #6C #00 #75 #00 #67 #00 #69 #00 #6E #00 #73 #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 #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 #10 #00 #53 #00 #74 #00 #61 #00 #6E #00 #64 #00 #61 #00 #72 #00 #64 #01 #01 #00 #00 #00 #06 #00 #00 #00 #1A #00 #69 #00 #6E #00 #66 #00 #6F #00 #50 #00 #61 #00 #6E #00 #65 #00 #6C #00 #44 #00 #6F #00 #63 #00 #6B #01 #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 #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 #10 #00 #77 #00 #69 #00 #6E #00 #64 #00 #6F #00 #77 #00 #5F #00 #30 #01 #00 #00 #00 #10 #00 #77 #00 #69 #00 #6E #00 #64 #00 #6F #00 #77 #00 #5F #00 #31 #01 #00 #00 #00 #10 #00 #77 #00 #69 #00 #6E #00 #64 #00 #6F #00 #77 #00 #5F #00 #33 #01"/>
  </section>
 </document>
index 55249ed3f20d887cf51e6adca00e046feaa80f98..8a2ffb82cc8173419a9c0390bd97cf5ac40de28e 100644 (file)
@@ -58,6 +58,18 @@ CEA/DEN, CEDRAT, EDF R&amp;D, LEG, PRINCIPIA R&amp;D, BUREAU VERITAS</translatio
         <source>SALOME_VIDEO_TUTORIALS</source>
         <translation>Video Tutorials</translation>
     </message>
+    <message>
+        <source>PRP_SALOME_VIDEO_TUTORIALS</source>
+        <translation>Visit YouTube channel with some videos</translation>
+    </message>
+    <message>
+        <source>SALOME_TUTORIALS</source>
+        <translation>Tutorials</translation>
+    </message>
+    <message>
+        <source>PRP_SALOME_TUTORIALS</source>
+        <translation>Try tutorials from SALOME site</translation>
+    </message>
     <message>
         <source>ENTRY_COLUMN</source>
         <translation>Entry</translation>
@@ -168,6 +180,10 @@ The changes will be applied on the next application session.</translation>
         <source>OBJECT_BROWSER</source>
         <translation>Object Browser</translation>
     </message>
+    <message>
+        <source>INFO_PANEL</source>
+        <translation>Help panel</translation>
+    </message>
     <message>
         <source>PRP_DESK_PREFERENCES</source>
         <translation>Allow to change the preferences</translation>
@@ -1121,6 +1137,18 @@ File does not exist</translation>
     <source>PREF_PY_NUM_COLUMNS</source>
     <translation>Number of columns:</translation>
   </message>
+  <message>
+    <source>INFO_WELCOME_TO_SALOME</source>
+    <translation>Welcome to SALOME</translation>
+  </message>
+  <message>
+    <source>INFO_GETTING_STARTED</source>
+    <translation>Getting started</translation>
+  </message>
+  <message>
+    <source>INFO_AVAILABLE_MODULES</source>
+    <translation>Available modules</translation>
+  </message>
 </context>
 <context>
     <name>LightApp_Module</name>
index 3667f6b0dd512f7f32de37f184f6c56174f0ff7f..ad5568fc2aca3da34e42dd20d7bc4025fe67b545 100644 (file)
@@ -58,6 +58,18 @@ CEA/DEN, CEDRAT, EDF R&amp;D, LEG, PRINCIPIA R&amp;D, BUREAU VERITAS</translatio
         <source>SALOME_VIDEO_TUTORIALS</source>
         <translation type="unfinished">Video Tutorials</translation>
     </message>
+    <message>
+        <source>PRP_SALOME_VIDEO_TUTORIALS</source>
+        <translation type="unfinished">Visit YouTube channel with some videos</translation>
+    </message>
+    <message>
+        <source>SALOME_TUTORIALS</source>
+        <translation type="unfinished">Tutorials</translation>
+    </message>
+    <message>
+        <source>PRP_SALOME_TUTORIALS</source>
+        <translation type="unfinished">Try tutorials from SALOME site</translation>
+    </message>
     <message>
         <source>ENTRY_COLUMN</source>
         <translation>Entrée</translation>
@@ -168,6 +180,10 @@ Les modifications seront appliquées à la prochaine session.</translation>
         <source>OBJECT_BROWSER</source>
         <translation>Arbre d&apos;étude</translation>
     </message>
+    <message>
+        <source>INFO_PANEL</source>
+        <translation type="unfinished">Help panel</translation>
+    </message>
     <message>
         <source>PRP_DESK_PREFERENCES</source>
         <translation>Permettre de changer les préférences</translation>
@@ -1121,6 +1137,18 @@ Le fichier n&apos;existe pas</translation>
         <source>PREF_PY_NUM_COLUMNS</source>
         <translation>Nombre de colonnes:</translation>
     </message>
+    <message>
+      <source>INFO_WELCOME_TO_SALOME</source>
+      <translation type="unfinished">Welcome to SALOME</translation>
+    </message>
+    <message>
+      <source>INFO_GETTING_STARTED</source>
+      <translation type="unfinished">Getting started</translation>
+    </message>
+    <message>
+      <source>INFO_AVAILABLE_MODULES</source>
+      <translation type="unfinished">Available modules</translation>
+    </message>
 </context>
 <context>
     <name>LightApp_Module</name>
index 0d83e623c6fe15d58aad1bb0eca8310a8d5294b8..5688c2296cd247b1a465ee16596f7a3472b1ffc4 100644 (file)
@@ -58,6 +58,18 @@ CEA/DEN, CEDRAT, EDF R&amp;D, LEG, PRINCIPIA R&amp;D, BUREAU VERITAS</translatio
         <source>SALOME_VIDEO_TUTORIALS</source>
         <translation type="unfinished">Video Tutorials</translation>
     </message>
+    <message>
+        <source>PRP_SALOME_VIDEO_TUTORIALS</source>
+        <translation type="unfinished">Visit YouTube channel with some videos</translation>
+    </message>
+    <message>
+        <source>SALOME_TUTORIALS</source>
+        <translation type="unfinished">Tutorials</translation>
+    </message>
+    <message>
+        <source>PRP_SALOME_TUTORIALS</source>
+        <translation type="unfinished">Try tutorials from SALOME site</translation>
+    </message>
     <message>
       <source>ENTRY_COLUMN</source>
       <translation>エントリ</translation>
@@ -167,6 +179,10 @@ Pythonファイルは、文字、数字、アンダースコアが含まれて
       <source>OBJECT_BROWSER</source>
       <translation>オブジェクトブラウザー</translation>
     </message>
+    <message>
+        <source>INFO_PANEL</source>
+        <translation type="unfinished">Help panel</translation>
+    </message>
     <message>
       <source>PRP_DESK_PREFERENCES</source>
       <translation>設定を変更することができます。</translation>
@@ -1119,6 +1135,18 @@ Pythonファイルは、文字、数字、アンダースコアが含まれて
       <source>PREF_PY_NUM_COLUMNS</source>
       <translation>列数</translation>
     </message>
+    <message>
+      <source>INFO_WELCOME_TO_SALOME</source>
+      <translation type="unfinished">Welcome to SALOME</translation>
+    </message>
+    <message>
+      <source>INFO_GETTING_STARTED</source>
+      <translation type="unfinished">Getting started</translation>
+    </message>
+    <message>
+      <source>INFO_AVAILABLE_MODULES</source>
+      <translation type="unfinished">Available modules</translation>
+    </message>
   </context>
   <context>
     <name>LightApp_Module</name>
index 74f9edfd146d024f58f6c252e13b9284bae5cb6f..09835fef843486b3cddcda865d9ed785173fbc2d 100644 (file)
@@ -33,7 +33,7 @@ SET(_link_LIBRARIES ${QT_LIBRARIES} ${OPENGL_LIBRARIES})
 # --- headers ---
 
 # header files / to be processed by moc
-SET(_moc_HEADERS   
+SET(_moc_HEADERS
   QtxAction.h
   QtxActionGroup.h
   QtxActionMenuMgr.h
@@ -53,6 +53,7 @@ SET(_moc_HEADERS
   QtxFontEdit.h
   QtxGridBox.h
   QtxGroupBox.h
+  QtxInfoPanel.h
   QtxIntSpinBox.h
   QtxIntSpinSlider.h
   QtxListAction.h
@@ -146,6 +147,7 @@ SET(_other_SOURCES
   QtxFontEdit.cxx
   QtxGridBox.cxx
   QtxGroupBox.cxx
+  QtxInfoPanel.cxx
   QtxIntSpinBox.cxx
   QtxIntSpinSlider.cxx
   QtxListAction.cxx
index fc98276542d3be126a1daeb89da5154b158a8027..4bb125b31b4b855876aee5c427b561d8b2e1305d 100644 (file)
@@ -376,13 +376,7 @@ QtxDockWidget::~QtxDockWidget()
 */
 QSize QtxDockWidget::sizeHint() const
 {
-  QSize sz = QDockWidget::sizeHint();
-
-  // printf( "----------------> QtxDockWidget::sizeHint()\n" );
-
   return QSize( 500, 100 );
-
-  return sz;
 }
 
 /*!
@@ -391,9 +385,7 @@ QSize QtxDockWidget::sizeHint() const
 */
 QSize QtxDockWidget::minimumSizeHint() const
 {
-  QSize sz = QDockWidget::minimumSizeHint();
-
-  return sz;
+  return QDockWidget::minimumSizeHint();
 }
 
 /*!
@@ -415,6 +407,9 @@ void QtxDockWidget::setVisible( bool on )
     else
       myWatcher->hidden( this );
   }
+
+  if ( on )
+    emit( aboutToShow() );
 }
 
 /*!
index 53ecbb61f8e1887527e7da03be7c7df48d8fff3b..048a9e64d9af1b49a854fd248c8da512b0995f67 100644 (file)
@@ -49,6 +49,7 @@ public:
 
 signals:
   void            orientationChanged( Qt::Orientation );
+  void            aboutToShow();
 
 public slots:
   virtual void    setVisible( bool );
diff --git a/src/Qtx/QtxInfoPanel.cxx b/src/Qtx/QtxInfoPanel.cxx
new file mode 100644 (file)
index 0000000..49b44dd
--- /dev/null
@@ -0,0 +1,415 @@
+// 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
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "QtxInfoPanel.h"
+
+#include <QAction>
+#include <QFont>
+#include <QGroupBox>
+#include <QLabel>
+#include <QMap>
+#include <QPalette>
+#include <QSizePolicy>
+#include <QToolButton>
+#include <QVBoxLayout>
+#include <QScrollArea>
+
+/*!
+  \internal
+  \class QtxInfoPanel::Container
+  \brief Container to store widgets within info panel
+*/
+class QtxInfoPanel::Container: public QWidget
+{
+public:
+  Container( QWidget* = 0 );
+  Container( const QString&, QWidget* = 0 );
+
+  void addAction( QAction*, const int );
+  void addLabel( const QString&, Qt::Alignment, const int );
+  void addGroup( const QString&, const int );
+
+  QWidget* find( const int ) const;
+
+  void remove( const int );
+  void clear();
+
+  void put( QWidget* );
+
+private:
+  QMap<int, QWidget*> ids;
+  QGroupBox* group;
+};
+
+QtxInfoPanel::Container::Container( QWidget* parent )
+  : QWidget( parent ), group( 0 )
+{
+  QVBoxLayout* l = new QVBoxLayout( this );
+  l->setContentsMargins( 0, 0, 0, 0 );
+}
+
+QtxInfoPanel::Container::Container( const QString& title, QWidget* parent )
+  : Container( parent )
+{
+  QVBoxLayout* l = dynamic_cast<QVBoxLayout*>( layout() );
+  group = new QGroupBox( title );
+  group->setLayout( new QVBoxLayout() );
+  l->addWidget( group );
+}
+
+void QtxInfoPanel::Container::put( QWidget* widget )
+{
+  QVBoxLayout* l = group ? dynamic_cast<QVBoxLayout*>( group->layout() ) : dynamic_cast<QVBoxLayout*>( layout() );
+  l->addWidget( widget );
+}
+
+void QtxInfoPanel::Container::addLabel( const QString& text, Qt::Alignment alignment, const int id )
+{
+  QLabel* label = new QLabel( text );
+  QFont f = label->font();
+  f.setItalic( true );
+  label->setFont( f );
+  label->setAlignment( alignment );
+  label->setWordWrap( true );
+  put( label );
+  ids[ id ] = label;
+}
+
+void QtxInfoPanel::Container::addAction( QAction* action, const int id )
+{
+  QToolButton* button = new QToolButton( this );
+  button->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed );
+  button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
+  button->setAutoRaise( true );
+  button->setDefaultAction( action );
+  put( button );
+  ids[ id ] = button;
+}
+
+void QtxInfoPanel::Container::addGroup( const QString& text, const int id )
+{
+  Container* group = new Container( text, this );
+  put( group );
+  ids[ id ] = group;
+}
+
+QWidget* QtxInfoPanel::Container::find( const int id ) const
+{
+  if ( ids.contains( id ) )
+    return ids[id];
+
+  QMap<int, QWidget*>::ConstIterator it;
+  QWidget* widget = 0;
+  for( it = ids.begin(); it != ids.end() && !widget; ++it )
+  {
+    Container* group = dynamic_cast<Container*>( it.value() );
+    if ( group )
+      widget = group->find( id );
+  }
+
+  return widget;
+}
+
+void QtxInfoPanel::Container::remove( const int id )
+{
+  if ( ids.contains( id ) )
+  {
+    QVBoxLayout* l = group ? dynamic_cast<QVBoxLayout*>( group->layout() ) : dynamic_cast<QVBoxLayout*>( layout() );
+    l->removeWidget( ids[id] );
+    ids[id]->deleteLater();
+    l->invalidate();
+    ids.remove( id );
+  }
+}
+
+void QtxInfoPanel::Container::clear()
+{
+  QVBoxLayout* l = group ? dynamic_cast<QVBoxLayout*>( group->layout() ) : dynamic_cast<QVBoxLayout*>( layout() );
+
+  QList<QWidget*> widgets = ids.values();
+  foreach( QWidget* widget, widgets )
+  {
+    l->removeWidget( widget );
+    widget->deleteLater();
+  }
+
+  l->invalidate();
+  ids.clear();
+}
+
+
+/*!
+  \internal
+  \class QtxInfoPanel::Title
+  \brief Info panel's title widget
+*/
+class QtxInfoPanel::Title: public QLabel
+{
+public:
+  Title( QWidget* parent = 0 );
+};
+
+QtxInfoPanel::Title::Title( QWidget* parent )
+  : QLabel( parent )
+{
+  setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed );
+  QString bg = palette().color( QPalette::Highlight ).name();
+  QString fg = palette().color( QPalette::HighlightedText ).name();
+  setStyleSheet( QString( "QLabel { background:%1; color:%2; }" ).arg( bg ).arg( fg ) );
+  setTextFormat( Qt::PlainText );
+  QFont f = font();
+  f.setBold( true );
+  setFont( f );
+  setContentsMargins( 2, 5, 2, 5 );
+}
+
+
+/*!
+  \class QtxInfoPanel
+  \brief Info panel which allows presenting welcome, useful hints
+  and other information dynamically, e.g. in the dock panel of main
+  application's window.
+
+  The *Info panel* normally has a title (aimed to shortly present the
+  current application's context) and a set of buttons and text labels
+  combined into the groups (which may be nested).
+
+  Buttons normally represent some quick actions which are applicable in
+  the current context. Text labels can be used to show additional information
+  like hints, proposed actions, etc.
+
+  To set the title to the panel, use method setTitle(). Text label can be
+  added to the panel with addLabel() method, action (button) is added via
+  addAction() method.
+
+  By default, items are added to the top level, untitled group. Additionally,
+  panel allows arranging items into groups; new group can be added with the
+  addGroup() method.
+
+  Each of addAction(), addLabel(), addGroup() methods return item's unique
+  identifier. This identifier can be used, for instance, to enable/disable
+  item with setEnabled() method, hide/show with setVisible() method, remove
+  from panel with remove() method. The same action can be added to the panel
+  several times, e.g. to the different groups - the corresponding buttons will
+  have different unique ids.
+
+  To remove all contents of panel, use clear() method.
+*/
+
+/*!
+  \brief Create panel.
+  \param parent Parent widget.
+ */
+QtxInfoPanel::QtxInfoPanel( QWidget* parent )
+  : QWidget( parent )
+{
+  title = new Title( this );
+  container = new Container( this );
+
+  QVBoxLayout* layout = new QVBoxLayout( this );
+  layout->setContentsMargins( 0, 0, 0, 0 );
+
+  QWidget* wg = new QWidget();
+  QVBoxLayout* wg_layout = new QVBoxLayout( wg );
+  wg_layout->setContentsMargins( 0, 0, 0, 0 );
+  wg_layout->addWidget( container );
+  wg_layout->addStretch();
+  
+  QScrollArea* scroll = new QScrollArea();
+  scroll->setWidgetResizable( true );
+  scroll->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
+  scroll->setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Expanding );
+  scroll->setSizeAdjustPolicy( QScrollArea::AdjustToContents );
+  scroll->setFrameStyle( QScrollArea::NoFrame );
+  scroll->setContentsMargins( 0, 0, 0, 0 );
+  scroll->setWidget( wg );
+  
+  layout->addWidget( title );
+  layout->addWidget( scroll );
+  setTitle( "" );
+}
+
+/*!
+  \brief Destructor.
+*/
+QtxInfoPanel::~QtxInfoPanel()
+{
+}
+
+/*!
+  \brief Add left-aligned text label to the given group.
+  \param text Label's text.
+  \param groupId Group's identifier. Value -1 (default) is used
+  to add label to the top-level (untitled) group.
+  \return Label's unique identifier.
+*/
+int QtxInfoPanel::addLabel( const QString& text, const int groupId )
+{
+  return addLabel( text, Qt::AlignLeft, groupId );
+}
+
+/*!
+  \brief Add text label to the given group.
+  \param text Label's text.
+  \param alignment Label's alignment.
+  \param groupId Group's identifier. Value -1 (default) is used
+  to add label to the top-level (untitled) group.
+  \return Label's unique identifier.
+*/
+int QtxInfoPanel::addLabel( const QString& text, Qt::Alignment alignment, const int groupId )
+{
+  int id = 0;
+  Container* c = dynamic_cast<Container*>( find( groupId ) );
+  if ( c )
+  {
+    id = generateId();
+    c->addLabel( text, alignment, id );
+  }
+  return id;
+}
+
+/*!
+  \brief Add action button to the given group.
+  \param action Action being added (note: parent is not changed).
+  \param groupId Group's identifier. Value -1 (default) is used
+  to add button to the top-level (untitled) group.
+  \return Button's unique identifier.
+*/
+int QtxInfoPanel::addAction( QAction* action, const int groupId )
+{
+  int id = 0;
+  Container* c = dynamic_cast<Container*>( find( groupId ) );
+  if ( c )
+  {
+    id = generateId();
+    c->addAction( action, id );
+  }
+  return id;
+}
+
+/*!
+  \brief Add (sub-)group to the given group.
+  \param text Group's title.
+  \param groupId Parent group's identifier. Value -1 (default) is used
+  to add (sub-)group to the top-level (untitled) group (i.e. panel itself).
+  \return Group's unique identifier.
+*/
+int QtxInfoPanel::addGroup( const QString& text, const int groupId )
+{
+  int id = 0;
+  Container* c = dynamic_cast<Container*>( find( groupId ) );
+  if ( c )
+  {
+    id = generateId();
+    c->addGroup( text, id );
+  }
+  return id;
+}
+
+/*!
+  \brief Set panel's title.
+  \param text %Title text (empty string removes title).
+*/
+void QtxInfoPanel::setTitle( const QString& text )
+{
+  title->setText( text );
+  title->setVisible( !title->text().isEmpty() );
+}
+
+/*!
+  \brief Remove given item from panel.
+  \note If a group is removed, all its contents (recursively) is removed
+  as well.
+  \param id Item's (label's, button's, group's) identifier.
+*/
+void QtxInfoPanel::remove( const int id )
+{
+  QWidget* widget = find( id );
+  if ( widget )
+  {
+    Container* group = dynamic_cast<Container*>( widget->parentWidget() );
+    if ( !group )
+      group = dynamic_cast<Container*>( widget->parentWidget()->parentWidget() );
+    if ( group )
+      group->remove( id );
+  }
+}
+
+/*!
+  \brief Clear contents of panel of group.
+  \param groupId Group's identifier. Value -1 (default) is used
+  to clear all contents of panel.
+*/
+void QtxInfoPanel::clear( const int groupId )
+{
+  Container* c = dynamic_cast<Container*>( find( groupId ) );
+  if ( c )
+    c->clear();
+}
+
+/*!
+  \internal
+  \brief Find widget that represents given item.
+  \param id Item's (label's, button's, group's) identifier.
+  \return Item's widget (0 if not found).
+*/
+QWidget* QtxInfoPanel::find( const int id ) const
+{
+  if ( id == -1 )
+    return container;
+  return container->find( id );
+}
+
+/*!
+  \brief Change item's visibility.
+  \param id Item's (label's, button's, group's) identifier.
+  \param visible \c true to show item, \c false to hide it.
+*/
+void QtxInfoPanel::setVisible( const int id, bool visible )
+{
+  QWidget* widget = find( id );
+  if ( widget )
+    widget->setVisible( visible );
+}
+
+/*!
+  \brief Enable / disable item.
+  \param id Item's (label's, button's, group's) identifier.
+  \param enabled \c true to enable item, \c false to disable it.
+*/
+void QtxInfoPanel::setEnabled( const int id, bool enabled )
+{
+  QWidget* widget = find( id );
+  if ( widget )
+    widget->setEnabled( enabled );
+}
+
+/*!
+  \internal
+  \brief Generate new unique identifier.
+  \return Unique identifier.
+*/
+int QtxInfoPanel::generateId() const
+{
+  static int id = -100;
+  return --id;
+}
diff --git a/src/Qtx/QtxInfoPanel.h b/src/Qtx/QtxInfoPanel.h
new file mode 100644 (file)
index 0000000..4f4120d
--- /dev/null
@@ -0,0 +1,72 @@
+// 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
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef QTXINFOPANEL_H
+#define QTXINFOPANEL_H
+
+#include "Qtx.h"
+
+#include <QWidget>
+
+#ifdef WIN32
+#pragma warning( disable:4251 )
+#endif
+
+class QAction;
+
+class QTX_EXPORT QtxInfoPanel : public QWidget
+{
+  Q_OBJECT
+
+  class Container;
+  class Title;
+
+public:
+  QtxInfoPanel( QWidget* = 0 );
+  ~QtxInfoPanel();
+
+  void                setTitle( const QString& );
+  int                 addLabel( const QString&, const int = -1 );
+  int                 addLabel( const QString&, Qt::Alignment, const int = -1 );
+  int                 addAction( QAction*, const int = -1 );
+  int                 addGroup( const QString&, const int = -1 );
+
+  void                remove( const int );
+  void                clear( const int = -1 );
+
+  void                setVisible( const int, bool );
+  void                setEnabled( const int, bool );
+
+private:
+  int                 generateId() const;
+  QWidget*            find( const int ) const;
+
+private:
+  Title*              title;
+  Container*          container;
+};
+
+#ifdef WIN32
+#pragma warning( default:4251 )
+#endif
+
+#endif // QTXINFOPANEL_H
index e243c2d4aede656b54e23fa518f2bda0be6c3d58..55d8e32bb6042584a1886b8d2208bd53cd0973a0 100644 (file)
@@ -56,6 +56,7 @@
 #include "QtxActionMenuMgr.h"
 #include "QtxWorkstack.h"
 #include "QtxTreeView.h"
+#include "QtxInfoPanel.h"
 #include "SALOME_Event.h"
 #include "STD_TabDesktop.h"
 #include "SUIT_DataBrowser.h"
@@ -2903,6 +2904,256 @@ void SalomePyQt::message( const QString& msg, bool addSeparator )
   ProcessVoidEvent( new TEvent( msg, addSeparator ) );
 }
 
+/*!
+  \brief Set the title to the Help panel.
+  \param title Title text (empty string removes title)
+*/
+void SalomePyQt::infoSetTitle( const QString& title )
+{
+  class TEvent: public SALOME_Event
+  {
+    QString myTitle;
+  public:
+    TEvent( const QString& title ) 
+      : myTitle( title ) {}
+    virtual void Execute()
+    {
+      if ( LightApp_Application* anApp = getApplication() ) {
+        QtxInfoPanel* ip = anApp->infoPanel();
+        if ( ip )
+          ip->setTitle( myTitle );
+      }
+    }
+  };
+  ProcessVoidEvent( new TEvent( title ) );
+}
+
+/*!
+  \fn int SalomePyQt::infoAddLabel( const QString& text, const int groupId )
+  \brief Insert left-aligned text label into the Help panel
+  \param text Label text
+  \param groupId Parent group's identifier (defaults to -1 for top-level group)
+  \return Label's identifier
+*/
+
+class TInfoAddLabel2paramEvent: public SALOME_Event
+{
+public:
+  typedef int TResult;
+  TResult myResult;
+  QString myText;
+  int     myGroupId;
+  TInfoAddLabel2paramEvent( const QString& text, const int groupId )
+    : myText( text ), myGroupId( groupId ) {}
+  virtual void Execute()
+  {
+    if ( LightApp_Application* anApp = getApplication() ) {
+      QtxInfoPanel* ip = anApp->infoPanel();
+      if ( ip )
+        myResult = ip->addLabel( myText, myGroupId );
+    }
+  }
+};
+int SalomePyQt::infoAddLabel( const QString& text, const int groupId )
+{
+  return ProcessEvent( new TInfoAddLabel2paramEvent( text, groupId ) );
+}
+
+/*!
+  \fn int SalomePyQt::infoAddLabel( const QString& text, Qt::Alignment alignment, const int groupId )
+  \brief Insert text label into the Help panel
+  \param text Label text
+  \param alignment Alignment flag for text label
+  \param groupId Parent group's identifier (defaults to -1 for top-level group)
+  \return Label's identifier
+*/
+
+class TInfoAddLabel3paramEvent: public SALOME_Event
+{
+public:
+  typedef int TResult;
+  TResult myResult;
+  QString myText;
+  Qt::Alignment myAlignment;
+  int     myGroupId;
+  TInfoAddLabel3paramEvent( const QString& text, Qt::Alignment alignment, const int groupId )
+    : myText( text ), myAlignment( alignment ), myGroupId( groupId ) {}
+  virtual void Execute()
+  {
+    if ( LightApp_Application* anApp = getApplication() ) {
+      QtxInfoPanel* ip = anApp->infoPanel();
+      if ( ip )
+        myResult = ip->addLabel( myText, myAlignment, myGroupId );
+    }
+  }
+};
+int SalomePyQt::infoAddLabel( const QString& text, Qt::Alignment alignment, const int groupId )
+{
+  return ProcessEvent( new TInfoAddLabel3paramEvent( text, alignment, groupId ) );
+}
+
+/*!
+  \fn int SalomePyQt::infoAddAction( QAction* action, const int groupId )
+  \brief Insert action button into the Help panel
+  \param action Action being added
+  \param groupId Parent group's identifier (defaults to -1 for top-level group)
+  \return Action's identifier
+*/
+
+class TInfoAddActionEvent: public SALOME_Event
+{
+public:
+  typedef int TResult;
+  TResult myResult;
+  QAction* myAction;
+  int     myGroupId;
+  TInfoAddActionEvent( QAction* action, const int groupId )
+    : myAction( action ), myGroupId( groupId ) {}
+  virtual void Execute()
+  {
+    if ( LightApp_Application* anApp = getApplication() ) {
+      QtxInfoPanel* ip = anApp->infoPanel();
+      if ( ip )
+        myResult = ip->addAction( myAction, myGroupId );
+    }
+  }
+};
+int SalomePyQt::infoAddAction( QAction* action, const int groupId )
+{
+  return ProcessEvent( new TInfoAddActionEvent( action, groupId ) );
+}
+
+/*!
+  \fn int SalomePyQt::infoAddGroup( const QString& text, const int groupId )
+  \brief Create a (sub-)group in the Help panel
+  \param text Group title
+  \param groupId Parent group's identifier (defaults to -1 for top-level group)
+  \return Group's identifier
+*/
+
+class TInfoAddGroupEvent: public SALOME_Event
+{
+public:
+  typedef int TResult;
+  TResult myResult;
+  QString myText;
+  int     myGroupId;
+  TInfoAddGroupEvent( const QString& text, const int groupId )
+    : myText( text ), myGroupId( groupId ) {}
+  virtual void Execute()
+  {
+    if ( LightApp_Application* anApp = getApplication() ) {
+      QtxInfoPanel* ip = anApp->infoPanel();
+      if ( ip )
+        myResult = ip->addGroup( myText, myGroupId );
+    }
+  }
+};
+int SalomePyQt::infoAddGroup( const QString& text, const int groupId )
+{
+  return ProcessEvent( new TInfoAddGroupEvent( text, groupId ) );
+}
+
+/*!
+  \brief Remove item from the Help panel
+  \param id Item's (label's, action's, group's, ...) identifier
+*/
+void SalomePyQt::infoRemove( const int id )
+{
+  class TEvent: public SALOME_Event
+  {
+    int myId;
+  public:
+    TEvent( const int id ) 
+      : myId( id ) {}
+    virtual void Execute()
+    {
+      if ( LightApp_Application* anApp = getApplication() ) {
+        QtxInfoPanel* ip = anApp->infoPanel();
+        if ( ip )
+          ip->remove( myId );
+      }
+    }
+  };
+  ProcessVoidEvent( new TEvent( id ) );
+}
+
+/*!
+  \brief Clear Help panel's contents
+  \param groupId Group's identifier (default is -1, to clear whole panel)
+*/
+void SalomePyQt::infoClear( const int groupId )
+{
+  class TEvent: public SALOME_Event
+  {
+    int myGroupId;
+  public:
+    TEvent( const int groupId ) 
+      : myGroupId( groupId ) {}
+    virtual void Execute()
+    {
+      if ( LightApp_Application* anApp = getApplication() ) {
+        QtxInfoPanel* ip = anApp->infoPanel();
+        if ( ip )
+          ip->clear( myGroupId );
+      }
+    }
+  };
+  ProcessVoidEvent( new TEvent( groupId ) );
+}
+
+/*!
+  \brief Set item's visibility in the Help panel
+  \param id Item's (label's, action's, group's, ...) identifier
+  \param visible Visibility flag
+*/
+void SalomePyQt::infoSetVisible( const int id, bool visible )
+{
+  class TEvent: public SALOME_Event
+  {
+    int myId;
+    bool myVisible;
+  public:
+    TEvent( const int id, bool visible ) 
+      : myId( id ), myVisible( visible ) {}
+    virtual void Execute()
+    {
+      if ( LightApp_Application* anApp = getApplication() ) {
+        QtxInfoPanel* ip = anApp->infoPanel();
+        if ( ip )
+          ip->setVisible( myId, myVisible );
+      }
+    }
+  };
+  ProcessVoidEvent( new TEvent( id, visible ) );
+}
+
+/*!
+  \brief Enable/disable item in the Help panel
+  \param id Item's (label's, action's, group's, ...) identifier
+  \param enabled Enabled state
+*/
+void SalomePyQt::infoSetEnabled( const int id, bool enabled )
+{
+  class TEvent: public SALOME_Event
+  {
+    int myId;
+    bool myEnabled;
+  public:
+    TEvent( const int id, bool enabled ) 
+      : myId( id ), myEnabled( enabled ) {}
+    virtual void Execute()
+    {
+      if ( LightApp_Application* anApp = getApplication() ) {
+        QtxInfoPanel* ip = anApp->infoPanel();
+        if ( ip )
+          ip->setEnabled( myId, myEnabled );
+      }
+    }
+  };
+  ProcessVoidEvent( new TEvent( id, enabled ) );
+}
+
 /*!
   \brief Remove all the messages from the Log messages output window.
 */
index 34089b95b2eb1219c48fe6ce2beb39e86ef535e2..82ecb817302cc3f1656e52a40f2a07fc82205cdb 100644 (file)
@@ -89,6 +89,7 @@ enum {
   WT_ObjectBrowser = LightApp_Application::WT_ObjectBrowser,
   WT_PyConsole     = LightApp_Application::WT_PyConsole,
   WT_LogWindow     = LightApp_Application::WT_LogWindow,
+  WT_InfoPanel     = LightApp_Application::WT_InfoPanel,
 #ifndef GUI_DISABLE_CORBA
   WT_NoteBook      = SalomeApp_Application::WT_NoteBook,
   WT_User          = SalomeApp_Application::WT_User
@@ -199,6 +200,18 @@ public:
   static void              registerModule( const QString& );
   static void              updateObjBrowser();
 
+  static void              infoSetTitle( const QString& );
+  static int               infoAddLabel( const QString&, const int = -1 );
+  static int               infoAddLabel( const QString&, Qt::Alignment, const int = -1 );
+  static int               infoAddAction( QAction*, const int = -1 );
+  static int               infoAddGroup( const QString&, const int = -1 );
+
+  static void              infoRemove( const int );
+  static void              infoClear( const int = -1 );
+
+  static void              infoSetVisible( const int, bool );
+  static void              infoSetEnabled( const int, bool );
+
   static void              putInfo( const QString&, const int = 0 );
   static int               showNotification( const QString&, const QString&, const int = -1 );
   static void              hideNotification( const QString& );
index ed20aafac82d3e1ce59243845255748bee18013e..bc30e3450af4aaf21e452ef6d5553917388bbccd 100644 (file)
@@ -79,6 +79,7 @@ enum WindowType {
   WT_ObjectBrowser,
   WT_PyConsole,
   WT_LogWindow,
+  WT_InfoPanel,
 %If (ENABLE_CORBA)
   WT_NoteBook,
 %End
@@ -310,6 +311,18 @@ public:
   static void              registerModule( const QString& ) /ReleaseGIL/ ;
   static void              updateObjBrowser() /ReleaseGIL/ ;
 
+  static void              infoSetTitle( const QString& ) /ReleaseGIL/ ;
+  static int               infoAddLabel( const QString&, const int = -1 ) /ReleaseGIL/ ;
+  static int               infoAddLabel( const QString&, Qt::Alignment, const int = -1 ) /ReleaseGIL/ ;
+  static int               infoAddAction( QAction*, const int = -1 ) /ReleaseGIL/ ;
+  static int               infoAddGroup( const QString&, const int = -1 ) /ReleaseGIL/ ;
+
+  static void              infoRemove( const int ) /ReleaseGIL/ ;
+  static void              infoClear( const int = -1 ) /ReleaseGIL/ ;
+
+  static void              infoSetVisible( const int, bool ) /ReleaseGIL/ ;
+  static void              infoSetEnabled( const int, bool ) /ReleaseGIL/ ;
+
   static void              putInfo( const QString&, const int = 0 ) /ReleaseGIL/ ;
   static int               showNotification( const QString&, const QString&, const int = -1 ) /ReleaseGIL/ ;
   static void              hideNotification( const QString& ) /ReleaseGIL/ ;
index 382d9db5ab00f1852c41e8a87448d31f6fa3d7c9..0956e8f71e91f1793dd6d21065369d0aa42448f3 100644 (file)
@@ -144,11 +144,11 @@ Directory with this name exist on disc. Try to use another name</translation>
     </message>
     <message>
         <source>PRP_DESK_FILE_NEW</source>
-        <translation>Creates a new document</translation>
+        <translation>Create a new document</translation>
     </message>
     <message>
         <source>PRP_DESK_FILE_MRU</source>
-        <translation>Opens a document</translation>
+        <translation>Open a document</translation>
     </message>
     <message>
         <source>MEN_DESK_FILE_NEW</source>
@@ -376,7 +376,7 @@ Do you want to overwrite it?</translation>
     </message>
     <message>
         <source>PRP_DESK_FILE_OPEN</source>
-        <translation>Opens an existing document</translation>
+        <translation>Open an existing document</translation>
     </message>
     <message>
         <source>PRP_DESK_FILE_REOPEN</source>
@@ -384,7 +384,7 @@ Do you want to overwrite it?</translation>
     </message>
     <message>
         <source>PRP_DESK_FILE_SAVE</source>
-        <translation>Saves the active document</translation>
+        <translation>Save the active document</translation>
     </message>
     <message>
         <source>PRP_DESK_WINDOW_HTILE</source>