Salome HOME
Increase version to 7.3.0.
[tools/install.git] / src / SALOME_InstallWizard.cxx
index bc84ab480f6a59910c30729ba3c421b6a9ab81e1..9228f170997c4f6120c4371428f56fdc9d800696 100644 (file)
@@ -3,7 +3,7 @@
 //  Author    : Vadim SANDLER, Open CASCADE SAS (vadim.sandler@opencascade.com)
 //  Project   : SALOME
 //  Module    : Installation Wizard
-//  Copyright : 2002-2007 CEA
+//  Copyright : 2002-2013 CEA
 
 #include "globals.h"
 
@@ -43,6 +43,7 @@
 #include <qradiobutton.h>
 #include <qbuttongroup.h>
 #include <qregexp.h>
+#include <qdir.h>
 
 #ifdef WNT
 #include <iostream.h>
@@ -50,6 +51,7 @@
 #else
 #include <unistd.h>
 #include <algo.h>
+#include <sys/utsname.h>
 #endif
 
 #ifdef WNT
 QString tmpDirName() { return QString(  "/INSTALLWORK" ) + QString::number( getpid() ); }
 #define TEMPDIRNAME tmpDirName()
 
+// uncomment next line to redirect all shell output (usually for errors) to /dev/null device
+// #define USE_DEV_NULL
+
+// ================================================================
+/*!
+ *  Script
+ *  Helper class to generate shell command
+ */
+// ================================================================
+class Script
+{
+public:
+  Script( const QString& cmd = QString::null, const QString& sep = " " ) : mySeparator( sep )
+  {
+    append( cmd );
+  }
+  void append( const QString& cmd )
+  {
+    if ( !cmd.isEmpty() ) myList.append( cmd );
+  }
+  Script& operator<<( const QString& cmd )
+  {
+    append( cmd );
+    return *this;
+  }
+  QString script() const
+  {
+    return myList.join( mySeparator );
+  }
+  void clear()
+  {
+    myList.clear();
+  }
+private:
+  QStringList myList;
+  QString     mySeparator;
+};
+
 // ================================================================
 /*!
  *  ProcessThread
- *  Class for executing systen commands
+ *  Class for executing system commands
  */
 // ================================================================
 static QMutex myMutex(false);
@@ -203,29 +243,29 @@ private:
 
 // ================================================================
 /*!
- *  DefineDependeces [ static ]
- *  Defines list of dependancies as string separated by space symbols
+ *  getAllProducts [ static ]
+ *  Defines list of all products as a string separated by space symbols
  */
 // ================================================================
-static QString DefineDependeces(MapProducts& theProductsMap)
+static QString getAllProducts(MapProducts& theProductsMap)
 {
-  QStringList aProducts;
+  QStringList aModules, aPrereqs;
   for ( MapProducts::Iterator mapIter = theProductsMap.begin(); mapIter != theProductsMap.end(); ++mapIter ) {
     QCheckListItem* item = mapIter.key();
     Dependancies dep = mapIter.data();
-    QStringList deps = dep.getDependancies();
-    for (int i = 0; i<(int)deps.count(); i++ ) {
-      if ( !aProducts.contains( deps[i] ) ) {
-       aProducts.append( deps[i] );
-       aProducts.append( deps[i] + "_src" );
+    QString curModule = item->text(0);
+    if ( !aModules.contains( curModule ) && !aPrereqs.contains( curModule ) ) {
+      if ( dep.getType() == "component" ) {
+       aModules.append( curModule );
+       aModules.append( curModule + "_src" );
+      }
+      else {
+       aPrereqs.append( curModule );
+       aPrereqs.append( curModule + "_src" );
       }
-    }
-    if ( !aProducts.contains( item->text(0) ) ) {
-      aProducts.append( item->text(0) );
-      aProducts.append( item->text(0) + "_src" );
     }
   }
-  return aProducts.join(" ");
+  return QStringList(aPrereqs+aModules).join(" ");
 }
 
 // ================================================================
@@ -275,10 +315,18 @@ static bool makeDir( const QString& theDir, QString& theCreated )
       QFileInfo fi( aDir.left( start ) );
       if ( !fi.exists() ) {
        // VSR: Create directory and set permissions to allow other users to remove it
-       QString script = "mkdir " + fi.absFilePath();
-       script += "; chmod 777 " + fi.absFilePath();
-       script += " > /dev/null";
-       if ( system( script.latin1() ) )
+       Script script;
+       script << "mkdir" << QUOTE( fi.absFilePath() );
+#ifdef USE_DEV_NULL
+       script << ">& /dev/null";
+#endif
+       script << "&&";
+       script << "chmod 777" << QUOTE( fi.absFilePath() );
+#ifdef USE_DEV_NULL
+       script << ">& /dev/null";
+#endif
+       ___MESSAGE___( "script = " << script.script().latin1() );
+       if ( system( script.script().latin1() ) )
          return false;
        // VSR: Remember the top of the created directory (to remove it in the end of the installation)
        if ( theCreated.isNull() )
@@ -289,9 +337,13 @@ static bool makeDir( const QString& theDir, QString& theCreated )
   }
   if ( !QFileInfo( aDir ).exists() ) {
     // VSR: Create directory, other users should NOT have possibility to remove it!!!
-    QString script = "mkdir " + aDir;
-    script += " > /dev/null";
-    if ( system( script.latin1() ) )
+    Script script;
+    script << "mkdir" << QUOTE( aDir );
+#ifdef USE_DEV_NULL
+    script << ">& /dev/null";
+#endif
+    ___MESSAGE___( "script = " << script.script().latin1() );
+    if ( system( script.script().latin1() ) )
       return false;
     // VSR: Remember the top of the created directory (to remove it in the end of the installation)
     if ( theCreated.isNull() )
@@ -343,7 +395,7 @@ static bool hasSpace( const QString& dir )
  *  Creates HTML-wrapped title text
  */
 // ================================================================
-QString makeTitle( const QString& text, const QString& separator = " ", bool fl = true )
+static QString makeTitle( const QString& text, const QString& separator = " ", bool fl = true )
 {
   QStringList words = QStringList::split( separator, text );
   if ( fl ) {
@@ -387,7 +439,7 @@ public:
   AboutDlg( SALOME_InstallWizard* parent ) : QDialog( parent, "About dialog box", true )
   {
     // caption
-    setCaption( QString( "About %1" ).arg( parent->getIWName() ) );
+    setCaption( tr( "About %1" ).arg( parent->getIWName() ) );
     // palette
     QPalette pal = palette();
     QColorGroup cg = pal.active();
@@ -399,34 +451,22 @@ public:
     QGridLayout* main = new QGridLayout( this, 1, 1, 11, 6 );
     // image
     QLabel* logo = new QLabel( this, "logo" );
-    logo->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) );
-    logo->setMinimumSize( 32, 32 ); logo->setMaximumSize( 32, 32 );
-    logo->setPaletteBackgroundColor( QColor( 234, 250, 234 ) );
+    logo->setFixedSize( 24, 24 );
     logo->setFrameStyle( QLabel::NoFrame | QLabel::Plain );
     logo->setPixmap( pixmap( pxAbout ) );
     logo->setScaledContents( false );
     logo->setAlignment( QLabel::AlignCenter );
-    // decoration
-    QLabel* decorLeft = new QLabel( this, "decorLeft" );
-    decorLeft->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Expanding ) );
-    decorLeft->setMinimumWidth( 32 ); decorLeft->setMaximumWidth( 32 );
-    decorLeft->setPaletteBackgroundColor( QColor( 234, 250, 234 ) );
-    decorLeft->setScaledContents( false );
-    QLabel* decorTop = new QLabel( this, "decorTop" );
-    decorTop->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
-    decorTop->setMinimumHeight( 32 ); decorTop->setMaximumHeight( 32 );
-    decorTop->setPaletteBackgroundColor( QColor( 234, 250, 234 ) );
-    decorTop->setScaledContents( false );
     // contents
     QLabel* title = new QLabel( this, "title" );
     QString tlt = parent->getIWName();
     title->setText( makeTitle( tlt ) );
     QLabel* version = new QLabel( this, "version" );
-    version->setText( QString( "<b>Version</b>: %1.%1.%1" ).arg( __IW_VERSION_MAJOR__ ) \
-                     .arg( __IW_VERSION_MINOR__ ) \
+    version->setText( QString( "<b>Version</b>: %1.%1.%1" )
+                     .arg( __IW_VERSION_MAJOR__ )
+                     .arg( __IW_VERSION_MINOR__ )
                      .arg( __IW_VERSION_PATCH__ ) );
     QLabel* copyright = new QLabel( this, "copyright" );
-    copyright->setText( "<b>Copyright</b> &copy; 2004-2007 CEA" );
+    copyright->setText( "<b>Copyright</b> &copy; 2002-2013 CEA" );
     QFont font = title->font();
     font.setPointSize( (int)( font.pointSize() * 1.8 ) );
     title->setFont( font );
@@ -442,18 +482,15 @@ public:
     url->setFont( font );
     // layout
     main->addWidget( logo, 0, 0 );
-    main->addMultiCellWidget( decorLeft, 1, 5, 0, 0 );
-    main->addWidget( decorTop, 0, 1 );
-    main->addWidget( title, 1, 1 );
-    main->addWidget( version, 2, 1 );
-    main->addWidget( copyright, 3, 1 );
-    main->addWidget( line, 4, 1 );
-    main->addWidget( url, 5, 1 );
+    main->addWidget( title, 0, 1 );
+    main->addWidget( version, 1, 1 );
+    main->addWidget( copyright, 2, 1 );
+    main->addWidget( line, 3, 1 );
+    main->addWidget( url, 4, 1 );
     // resize
     QFontMetrics fm( title->font() );
     int width = (int)( fm.width( tlt ) * 1.5 );
     title->setMinimumWidth( width );
-    setMaximumSize( minimumSize() );
   }
   void mousePressEvent( QMouseEvent* )
   {
@@ -469,7 +506,9 @@ public:
 // ================================================================
 SALOME_InstallWizard::SALOME_InstallWizard(const QString& aXmlFileName,
                                           const QString& aTargetDir,
-                                          const QString& aTmpDir)
+                                          const QString& aTmpDir,
+                                          const bool     aForceSrc,
+                                          const bool     aSingleDir)
      : InstallWizard( qApp->desktop(), "SALOME_InstallWizard", false, 0 ),
        helpWindow( NULL ),
        moreMode( false ),
@@ -482,17 +521,24 @@ SALOME_InstallWizard::SALOME_InstallWizard(const QString& aXmlFileName,
   xmlFileName  = aXmlFileName;
   myTargetPath = aTargetDir;
   myTmpPath    = aTmpDir;
+  forceSrc     = aForceSrc;
+  singleDir    = aSingleDir;
   stateChanged = true;
-  binPath = QDir::currentDirPath() + "/Products/BINARIES";
-  srcPath = QDir::currentDirPath() + "/Products/SOURCES";
+
+  QDir rootDir( rootDirPath() );
+  binPath = rootDir.filePath( "Products/BINARIES" );
+  srcPath = rootDir.filePath( "Products/SOURCES" );
+  oneProdDirName = "PRODUCTS";
+  
+  commonPlatform = "Debian 3.1";
   
   //
   // get XML filename and current platform
   //
   // ... get current platform
-  curPlatform = currentPlatform();
-//   cout << "curOS = " << curPlatform << endl;
-//   curPlatform = "";
+  curPlatform = currentPlatform().join(" ");
+  //cout << "curOS = " << curPlatform << endl;
+  refPlatform = "";
   // ... check XML and platform definition
   getXmlAndPlatform();
 
@@ -511,10 +557,11 @@ SALOME_InstallWizard::SALOME_InstallWizard(const QString& aXmlFileName,
   addLogo( pixmap( pxLogo ) );
 
   // set defaults
-  setVersion( "3.2.7" );
+  setVersion( "7.3.0" );
   setCaption( tr( "SALOME %1" ).arg( myVersion ) );
-  setCopyright( tr( "Copyright (C) 2007 CEA" ) );
-  setLicense( tr( "All rights reserved." ) );
+  setCopyright( tr( "<h5>Copyright &copy; 2007-2013 CEA/DEN, EDF R&amp;D, OPEN CASCADE<br></h5>"
+               "<h5>Copyright &copy; 2003-2007 OPEN CASCADE,<br>EADS/CCR, LIP6, CEA/DEN, CEDRAT, EDF R&amp;D,<br>LEG, PRINCIPIA R&amp;D, BUREAU VERITAS</h5>" ));
+  setLicense( tr( "<h5>GNU LGPL</h5>" ) );
 
   ___MESSAGE___( "Configuration file : " << xmlFileName.latin1() );
   ___MESSAGE___( "Target directory   : " << myTargetPath.latin1() );
@@ -528,14 +575,12 @@ SALOME_InstallWizard::SALOME_InstallWizard(const QString& aXmlFileName,
 
   // create instance of class for starting shell script to get available disk space
   diskSpaceProc = new QProcess( this, "procDiskSpace" );
-  connect( diskSpaceProc, SIGNAL( processExited() ), this, SLOT( updateAvailableSpace() ) );
-
   // create instance of class for starting shell install script
   shellProcess = new QProcess( this, "shellProcess" );
-
+  // create instance of class for starting shell script to modify SALOME *.la files
+  modifyLaProc = new QProcess( this, "modifyLaProc" );
   // create instance of class for starting shell script to check Fortran libraries
   checkFLibProc = new QProcess( this, "checkFLibProc" );
-  connect(checkFLibProc, SIGNAL( processExited() ), this, SLOT( checkFLibResult() ) );
 
   // create introduction page
   setupIntroPage();
@@ -567,11 +612,19 @@ SALOME_InstallWizard::SALOME_InstallWizard(const QString& aXmlFileName,
   connect( this, SIGNAL( helpClicked() ),  this, SLOT( helpClicked() ) );
   connect( this, SIGNAL( aboutClicked() ), this, SLOT( onAbout() ) );
 
-  // catch signals from launched script
+  // catch signals from launched diskSpaceProc
+  connect( diskSpaceProc, SIGNAL( processExited() ), this, SLOT( updateAvailableSpace() ) );
+  // catch signals from launched shellProcess
   connect(shellProcess, SIGNAL( readyReadStdout() ), this, SLOT( readFromStdout() ) );
   connect(shellProcess, SIGNAL( readyReadStderr() ), this, SLOT( readFromStderr() ) );
   connect(shellProcess, SIGNAL( processExited() ),   this, SLOT( productInstalled() ) );
   connect(shellProcess, SIGNAL( wroteToStdin() ),    this, SLOT( wroteToStdin() ) );
+  // catch signals from launched modifyLaProc
+  connect(modifyLaProc, SIGNAL( readyReadStdout() ), this, SLOT( readFromStdout() ) );
+  connect(modifyLaProc, SIGNAL( readyReadStderr() ), this, SLOT( readFromStderr() ) );
+  connect(modifyLaProc, SIGNAL( processExited() ), this, SLOT( checkModifyLaResult() ) );
+  // catch signals from launched checkFLibProc
+  connect(checkFLibProc, SIGNAL( processExited() ), this, SLOT( checkFLibResult() ) );
 
   // create validation thread
   myThread = new ProcessThread( this );
@@ -589,63 +642,119 @@ SALOME_InstallWizard::SALOME_InstallWizard(const QString& aXmlFileName,
 SALOME_InstallWizard::~SALOME_InstallWizard()
 {
   shellProcess->kill(); // kill it for sure
-  QString script = "kill -9 ";
   int PID = (int)shellProcess->processIdentifier();
   if ( PID > 0 ) {
-    script += QString::number( PID );
-    script += " > /dev/null";
-    ___MESSAGE___( "script: " << script.latin1() );
-    if ( system( script.latin1() ) ) {
+    Script script;
+    script << "kill -9" << QString::number( PID );
+#ifdef USE_DEV_NULL
+    script << ">& /dev/null";
+#endif
+    ___MESSAGE___( "script: " << script.script().latin1() );
+    if ( system( script.script().latin1() ) ) {
+      // error
     }
   }
   delete myThread;
 }
 // ================================================================
+/*!
+ *  SALOME_InstallWizard::getBasePlatform
+ *  Determine the base platform for binaries installation
+ */
+// ================================================================
+QString SALOME_InstallWizard::getBasePlatform()
+{
+  QString aBasePlt = "";
+  if ( platformsMap.find( curPlatform ) != platformsMap.end() )
+    aBasePlt = curPlatform;
+  else
+    aBasePlt = commonPlatform;
+  return aBasePlt;
+}
+// ================================================================
 /*!
  *  SALOME_InstallWizard::currentPlatform
  *  Tries to determine the current user's operating system
  */
 // ================================================================
-QString SALOME_InstallWizard::currentPlatform()
+QStringList SALOME_InstallWizard::currentPlatform()
 {
   // file parsing
-  QString curOS = "";
+  QString platName, platVersion, platArch;
   QString osFileName = "/etc/issue";
   if ( QFile::exists( osFileName ) ) {
     QFile file( osFileName );
     if ( file.open( IO_ReadOnly ) ) {
       QTextStream stream( &file );
-      QString str = stream.readLine();
+      QStringList lines = QStringList::split( "\n", stream.read() );
       file.close();
-      // line parsing
-      QString pltName = "", platVersion = "", platBit = "";
-      QRegExp rx( "(.*)[L|l]inux.*release\\s+([\\d.]*)" );
-//       str = "Debian GNU/Linux 3.1 \n \l";
-//       str = "Red Hat Enterprise Linux WS release 4 (Nahant)";
-//       str = "Mandriva Linux release 2006.0 (Official) for x86_64";
-      int pos = rx.search( str );
-      if ( pos == -1 ) {// Debian case
-       rx = QRegExp( "(.*)GNU/Linux\\s+([\\d.]*)" );
-       pos = rx.search( str );
-      }
-      if ( pos > -1 ) {
-       pltName = rx.cap( 1 );
-       platVersion = rx.cap( 2 );
-       rx = QRegExp( "x86_64" );
-       pos = rx.search( str );
-       if ( pos > -1 )
-         platBit = "_64";
-       curOS = pltName + platVersion + platBit;
+      for ( uint i = 0; i < lines.count(); i++ ) {
+       QString str = lines[i];
+        if ( str.isEmpty() ) continue;
+        // parse line
+        QRegExp regvar = QRegExp( "(.*)\\s+[^\\s]*[R|r]elease[^\\s]*\\s+([\\d.]*)" );
+        int pos = regvar.search( str );
+        if ( pos == -1 ) {
+         regvar = QRegExp( "(.*)\\s+[^\\s]*[L|l][I|i][N|n][U|u][X|x][^\\s]*(.*)\\s+([\\d.]*)\\s+" );
+         pos = regvar.search( str );
+        }
+        if ( pos >= 0 ) {
+         QStringList name;
+         for ( int i = 1; i < regvar.numCaptures(); i++ )
+           name.append( regvar.cap( i ) );
+
+         // retrieve platform name
+         platName = QStringList::split( " ", name.join( " " ) ).join( " " );
+         platName = platName.replace( "Linux", "" ).replace( "linux", "" ).replace( "LINUX", "" ).stripWhiteSpace();
+         platName = platName.replace( "Welcome to", "" ).stripWhiteSpace();
+          platName = QStringList::split( " ", platName ).join( " " );
+         // retrieve platform version number
+         platVersion = regvar.cap( regvar.numCaptures() );
+         // retrieve platform 
+         utsname uname_data;
+         uname( &uname_data );
+         if ( QString( uname_data.machine ) == "x86_64" )
+           platArch = "64bit";
+          break;
+        }
       }
     }
   }
-  //   return curOS.remove( " " );
-  QString str( " " );
-  int index = 0;
-  while ( (index = curOS.find( str, index, true)) != -1 )
-    curOS.remove( index, str.length() );
-  return curOS;
+  QStringList vals;
+  if ( !platName.isEmpty() )    vals.append( platName ); 
+  if ( !platVersion.isEmpty() ) vals.append( platVersion ); 
+  if ( !platArch.isEmpty() )    vals.append( platArch ); 
+  return vals;
+}
+
+// ================================================================
+/*!
+ *  SALOME_InstallWizard::rootDirPath
+ *  Get application root dir
+ */
+// ================================================================
+QString SALOME_InstallWizard::rootDirPath()
+{
+  static QString rootDir;
+  if ( rootDir.isEmpty() ) {
+    QDir appDir( qApp->applicationDirPath() );
+    appDir.cdUp();
+    rootDir = appDir.absPath();
+  }
+  return rootDir;
+}
+
+// ================================================================
+/*!
+ *  SALOME_InstallWizard::getPlatformBinPath
+ *  Get platform binaries path
+ */
+// ================================================================
+QString SALOME_InstallWizard::getPlatformBinPath( const QString& plt ) const
+{
+  return QDir::cleanDirPath( getBinPath() + "/" + QStringList::split( " ", plt ).join( "_" ) );
 }
+
 // ================================================================
 /*!
  *  SALOME_InstallWizard::getXmlMap
@@ -653,17 +762,20 @@ QString SALOME_InstallWizard::currentPlatform()
  *  corresponding XML files.
  */
 // ================================================================
-MapXmlFiles SALOME_InstallWizard::getXmlMap( const QString& xmlFileName )
+MapXmlFiles SALOME_InstallWizard::getXmlMap( const QString& aXmlFileName )
 {
   MapXmlFiles xmlMap;
   QStringList xmlList;
-  if ( xmlFileName )
-    xmlList.append( xmlFileName );
+  if ( !aXmlFileName.isEmpty() )
+    xmlList.append( QFileInfo( aXmlFileName ).absFilePath() );
   else {
-    QDir dir( QDir::currentDirPath() );
-    xmlList = dir.entryList( "*.xml", QDir::Files | QDir::Readable );
+    QDir dir( rootDirPath() );
+    QStringList entries = dir.entryList( "*.xml", QDir::Files | QDir::Readable );
+    if ( entries.remove( "config.xml" ) )
+      entries.append( "config.xml" );
+    for ( uint i = 0; i < entries.count(); i++ )
+      xmlList.append( QDir( rootDirPath() ).filePath( entries[i] ) ); 
   }
-//   cout << xmlList.join(",") << endl;
   // XML files parsing
   QFile file;
   QDomDocument doc( "xml_doc" );
@@ -692,11 +804,10 @@ MapXmlFiles SALOME_InstallWizard::getXmlMap( const QString& xmlFileName )
        platforms = elem.attribute( "platforms" ).stripWhiteSpace();
        QStringList platList = QStringList::split( ",", platforms );
        for ( uint j = 0; j < platList.count(); j++ ) {
-         if ( !platList[j].isEmpty() && xmlMap.find( platList[j] ) == xmlMap.end() )
+         QString platform = platList[j].stripWhiteSpace();
+         if ( !platform.isEmpty() && xmlMap.find( platform ) == xmlMap.end() )
            xmlMap[ platList[j] ] = xmlList[i];
        }
-//     if ( !curPlatform.isEmpty() && xmlMap.find( curPlatform ) != xmlMap.end() )
-//       return xmlMap;
       }
     }
   }
@@ -711,12 +822,18 @@ MapXmlFiles SALOME_InstallWizard::getXmlMap( const QString& xmlFileName )
 void SALOME_InstallWizard::getXmlAndPlatform()
 {
   MapXmlFiles xmlMap;
-  if ( xmlFileName.isNull() ) {
+  if ( xmlFileName.isEmpty() ) {
     xmlMap = getXmlMap();
     if ( !curPlatform.isEmpty() ) {
       // try to get XML file for current platform
-      if ( xmlMap.find( curPlatform ) != xmlMap.end() )
+      if ( xmlMap.find( curPlatform ) != xmlMap.end() ) {
        xmlFileName = xmlMap[ curPlatform ];
+       QFileInfo fibp( getPlatformBinPath( curPlatform ) );
+       if ( !fibp.isDir() ) {
+         warnMsg = tr( "Binaries are absent for current platform" );
+       }
+       platformsMap = xmlMap;
+      }
       else {
        platformsMap = xmlMap;
        warnMsg = tr( "Your Linux platform is not supported by this SALOME package" );
@@ -725,7 +842,7 @@ void SALOME_InstallWizard::getXmlAndPlatform()
     else {
       // get all supported platforms
       platformsMap = xmlMap;
-      warnMsg = tr( "Install Wizard can't define your Linux platform" );
+      warnMsg = tr( "Installation Wizard can't identify target Linux platform" );
     }
   }
   else {
@@ -739,6 +856,9 @@ void SALOME_InstallWizard::getXmlAndPlatform()
          platformsMap.insert( it.key(), it.data(), true );
        warnMsg = tr( "The given configuration file doesn't support your Linux platform" );
       }
+      else {
+       platformsMap = xmlMap;
+      }
     }
     else {
       // get all supported platforms
@@ -746,7 +866,7 @@ void SALOME_InstallWizard::getXmlAndPlatform()
       MapXmlFiles::Iterator it;
       for ( it = xmlMap.begin(); it != xmlMap.end(); ++it )
        platformsMap.insert( it.key(), it.data(), true );
-      warnMsg = tr( "Install Wizard can't define your Linux platform" );
+      warnMsg = tr( "Installation Wizard can't define your Linux platform" );
     }
   }
 }
@@ -807,7 +927,7 @@ void SALOME_InstallWizard::setupIntroPage()
   // create logo picture
   logoLab = new QLabel( introPage );
   logoLab->setPixmap( pixmap( pxBigLogo ) );
-  logoLab->setScaledContents( false );
+  logoLab->setScaledContents( true );
   logoLab->setFrameStyle( QLabel::Plain | QLabel::NoFrame );
   logoLab->setAlignment( AlignCenter );
   // create version box
@@ -942,10 +1062,6 @@ void SALOME_InstallWizard::setupTypePage()
 // ================================================================
 void SALOME_InstallWizard::setupPlatformPage()
 {
-  // create page or not?
-  if ( platformsMap.isEmpty() )
-    return;
-
   // create page
   platformsPage = new QWidget( this, "PlatformsPage" );
   QGridLayout* pageLayout = new QGridLayout( platformsPage );
@@ -956,13 +1072,9 @@ void SALOME_InstallWizard::setupPlatformPage()
   QFont fnt = warnLab2->font();
   fnt.setBold( true );
   warnLab2->setFont( fnt );
-  if ( installType == Compile && platformsMap.find( curPlatform ) == platformsMap.end() )
-    warnMsg += tr( " and compilation is not tested on this one." );
-  else
-    warnMsg += ".";
   warnLab = new QLabel( warnMsg, platformsPage );
   warnLab->setAlignment( Qt::AlignHCenter | Qt::WordBreak );
-  QLabel* warnLab3 = new QLabel( tr( "If you want to proceed anyway, please select platform from the following list:" ), 
+  warnLab3 = new QLabel( tr( "If you want to proceed anyway, please select platform from the following list:" ), 
                                 platformsPage );
   warnLab3->setAlignment( Qt::AlignHCenter | Qt::WordBreak );
   // create button group
@@ -1119,11 +1231,22 @@ void SALOME_InstallWizard::setupProductsPage()
   sizeLayout->addWidget( requiredTemp,  1, 1 );
   sizeLayout->addWidget( reqLab3,       2, 0 );
   sizeLayout->addWidget( availableSize, 2, 1 );
+  // ... 'single installation directory' check-boxes
+  oneModDirBtn = new QMyCheckBox( tr( "Install modules to a single directory" ), productsPage );
+  setAboutInfo( oneModDirBtn, tr( "Check this box if you want to install binaries of\nthe selected SALOME modules into a single directory" ) );
+  oneProdDirBtn = new QMyCheckBox( tr( "Install prerequisites to a single directory" ), productsPage );
+  setAboutInfo( oneProdDirBtn, tr( "Check this box if you want to install binaries of\nthe selected prerequisites into a single directory" ) );
+  oneProdDirBtn->hide(); // temporarily! waiting for correct prerequisites availability
+  QFrame* split_line = new QFrame( productsPage, "split_line" );
+  split_line->setFrameStyle( QFrame::HLine | QFrame::Sunken );
 
   // layout common widgets
-  pageLayout->addMultiCellLayout( leftBoxLayout, 0, 1, 0, 0 );
+  pageLayout->addMultiCellLayout( leftBoxLayout, 0, 4, 0, 0 );
   pageLayout->addWidget         ( productInfo,   0,    1    );
   pageLayout->addLayout         ( sizeLayout,    1,    1    );
+  pageLayout->addWidget         ( split_line,    2,    1    );
+  pageLayout->addWidget         ( oneModDirBtn,  3,    1    );
+  pageLayout->addWidget         ( oneProdDirBtn, 4,    1    );
 
   // adding page
   addPage( productsPage, tr( "Choice of the products to be installed" ) );
@@ -1222,14 +1345,20 @@ void SALOME_InstallWizard::setupProgressPage()
   progressView = new ProgressView( widget );
   progressView->setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Expanding ) );
   progressView->setMinimumSize( 100, 10 );
+  // possibility to ignore all errors
+  ignoreErrCBox = new QCheckBox( tr( "Ignore errors" ), widget );
+  setAboutInfo( ignoreErrCBox, tr( "Check this option if you want to proceed installation \nprocess even there will be some errors" ) );
+  ignoreErrCBox->setChecked( false );
+  // product installation status bar
   statusLab = new QLabel( widget );
   statusLab->setFrameShape( QButtonGroup::LineEditPanel );
   setAboutInfo( progressView, tr( "Installation status on the selected products" ) );
   // layouting
   layout->addRowSpacing( 0, 6 );
-  layout->addWidget( resultLab,    1, 0 );
-  layout->addWidget( progressView, 2, 0 );
-  layout->addWidget( statusLab,    3, 0 );
+  layout->addWidget( resultLab,     1, 0 );
+  layout->addWidget( progressView,  2, 0 );
+  layout->addWidget( ignoreErrCBox, 3, 0 );
+  layout->addWidget( statusLab,     4, 0 );
   // layouting
   pageLayout->addWidget( splitter,  0, 0 );
   // adding page
@@ -1269,7 +1398,7 @@ void SALOME_InstallWizard::setupReadmePage()
   pageLayout->addLayout( hLayout );
 
   // loading README file
-  QString readmeFile = QDir::currentDirPath() + "/README";
+  QString readmeFile = QDir( rootDirPath() ).filePath( "README" );
   QString text;
   if ( readFile( readmeFile, text ) )
     readme->setText( text );
@@ -1350,26 +1479,45 @@ bool SALOME_InstallWizard::acceptData( const QString& pageTitle )
   QWidget* aPage = InstallWizard::page( pageTitle );
   if ( aPage == typePage ) {
     // installation type page
+    warnLab3->show();
+    this->setAppropriate( platformsPage, false );
     if ( installType == Binaries ) { // 'Binary' installation type
       // check binaries directory
       QFileInfo fib( QDir::cleanDirPath( getBinPath() ) );
-      if ( !fib.exists() ) {
+      if ( !fib.isDir() ) {
        QMessageBox::warning( this,
                              tr( "Warning" ),
                              tr( "The directory %1 doesn't exist.\n"
-                                 "This directory must contain sources archives.\n").arg( fib.absFilePath() ),
+                                 "This directory must contains another one directory with binary archives for current platform.").arg( fib.absFilePath() ),
                              QMessageBox::Ok,
                              QMessageBox::NoButton, 
                              QMessageBox::NoButton );
        return false;
       }
+      if ( platformsMap.find( curPlatform ) == platformsMap.end() ) {
+       // Unknown platform case
+       QString aMsg = warnMsg + tr( ".\nBy default the universal binary package will be installed." );
+       aMsg += tr( "\nIf you want to select another one, please use the following list:" );
+       warnLab->setText( aMsg );
+       warnLab3->hide();
+       this->setAppropriate( platformsPage, true );
+      }
+      else {
+       // Supported platform case
+       QFileInfo fibp( getPlatformBinPath( curPlatform ) );
+       if ( !fibp.isDir() ) {
+         warnLab->setText( tr( "Binaries are absent for current platform." ) );
+         this->setAppropriate( platformsPage, true );
+       }
+      }
+
       // check sources directory
       QFileInfo fis( QDir::cleanDirPath( getSrcPath() ) );
-      if ( !fis.exists() )
+      if ( !fis.isDir() )
        if ( QMessageBox::warning( this,
                                   tr( "Warning" ),
                                   tr( "The directory %1 doesn't exist.\n"
-                                      "This directory must contain sources archives.\n"
+                                      "This directory must contains sources archives.\n"
                                       "Continue?" ).arg( fis.absFilePath() ),
                                   tr( "&Yes" ),
                                   tr( "&No" ), 
@@ -1379,21 +1527,73 @@ bool SALOME_InstallWizard::acceptData( const QString& pageTitle )
     else { // 'Source' or 'Compile' installation type
       // check sources directory
       QFileInfo fis( QDir::cleanDirPath( getSrcPath() ) );
-      if ( !fis.exists() ) {
+      if ( !fis.isDir() ) {
        QMessageBox::warning( this,
                              tr( "Warning" ),
                              tr( "The directory %1 doesn't exist.\n"
-                                 "This directory must contain sources archives.\n" ).arg( fis.absFilePath() ),
+                                 "This directory must contains sources archives.\n" ).arg( fis.absFilePath() ),
                              QMessageBox::Ok,
                              QMessageBox::NoButton, 
                              QMessageBox::NoButton );
        return false;
       }
+      else if ( !QDir( fis.filePath(), "*.tar.gz" ).count() ) {
+       QMessageBox::warning( this,
+                             tr( "Warning" ),
+                             tr( "The directory %1 doesn't contain source archives.\n" ).arg( fis.absFilePath() ),
+                             QMessageBox::Ok,
+                             QMessageBox::NoButton, 
+                             QMessageBox::NoButton );
+       return false;
+      }
+      if ( platformsMap.find( curPlatform ) == platformsMap.end() ) {
+       QString aMsg = warnMsg + ".";
+       if ( installType == Compile )
+         aMsg = warnMsg + tr( " and compilation is not tested on this one." );
+       warnLab->setText( aMsg );
+       this->setAppropriate( platformsPage, true );
+      }
     }
   }
 
-  else if ( aPage == dirPage ) {
+  else if ( aPage == platformsPage ) {
     // installation platform page
+    if ( platBtnGrp->id( platBtnGrp->selected() ) == -1 ) {
+      QMessageBox::warning( this,
+                           tr( "Warning" ),
+                           tr( "Select installation platform before" ),
+                           QMessageBox::Ok,
+                           QMessageBox::NoButton,
+                           QMessageBox::NoButton );
+      return false;
+    }
+    else if ( installType == Binaries ) {
+      QString aPlatform = platBtnGrp->selected()->name();
+      QFileInfo fib( getPlatformBinPath( aPlatform ) );
+      if ( !fib.isDir() ) {
+       QMessageBox::warning( this,
+                             tr( "Warning" ),
+                             tr( "The directory %1 doesn't exist.\n"
+                                 "This directory must contains binary archives.\n" ).arg( fib.absFilePath() ),
+                             QMessageBox::Ok,
+                             QMessageBox::NoButton, 
+                             QMessageBox::NoButton );
+       return false;
+      }
+      else if ( QDir( fib.filePath(), "*.tar.gz" ).count() == 0 ) {
+       QMessageBox::warning( this,
+                             tr( "Warning" ),
+                             tr( "The directory %1 doesn't contain binary archives.\n" ).arg( fib.absFilePath() ),
+                             QMessageBox::Ok,
+                             QMessageBox::NoButton, 
+                             QMessageBox::NoButton );
+       return false;
+      }
+    }
+  }
+
+  else if ( aPage == dirPage ) {
+    // installation directory page
     // ########## check target and temp directories (existence and available disk space)
     // get dirs
     QString targetDir = QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() );
@@ -1409,7 +1609,7 @@ bool SALOME_InstallWizard::acceptData( const QString& pageTitle )
       return false;
     }
     QFileInfo fi( QDir::cleanDirPath( targetDir ) );
-    if ( !fi.exists() ) {
+    if ( !fi.isDir() ) {
       bool toCreate =
        QMessageBox::warning( this,
                              tr( "Warning" ),
@@ -1443,7 +1643,7 @@ bool SALOME_InstallWizard::acceptData( const QString& pageTitle )
     if ( !fi.isWritable() ) {
       QMessageBox::warning( this,
                             tr( "Warning" ),
-                            tr( "The directory %1 is not writeable.\n"
+                            tr( "The directory %1 is not writable.\n"
                                "Please, enter valid target directory path or change permissions" ).arg( fi.absFilePath() ),
                             QMessageBox::Ok,
                             QMessageBox::NoButton,
@@ -1501,13 +1701,13 @@ bool SALOME_InstallWizard::acceptData( const QString& pageTitle )
       return false;
     }
     // run script that checks available disk space for installing of products    // returns 1 in case of error
+    QDir rd( rootDirPath() );
     QFileInfo fi( QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() ) );
-    QString script = "./config_files/checkSize.sh '";
-    script += fi.absFilePath();
-    script += "' ";
-    script += QString( "%1" ).arg( totSize );
-    ___MESSAGE___( "script = " << script.latin1() );
-    if ( system( script ) ) {
+    Script script;
+    script << QUOTE( rd.filePath( "config_files/checkSize.sh" ) );
+    script << QUOTE( fi.absFilePath() ) << QString::number( totSize );
+    ___MESSAGE___( "script = " << script.script().latin1() );
+    if ( system( script.script().latin1() ) ) {
       QMessageBox::critical( this,
                              tr( "Out of space" ),
                              tr( "There is no available disk space for installing of selected products" ),
@@ -1521,12 +1721,11 @@ bool SALOME_InstallWizard::acceptData( const QString& pageTitle )
     // run script that check available disk space for temporary files
     // returns 1 in case of error
     QFileInfo fit( QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) );
-    QString tscript = "./config_files/checkSize.sh '";
-    tscript += fit.absFilePath();
-    tscript += "' ";
-    tscript += QString( "%1" ).arg( tempSize );
-    ___MESSAGE___( "script = " << tscript.latin1() );
-    if ( system( tscript ) ) {
+    Script tscript;
+    tscript << QUOTE( rd.filePath( "config_files/checkSize.sh" ) );
+    tscript << QUOTE( fit.absFilePath() ) << QString::number( tempSize );
+    ___MESSAGE___( "script = " << tscript.script().latin1() );
+    if ( system( tscript.script().latin1() ) ) {
       QMessageBox::critical( this,
                             tr( "Out of space" ),
                             tr( "There is no available disk space for the temporary files" ),
@@ -1562,11 +1761,12 @@ bool SALOME_InstallWizard::acceptData( const QString& pageTitle )
          }
          // check installation script existence
          else {
-           QFileInfo fi( QString("./config_files/") + item->text(2) );
+           QDir rd( rootDirPath() );
+           QFileInfo fi( rd.filePath( QString( "config_files/%1" ).arg( item->text(2) ) ) );
            if ( !fi.exists() || !fi.isExecutable() ) {
              QMessageBox::warning( this,
                                    tr( "Error" ),
-                                   tr( "The script %1 required for %2 doesn't exist or doesn't have execute permissions.").arg("./config_files/" + item->text(2)).arg(item->text(0)),
+                                   tr( "The script %1 required for %2 doesn't exist or doesn't have execute permissions.").arg(fi.filePath()).arg(item->text(0)),
                                    QMessageBox::Ok,
                                    QMessageBox::NoButton,
                                    QMessageBox::NoButton );
@@ -1647,28 +1847,129 @@ void SALOME_InstallWizard::updateAvailableSpace()
     availableSize->setText( diskSpaceProc->readLineStdout() + " KB");
 }
 // ================================================================
+/*!
+ *  SALOME_InstallWizard::runModifyLaFiles
+ *  Run the modification of SALOME *.la files
+ */
+// ================================================================
+void SALOME_InstallWizard::runModifyLaFiles()
+{
+  modifyLaProc->clearArguments();
+  // ... update status label
+  statusLab->setText( tr( "Modification of *.la files of SALOME modules..." ) );
+  // set process arguments
+  modifyLaProc->setWorkingDirectory( QDir( rootDirPath() ).filePath( "config_files" ) );
+  modifyLaProc->addArgument( "modifyLaFiles.sh" );
+  modifyLaProc->addArgument( "modify_la_files" );
+  modifyLaProc->addArgument( QDir::cleanDirPath( QFileInfo( targetFolder->text().stripWhiteSpace() ).absFilePath() ) );
+  // ... run script
+  if ( !modifyLaProc->start() )
+    ___MESSAGE___( "Error: process could not start!" );
+}
+// ================================================================
+/*!
+ *  SALOME_InstallWizard::checkModifyLaResult
+ *  Slot to take result of modification SALOME *.la files
+ */
+// ================================================================
+void SALOME_InstallWizard::checkModifyLaResult()
+{
+  if ( modifyLaProc->normalExit() && modifyLaProc->exitStatus() == 1 )
+    runCheckFLib();
+  else {
+    // abort of the current installation
+    abort();
+    statusLab->setText( tr( "Installation has been aborted" ) );
+    QMessageBox::critical( this,
+                          tr( "Error" ),
+                          tr( "Modification of *.la SALOME files has not been completed."),
+                          QMessageBox::Ok,
+                          QMessageBox::NoButton,
+                          QMessageBox::NoButton );
+    // enable <Next> button
+    setNextEnabled( true );
+    doPostActions( tr( "&Start" ), tr( "Start installation process" ) );
+    connect(    this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
+    // enable <Back> button
+    setBackEnabled( true );
+  }
+}
+// ================================================================
+/*!
+ *  SALOME_InstallWizard::runCheckFLib
+ *  Run the Fortran and other required libraries checking
+ */
+// ================================================================
+void SALOME_InstallWizard::runCheckFLib()
+{
+  // Check Fortran libraries
+  checkFLibProc->clearArguments();
+  // ... update status label
+  statusLab->setText( tr( "Check Fortran and other required libraries..." ) );
+  // ... search "not found" libraries
+  checkFLibProc->setWorkingDirectory( QDir( rootDirPath() ).filePath( "config_files" ) );
+  checkFLibProc->addArgument( "checkFortran.sh" );
+  checkFLibProc->addArgument( "find_libraries" );
+  checkFLibProc->addArgument( QDir::cleanDirPath( QFileInfo( targetFolder->text().stripWhiteSpace() ).absFilePath() ) );
+  // ... run script
+  if ( !checkFLibProc->start() )
+    ___MESSAGE___( "Error: process could not start!" );
+}
+// ================================================================
 /*!
  *  SALOME_InstallWizard::checkFLibResult
- *  Slot to take result of Fortran libraries checking
+ *  Slot to take result of Fortran and other required libraries checking
  */
 // ================================================================
 void SALOME_InstallWizard::checkFLibResult()
 {
   if ( checkFLibProc->normalExit() && checkFLibProc->exitStatus() == 1 ) {
-    QStringList notFoundLibsList;
+    QStringList notFoundLibsList, notFoundOptLibsList;
     QString record = "";
+    QStringList prefOptLibs = getOptionalLibs();
+    // create list of strings with all 'not found' libraries
     while ( checkFLibProc->canReadLineStdout() ) {
-      record = checkFLibProc->readLineStdout();
-      if ( !record.isEmpty() && !notFoundLibsList.contains( record ) )
-       notFoundLibsList.append( record );
-    }
-    QMessageBox::warning( this,
-                         tr( "Warning" ),
-                         tr( "The following libraries are absent on current system:\n"
-                         "%1").arg( notFoundLibsList.join( "\n" ) ),
-                         QMessageBox::Ok,
-                         QMessageBox::NoButton,
-                         QMessageBox::NoButton );
+      record = checkFLibProc->readLineStdout().stripWhiteSpace();
+      if ( !record.isEmpty() ) {
+       record = QStringList::split( " ", record )[0];
+       if ( !notFoundLibsList.contains( record ) && 
+            !notFoundOptLibsList.contains( record ) ) {
+         bool isOptional = false;
+         QStringList::Iterator it_opt;
+         for ( it_opt = prefOptLibs.begin(); it_opt != prefOptLibs.end(); ++it_opt )
+           if ( record.startsWith( (*it_opt).stripWhiteSpace(), false ) ) {
+             isOptional = true;
+             break;
+           }
+         isOptional ? notFoundOptLibsList.append( record )             \
+           : notFoundLibsList.append( record );
+       }
+      }
+    }
+    QString msg = tr( "Some libraries are absent!<br><br>" );
+    if ( !notFoundLibsList.isEmpty() ) {
+      msg += tr( "One or several <b>mandatory</b> libraries listed below are not found. SALOME <u>may not work</u> properly.<br>" );
+      msg += notFoundLibsList.join( "<br>" );
+      msg += "<br><br>";
+    }
+    if ( !notFoundOptLibsList.isEmpty() ) {
+      msg += tr( "One or several <b>optional</b> libraries listed below are not found. This <u>does not affect</u> on the correct work of SALOME platform.<br>" );
+      msg += notFoundOptLibsList.join( "<br>" );
+    }
+    if ( !notFoundLibsList.isEmpty() )
+      QMessageBox::warning( this,
+                           tr( "Warning" ),
+                           msg,
+                           QMessageBox::Ok,
+                           QMessageBox::NoButton,
+                           QMessageBox::NoButton );
+    else if ( !notFoundOptLibsList.isEmpty() )
+      QMessageBox::information( this,
+                               tr( "Information" ),
+                               msg,
+                               QMessageBox::Ok,
+                               QMessageBox::NoButton,
+                               QMessageBox::NoButton );
   }
   // Update GUI and check installation errors
   completeInstallation();
@@ -1734,8 +2035,8 @@ void SALOME_InstallWizard::checkProductPage()
   QFileInfo fi( QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() ) );
   if ( fi.exists() ) {
     diskSpaceProc->clearArguments();
-    QString script = "./config_files/diskSpace.sh";
-    diskSpaceProc->addArgument( script );
+    diskSpaceProc->setWorkingDirectory( QDir( rootDirPath() ).filePath( "config_files" ) );
+    diskSpaceProc->addArgument( "diskSpace.sh" );
     diskSpaceProc->addArgument( fi.absFilePath() );
     // run script
     diskSpaceProc->start();
@@ -1758,8 +2059,10 @@ void SALOME_InstallWizard::setPrerequisites( QCheckListItem* item )
     return;
   // get all prerequisites
   QStringList dependOn = productsMap[ item ].getDependancies();
-  // install MED without GUI case
-  if ( installGuiBtn->state() != QButton::On && item->text(0) == "MED" ) {
+  // install SALOME without GUI case
+  if ( installGuiBtn->state() != QButton::On && 
+       woGuiModules.find( item->text(0) ) != woGuiModules.end() && 
+       woGuiModules[item->text(0)] == True ) {
     dependOn.remove( "GUI" );
   }
   // setting prerequisites
@@ -1773,6 +2076,7 @@ void SALOME_InstallWizard::setPrerequisites( QCheckListItem* item )
          itProd.key()->setOn( true );
          itProd.key()->setEnabled( false );
        }
+       break;
       }
     }
   }
@@ -1796,10 +2100,6 @@ void SALOME_InstallWizard::unsetPrerequisites( QCheckListItem* item )
   for ( itProd = productsMap.begin(); itProd != productsMap.end(); ++itProd ) {
     if ( itProd.data().getType() == productsMap[ item ].getType() ) {
       QStringList dependOn = itProd.data().getDependancies();
-      // install MED without GUI case
-      if ( installGuiBtn->state() != QButton::On && itemName == "GUI" ) {
-       dependOn.remove( "MED" );
-      }
       for ( int i = 0; i < (int)dependOn.count(); i++ ) {
        if ( dependOn[ i ] == itemName ) {
          if ( itProd.key()->isOn() ) {
@@ -1827,6 +2127,7 @@ void SALOME_InstallWizard::unsetPrerequisites( QCheckListItem* item )
              for ( int k = 0; k < (int)prereqsList.count(); k++ ) {
                if ( prereqsList[ k ] == itProd1.data().getName() ) {
                  nbDependents++;
+                 break;
                }
              }
            }
@@ -1836,6 +2137,7 @@ void SALOME_InstallWizard::unsetPrerequisites( QCheckListItem* item )
            itProd1.key()->setOn( false );
          }
        }
+       break;
       }
     }
   }
@@ -1869,38 +2171,39 @@ void SALOME_InstallWizard::launchScript()
     progressView->setStatus( prodProc, Processing );
     progressView->ensureVisible( prodProc );
     
-    QCheckListItem* item;
-    if ( prodProc != "gcc" )
-      item = findItem( prodProc );
+    QCheckListItem* item = 0;
     // fill in script parameters
     shellProcess->clearArguments();
     // ... script name
-    shellProcess->setWorkingDirectory( QDir::cleanDirPath( QFileInfo( "./config_files/" ).absFilePath() ) );
-    if ( prodProc != "gcc" )
+    shellProcess->setWorkingDirectory( QDir( rootDirPath() ).filePath( "config_files" ) );
+    if ( !extraProducts.contains( prodProc ) ) {
+      item = findItem( prodProc );
       shellProcess->addArgument( item->text(2) );
+    }
     else
-      shellProcess->addArgument( "gcc-common.sh" );
+      shellProcess->addArgument( extraProducts[ prodProc ] );
 
+    // ... get folder with binaries
+    QString OS = getPlatform();
+    if ( refPlatform.isEmpty() && platformsMap.find( curPlatform ) == platformsMap.end() )
+      OS = commonPlatform;
+    QString binDir = getPlatformBinPath( OS );
     // ... temp folder
     QString tmpFolder = QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + TEMPDIRNAME;
     //if( !tempFolder->isEnabled() )
     //  tmpFolder = "/tmp";
 
     // ... not install : try to find preinstalled
-    if ( !progressView->isVisible( prodProc ) ) {
+    if ( notInstall.contains( prodProc ) || prodProc == "gcc" ) {
       shellProcess->addArgument( "try_preinstalled" );
       shellProcess->addArgument( QFileInfo( tmpFolder ).absFilePath() );
-      shellProcess->addArgument( QDir::currentDirPath() + "/Products" );
+      shellProcess->addArgument( QDir( rootDirPath() ).filePath( "Products" ) );
       statusLab->setText( tr( "Collecting environment for '" ) + prodProc + "'..." );
     }
     // ... binaries ?
     else if ( installType == Binaries ) {
       shellProcess->addArgument( "install_binary" );
       shellProcess->addArgument( QFileInfo( tmpFolder ).absFilePath() );
-      QString binDir = QDir::cleanDirPath( getBinPath() );
-      QString OS = getPlatform();
-      if ( !OS.isEmpty() )
-       binDir += "/" + OS;
       shellProcess->addArgument( binDir );
       statusLab->setText( tr( "Installing '" ) + prodProc + "'..." );
     }
@@ -1916,15 +2219,15 @@ void SALOME_InstallWizard::launchScript()
     QString tgtFolder = QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() );
     shellProcess->addArgument( QFileInfo( tgtFolder ).absFilePath() );
     // ... list of all products
-    QString depproducts = DefineDependeces(productsMap);
-    depproducts.prepend( "gcc " );
+    QString depproducts = getAllProducts(productsMap);
+    depproducts.prepend( QStringList( extraProducts.keys() ).join(" ") + " " );
     ___MESSAGE___( "Dependancies"<< depproducts.latin1() );
     shellProcess->addArgument( depproducts );
     // ... product name - currently installed product
-    if ( prodProc != "gcc" )
+    if ( !extraProducts.contains( prodProc ) )
       shellProcess->addArgument( item->text(0) );
     else
-      shellProcess->addArgument( "gcc" );
+      shellProcess->addArgument( prodProc );
     // ... list of products being installed
     shellProcess->addArgument( prodSequence.join( " " ) );
     // ... sources directory
@@ -1934,62 +2237,87 @@ void SALOME_InstallWizard::launchScript()
       shellProcess->addArgument( "TRUE" );
     else 
       shellProcess->addArgument( "FALSE" );
-    // ... install MED with GUI or not?
-    if ( installGuiBtn->state() != QButton::On && prodProc == "MED" && 
-        (installType == Binaries || installType == Compile) )
-      shellProcess->addArgument( "FALSE" );
+    // ... binaries directory
+    shellProcess->addArgument( binDir );
+    // ... install SALOME with GUI or not?
+    if ( woGuiModules.find( prodProc ) != woGuiModules.end() )
+      ( installGuiBtn->state() != QButton::On && woGuiModules[ prodProc ] == True ) ? 
+       shellProcess->addArgument( "FALSE" ) : 
+       shellProcess->addArgument( "TRUE" );
+    // ... single installation directory for SALOME modules, if this option was selected
+    if ( oneModDirBtn->isChecked() ) {
+      MapProducts::Iterator mapIter;
+      for ( mapIter = productsMap.begin(); mapIter != productsMap.end(); ++mapIter )
+       if ( mapIter.data().getName() == prodProc && mapIter.data().getType() == "component" ) {
+         shellProcess->addArgument( "TRUE" );
+         break;
+       }
+    }
+    // ... single installation directory for prerequisites, if this option was selected
+    if ( oneProdDirBtn->isChecked() ) {
+      if ( prodProc == "DebianLibsForSalome" )
+       shellProcess->addArgument( oneProdDirName );
+      else {
+       MapProducts::Iterator mapIter;
+       for ( mapIter = productsMap.begin(); mapIter != productsMap.end(); ++mapIter )
+         if ( mapIter.data().getName() == prodProc && mapIter.data().getType() == "prerequisite" ) {
+           shellProcess->addArgument( oneProdDirName );
+           break;
+         }
+      }
+    }
+    
     // run script
     if ( !shellProcess->start() ) {
       // error handling can be here
+      QStringList args = shellProcess->arguments();
       ___MESSAGE___( "error" );
+      ___MESSAGE___( "cmd: " << args.join(" ").latin1() );
     }
     return;
   }
+
+  // else try to find aborted product
+  prodProc = progressView->findStatus( Aborted );
+  if ( !prodProc.isNull() )
+    return; // installation has been aborted
+
   ___MESSAGE___( "All products have been installed successfully" );
   // all products are installed successfully
   MapProducts::Iterator mapIter;
   ___MESSAGE___( "starting pick-up environment" );
-  QString depproducts = QUOTE( DefineDependeces(productsMap).prepend( "gcc " ) );
+  QString depproducts = QUOTE( getAllProducts(productsMap).prepend( QStringList( extraProducts.keys() ).join(" ") + " " ) );
   for ( mapIter = productsMap.begin(); mapIter != productsMap.end(); ++mapIter ) {
     QCheckListItem* item = mapIter.key();
     Dependancies dep = mapIter.data();
     if ( item->isOn() && dep.pickUpEnvironment() ) {
       statusLab->setText( tr( "Pick-up products environment for " ) + dep.getName().latin1() + "..." );
       ___MESSAGE___( "... for " << dep.getName().latin1() );
-      QString script;
-      script += "cd " + QUOTE( QFileInfo( QDir::cleanDirPath( "./config_files/" ) ).absFilePath() ) + "; ";
-      script += item->text(2) + " ";
-      script += "pickup_env ";
-      script += QUOTE( QFileInfo( QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + TEMPDIRNAME ).absFilePath() ) + " ";
-      script += QUOTE( QFileInfo( QDir::cleanDirPath( QDir::currentDirPath() + "/Products" ) ).absFilePath() ) + " ";
-      script += QUOTE( QFileInfo( QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() ) ).absFilePath() ) + " ";
-      script += depproducts + " ";
-      script += item->text(0) + " ";
-      script += QUOTE( prodSequence.join( " " ) );
-      ___MESSAGE___( "... --> " << script.latin1() );
-      if ( system( script.latin1() ) ) {
+      QDir rd( rootDirPath() );
+      Script script;
+      script << "cd" << QUOTE( rd.filePath( "config_files" ) ) << ";";
+      script << item->text(2) << "pickup_env";
+      script << QUOTE( QFileInfo( QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + TEMPDIRNAME ).absFilePath() );
+      script << QUOTE( QFileInfo( QDir::cleanDirPath( QDir( rootDirPath() ).filePath( "Products" ) ) ).absFilePath() );
+      script << QUOTE( QFileInfo( QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() ) ).absFilePath() );
+      script << depproducts << item->text(0) << QUOTE( prodSequence.join( " " ) );
+      ___MESSAGE___( "... --> " << script.script().latin1() );
+      if ( system( script.script().latin1() ) ) {
        ___MESSAGE___( "ERROR" );
       }
     }
   }
-  
+
   if ( installType == Binaries ) {
-    // Check Fortran libraries
-    // ... update status label
-    statusLab->setText( tr( "Check Fortran libraries..." ) );
-    // ... search "not found" libraries
-    checkFLibProc->setWorkingDirectory( QDir::cleanDirPath( QFileInfo( "./config_files/" ).absFilePath() ) );
-    checkFLibProc->addArgument( "checkFortran.sh" );
-    checkFLibProc->addArgument( "find_libraries" );
-    checkFLibProc->addArgument( QDir::cleanDirPath( QFileInfo( targetFolder->text().stripWhiteSpace() ).absFilePath() ) );
-    // ... run script
-    if ( !checkFLibProc->start() ) {
-      ___MESSAGE___( "Error: process could not start!" );
-    }
+    if ( oneModDirBtn->isChecked() )
+      runModifyLaFiles();
+    else
+      runCheckFLib();
   }
-  else
+  else {
     // Update GUI and check installation errors
     completeInstallation();
+  }
   
 }
 // ================================================================
@@ -2004,10 +2332,7 @@ void SALOME_InstallWizard::completeInstallation()
   statusLab->setText( tr( "Installation completed" ) );
   // <Next> button
   setNextEnabled( true );
-  nextButton()->setText( tr( "&Next >" ) );
-  setAboutInfo( nextButton(), tr( "Move to the next step of the installation procedure" ) );
-  disconnect( this, SIGNAL( nextClicked() ), this, SLOT( next() ) );
-  disconnect( this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
+  doPostActions( tr( "&Next >" ), tr( "Move to the next step of the installation procedure" ) );
   connect(    this, SIGNAL( nextClicked() ), this, SLOT( next() ) );
   // <Back> button
   setBackEnabled( true );
@@ -2022,7 +2347,7 @@ void SALOME_InstallWizard::completeInstallation()
   if ( hasErrors ) {
     if ( QMessageBox::warning( this,
                               tr( "Warning" ),
-                              tr( "There were some errors and/or warnings during the installation.\n"
+                              tr( "There were some errors during the installation.\n"
                                   "Do you want to save the installation log?" ),
                               tr( "&Save" ),
                               tr( "&Cancel" ),
@@ -2051,8 +2376,8 @@ void SALOME_InstallWizard::onInstallGuiBtn()
       }
       else {
        QString itemName = itProd.data().getName();
-       if ( itemName != "KERNEL" && itemName != "MED" && 
-            itemName != "SAMPLES" && itemName != "DOCUMENTATION" ) {
+       if ( woGuiModules.find( itemName ) == woGuiModules.end() || 
+            woGuiModules[ itemName ] == False ) {
          itProd.key()->setOn( false );
          itProd.key()->setEnabled( false );
        }
@@ -2101,15 +2426,17 @@ void SALOME_InstallWizard::onFinishButton()
   ButtonList::Iterator it;
   for ( it = buttons.begin(); it != buttons.end(); ++it ) {
     if ( (*it).button() && (*it).button() == btn ) {
-      QString script;
-      script += "( cd " + QUOTE( QFileInfo( QDir::cleanDirPath( "./config_files/" ) ).absFilePath() ) + "; ";
-      script +=  + (*it).script();
-      script += " execute ";
-      script += QUOTE( QFileInfo( QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() ) ).absFilePath() ) + " ";
-      script += QUOTE( QFileInfo( QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + TEMPDIRNAME ).absFilePath() ) + " ";
-      script += " > /dev/null )";
-      ___MESSAGE___( "script: " << script.latin1() );
-      if ( (*it).script().isEmpty() || system( script.latin1() ) ) {
+      QDir rd( rootDirPath() );
+      Script script;
+      script << "cd" << QUOTE( rd.filePath( "config_files" ) ) << ";";
+      script << (*it).script() << "execute";
+      script << QUOTE( QFileInfo( QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() ) ).absFilePath() );
+      script << QUOTE( QFileInfo( QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + TEMPDIRNAME ).absFilePath() );
+#ifdef USE_DEV_NULL
+      script << ">& /dev/null";
+#endif
+      ___MESSAGE___( "script: " << script.script().latin1() );
+      if ( (*it).script().isEmpty() || system( script.script().latin1() ) ) {
        QMessageBox::warning( this,
                              tr( "Error" ),
                              tr( "Can't perform action!"),
@@ -2217,22 +2544,30 @@ void SALOME_InstallWizard::clean(bool rmDir)
   myWC.wakeAll();
   while ( myThread->running() );
   // first remove temporary files
-  QString script = "cd ./config_files/; remove_tmp.sh '";
-  script += tempFolder->text().stripWhiteSpace() + TEMPDIRNAME;
-  script += "' ";
-  script += QUOTE(DefineDependeces(productsMap));
-  script += " > /dev/null";
-  ___MESSAGE___( "script = " << script.latin1() );
-  if ( system( script.latin1() ) ) {
+  QDir rd( rootDirPath() );
+  Script script;
+  script << "cd" << QUOTE( rd.filePath( "config_files" ) ) << ";";
+  script << "remove_tmp.sh" << QUOTE( tempFolder->text().stripWhiteSpace() + TEMPDIRNAME );
+  script << QUOTE( getAllProducts( productsMap ) );
+#ifdef USE_DEV_NULL
+  script << ">& /dev/null";
+#endif
+  ___MESSAGE___( "script = " << script.script().latin1() );
+  if ( system( script.script().latin1() ) ) {
+    // error
   }
   // then try to remove created temporary directory
   //script = "rm -rf " + QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + TEMPDIRNAME;
   if ( rmDir && !tmpCreated.isNull() ) {
-    script = "rm -rf " + tmpCreated;
-    script += " > /dev/null";
-    if ( system( script.latin1() ) ) {
+    script.clear();
+    script << "rm -rf" << QUOTE( tmpCreated );
+#ifdef USE_DEV_NULL
+    script << ">& /dev/null";
+#endif
+    if ( system( script.script().latin1() ) ) {
+      // error
     }
-    ___MESSAGE___( "script = " << script.latin1() );
+    ___MESSAGE___( "script = " << script.script().latin1() );
   }
 }
 // ================================================================
@@ -2243,10 +2578,7 @@ void SALOME_InstallWizard::clean(bool rmDir)
 // ================================================================
 void SALOME_InstallWizard::pageChanged( const QString & mytitle)
 {
-  nextButton()->setText( tr( "&Next >" ) );
-  setAboutInfo( nextButton(), tr( "Move to the next step of the installation procedure" ) );
-  disconnect( this, SIGNAL( nextClicked() ), this, SLOT( next() ) );
-  disconnect( this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
+  doPostActions( tr( "&Next >" ), tr( "Move to the next step of the installation procedure" ) );
   connect(    this, SIGNAL( nextClicked() ), this, SLOT( next() ) );
   cancelButton()->disconnect();
   connect( cancelButton(), SIGNAL( clicked()), this, SLOT( reject() ) );
@@ -2259,7 +2591,10 @@ void SALOME_InstallWizard::pageChanged( const QString & mytitle)
   if ( aPage == typePage ) {
     // installation type page
     if ( buttonGrp->id( buttonGrp->selected() ) == -1 )
-      binBtn->animateClick(); // set default installation type
+      // set default installation type
+      forceSrc ? srcCompileBtn->animateClick() : binBtn->animateClick();
+    else
+      buttonGrp->selected()->animateClick();
   }
   else if ( aPage == platformsPage ) {
     // installation platforms page
@@ -2269,21 +2604,21 @@ void SALOME_InstallWizard::pageChanged( const QString & mytitle)
        QString plat = it.key();
        QRadioButton* rb = ( (QRadioButton*) platBtnGrp->child( plat ) );
        if ( installType == Binaries ) {
-         QFileInfo fib( QDir::cleanDirPath( getBinPath() + "/" + plat ) );
-         rb->setEnabled( fib.exists() );
-       }
-       else {
-         QFileInfo fis( QDir::cleanDirPath( getSrcPath() ) );
-         rb->setEnabled( fis.exists() );
+         QFileInfo fib( getPlatformBinPath( plat ) );
+         rb->setEnabled( true/*fib.isDir()*/ );
+         if ( platBtnGrp->id( platBtnGrp->selected() ) == -1 && plat == getBasePlatform() )
+           rb->animateClick();
        }
-       rb->setChecked( rb->isChecked() && rb->isEnabled() );
+//     rb->setChecked( rb->isChecked() && rb->isEnabled() );
+       if ( rb->isChecked() && rb->isEnabled() )
+         rb->animateClick();
       }
       setNextEnabled( platformsPage, platBtnGrp->id( platBtnGrp->selected() ) != -1 );
     }
   }
   else  if ( aPage == dirPage ) {
     // installation and temporary directories page
-    if ( ( indexOf( platformsPage ) != -1 ? 
+    if ( ( ( this->indexOf( platformsPage ) != -1 && this->appropriate( platformsPage ) ) ? 
           previousPage == platformsPage : previousPage == typePage ) 
         && stateChanged ) {
       // clear global variables before reading XML file
@@ -2298,6 +2633,16 @@ void SALOME_InstallWizard::pageChanged( const QString & mytitle)
       if ( tempFolder->text().isEmpty() )
        parser->setTempDir( tempFolder );
       parser->readXmlFile( xmlFileName );
+      // create a map of SALOME modules names, that can support installation without GUI mode
+      if ( woGuiModules.isEmpty() ) {
+       MapProducts::Iterator mapIter;
+       for ( mapIter = productsMap.begin(); mapIter != productsMap.end(); mapIter++ ) {
+         Dependancies dep = mapIter.data();
+         if ( dep.getType() == "component" && dep.supportWoGuiMode() != NotDefined )
+           woGuiModules[ dep.getName() ] = dep.supportWoGuiMode();
+       }
+      }
+  
       // update required size for each product
       updateSizeColumn();
       // take into account command line parameters
@@ -2317,6 +2662,11 @@ void SALOME_InstallWizard::pageChanged( const QString & mytitle)
       updateSizeColumn();
       rmSrcPrevState = removeSrcBtn->isChecked();
     }
+    // add extra products to install list
+    extraProducts.clear();
+    //extraProducts.insert( "gcc", "gcc-common.sh" );
+    if ( refPlatform == commonPlatform && installType == Binaries )
+      extraProducts.insert( "DebianLibsForSalome", "DEBIANFORSALOME-3.1.sh" );
   }
   else if ( aPage == productsPage ) {
     // products page
@@ -2337,11 +2687,7 @@ void SALOME_InstallWizard::pageChanged( const QString & mytitle)
       passedParams->clear();
       passedParams->setEnabled( false );
       QFont f = parametersLab->font(); f.setBold( false ); parametersLab->setFont( f );
-      nextButton()->setText( tr( "&Start" ) );
-      setAboutInfo( nextButton(), tr( "Start installation process" ) );
-      // reconnect Next button - to use it as Start button
-      disconnect( this, SIGNAL( nextClicked() ), this, SLOT( next() ) );
-      disconnect( this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
+      doPostActions( tr( "&Start" ), tr( "Start installation process" ) );
       connect(    this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
       setNextEnabled( true );
       // reconnect Cancel button to terminate process
@@ -2353,15 +2699,17 @@ void SALOME_InstallWizard::pageChanged( const QString & mytitle)
     ButtonList::Iterator it;
     for ( it = buttons.begin(); it != buttons.end(); ++it ) {
       if ( (*it).button() ) {
-       QString script;
-       script += "( cd " + QUOTE( QFileInfo( QDir::cleanDirPath( "./config_files/" ) ).absFilePath() ) + "; ";
-       script +=  + (*it).script();
-       script += " check_enabled ";
-       script += QUOTE( QFileInfo( QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() ) ).absFilePath() ) + " ";
-       script += QUOTE( QFileInfo( QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + TEMPDIRNAME ).absFilePath() ) + " ";
-       script += " > /dev/null )";
-       ___MESSAGE___( "script: " << script.latin1() );
-       (*it).button()->setEnabled( !(*it).script().isEmpty() && !system( script.latin1() ) );
+       QDir rd( rootDirPath() );
+       Script script;
+       script << "cd" << QUOTE( rd.filePath( "config_files" ) ) << ";";
+       script << (*it).script() << "check_enabled";
+       script << QUOTE( QFileInfo( QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() ) ).absFilePath() );
+       script << QUOTE( QFileInfo( QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + TEMPDIRNAME ).absFilePath() );
+#ifdef USE_DEV_NULL
+       script << ">& /dev/null";
+#endif
+       ___MESSAGE___( "script: " << script.script().latin1() );
+       (*it).button()->setEnabled( !(*it).script().isEmpty() && !system( script.script().latin1() ) );
       }
     }
     finishButton()->setEnabled( true );
@@ -2384,16 +2732,21 @@ void SALOME_InstallWizard::onButtonGroup( int rbIndex )
     installType = InstallationType( rbIndex );
     // management of the <Remove source and tmp files> check-box
     removeSrcBtn->setEnabled( installType == Compile );
+    oneModDirBtn->setEnabled( installType == Binaries /*|| installType == Compile*/ );
+    oneProdDirBtn->setEnabled( installType == Binaries || installType == Compile );
+    refPlatform = "";
+    xmlFileName = getXmlFile( curPlatform );
   }
   else if ( aPage == platformsPage ) {
     refPlatform = platBtnGrp->find( rbIndex )->name();
-    xmlFileName = platformsMap[ refPlatform ];
-//     cout << xmlFileName << endl;
+    xmlFileName = getXmlFile( refPlatform );
     setNextEnabled( platformsPage, true );
   }
   if ( prevType != installType || 
        ( indexOf( platformsPage ) != -1 ? prevPlat != getPlatform() : false ) ) {
     stateChanged = true;
+    oneModDirBtn->setChecked( installType == Binaries && singleDir );
+    oneProdDirBtn->setChecked( false );
   }
 }
 // ================================================================
@@ -2464,6 +2817,7 @@ void SALOME_InstallWizard::onStart()
   if ( nextButton()->text() == tr( "&Stop" ) ) {
     statusLab->setText( tr( "Aborting installation..." ) );
     shellProcess->kill();
+    modifyLaProc->kill();
     while( shellProcess->isRunning() );
     statusLab->setText( tr( "Installation has been aborted by user" ) );
     return;
@@ -2475,6 +2829,8 @@ void SALOME_InstallWizard::onStart()
   installInfo->setFinished( false );
   passedParams->clear();
   passedParams->setEnabled( false );
+  // disable 'Ignore errors' checkbox during installation process
+  ignoreErrCBox->setEnabled( false );
   QFont f = parametersLab->font(); f.setBold( false ); parametersLab->setFont( f );
 
   // update status label
@@ -2482,8 +2838,8 @@ void SALOME_InstallWizard::onStart()
   // clear lists of products
   toInstall.clear();
   notInstall.clear();
+  toInstall += extraProducts.keys();
   // ... and fill it for new process
-  toInstall.append( "gcc" );
   QCheckListItem* item = (QCheckListItem*)( prereqsView->firstChild() );
   while( item ) {
     if ( productsMap.contains( item ) ) {
@@ -2505,16 +2861,18 @@ void SALOME_InstallWizard::onStart()
     item = (QCheckListItem*)( item->nextSibling() );
   }
   // if something at all is selected
-  if ( (int)toInstall.count() > 1 ) {
+  if ( (int)toInstall.count() > 0 ) {
 
     if ( installType == Compile ) {
       // update status label
       statusLab->setText( tr( "Check Fortran compiler..." ) );
       // check Fortran compiler.
-      QString script = "./config_files/checkFortran.sh find_compilers";
-      script += " " + QUOTE( QFileInfo( QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + TEMPDIRNAME ).absFilePath() );
-      ___MESSAGE___( "script = " << script.latin1() );
-      if ( system( script ) ) {
+      QDir rd( rootDirPath() );
+      Script script;
+      script << QUOTE( rd.filePath( "config_files/checkFortran.sh" ) ) << "find_compilers";
+      script << QUOTE( QFileInfo( QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + TEMPDIRNAME ).absFilePath() );
+      ___MESSAGE___( "script = " << script.script().latin1() );
+      if ( system( script.script().latin1() ) ) {
        QMessageBox::critical( this,
                               tr( "Error" ),
                               tr( "Fortran compiler was not found at current system!\n"
@@ -2527,11 +2885,7 @@ void SALOME_InstallWizard::onStart()
        statusLab->setText( tr( "Installation has been aborted" ) );
        // enable <Next> button
        setNextEnabled( true );
-       nextButton()->setText( tr( "&Start" ) );
-       setAboutInfo( nextButton(), tr( "Start installation process" ) );
-       // reconnect Next button - to use it as Start button
-       disconnect( this, SIGNAL( nextClicked() ), this, SLOT( next() ) );
-       disconnect( this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
+       doPostActions( tr( "&Start" ), tr( "Start installation process" ) );
        connect(    this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
        // enable <Back> button
        setBackEnabled( true );
@@ -2555,12 +2909,12 @@ void SALOME_InstallWizard::onStart()
     ProgressViewItem* progressItem;
     // set status for installed products
     for ( int i = 0; i < (int)toInstall.count(); i++ ) {
-      if ( toInstall[i] != "gcc" ) {
+      if ( !extraProducts.contains( toInstall[i] ) ) {
        item = findItem( toInstall[i] );
        progressView->addProduct( item->text(0), item->text(2) );
        continue;
       }
-      progressItem = progressView->addProduct( "gcc", "gcc-common.sh" );
+      progressItem = progressView->addProduct( toInstall[i], extraProducts[toInstall[i]] );
       progressItem->setVisible( false );
     }
     // set status for not installed products
@@ -2572,7 +2926,7 @@ void SALOME_InstallWizard::onStart()
     // get specified list of products being installed
     prodSequence.clear();
     for (int i = 0; i<(int)toInstall.count(); i++ ) {
-      if ( toInstall[i] == "gcc" ) {
+      if ( extraProducts.contains( toInstall[i] ) ) {
        prodSequence.append( toInstall[i] );
        continue;
       }
@@ -2597,10 +2951,12 @@ void SALOME_InstallWizard::onStart()
 
     // create a backup of 'env_build.csh', 'env_build.sh', 'env_products.csh', 'env_products.sh'
     // ( backup of 'salome.csh' and 'salome.sh' is made if pick-up environment is called )
-    QString script = "./config_files/backupEnv.sh ";
-    script += QUOTE( QFileInfo( QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() ) ).absFilePath() );
-    ___MESSAGE___( "script = " << script.latin1() );
-    if ( system( script ) ) {
+    QDir rd( rootDirPath() );
+    Script script;
+    script << QUOTE( rd.filePath( "config_files/backupEnv.sh" ) );
+    script << QUOTE( QFileInfo( QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() ) ).absFilePath() );
+    ___MESSAGE___( "script = " << script.script().latin1() );
+    if ( system( script.script().latin1() ) ) {
       if ( QMessageBox::warning( this,
                                 tr( "Warning" ),
                                 tr( "Backup environment files have not been created.\n"
@@ -2611,13 +2967,9 @@ void SALOME_InstallWizard::onStart()
        // installation aborted
        abort();
        statusLab->setText( tr( "Installation has been aborted by user" ) );
-       // enable <Next> button
+       // update <Next> button
        setNextEnabled( true );
-       nextButton()->setText( tr( "&Start" ) );
-       setAboutInfo( nextButton(), tr( "Start installation process" ) );
-       // reconnect Next button - to use it as Start button
-       disconnect( this, SIGNAL( nextClicked() ), this, SLOT( next() ) );
-       disconnect( this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
+       doPostActions( tr( "&Start" ), tr( "Start installation process" ) );
        connect(    this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
        // enable <Back> button
        setBackEnabled( true );
@@ -2669,16 +3021,9 @@ void SALOME_InstallWizard::productInstalled()
     installInfo->setFinished( true );
     // enable <Next> button
     setNextEnabled( true );
-    nextButton()->setText( tr( "&Start" ) );
-    setAboutInfo( nextButton(), tr( "Start installation process" ) );
-    // reconnect Next button - to use it as Start button
-    disconnect( this, SIGNAL( nextClicked() ), this, SLOT( next() ) );
-    disconnect( this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
+    doPostActions( tr( "&Start" ), tr( "Start installation process" ) );
     connect(    this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
-    //nextButton()->setText( tr( "&Next >" ) );
-    //setAboutInfo( nextButton(), tr( "Move to the next step of the installation procedure" ) );
-    //disconnect( this, SIGNAL( nextClicked() ), this, SLOT( next() ) );
-    //disconnect( this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
+    //doPostActions( tr( "&Next >" ), tr( "Move to the next step of the installation procedure" ) );
     //connect(    this, SIGNAL( nextClicked() ), this, SLOT( next() ) );
     // enable <Back> button
     setBackEnabled( true );
@@ -2724,6 +3069,8 @@ void SALOME_InstallWizard::tryTerminate()
 void SALOME_InstallWizard::onCancel()
 {
   shellProcess->kill();
+  modifyLaProc->kill();
+  checkFLibProc->kill();
   reject();
 }
 // ================================================================
@@ -2802,11 +3149,12 @@ void SALOME_InstallWizard::wroteToStdin( )
 void SALOME_InstallWizard::readFromStdout( )
 {
   ___MESSAGE___( "Something was sent to stdout" );
-  while ( shellProcess->canReadLineStdout() ) {
-    installInfo->append( QString( shellProcess->readLineStdout() ) );
+  QProcess* theProcess = ( QProcess* )sender();
+  while ( theProcess->canReadLineStdout() ) {
+    installInfo->append( QString( theProcess->readLineStdout() ) );
     installInfo->scrollToBottom();
   }
-  QString str( shellProcess->readStdout() );
+  QString str( theProcess->readStdout() );
   if ( !str.isEmpty() ) {
     installInfo->append( str );
     installInfo->scrollToBottom();
@@ -2824,17 +3172,22 @@ void SALOME_InstallWizard::readFromStdout( )
 void SALOME_InstallWizard::readFromStderr( )
 {
   ___MESSAGE___( "Something was sent to stderr" );
-  while ( shellProcess->canReadLineStderr() ) {
-    installInfo->append( OUTLINE_TEXT( QString( shellProcess->readLineStderr() ) ) );
+  QProcess* theProcess = ( QProcess* )sender();
+  while ( theProcess->canReadLineStderr() ) {
+    installInfo->append( OUTLINE_TEXT( QString( theProcess->readLineStderr() ) ) );
     installInfo->scrollToBottom();
     hasErrors = true;
   }
-  QString str( shellProcess->readStderr() );
+  QString str( theProcess->readStderr() );
   if ( !str.isEmpty() ) {
     installInfo->append( OUTLINE_TEXT( str ) );
     installInfo->scrollToBottom();
     hasErrors = true;
   }
+
+  // stop or proceed installation process
+  manageInstProc();
+
   // VSR: 10/11/05 - disable answer mode ==>
   // passedParams->setEnabled( true );
   // passedParams->setFocus();
@@ -2842,6 +3195,41 @@ void SALOME_InstallWizard::readFromStderr( )
   // VSR: 10/11/05 - disable answer mode <==
 }
 // ================================================================
+/*!
+ *  SALOME_InstallWizard::manageInstProc
+ *  QProcess slot: -->stop installation if there is an error in stderr
+ */
+// ================================================================
+void SALOME_InstallWizard::manageInstProc()
+{
+  if ( !hasErrors || ignoreErrCBox->isChecked() )
+    return; //proceed installation process
+  
+  // abort the current installation
+  statusLab->setText( tr( "Aborting installation..." ) );
+  abort();
+  statusLab->setText( tr( "Installation has been aborted because some errors" ) );
+  if ( QMessageBox::critical( this,
+                             tr( "Error" ),
+                             tr( "Installation process has been stopped, because an error occured \n"
+                                 "during an installation of the current product!\n"
+                                 "Please see the installation progress view for more details about the error.\n\n"
+                                 "Do you want to save the installation log?" ),
+                             tr( "&Save" ),
+                             tr( "&Cancel" ),
+                             QString::null,
+                             0,
+                             1 ) == 0 )
+    saveLog();
+  // enable <Next> button
+  setNextEnabled( true );
+  doPostActions( tr( "&Start" ), tr( "Start installation process" ) );
+  connect( this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
+  // enable <Back> button
+  setBackEnabled( true );
+  installInfo->setFinished( true );
+}
+// ================================================================
 /*!
  *  SALOME_InstallWizard::setDependancies
  *  Sets dependancies for the product item
@@ -2852,6 +3240,24 @@ void SALOME_InstallWizard::setDependancies( QCheckListItem* item, Dependancies d
   productsMap[item] = dep;
 }
 // ================================================================
+/*!
+ *  SALOME_InstallWizard::doPostActions
+ *  Executes some actions after finish of installation process (successful or not)
+ */
+// ================================================================
+void SALOME_InstallWizard::doPostActions( const QString& btnText,
+                                         const QString& btnAboutInfo )
+{
+  // update <Next> button
+  nextButton()->setText( btnText );
+  setAboutInfo( nextButton(), btnAboutInfo );
+  // reconnect Next button - to use it as Start button
+  disconnect( this, SIGNAL( nextClicked() ), this, SLOT( next() ) );
+  disconnect( this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
+  // enable 'Ignore errors' checkbox
+  ignoreErrCBox->setEnabled( true );
+}
+// ================================================================
 /*!
  *  SALOME_InstallWizard::addFinishButton
  *  Add button for the <Finish> page.
@@ -2912,6 +3318,7 @@ void SALOME_InstallWizard::saveLog()
   QDateTime dt = QDateTime::currentDateTime();
   QString fileName = dt.toString("ddMMyy-hhmm");
   fileName.prepend("install-"); fileName.append(".html");
+  fileName = QFileInfo( QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() ), fileName ).absFilePath();
   fileName = QFileDialog::getSaveFileName( fileName,
                                           QString( "HTML files (*.htm *.html)" ),
                                           this, 0,