Salome HOME
PR: mergefrom_PAL_OCC_21Oct04
[modules/kernel.git] / src / SALOMEGUI / QAD_Desktop.cxx
index 189665a8e367f45ae0dda69484e9b97d77557de6..ac1763f4d810eb166a47bf99a18001743cc8be21 100644 (file)
   \class QAD_Desktop QAD_Desktop.h
   \brief Main desktop of QAD-based application.
 */
-using namespace std;
 # include "Utils_ORB_INIT.hxx"
 # include "Utils_SINGLETON.hxx"
 
 #define         INCLUDE_MENUITEM_DEF
+#define  DEFAULT_BROWSER "mozilla"
+
 
 #include "QAD.h"
 #include "QAD_Help.h"
@@ -42,6 +43,7 @@ using namespace std;
 #include "QAD_Desktop.h"
 #include "QAD_LeftFrame.h"
 #include "QAD_RightFrame.h"
+#include "QAD_PyEditor.h"
 #include "QAD_Operation.h"
 #include "QAD_XmlHandler.h"
 #include "QAD_MessageBox.h"
@@ -51,21 +53,28 @@ using namespace std;
 #include "QAD_ObjectBrowser.h"
 #include "QAD_Resource.h"
 #include "QAD_FileDlg.h"
-#include "QAD_HelpWindow.h"
+//NRI #include "QAD_HelpWindow.h"
 #include "QAD_DirListDlg.h"
 #include "QAD_WaitCursor.h"
+#include "SALOMEGUI.h"
 #include "SALOMEGUI_OpenWith.h"
 #include "SALOMEGUI_StudyPropertiesDlg.h"
 #include "SALOMEGUI_TrihedronSizeDlg.h"
+#include "SALOMEGUI_ExternalBrowserDlg.h"
 #include "SALOMEGUI_LoadStudiesDlg.h"
-#include "SALOME_Selection.h"
+//#include "SALOME_Selection.h"
 #include "SALOME_InteractiveObject.hxx"
 #include "SALOME_ListIteratorOfListIO.hxx"
 #include "SALOMEGUI_AboutDlg.h"
 #include "SALOMEGUI_ViewChoiceDlg.h"
+#include "SALOMEGUI_SetValueDlg.h"
 #include "utilities.h"
 
 #include "SALOMEGUI_CloseDlg.h"
+#include "SALOMEGUI_ActivateComponentDlg.h"
+#include "SALOMEGUI_QtCatchCorbaException.hxx"
+
+#include "SALOME_Event.hxx"
 
 // QT Includes
 #include <qlabel.h>
@@ -87,6 +96,9 @@ using namespace std;
 #include <qfontdialog.h>
 #include <qlineedit.h>
 #include <qdatetime.h>
+#include <qthread.h>
+
+#include <qstringlist.h>
 
 #if QT_VERSION > 300
   #include <qlistbox.h>
@@ -94,9 +106,11 @@ using namespace std;
 #endif
 
 // Open CASCADE Includes
+#include <OSD_SharedLibrary.hxx>
 #include <OSD_LoadMode.hxx>
 #include <OSD_Function.hxx>
 #include <TCollection_AsciiString.hxx>
+using namespace std;
 
 static const char* SEPARATOR    = ":";
 
@@ -108,6 +122,18 @@ extern "C"
 QAD_ResourceMgr* QAD_Desktop::resourceMgr = 0;
 QPalette*       QAD_Desktop::palette = 0;
 
+static QString createString( int theItemId, int thePosId ) 
+{
+  QString aRetString = QString("item-id=");
+  QString aString;
+  QString aItemId = aString.setNum(theItemId);
+  QString aPosId = aString.setNum(thePosId);
+  aRetString = aRetString + '"'; aRetString = aRetString + aItemId; aRetString = aRetString + '"'; 
+  aRetString = aRetString + " pos-id="; aRetString = aRetString + '"';
+  aRetString = aRetString + aPosId; 
+  aRetString = aRetString + '"'; aRetString = aRetString + ">";
+  return aRetString;
+}
 
 /*!
     Creates the resource manager [ static ]
@@ -174,9 +200,10 @@ myStatusBar(0),
 myActiveApp(0),
 myActiveStudy(0),
 myCntUntitled(0),
-myHelpWindow(0),
+//NRImyHelpWindow(0),
 myDefaultTitle( tr("DESK_DEFAULTTITLE") ),
-myQueryClose( true )
+myQueryClose( true ),
+myAboutToClose( false )
 {
   /* Force reading of user config file */
   QAD_CONFIG->readConfigFile();  
@@ -262,9 +289,9 @@ myQueryClose( true )
     QString resDir;
 
     /* find component icon */
-    QString iconfile = strdup(list_composants[ind].moduleicone) ;
-    QString modulename = strdup(list_composants[ind].modulename) ;
-    QString moduleusername = strdup(list_composants[ind].moduleusername) ;
+    QString iconfile = CORBA::string_dup(list_composants[ind].moduleicone) ;
+    QString modulename = CORBA::string_dup(list_composants[ind].modulename) ;
+    QString moduleusername = CORBA::string_dup(list_composants[ind].moduleusername) ;
 
     //    MESSAGE ( " MODULE = " << modulename )
     //    MESSAGE ( " MODULE icon = " << iconfile )
@@ -295,10 +322,8 @@ myQueryClose( true )
          tr("INF_RESOURCES");
        //QMessageBox::warning( this, tr("WRN_WARNING"), errMsg, tr ("BUT_OK") );
       }
-
-    if ( !QString(list_composants[ind].modulename).isEmpty() )
-      myCombo->insertItem( strdup(list_composants[ind].moduleusername) );
-
+    if ( ( resDir || moduleusername == "Salome" ) && !modulename.isEmpty() ) // VSR: Force "Salome" component to appear in the combo box
+      myCombo->insertItem( moduleusername );
   }
 
   myCombo->adjustSize();
@@ -334,6 +359,7 @@ QAD_Desktop::~QAD_Desktop ()
   //NRI : SAL2214
   myNewViewPopup.clear();
   //NRI : SAL2214
+  myHelpContentsModulePopup.clear();
   myToolsPopup.clear();
   myPrefPopup.clear();
   myStdActions.clear();
@@ -342,8 +368,8 @@ QAD_Desktop::~QAD_Desktop ()
   myToolBarAction.clear();
   myApps.clear();
   delete resourceMgr;
-  if (myHelpWindow)
-    myHelpWindow->close();
+//NRI   if (myHelpWindow)
+//     myHelpWindow->close();
   resourceMgr = 0;
   QAD_Application::desktop = 0;
 }
@@ -364,7 +390,17 @@ const int IdSelectAll = 1004;
 */
 bool QAD_Desktop::eventFilter( QObject* o, QEvent* e )
 {
-  if ( e->type() == QEvent::ContextMenu ) {
+  if (e->type() == QEvent::Close && o == this )
+    myAboutToClose = true;
+  else if (e->type() == 2000   ) {
+    QMessageBox::information (this, tr ( "Help Information" ), tr ( "Can't run choosen browser.\nRunning default browser (Mozilla). "));
+    return TRUE;
+  }
+  else if (e->type() == 2001 ) {
+    QMessageBox::critical(this, tr ( "Help Error" ), tr ( "Can't run the default browser.") );
+    return TRUE;
+  }
+  else if ( e->type() == QEvent::ContextMenu ) {
     QContextMenuEvent* ce = (QContextMenuEvent*)e;
     if ( o->inherits("QRenameEdit") ) {
       return TRUE;
@@ -419,9 +455,27 @@ bool QAD_Desktop::eventFilter( QObject* o, QEvent* e )
       }
     }
   }
+  else if ( e->type() == SALOME_EVENT ) { 
+    SALOME_Event* aSE = (SALOME_Event*)((QCustomEvent*)e)->data();
+    processEvent(aSE);
+    ((QCustomEvent*)e)->setData( 0 );
+    return TRUE;
+  }
   return QMainWindow::eventFilter( o, e );
 }
 
+/*!
+    Dispatches <theEvent> to the target component GUI
+*/
+void QAD_Desktop::processEvent( SALOME_Event* theEvent )
+{
+  if(theEvent){
+    theEvent->Execute();
+    // Signal the calling thread that the event has been processed
+    theEvent->processed();
+  }
+}
+
 /*!
     Creates and initializes the standard file operations
     such as 'New/Open/Save/SaveAs/Close' and 'Help'.
@@ -557,9 +611,16 @@ void QAD_Desktop::createActions()
     exitAction->addTo( &myFilePopup );
     myStdActions.insert ( FileExitId, exitAction );
  
+    QAD_ASSERT( connect( &myFilePopup, SIGNAL(highlighted( int )), 
+                        this, SLOT(onFilePopupStatusText( int )) ));
+    
+
     /* 'Edit' actions : provided by application only */
     myEditPos = 0;
 
+    QAD_ASSERT( connect( &myEditPopup, SIGNAL(highlighted( int )), 
+                        this, SLOT(onEditPopupStatusText( int )) ));
+
     /* 'View' actions */
     /* toolbars popup menu */
     myViewPopup.insertItem( tr("MEN_DESK_VIEW_TOOLBARS"), &myToolBarsPopup );
@@ -601,6 +662,9 @@ void QAD_Desktop::createActions()
 
     myViewPos = myViewPopup.count();
 
+    QAD_ASSERT( connect( &myViewPopup, SIGNAL(highlighted( int )), 
+                        this, SLOT(onViewPopupStatusText( int )) ));
+
     /* Parse xml file */
     QAD_ResourceMgr* resMgr = QAD_Desktop::createResourceManager();
     if ( resMgr ) {
@@ -715,6 +779,8 @@ void QAD_Desktop::createActions()
     QAD_ASSERT(connect( myQAG, SIGNAL(selected(QActionP * )), this, SLOT(onDefaultViewer(QActionP *) )));
     //VRV: T2.5 - add default viewer
 
+    myPrefPopup.insertSeparator();
+
     QActionP* viewerTrihedronAction = new QActionP( "", tr("MEN_DESK_PREF_VIEWER_TRIHEDRON"), 0, this );
     QAD_ASSERT(connect( viewerTrihedronAction, SIGNAL(activated()), this, SLOT(onViewerTrihedron() )));
     viewerTrihedronAction->addTo( &myPrefPopup );
@@ -743,8 +809,21 @@ void QAD_Desktop::createActions()
     ASCIISaveAction->addTo( &myPrefPopup );
     myStdActions.insert( PrefASCIISave, ASCIISaveAction );
 
+    /* Undo level */
+    QActionP* UndoLevelAction = new QActionP( "", tr("MEN_DESK_PREF_UNDO_LEVEL"), 0, this );
+    QAD_ASSERT(connect( UndoLevelAction, SIGNAL(activated()), this, SLOT(onUndoLevel() )));
+    UndoLevelAction->addTo( &myPrefPopup );
+    myStdActions.insert( PrefUndoLevelId, UndoLevelAction );
+
     myPrefPopup.insertSeparator();
     
+    /* External Browser */
+    QActionP* externalBrowserAction = new QActionP( "", tr("MEN_DESK_PREF_EXTERNAL_BROWSER"), 0, this );
+    QAD_ASSERT(connect( externalBrowserAction, SIGNAL(activated()), this, SLOT(onExternalBrowser() )));
+    externalBrowserAction->addTo( &myPrefPopup );
+    myStdActions.insert( PrefExternalBrowserId, externalBrowserAction );
+        
+    myPrefPopup.insertSeparator();
     /* BrowserPopup */
     myPrefPopup.insertItem( tr("MEN_DESK_PREF_OBJECTBROWSER"), &myObjBrowserPopup );
     
@@ -791,7 +870,7 @@ void QAD_Desktop::createActions()
     QActionP* objectBrowserCHRONO_SORTAction = new QActionP( "", tr("MEN_DESK_PREF_OBJECTBROWSER_CHRONO_SORT"), 0, this, 0, true );
     QAD_ASSERT(connect( objectBrowserCHRONO_SORTAction, SIGNAL(activated()), this, SLOT(onObjectBrowser() )));
     objectBrowserCHRONO_SORTAction->setToggleAction(true);
-    QString showSORT = QAD_CONFIG->getSetting("ObjectBrowser:CHRONO_SORT");
+    QString showSORT = QAD_CONFIG->getSetting("ObjectBrowser:ChronologicalSort");
     
     if ( showSORT.compare( aTrueQString ) == 0 )
       objectBrowserCHRONO_SORTAction->setOn(true) ;
@@ -801,6 +880,34 @@ void QAD_Desktop::createActions()
     objectBrowserCHRONO_SORTAction->addTo( &myObjBrowserPopup );
     myStdActions.insert( PrefObjectBrowserCHRONO_SORTId, objectBrowserCHRONO_SORTAction ) ;
     
+    /* Show or don't Show UseCase browser */
+    QActionP* objectBrowserShowUseCaseAction = new QActionP( "", tr("MEN_DESK_PREF_OBJECTBROWSER_SHOW_USECASE"), 0, this, 0, true );
+    QAD_ASSERT(connect( objectBrowserShowUseCaseAction, SIGNAL(activated()), this, SLOT(onObjectBrowser() )));
+    objectBrowserShowUseCaseAction->setToggleAction(true);
+    QString showUseCase = QAD_CONFIG->getSetting("ObjectBrowser:ShowUseCaseBrowser");
+    
+    if ( showUseCase.compare( aTrueQString ) == 0 )
+      objectBrowserShowUseCaseAction->setOn(true) ;
+    else
+      objectBrowserShowUseCaseAction->setOn(false) ;
+    
+    objectBrowserShowUseCaseAction->addTo( &myObjBrowserPopup );
+    myStdActions.insert( PrefObjectBrowserShowUseCaseId, objectBrowserShowUseCaseAction ) ;
+
+    /* Resize or don't resize columns automatically */
+    QActionP* objectBrowserNoAutoSizeAction = new QActionP( "", tr("MEN_DESK_PREF_OBJECTBROWSER_NO_AUTOSIZE"), 0, this, 0, true );
+    QAD_ASSERT(connect( objectBrowserNoAutoSizeAction, SIGNAL(activated()), this, SLOT(onObjectBrowser() )));
+    objectBrowserNoAutoSizeAction->setToggleAction(true);
+    QString noAutoSize = QAD_CONFIG->getSetting("ObjectBrowser:NoAutoSizeColumns");
+    
+    if ( noAutoSize.compare( aTrueQString ) == 0 )
+      objectBrowserNoAutoSizeAction->setOn(true) ;
+    else
+      objectBrowserNoAutoSizeAction->setOn(false) ;
+    
+    objectBrowserNoAutoSizeAction->addTo( &myObjBrowserPopup );
+    myStdActions.insert( PrefObjectBrowserNoAutoSizeColumnsId, objectBrowserNoAutoSizeAction ) ;
+
     myPrefPopup.insertSeparator();
 
     QActionP* dirAction = new QActionP( "", tr("MEN_DESK_PREF_DIRICTORIES"), ALT+Key_D, this );
@@ -865,12 +972,70 @@ void QAD_Desktop::createActions()
     /* 'Help' actions
      */
     /* contents */
-    QActionP* helpContentsAction = new QActionP( "", tr("MEN_DESK_HELP_CONTENTS"), Key_F1, this );
-    helpContentsAction->setStatusTip ( tr("PRP_DESK_HELP_CONTENTS") );
-    QAD_ASSERT(connect( helpContentsAction, SIGNAL(activated()),
-                       this, SLOT( onHelpContents() )));
-    helpContentsAction->addTo( &myHelpPopup );
-    myStdActions.insert( HelpContentsId , helpContentsAction );
+    // MZN : Commented
+    // QActionP* helpContentsAction = new QActionP( "", tr("MEN_DESK_HELP_CONTENTS"), Key_F1, this );
+    // helpContentsAction->setStatusTip ( tr("PRP_DESK_HELP_CONTENTS") );
+//     QAD_ASSERT(connect( helpContentsAction, SIGNAL(activated()),
+//                     this, SLOT( onHelpContents() )));
+//     helpContentsAction->addTo( &myHelpPopup );
+//     myStdActions.insert( HelpContentsId , helpContentsAction );
+                               
+//     id = myHelpPopup.insertSeparator();
+                                                  
+    /* GUI contents */
+    myHelpPopup.insertItem( tr("MEN_DESK_HELP_MODULECONTENTS"), &myHelpContentsModulePopup, HelpContentsModuleId);
+    bool toEnable = false;
+    
+    CORBA::Object_var objVarN = myNameService->Resolve("/Kernel/ModulCatalog");
+    myCatalogue  = SALOME_ModuleCatalog::ModuleCatalog::_narrow(objVarN);
+    
+    SALOME_ModuleCatalog::ListOfIAPP_Affich_var list_composants =
+      myCatalogue->GetComponentIconeList();
+      
+    for (unsigned int ind = 0; ind < list_composants->length(); ind++) {
+      QString aModuleName = CORBA::string_dup(list_composants[ind].modulename) ;
+      QString dir;
+      if (dir = getenv( aModuleName + "_ROOT_DIR")) {
+       dir = QAD_Tools::addSlash( QAD_Tools::addSlash(dir) + "doc/salome/" );
+       QString aFileName = aModuleName + "_index.html"; 
+       if ( QFileInfo( dir + aFileName ).exists() ) {
+         QString aModuleUserName = CORBA::string_dup(list_composants[ind].moduleusername) ;
+         if ( aModuleUserName == "Salome" )  aModuleUserName = "Kernel" ;
+         QActionP* moduleHelpAction = new QActionP( "", aModuleUserName + " Help" , 0, this, aModuleName);
+         QAD_ASSERT(connect( moduleHelpAction, SIGNAL(activated()), this, SLOT(onHelpContentsModule() )));
+         moduleHelpAction->addTo( &myHelpContentsModulePopup );
+         if (!toEnable) toEnable = true;
+       }
+      }
+    }
+    
+    myHelpContentsModulePopup.setEnabled(toEnable);
+              
+   // NRI : Temporary commented
+
+//     QActionP* helpContentsActionGUI = new QActionP( "", tr("MEN_DESK_HELP_GUICONTENTS"), 0, this );
+//     helpContentsActionGUI->setStatusTip ( tr("PRP_DESK_HELP_GUICONTENTS") );
+//     QAD_ASSERT(connect( helpContentsActionGUI, SIGNAL(activated()),
+//                     this, SLOT( onHelpContentsGUI() )));
+//     helpContentsActionGUI->addTo( &myHelpPopup );
+//     myStdActions.insert( HelpContentsId , helpContentsActionGUI );
+
+    
+    /* TUI contents */
+    /*
+    QActionP* helpContentsActionTUI = new QActionP( "", tr("MEN_DESK_HELP_TUICONTENTS"), 0, this );
+    helpContentsActionTUI->setStatusTip ( tr("PRP_DESK_HELP_TUICONTENTS") );
+    QAD_ASSERT(connect( helpContentsActionTUI, SIGNAL(activated()),
+                       this, SLOT( onHelpContentsTUI() )));
+    helpContentsActionTUI->addTo( &myHelpPopup );
+    myStdActions.insert( HelpContentsId , helpContentsActionTUI );                                                
+    */
+
+
+    // Provide status tip for Module help menu item
+    QAD_ASSERT( connect( &myHelpPopup, SIGNAL(highlighted( int )), this,
+                        SLOT(onHelpModulePopupStatusText( int )) ));
+       
 
     /* search */
 //    QActionP* helpSearchAction = new QActionP( "", tr("MEN_DESK_HELP_SEARCH"), 0, this );
@@ -1001,6 +1166,7 @@ void QAD_Desktop::updateCaption( UpdateCommand cmd )
     else
     {  /* default icon and title */
        setIcon( myDefaultIcon );
+       qApp->processEvents();
        setCaption( myDefaultTitle );
     }
 }
@@ -1128,6 +1294,18 @@ QAD_Study* QAD_Desktop::findStudy( SALOMEDS::Study_ptr theStudy )
   return 0;
 }
 
+/*!
+  Gets value of max undo level for SALOMEDS::Study's from preferences
+*/
+int QAD_Desktop::getUndoLevel()
+{
+  static int MAX_UNDO = 10;
+  int anUndoLevel = MAX_UNDO;
+  QString aLevel = QAD_CONFIG->getSetting("Desktop:UndoLevel");
+  if(!aLevel.isEmpty()) anUndoLevel = aLevel.toInt();
+  return anUndoLevel;
+}
+
 /*!
     Returns current active application
 */
@@ -1181,48 +1359,48 @@ QString QAD_Desktop::getComponentUserName(const char *componentName)
   return "";
 }
 
-/*!
-  gets application Help Window (and creates if necessary)
-*/
-QAD_HelpWindow* QAD_Desktop::getHelpWindow()
-{
-  if (!myHelpWindow) {
-    myHelpWindow = new QAD_HelpWindow();  
+// /*!
+//   gets application Help Window (and creates if necessary)
+// */
+// QAD_HelpWindow* QAD_Desktop::getHelpWindow()
+// {
+//   if (!myHelpWindow) {
+//     myHelpWindow = new QAD_HelpWindow();  
     
-    QMap<QString,QString>::Iterator it;
-    for( it = mapComponentName.begin(); it != mapComponentName.end(); ++it ) {
-      QCString dir;
-      QString root;
+//     QMap<QString,QString>::Iterator it;
+//     for( it = mapComponentName.begin(); it != mapComponentName.end(); ++it ) {
+//       QCString dir;
+//       QString root;
       
-      // look for index.html and set homeDir
-      // 1. $(MODULE_ROOT_DIR)/doc/index.html
-      // 2. $(MODULE_ROOT_DIR)/doc/html/index.html
-      // 3. $(MODULE_ROOT_DIR)/doc/html/html/index.html
-
-      if (dir = getenv( QString( it.data() + "_ROOT_DIR")) ) {
-       root = QAD_Tools::addSlash( QAD_Tools::addSlash(dir) + QAD_Tools::addSlash("share")  + QAD_Tools::addSlash("salome")  + "doc" );
-       if ( QFileInfo( root + "index.html" ).exists() ) {
-         helpContext( root + "index.html", "" );
-       }
-       else {
-         root = QAD_Tools::addSlash( root + "html" );
-         if ( QFileInfo( root + "index.html" ).exists() ) {
-           helpContext( root + "index.html", "" );
-         }
-         else {
-           root = QAD_Tools::addSlash( root + "html" );
-           if ( QFileInfo( root + "index.html" ).exists() ) {
-             helpContext( root + "index.html", "" );
-           }
-         }
-       }
-      }
-    }
+//       // look for index.html and set homeDir
+//       // 1. $(MODULE_ROOT_DIR)/doc/index.html
+//       // 2. $(MODULE_ROOT_DIR)/doc/html/index.html
+//       // 3. $(MODULE_ROOT_DIR)/doc/html/html/index.html
+
+//       if (dir = getenv( QString( it.data() + "_ROOT_DIR")) ) {
+//     root = QAD_Tools::addSlash( QAD_Tools::addSlash(dir) + QAD_Tools::addSlash("share")  + QAD_Tools::addSlash("salome")  + "doc" );
+//     if ( QFileInfo( root + "index.html" ).exists() ) {
+//       helpContext( root + "index.html", "" );
+//     }
+//     else {
+//       root = QAD_Tools::addSlash( root + "html" );
+//       if ( QFileInfo( root + "index.html" ).exists() ) {
+//         helpContext( root + "index.html", "" );
+//       }
+//       else {
+//         root = QAD_Tools::addSlash( root + "html" );
+//         if ( QFileInfo( root + "index.html" ).exists() ) {
+//           helpContext( root + "index.html", "" );
+//         }
+//       }
+//     }
+//       }
+//     }
     
-    connect(myHelpWindow, SIGNAL(helpWindowClosed()), this, SLOT(onHelpWindowClosed()));
-  }
-  return myHelpWindow;
-}
+//     connect(myHelpWindow, SIGNAL(helpWindowClosed()), this, SLOT(onHelpWindowClosed()));
+//   }
+//   return myHelpWindow;
+// }
 
 /*!
     Called when desktop is closing
@@ -1237,36 +1415,44 @@ void QAD_Desktop::closeEvent ( QCloseEvent* e )
                                      QAD_NO, QAD_NO ) == QAD_YES;
   }
 
-  if ( doClose ) { 
-    for ( QAD_Application* app = myApps.first(); app; app = myApps.next() ) { 
-      QList<QAD_Study>& studies = app->getStudies();
-      for(QAD_Study* study = studies.first(); study != 0; study = studies.next()) {
-       if(myQueryClose && study->getStudyDocument()->IsModified()) {
-         SALOMEGUI_CloseDlg aDlg( this );
-         switch ( aDlg.exec() ) {
-         case 1:
-           if ( !onSaveStudy( study ) ) {
-             putInfo( tr("INF_CANCELLED") );
-             e->ignore();
-             return;
-           }
-           break;
-         case 2:
-         case 3:
-           break;
-         case 0:
-         default: 
-           e->ignore();
+  for ( QAD_Application* app = myApps.first(); doClose && app; app = myApps.next() ) { 
+    QList<QAD_Study>& studies = app->getStudies();
+    for(QAD_Study* study = studies.first(); doClose && study != 0; study = studies.next()) {
+      if(myQueryClose && study->getStudyDocument()->IsModified()) {
+       SALOMEGUI_CloseDlg aDlg( this );
+       switch ( aDlg.exec() ) {
+       case 1:
+         if ( !onSaveStudy( study ) ) {
            putInfo( tr("INF_CANCELLED") );
-           return;
+           doClose = false;
          }
+         break;
+       case 2:
+       case 3:
+         break;
+       case 0:
+       default: 
+         doClose = false;
+         putInfo( tr("INF_CANCELLED") );
        }
-       study->close();
       }
+      if ( doClose )
+       study->close();
     }
   }
+
   myQueryClose = true;
-  doClose ? e->accept() : e->ignore();
+
+  if ( !doClose ) {
+    myAboutToClose = false;
+    // onActiveStudyChanged() is normally caused by QWorkspace::eventFilter(), 
+    // but this call was blocked by myAboutToClose == true, so now we should do it manually
+    onActiveStudyChanged(); 
+
+    e->ignore();
+  }
+  else
+    e->accept();
 }
 
 /*!
@@ -1395,8 +1581,8 @@ void QAD_Desktop::onLoadStudy()
          //don't ask user to remove study permanently
          if (app->getStudyByName ( name ) != NULL)
            onCloseStudy ( app->getStudyByName ( name ), false );
-         else if (app->getStudyByName ( QAD_Tools::getFileNameFromPath( name, false )) != NULL)
-           onCloseStudy ( app->getStudyByName ( QAD_Tools::getFileNameFromPath( name, false )), false );
+         else if (app->getStudyByName ( QAD_Tools::getFileNameFromPath( name, true )) != NULL)
+           onCloseStudy ( app->getStudyByName ( QAD_Tools::getFileNameFromPath( name, true )), false );
        }
       appFound = true;
       
@@ -1484,8 +1670,7 @@ void QAD_Desktop::onOpenStudy()
     SALOMEDS::ListOfOpenStudies_var List = myStudyMgr->GetOpenStudies();
     for (unsigned int ind = 0; ind < List->length();ind++) {
       QString NameExistingStudy(List[ind]);
-      QString NameOpeningStudy = QAD_Tools::getFileNameFromPath( name, false );
-     
+      QString NameOpeningStudy = QAD_Tools::getFileNameFromPath( name, true );
       if ( NameExistingStudy.compare( NameOpeningStudy ) == 0 ) {
        if ( QAD_MessageBox::warn2 ( this, tr("WRN_WARNING"),
                                     tr("QUE_DOC_ALREADYEXIST").arg( name ),
@@ -1530,8 +1715,8 @@ void QAD_Desktop::onOpenStudy()
                //don't ask user to remove study permanently
                if (app->getStudyByName ( name ) != NULL)
                  onCloseStudy ( app->getStudyByName ( name ), false );
-               else if (app->getStudyByName ( QAD_Tools::getFileNameFromPath( name, false )) != NULL)
-                 onCloseStudy ( app->getStudyByName ( QAD_Tools::getFileNameFromPath( name, false )), false );
+               else if (app->getStudyByName ( QAD_Tools::getFileNameFromPath( name, true )) != NULL)
+                 onCloseStudy ( app->getStudyByName ( QAD_Tools::getFileNameFromPath( name, true )), false );
            }
            appFound = true;
 
@@ -1542,12 +1727,7 @@ void QAD_Desktop::onOpenStudy()
                                      tr("ERR_ERROR"),
                                      tr("ERR_DOC_CANTOPEN") + "\n" + name,
                                      tr("BUT_OK") );
-           } else if (myActiveComp != "") {
-             QApplication::setOverrideCursor( Qt::waitCursor );
-             loadComponentData(mapComponentName[myActiveComp]);
-             openStudy->updateObjBrowser(true);
-             QApplication::restoreOverrideCursor();
-           }
+           } 
            break;
        }
     }
@@ -1564,6 +1744,13 @@ void QAD_Desktop::onOpenStudy()
 
 bool QAD_Desktop::loadComponentData( const QString& compName )
 {
+  QAD_WaitCursor wc;
+
+  if ( compName.isEmpty() ) {
+    MESSAGE("loadComponentData(): empty component name passed!")
+    return false;
+  }
+
   // Open component's data in active study if any
   MESSAGE("loadComponentData(): Opening " << compName << " component data ")
   if (!myActiveStudy) {
@@ -1584,33 +1771,36 @@ bool QAD_Desktop::loadComponentData( const QString& compName )
       comp = getEngine( "FactoryServerPy", compName);
   }
 
+  if ( CORBA::is_nil( comp ) ) {
+    MESSAGE("loadComponentData(): Engine is null");
+    return false;
+  }  
+
   SALOMEDS::Study_var aStudy = myActiveStudy->getStudyDocument();
   SALOMEDS::SComponent_var SCO = SALOMEDS::SComponent::_narrow(aStudy->FindObject( getComponentUserName(compName) ));
           
   if (!SCO->_is_nil()) {
-    if (!CORBA::is_nil(comp)) {
-      SALOMEDS::Driver_var   driver = SALOMEDS::Driver::_narrow(comp);
-      if (!CORBA::is_nil(driver)) {
-       SALOMEDS::StudyBuilder_var  B = aStudy->NewBuilder();
-       if (!CORBA::is_nil(B)) {
-         QAD_Operation* op = new QAD_Operation( myActiveStudy );
-         op->start();
+    SALOMEDS::Driver_var   driver = SALOMEDS::Driver::_narrow(comp);
+    if (!CORBA::is_nil(driver)) {
+      SALOMEDS::StudyBuilder_var  B = aStudy->NewBuilder();
+      if (!CORBA::is_nil(B)) {
+       try {
          B->LoadWith(SCO,driver);
-         op->finish();
-       } else {
+       }
+       catch( const SALOME::SALOME_Exception& ) {
+         // Oops, something went wrong while loading -> return an error
          return false;
        }
-      } else {
-       MESSAGE("loadComponentData(): Driver is null");
-       return false;
-      }
+      } 
     } else {
-      MESSAGE("loadComponentData(): Engine is null");
+      MESSAGE("loadComponentData(): Driver is null");
+      // Incorrect! All components should inherit SALOMEDS::Driver
       return false;
     }
   } else {
     MESSAGE("loadComponentData(): SComponent is null");
-    return false;
+    // Don't return false here, for there might be no data 
+    // for a given component in the study yet
   }
 
   return true;
@@ -1699,15 +1889,7 @@ bool QAD_Desktop::onSaveAsStudy( QAD_Study* study )
 */
 bool QAD_Desktop::onCloseStudy()
 {
-  bool close = this->onCloseStudy ( myActiveStudy, true );
-  if ( close && !myXmlHandler->myIdList.IsEmpty() ) {
-    clearMenus();
-    myActiveComp = "";
-    myCombo->setCurrentItem (0);
-    for ( QToolButton* aButton=myComponentButton.first(); aButton; aButton=myComponentButton.next() ) {
-      aButton->setOn(false);
-    }
-  }
+  bool close = this->onCloseStudy ( getActiveStudy(), true );
   return close;
 }
 
@@ -1758,6 +1940,7 @@ bool QAD_Desktop::onCloseStudy( QAD_Study* study, bool ask )
   /* close active component */
   if (!myXmlHandler->myIdList.IsEmpty())
     {
+      deactivateComponent();
       clearMenus();
       myActiveComp="";
       myCombo->setCurrentItem (0);
@@ -1807,13 +1990,13 @@ void QAD_Desktop::onCascade()
       it.current()->resize((int)(0.8*w), (int)(0.8*h));
 }
 
-/*!
-  called when help window closed
-*/
-void QAD_Desktop::onHelpWindowClosed()
-{
-  myHelpWindow = 0;
-}
+// /*!
+//   called when help window closed
+// */
+// void QAD_Desktop::onHelpWindowClosed()
+// {
+//   myHelpWindow = 0;
+// }
 
 /*!
     Called when 'view status bar' option
@@ -1861,10 +2044,10 @@ void QAD_Desktop::onSelectionMode()
 {
   const QActionP* obj = (QActionP*) sender();
   
-  int SelectionMode = 4;
+  Selection_Mode SelectionMode = ActorSelection;
 
   if ( obj == myStdActions.at(SelectionActorId) ) {
-    SelectionMode = 4;
+    SelectionMode = ActorSelection;
     if ( obj->isOn() ) {
       myStdActions.at(SelectionCellId)->setOn(false);
       myStdActions.at(SelectionEdgeId)->setOn(false);
@@ -1873,7 +2056,7 @@ void QAD_Desktop::onSelectionMode()
       myStdActions.at(SelectionActorId)->setOn(true);
 
   } else if ( obj == myStdActions.at(SelectionCellId) ) {
-    SelectionMode = 3
+    SelectionMode = CellSelection
     if ( obj->isOn() ) {
       myStdActions.at(SelectionActorId)->setOn(false);
       myStdActions.at(SelectionEdgeId)->setOn(false);
@@ -1882,7 +2065,7 @@ void QAD_Desktop::onSelectionMode()
       myStdActions.at(SelectionActorId)->setOn(true);
       
   } else if ( obj == myStdActions.at(SelectionEdgeId) ) {
-    SelectionMode = 2;    
+    SelectionMode = EdgeOfCellSelection;    
     if ( obj->isOn() ) {
       myStdActions.at(SelectionActorId)->setOn(false);
       myStdActions.at(SelectionCellId)->setOn(false);
@@ -1891,7 +2074,7 @@ void QAD_Desktop::onSelectionMode()
       myStdActions.at(SelectionActorId)->setOn(true);
       
   } else if ( obj == myStdActions.at(SelectionPointId) ) {
-    SelectionMode = 1;
+    SelectionMode = NodeSelection;
     if ( obj->isOn() ) {
       myStdActions.at(SelectionEdgeId)->setOn(false);
       myStdActions.at(SelectionCellId)->setOn(false);
@@ -1910,10 +2093,10 @@ void QAD_Desktop::onSelectionMode()
 /*!
     Called on 'View\Selection Mode'
 */
-void QAD_Desktop::SetSelectionMode(int mode, bool activeCompOnly)
+void QAD_Desktop::SetSelectionMode(Selection_Mode mode, bool activeCompOnly)
 {
   switch (mode) {
-  case 1:
+  case NodeSelection:
     {
       myStdActions.at(SelectionEdgeId)->setOn(false);
       myStdActions.at(SelectionCellId)->setOn(false);
@@ -1921,7 +2104,7 @@ void QAD_Desktop::SetSelectionMode(int mode, bool activeCompOnly)
       myStdActions.at(SelectionPointId)->setOn(true);
       break;
     }
-  case 2:
+  case EdgeOfCellSelection:
     {
       myStdActions.at(SelectionActorId)->setOn(false);
       myStdActions.at(SelectionCellId)->setOn(false);
@@ -1929,15 +2112,18 @@ void QAD_Desktop::SetSelectionMode(int mode, bool activeCompOnly)
       myStdActions.at(SelectionEdgeId)->setOn(true);
       break;
     }
-  case 3:
-    {
+  case CellSelection:
+  case EdgeSelection:
+  case FaceSelection:
+  case VolumeSelection:
+   {
       myStdActions.at(SelectionActorId)->setOn(false);
       myStdActions.at(SelectionEdgeId)->setOn(false);
       myStdActions.at(SelectionPointId)->setOn(false);
       myStdActions.at(SelectionCellId)->setOn(true);
       break;
     }
-  case 4:
+  case ActorSelection:
     {
       myStdActions.at(SelectionCellId)->setOn(false);
       myStdActions.at(SelectionEdgeId)->setOn(false);
@@ -1984,27 +2170,167 @@ void QAD_Desktop::onNewWindow3d()
   //NRI : SAL2214
 }
 
+// Helps to execute command
+class RunBrowser: public QThread {
+public:
+  
+  RunBrowser(QString theApp, QString theParams, QString theHelpFile, QString theContext=NULL): 
+    myApp(theApp), myParams(theParams), myHelpFile("file:" + theHelpFile + theContext), myStatus(0) {};
+  virtual void run()
+  {
+    QString aCommand;
+    
+    if ( !myApp.isEmpty())
+      {
+       aCommand.sprintf("%s %s %s",myApp.latin1(),myParams.latin1(),myHelpFile.latin1());
+       myStatus = system(aCommand);
+       if(myStatus != 0)
+         {
+           QCustomEvent* ce2000 = new QCustomEvent (2000);
+           postEvent (qApp, ce2000);
+         }
+      }
+    
+    if( myStatus != 0 || myApp.isEmpty())
+      {
+       myParams = "";
+       aCommand.sprintf("%s %s %s", QString(DEFAULT_BROWSER).latin1(),myParams.latin1(), myHelpFile.latin1()); 
+       myStatus = system(aCommand);
+       if(myStatus != 0)
+         {
+           QCustomEvent* ce2001 = new QCustomEvent (2001);
+           postEvent (qApp, ce2001);
+         }
+      }
+  }
+
+private:
+  QString myApp;
+  QString myParams;
+  QString myHelpFile;
+  int myStatus;
+  
+};
+
+// Provide status tip for GUI help menu item
+
+void QAD_Desktop::onHelpModulePopupStatusText(int id)
+{
+  int Id = myHelpPopup.idAt( 0 ); // HelpContentsModuleId
+  //  MESSAGE ( "myHelpContentsModulePopup : " << id << "-" << Id)
+  if (id == Id)
+    putInfo("Shows the help contents of each module");
+}
+
 /*!
     Called on 'help\contents'
 */
 void QAD_Desktop::onHelpContents()
-{
-  if (myActiveApp)
-    myActiveApp->helpContents();
-  else
-    helpContents();
+{  if (myActiveComp == "")
+    myActiveComp = getComponentUserName( "KERNEL" ); //NRI "Salome";
+
+  QCString dir;
+  QString root;
+  QString homeDir;
+  if (dir = getenv( getComponentName( myActiveComp ) + "_ROOT_DIR")) {
+    root = QAD_Tools::addSlash( QAD_Tools::addSlash(dir) + QAD_Tools::addSlash("share")  + QAD_Tools::addSlash("salome")  + QAD_Tools::addSlash("doc") + "html" );
+    if ( QFileInfo( root + "index.html" ).exists() ) {
+      homeDir = root;
+    } else {
+      QMessageBox::warning( this, tr("WRN_WARNING"), 
+                           QString( "%1index.html doesn't exist." ).arg(root), tr ("BUT_OK") );
+      return;
+    }
+  }
+
+  QString helpFile = QFileInfo( homeDir + "index.html" ).absFilePath();   
+  QString anApp = QAD_CONFIG->getSetting("ExternalBrowser:Application");
+  QString aParams = QAD_CONFIG->getSetting("ExternalBrowser:Parameters");
+   
+  RunBrowser* rs = new RunBrowser(anApp, aParams, helpFile);
+  rs->start();
 }
 
 /*!
-    Called on 'help\search'
+    Called on 'Module Help Reference'
 */
-void QAD_Desktop::onHelpSearch()
+void QAD_Desktop::onHelpContentsModule()
+{ 
+  const QActionP* obj = (QActionP*) sender();
+  
+  QString aComponentName = obj->name();
+  QString aFileName = aComponentName + "_index.html";
+
+  QCString dir;
+  QString root;
+  QString homeDir;
+  if (dir = getenv( aComponentName + "_ROOT_DIR")) {
+    root = QAD_Tools::addSlash( QAD_Tools::addSlash(dir) +  QAD_Tools::addSlash("doc") +  QAD_Tools::addSlash("salome") );
+    if ( QFileInfo( root + aFileName ).exists() ) {
+      homeDir = root;
+    } else {
+      QMessageBox::warning( this, tr("WRN_WARNING"), 
+                           QString( "%1"+ aFileName + " doesn't exist." ).arg(root), tr ("BUT_OK") );
+      return;
+    }
+  }
+
+  QString helpFile = QFileInfo( homeDir + aFileName ).absFilePath();   
+  QString anApp = QAD_CONFIG->getSetting("ExternalBrowser:Application");
+  QString aParams = QAD_CONFIG->getSetting("ExternalBrowser:Parameters");
+   
+  RunBrowser* rs = new RunBrowser(anApp, aParams, helpFile);
+  rs->start();
+}
+
+/*!
+    Called on 'help\TUI Reference'
+*/
+
+/* Commented
+void QAD_Desktop::onHelpContentsTUI()
 {
-  if (myActiveApp)
-    myActiveApp->helpSearch();
-  else
-    helpSearch();
+  if (myActiveComp == "")
+    myActiveComp = getComponentUserName( "KERNEL" ); //NRI "Salome";
+
+  QCString dir;
+  QString root;
+  QString homeDir;
+  if (dir = getenv( getComponentName( myActiveComp ) + "_ROOT_DIR")) {
+    root = QAD_Tools::addSlash( QAD_Tools::addSlash(dir) + QAD_Tools::addSlash("doc") + "html" );
+    if ( QFileInfo( root + "index.html" ).exists() ) {
+      homeDir = root;
+    } else if (QFileInfo( root + "html/index.html" ).exists())
+      homeDir = root + QAD_Tools::addSlash("html");
+    else {
+      QMessageBox::warning( this, tr("WRN_WARNING"), 
+                           QString( "%1index.html doesn't exist." ).arg(root), tr ("BUT_OK") );
+      return;
+    }
+  }
+  
+  QString helpFile = QFileInfo( homeDir + "index.html" ).absFilePath(); 
+  
+  QString anApp = QAD_CONFIG->getSetting("ExternalBrowser:Application");
+  QString aParams = QAD_CONFIG->getSetting("ExternalBrowser:Parameters");
+   
+  RunBrowser* rs = new RunBrowser(anApp, aParams, helpFile);
+  rs->start();
 }
+*/
+
+
+// /*!
+//     Called on 'help\search'
+// */
+// void QAD_Desktop::onHelpSearch()
+// {
+//   if (myActiveApp)
+//     myActiveApp->helpSearch();
+//   else
+//     helpSearch();
+// }
 
 /*!
     Called on 'help\about'
@@ -2133,10 +2459,10 @@ void QAD_Desktop::onWindowPopupAboutToShow()
 */
 void QAD_Desktop::onWindowsPopupStatusText( int id )
 {
-    int cascadeId = myWindowPopup.idAt( 0 );
-    int tileId = myWindowPopup.idAt( 1 );
+    int cascadeId = myWindowPopup.idAt( 1 );
+    int tileId = myWindowPopup.idAt( 2 );
     if ( id == cascadeId || id == tileId )
-       return;
+      return;
     putInfo( tr("PRP_DESK_WINDOW_ACTIVATE") );
 }
 
@@ -2241,7 +2567,9 @@ void QAD_Desktop::onOpenWith()
     if (SCO->FindAttribute(anAttr, "AttributeName")) {
       aName = SALOMEDS::AttributeName::_narrow(anAttr);
       name = aName->Value();
-      SALOME_ModuleCatalog::Acomponent_var Comp = myCatalogue->GetComponent( mapComponentName[name] );
+      if ( getComponentName( name ).isEmpty() )
+       return;
+      SALOME_ModuleCatalog::Acomponent_var Comp = myCatalogue->GetComponent( getComponentName(name) );
       if ( !Comp->_is_nil() ) {
        
        SALOME_ModuleCatalog::ListOfComponents_var list_type_composants =
@@ -2252,7 +2580,9 @@ void QAD_Desktop::onOpenWith()
        } else if ( list_type_composants->length() > 1 ) {
          SALOMEGUI_OpenWith* aDlg = new SALOMEGUI_OpenWith( this );
          for (unsigned int ind = 0; ind < list_type_composants->length();ind++) {
-           aDlg->addComponent( strdup(list_type_composants[ind]) );
+           QString compusername = getComponentUserName( (char*)list_type_composants[ind] );
+           if ( !compusername.isEmpty() )
+             aDlg->addComponent( compusername );
          }
          
          int retVal = aDlg->exec();
@@ -2292,28 +2622,16 @@ void QAD_Desktop::onOpenWith()
   QApplication::restoreOverrideCursor();
 }
 
-typedef bool OneDim1(QAD_Desktop*);
-typedef bool OneDim2(QAD_Desktop*, char*);
 
 /*!
   Called to define settings of component.
 */
 void QAD_Desktop::setSettings()
 {
-  if (!myActiveComp.isEmpty()) {
-    OSD_Function osdF = mySharedLibrary.DlSymb("SetSettings");
-    if ( osdF != NULL )
-      if (_islibso)
-       {
-         OneDim1 (*f1) = (bool (*) (QAD_Desktop*)) osdF;
-         (*f1)(this);
-       }
-      else
-       {
-         QString Component =mapComponentName[myActiveComp];
-         OneDim2 (*f1) = (bool (*) (QAD_Desktop*, char*)) osdF;
-         (*f1)(this, (char*)Component.latin1());
-       }
+  SALOMEGUI* anActiveGUI = getActiveGUI();
+  if ( anActiveGUI ) {
+    QString Component = mapComponentName[myActiveComp];
+    anActiveGUI->SetSettings( this, (char*)Component.latin1() );
   }
 }
 
@@ -2322,6 +2640,11 @@ void QAD_Desktop::setSettings()
 */
 bool QAD_Desktop::loadComponent(QString Component)
 {
+  if ( Component.isEmpty() ) {
+    MESSAGE("loadComponent(): empty component name passed!")
+    return false;
+  }
+
   QAD_WaitCursor wc;
   QString resDir("/");  //NRI : Pb under Windows
 
@@ -2366,6 +2689,14 @@ bool QAD_Desktop::loadComponent(QString Component)
   QXmlSimpleReader reader;
   reader.setContentHandler( myXmlHandler );
   reader.setErrorHandler( myXmlHandler );
+
+  bool IsMaxActStudy = myActiveStudy->getActiveStudyFrame()->isMaximized();
+  if (IsMaxActStudy) {
+    QString aSourceData = source.data();
+    aSourceData = changeXmlInputSourceData( aSourceData, Component );
+    source.setData(aSourceData);
+  }
+
   bool ok = reader.parse( source );
   file.close();
   if ( !ok ) {
@@ -2385,95 +2716,6 @@ bool QAD_Desktop::loadComponent(QString Component)
   int nbToolbars = 0;
   if (myActiveMenus)
     nbToolbars = myActiveMenus->getToolBarList().count();
-  /* Open Shared Library */
-  mySharedLibrary = OSD_SharedLibrary();
-  _islibso = false;
-
-  QString ComponentLib;
-  QCString libs;
-  QFileInfo fileInfo ;
-  QString fileString ;
-  QString dir;
-
-  if ( libs = getenv("LD_LIBRARY_PATH")) {
-    //    MESSAGE ( " LD_LIBRARY_PATH : " << libs );
-    QStringList dirList = QStringList::split( SEPARATOR, libs, false ); // skip empty entries
-    for ( int i = dirList.count()-1; i >= 0; i-- ) {
-      dir = dirList[ i ];
-#ifdef WNT
-      fileString = QAD_Tools::addSlash( dir ) + "lib" + Component + "GUI.dll" ;
-#else
-      fileString = QAD_Tools::addSlash( dir ) + "lib" + Component + "GUI.so" ;
-#endif
-    
-      fileInfo.setFile(fileString) ;
-      if (fileInfo.exists()) {
-       //      MESSAGE ( " GUI library = " << fileString );
-       ComponentLib = fileInfo.fileName() ;
-       _islibso = true;
-       break;
-      }
-    }
-  }
-
-  if (!_islibso) // component GUI could be in PyQt, use generic library
-    {
-      MESSAGE("GUI library not found, trying generic library for PyQt GUI");
-      bool found = false;
-      if (dir = getenv("KERNEL_ROOT_DIR"))
-       {
-         dir = QAD_Tools::addSlash(dir) ;
-         dir = dir + "lib" ;
-         dir = QAD_Tools::addSlash(dir) ;
-         dir = dir + "salome" ;
-         dir = QAD_Tools::addSlash(dir) ;
-#ifdef WNT
-         dir = dir + "libSalomePyQtcmodule.dll" ;
-#else
-         dir = dir + "libSalomePyQtcmodule.so" ;
-#endif
-         MESSAGE ( " GUI library = " << dir );
-         fileInfo.setFile(dir) ;
-         if (fileInfo.exists())
-           {
-             ComponentLib = fileInfo.fileName() ;
-             found = true;
-           }
-       }
-      if ( !found )
-       {
-         QMessageBox::critical( this,
-                                tr("ERR_ERROR"),
-                                tr("ERR_LIBGUI" ).arg(Component) );
-         return false;
-       }
-    }
-
-  mySharedLibrary.SetName(TCollection_AsciiString((char*)ComponentLib.latin1()).ToCString());
-  ok = mySharedLibrary.DlOpen(OSD_RTLD_LAZY);
-  if (!ok) {
-    wc.stop();
-    QMessageBox::critical( this,
-                          tr("ERR_ERROR"),
-                          tr( mySharedLibrary.DlError() ) );
-    return false;
-  }
-
-  /* SETTINGS */
-  OSD_Function osdF = mySharedLibrary.DlSymb("SetSettings");
-  if ( osdF != NULL )
-    if (_islibso)
-      {
-       OneDim1 (*f1) = (bool (*) (QAD_Desktop*)) osdF;
-       (*f1)(this);
-      }
-    else
-      {
-       OneDim2 (*f1) = (bool (*) (QAD_Desktop*, char*)) osdF;
-       (*f1)(this, (char*)Component.latin1());
-      }
-
-  
 
   /* COMPONENT INTERFACE */
   SALOME_ModuleCatalog::Acomponent_ptr aComponent =
@@ -2535,6 +2777,120 @@ bool QAD_Desktop::loadComponent(QString Component)
   return true;
 }
 
+QString QAD_Desktop::changeXmlInputSourceData(QString theData, QString theComponent) 
+{
+  //  MESSAGE ( " changeXmlInputSourceData : " << theComponent.latin1() )
+  if ( theComponent=="SUPERV" ) {
+    //Supervision main menu item
+    int aItemId = 300;
+    int aPosId = 3;
+    QString aStrOld = createString( aItemId, aPosId );
+    QString aStrNew = createString( aItemId, aPosId+1 );
+    theData = theData.replace( QRegExp(aStrOld), aStrNew );
+  }
+  
+  if ( theComponent == "VISU" ) {
+    //Visualization main menu item
+    int aItemId = 401;
+    int aPosId = 3;
+    QString aStrOld = createString( aItemId, aPosId );
+    QString aStrNew = createString( aItemId, aPosId+1 );
+    theData = theData.replace( QRegExp(aStrOld), aStrNew );
+
+    //Selection main menu item
+    aItemId = 41;
+    aPosId = 4;
+    aStrOld = createString( aItemId, aPosId );
+    aStrNew = createString( aItemId, aPosId+1 );
+    theData = theData.replace( QRegExp(aStrOld), aStrNew );
+        
+    //Representation main menu item
+    aItemId = 42;
+    aPosId = 5;
+    aStrOld = createString( aItemId, aPosId );
+    aStrNew = createString( aItemId, aPosId+1 );
+    theData = theData.replace( QRegExp(aStrOld), aStrNew );
+  }
+
+  if ( theComponent == "SMESH" ) {
+    //Hypotheses main menu item
+    int aItemId = 50;
+    int aPosId = 3;
+    QString aStrOld = createString( aItemId, aPosId );
+    QString aStrNew = createString( aItemId, aPosId+1 );
+    theData = theData.replace( QRegExp(aStrOld), aStrNew );
+
+    //Mesh main menu item
+    aItemId = 70;
+    aPosId = 4;
+    aStrOld = createString( aItemId, aPosId );
+    aStrNew = createString( aItemId, aPosId+1 );
+    theData = theData.replace( QRegExp(aStrOld), aStrNew );
+
+    //Controls main menu item
+    aItemId = 60;
+    aPosId = 5;
+    aStrOld = createString( aItemId, aPosId );
+    aStrNew = createString( aItemId, aPosId+1 );
+    theData = theData.replace( QRegExp(aStrOld), aStrNew );
+
+    //Modification main menu item
+    aItemId = 40;
+    aPosId = 6;
+    aStrOld = createString( aItemId, aPosId );
+    aStrNew = createString( aItemId, aPosId+1 );
+    theData = theData.replace( QRegExp(aStrOld), aStrNew );
+
+    //Numbering main menu item
+//     aItemId = 80;
+//     aPosId = 7;
+//     aStrOld = createString( aItemId, aPosId );
+//     aStrNew = createString( aItemId, aPosId+1 );
+//     theData = theData.replace( QRegExp(aStrOld), aStrNew );
+  }
+  
+  if ( theComponent == "GEOM" ) {
+    //New Entity main menu item
+    int aItemId = 40;
+    int aPosId = 3;
+    QString aStrOld = createString( aItemId, aPosId );
+    QString aStrNew = createString( aItemId, aPosId+1 );
+    theData = theData.replace( QRegExp(aStrOld), aStrNew );
+
+    //Operations main menu item
+    aItemId = 50;
+    aPosId = 4;
+    aStrOld = createString( aItemId, aPosId );
+    aStrNew = createString( aItemId, aPosId+1 );
+    theData = theData.replace( QRegExp(aStrOld), aStrNew );
+
+    //Repair main menu item
+    aItemId = 60;
+    aPosId = 5;
+    aStrOld = createString( aItemId, aPosId );
+    aStrNew = createString( aItemId, aPosId+1 );
+    theData = theData.replace( QRegExp(aStrOld), aStrNew );
+
+    //Measures main menu item
+    aItemId = 70;
+    aPosId = 6;
+    aStrOld = createString( aItemId, aPosId );
+    aStrNew = createString( aItemId, aPosId+1 );
+    theData = theData.replace( QRegExp(aStrOld), aStrNew );
+  }
+
+  if ( theComponent == "MED" ) {
+    //MED main menu item
+    int aItemId = 90;
+    int aPosId = 3;
+    QString aStrOld = createString( aItemId, aPosId );
+    QString aStrNew = createString( aItemId, aPosId+1 );
+    theData = theData.replace( QRegExp(aStrOld), aStrNew );
+  }
+  
+  return theData;
+}
+
 typedef bool OneDim(int, QAD_Desktop*);
 typedef void (*PTR_FACTORY_FUNCTION)( CORBA::ORB_var &orb, QWidget *parent, const char *name ) ;
 
@@ -2572,8 +2928,7 @@ void QAD_Desktop::onDispatchTools(int id)
   bool libToolsGUI = true;
   if( QAD_XmlHandler::_bibmap[ id ].isEmpty() ) 
   { 
-
-    if ( dir = getenv("SALOME_SITE_DIR"))  {
+    if ( (dir = getenv("KERNEL_ROOT_DIR")) && !found ) {
       dir = QAD_Tools::addSlash(dir) ;
       dir = dir + "lib" ;
       dir = QAD_Tools::addSlash(dir) ;
@@ -2591,79 +2946,11 @@ void QAD_Desktop::onDispatchTools(int id)
        found = true;
       }
     }
-    
-    if ( (dir = getenv("SALOME_ROOT_DIR")) && !found ) {
-      dir = QAD_Tools::addSlash(dir) ;
-      dir = dir + "lib" ;
-      dir = QAD_Tools::addSlash(dir) ;
-      dir = dir + "salome" ;
-      dir = QAD_Tools::addSlash(dir) ;
-#ifdef WNT
-      dir = dir + "libToolsGUI.dll" ;
-#else
-      dir = dir + "libToolsGUI.so" ;
-#endif
-      MESSAGE ( " GUI library = " << dir );
-      fileInfo.setFile(dir) ;
-      if (fileInfo.exists()) {
-       ToolsLib = fileInfo.fileName() ;
-       found = true;
-      }
-    }
-    
-    if ( (dir = getenv("KERNEL_ROOT_DIR")) && !found ) {
-      dir = QAD_Tools::addSlash(dir) ;
-      dir = dir + "lib" ;
-      dir = QAD_Tools::addSlash(dir) ;
-      dir = dir + "salome" ;
-      dir = QAD_Tools::addSlash(dir) ;
-#ifdef WNT
-      dir = dir + "libToolsGUI.dll" ;
-#else
-      dir = dir + "libToolsGUI.so" ;
-#endif
-      MESSAGE ( " GUI library = " << dir );
-      fileInfo.setFile(dir) ;
-      if (fileInfo.exists()) {
-       ToolsLib = fileInfo.fileName() ;
-       found = true;
-      }
-    }
-  }
-  else {
-    libToolsGUI = false;
-    SCRUTE( QAD_XmlHandler::_bibmap[ id ] ) ;
-    if ( dir = getenv("SALOME_SITE_DIR"))  {
-      dir = QAD_Tools::addSlash(dir) ;
-      dir = dir + "lib" ;
-      dir = QAD_Tools::addSlash(dir) ;
-      dir = dir + "salome" ;
-      dir = QAD_Tools::addSlash(dir) ;
-      dir = dir + QAD_XmlHandler::_bibmap[ id ].latin1() ;
-      MESSAGE ( " GUI library = " << dir );
-      fileInfo.setFile(dir) ;
-      if (fileInfo.exists()) {
-       ToolsLib = fileInfo.fileName() ;
-       found = true;
-      }
-    }
-    
-    if ( (dir = getenv("SALOME_ROOT_DIR")) && !found ) {
-      dir = QAD_Tools::addSlash(dir) ;
-      dir = dir + "lib" ;
-      dir = QAD_Tools::addSlash(dir) ;
-      dir = dir + "salome" ;
-      dir = QAD_Tools::addSlash(dir) ;
-      dir = dir + QAD_XmlHandler::_bibmap[ id ].latin1() ;
-      MESSAGE ( " GUI library = " << dir );
-      fileInfo.setFile(dir) ;
-      if (fileInfo.exists()) {
-       ToolsLib = fileInfo.fileName() ;
-       found = true;
-      }
-    }
-    
-    if ( (dir = getenv("KERNEL_ROOT_DIR")) && !found ) {
+  }
+  else {
+    libToolsGUI = false;
+    SCRUTE( QAD_XmlHandler::_bibmap[ id ] ) ;
+    if ( (dir = getenv("KERNEL_ROOT_DIR")) && !found ) {
       dir = QAD_Tools::addSlash(dir) ;
       dir = dir + "lib" ;
       dir = QAD_Tools::addSlash(dir) ;
@@ -2707,14 +2994,9 @@ void QAD_Desktop::onDispatchTools(int id)
  */
 void QAD_Desktop::onDispatch(int id)
 {
-  if (!myActiveComp.isEmpty()) {
-    OSD_Function osdF = mySharedLibrary.DlSymb("OnGUIEvent");
-    OneDim (*f1) = NULL;
-    if ( osdF != NULL ) {
-      f1 = (bool (*) (int, QAD_Desktop*)) osdF;
-      (*f1)(id,this);
-    }
-  }
+  SALOMEGUI* anActiveGUI = getActiveGUI();
+  if ( anActiveGUI ) 
+    anActiveGUI->OnGUIEvent(id,this);
 }
 
 /*!
@@ -2734,12 +3016,32 @@ void QAD_Desktop::onComboActiveComponent( const QString & component, bool isLoad
 {
   if (myActiveStudy != 0) {
     if (myActiveComp.compare(component)!=0) {
+      // deactivate previous component
+      deactivateComponent();
+
       if (!myXmlHandler->myIdList.IsEmpty()) clearMenus();
       if ( myCombo->currentText() != component )
        myCombo->setCurrentText( component );
       //NRI if (component.compare(QString("Salome"))!= 0) {
       if (component.compare( getComponentUserName( "KERNEL" ) )!= 0) {
 //     QApplication::setOverrideCursor( Qt::waitCursor );
+       bool isOk = ( !isLoadData || loadComponentData( getComponentName(component) ) );
+       if ( !isOk ) {
+         QAD_MessageBox::error1( this, 
+                                tr("ERR_ERROR"),
+                                tr("ERR_COMP_DATA_NOT_LOADED").arg( component ), 
+                                tr("BUT_OK") );          
+       }
+
+       if ( !isOk || !loadComponent( getComponentName(component) ) ) {
+         myCombo->setCurrentItem (0);
+         for ( QToolButton* aButton=myComponentButton.first(); aButton; aButton=myComponentButton.next() ) {
+           aButton->setOn(false);
+         }
+         myActiveComp = "";
+         return;
+       }
+
        myActiveComp = component;
 
        SALOME_Selection* oldSel = SALOME_Selection::Selection( myActiveStudy->getSelection() );
@@ -2752,13 +3054,6 @@ void QAD_Desktop::onComboActiveComponent( const QString & component, bool isLoad
        }
 
        myActiveStudy->Selection( component );
-       if ( !loadComponent(mapComponentName[component]) ) {
-         myCombo->setCurrentItem (0);
-         for ( QToolButton* aButton=myComponentButton.first(); aButton; aButton=myComponentButton.next() ) {
-           aButton->setOn(false);
-         }
-         myActiveComp = "";
-       }
 
        SALOME_Selection* Sel = SALOME_Selection::Selection( myActiveStudy->getSelection() );
        SALOME_ListIteratorOfListIO It( oldSel->StoredIObjects() );
@@ -2772,10 +3067,13 @@ void QAD_Desktop::onComboActiveComponent( const QString & component, bool isLoad
          
        }
 
-       // Open new component's data in active study if any
-       if(isLoadData) loadComponentData(mapComponentName[component]);
-
        oldSel->Clear();
+
+       /* SETTINGS */
+       // IMPORTANT: SetSettings() should be called AFTER SALOME_Selection
+       // has been created for a newly activated component
+       getComponentGUI(component)->SetSettings( this, (char*)getComponentName(component).latin1() );
+
        myActiveStudy->updateObjBrowser(true);
 
 //     QApplication::restoreOverrideCursor();
@@ -2796,20 +3094,46 @@ void QAD_Desktop::onComboActiveComponent( const QString & component, bool isLoad
          aButton->setOn(true);
       }
     }
-  } else {
-    QMessageBox::critical( 0,
-                          tr( "ERR_ERROR" ),
-                          tr( "WRN_LOAD_COMPONENT" ) );
-    myCombo->setCurrentItem (0);       
-    for ( QToolButton* aButton=myComponentButton.first(); aButton; aButton=myComponentButton.next() ) {
-      aButton->setOn(false);
-    }
-  }
+  } else if (component.compare(QString("Salome"))!= 0) {
+
+      QPixmap pm;
+      for ( QToolButton* aButton=myComponentButton.first(); aButton; aButton=myComponentButton.next() ) {
+       if ( aButton->textLabel().compare( component ) == 0 )
+         pm = aButton->iconSet().pixmap();
+      }
+      SALOMEGUI_ActivateComponentDlg aDlg( this, component, pm );
+      int res = aDlg.exec();
+      
+      switch ( res )
+       {
+       case 1:
+         onNewStudy();
+         onComboActiveComponent(component,true);                 
+         break;
+       case 2:
+          onOpenStudy();       
+         onComboActiveComponent(component,true);
+         break;
+       case 3:
+         onLoadStudy();
+         onComboActiveComponent(component,true);;
+         break;
+       case 0:
+       default:
+         putInfo( tr("INF_CANCELLED") );
+         myCombo->setCurrentItem (0);  
+         for ( QToolButton* aButton=myComponentButton.first(); aButton; aButton=myComponentButton.next() ) {
+          aButton->setOn(false);
+          // return;
+         }
+       }
+      }
 }
 
 /*!
  */
 void QAD_Desktop::activateComponent(const QString& theName, bool isLoadData){
+  
   int nbItem = myCombo->count();
   int Index = 0;
 
@@ -2834,7 +3158,8 @@ void QAD_Desktop::onButtonActiveComponent( )
  */
 void QAD_Desktop::clearMenus()
 {
-  onActiveStudyChanged();
+  // san - commented as presumably obsolete
+  //  onActiveStudyChanged();
 
   /* menus */
   myMenusList.clear();
@@ -2876,13 +3201,9 @@ typedef bool TwoDim1(QKeyEvent* pe, QAD_Desktop*, QAD_StudyFrame*);
 void QAD_Desktop::onKeyPress( QKeyEvent* pe )
 {
   //  MESSAGE ( "QAD_Desktop::onKeyPress" )
-  if (!myActiveComp.isEmpty()) {
-    OSD_Function osdF = mySharedLibrary.DlSymb("OnKeyPress");
-    if ( osdF != NULL ) {
-      TwoDim1 (*f1) = (bool (*) (QKeyEvent*, QAD_Desktop*, QAD_StudyFrame*)) osdF;
-      (*f1)(pe,this,myActiveStudy->getActiveStudyFrame());
-    }
-  }
+  SALOMEGUI* anActiveGUI = getActiveGUI();
+  if ( anActiveGUI ) 
+    anActiveGUI->OnKeyPress(pe,this,myActiveStudy->getActiveStudyFrame());
 }
 
 typedef bool TwoDim(QMouseEvent* pe, QAD_Desktop*, QAD_StudyFrame*);
@@ -2892,13 +3213,9 @@ typedef bool TwoDim(QMouseEvent* pe, QAD_Desktop*, QAD_StudyFrame*);
 bool QAD_Desktop::onMousePress( QMouseEvent* pe )
 {
   //  MESSAGE ( "QAD_Desktop::onMousePress" )
-  if (!myActiveComp.isEmpty()) {
-    OSD_Function osdF = mySharedLibrary.DlSymb("OnMousePress");
-    if ( osdF != NULL ) {
-      TwoDim (*f1) = (bool (*) (QMouseEvent*, QAD_Desktop*, QAD_StudyFrame*)) osdF;
-      return (*f1)(pe,this,myActiveStudy->getActiveStudyFrame());
-    }
-  }
+  SALOMEGUI* anActiveGUI = getActiveGUI();
+  if ( anActiveGUI ) 
+    return anActiveGUI->OnMousePress(pe,this,myActiveStudy->getActiveStudyFrame());
   return false;
 }
 
@@ -2907,13 +3224,9 @@ bool QAD_Desktop::onMousePress( QMouseEvent* pe )
  */
 void QAD_Desktop::onMouseMove( QMouseEvent* pe )
 {
-  if (!myActiveComp.isEmpty()) {
-    OSD_Function osdF = mySharedLibrary.DlSymb("OnMouseMove");
-    if ( osdF != NULL ) {
-      TwoDim (*f1) = (bool (*) (QMouseEvent*, QAD_Desktop*, QAD_StudyFrame*)) osdF;
-      (*f1)(pe,this,myActiveStudy->getActiveStudyFrame());
-    }
-  }
+  SALOMEGUI* anActiveGUI = getActiveGUI();
+  if ( anActiveGUI ) 
+    anActiveGUI->OnMouseMove(pe,this,myActiveStudy->getActiveStudyFrame());
 }
 
 /*!
@@ -2924,55 +3237,197 @@ const QString& QAD_Desktop::getActiveComponent() const
   return myActiveComp;
 }
 
+SALOMEGUI* QAD_Desktop::getActiveGUI()
+{
+  SALOMEGUI* anActiveGUI = 0;
+  if ( myComponents.find( myActiveComp ) != myComponents.end() )
+    anActiveGUI = myComponents[myActiveComp];
+  return anActiveGUI;
+}
 
-typedef bool defineP( QString & theContext, QString & theParent, QString & theObject);
+typedef SALOMEGUI* (*ComponentGUI)();
 
-void QAD_Desktop::definePopup(QString & theContext,
-                             QString & theParent, 
-                             QString & theObject ) 
+SALOMEGUI* QAD_Desktop::getComponentGUI( const QString& component )
 {
-  if (!myActiveComp.isEmpty()) {
-    OSD_Function osdF = mySharedLibrary.DlSymb("definePopup");
+  SALOMEGUI* aCompGUI = 0;
+  if ( component.isEmpty() || getComponentName( component ).isEmpty() )
+    return aCompGUI;
+  
+  // Load component GUI if requested for the first time
+  if ( myComponents.find( component ) == myComponents.end() ) {
+    OSD_SharedLibrary aSharedLibrary;
+    QString ComponentLib;
+    QCString libs;
+    QFileInfo fileInfo ;
+    QString fileString ;
+    QString dir;
+
+    QAD_WaitCursor wc;
+    
+    _islibso= false;
+
+    if ( libs = getenv("LD_LIBRARY_PATH")) {
+      //    MESSAGE ( " LD_LIBRARY_PATH : " << libs );
+      QStringList dirList = QStringList::split( SEPARATOR, libs, false ); // skip empty entries
+      for ( int i = dirList.count()-1; i >= 0; i-- ) {
+       dir = dirList[ i ];
+#ifdef WNT
+       fileString = QAD_Tools::addSlash( dir ) + "lib" + getComponentName( component ) + "GUI.dll" ;
+#else
+       fileString = QAD_Tools::addSlash( dir ) + "lib" + getComponentName( component ) + "GUI.so" ;
+#endif
+
+       fileInfo.setFile(fileString) ;
+       if (fileInfo.exists()) {
+         // MESSAGE( " GUI library = " << fileString.latin1() );
+         ComponentLib = fileInfo.fileName() ;
+         _islibso = true;
+         break;
+       }
+      }
+    }
+
+    if (!_islibso) // component GUI could be in PyQt, use generic library
+    {
+      MESSAGE("GUI library not found, trying generic library for PyQt GUI");
+      bool found = false;
+      if (dir = getenv("KERNEL_ROOT_DIR"))
+      {
+       dir = QAD_Tools::addSlash(dir) ;
+       dir = dir + "lib" ;
+       dir = QAD_Tools::addSlash(dir) ;
+       dir = dir + "salome" ;
+       dir = QAD_Tools::addSlash(dir) ;
+#ifdef WNT
+       dir = dir + "libSalomePyQtcmodule.dll" ;
+#else
+       dir = dir + "libSalomePyQtcmodule.so" ;
+#endif
+       MESSAGE ( " GUI library = " << dir );
+       fileInfo.setFile(dir) ;
+       if (fileInfo.exists())
+       {
+         ComponentLib = fileInfo.fileName() ;
+         found = true;
+       }
+      }
+      if ( !found )
+      {
+       QMessageBox::critical( this,
+                             tr("ERR_ERROR"),
+                             tr("ERR_LIBGUI" ).arg(component) );
+       return aCompGUI;
+      }
+    }
+
+    aSharedLibrary.SetName(TCollection_AsciiString((char*)ComponentLib.latin1()).ToCString());
+    bool ok = aSharedLibrary.DlOpen(OSD_RTLD_LAZY);
+    if (!ok) {
+      wc.stop();
+      QMessageBox::critical( this,
+                           tr("ERR_ERROR"),
+                           tr( aSharedLibrary.DlError() ) );
+      return aCompGUI;
+    }
+
+    OSD_Function osdF = aSharedLibrary.DlSymb("GetComponentGUI");
     if ( osdF != NULL ) {
-      defineP (*f1) = (bool (*) (QString &, QString &, QString &)) osdF;
-      (*f1)(theContext, theParent, theObject);
+      ComponentGUI f1 = (SALOMEGUI* (*) ()) osdF;
+      SALOMEGUI* aCompGUI = (*f1)();
+      if ( aCompGUI )
+       myComponents.insert( component, aCompGUI );
+      else {
+       wc.stop();
+       QMessageBox::critical( this,
+                             tr("ERR_ERROR"),
+                             tr("ERR_GET_GUI_FAILED" ).arg(component) );
+       return aCompGUI;
+      }
+    }
+    else {
+      wc.stop();
+      QMessageBox::critical( this,
+                           tr("ERR_ERROR"),
+                           tr("ERR_GET_GUI_NOT_FOUND" ).arg(ComponentLib) );
+      return aCompGUI;
     }
   }
+  aCompGUI = myComponents[component];
+  return aCompGUI;
 }
 
+
 /*!
-    Create popup
+    Returns name of active component
 */
-void QAD_Desktop::createPopup(QPopupMenu* popupFather, QPopupMenu* popup,
-                             QString text, int popupID, bool separator)
-{
-  QMenuItem* item = popup->findItem(popupID);
-  if (item) {
-    QPopupMenu* popupChild = item->popup();
-    if ( popupChild ) {
-      QPopupMenu* newPopup = new QPopupMenu;
-      int count = popupChild->count();
-      // add items at the top of <popupFather>
-      for (int i = count - 1; i >= 0; i--) {
-       int j = popupChild->idAt(i);
-       QString text = popupChild->text(j);
-       createPopup( newPopup, popupChild, text, j);
+QString QAD_Desktop::getComponentDataType() const
+{
+  using namespace SALOMEDS;
+  Study_var aStudy = getActiveStudy()->getStudyDocument();
+  SObject_var aSObject = aStudy->FindObject(myActiveComp.latin1());
+  SComponent_var aComponent = SComponent::_narrow(aSObject);
+  if(!aComponent->_is_nil()){
+    CORBA::String_var aString = aComponent->ComponentDataType();
+    return aString.in();
+  }
+  return "";
+}
+
+void QAD_Desktop::definePopup(QString & theContext,
+                             QString & theParent, 
+                             QString & theObject ) 
+{
+  SALOMEGUI* anActiveGUI = getActiveGUI();
+  if ( anActiveGUI ) 
+    anActiveGUI->DefinePopup(theContext, theParent, theObject);
+}
+
+
+/*!
+    Copy popup menu [ static ]
+*/
+static void makePopup( QPopupMenu* popup, QPopupMenu* fromPopup, QAD_Desktop* receiver ) 
+{
+  // safe check
+  if ( !popup || !fromPopup ) 
+    return;
+  // iterator through all popup items
+  for ( int i = fromPopup->count()-1; i >= 0; i-- ) {
+    int cmdId = fromPopup->idAt( i );
+    QMenuItem* item = fromPopup->findItem( cmdId );
+    if ( item ) {
+      // if item is a separator
+      if ( item->isSeparator() ) {
+       popup->insertSeparator( 0 );
+      }
+      else {
+       QIconSet* iconSet = item->iconSet();
+       QKeySequence accel = fromPopup->accel( cmdId );
+
+       QPopupMenu* popupChild = item->popup();
+       // if item is a popup
+       if ( popupChild && popupChild != fromPopup ) {
+         QPopupMenu* newPopup = new QPopupMenu( popup );
+         if ( iconSet ) 
+           popup->insertItem( *iconSet, item->text(), newPopup, cmdId, 0 );
+         else
+           popup->insertItem( item->text(), newPopup, cmdId, 0 );
+         makePopup( newPopup, popupChild, receiver );
+       }
+       // if item is a command
+       else {
+         if ( iconSet ) 
+           popup->insertItem( *iconSet, item->text(), cmdId, 0 );
+         else
+           popup->insertItem( item->text(), cmdId, 0 );
+         popup->connectItem( cmdId, receiver, SLOT( onDispatch( int ) ) );
+       }
+       popup->setAccel( accel, cmdId );
       }
-      popupFather->insertItem(popup->text(popupID),
-                             newPopup, popupID, 0);
-    } else {
-      if ( !text.isNull() ) {
-       popupFather->insertItem(popup->text(popupID),
-                               this,
-                               SLOT( onDispatch(int) ), 0, popupID, 0);// try adding item at the top
-      } /*else if ( separator ) 
-       popupFather->insertTearOffHandle(-1, 0);*/
-      else
-       popupFather->insertSeparator(0);
     }
   }
 }
-
+    
 /*!
     Create popup
 */
@@ -2981,34 +3436,8 @@ void QAD_Desktop::createPopup(QPopupMenu* popup, const QString & theContext,
 {
   if ( !myActiveComp.isEmpty() && 
        getOperatorMenus()->createPopupMenu(theContext,theParent,theObject) != NULL ) {
-    QPopupMenu* aPopup = getOperatorMenus()->createPopupMenu(theContext,theParent,theObject)->getPopup();
-    int count = aPopup->count();
-
-    //for (int i = 0; i < count; i++) {
-    for (int i = count - 1; i >= 0; i--) {
-      int id = aPopup->idAt(i);
-      QString text = aPopup->text(id);
-      //QString mes("Inserting popup menu item loaded from XML: ");
-      //mes += text;
-      //MESSAGE ( mes.latin1() )
-      if (i==0)
-       popup->insertItem(aPopup->text(id),
-                         this,
-                         SLOT( onDispatch(int) ), 0, id, 0);// try adding item at the top
-      else
-       createPopup( popup, aPopup, text, id);
-    }
-  } //else {
-    //QString mes("Popup does not exist for given (Context = ");
-    //mes += theContext;
-    //mes += ", Parent = ";
-    //mes += theParent;
-    //mes += ", Object = ";
-    //mes += theObject;
-    //MESSAGE (mes.latin1())
-      //popup->clear();
-  //}
-
+    makePopup( popup, getOperatorMenus()->createPopupMenu(theContext,theParent,theObject)->getPopup(), this );
+  }
   // IAPP Popup 
   // Should be moved to SALOMEGUI_Application::onCreatePopup()...
   if ( myActiveComp.isEmpty() ) {
@@ -3028,38 +3457,60 @@ void QAD_Desktop::createPopup(QPopupMenu* popup, const QString & theContext,
       }
     } 
   }
-}
 
-typedef bool activeStudyChanged(QAD_Desktop*);
+}
 
 void QAD_Desktop::onActiveStudyChanged()
 {
-  if (!myActiveComp.isEmpty()) {
-    OSD_Function osdF = mySharedLibrary.DlSymb("activeStudyChanged");
-    if ( osdF != NULL ) {
-      activeStudyChanged (*f1) = (bool (*) (QAD_Desktop*)) osdF;
-      (*f1)(this);
-    }  
+  // Avoid recursive calls caused by QAD_MessageBox
+  static bool isRecursion = false;
+  if ( isRecursion || myAboutToClose )
+    return;
+
+  if (myActiveComp != "") {
+    // Try to load active component's data in the activated study
+    if ( !loadComponentData(mapComponentName[myActiveComp]) ) {
+      isRecursion = true;
+      QAD_MessageBox::error1( this, 
+                            tr("ERR_ERROR"),
+                            tr("ERR_COMP_DATA_NOT_LOADED").arg( myActiveComp ), 
+                            tr("BUT_OK") );
+      // Error while loading component's data -> deactivate it
+      deactivateComponent();
+      if (!myXmlHandler->myIdList.IsEmpty()) clearMenus();
+      myCombo->setCurrentItem (0);
+      for ( QToolButton* aButton=myComponentButton.first(); aButton; aButton=myComponentButton.next() ) {
+       aButton->setOn(false);
+      }
+      myActiveComp = "";
+      isRecursion = false;
+      return;
+    }
+    else
+      myActiveStudy->updateObjBrowser(true);
   }
+
+  SALOMEGUI* anActiveGUI = getActiveGUI();
+  if ( anActiveGUI ) 
+    anActiveGUI->ActiveStudyChanged(this);
+}
+
+void QAD_Desktop::deactivateComponent()
+{
+  SALOMEGUI* anActiveGUI = getActiveGUI();
+  if ( anActiveGUI ) 
+    anActiveGUI->Deactivate();
 }
 
-typedef bool customP(QAD_Desktop*, QPopupMenu*, const QString & theContext,
-                    const QString & theParent, const QString & theObject);
 /*!
   Custom popup ( GUI Library )
 */
 void QAD_Desktop::customPopup(QPopupMenu* popup, const QString & theContext,
                              const QString & theParent, const QString & theObject)
 {
-  if (!myActiveComp.isEmpty()) {
-    OSD_Function osdF = mySharedLibrary.DlSymb("customPopup");
-    if ( osdF != NULL ) {
-      customP (*f1) = (bool (*) (QAD_Desktop*, QPopupMenu*, const QString &,
-                                const QString &, const QString &)) osdF;
-      (*f1)(this, popup, theContext, theParent, theObject);
-    }
-  }
+  SALOMEGUI* anActiveGUI = getActiveGUI();
+  if ( anActiveGUI ) 
+    anActiveGUI->CustomPopup(this, popup, theContext, theParent, theObject);
 }
 
 void QAD_Desktop::onObjectBrowser()
@@ -3102,10 +3553,30 @@ void QAD_Desktop::onObjectBrowser()
   bool showCHRONO_SORT ;
   if ( myStdActions.at( PrefObjectBrowserCHRONO_SORTId )->isOn() ) {
     showCHRONO_SORT = true;
-    QAD_CONFIG->addSetting( "ObjectBrowser:CHRONO_SORT", "true");
+    QAD_CONFIG->addSetting( "ObjectBrowser:ChronologicalSort", "true");
   } else {
     showCHRONO_SORT = false;
-    QAD_CONFIG->addSetting( "ObjectBrowser:CHRONO_SORT", "false");
+    QAD_CONFIG->addSetting( "ObjectBrowser:ChronologicalSort", "false");
+  }
+
+  /* To show or not to show UseCase browser */
+  bool showUseCase;
+  if ( myStdActions.at( PrefObjectBrowserShowUseCaseId )->isOn() ) {
+    showUseCase = true;
+    QAD_CONFIG->addSetting( "ObjectBrowser:ShowUseCaseBrowser", "true");
+  } else {
+    showUseCase = false;
+    QAD_CONFIG->addSetting( "ObjectBrowser:ShowUseCaseBrowser", "false");
+  }
+
+  /* Resize or don't resize columns automatically */
+  bool autoSize;
+  if ( myStdActions.at( PrefObjectBrowserNoAutoSizeColumnsId )->isOn() ) {
+    autoSize = false;
+    QAD_CONFIG->addSetting( "ObjectBrowser:NoAutoSizeColumns", "true");
+  } else {
+    autoSize = true;
+    QAD_CONFIG->addSetting( "ObjectBrowser:NoAutoSizeColumns", "false");
   }
 
   if ( myActiveApp ) {
@@ -3118,6 +3589,8 @@ void QAD_Desktop::onObjectBrowser()
        sf->getLeftFrame()->getObjectBrowser()->setShowValueColumn( showValue );
        sf->getLeftFrame()->getObjectBrowser()->setEnableChronoSort( showCHRONO_SORT );
 //     sf->getLeftFrame()->getObjectBrowser()->setShowIAPP( showIAPP ); // this is done by below updateObjBrowser() call
+       sf->getLeftFrame()->getObjectBrowser()->showUseCaseBrowser( showUseCase );
+       sf->getLeftFrame()->getObjectBrowser()->autoSizeColumns( autoSize );
       }
       study->updateObjBrowser(true);
     }
@@ -3144,13 +3617,40 @@ void QAD_Desktop::onViewerTrihedron()
       for ( QAD_Study* study = studies.first(); study; study = studies.next() )  {
        int nbSf = study->getStudyFramesCount();
        for ( int i = 0; i < nbSf; i++ ) {
-         study->getStudyFrame(i)->getRightFrame()->getViewFrame()->SetTrihedronSize((int)dim);
+         study->getStudyFrame(i)->getRightFrame()->getViewFrame()->onAdjustTrihedron();
        }
       }
     }
   }
 }
 
+void QAD_Desktop::onExternalBrowser()
+{
+  QString theApp = QAD_CONFIG->getSetting("ExternalBrowser:Application");
+  QString theParams = QAD_CONFIG->getSetting("ExternalBrowser:Parameters");
+   
+  SALOMEGUI_ExternalBrowserDlg *Dlg = new SALOMEGUI_ExternalBrowserDlg(this);
+  
+  if (!theApp.isEmpty())
+    {
+      QString theParams = QAD_CONFIG->getSetting("ExternalBrowser:Parameters");
+      Dlg->setSettings(theApp, theParams);
+    }
+  int r = Dlg->exec();
+  QString theAppFromDialog = Dlg->getApp();
+  QString theParamsFromDialog = Dlg->getParams();
+  delete Dlg;
+  
+  if (r == QDialog::Accepted) 
+    {
+      QAD_CONFIG->addSetting("ExternalBrowser:Application", theAppFromDialog );
+      QAD_CONFIG->addSetting("ExternalBrowser:Parameters", theParamsFromDialog );
+    }
+  
+}
+
+
 void QAD_Desktop::onDirList() 
 {
   // getting dir list from settings
@@ -3229,6 +3729,7 @@ void QAD_Desktop::onViewerOCC()
   QColor c = QColorDialog::getColor( color, QAD_Application::getDesktop() );
 
   if (c.isValid()) {
+    /* VSR : PAL5420 ---------------------------------------------------
     if ( myActiveApp ) {
       QList<QAD_Study>& studies = myActiveApp->getStudies();
       for ( QAD_Study* study = studies.first(); study; study = studies.next() )  {
@@ -3241,6 +3742,7 @@ void QAD_Desktop::onViewerOCC()
        }
       }
     }
+    VSR : PAL5420 --------------------------------------------------- */
     QAD_CONFIG->addSetting( "OCCViewer:BackgroundColorRed",   c.red() );
     QAD_CONFIG->addSetting( "OCCViewer:BackgroundColorGreen", c.green() );
     QAD_CONFIG->addSetting( "OCCViewer:BackgroundColorBlue",  c.blue() );
@@ -3264,6 +3766,7 @@ void QAD_Desktop::onGraphSupervisor()
   QColor c = QColorDialog::getColor( color, QAD_Application::getDesktop() );
 
   if (c.isValid()) {
+    /* VSR : PAL5420 ---------------------------------------------------
     if ( myActiveApp ) {
       QList<QAD_Study>& studies = myActiveApp->getStudies();
       for ( QAD_Study* study = studies.first(); study; study = studies.next() )  {
@@ -3276,7 +3779,7 @@ void QAD_Desktop::onGraphSupervisor()
        }
       }
     }
-    
+    VSR : PAL5420 --------------------------------------------------- */
     QAD_CONFIG->addSetting( "SUPERVGraph:BackgroundColorRed",   c.red() );
     QAD_CONFIG->addSetting( "SUPERVGraph:BackgroundColorGreen", c.green() );
     QAD_CONFIG->addSetting( "SUPERVGraph:BackgroundColorBlue",  c.blue() );
@@ -3300,6 +3803,7 @@ void QAD_Desktop::onViewerVTK()
   QColor c = QColorDialog::getColor( color, QAD_Application::getDesktop() );
 
   if (c.isValid()) {
+    /* VSR : PAL5420 ---------------------------------------------------
     if ( myActiveApp ) {
       QList<QAD_Study>& studies = myActiveApp->getStudies();
       for ( QAD_Study* study = studies.first(); study; study = studies.next() )  {
@@ -3312,7 +3816,7 @@ void QAD_Desktop::onViewerVTK()
        }
       }
     }
-    
+    VSR : PAL5420 --------------------------------------------------- */
     QAD_CONFIG->addSetting( "VTKViewer:BackgroundColorRed",   c.red() );
     QAD_CONFIG->addSetting( "VTKViewer:BackgroundColorGreen", c.green() );
     QAD_CONFIG->addSetting( "VTKViewer:BackgroundColorBlue",  c.blue() );
@@ -3332,12 +3836,13 @@ void QAD_Desktop::onPlot2d()
     color = QColor( bgRed, bgGreen, bgBlue );
   }
   else {
-    color = QColor(0, 0, 0);  
+    color = QColor(255, 255, 255);  
   }
 
   color = QColorDialog::getColor( color, QAD_Application::getDesktop() );
 
   if ( color.isValid() ) {
+    /* VSR : PAL5420 ---------------------------------------------------
     if ( myActiveApp ) {
       QList<QAD_Study>& studies = myActiveApp->getStudies();
       for ( QAD_Study* study = studies.first(); study; study = studies.next() )  {
@@ -3350,6 +3855,7 @@ void QAD_Desktop::onPlot2d()
        }
       }
     }
+    VSR : PAL5420 --------------------------------------------------- */
     QStringList bgData; 
     bgData.append( QString::number( color.red() ) );
     bgData.append( QString::number( color.green() ) );
@@ -3366,52 +3872,58 @@ void QAD_Desktop::helpAbout()
   delete About;
 }
 
-/* Help Search */
-void QAD_Desktop::helpSearch()
-{
-}
-
-/* Help Contents */
-void QAD_Desktop::helpContents()
-{
-  if (myActiveComp == "")
-    myActiveComp = getComponentUserName( "KERNEL" ); //NRI "Salome";
-
-  QCString dir;
-  QString root;
-  if (dir = getenv( getComponentName( myActiveComp ) + "_ROOT_DIR")) {
-    root = QAD_Tools::addSlash( QAD_Tools::addSlash(dir) + QAD_Tools::addSlash("share")  + QAD_Tools::addSlash("salome")  + "doc" );
-    if ( QFileInfo( root + "index.html" ).exists() ) {
-      helpContext( root + "index.html", "" );
-    }
-    else {
-      root = QAD_Tools::addSlash( root + "html" );
-      if ( QFileInfo( root + "index.html" ).exists() ) {
-       helpContext( root + "index.html", "" );
-      }
-      else {
-       root = QAD_Tools::addSlash( root + "html" );
-       if ( QFileInfo( root + "index.html" ).exists() ) {
-         helpContext( root + "index.html", "" );
-       }
-      }
-    }
-  }
+// /* Help Search */
+// void QAD_Desktop::helpSearch()
+// {
+// }
+
+// /* Help Contents */
+// void QAD_Desktop::helpContents()
+// {
+//   if (myActiveComp == "")
+//     myActiveComp = getComponentUserName( "KERNEL" ); //NRI "Salome";
+
+//   QCString dir;
+//   QString root;
+//   if (dir = getenv( getComponentName( myActiveComp ) + "_ROOT_DIR")) {
+//     root = QAD_Tools::addSlash( QAD_Tools::addSlash(dir) + QAD_Tools::addSlash("share")  + QAD_Tools::addSlash("salome")  + "doc" );
+//     if ( QFileInfo( root + "index.html" ).exists() ) {
+//       helpContext( root + "index.html", "" );
+//     }
+//     else {
+//       root = QAD_Tools::addSlash( root + "html" );
+//       if ( QFileInfo( root + "index.html" ).exists() ) {
+//     helpContext( root + "index.html", "" );
+//       }
+//       else {
+//     root = QAD_Tools::addSlash( root + "html" );
+//     if ( QFileInfo( root + "index.html" ).exists() ) {
+//       helpContext( root + "index.html", "" );
+//     }
+//       }
+//     }
+//   }
   
-  //NRI getHelpWindow()->contents();
-  getHelpWindow()->show();
-  getHelpWindow()->raise();
-  getHelpWindow()->setActiveWindow();
-}
+// //   //NRI getHelpWindow()->contents();
+// //   getHelpWindow()->show();
+// //   getHelpWindow()->raise();
+// //   getHelpWindow()->setActiveWindow();
+// }
 
 /* Help Context */
-void QAD_Desktop::helpContext(const QString& source, const QString& context)
-{
-  getHelpWindow()->context(source, context);
-  getHelpWindow()->show();
-  getHelpWindow()->raise();
-  getHelpWindow()->setActiveWindow();
-}
+//void QAD_Desktop::helpContext(const QString& source, const QString& context)
+//{
+//  //getHelpWindow()->context(source, context);   //implemented in QAD_HelpWindow::context( const QString& _source, const QString& _context)
+//  //getHelpWindow()->show();                     //from QMainWindow class
+//  //getHelpWindow()->raise();                    //from QMainWindow class
+//  //getHelpWindow()->setActiveWindow();          //from QMainWindow class
+
+//  QString anApp = QAD_CONFIG->getSetting("ExternalBrowser:Application");
+//  QString aParams = QAD_CONFIG->getSetting("ExternalBrowser:Parameters");
+   
+//  RunBrowser* rs = new RunBrowser(anApp, aParams, source, context);
+//  rs->start();
+//}
 
 /* Preferences/MultiFile Save */
 void QAD_Desktop::onMultiFileSave()
@@ -3431,6 +3943,121 @@ void QAD_Desktop::onASCIISave()
     QAD_CONFIG->addSetting( "Desktop:ASCIISave", "false");
 }
 
+/* Preferences / Undo Level */
+void QAD_Desktop::onUndoLevel()
+{
+  static int MAX_UNDO_LEVEL = 1000;
+  bool isAccepted = false;
+  static QString aLabel = QString("Level value (%1 ... %2) : ").
+    arg(1).arg(MAX_UNDO_LEVEL);
+  int anUndoLevel = 
+    SALOMEGUI_SetValueDlg::getInteger("Undo Level",aLabel,
+                                     1,MAX_UNDO_LEVEL,getUndoLevel(),
+                                     &isAccepted);
+  if(!isAccepted) return;
+  QAD_CONFIG->addSetting("Desktop:UndoLevel", anUndoLevel);
+  if(!myActiveApp) return;
+  QList<QAD_Study>& studies = myActiveApp->getStudies();
+  int aWasWarning = 0;
+  for(QAD_Study* study = studies.first(); study; study = studies.next()){
+    SALOMEDS::Study_var aStudyDoc = study->getStudyDocument();
+    SALOMEDS::StudyBuilder_var aStudyBuilder = aStudyDoc->NewBuilder();
+    if (!aStudyDoc->GetProperties()->IsLocked()) {
+      aStudyBuilder->UndoLimit(anUndoLevel);
+    } else  {
+      if (!aWasWarning) {
+       QAD_MessageBox::warn1 ((QWidget*)QAD_Application::getDesktop(),
+                              QObject::tr("WRN_WARNING"), 
+                              QObject::tr("WRN_STUDY_LOCKED"),
+                              QObject::tr("BUT_OK"));
+       aWasWarning = 1;
+      }
+    }
+  }
+}
+
+/* Update status bar for File menu items */
+void QAD_Desktop::onFilePopupStatusText( int id )
+{
+  QString component = getActiveComponent();
+  
+  if (component != "") {
+    //one of the modules is active now
+    int importId = myFilePopup.idAt(8);
+    int exportId = myFilePopup.idAt(9);
+    int importTableId = myFilePopup.idAt(10);
+   
+    if (component == getComponentUserName("SMESH") || component == getComponentUserName("GEOM")) {
+      if (id == importId)
+       putInfo( tr("PRP_DESK_FILE_IMPORT") );
+      if (id == exportId)
+       putInfo( tr("PRP_DESK_FILE_EXPORT") );
+    }
+    if (component == getComponentUserName("VISU")) {
+      if (id == importId)
+       putInfo( tr("PRP_DESK_FILE_IMPORTMED") );
+      if (id == importTableId)
+       putInfo( tr("PRP_DESK_FILE_IMPORTTABLE") );
+      if (id == exportId)
+       putInfo( tr("PRP_DESK_FILE_EXPLOREMEDFILE") );
+    }
+    if (component == getComponentUserName("SUPERV")) {
+      if (id == importId)
+       putInfo( tr("PRP_DESK_FILE_IMPORTDF") );
+      if (id == exportId)
+       putInfo( tr("PRP_DESK_FILE_EXPORTDF") );
+    }
+  }
+}
+
+/* Update status bar for Edit menu items */
+void QAD_Desktop::onEditPopupStatusText( int id )
+{
+  QString component = getActiveComponent();
+  
+  if (component != "") {
+    //one of the modules is active now
+   
+    if (component == getComponentUserName("SMESH") || component == getComponentUserName("GEOM") ) {
+      int deleteId = myEditPopup.idAt(5);
+      if (id == deleteId)
+       putInfo( tr("PRP_DESK_EDIT_DELETE") );
+    }
+    if (component == getComponentUserName("SUPERV") ) {
+      int newDFId = myEditPopup.idAt(5);
+      int modifyDFId = myEditPopup.idAt(6);
+      if (id == newDFId)
+       putInfo( tr("PRP_DESK_EDIT_NEWDF") );
+      if (id == modifyDFId)
+       putInfo( tr("PRP_DESK_EDIT_MODIFYDF") );
+    }
+  }
+}
+
+/* Update status bar for View menu items */
+void QAD_Desktop::onViewPopupStatusText( int id )
+{
+  QString component = getActiveComponent();
+  
+  if (component != "") {
+    //one of the modules is active now
+    int DispModeId = myViewPopup.idAt(2);
+    
+    if (component == getComponentUserName("GEOM")) {
+      if (id == DispModeId)
+       putInfo( tr("PRP_DESK_VIEW_DISPLAYMODE") );
+    }
+    if (component == getComponentUserName("SMESH")) {
+      int updateId = myViewPopup.idAt(3);
+
+      if (id == DispModeId)
+       putInfo( tr("PRP_DESK_VIEW_DISPLAYMODE") );
+      if (id == updateId)
+       putInfo( tr("PRP_DESK_VIEW_UPDATE") );
+    }
+  }
+}
+
 /*********************************************************************
 ** Class: AppSelectionDlg
 ** Descr: Dialog for the selection of the application when several