Salome HOME
Copyright update 2022
[modules/gui.git] / src / LightApp / LightApp_Application.cxx
index 1aa01cf53bf075d186cc28c3843646a311ebe0a4..e86a70914403dd37207f75b4073c550d65590aa7 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2020  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2022  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>
 #include <utilities.h>
 
 #define FIRST_HELP_ID 1000000
+#define HAS_WWW_URL true
+#define HAS_FORUM_URL true
+#define HAS_YOUTUBE_URL true
+#define HAS_TUTORIAL_URL false
 
 #ifndef DISABLE_SALOMEOBJECT
   #include <SALOME_InteractiveObject.hxx>
@@ -300,6 +305,24 @@ namespace
       result = QLocale( lang ).nativeLanguageName();
     return result;
   }
+
+  QString getHelpItem( const QString& section, const QString& parameter, const QString& root = QString() )
+  {
+    SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
+    foreach( QString item, resMgr->stringValue( section, parameter ).split( ";;", QString::SkipEmptyParts ) )
+    {
+      if ( item.startsWith( "http", Qt::CaseInsensitive ) )
+        return item;
+      QString path = item;
+      path.remove( QRegExp( "#.*$" ) );
+      QFileInfo fi( path );
+      if ( fi.isRelative() && !root.isEmpty() )
+        path = Qtx::addSlash( root ) + path;
+      if ( QFile::exists( path ) )
+        return item;
+    }
+    return QString();
+  }
 }
 
 /*!Create new instance of LightApp_Application.*/
@@ -464,7 +487,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 +549,9 @@ bool LightApp_Application::activateModule( const QString& modName )
 
   saveDockWindowsState();
 
+  if ( infoPanel() )
+    infoPanel()->clear();
+
   bool status = CAM_Application::activateModule( modName );
 
   updateModuleActions();
@@ -539,7 +565,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,50 +620,69 @@ void LightApp_Application::createActions()
   // Help menu
 
   int helpMenu = createMenu( tr( "MEN_DESK_HELP" ), -1, -1, 1000 );
-  
+
   int id = LightApp_Application::UserID + FIRST_HELP_ID;
 
+  QString url;
+
   // 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,
-                               resMgr->loadPixmap( "LightApp", tr( "ICON_WWW" ), false ),
-                               title, title,
-                               0, desk, false, this, SLOT( onHelpContentsModule() ) );
-    as->setData( url );
-    createMenu( as, helpMenu, -1, 0 );
-    id++;
+  if ( HAS_WWW_URL ) {
+    url = resMgr->stringValue("GUI", "site_url");
+    if ( !url.isEmpty() ) {
+      QString title = tr ( "SALOME_SITE" );
+      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 );
+    }
   }
 
   // b) Link to Forum
-  url = resMgr->stringValue("GUI", "forum_url");
-  if ( !url.isEmpty() ) {
-    QString title = tr ( "SALOME_FORUM" );
-    QAction* af = createAction( helpMenu, 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++;
+  if ( HAS_FORUM_URL ) {
+    url = resMgr->stringValue("GUI", "forum_url");
+    if ( !url.isEmpty() ) {
+      QString title = tr ( "SALOME_FORUM" );
+      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 );
+    }
   }
 
   // c) Link to YouTube channel
-  url = resMgr->stringValue("GUI", "channel_url");
-  if ( !url.isEmpty() ) {
-    createMenu( separator(), helpMenu, -1, 0 );
-    QString title = tr ( "SALOME_VIDEO_TUTORIALS" );
-    QAction* av = createAction( helpMenu, title,
-                               resMgr->loadPixmap( "LightApp", tr( "ICON_LIFE_RIGN" ), false ),
-                               title, title,
-                               0, desk, false, this, SLOT( onHelpContentsModule() ) );
-    av->setData( url );
-    createMenu( av, helpMenu, -1, 0 );
-    id++;
+  if ( HAS_YOUTUBE_URL ) {
+    url = resMgr->stringValue("GUI", "channel_url");
+    if ( !url.isEmpty() ) {
+      createMenu( separator(), helpMenu, -1, 0 );
+      QString title = tr ( "SALOME_VIDEO_TUTORIALS" );
+      QAction* av = createAction( VideosId, title,
+                                  resMgr->loadPixmap( "LightApp", tr( "ICON_LIFE_RIGN" ), false ),
+                                  title, tr( "PRP_SALOME_VIDEO_TUTORIALS" ),
+                                  0, desk, false, this, SLOT( onHelpContentsModule() ) );
+      av->setData( url );
+      createMenu( av, helpMenu, -1, 0 );
+    }
+  }
+
+  // d) Link to Tutorials
+  if ( HAS_TUTORIAL_URL ) {
+    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 );
+    }
   }
 
-  // d) Help for modules
+  // e) Help for modules
 
   // - First create top-level menus to preserve correct order
   QString userGuide = "User's Guide";
@@ -659,7 +704,7 @@ 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  = Qtx::getenv( rootDir.toUtf8().constData() );        // module root dir path
+    QString modDir  = Qtx::getenv( rootDir.toUtf8().constData() );   // module root dir path
     QString docSection;
     if (resMgr->hasValue( modName, "documentation" ) )
       docSection = resMgr->stringValue(modName, "documentation");
@@ -669,29 +714,11 @@ void LightApp_Application::createActions()
       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() ) {
-          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;
-              }
-            }
-          }
-        }
+      foreach( QString paramName, resMgr->parameters( docSection ) ) {
+        QString key = paramName.contains( "%1" ) ? paramName.arg( aModule ) : paramName;
+        QString helpItem = getHelpItem( docSection, paramName );
+        if ( !helpItem.isEmpty() )
+          helpData.insert( key, helpItem );
       }
     }
 
@@ -705,7 +732,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 +746,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() ) );
@@ -742,20 +769,15 @@ void LightApp_Application::createActions()
 
   QStringList addHelpItems = resMgr->parameters( "add_help" );
   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;
-        }
-      }
+    QString helpItem = getHelpItem( "add_help", paramName );
+    if ( !helpItem.isEmpty() )
+    {
+      QPixmap helpIcon = helpItem.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( helpItem );
+      createMenu( a, helpMenu, -1, 10 );
     }
   }
 
@@ -1006,7 +1028,7 @@ void LightApp_Application::onNewDoc()
 
   //asl: fix for 0020515
   saveDockWindowsState();
-  
+
   CAM_Application::onNewDoc();
 }
 
@@ -1064,7 +1086,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 )
@@ -1206,12 +1228,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() )
       {
@@ -1236,7 +1263,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
 
@@ -1248,7 +1275,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 );
@@ -1369,9 +1396,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 +1477,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
 */
@@ -1455,7 +1496,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
 */
@@ -1793,6 +1834,7 @@ void LightApp_Application::onStudyCreated( SUIT_Study* theStudy )
   }
 
   getWindow( WT_ObjectBrowser );
+  getWindow( WT_InfoPanel );
 
   loadDockWindowsState();
 
@@ -1824,6 +1866,7 @@ void LightApp_Application::onStudyOpened( SUIT_Study* theStudy )
   }
 
   getWindow( WT_ObjectBrowser );
+  getWindow( WT_InfoPanel );
 
   loadDockWindowsState();
 
@@ -2129,6 +2172,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 +2216,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 );
   }
 }
@@ -2345,7 +2396,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" );
@@ -4126,6 +4177,36 @@ 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 );
+    if ( HAS_TUTORIAL_URL ) {
+      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 +5095,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.
@@ -5181,7 +5268,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;
 
@@ -5196,18 +5283,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 ( 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 );
       }
     }
   }