Salome HOME
Implement features:
[tools/install.git] / src / SALOME_InstallWizard.cxx
index 9a83803f0d64b2763397267427b56b4b14491755..bafdec9b1ff6aa30df25c9fddebc25ca5cb89017 100644 (file)
@@ -1,9 +1,9 @@
-//  File      : SALOME_InstallWizard.cxx 
+//  File      : SALOME_InstallWizard.cxx
 //  Created   : Thu Dec 18 12:01:00 2002
-//  Author    : Vadim SANDLER
+//  Author    : Vadim SANDLER, Open CASCADE SAS (vadim.sandler@opencascade.com)
 //  Project   : SALOME
 //  Module    : Installation Wizard
-//  Copyright : 2004-2005 CEA
+//  Copyright : 2002-2006 CEA
 
 #include "globals.h"
 
 #include <qcheckbox.h>
 #include <qsplitter.h>
 #include <qlayout.h>
-#include <qfiledialog.h> 
+#include <qfiledialog.h>
 #include <qapplication.h>
-#include <qfileinfo.h> 
-#include <qmessagebox.h> 
-#include <qtimer.h> 
+#include <qfileinfo.h>
+#include <qmessagebox.h>
+#include <qtimer.h>
 #include <qvbox.h>
-#include <qwhatsthis.h> 
+#include <qwhatsthis.h>
 #include <qtooltip.h>
 #include <qfile.h>
 #include <qthread.h>
 #include <qwaitcondition.h>
+#include <qmutex.h>
+#include <qstringlist.h>
+#include <qpopupmenu.h>
+#include <qregexp.h>
 
 #ifdef WNT
 #include <iostream.h>
@@ -54,16 +58,17 @@ QString tmpDirName() { return QString(  "/INSTALLWORK" ) + QString::number( getp
 
 // ================================================================
 /*!
- *  QProcessThread
+ *  ProcessThread
  *  Class for executing systen commands
  */
 // ================================================================
-QWaitCondition myWC;
-class QProcessThread: public QThread
+static QMutex myMutex(false);
+static QWaitCondition myWC;
+class ProcessThread: public QThread
 {
   typedef QPtrList<QCheckListItem> ItemList;
 public:
-  QProcessThread( SALOME_InstallWizard* iw ) : QThread(), myWizard( iw ) { myItems.setAutoDelete( false ); }
+  ProcessThread( SALOME_InstallWizard* iw ) : QThread(), myWizard( iw ) { myItems.setAutoDelete( false ); }
 
   void addCommand( QCheckListItem* item, const QString& cmd ) {
     myItems.append( item );
@@ -75,15 +80,17 @@ public:
 
   virtual void run() {
     while ( hasCommands() ) {
-      ___MESSAGE___( "QProcessThread::run - Processing command : " << myCommands[ 0 ].latin1() );
-      int result = system( myCommands[ 0 ] ) / 256; // return code is <errno> * 256 
-      ___MESSAGE___( "QProcessThread::run - Result : " << result );
+      ___MESSAGE___( "ProcessThread::run - Processing command : " << myCommands[ 0 ].latin1() );
+      int result = system( myCommands[ 0 ] ) / 256; // return code is <errno> * 256
+      ___MESSAGE___( "ProcessThread::run - Result : " << result );
       QCheckListItem* item = myItems.first();
       myCommands.pop_front();
       myItems.removeFirst();
+      myMutex.lock();
       SALOME_InstallWizard::postValidateEvent( myWizard, result, (void*)item );
       if ( hasCommands() )
-       myWC.wait();
+       myWC.wait(&myMutex);
+      myMutex.unlock();
     };
   }
 
@@ -104,23 +111,26 @@ class WarnDialog: public QDialog
   static WarnDialog* myDlg;
   bool myCloseFlag;
 
-  WarnDialog( QWidget* parent ) 
+  WarnDialog( QWidget* parent )
   : QDialog( parent, "WarnDialog", true, WDestructiveClose ) {
     setCaption( tr( "Information" ) );
     myCloseFlag = false;
     QLabel* lab = new QLabel( tr( "Please, wait while checking native products configuration ..." ), this );
     lab->setAlignment( AlignCenter );
-    lab->setFrameStyle( QFrame::Box | QFrame::Plain ); 
+    lab->setFrameStyle( QFrame::Box | QFrame::Plain );
     QVBoxLayout* l = new QVBoxLayout( this );
     l->setMargin( 0 );
     l->add( lab );
-    this->setFixedSize( lab->sizeHint().width()  + 50, 
+    this->setFixedSize( lab->sizeHint().width()  + 50,
                        lab->sizeHint().height() * 5 );
   }
   void accept() { return; }
   void reject() { return; }
-  void closeEvent( QCloseEvent* e) { if ( !myCloseFlag ) return; QDialog::closeEvent( e ); }
-  
+  void closeEvent( QCloseEvent* e )
+  { if ( !myCloseFlag ) return;
+    e->accept();
+    QDialog::closeEvent( e );
+  }
   ~WarnDialog() { myDlg = 0; }
 public:
   static void showWarnDlg( QWidget* parent, bool show ) {
@@ -128,7 +138,7 @@ public:
       if ( !myDlg ) {
        myDlg = new WarnDialog( parent );
        QSize sh = myDlg->size();
-       myDlg->move( parent->x() + (parent->width()-sh.width())/2, 
+       myDlg->move( parent->x() + (parent->width()-sh.width())/2,
                     parent->y() + (parent->height()-sh.height())/2 );
        myDlg->show();
       }
@@ -146,13 +156,55 @@ public:
 };
 WarnDialog* WarnDialog::myDlg = 0;
 
+// ================================================================
+/*!
+ *  InstallInfo
+ *  Installation progress info window class
+ */
+// ================================================================
+class InstallInfo : public QTextEdit
+{
+public:
+  InstallInfo( QWidget* parent ) : QTextEdit( parent ), finished( false ) {}
+  void setFinished( const bool f ) { finished = f; }
+protected:
+  QPopupMenu* createPopupMenu( const QPoint& )
+  {
+    int para1, col1, para2, col2;
+    getSelection(&para1, &col1, &para2, &col2);
+    bool allSelected = hasSelectedText() &&
+      para1 == 0 && para2 == paragraphs()-1 && col1 == 0 && col2 == paragraphLength(para2);
+    QPopupMenu* popup = new QPopupMenu( this );
+    int id = popup->insertItem( tr( "&Copy" ) );
+    popup->setItemEnabled( id, hasSelectedText() );
+    popup->connectItem ( id, this, SLOT( copy() ) );
+    id = popup->insertItem( tr( "Select &All" ) );
+    popup->setItemEnabled( id, (bool)text().length() && !allSelected );
+    popup->connectItem ( id, this, SLOT( selectAll() ) );
+    if ( finished ) {
+      QWidget* p = parentWidget();
+      while ( p && !p->inherits( "SALOME_InstallWizard" ) )
+       p = p->parentWidget();
+      if ( p && p->inherits( "SALOME_InstallWizard" ) ) {
+       popup->insertSeparator();
+       id = popup->insertItem( tr( "&Save Log" ) );
+       popup->setItemEnabled( id, (bool)text().length() );
+       popup->connectItem ( id, (SALOME_InstallWizard*)p, SLOT( saveLog() ) );
+      }
+    }
+    return popup;
+  }
+private:
+  bool finished;
+};
+
 // ================================================================
 /*!
  *  DefineDependeces [ static ]
  *  Defines list of dependancies as string separated by space symbols
  */
 // ================================================================
-static QString DefineDependeces(MapProducts& theProductsMap) 
+static QString DefineDependeces(MapProducts& theProductsMap)
 {
   QStringList aProducts;
   for ( MapProducts::Iterator mapIter = theProductsMap.begin(); mapIter != theProductsMap.end(); ++mapIter ) {
@@ -169,10 +221,22 @@ static QString DefineDependeces(MapProducts& theProductsMap)
   return aProducts.join(" ");
 }
 
+// ================================================================
+/*!
+ *  setAboutInfo [ static ]
+ *  Sets 'what's this' and 'tooltip' information for the widget
+ */
+// ================================================================
+static void setAboutInfo( QWidget* widget, const QString& tip )
+{
+  QWhatsThis::add( widget, tip );
+  QToolTip::add  ( widget, tip );
+}
+
 #define QUOTE(arg) QString("'") + QString(arg) + QString("'")
 
 /* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-               T H E   O L D   I M P L E M E N T A T I O N 
+               T H E   O L D   I M P L E M E N T A T I O N
 static QString DefineDependeces(MapProducts& theProductsMap, QCheckListItem* product ){
   QStringList aProducts;
   if ( theProductsMap.contains( product ) ) {
@@ -266,33 +330,166 @@ static bool hasSpace( const QString& dir )
   return false;
 }
 
+// ================================================================
+/*!
+ *  makeTitle
+ *  Creates HTML-wrapped title text
+ */
+// ================================================================
+QString makeTitle( const QString& text, const QString& separator = " ", bool fl = true )
+{
+  QStringList words = QStringList::split( separator, text );
+  if ( fl ) {
+    for ( uint i = 0; i < words.count(); i++ )
+      words[i] = QString( "<font color=red>%1</font>" ).arg( words[i].left(1) ) + words[i].mid(1);
+  }
+  else {
+    if ( words.count() > 0 )
+      words[0] = QString( "<font color=red>%1</font>" ).arg( words[0] );
+    if ( words.count() > 1 )
+      words[words.count()-1] = QString( "<font color=red>%1</font>" ).arg( words[words.count()-1] );
+  }
+  QString res = words.join( separator );
+  if ( !res.isEmpty() )
+    res = QString( "<b>%1</b>" ).arg( res );
+  return res;
+}
+
+// ================================================================
+/*!
+ *  QMyCheckBox class : custom check box
+ *  The only goal is to give access to the protected setState() method
+ */
+// ================================================================
+class QMyCheckBox: public QCheckBox
+{
+public:
+  QMyCheckBox( const QString& text, QWidget* parent, const char* name = 0 ) : QCheckBox ( text, parent, name ) {}
+  void setState ( ToggleState s ) { QCheckBox::setState( s ); }
+};
+
+// ================================================================
+/*!
+ *  AboutDlg
+ *  "About dialog box.
+ */
+// ================================================================
+class AboutDlg: public QDialog
+{
+public:
+  AboutDlg( SALOME_InstallWizard* parent ) : QDialog( parent, "About dialog box", true )
+  {
+    // caption
+    setCaption( QString( "About %1" ).arg( parent->getIWName() ) );
+    // palette
+    QPalette pal = palette();
+    QColorGroup cg = pal.active();
+    cg.setColor( QColorGroup::Foreground, Qt::darkBlue );
+    cg.setColor( QColorGroup::Background, Qt::white );
+    pal.setActive( cg ); pal.setInactive( cg ); pal.setDisabled( cg );
+    setPalette( pal );
+    // layout
+    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->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__ ) \
+                     .arg( __IW_VERSION_PATCH__ ) );
+    QLabel* copyright = new QLabel( this, "copyright" );
+    copyright->setText( "<b>Copyright</b> &copy; 2004-2006 CEA" );
+    QFont font = title->font();
+    font.setPointSize( (int)( font.pointSize() * 1.8 ) );
+    title->setFont( font );
+    QFrame* line = new QFrame( this, "line" );
+    line->setFrameStyle( QFrame::HLine | QFrame::Sunken );
+    QLabel* url = new QLabel( this, "url" );
+    url->setText( makeTitle( "www.salome-platform.org", ".", false ) );
+    url->setAlignment( AlignRight );
+    font = version->font();
+    font.setPointSize( (int)( font.pointSize() / 1.2 ) );
+    version->setFont( font );
+    copyright->setFont( font );
+    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 );
+    // resize
+    QFontMetrics fm( title->font() );
+    int width = (int)( fm.width( tlt ) * 1.5 );
+    title->setMinimumWidth( width );
+    setMaximumSize( minimumSize() );
+  }
+  void mousePressEvent( QMouseEvent* )
+  {
+    accept();
+  }
+};
+
 // ================================================================
 /*!
  *  SALOME_InstallWizard::SALOME_InstallWizard
  *  Constructor
  */
 // ================================================================
-SALOME_InstallWizard::SALOME_InstallWizard(QString aXmlFileName)
-     : InstallWizard( qApp->desktop(), "SALOME_InstallWizard", false, 0 ), 
-       helpWindow( NULL ), 
-       moreMode( false ), 
-       previousPage( 0 ), 
+SALOME_InstallWizard::SALOME_InstallWizard(const QString& aXmlFileName,
+                                          const QString& aTargetDir,
+                                          const QString& aTmpDir,
+                                          const bool     aForceSrc)
+     : InstallWizard( qApp->desktop(), "SALOME_InstallWizard", false, 0 ),
+       helpWindow( NULL ),
+       moreMode( false ),
+       previousPage( 0 ),
        exitConfirmed( false )
 {
-  myIWName = tr( "Installation Wizard" );
-  tmpCreated = QString::null;
-  xmlFileName = aXmlFileName;
-  QFont fnt = font(); fnt.setPointSize( 14 ); fnt.setBold( true );
+  myIWName      = tr( "Installation Wizard" );
+  tmpCreated    = QString::null;
+  xmlFileName   = aXmlFileName;
+  targetDirPath = aTargetDir;
+  tmpDirPath    = aTmpDir;
+
+  // set application font
+  QFont fnt = font();
+  fnt.setPointSize( 14 );
+  fnt.setBold( true );
   setTitleFont( fnt );
 
   // set icon
-  setIcon( QPixmap( ( const char** ) image0_data ) );
+  setIcon( pixmap( pxIcon ) );
   // enable sizegrip
   setSizeGripEnabled( true );
-  
+
   // add logo
-  addLogo( QPixmap( (const char**)image1_data ) );
-  
+  addLogo( pixmap( pxLogo ) );
+
   // set defaults
   setVersion( "1.2" );
   setCaption( tr( "PAL/SALOME %1" ).arg( myVersion ) );
@@ -300,7 +497,9 @@ SALOME_InstallWizard::SALOME_InstallWizard(QString aXmlFileName)
   setLicense( tr( "All right reserved" ) );
   setOS( "" );
 
-  ___MESSAGE___( "Config. file : " << xmlFileName );
+  ___MESSAGE___( "Configuration file : " << xmlFileName.latin1() );
+  ___MESSAGE___( "Target directory   : " << targetDirPath.latin1() );
+  ___MESSAGE___( "Temporary directory: " << tmpDirPath.latin1() );
 
   // xml reader
   QFile xmlfile(xmlFileName);
@@ -310,7 +509,7 @@ SALOME_InstallWizard::SALOME_InstallWizard(QString aXmlFileName)
 
     StructureParser* handler = new StructureParser( this );
     reader.setContentHandler( handler );
-    reader.parse( source );  
+    reader.parse( source );
   }
 
   // create instance of class for starting shell install script
@@ -319,30 +518,27 @@ SALOME_InstallWizard::SALOME_InstallWizard(QString aXmlFileName)
   // create introduction page
   setupIntroPage();
   // create products page
-  setupProductsPage();
+  setupProductsPage(aForceSrc);
   // create prestart page
   setupCheckPage();
   // create progress page
   setupProgressPage();
   // create readme page
   setupReadmePage();
-  
+
   // common buttons
-  QWhatsThis::add( backButton(),   tr( "Returns to the previous step of the installation procedure" ) );
-  QToolTip::add  ( backButton(),   tr( "Returns to the previous step of the installation procedure" ) );
-  QWhatsThis::add( nextButton(),   tr( "Moves to the next step of the installation procedure" ) );
-  QToolTip::add  ( nextButton(),   tr( "Moves to the next step of the installation procedure" ) );
-  QWhatsThis::add( finishButton(), tr( "Finishes installation and quits program" ) );
-  QToolTip::add  ( finishButton(), tr( "Finishes installation and quits program" ) );
-  QWhatsThis::add( cancelButton(), tr( "Cancels installation and quits program" ) );
-  QToolTip::add  ( cancelButton(), tr( "Cancels installation and quits program" ) );
-  QWhatsThis::add( helpButton(),   tr( "Displays help information window" ) );
-  QToolTip::add  ( helpButton(),   tr( "Displays help information window" ) );
-  
+  setAboutInfo( backButton(),   tr( "Return to the previous step\nof the installation procedure" ) );
+  setAboutInfo( nextButton(),   tr( "Move to the next step\nof the installation procedure" ) );
+  setAboutInfo( finishButton(), tr( "Finish the installation and quit the program" ) );
+  setAboutInfo( cancelButton(), tr( "Cancel the installation and quit the program" ) );
+  setAboutInfo( helpButton(),   tr( "Show the help information" ) );
+
   // common signals connections
   connect( this, SIGNAL( selected( const QString& ) ),
-                                          this, SLOT( pageChanged( const QString& ) ) );
-  connect( this, SIGNAL( helpClicked() ), this, SLOT( helpClicked() ) );
+                                           this, SLOT( pageChanged( const QString& ) ) );
+  connect( this, SIGNAL( helpClicked() ),  this, SLOT( helpClicked() ) );
+  connect( this, SIGNAL( aboutClicked() ), this, SLOT( onAbout() ) );
+
   // catch signals from launched script
   connect(shellProcess, SIGNAL( readyReadStdout() ), this, SLOT( readFromStdout() ) );
   connect(shellProcess, SIGNAL( readyReadStderr() ), this, SLOT( readFromStderr() ) );
@@ -350,7 +546,11 @@ SALOME_InstallWizard::SALOME_InstallWizard(QString aXmlFileName)
   connect(shellProcess, SIGNAL( wroteToStdin() ),    this, SLOT( wroteToStdin() ) );
 
   // create validation thread
-  myThread = new QProcessThread( this );
+  myThread = new ProcessThread( this );
+
+  // show about button
+  setAboutIcon( pixmap( pxAbout ) );
+  showAboutBtn( true );
 }
 // ================================================================
 /*!
@@ -367,7 +567,7 @@ SALOME_InstallWizard::~SALOME_InstallWizard()
     script += QString::number( PID );
     script += " > /dev/null";
     ___MESSAGE___( "script: " << script.latin1() );
-    if ( system( script.latin1() ) ) { 
+    if ( system( script.latin1() ) ) {
     }
   }
   delete myThread;
@@ -397,10 +597,10 @@ void SALOME_InstallWizard::closeEvent( QCloseEvent* ce )
     return;
   }
   if ( !exitConfirmed ) {
-    if ( QMessageBox::information( this, 
-                                  tr( "Exit" ), 
-                                  tr( "Do you want to quit %1?" ).arg( getIWName() ), 
-                                  tr( "&Yes" ), 
+    if ( QMessageBox::information( this,
+                                  tr( "Exit" ),
+                                  tr( "Do you want to quit %1?" ).arg( getIWName() ),
+                                  tr( "&Yes" ),
                                   tr( "&No" ),
                                   QString::null,
                                   0,
@@ -424,14 +624,13 @@ void SALOME_InstallWizard::setupIntroPage()
 {
   // create page
   introPage = new QWidget( this, "IntroPage" );
-  QGridLayout* pageLayout = new QGridLayout( introPage ); 
+  QGridLayout* pageLayout = new QGridLayout( introPage );
   pageLayout->setMargin( 0 ); pageLayout->setSpacing( 6 );
   // create logo picture
-  QPixmap logo( (const char**)SALOME_Logo_xpm );
   logoLab = new QLabel( introPage );
-  logoLab->setPixmap( logo );
+  logoLab->setPixmap( pixmap( pxBigLogo ) );
   logoLab->setScaledContents( false );
-  logoLab->setFrameStyle( QLabel::Plain | QLabel::Box );
+  logoLab->setFrameStyle( QLabel::Plain | QLabel::NoFrame );
   logoLab->setAlignment( AlignCenter );
   // create version box
   QVBox* versionBox = new QVBox( introPage ); versionBox->setSpacing( 6 );
@@ -475,59 +674,40 @@ void SALOME_InstallWizard::setupIntroPage()
  *  Creates products page
  */
 // ================================================================
-void SALOME_InstallWizard::setupProductsPage()
+void SALOME_InstallWizard::setupProductsPage(const bool forceSrc)
 {
+  //
   // create page
+  //
   productsPage = new QWidget( this, "ProductsPage" );
-  QGridLayout* pageLayout = new QGridLayout( productsPage ); 
+  QGridLayout* pageLayout = new QGridLayout( productsPage );
   pageLayout->setMargin( 0 ); pageLayout->setSpacing( 6 );
-  // target directory
-  QLabel* targetLab = new QLabel( tr( "Type the target directory:" ), productsPage );
+  //
+  // create common widgets
+  //
+  // ... target directory
+  QLabel* targetLab = new QLabel( tr( "Installation directory:" ), productsPage );
   targetFolder = new QLineEdit( productsPage );
-  QWhatsThis::add( targetFolder, tr( "Enter target root directory where products will be installed" ) );
-  QToolTip::add  ( targetFolder, tr( "Enter target root directory where products will be installed" ) );
+  setAboutInfo( targetFolder, tr( "Enter the target directory where the products\nshould be installed to" ) );
   targetBtn = new QPushButton( tr( "Browse..." ), productsPage );
-  QWhatsThis::add( targetBtn, tr( "Click this to browse target directory" ) );
-  QToolTip::add  ( targetBtn, tr( "Click this to browse target directory" ) );
-  // create advanced mode widgets container
-  moreBox = new QWidget( productsPage );
-  QGridLayout* moreBoxLayout = new QGridLayout( moreBox );
-  moreBoxLayout->setMargin( 0 ); moreBoxLayout->setSpacing( 6 );
-  // temp directory
-  QLabel* tempLab = new QLabel( tr( "Type the directory for the temporary files:" ), moreBox );
-  tempFolder = new QLineEdit( moreBox );
-  //  tempFolder->setText( "/tmp" ); // default is /tmp directory
-  QWhatsThis::add( tempFolder, tr( "Enter directory where to put temporary files" ) );
-  QToolTip::add  ( tempFolder, tr( "Enter directory where to put temporary files" ) );
-  tempBtn = new QPushButton( tr( "Browse..." ), moreBox );
-  tempBtn->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) );
-  QWhatsThis::add( tempBtn, tr( "Click this to browse temporary directory" ) );
-  QToolTip::add  ( tempBtn, tr( "Click this to browse temporary directory" ) );
-  // create products list
-  productsView = new ProductsView( moreBox );
-  productsView->setMinimumSize( 250, 180 );
-  QWhatsThis::add( productsView, tr( "This view lists the products you wish to be installed" ) );
-  QToolTip::add  ( productsView, tr( "This view lists the products you wish to be installed" ) );
-  // products info box
-  productsInfo = new QTextBrowser( moreBox );
-  productsInfo->setMinimumSize( 270, 135 );
-  QWhatsThis::add( productsInfo, tr( "Shows info about the product: required disk space and prerequisites" ) );
-  QToolTip::add  ( productsInfo, tr( "Shows info about the product: required disk space and prerequisites" ) );
-  // disk space labels
-  QLabel* reqLab1 = new QLabel( tr( "Total disk space required:" ), moreBox );
-  QWhatsThis::add( reqLab1, tr( "Shows total disk space required for installing selected products" ) );
-  QToolTip::add  ( reqLab1, tr( "Shows total disk space required for installing selected products" ) );
-  requiredSize = new QLabel( moreBox );
+  setAboutInfo( targetBtn, tr( "Click this button to browse\nthe installation directory" ) );
+  // ... temporary directory
+  QLabel* tempLab = new QLabel( tr( "Temporary directory:" ), productsPage );
+  tempFolder = new QLineEdit( productsPage );
+  setAboutInfo( tempFolder, tr( "The directory which should be used\nfor temporary files" ) );
+  tempBtn = new QPushButton( tr( "Browse..." ), productsPage );
+  setAboutInfo( tempBtn, tr( "Click this button to browse\nthe temporary directory" ) );
+  // ... disk space labels
+  QLabel* reqLab1 = new QLabel( tr( "Disk space required:" ), productsPage );
+  setAboutInfo( reqLab1, tr( "Total disk space required for the installation\nof the selected products" ) );
+  requiredSize = new QLabel( productsPage );
   requiredSize->setMinimumWidth( 100 );
-  QWhatsThis::add( requiredSize, tr( "Shows total disk space required for installing selected products" ) );
-  QToolTip::add  ( requiredSize, tr( "Shows total disk space required for installing selected products" ) );
-  QLabel* reqLab2 = new QLabel( tr( "Space for temporary files:" ), moreBox );
-  QWhatsThis::add( reqLab2, tr( "Shows additional disk space which is required for temporary files" ) );
-  QToolTip::add  ( reqLab2, tr( "Shows additional disk space which is required for temporary files" ) );
-  requiredTemp = new QLabel( moreBox );
+  setAboutInfo( requiredSize, tr( "Total disk space required for the installation\nof the selected products" ) );
+  QLabel* reqLab2 = new QLabel( tr( "Space for temporary files:" ), productsPage );
+  setAboutInfo( reqLab2, tr( "Disk space required for the temporary files" ) );
+  requiredTemp = new QLabel( productsPage );
   requiredTemp->setMinimumWidth( 100 );
-  QWhatsThis::add( requiredTemp, tr( "Shows additional disk space which is required for temporary files" ) );
-  QToolTip::add  ( requiredTemp, tr( "Shows additional disk space which is required for temporary files" ) );
+  setAboutInfo( requiredTemp, tr( "Disk space required for the temporary files" ) );
   QFont fnt = reqLab1->font();
   fnt.setBold( true );
   reqLab1->setFont( fnt );
@@ -539,37 +719,94 @@ void SALOME_InstallWizard::setupProductsPage()
   sizeLayout->addWidget( requiredSize, 0, 1 );
   sizeLayout->addWidget( reqLab2,      1, 0 );
   sizeLayout->addWidget( requiredTemp, 1, 1 );
-  // prerequisites checkbox
-  prerequisites = new QCheckBox( tr( "Auto set prerequisites products" ), moreBox );
+  //
+  // create <More...> mode widgets container
+  //
+  moreBox = new QWidget( productsPage );
+  QGridLayout* moreBoxLayout = new QGridLayout( moreBox );
+  moreBoxLayout->setMargin( 0 ); moreBoxLayout->setSpacing( 6 );
+  //
+  // create <More...> mode widgets
+  //
+  // ... products list
+  productsView = new ProductsView( moreBox );
+  productsView->setMinimumSize( 250, 180 );
+  setAboutInfo( productsView, tr( "The products available for the installation" ) );
+  // ... products info box
+  productsInfo = new QTextBrowser( moreBox );
+  productsInfo->setMinimumSize( 270, 135 );
+  setAboutInfo( productsInfo, tr( "Short information about the product being selected" ) );
+  // ... prerequisites checkbox
+  prerequisites = new QCheckBox( tr( "Automatic dependencies" ), moreBox );
   prerequisites->setChecked( true );
-  QWhatsThis::add( prerequisites, tr( "Check this if you want prerequisites products to be set on automatically" ) );
-  QToolTip::add  ( prerequisites, tr( "Check this if you want prerequisites products to be set on automatically" ) );
-  // <Unselect All> buttons
-  unselectBtn  = new QPushButton( tr( "&Unselect All" ),    moreBox );
-  QWhatsThis::add( unselectBtn, tr( "Unselects all products" ) );
-  QToolTip::add  ( unselectBtn, tr( "Unselects all products" ) );
-  QVBoxLayout* btnLayout = new QVBoxLayout; btnLayout->setMargin( 0 ); btnLayout->setSpacing( 6 );
-  btnLayout->addWidget( unselectBtn );
-  // layouting advancet mode widgets
-  moreBoxLayout->addMultiCellWidget( tempLab,      0, 0, 0, 2 );
-  moreBoxLayout->addMultiCellWidget( tempFolder,   1, 1, 0, 1 );
-  moreBoxLayout->addWidget         ( tempBtn,      1,    2    );
-  moreBoxLayout->addMultiCellWidget( productsView, 2, 5, 0, 0 );
-  moreBoxLayout->addMultiCellWidget( productsInfo, 2, 2, 1, 2 );
-  moreBoxLayout->addMultiCellWidget( prerequisites,3, 3, 1, 2 );
-  moreBoxLayout->addMultiCellLayout( btnLayout,    4, 4, 1, 2 );
-  moreBoxLayout->addMultiCellLayout( sizeLayout,   5, 5, 1, 2 );
-  // <More...> button
+  setAboutInfo( prerequisites, tr( "Check this box if you want the prerequisite products\nto be selected automatically" ) );
+  // ... <Unselect All> button
+  unselectBtn = new QPushButton( tr( "&Unselect All" ), moreBox );
+  setAboutInfo( unselectBtn, tr( "Click this button to deselect all the products" ) );
+  // ... <SALOME sources> and <SALOME binaries> tri-state checkboxes
+  selectBinBtn = new QMyCheckBox( tr( "SALOME binaries" ), moreBox );
+  selectBinBtn->setTristate( true );
+  setAboutInfo( selectBinBtn, tr( "Click this button to select/deselect SALOME binaries" ) );
+  selectSrcBtn = new QMyCheckBox( tr( "SALOME sources" ), moreBox );
+  selectSrcBtn->setTristate( true );
+  setAboutInfo( selectSrcBtn, tr( "Click this button to select/deselect SALOME sources" ) );
+  buildSrcBtn = new QMyCheckBox( tr( "Build SALOME sources" ), moreBox );
+  setAboutInfo( buildSrcBtn, tr( "Check this box if you want to build selected\nSALOME modules from sources" ) );
+  QGridLayout* btnLayout = new QGridLayout; btnLayout->setMargin( 0 ); btnLayout->setSpacing( 6 );
+  btnLayout->addMultiCellWidget( unselectBtn,  0, 0, 0, 1 );
+  btnLayout->addMultiCellWidget( selectBinBtn, 1, 1, 0, 1 );
+  btnLayout->addMultiCellWidget( selectSrcBtn, 2, 2, 0, 1 );
+  btnLayout->addWidget(          buildSrcBtn,  3,    1 );
+  btnLayout->addColSpacing( 0, 20 );
+  btnLayout->setColStretch( 1, 10 );
+  //
+  // layout <More...> mode widgets
+  //
+  moreBoxLayout->addMultiCellWidget( productsView, 0, 3, 0, 0 );
+  moreBoxLayout->addWidget( productsInfo, 0, 1 );
+  moreBoxLayout->addWidget( prerequisites,1, 1 );
+  moreBoxLayout->addLayout( btnLayout,    2, 1 );
+  //
+  // create <Less...> mode widgets container
+  //
+  lessBox = new QWidget( productsPage );
+  QGridLayout* lessBoxLayout = new QGridLayout( lessBox );
+  lessBoxLayout->setMargin( 0 ); lessBoxLayout->setSpacing( 6 );
+  //
+  // create <Less...> mode widgets
+  //
+  // ... <Install all products from sources> check box
+  allFromSrcBtn = new QMyCheckBox( tr( "Install all products from sources" ), lessBox );
+  allFromSrcBtn->setChecked( forceSrc );
+  setAboutInfo( allFromSrcBtn, tr( "Check this box if you want to build\nall the products from sources.\n\nWarning: this is long-time operation!" ) );
+  lessBoxLayout->addWidget( allFromSrcBtn, 0, 0 );
+  lessBoxLayout->setRowStretch( 1, 10 );
+  //
+  // create <More...>/<Less...> button
+  // 
   moreBtn = new QPushButton( tr( "More..." ), productsPage );
-  // layouting
+  setAboutInfo( moreBtn, tr( "Switch to the advanced mode" ) );
+  //
+  // layout all widgets
+  //
+  QFrame* line = new QFrame( productsPage, "line" );
+  line->setFrameStyle( QFrame::HLine | QFrame::Sunken );
   pageLayout->addMultiCellWidget( targetLab,    0, 0, 0, 1 );
   pageLayout->addWidget         ( targetFolder, 1,    0    );
   pageLayout->addWidget         ( targetBtn,    1,    1    );
-  pageLayout->addMultiCellWidget( moreBox,      2, 2, 0, 1 );
-  pageLayout->addWidget         ( moreBtn,      3,    1    );
-  pageLayout->setRowStretch( 2, 5 );
-  //pageLayout->addRowSpacing( 6, 10 );
+  pageLayout->addMultiCellWidget( tempLab,      2, 2, 0, 1 );
+  pageLayout->addWidget         ( tempFolder,   3,    0    );
+  pageLayout->addWidget         ( tempBtn,      3,    1    );
+  pageLayout->addMultiCellWidget( moreBox,      4, 4, 0, 1 );
+  pageLayout->addMultiCellWidget( lessBox,      5, 5, 0, 1 );
+  pageLayout->addMultiCellWidget( line,         6, 6, 0, 1 );
+  pageLayout->addLayout         ( sizeLayout,   7,    0    );
+  pageLayout->addWidget         ( moreBtn,      7,    1    );
+  pageLayout->setRowStretch( 4, 5 );
+  pageLayout->setRowStretch( 5, 5 );
+  //
   // xml reader
+  //
   QFile xmlfile(xmlFileName);
   if ( xmlfile.exists() ) {
     QXmlInputSource source( &xmlfile );
@@ -580,8 +817,16 @@ void SALOME_InstallWizard::setupProductsPage()
     handler->setTargetDir(targetFolder);
     handler->setTempDir(tempFolder);
     reader.setContentHandler( handler );
-    reader.parse( source );  
-  }
+    reader.parse( source );
+  }
+  //
+  // take into account command line parameters
+  //
+  if ( !targetDirPath.isEmpty() )
+    targetFolder->setText( targetDirPath );
+  if ( !tmpDirPath.isEmpty() )
+    tempFolder->setText( tmpDirPath );
+
   // set first item to be selected
   if ( productsView->childCount() > 0 ) {
     productsView->setSelected( productsView->firstChild(), true );
@@ -590,21 +835,32 @@ void SALOME_InstallWizard::setupProductsPage()
   // adding page
   addPage( productsPage, tr( "Installation settings" ) );
   // connecting signals
-  connect( productsView, SIGNAL( selectionChanged() ), 
-                                              this, SLOT( onSelectionChanged() ) );
-  connect( productsView, SIGNAL( itemToggled( QCheckListItem* ) ), 
-                                              this, SLOT( onItemToggled( QCheckListItem* ) ) );
-  connect( unselectBtn,  SIGNAL( clicked() ), this, SLOT( onProdBtn() ) );
+  connect( productsView,  SIGNAL( selectionChanged() ),
+          this,          SLOT( onSelectionChanged() ) );
+  connect( productsView,  SIGNAL( itemToggled( QCheckListItem* ) ),
+          this,          SLOT( onItemToggled( QCheckListItem* ) ) );
+  connect( unselectBtn,   SIGNAL( clicked() ), 
+          this,          SLOT( onProdBtn() ) );
+  connect( selectSrcBtn,  SIGNAL( stateChanged(int) ),
+          this,          SLOT( onProdBtn() ) );
+  connect( selectBinBtn,  SIGNAL( stateChanged(int) ),
+          this,          SLOT( onProdBtn() ) );
+  connect( buildSrcBtn,   SIGNAL( stateChanged(int) ),
+          this,          SLOT( onProdBtn() ) );
+  connect( allFromSrcBtn, SIGNAL( stateChanged(int) ), 
+          this,          SLOT( onBuildAll() ) );
   // connecting signals
-  connect( targetFolder, SIGNAL( textChanged( const QString& ) ),
-                                              this, SLOT( directoryChanged( const QString& ) ) );
-  connect( targetBtn,    SIGNAL( clicked() ), this, SLOT( browseDirectory() ) );
-  connect( tempFolder,   SIGNAL( textChanged( const QString& ) ),
-                                              this, SLOT( directoryChanged( const QString& ) ) );
-  connect( tempBtn,      SIGNAL( clicked() ), this, SLOT( browseDirectory() ) );
-  connect( moreBtn,      SIGNAL( clicked() ), this, SLOT( onMoreBtn() ) );
+  connect( targetFolder,  SIGNAL( textChanged( const QString& ) ),
+          this,          SLOT( directoryChanged( const QString& ) ) );
+  connect( targetBtn,     SIGNAL( clicked() ), 
+          this,          SLOT( browseDirectory() ) );
+  connect( tempFolder,    SIGNAL( textChanged( const QString& ) ),
+          this,          SLOT( directoryChanged( const QString& ) ) );
+  connect( tempBtn,       SIGNAL( clicked() ), this, SLOT( browseDirectory() ) );
+  connect( moreBtn,       SIGNAL( clicked() ), this, SLOT( onMoreBtn() ) );
   // start on default - non-advanced - mode
   moreBox->hide();
+  onBuildAll();
 }
 // ================================================================
 /*!
@@ -616,15 +872,14 @@ void SALOME_InstallWizard::setupCheckPage()
 {
   // create page
   prestartPage = new QWidget( this, "PrestartPage" );
-  QVBoxLayout* pageLayout = new QVBoxLayout( prestartPage ); 
+  QVBoxLayout* pageLayout = new QVBoxLayout( prestartPage );
   pageLayout->setMargin( 0 ); pageLayout->setSpacing( 6 );
   // choice text view
   choices = new QTextEdit( prestartPage );
   choices->setReadOnly( true );
   choices->setTextFormat( RichText );
   choices->setUndoRedoEnabled ( false );
-  QWhatsThis::add( choices, tr( "Displays information about installation settings you made" ) );
-  QToolTip::add  ( choices, tr( "Displays information about installation settings you made" ) );
+  setAboutInfo( choices, tr( "Information about the installation choice you have made" ) );
   QPalette pal = choices->palette();
   pal.setColor( QColorGroup::Base, QApplication::palette().active().background() );
   choices->setPalette( pal );
@@ -645,29 +900,31 @@ void SALOME_InstallWizard::setupProgressPage()
 {
   // create page
   progressPage = new QWidget( this, "progressPage" );
-  QGridLayout* pageLayout = new QGridLayout( progressPage ); 
+  QGridLayout* pageLayout = new QGridLayout( progressPage );
   pageLayout->setMargin( 0 ); pageLayout->setSpacing( 6 );
   // top splitter
   splitter = new QSplitter( Vertical, progressPage );
   splitter->setOpaqueResize( true );
   // the parent for the widgets
   QWidget* widget = new QWidget( splitter );
-  QGridLayout* layout = new QGridLayout( widget ); 
+  QGridLayout* layout = new QGridLayout( widget );
   layout->setMargin( 0 ); layout->setSpacing( 6 );
   // installation progress view box
-  installInfo = new QTextEdit( widget );
+  installInfo = new InstallInfo( widget );
   installInfo->setReadOnly( true );
   installInfo->setTextFormat( RichText );
   installInfo->setUndoRedoEnabled ( false );
   installInfo->setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Expanding ) );
   installInfo->setMinimumSize( 100, 10 );
-  QWhatsThis::add( installInfo, tr( "Displays installation process" ) );
-  QToolTip::add  ( installInfo, tr( "Displays installation process" ) );
+  setAboutInfo( installInfo, tr( "Installation process output" ) );
   // parameters for the script
   parametersLab = new QLabel( tr( "Enter your answer here:" ), widget );
   passedParams = new QLineEdit ( widget );
-  QWhatsThis::add( passedParams, tr( "Use this field to enter answer for the running script when it is necessary") );
-  QToolTip::add  ( passedParams, tr( "Use this field to enter answer for the running script when it is necessary") );
+  setAboutInfo( passedParams, tr( "Use this field to enter the answer\nfor the running script when it is necessary") );
+  // VSR: 10/11/05 - disable answer mode ==>
+  parametersLab->hide();
+  passedParams->hide();
+  // VSR: 10/11/05 - disable answer mode <==
   // layouting
   layout->addWidget( installInfo,   0, 0 );
   layout->addWidget( parametersLab, 1, 0 );
@@ -675,15 +932,14 @@ void SALOME_InstallWizard::setupProgressPage()
   layout->addRowSpacing( 3, 6 );
   // the parent for the widgets
   widget = new QWidget( splitter );
-  layout = new QGridLayout( widget ); 
+  layout = new QGridLayout( widget );
   layout->setMargin( 0 ); layout->setSpacing( 6 );
   // installation results view box
   QLabel* resultLab = new QLabel( tr( "Installation Status:" ), widget );
   progressView = new ProgressView( widget );
   progressView->setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Expanding ) );
   progressView->setMinimumSize( 100, 10 );
-  QWhatsThis::add( progressView, tr( "Displays installation status" ) );
-  QToolTip::add  ( progressView, tr( "Displays installation status" ) );
+  setAboutInfo( progressView, tr( "Installation status on the selected products" ) );
   // layouting
   layout->addRowSpacing( 0, 6 );
   layout->addWidget( resultLab,    1, 0 );
@@ -705,32 +961,41 @@ void SALOME_InstallWizard::setupReadmePage()
 {
   // create page
   readmePage = new QWidget( this, "ReadmePage" );
-  QVBoxLayout* pageLayout = new QVBoxLayout( readmePage ); 
+  QVBoxLayout* pageLayout = new QVBoxLayout( readmePage );
   pageLayout->setMargin( 0 ); pageLayout->setSpacing( 6 );
   // README info text box
   readme = new QTextEdit( readmePage );
   readme->setReadOnly( true );
   readme->setTextFormat( PlainText );
-  readme->setFont( QFont( "Fixed", 10 ) );
+  readme->setFont( QFont( "Fixed", 12 ) );
   readme->setUndoRedoEnabled ( false );
-  QWhatsThis::add( readme, tr( "Displays README information" ) );
-  QToolTip::add  ( readme, tr( "Displays README information" ) );
+  setAboutInfo( readme, tr( "README information" ) );
   QPalette pal = readme->palette();
   pal.setColor( QColorGroup::Base, QApplication::palette().active().background() );
   readme->setPalette( pal );
   readme->setMinimumHeight( 10 );
-  // <Launch SALOME> button
-  runSalomeBtn = new QPushButton( tr( "Launch SALOME" ), readmePage );
-  QWhatsThis::add( runSalomeBtn, tr( "Click this button to run SALOME desktop" ) );
-  QToolTip::add  ( runSalomeBtn, tr( "Click this button to run SALOME desktop" ) );
-  QHBoxLayout* hLayout = new QHBoxLayout;
-  hLayout->addWidget( runSalomeBtn ); hLayout->addStretch();
-  // layouting
+
   pageLayout->addWidget( readme );
   pageLayout->setStretchFactor( readme, 5 );
-  pageLayout->addLayout( hLayout );
-  // connecting signals
-  connect( runSalomeBtn, SIGNAL( clicked() ), this, SLOT( onLaunchSalome() ) );
+
+  // Operation buttons
+  if ( buttons.count() > 0 ) {
+    QHBoxLayout* hLayout = new QHBoxLayout;
+    hLayout->setMargin( 0 ); hLayout->setSpacing( 6 );
+    ButtonList::Iterator it;
+    for ( it = buttons.begin(); it != buttons.end(); ++it ) {
+      QButton* b = new QPushButton( tr( (*it).label() ), readmePage );
+      if ( !(*it).tootip().isEmpty() ) {
+       setAboutInfo( b, tr( (*it).tootip() ) );
+      }
+      hLayout->addWidget( b );
+      (*it).setButton( b );
+      connect( b, SIGNAL( clicked() ), this, SLOT( onFinishButton() ) );
+    }
+    hLayout->addStretch();
+    pageLayout->addLayout( hLayout );
+  }
+
   // loading README file
   QString readmeFile = QDir::currentDirPath() + "/README";
   QString text;
@@ -738,6 +1003,7 @@ void SALOME_InstallWizard::setupReadmePage()
     readme->setText( text );
   else
     readme->setText( tr( "README file has not been found" ) );
+
   // adding page
   addPage( readmePage, tr( "Finish installation" ) );
 }
@@ -761,16 +1027,16 @@ void SALOME_InstallWizard::showChoiceInfo()
     text += "<br>";
   }
   if ( !myOS.isEmpty() ) {
-    text += tr( "Target platform" ) + ": <b>" + myOS + "</b><br>";
+    text += tr( "Reference Linux platform" ) + ": <b>" + myOS + "</b><br>";
     text += "<br>";
   }
-  text += tr( "Products to be used" ) + ":<ul>";
+  text += tr( "Native products to be used" ) + ":<ul>";
   QCheckListItem* item = (QCheckListItem*)( productsView->firstChild() );
   while( item ) {
     if ( productsMap.contains( item ) ) {
       if ( item->childCount() > 0 ) {
         if ( productsView->isNative( item ) ) {
-          text += "<li><b>" + item->text() + "</b> " + tr( "as native" ) + "<br>";
+          text += "<li><b>" + item->text() + "</b><br>";
           nbProd++;
         }
       }
@@ -786,13 +1052,18 @@ void SALOME_InstallWizard::showChoiceInfo()
   item = (QCheckListItem*)( productsView->firstChild() );
   while( item ) {
     if ( productsMap.contains( item ) ) {
+      if ( productsMap[ item ].hasContext( "salome sources" ) || 
+          productsMap[ item ].hasContext( "salome binaries" ) ) {
+       item = (QCheckListItem*)( item->nextSibling() );
+       continue; // skip SALOME sources and binaries
+      }
       if ( item->childCount() > 0 ) {
         if ( productsView->isBinaries( item ) ) {
-          text += "<li><b>" + item->text() + "</b> " + tr( "as binaries" ) + "<br>";
+          text += "<li><b>" + item->text() + " " + item->text(1) + "</b> " + tr( "as binaries" ) + "<br>";
           nbProd++;
         }
         else if ( productsView->isSources( item ) ) {
-          text+= "<li><b>" + item->text() + "</b> " + tr( "as sources" ) + "<br>";
+          text+= "<li><b>" + item->text() + " " + item->text(1) + "</b> " + tr( "as sources" ) + "<br>";
           nbProd++;
         }
       }
@@ -807,6 +1078,40 @@ void SALOME_InstallWizard::showChoiceInfo()
     text += "<li><b>" + tr( "none" ) + "</b><br>";
   }
   text += "</ul>";
+  // SALOME binaries, sources, samples
+  QString textBin  = "";
+  QString textSrc  = "";
+  QString textBoth = "";
+  item = (QCheckListItem*)( productsView->firstChild() );
+  while( item ) {
+    if ( productsMap.contains( item ) ) {
+      if ( !productsMap[ item ].hasContext( "salome sources" ) &&
+          productsMap[ item ].hasContext( "salome binaries" ) ) {
+       if ( ( item->childCount() > 0 && productsView->isBinaries( item ) || item->isOn() ) && item->isEnabled() ) {
+         textBin += "<li><b>" + item->text().replace( QRegExp( "(-)?bin", false ), "" ) + "</b><br>";
+        }
+      }
+      if ( productsMap[ item ].hasContext( "salome sources" ) &&
+          !productsMap[ item ].hasContext( "salome binaries" ) ) {
+       if ( item->childCount() > 0 && productsView->isSources( item ) || item->isOn() ) {
+         textSrc += "<li><b>" + item->text().replace( QRegExp( "(-)?src", false ), "" ) + "</b><br>";
+        }
+      }
+      if ( productsMap[ item ].hasContext( "salome sources" ) &&
+          productsMap[ item ].hasContext( "salome binaries" ) ) {
+       if ( item->childCount() > 0 && productsView->isSources( item ) || item->isOn() ) {
+         textBoth += "<li><b>" + item->text() + "</b><br>";
+        }
+      }
+    }
+    item = (QCheckListItem*)( item->nextSibling() );
+  }
+  if ( !textBin.isEmpty() )
+    text += tr( "SALOME binaries to be installed" ) + ":<ul>" + textBin + "</ul>";
+  if ( !textSrc.isEmpty() )
+    text += tr( "SALOME sources to be installed" ) + ( buildSrcBtn->isChecked() ? tr( " and build" ) : QString( "" ) )  + ":<ul>" + textSrc + "</ul>";
+  if ( !textBoth.isEmpty() )
+    text += tr( "Other SALOME modules to be installed" ) + ":<ul>" + textBoth + "</ul>";
   text += tr( "Total disk space required:" ) + " <b>" + QString::number( totSize ) + " Kb</b><br>" ;
   text += tr( "Space for temporary files required:" ) + " <b>" + QString::number( tempSize ) + " Kb</b><br>" ;
   text += "<br>";
@@ -814,7 +1119,7 @@ void SALOME_InstallWizard::showChoiceInfo()
   // VSR: Temporary folder is used always now and it is not necessary to disable it -->
   // if ( tempSize > 0 )
   // VSR: <----------------------------------------------------------------------------
-  text += tr( "Temp directory:" ) + " <b>" + QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + "</b><br>";
+  text += tr( "Temporary directory:" ) + " <b>" + QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + "</b><br>";
   text += "<br>";
   choices->setText( text );
 }
@@ -833,10 +1138,10 @@ bool SALOME_InstallWizard::acceptData( const QString& pageTitle )
     long totSize, tempSize;
     bool anySelected = checkSize( &totSize, &tempSize );
     if ( !anySelected ) {
-      QMessageBox::warning( this, 
-                            tr( "Warning" ), 
-                            tr( "Select one or more products to install" ), 
-                            QMessageBox::Ok, 
+      QMessageBox::warning( this,
+                            tr( "Warning" ),
+                            tr( "Select one or more products to install" ),
+                            QMessageBox::Ok,
                             QMessageBox::NoButton,
                             QMessageBox::NoButton );
       return false;
@@ -847,62 +1152,62 @@ bool SALOME_InstallWizard::acceptData( const QString& pageTitle )
     QString tempDir   = QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() );
     // directories should differ
 //    if (!targetDir.isEmpty() && tempDir == targetDir) {
-//      QMessageBox::warning( this, 
-//                         tr( "Warning" ), 
-//                         tr( "Target and temporary directories must be different"), 
-//                         QMessageBox::Ok, 
-//                         QMessageBox::NoButton, 
+//      QMessageBox::warning( this,
+//                         tr( "Warning" ),
+//                         tr( "Target and temporary directories must be different"),
+//                         QMessageBox::Ok,
+//                         QMessageBox::NoButton,
 //                         QMessageBox::NoButton );
 //     return false;
 //    }
     // check target directory
     if ( targetDir.isEmpty() ) {
-      QMessageBox::warning( this, 
-                            tr( "Warning" ), 
-                            tr( "Please, enter valid target directory path" ), 
-                            QMessageBox::Ok, 
+      QMessageBox::warning( this,
+                            tr( "Warning" ),
+                            tr( "Please, enter valid target directory path" ),
+                            QMessageBox::Ok,
                             QMessageBox::NoButton,
                             QMessageBox::NoButton );
       return false;
     }
     QFileInfo fi( QDir::cleanDirPath( targetDir ) );
     if ( !fi.exists() ) {
-      bool toCreate = 
-       QMessageBox::warning( this, 
-                             tr( "Warning" ), 
+      bool toCreate =
+       QMessageBox::warning( this,
+                             tr( "Warning" ),
                              tr( "The directory %1 doesn't exist.\n"
-                                 "Do you want to create directory?" ).arg( fi.absFilePath() ), 
-                             QMessageBox::Yes, 
+                                 "Create directory?" ).arg( fi.absFilePath() ),
+                             QMessageBox::Yes,
                              QMessageBox::No,
                              QMessageBox::NoButton ) == QMessageBox::Yes;
-      if ( !toCreate) 
+      if ( !toCreate)
        return false;
       if ( !makeDir( fi.absFilePath(), tmpstr ) ) {
-       QMessageBox::critical( this, 
-                              tr( "Error" ), 
-                              tr( "Can't create the directory\n%1").arg( fi.absFilePath() ), 
-                              QMessageBox::Ok, 
-                              QMessageBox::NoButton, 
+       QMessageBox::critical( this,
+                              tr( "Error" ),
+                              tr( "Can't create the directory\n%1").arg( fi.absFilePath() ),
+                              QMessageBox::Ok,
+                              QMessageBox::NoButton,
                               QMessageBox::NoButton );
        return false;
       }
     }
     if ( !fi.isDir() ) {
-      QMessageBox::warning( this, 
-                            tr( "Warning" ), 
-                            tr( "The directory %1 is not a directory.\n"
-                               "Please, enter valid target directory path" ).arg( fi.absFilePath() ), 
-                            QMessageBox::Ok, 
+      QMessageBox::warning( this,
+                            tr( "Warning" ),
+                            tr( "%1 is not a directory.\n"
+                               "Please, enter valid target directory path" ).arg( fi.absFilePath() ),
+                            QMessageBox::Ok,
                             QMessageBox::NoButton,
                             QMessageBox::NoButton );
       return false;
     }
     if ( !fi.isWritable() ) {
-      QMessageBox::warning( this, 
-                            tr( "Warning" ), 
+      QMessageBox::warning( this,
+                            tr( "Warning" ),
                             tr( "The directory %1 is not writeable.\n"
-                               "Please, enter valid target directory path or change permissions" ).arg( fi.absFilePath() ), 
-                            QMessageBox::Ok, 
+                               "Please, enter valid target directory path or change permissions" ).arg( fi.absFilePath() ),
+                            QMessageBox::Ok,
                             QMessageBox::NoButton,
                             QMessageBox::NoButton );
       return false;
@@ -918,41 +1223,82 @@ bool SALOME_InstallWizard::acceptData( const QString& pageTitle )
                               QMessageBox::NoButton ) == QMessageBox::No ) {
       return false;
     }
-    QString binDir = "./Products/BINARIES";
-    if ( !myOS.isEmpty() )
-      binDir += "/" + myOS;
-    QFileInfo fib( QDir::cleanDirPath( binDir ) );
-    if ( !fib.exists() ) {
-      QMessageBox::warning( this, 
-                           tr( "Warning" ), 
-                           tr( "The directory %1 doesn't exist.\n"
-                               "This directory must contain binaries archives." ).arg( fib.absFilePath() ));
+    // check sources/binaries archives directories existance
+    int nbSources = 0, nbBinaries = 0;
+    QCheckListItem* nitem = (QCheckListItem*)( productsView->firstChild() );
+    while( nitem ) {
+      if ( productsMap.contains( nitem ) ) {
+       if ( nitem->childCount() > 0 ) {
+         if ( productsView->isBinaries( nitem ) )
+           nbBinaries++;
+         else if ( productsView->isSources( nitem ) )
+           nbSources++;
+       }
+       else if ( nitem->isOn() ) {
+         nbBinaries++;
+         nbSources++;
+       }
+      }
+      nitem = (QCheckListItem*)( nitem->nextSibling() );
+    }
+
+    if ( nbBinaries > 0 ) {
+      QString binDir = "./Products/BINARIES";
+      if ( !myOS.isEmpty() )
+       binDir += "/" + myOS;
+      QFileInfo fib( QDir::cleanDirPath( binDir ) );
+      if ( !fib.exists() ) {
+       if ( QMessageBox::warning( this,
+                                  tr( "Warning" ),
+                                  tr( "The directory %1 doesn't exist.\n"
+                                      "This directory must contain binaries archives.\n"
+                                      "Continue?" ).arg( fib.absFilePath() ),
+                                  QMessageBox::Yes,
+                                  QMessageBox::No,
+                                  QMessageBox::NoButton ) == QMessageBox::No )
+         return false;
+      }
+    }
+    if ( nbSources > 0 ) {
+      QString srcDir = "./Products/SOURCES";
+      QFileInfo fis( QDir::cleanDirPath( srcDir ) );
+      if ( !fis.exists() ) {
+       if ( QMessageBox::warning( this,
+                                  tr( "Warning" ),
+                                  tr( "The directory %1 doesn't exist.\n"
+                                      "This directory must contain sources archives.\n"
+                                      "Continue?" ).arg( fis.absFilePath() ),
+                                  QMessageBox::Yes,
+                                  QMessageBox::No,
+                                  QMessageBox::NoButton ) == QMessageBox::No )
+         return false;
+      }
     }
     // run script that checks available disk space for installing of products    // returns 1 in case of error
     QString script = "./config_files/checkSize.sh '";
     script += fi.absFilePath();
     script += "' ";
     script += QString( "%1" ).arg( totSize );
-    ___MESSAGE___( "script = " << script );
+    ___MESSAGE___( "script = " << script.latin1() );
     if ( system( script ) ) {
-      QMessageBox::critical( this, 
-                             tr( "Out of space" ), 
-                             tr( "There is not available disk space for installing of selected products" ), 
-                             QMessageBox::Ok, 
-                             QMessageBox::NoButton, 
+      QMessageBox::critical( this,
+                             tr( "Out of space" ),
+                             tr( "There is no available disk space for installing of selected products" ),
+                             QMessageBox::Ok,
+                             QMessageBox::NoButton,
                              QMessageBox::NoButton );
       return false;
     }
     // check temp directory
     if ( tempDir.isEmpty() ) {
       if ( moreMode ) {
-       QMessageBox::warning( this, 
-                             tr( "Warning" ), 
-                             tr( "Please, enter valid temp directory path" ), 
-                             QMessageBox::Ok, 
+       QMessageBox::warning( this,
+                             tr( "Warning" ),
+                             tr( "Please, enter valid temporary directory path" ),
+                             QMessageBox::Ok,
                              QMessageBox::NoButton,
                              QMessageBox::NoButton );
-       return false; 
+       return false;
       }
       else {
        tempDir = "/tmp";
@@ -961,11 +1307,11 @@ bool SALOME_InstallWizard::acceptData( const QString& pageTitle )
     }
     QFileInfo fit( QDir::cleanDirPath( tempDir ) );
     if ( !makeDir( fit.absFilePath() + TEMPDIRNAME, tmpCreated ) ) {
-      QMessageBox::critical( this, 
-                            tr( "Error" ), 
-                            tr( "Can't use temporary directory.\nCheck permissions for the %1 directory.").arg( fit.absFilePath() ), 
-                            QMessageBox::Ok, 
-                            QMessageBox::NoButton, 
+      QMessageBox::critical( this,
+                            tr( "Error" ),
+                            tr( "Can't use temporary directory.\nCheck permissions for the %1 directory.").arg( fit.absFilePath() ),
+                            QMessageBox::Ok,
+                            QMessageBox::NoButton,
                             QMessageBox::NoButton );
       return false;
     }
@@ -975,13 +1321,13 @@ bool SALOME_InstallWizard::acceptData( const QString& pageTitle )
     tscript += fit.absFilePath();
     tscript += "' ";
     tscript += QString( "%1" ).arg( tempSize );
-    ___MESSAGE___( "script = " << tscript );
+    ___MESSAGE___( "script = " << tscript.latin1() );
     if ( system( tscript ) ) {
-      QMessageBox::critical( this, 
-                            tr( "Out of space" ), 
-                            tr( "There is not available disk space for the temporary files" ), 
-                            QMessageBox::Ok, 
-                            QMessageBox::NoButton, 
+      QMessageBox::critical( this,
+                            tr( "Out of space" ),
+                            tr( "There is no available disk space for the temporary files" ),
+                            QMessageBox::Ok,
+                            QMessageBox::NoButton,
                             QMessageBox::NoButton );
       return false;
     }
@@ -992,35 +1338,46 @@ bool SALOME_InstallWizard::acceptData( const QString& pageTitle )
     while( item ) {
       if ( productsMap.contains( item ) ) {
        if ( item->childCount() > 0 ) {
-         if ( !productsView->isNone( item ) ) {
+         // VSR : 29/01/05 : Check installation script even if product is not being installed
+         //      if ( !productsView->isNone( item ) ) {
            if ( item->text(2).isEmpty() || item->text(2).isNull() ) {
-             QMessageBox::warning( this, 
-                                   tr( "Warning" ), 
-                                   tr( "You don't have a defined script for %1").arg(item->text(0)), 
-                                   QMessageBox::Ok, 
-                                   QMessageBox::NoButton, 
+             QMessageBox::warning( this,
+                                   tr( "Error" ),
+                                   tr( "The installation script for %1 is not defined.").arg(item->text(0)),
+                                   QMessageBox::Ok,
+                                   QMessageBox::NoButton,
                                    QMessageBox::NoButton );
-             productsView->setNone( item );
+              if ( !moreMode )
+               onMoreBtn();
+             productsView->setCurrentItem( item );
+             productsView->setSelected( item, true );
+             productsView->ensureItemVisible( item );
+             //productsView->setNone( item );
              return false;
            } else {
              QFileInfo fi( QString("./config_files/") + item->text(2) );
-             if ( !fi.exists() ) {
-               QMessageBox::warning( this, 
-                                     tr( "Warning" ),  
-                                     tr( "%1 required for %2 doesn't exist.").arg("./config_files/" + item->text(2)).arg(item->text(0)),  
-                                     QMessageBox::Ok, 
-                                     QMessageBox::NoButton, 
+             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)),
+                                     QMessageBox::Ok,
+                                     QMessageBox::NoButton,
                                      QMessageBox::NoButton );
-               productsView->setNone( item );
+                if ( !moreMode )
+                 onMoreBtn();
+               productsView->setCurrentItem( item );
+               productsView->setSelected( item, true );
+               productsView->ensureItemVisible( item );
+               //productsView->setNone( item );
                return false;
-             }       
+             }
            }
-         }
+           //    }
          // collect native products
          if ( productsView->isNative( item ) ) {
            if ( natives.find( item->text(0) ) == natives.end() )
              natives.append( item->text(0) );
-         } 
+         }
          else if ( productsView->isBinaries( item ) || productsView->isSources( item ) ) {
            QStringList dependOn = productsMap[ item ].getDependancies();
            for ( int i = 0; i < (int)dependOn.count(); i++ ) {
@@ -1028,14 +1385,14 @@ bool SALOME_InstallWizard::acceptData( const QString& pageTitle )
              if ( depitem ) {
                if ( productsView->isNative( depitem ) && natives.find( depitem->text(0) ) == natives.end() )
                  natives.append( depitem->text(0) );
-             } 
+             }
              else {
-               QMessageBox::warning( this, 
-                                     tr( "Warning" ), 
+               QMessageBox::warning( this,
+                                     tr( "Error" ),
                                      tr( "%1 is required for %2 %3 installation.\n"
-                                         "Please, add this product in config.xml file.").arg(dependOn[ i ]).arg(item->text(0)).arg(item->text(1)), 
-                                     QMessageBox::Ok, 
-                                     QMessageBox::NoButton, 
+                                         "This product is missing in the configuration file %4.").arg(dependOn[ i ]).arg(item->text(0)).arg(item->text(1)).arg(xmlFileName),
+                                     QMessageBox::Ok,
+                                     QMessageBox::NoButton,
                                      QMessageBox::NoButton );
                return false;
              }
@@ -1048,30 +1405,32 @@ bool SALOME_InstallWizard::acceptData( const QString& pageTitle )
     QString tmpFolder = QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + TEMPDIRNAME;
     QString tgtFolder = QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() );
     myThread->clearCommands();
-    for ( unsigned i = 0; i < natives.count(); i++ ) {
-      item = findItem( natives[ i ] );
-      if ( item ) {
-       QString dependOn = productsMap[ item ].getDependancies().join(" ");
-       QString script = "cd ./config_files/;" + item->text(2) + " try_native " +
-               QFileInfo( tmpFolder ).absFilePath() + " " + QDir::currentDirPath() + "/Products " + QFileInfo( tgtFolder ).absFilePath() + " " +
-               QUOTE(dependOn) + " " + item->text(0);
-
-       myThread->addCommand( item, script );
-      }
-      else {
-       QMessageBox::warning( this, 
-                             tr( "Warning" ), 
-                             tr( "%The product %1 %2 required for installation.\n"
-                                 "Please, add this product in config.xml file.").arg(item->text(0)).arg(item->text(1)),
-                             QMessageBox::Ok, 
-                             QMessageBox::NoButton, 
-                             QMessageBox::NoButton );
-       return false;
+    if ( natives.count() > 0 ) {
+      for ( unsigned i = 0; i < natives.count(); i++ ) {
+       item = findItem( natives[ i ] );
+       if ( item ) {
+         QString dependOn = productsMap[ item ].getDependancies().join(" ");
+         QString script = "cd ./config_files/;" + item->text(2) + " try_native " +
+                 QFileInfo( tmpFolder ).absFilePath() + " " + QDir::currentDirPath() + "/Products " + QFileInfo( tgtFolder ).absFilePath() + " " +
+                 QUOTE(dependOn) + " " + item->text(0);
+
+         myThread->addCommand( item, script );
+       }
+       else {
+         QMessageBox::warning( this,
+                               tr( "Warning" ),
+                               tr( "%The product %1 %2 required for installation.\n"
+                                   "This product is missing in the configuration file %4.").arg(item->text(0)).arg(item->text(1)).arg(xmlFileName),
+                               QMessageBox::Ok,
+                               QMessageBox::NoButton,
+                               QMessageBox::NoButton );
+         return false;
+       }
       }
+      WarnDialog::showWarnDlg( this, true );
+      myThread->start();
+      return true; // return in order to avoid default postValidateEvent() action
     }
-    WarnDialog::showWarnDlg( this, true );
-    myThread->start();
-    return true; // return in order to avoid default postValidateEvent() action
   }
   return InstallWizard::acceptData( pageTitle );
 }
@@ -1094,13 +1453,13 @@ bool SALOME_InstallWizard::checkSize( long* totSize, long* tempSize )
       tots += dep.getSize();
     }
     else if ( productsView->isSources( item ) ) {
-      tots += dep.getSize(true);
+      tots += dep.getSize( !buildSrcBtn->isChecked() );
       temps = max( temps, dep.getTempSize() );
     }
     if ( !productsView->isNone( item ) )
       nbSelected++;
   }
+
   if ( totSize )
     *totSize = tots;
   if ( tempSize )
@@ -1116,6 +1475,48 @@ bool SALOME_InstallWizard::checkSize( long* totSize, long* tempSize )
 // ================================================================
 void SALOME_InstallWizard::checkProductPage()
 {
+  // update <SALOME sources>, <SALOME binaries> check boxes state
+
+  selectSrcBtn->blockSignals( true );
+  selectBinBtn->blockSignals( true );
+
+  int totSrc = 0, selSrc = 0;
+  MapProducts::Iterator itProd;
+  for ( itProd = productsMap.begin(); itProd != productsMap.end(); ++itProd ) {
+    bool srcctx = itProd.data().hasContext( "salome sources" );
+    bool binctx = itProd.data().hasContext( "salome binaries" );
+    if ( srcctx && !binctx ) {
+      totSrc++;
+      if ( productsView->isSources( itProd.key() ) )
+       selSrc++;
+    }
+  }
+  selectSrcBtn->setState( selSrc == 0 ? QButton::Off : ( selSrc == totSrc ? QButton::On : QButton::NoChange  ) );
+
+  buildSrcBtn->setEnabled( selSrc > 0 );
+  selectBinBtn->setEnabled( !buildSrcBtn->isEnabled() || !buildSrcBtn->isChecked() ); 
+  for ( itProd = productsMap.begin(); itProd != productsMap.end(); ++itProd ) {
+    if ( itProd.data().hasContext( "salome sources" ) && !itProd.data().hasContext( "salome binaries" ) ) {
+      productsView->setItemEnabled( productsView->findBinItem( itProd.data().getName() ) , 
+                                   !productsView->isSources( itProd.key() ) || !buildSrcBtn->isChecked() );
+    }
+  }
+
+  int totBin = 0, selBin = 0;
+  for ( itProd = productsMap.begin(); itProd != productsMap.end(); ++itProd ) {
+    bool srcctx = itProd.data().hasContext( "salome sources" );
+    bool binctx = itProd.data().hasContext( "salome binaries" );
+    if ( binctx && !srcctx ) {
+      totBin++;
+      if ( productsView->isBinaries( itProd.key() ) )
+       selBin++;
+    }
+  }
+  selectBinBtn->setState( selBin == 0 ? QButton::Off : ( selBin == totBin ? QButton::On : QButton::NoChange  ) );
+
+  selectSrcBtn->blockSignals( false );
+  selectBinBtn->blockSignals( false );
+
   long tots = 0, temps = 0;
 
   // check if any product is selected;
@@ -1216,7 +1617,11 @@ void SALOME_InstallWizard::launchScript()
     }
     // ... sources ?
     else if ( productsView->isSources( item ) ) {
-      shellProcess->addArgument( "install_source" );
+      shellProcess->addArgument( productsMap[ item ].hasContext( "salome sources" )   && 
+                                //!productsMap[ item ].hasContext( "salome binaries" ) && 
+                                buildSrcBtn->isChecked() ?
+                                "install_source_and_build" : 
+                                "install_source" );
       shellProcess->addArgument( QFileInfo( tmpFolder ).absFilePath() );
       shellProcess->addArgument( QDir::currentDirPath() + "/Products/SOURCES" );
     }
@@ -1235,9 +1640,9 @@ void SALOME_InstallWizard::launchScript()
     // ... target folder
     QString tgtFolder = QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() );
     shellProcess->addArgument( QFileInfo( tgtFolder ).absFilePath() );
-    
 
-    QString depproducts = DefineDependeces(productsMap); 
+
+    QString depproducts = DefineDependeces(productsMap);
     ___MESSAGE___( "Dependancies"<< depproducts.latin1() );
 
     shellProcess->addArgument( depproducts );
@@ -1259,9 +1664,9 @@ void SALOME_InstallWizard::launchScript()
   for ( mapIter = productsMap.begin(); mapIter != productsMap.end(); ++mapIter ) {
     QCheckListItem* item = mapIter.key();
     Dependancies dep = mapIter.data();
-    QString depproducts = QUOTE( DefineDependeces(productsMap) ); 
-    if ( dep.pickUpEnvironment() ) {
-      ___MESSAGE___( "... for " << dep.getName() );
+    QString depproducts = QUOTE( DefineDependeces(productsMap) );
+    if ( !productsView->isNone( item ) && dep.pickUpEnvironment() ) {
+      ___MESSAGE___( "... for " << dep.getName().latin1() );
       QString script;
       script += "cd " + QUOTE( QFileInfo( QDir::cleanDirPath( "./config_files/" ) ).absFilePath() ) + "; ";
       script += item->text(2) + " ";
@@ -1272,24 +1677,25 @@ void SALOME_InstallWizard::launchScript()
       script += depproducts + " ";
       script += item->text(0);
       ___MESSAGE___( "... --> " << script.latin1() );
-      if ( system( script.latin1() ) ) { 
-       ___MESSAGE___( "ERROR" ); 
+      if ( system( script.latin1() ) ) {
+       ___MESSAGE___( "ERROR" );
       }
     }
   }
   // <Next> button
-  nextButton()->setEnabled( true );
+  setNextEnabled( true );
   nextButton()->setText( tr( "&Next >" ) );
-  QWhatsThis::add( nextButton(), tr( "Moves to the next step of the installation procedure" ) );
-  QToolTip::add  ( nextButton(), tr( "Moves to the next step of the installation procedure" ) );
-  nextButton()->disconnect();
-  connect( nextButton(), SIGNAL( clicked() ), this, SLOT( 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() ) );
+  connect(    this, SIGNAL( nextClicked() ), this, SLOT( next() ) );
   // <Back> button
-  backButton()->setEnabled( true );
+  setBackEnabled( true );
   // script parameters
   passedParams->clear();
   passedParams->setEnabled( false );
   QFont f = parametersLab->font(); f.setBold( false ); parametersLab->setFont( f );
+  installInfo->setFinished( true );
   if ( isMinimized() )
     showNormal();
   raise();
@@ -1304,11 +1710,15 @@ void SALOME_InstallWizard::onMoreBtn()
 {
   if ( moreMode ) {
     moreBox->hide();
+    lessBox->show();
     moreBtn->setText( tr( "More..." ) );
+    setAboutInfo( moreBtn, tr( "Switch to the advanced mode" ) );
   }
   else {
     moreBox->show();
+    lessBox->hide();
     moreBtn->setText( tr( "Less..." ) );
+    setAboutInfo( moreBtn, tr( "Switch to the basic mode" ) );
   }
   qApp->processEvents();
   moreMode = !moreMode;
@@ -1323,49 +1733,52 @@ void SALOME_InstallWizard::onMoreBtn()
 }
 // ================================================================
 /*!
- *  SALOME_InstallWizard::onLaunchSalome
- *  <Launch Salome> button slot
+ *  SALOME_InstallWizard::onFinishButton
+ *  Operation buttons slot
  */
 // ================================================================
-void SALOME_InstallWizard::onLaunchSalome()
+void SALOME_InstallWizard::onFinishButton()
 {
-  QString msg = tr( "You don't have SALOME binaries installed in the %1 directory!" ).arg( targetFolder->text() );
-
-  QCheckListItem* item = findItem( "KERNEL-Bin" );
-  if ( item ) {
-    QFileInfo fi( targetFolder->text() + "/KERNEL_" + item->text(1) + "/bin/salome/runSalome" );
-    QFileInfo fienv( targetFolder->text() + "/KERNEL_" + item->text(1) + "/salome.csh" );
-    if ( fienv.exists() ) {
-      if ( fi.exists() ) {
-       QString script;
-       script += "cd " + targetFolder->text() + "/KERNEL_" + item->text(1) + "; ";
-       script += "source salome.csh; ";
-       script += "cd bin/salome; ";
-       script += "runSalome > /dev/null";
-       script = "(csh -c '" + script + "')";
-       ___MESSAGE___( "script: " << script.latin1() );
-       if ( !system( script.latin1() ) )
-         return;
-       else
-         msg = tr( "Can't launch SALOME." );
+  const QObject* btn = sender();
+  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() ) ) {
+       QMessageBox::warning( this,
+                             tr( "Error" ),
+                             tr( "Can't perform action!"),
+                             QMessageBox::Ok,
+                             QMessageBox::NoButton,
+                             QMessageBox::NoButton );
       }
-      else
-       msg = tr( "Can't launch SALOME." ) + "\n" + tr( "runSalome file can not be found." );
+      return;
     }
-    else
-      msg = tr( "Can't launch SALOME." ) + "\n" + tr( "Can't find environment file." );
-  }
-  QMessageBox::warning( this, 
-                       tr( "Error" ), 
-                       msg,
-                       QMessageBox::Ok, 
-                       QMessageBox::NoButton,
-                       QMessageBox::NoButton );
+  }
 }
+// ================================================================
+/*!
+ *  SALOME_InstallWizard::onAbout
+ *  <About> button slot: shows <About> dialog box
+ */
+// ================================================================
+void SALOME_InstallWizard::onAbout()
+{
+  AboutDlg d( this );
+  d.exec();
+}
+
 // ================================================================
 /*!
  *  SALOME_InstallWizard::findItem
- *  Searches product listview item with given symbolic name 
+ *  Searches product listview item with given symbolic name
  */
 // ================================================================
 QCheckListItem* SALOME_InstallWizard::findItem( const QString& sName )
@@ -1406,10 +1819,10 @@ void SALOME_InstallWizard::reject()
 {
   ___MESSAGE___( "REJECTED" );
   if ( !exitConfirmed ) {
-    if ( QMessageBox::information( this, 
-                                  tr( "Exit" ), 
-                                  tr( "Do you want to quit %1?" ).arg( getIWName() ), 
-                                  tr( "&Yes" ), 
+    if ( QMessageBox::information( this,
+                                  tr( "Exit" ),
+                                  tr( "Do you want to quit %1?" ).arg( getIWName() ),
+                                  tr( "&Yes" ),
                                   tr( "&No" ),
                                   QString::null,
                                   0,
@@ -1451,7 +1864,7 @@ void SALOME_InstallWizard::clean(bool rmDir)
   script += "' ";
   script += QUOTE(DefineDependeces(productsMap));
   script += " > /dev/null";
-  ___MESSAGE___( "script = " << script );
+  ___MESSAGE___( "script = " << script.latin1() );
   if ( system( script.latin1() ) ) {
   }
   // VSR: then try to remove created temporary directory
@@ -1461,7 +1874,7 @@ void SALOME_InstallWizard::clean(bool rmDir)
     script += " > /dev/null";
     if ( system( script.latin1() ) ) {
     }
-    ___MESSAGE___( "script = " << script );
+    ___MESSAGE___( "script = " << script.latin1() );
   }
 }
 // ================================================================
@@ -1473,10 +1886,10 @@ void SALOME_InstallWizard::clean(bool rmDir)
 void SALOME_InstallWizard::pageChanged( const QString & mytitle)
 {
   nextButton()->setText( tr( "&Next >" ) );
-  QWhatsThis::add( nextButton(), tr( "Moves to the next step of the installation procedure" ) );
-  QToolTip::add  ( nextButton(), tr( "Moves to the next step of the installation procedure" ) );
-  nextButton()->disconnect();
-  connect( nextButton(), SIGNAL( clicked() ), this, SLOT( 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() ) );
+  connect(    this, SIGNAL( nextClicked() ), this, SLOT( next() ) );
   cancelButton()->disconnect();
   connect( cancelButton(), SIGNAL( clicked()), this, SLOT( reject() ) );
 
@@ -1498,26 +1911,37 @@ void SALOME_InstallWizard::pageChanged( const QString & mytitle)
       // progress page
       progressView->clear();
       installInfo->clear();
+      installInfo->setFinished( false );
       passedParams->clear();
       passedParams->setEnabled( false );
       QFont f = parametersLab->font(); f.setBold( false ); parametersLab->setFont( f );
       nextButton()->setText( tr( "&Start" ) );
-      QWhatsThis::add( nextButton(), tr( "Starts installation process" ) );
-      QToolTip::add  ( nextButton(), tr( "Starts installation process" ) );
+      setAboutInfo( nextButton(), tr( "Start installation process" ) );
       // reconnect Next button - to use it as Start button
-      nextButton()->disconnect();
-      connect( nextButton(), SIGNAL( clicked() ), this, SLOT( onStart() ) );
-      nextButton()->setEnabled( true );
+      disconnect( this, SIGNAL( nextClicked() ), this, SLOT( next() ) );
+      disconnect( this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
+      connect(    this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
+      setNextEnabled( true );
       // reconnect Cancel button to terminate process
       cancelButton()->disconnect();
       connect( cancelButton(), SIGNAL( clicked() ), this, SLOT( tryTerminate() ) );
     }
   }
   else if ( aPage == readmePage ) {
-    QCheckListItem* item = findItem( "KERNEL-Bin" );
-    runSalomeBtn->setEnabled( item &&
-                             QFileInfo( targetFolder->text() + "/KERNEL_" + item->text(1) + "/bin/salome/runSalome" ).exists() &&
-                             QFileInfo( targetFolder->text() + "/KERNEL_" + item->text(1) + "/salome.csh" ).exists() );
+    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() ) );
+      }
+    }
     finishButton()->setEnabled( true );
   }
   previousPage = aPage;
@@ -1538,8 +1962,8 @@ void SALOME_InstallWizard::helpClicked()
       helpWindow->installEventFilter( this );
     }
     else {
-      QMessageBox::warning( this, 
-                           tr( "Help file not found" ), 
+      QMessageBox::warning( this,
+                           tr( "Help file not found" ),
                            tr( "Sorry, help is unavailable" ) );
     }
   }
@@ -1589,6 +2013,17 @@ void SALOME_InstallWizard::directoryChanged( const QString& /*text*/ )
 // ================================================================
 void SALOME_InstallWizard::onStart()
 {
+  if ( nextButton()->text() == tr( "&Stop" ) ) {
+    shellProcess->kill();
+    while( shellProcess->isRunning() );
+    return;
+  }
+  progressView->clear();
+  installInfo->clear();
+  installInfo->setFinished( false );
+  passedParams->clear();
+  passedParams->setEnabled( false );
+  QFont f = parametersLab->font(); f.setBold( false ); parametersLab->setFont( f );
   // clear list of products to install ...
   toInstall.clear();
   // ... and fill it for new process
@@ -1604,9 +2039,11 @@ void SALOME_InstallWizard::onStart()
   if ( !toInstall.isEmpty() ) {
     clean(false); // VSR 07/02/05 - bug fix: first we should clear temporary directory
     // disable <Next> button
-    nextButton()->setEnabled( false );
+    //setNextEnabled( false );
+    nextButton()->setText( tr( "&Stop" ) );
+    setAboutInfo( nextButton(), tr( "Abort installation process" ) );
     // disable <Back> button
-    backButton()->setEnabled ( false );
+    setBackEnabled( false );
     // enable script parameters line edit
     // VSR commented: 18/09/03: passedParams->setEnabled( true );
     // VSR commented: 18/09/03: passedParams->setFocus();
@@ -1620,7 +2057,7 @@ void SALOME_InstallWizard::onStart()
        type = tr( "sources" );
       else if ( productsView->isNative( item ) )
        type = tr( "native" );
-      else 
+      else
        type = tr( "not install" );
       progressView->addProduct( item->text(0), type, item->text(2) );
     }
@@ -1664,15 +2101,22 @@ void SALOME_InstallWizard::productInstalled( )
     passedParams->clear();
     passedParams->setEnabled( false );
     QFont f = parametersLab->font(); f.setBold( false ); parametersLab->setFont( f );
+    installInfo->setFinished( true );
     // enable <Next> button
-    nextButton()->setEnabled( true );
-    nextButton()->setText( tr( "&Next >" ) );
-    QWhatsThis::add( nextButton(), tr( "Moves to the next step of the installation procedure" ) );
-    QToolTip::add  ( nextButton(), tr( "Moves to the next step of the installation procedure" ) );
-    nextButton()->disconnect();
-    connect( nextButton(), SIGNAL( clicked() ), this, SLOT( next() ) );
+    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() ) );
+    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() ) );
+    //connect(    this, SIGNAL( nextClicked() ), this, SLOT( next() ) );
     // enable <Back> button
-    backButton()->setEnabled( true );
+    setBackEnabled( true );
   }
 }
 // ================================================================
@@ -1684,10 +2128,10 @@ void SALOME_InstallWizard::productInstalled( )
 void SALOME_InstallWizard::tryTerminate()
 {
   if ( shellProcess->isRunning() ) {
-    if ( QMessageBox::information( this, 
-                                  tr( "Exit" ), 
-                                  tr( "Do you want to quit %1?" ).arg( getIWName() ), 
-                                  tr( "&Yes" ), 
+    if ( QMessageBox::information( this,
+                                  tr( "Exit" ),
+                                  tr( "Do you want to quit %1?" ).arg( getIWName() ),
+                                  tr( "&Yes" ),
                                   tr( "&No" ),
                                   QString::null,
                                   0,
@@ -1750,7 +2194,7 @@ void SALOME_InstallWizard::onSelectionChanged()
   }
   else if ( productsView->isSources( aItem ) ) {
     text += "<b>" + tr( "install sources" ) + "</b>" + "<br>";
-    totSize = dep.getSize( true );
+    totSize = dep.getSize( !buildSrcBtn->isChecked() );
     tempSize = dep.getTempSize();
   }
   else if ( productsView->isNative( aItem ) ) {
@@ -1759,7 +2203,7 @@ void SALOME_InstallWizard::onSelectionChanged()
   else {
     text += "<b>" + tr( "not install" ) + "</b>" + "<br>";
   }
-  
+
   text += tr( "Disk space required" ) + ": " + QString::number( totSize ) + " Kb<br>";
   text += tr( "Disk space for tmp files required" ) + ": " + QString::number( tempSize ) + " Kb<br>";
   text += "<br>";
@@ -1799,6 +2243,8 @@ void SALOME_InstallWizard::onProdBtn()
 {
   const QObject* snd = sender();
   productsView->blockSignals( true );
+  selectSrcBtn->blockSignals( true );
+  selectBinBtn->blockSignals( true );
   if ( snd == unselectBtn ) {
     QCheckListItem* item = (QCheckListItem*)( productsView->firstChild() );
     while( item ) {
@@ -1806,6 +2252,62 @@ void SALOME_InstallWizard::onProdBtn()
       item = (QCheckListItem*)( item->nextSibling() );
     }
   }
+  else if ( snd == selectSrcBtn )  {
+    QMyCheckBox* checkBox = ( QMyCheckBox* )snd;
+    if ( checkBox->state() == QButton::NoChange )
+      checkBox->setState( QButton::On );
+    MapProducts::Iterator itProd;
+    for ( itProd = productsMap.begin(); itProd != productsMap.end(); ++itProd ) {
+      if ( itProd.data().hasContext( "salome sources" ) ) {
+       if ( checkBox->state() == QButton::Off ) {
+         int selBin = 0;
+         MapProducts::Iterator itProd1;
+         for ( itProd1 = productsMap.begin(); itProd1 != productsMap.end(); ++itProd1 ) {
+           if (  itProd1.data().hasContext( "salome binaries" ) &&
+                !itProd1.data().hasContext( "salome sources" ) &&
+                 productsView->isBinaries( itProd1.key() ) )
+             selBin++;
+         }
+         if ( !itProd.data().hasContext( "salome binaries" ) || !selBin )
+           productsView->setNone( itProd.key() );
+       }
+       else {
+         productsView->setSources( itProd.key() );
+         if ( prerequisites->isChecked() )
+           setPrerequisites( itProd.key() );
+       }
+      }
+    }
+  }
+  else if ( snd == selectBinBtn )  {
+    QMyCheckBox* checkBox = ( QMyCheckBox* )snd;
+    if ( checkBox->state() == QButton::NoChange )
+      checkBox->setState( QButton::On );
+    MapProducts::Iterator itProd;
+    for ( itProd = productsMap.begin(); itProd != productsMap.end(); ++itProd ) {
+      if ( itProd.data().hasContext( "salome binaries" ) ) {
+       if ( checkBox->state() == QButton::Off ) {
+         int selSrc = 0;
+         MapProducts::Iterator itProd1;
+         for ( itProd1 = productsMap.begin(); itProd1 != productsMap.end(); ++itProd1 ) {
+           if (  itProd1.data().hasContext( "salome sources" ) &&
+                !itProd1.data().hasContext( "salome binaries" ) &&
+                 productsView->isSources( itProd1.key() ) )
+             selSrc++;
+         }
+         if ( !itProd.data().hasContext( "salome sources" ) || !selSrc )
+           productsView->setNone( itProd.key() );
+       }
+       else {
+         productsView->setBinaries( itProd.key() );
+         if ( prerequisites->isChecked() )
+           setPrerequisites( itProd.key() );
+       }
+      }
+    }
+  }
+  selectSrcBtn->blockSignals( false );
+  selectBinBtn->blockSignals( false );
   productsView->blockSignals( false );
   onSelectionChanged();
   checkProductPage();
@@ -1839,6 +2341,9 @@ void SALOME_InstallWizard::readFromStdout( )
     installInfo->scrollToBottom();
   }
 }
+
+#define OUTLINE_TEXT(x) QString( "<font color=#FF0000><b>" ) + QString( x ) + QString( "</b></font>" )
+
 // ================================================================
 /*!
  *  SALOME_InstallWizard::readFromStderr
@@ -1849,17 +2354,19 @@ void SALOME_InstallWizard::readFromStderr( )
 {
   ___MESSAGE___( "Something was sent to stderr" );
   while ( shellProcess->canReadLineStderr() ) {
-    installInfo->append( QString( shellProcess->readLineStderr() ) );
+    installInfo->append( OUTLINE_TEXT( QString( shellProcess->readLineStderr() ) ) );
     installInfo->scrollToBottom();
   }
   QString str( shellProcess->readStderr() );
   if ( !str.isEmpty() ) {
-    installInfo->append( str );
+    installInfo->append( OUTLINE_TEXT( str ) );
     installInfo->scrollToBottom();
   }
-  passedParams->setEnabled( true );
-  passedParams->setFocus();
-  QFont f = parametersLab->font(); f.setBold( true ); parametersLab->setFont( f );
+  // VSR: 10/11/05 - disable answer mode ==>
+  // passedParams->setEnabled( true );
+  // passedParams->setFocus();
+  // QFont f = parametersLab->font(); f.setBold( true ); parametersLab->setFont( f );
+  // VSR: 10/11/05 - disable answer mode <==
 }
 // ================================================================
 /*!
@@ -1872,6 +2379,19 @@ void SALOME_InstallWizard::setDependancies( QCheckListItem* item, Dependancies d
   productsMap[item] = dep;
 }
 // ================================================================
+/*!
+ *  SALOME_InstallWizard::addFinishButton
+ *  Add button for the <Finish> page
+ */
+// ================================================================
+void SALOME_InstallWizard::addFinishButton( const QString& label,
+                                           const QString& tooltip,
+                                           const QString& script)
+{
+  if ( !label.isEmpty() )
+    buttons.append( Button( label, tooltip, script ) );
+}
+// ================================================================
 /*!
  *  SALOME_InstallWizard::polish
  *  Polishing of the widget - to set right initial size
@@ -1883,6 +2403,41 @@ void SALOME_InstallWizard::polish()
   InstallWizard::polish();
 }
 // ================================================================
+/*!
+ *  SALOME_InstallWizard::saveLog
+ *  Save installation log to file
+ */
+// ================================================================
+void SALOME_InstallWizard::saveLog()
+{
+  QString txt = installInfo->text();
+  if ( txt.length() <= 0 )
+    return;
+  QDateTime dt = QDateTime::currentDateTime();
+  QString fileName = dt.toString("ddMMyy-hhmm");
+  fileName.prepend("install-"); fileName.append(".html");
+  fileName = QFileDialog::getSaveFileName( fileName,
+                                          QString( "HTML files (*.htm *.html)" ),
+                                          this, 0,
+                                          tr( "Save Log file" ) );
+  if ( !fileName.isEmpty() ) {
+    QFile f( fileName );
+    if ( f.open( IO_WriteOnly ) ) {
+      QTextStream stream( &f );
+      stream << txt;
+      f.close();
+    }
+    else {
+      QMessageBox::critical( this,
+                            tr( "Error" ),
+                            tr( "Can't save file %1.\nCheck path and permissions.").arg( fileName ),
+                            QMessageBox::Ok,
+                            QMessageBox::NoButton,
+                            QMessageBox::NoButton );
+    }
+  }
+}
+// ================================================================
 /*!
  *  SALOME_InstallWizard::updateCaption
  *  Updates caption according to the current page number
@@ -1891,7 +2446,7 @@ void SALOME_InstallWizard::polish()
 void SALOME_InstallWizard::updateCaption()
 {
   QWidget* aPage = InstallWizard::currentPage();
-  if ( !aPage ) 
+  if ( !aPage )
     return;
   InstallWizard::setCaption( tr( myCaption ) + " " +
                             tr( getIWName() ) + " - " +
@@ -1911,34 +2466,60 @@ void SALOME_InstallWizard::processValidateEvent( const int val, void* data )
     InstallWizard::processValidateEvent( val, data );
     return;
   }
+  myMutex.lock();
+  myMutex.unlock();
   QCheckListItem* item = (QCheckListItem*)data;
   if ( val > 0 ) {
     if ( val == 2 ) {
       WarnDialog::showWarnDlg( 0, false );
       // when try_native returns 2 it means that native product version is higher than that is prerequisited
-      if ( QMessageBox::warning( this, 
-                                tr( "Warning" ), 
+      if ( QMessageBox::warning( this,
+                                tr( "Warning" ),
                                 tr( "You have newer version of %1 installed on your computer than that is required (%2).\nContinue?").arg(item->text(0)).arg(item->text(1)),
-                               QMessageBox::Yes, 
-                               QMessageBox::No, 
+                               QMessageBox::Yes,
+                               QMessageBox::No,
                                QMessageBox::NoButton ) == QMessageBox::No ) {
        myThread->clearCommands();
        myWC.wakeAll();
+       setNextEnabled( true );
+       setBackEnabled( true );
        return;
       }
+      WarnDialog::showWarnDlg( this, true );
     }
     else {
       WarnDialog::showWarnDlg( 0, false );
-      QMessageBox::warning( this, 
-                          tr( "Warning" ), 
-                          tr( "You don't have native %1 %2 installed").arg(item->text(0)).arg(item->text(1)), 
-                          QMessageBox::Ok, 
-                          QMessageBox::NoButton, 
-                          QMessageBox::NoButton );
-      productsView->setNone( item );
-      myThread->clearCommands();
-      myWC.wakeAll();
-      return;
+      bool binMode = productsView->hasBinaries( item );
+      bool srcMode = productsView->hasSources( item );
+      QStringList buttons;
+      buttons.append( binMode ? tr( "Install binaries" ) : ( srcMode ? tr( "Install sources" ) :
+                                                                      tr( "Select manually" ) ) );
+      buttons.append( binMode ? ( srcMode ? tr( "Install sources" ) : tr( "Select manually" ) ) :
+                                ( srcMode ? tr( "Select manually" ) : QString::null ) );
+      buttons.append( binMode && srcMode ? tr( "Select manually" ) : QString::null );
+      int answer = QMessageBox::warning( this,
+                                        tr( "Warning" ),
+                                        tr( "You don't have native %1 %2 on your computer.\nPlease, change your installation settings.").arg(item->text(0)).arg(item->text(1)),
+                                        buttons[0],
+                                        buttons[1],
+                                        buttons[2] );
+      if ( buttons[ answer ] == tr( "Install binaries" ) )
+        productsView->setBinaries( item );
+      else if ( buttons[ answer ] == tr( "Install sources" ) )
+        productsView->setSources( item );
+      else {
+        if ( !moreMode )
+         onMoreBtn();
+       productsView->setCurrentItem( item );
+       productsView->setSelected( item, true );
+       productsView->ensureItemVisible( item );
+        myThread->clearCommands();
+        myWC.wakeAll();
+        setNextEnabled( true );
+        setBackEnabled( true );
+        return;
+      }
+      WarnDialog::showWarnDlg( this, true );
     }
   }
   if ( myThread->hasCommands() )
@@ -1948,3 +2529,67 @@ void SALOME_InstallWizard::processValidateEvent( const int val, void* data )
     InstallWizard::processValidateEvent( val, data );
   }
 }
+
+// ================================================================
+/*!
+ *  SALOME_InstallWizard::resetToDefaultState
+ *  Reset to default state
+ */
+// ================================================================
+void SALOME_InstallWizard::resetToDefaultState()
+{
+  productsView->blockSignals( true );
+  buildSrcBtn->setChecked( false );
+  MapProducts::Iterator itProd;
+  for ( itProd = productsMap.begin(); itProd != productsMap.end(); ++itProd ) {
+    QString defMode = itProd.data().getDefault();
+    if ( defMode.isEmpty() )
+      defMode = tr( "install binaries" );
+    if ( defMode == tr( "install binaries" ) )
+      productsView->setBinaries( itProd.key() );
+    else if ( defMode == tr( "install sources" ) )
+      productsView->setSources( itProd.key() );
+    else if ( defMode == tr( "use native" ) )
+      productsView->setNative( itProd.key() );
+    else
+      productsView->setNone( itProd.key() );
+  }
+  productsView->blockSignals( false );
+}
+
+// ================================================================
+/*!
+ *  SALOME_InstallWizard::onBuildAll
+ *  Build all products from the sources check box slot
+ */
+// ================================================================
+void SALOME_InstallWizard::onBuildAll()
+{
+  const QObject* snd = sender();
+  if ( allFromSrcBtn->isChecked() ) {
+    productsView->blockSignals( true );
+    buildSrcBtn->setChecked( false );
+    MapProducts::Iterator mapIter;
+    for ( mapIter = productsMap.begin(); mapIter != productsMap.end(); ++mapIter )
+      productsView->setSources( mapIter.key() );
+    buildSrcBtn->setChecked( true );
+    productsView->blockSignals( false );
+    checkProductPage();
+    static bool firstTimeClicked = true;
+    if ( snd == allFromSrcBtn && firstTimeClicked ) {
+      QMessageBox::warning( this,
+                           tr( "Warning" ),
+                           tr( "The building of all products from sources can take a lot of time\n"
+                               "(more than 24 hours) depending on your computer performance!" ),
+                           QMessageBox::Ok,
+                           QMessageBox::NoButton,
+                           QMessageBox::NoButton );
+    }
+    firstTimeClicked = false;
+  }
+  else {
+    resetToDefaultState();
+    checkProductPage();
+  }
+  moreBtn->setEnabled( !allFromSrcBtn->isChecked() );
+}