Salome HOME
Fix pb. with result of checking libraries.
[tools/install.git] / src / SALOME_InstallWizard.cxx
index beec2a9f460d1eb60dc915c1d2ace92158868f8b..55872456cadd32d7a64de0f142c167cdad0488b4 100644 (file)
@@ -3,7 +3,7 @@
 //  Author    : Vadim SANDLER, Open CASCADE SAS (vadim.sandler@opencascade.com)
 //  Project   : SALOME
 //  Module    : Installation Wizard
-//  Copyright : 2002-2007 CEA
+//  Copyright : 2002-2008 CEA
 
 #include "globals.h"
 
@@ -203,29 +203,29 @@ private:
 
 // ================================================================
 /*!
- *  DefineDependeces [ static ]
- *  Defines list of dependancies as string separated by space symbols
+ *  getAllProducts [ static ]
+ *  Defines list of all products as a string separated by space symbols
  */
 // ================================================================
-static QString DefineDependeces(MapProducts& theProductsMap)
+static QString getAllProducts(MapProducts& theProductsMap)
 {
-  QStringList aProducts;
+  QStringList aModules, aPrereqs;
   for ( MapProducts::Iterator mapIter = theProductsMap.begin(); mapIter != theProductsMap.end(); ++mapIter ) {
     QCheckListItem* item = mapIter.key();
     Dependancies dep = mapIter.data();
-    QStringList deps = dep.getDependancies();
-    for (int i = 0; i<(int)deps.count(); i++ ) {
-      if ( !aProducts.contains( deps[i] ) ) {
-       aProducts.append( deps[i] );
-       aProducts.append( deps[i] + "_src" );
+    QString curModule = item->text(0);
+    if ( !aModules.contains( curModule ) && !aPrereqs.contains( curModule ) ) {
+      if ( dep.getType() == "component" ) {
+       aModules.append( curModule );
+       aModules.append( curModule + "_src" );
+      }
+      else {
+       aPrereqs.append( curModule );
+       aPrereqs.append( curModule + "_src" );
       }
-    }
-    if ( !aProducts.contains( item->text(0) ) ) {
-      aProducts.append( item->text(0) );
-      aProducts.append( item->text(0) + "_src" );
     }
   }
-  return aProducts.join(" ");
+  return QStringList(aPrereqs+aModules).join(" ");
 }
 
 // ================================================================
@@ -426,7 +426,7 @@ public:
                      .arg( __IW_VERSION_MINOR__ ) \
                      .arg( __IW_VERSION_PATCH__ ) );
     QLabel* copyright = new QLabel( this, "copyright" );
-    copyright->setText( "<b>Copyright</b> &copy; 2004-2007 CEA" );
+    copyright->setText( "<b>Copyright</b> &copy; 2004-2008 CEA" );
     QFont font = title->font();
     font.setPointSize( (int)( font.pointSize() * 1.8 ) );
     title->setFont( font );
@@ -469,7 +469,8 @@ public:
 // ================================================================
 SALOME_InstallWizard::SALOME_InstallWizard(const QString& aXmlFileName,
                                           const QString& aTargetDir,
-                                          const QString& aTmpDir)
+                                          const QString& aTmpDir,
+                                          const bool     aForceSrc)
      : InstallWizard( qApp->desktop(), "SALOME_InstallWizard", false, 0 ),
        helpWindow( NULL ),
        moreMode( false ),
@@ -482,9 +483,27 @@ SALOME_InstallWizard::SALOME_InstallWizard(const QString& aXmlFileName,
   xmlFileName  = aXmlFileName;
   myTargetPath = aTargetDir;
   myTmpPath    = aTmpDir;
+  forceSrc     = aForceSrc;
   stateChanged = true;
   binPath = QDir::currentDirPath() + "/Products/BINARIES";
   srcPath = QDir::currentDirPath() + "/Products/SOURCES";
+  oneModDirName = "SALOME";
+  oneProdDirName = "PRODUCTS";
+  
+  singleBinPlts << "Debian4.0" 
+               << "Debian3.1" 
+               << "Mandrake10.1" 
+               << "Mandriva2006.0" 
+               << "Mandriva2007.0" 
+               << "Mandriva2008.0" 
+               << "Mandriva2006.0_64"
+               << "Mandriva2008.0_64"
+               << "RedHat8.0"
+               << "RedHat9"
+               << "RedHatEnterprise4"
+               << "Scientific4.2"
+               << "Scientific4.3";
+  commonPlatform = "Debian3.1";
   
   //
   // get XML filename and current platform
@@ -511,10 +530,10 @@ SALOME_InstallWizard::SALOME_InstallWizard(const QString& aXmlFileName,
   addLogo( pixmap( pxLogo ) );
 
   // set defaults
-  setVersion( "3.2.6" );
+  setVersion( "4.1.1" );
   setCaption( tr( "SALOME %1" ).arg( myVersion ) );
-  setCopyright( tr( "Copyright (C) 2007 CEA" ) );
-  setLicense( tr( "All right reserved" ) );
+  setCopyright( tr( "Copyright (C) 2008 CEA" ) );
+  setLicense( tr( "All rights reserved." ) );
 
   ___MESSAGE___( "Configuration file : " << xmlFileName.latin1() );
   ___MESSAGE___( "Target directory   : " << myTargetPath.latin1() );
@@ -528,14 +547,12 @@ SALOME_InstallWizard::SALOME_InstallWizard(const QString& aXmlFileName,
 
   // create instance of class for starting shell script to get available disk space
   diskSpaceProc = new QProcess( this, "procDiskSpace" );
-  connect( diskSpaceProc, SIGNAL( processExited() ), this, SLOT( updateAvailableSpace() ) );
-
   // create instance of class for starting shell install script
   shellProcess = new QProcess( this, "shellProcess" );
-
+  // create instance of class for starting shell script to modify SALOME *.la files
+  modifyLaProc = new QProcess( this, "modifyLaProc" );
   // create instance of class for starting shell script to check Fortran libraries
   checkFLibProc = new QProcess( this, "checkFLibProc" );
-  connect(checkFLibProc, SIGNAL( processExited() ), this, SLOT( checkFLibResult() ) );
 
   // create introduction page
   setupIntroPage();
@@ -567,11 +584,19 @@ SALOME_InstallWizard::SALOME_InstallWizard(const QString& aXmlFileName,
   connect( this, SIGNAL( helpClicked() ),  this, SLOT( helpClicked() ) );
   connect( this, SIGNAL( aboutClicked() ), this, SLOT( onAbout() ) );
 
-  // catch signals from launched script
+  // catch signals from launched diskSpaceProc
+  connect( diskSpaceProc, SIGNAL( processExited() ), this, SLOT( updateAvailableSpace() ) );
+  // catch signals from launched shellProcess
   connect(shellProcess, SIGNAL( readyReadStdout() ), this, SLOT( readFromStdout() ) );
   connect(shellProcess, SIGNAL( readyReadStderr() ), this, SLOT( readFromStderr() ) );
   connect(shellProcess, SIGNAL( processExited() ),   this, SLOT( productInstalled() ) );
   connect(shellProcess, SIGNAL( wroteToStdin() ),    this, SLOT( wroteToStdin() ) );
+  // catch signals from launched modifyLaProc
+  connect(modifyLaProc, SIGNAL( readyReadStdout() ), this, SLOT( readFromStdout() ) );
+  connect(modifyLaProc, SIGNAL( readyReadStderr() ), this, SLOT( readFromStderr() ) );
+  connect(modifyLaProc, SIGNAL( processExited() ), this, SLOT( checkModifyLaResult() ) );
+  // catch signals from launched checkFLibProc
+  connect(checkFLibProc, SIGNAL( processExited() ), this, SLOT( checkFLibResult() ) );
 
   // create validation thread
   myThread = new ProcessThread( this );
@@ -601,6 +626,21 @@ SALOME_InstallWizard::~SALOME_InstallWizard()
   delete myThread;
 }
 // ================================================================
+/*!
+ *  SALOME_InstallWizard::getBasePlatform
+ *  Determine the base platform for binaries installation
+ */
+// ================================================================
+QString SALOME_InstallWizard::getBasePlatform()
+{
+  QString aBasePlt = "";
+  if ( singleBinPlts.contains(curPlatform) )
+    aBasePlt = curPlatform;
+  else
+    aBasePlt = commonPlatform;
+  return aBasePlt;
+}
+// ================================================================
 /*!
  *  SALOME_InstallWizard::currentPlatform
  *  Tries to determine the current user's operating system
@@ -692,8 +732,10 @@ MapXmlFiles SALOME_InstallWizard::getXmlMap( const QString& xmlFileName )
        platforms = elem.attribute( "platforms" ).stripWhiteSpace();
        QStringList platList = QStringList::split( ",", platforms );
        for ( uint j = 0; j < platList.count(); j++ ) {
-         if ( !platList[j].isEmpty() && xmlMap.find( platList[j] ) == xmlMap.end() )
-           xmlMap[ platList[j] ] = xmlList[i];
+         if ( !platList[j].isEmpty() )
+           if ( xmlMap.find( platList[j] ) == xmlMap.end() || 
+                xmlMap[ platList[j] ] == "config.xml" )
+             xmlMap[ platList[j] ] = xmlList[i];
        }
 //     if ( !curPlatform.isEmpty() && xmlMap.find( curPlatform ) != xmlMap.end() )
 //       return xmlMap;
@@ -715,8 +757,14 @@ void SALOME_InstallWizard::getXmlAndPlatform()
     xmlMap = getXmlMap();
     if ( !curPlatform.isEmpty() ) {
       // try to get XML file for current platform
-      if ( xmlMap.find( curPlatform ) != xmlMap.end() )
-       xmlFileName = xmlMap[ curPlatform ];
+      if ( xmlMap.find( curPlatform ) != xmlMap.end() ) {
+       xmlFileName = xmlMap[ getBasePlatform() ];
+       QFileInfo fibp( QDir::cleanDirPath( getBinPath() + "/" + getBasePlatform() ) );
+       if ( !fibp.isDir() ) {
+         warnMsg = tr( "Binaries are absent for current platform" );
+       }
+       platformsMap = xmlMap;
+      }
       else {
        platformsMap = xmlMap;
        warnMsg = tr( "Your Linux platform is not supported by this SALOME package" );
@@ -907,10 +955,11 @@ void SALOME_InstallWizard::setupTypePage()
   QLabel* srcCompileLab3 = new QLabel( " " + 
                                       tr( "it is a long time operation and it can take more than 24 hours depending\n on the computer." ), 
                                       buttonGrp );
-  removeSrcBtn = new QMyCheckBox( tr( "Remove sources and temporary files after compilation" ), typePage );
+  removeSrcBtn = new QCheckBox( tr( "Remove sources and temporary files after compilation" ), typePage );
   setAboutInfo( removeSrcBtn, tr( "Check this option if you want to remove sources of the products\nwith all the temporary files after build finishing" ) );
-  removeSrcBtn->setState( QButton::Off );
+  removeSrcBtn->setChecked( false );
   removeSrcBtn->setEnabled( false );
+  rmSrcPrevState = removeSrcBtn->isChecked();
 
   srcCompileLayout->addMultiCellWidget( srcCompileBtn,  0, 0, 0, 2 );
   srcCompileLayout->addMultiCell      ( spacer6,        1, 2, 0, 0 );
@@ -930,7 +979,6 @@ void SALOME_InstallWizard::setupTypePage()
   pageLayout->addWidget( buttonGrp, 0, 0 );
   // connecting signals
   connect( buttonGrp, SIGNAL( clicked(int) ), this, SLOT ( onButtonGroup(int) ) );
-  connect( removeSrcBtn,  SIGNAL( toggled( bool ) ), this, SLOT( onRemoveSrcBtn() ) );
   // adding page
   addPage( typePage, tr( "Installation type" ) );
 }
@@ -942,10 +990,6 @@ void SALOME_InstallWizard::setupTypePage()
 // ================================================================
 void SALOME_InstallWizard::setupPlatformPage()
 {
-  // create page or not?
-  if ( platformsMap.isEmpty() )
-    return;
-
   // create page
   platformsPage = new QWidget( this, "PlatformsPage" );
   QGridLayout* pageLayout = new QGridLayout( platformsPage );
@@ -956,13 +1000,9 @@ void SALOME_InstallWizard::setupPlatformPage()
   QFont fnt = warnLab2->font();
   fnt.setBold( true );
   warnLab2->setFont( fnt );
-  if ( installType == Compile && platformsMap.find( curPlatform ) == platformsMap.end() )
-    warnMsg += tr( " and compilation is not tested on this one." );
-  else
-    warnMsg += ".";
   warnLab = new QLabel( warnMsg, platformsPage );
   warnLab->setAlignment( Qt::AlignHCenter | Qt::WordBreak );
-  QLabel* warnLab3 = new QLabel( tr( "If you want to proceed anyway, please select platform from the following list:" ), 
+  warnLab3 = new QLabel( tr( "If you want to proceed anyway, please select platform from the following list:" ), 
                                 platformsPage );
   warnLab3->setAlignment( Qt::AlignHCenter | Qt::WordBreak );
   // create button group
@@ -1119,11 +1159,22 @@ void SALOME_InstallWizard::setupProductsPage()
   sizeLayout->addWidget( requiredTemp,  1, 1 );
   sizeLayout->addWidget( reqLab3,       2, 0 );
   sizeLayout->addWidget( availableSize, 2, 1 );
+  // ... 'single installation directory' check-boxes
+  oneModDirBtn = new QMyCheckBox( tr( "Install modules to a single directory" ), productsPage );
+  setAboutInfo( oneModDirBtn, tr( "Check this box if you want to install binaries of\nthe selected SALOME modules into a single directory" ) );
+  oneProdDirBtn = new QMyCheckBox( tr( "Install prerequisites to a single directory" ), productsPage );
+  setAboutInfo( oneProdDirBtn, tr( "Check this box if you want to install binaries of\nthe selected prerequisites into a single directory" ) );
+  oneProdDirBtn->hide(); // temporarily! waiting for correct prerequisites availability
+  QFrame* split_line = new QFrame( productsPage, "split_line" );
+  split_line->setFrameStyle( QFrame::HLine | QFrame::Sunken );
 
   // layout common widgets
-  pageLayout->addMultiCellLayout( leftBoxLayout, 0, 1, 0, 0 );
+  pageLayout->addMultiCellLayout( leftBoxLayout, 0, 4, 0, 0 );
   pageLayout->addWidget         ( productInfo,   0,    1    );
   pageLayout->addLayout         ( sizeLayout,    1,    1    );
+  pageLayout->addWidget         ( split_line,    2,    1    );
+  pageLayout->addWidget         ( oneModDirBtn,  3,    1    );
+  pageLayout->addWidget         ( oneProdDirBtn, 4,    1    );
 
   // adding page
   addPage( productsPage, tr( "Choice of the products to be installed" ) );
@@ -1323,11 +1374,6 @@ void SALOME_InstallWizard::showChoiceInfo()
   item = (QCheckListItem*)( prereqsView->firstChild() );
   while( item ) {
     if ( productsMap.contains( item ) ) {
-      if ( productsMap[ item ].hasType( "salome sources" ) || 
-          productsMap[ item ].hasType( "salome binaries" ) ) {
-       item = (QCheckListItem*)( item->nextSibling() );
-       continue; // skip SALOME sources and binaries
-      }
       if ( item->isOn() ) {
        text += "<li><b>" + item->text() + " " + productsMap[ item ].getVersion() + "</b><br>";
        nbProd++;
@@ -1355,6 +1401,8 @@ bool SALOME_InstallWizard::acceptData( const QString& pageTitle )
   QWidget* aPage = InstallWizard::page( pageTitle );
   if ( aPage == typePage ) {
     // installation type page
+    warnLab3->show();
+    this->setAppropriate( platformsPage, false );
     if ( installType == Binaries ) { // 'Binary' installation type
       // check binaries directory
       QFileInfo fib( QDir::cleanDirPath( getBinPath() ) );
@@ -1362,19 +1410,42 @@ bool SALOME_InstallWizard::acceptData( const QString& pageTitle )
        QMessageBox::warning( this,
                              tr( "Warning" ),
                              tr( "The directory %1 doesn't exist.\n"
-                                 "This directory must contain sources archives.\n").arg( fib.absFilePath() ),
+                                 "This directory must contains another one directory with binary archives for current platform.").arg( fib.absFilePath() ),
                              QMessageBox::Ok,
                              QMessageBox::NoButton, 
                              QMessageBox::NoButton );
        return false;
       }
+      if ( platformsMap.find( curPlatform ) == platformsMap.end() ) {
+       // Unknown platform case
+       QString aMsg = warnMsg + tr( ".\nBy default the universal binary package will be installed." );
+       aMsg += tr( "\nIf you want to select another one, please use the following list:" );
+       warnLab->setText( aMsg );
+       warnLab3->hide();
+       this->setAppropriate( platformsPage, true );
+      }
+      else {
+       // Supported platform case
+       QString aPlatform = curPlatform;
+       if ( curPlatform != getBasePlatform() ) {
+         refPlatform = getBasePlatform();
+         xmlFileName = platformsMap[ refPlatform ];
+         aPlatform = getPlatform();
+       }
+       QFileInfo fibp( QDir::cleanDirPath( getBinPath() + "/" + aPlatform ) );
+       if ( !fibp.isDir() ) {
+         warnLab->setText( tr( "Binaries are absent for current platform." ) );
+         this->setAppropriate( platformsPage, true );
+       }
+      }
+
       // check sources directory
       QFileInfo fis( QDir::cleanDirPath( getSrcPath() ) );
       if ( !fis.exists() )
        if ( QMessageBox::warning( this,
                                   tr( "Warning" ),
                                   tr( "The directory %1 doesn't exist.\n"
-                                      "This directory must contain sources archives.\n"
+                                      "This directory must contains sources archives.\n"
                                       "Continue?" ).arg( fis.absFilePath() ),
                                   tr( "&Yes" ),
                                   tr( "&No" ), 
@@ -1388,17 +1459,37 @@ bool SALOME_InstallWizard::acceptData( const QString& pageTitle )
        QMessageBox::warning( this,
                              tr( "Warning" ),
                              tr( "The directory %1 doesn't exist.\n"
-                                 "This directory must contain sources archives.\n" ).arg( fis.absFilePath() ),
+                                 "This directory must contains sources archives.\n" ).arg( fis.absFilePath() ),
                              QMessageBox::Ok,
                              QMessageBox::NoButton, 
                              QMessageBox::NoButton );
        return false;
       }
+      if ( platformsMap.find( curPlatform ) == platformsMap.end() ) {
+       QString aMsg = warnMsg + ".";
+       if ( installType == Compile )
+         aMsg = warnMsg + tr( " and compilation is not tested on this one." );
+       warnLab->setText( aMsg );
+       this->setAppropriate( platformsPage, true );
+      }
     }
   }
 
-  else if ( aPage == dirPage ) {
+  else if ( aPage == platformsPage ) {
     // installation platform page
+    if ( platBtnGrp->id( platBtnGrp->selected() ) == -1 ) {
+      QMessageBox::warning( this,
+                           tr( "Warning" ),
+                           tr( "Select installation platform before" ),
+                           QMessageBox::Ok,
+                           QMessageBox::NoButton,
+                           QMessageBox::NoButton );
+      return false;
+    }
+  }
+
+  else if ( aPage == dirPage ) {
+    // installation directory page
     // ########## check target and temp directories (existence and available disk space)
     // get dirs
     QString targetDir = QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() );
@@ -1448,7 +1539,7 @@ bool SALOME_InstallWizard::acceptData( const QString& pageTitle )
     if ( !fi.isWritable() ) {
       QMessageBox::warning( this,
                             tr( "Warning" ),
-                            tr( "The directory %1 is not writeable.\n"
+                            tr( "The directory %1 is not writable.\n"
                                "Please, enter valid target directory path or change permissions" ).arg( fi.absFilePath() ),
                             QMessageBox::Ok,
                             QMessageBox::NoButton,
@@ -1493,7 +1584,7 @@ bool SALOME_InstallWizard::acceptData( const QString& pageTitle )
     // ########## check if any products are selected to be installed
     long totSize, tempSize;
     bool anySelected = checkSize( &totSize, &tempSize );
-    if ( installType == Compile && removeSrcBtn->state() == QButton::On ) {
+    if ( installType == Compile && removeSrcBtn->isOn() ) {
       totSize += tempSize;
     }
     if ( !anySelected ) {
@@ -1626,17 +1717,14 @@ bool SALOME_InstallWizard::checkSize( long* totSize, long* tempSize )
     Dependancies dep = mapIter.data();
     if ( !item->isOn() )
       continue;
-    if ( installType == Compile && removeSrcBtn->state() == QButton::On )
-      tots += dep.getSize( Binaries );
-    else
-      tots += dep.getSize( installType );
+    tots += ( QStringList::split( " ", item->text(1) )[0] ).toLong();
     maxSrcTmp = max( maxSrcTmp, dep.getSize( Compile ) - dep.getSize( Binaries ) );
     temps += dep.getTempSize( installType );
     nbSelected++;
   }
 
   if ( totSize )
-    if ( installType == Compile && removeSrcBtn->state() == QButton::On )
+    if ( installType == Compile && removeSrcBtn->isOn() )
       temps += maxSrcTmp;
     *totSize = tots;
   if ( tempSize )
@@ -1655,6 +1743,80 @@ void SALOME_InstallWizard::updateAvailableSpace()
     availableSize->setText( diskSpaceProc->readLineStdout() + " KB");
 }
 // ================================================================
+/*!
+ *  SALOME_InstallWizard::runModifyLaFiles
+ *  Run the modification of SALOME *.la files
+ */
+// ================================================================
+void SALOME_InstallWizard::runModifyLaFiles()
+{
+  modifyLaProc->clearArguments();
+  // ... update status label
+  statusLab->setText( tr( "Modification of *.la files of SALOME modules..." ) );
+  // set process arguments
+  modifyLaProc->setWorkingDirectory( QDir::cleanDirPath( QFileInfo( "./config_files/" ).absFilePath() ) );
+  modifyLaProc->addArgument( "modifyLaFiles.sh" );
+  modifyLaProc->addArgument( "modify_la_files" );
+  modifyLaProc->addArgument( QDir::cleanDirPath( QFileInfo( targetFolder->text().stripWhiteSpace() ).absFilePath() ) );
+  modifyLaProc->addArgument( oneModDirName );
+  // ... run script
+  if ( !modifyLaProc->start() )
+    ___MESSAGE___( "Error: process could not start!" );
+}
+// ================================================================
+/*!
+ *  SALOME_InstallWizard::checkModifyLaResult
+ *  Slot to take result of modification SALOME *.la files
+ */
+// ================================================================
+void SALOME_InstallWizard::checkModifyLaResult()
+{
+  if ( modifyLaProc->normalExit() && modifyLaProc->exitStatus() == 1 )
+    runCheckFLib();
+  else {
+    // abort of the current installation
+    abort();
+    statusLab->setText( tr( "Installation has been aborted" ) );
+    QMessageBox::critical( this,
+                          tr( "Error" ),
+                          tr( "Modification of *.la SALOME files has not been completed."),
+                          QMessageBox::Ok,
+                          QMessageBox::NoButton,
+                          QMessageBox::NoButton );
+    // enable <Next> button
+    setNextEnabled( true );
+    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() ) );
+    // enable <Back> button
+    setBackEnabled( true );
+  }
+}
+// ================================================================
+/*!
+ *  SALOME_InstallWizard::runCheckFLib
+ *  Run the Fortran libraries checking
+ */
+// ================================================================
+void SALOME_InstallWizard::runCheckFLib()
+{
+  // Check Fortran libraries
+  checkFLibProc->clearArguments();
+  // ... update status label
+  statusLab->setText( tr( "Check Fortran libraries..." ) );
+  // ... search "not found" libraries
+  checkFLibProc->setWorkingDirectory( QDir::cleanDirPath( QFileInfo( "./config_files/" ).absFilePath() ) );
+  checkFLibProc->addArgument( "checkFortran.sh" );
+  checkFLibProc->addArgument( "find_libraries" );
+  checkFLibProc->addArgument( QDir::cleanDirPath( QFileInfo( targetFolder->text().stripWhiteSpace() ).absFilePath() ) );
+  // ... run script
+  if ( !checkFLibProc->start() )
+    ___MESSAGE___( "Error: process could not start!" );
+}
+// ================================================================
 /*!
  *  SALOME_InstallWizard::checkFLibResult
  *  Slot to take result of Fortran libraries checking
@@ -1663,16 +1825,17 @@ void SALOME_InstallWizard::updateAvailableSpace()
 void SALOME_InstallWizard::checkFLibResult()
 {
   if ( checkFLibProc->normalExit() && checkFLibProc->exitStatus() == 1 ) {
-    QString notFoundLibs;
+    QStringList notFoundLibsList;
+    QString record = "";
     while ( checkFLibProc->canReadLineStdout() ) {
-      notFoundLibs.append( checkFLibProc->readLineStdout() );
-      if ( checkFLibProc->canReadLineStdout() )
-       notFoundLibs.append( "\n" );
+      record = checkFLibProc->readLineStdout();
+      if ( !record.isEmpty() && !notFoundLibsList.contains( record ) )
+       notFoundLibsList.append( record );
     }
     QMessageBox::warning( this,
                          tr( "Warning" ),
                          tr( "The following libraries are absent on current system:\n"
-                         "%1").arg( notFoundLibs ),
+                         "%1").arg( notFoundLibsList.join( "\n" ) ),
                          QMessageBox::Ok,
                          QMessageBox::NoButton,
                          QMessageBox::NoButton );
@@ -1681,6 +1844,44 @@ void SALOME_InstallWizard::checkFLibResult()
   completeInstallation();
 }
 // ================================================================
+/*!
+ *  SALOME_InstallWizard::updateSizeColumn
+ *  Sets required size for each product according to 
+ *  installation type and 'Remove SRC & TMP' checkbox state
+ */
+// ================================================================
+void SALOME_InstallWizard::updateSizeColumn()
+{
+  long prodSize = 0;
+  bool removeSrc = removeSrcBtn->isChecked();
+  MapProducts::Iterator mapIter;
+  for ( mapIter = productsMap.begin(); mapIter != productsMap.end(); ++mapIter ) {
+    QCheckListItem* item = mapIter.key();
+    Dependancies dep = mapIter.data();
+    // get required size for current product
+    long binSize = dep.getSize( Binaries );
+    long srcSize = dep.getSize( Sources );
+    long bldSize = dep.getSize( Compile );
+    InstallationType instType = getInstType();
+    if ( instType == Binaries ) {
+      if ( dep.getType() == "component" )
+       prodSize = binSize + srcSize;
+      else
+       prodSize = ( binSize != 0 ? binSize : srcSize );
+    }
+    else if ( instType == Sources )
+      prodSize = srcSize;
+    else
+      if ( removeSrc )
+       prodSize = ( binSize != 0 ? binSize : srcSize );
+      else {
+       prodSize = ( bldSize != 0 ? bldSize : srcSize );
+      }
+    // fill in 'Size' field
+    item->setText( 1, QString::number( prodSize )+" KB" );
+  }
+}
+// ================================================================
 /*!
  *  SALOME_InstallWizard::checkProductPage
  *  Checks products page validity (directories and products selection) and
@@ -1727,8 +1928,10 @@ void SALOME_InstallWizard::setPrerequisites( QCheckListItem* item )
     return;
   // get all prerequisites
   QStringList dependOn = productsMap[ item ].getDependancies();
-  // install MED without GUI case
-  if ( installGuiBtn->state() != QButton::On && item->text(0) == "MED" ) {
+  // install SALOME without GUI case
+  if ( installGuiBtn->state() != QButton::On && 
+       woGuiModules.find( item->text(0) ) != woGuiModules.end() && 
+       woGuiModules[item->text(0)] == True ) {
     dependOn.remove( "GUI" );
   }
   // setting prerequisites
@@ -1742,6 +1945,7 @@ void SALOME_InstallWizard::setPrerequisites( QCheckListItem* item )
          itProd.key()->setOn( true );
          itProd.key()->setEnabled( false );
        }
+       break;
       }
     }
   }
@@ -1765,10 +1969,6 @@ void SALOME_InstallWizard::unsetPrerequisites( QCheckListItem* item )
   for ( itProd = productsMap.begin(); itProd != productsMap.end(); ++itProd ) {
     if ( itProd.data().getType() == productsMap[ item ].getType() ) {
       QStringList dependOn = itProd.data().getDependancies();
-      // install MED without GUI case
-      if ( installGuiBtn->state() != QButton::On && itemName == "GUI" ) {
-       dependOn.remove( "MED" );
-      }
       for ( int i = 0; i < (int)dependOn.count(); i++ ) {
        if ( dependOn[ i ] == itemName ) {
          if ( itProd.key()->isOn() ) {
@@ -1791,12 +1991,12 @@ void SALOME_InstallWizard::unsetPrerequisites( QCheckListItem* item )
        if ( itProd1.data().getType() == "prerequisite" ) {
          MapProducts::Iterator itProd2;
          for ( itProd2 = productsMap.begin(); itProd2 != productsMap.end(); ++itProd2 ) {
-           //      if ( itProd2.data().getType() == "component" ) {
            if ( itProd2.key()->isOn() ) {
              QStringList prereqsList = productsMap[ itProd2.key() ].getDependancies();
              for ( int k = 0; k < (int)prereqsList.count(); k++ ) {
                if ( prereqsList[ k ] == itProd1.data().getName() ) {
                  nbDependents++;
+                 break;
                }
              }
            }
@@ -1806,6 +2006,7 @@ void SALOME_InstallWizard::unsetPrerequisites( QCheckListItem* item )
            itProd1.key()->setOn( false );
          }
        }
+       break;
       }
     }
   }
@@ -1840,24 +2041,30 @@ void SALOME_InstallWizard::launchScript()
     progressView->ensureVisible( prodProc );
     
     QCheckListItem* item;
-    if ( prodProc != "gcc" )
-      item = findItem( prodProc );
     // fill in script parameters
     shellProcess->clearArguments();
     // ... script name
     shellProcess->setWorkingDirectory( QDir::cleanDirPath( QFileInfo( "./config_files/" ).absFilePath() ) );
-    if ( prodProc != "gcc" )
+    if ( !extraProducts.contains( prodProc ) ) {
+      item = findItem( prodProc );
       shellProcess->addArgument( item->text(2) );
+    }
     else
-      shellProcess->addArgument( "gcc-common.sh" );
-
+      shellProcess->addArgument( extraProducts[ prodProc ] );
+
+    // ... get folder with binaries
+    QString binDir = QDir::cleanDirPath( getBinPath() );
+    QString OS = getPlatform();
+    if ( refPlatform.isEmpty() && singleBinPlts.contains(curPlatform) == 0 )
+      OS = commonPlatform;
+    binDir += "/" + OS;
     // ... temp folder
     QString tmpFolder = QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + TEMPDIRNAME;
     //if( !tempFolder->isEnabled() )
     //  tmpFolder = "/tmp";
 
     // ... not install : try to find preinstalled
-    if ( !progressView->isVisible( prodProc ) ) {
+    if ( notInstall.contains( prodProc ) || prodProc == "gcc" ) {
       shellProcess->addArgument( "try_preinstalled" );
       shellProcess->addArgument( QFileInfo( tmpFolder ).absFilePath() );
       shellProcess->addArgument( QDir::currentDirPath() + "/Products" );
@@ -1867,10 +2074,6 @@ void SALOME_InstallWizard::launchScript()
     else if ( installType == Binaries ) {
       shellProcess->addArgument( "install_binary" );
       shellProcess->addArgument( QFileInfo( tmpFolder ).absFilePath() );
-      QString binDir = QDir::cleanDirPath( getBinPath() );
-      QString OS = getPlatform();
-      if ( !OS.isEmpty() )
-       binDir += "/" + OS;
       shellProcess->addArgument( binDir );
       statusLab->setText( tr( "Installing '" ) + prodProc + "'..." );
     }
@@ -1886,28 +2089,54 @@ void SALOME_InstallWizard::launchScript()
     QString tgtFolder = QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() );
     shellProcess->addArgument( QFileInfo( tgtFolder ).absFilePath() );
     // ... list of all products
-    QString depproducts = DefineDependeces(productsMap);
-    depproducts.prepend( "gcc " );
+    QString depproducts = getAllProducts(productsMap);
+    depproducts.prepend( QStringList( extraProducts.keys() ).join(" ") + " " );
     ___MESSAGE___( "Dependancies"<< depproducts.latin1() );
     shellProcess->addArgument( depproducts );
     // ... product name - currently installed product
-    if ( prodProc != "gcc" )
+    if ( !extraProducts.contains( prodProc ) )
       shellProcess->addArgument( item->text(0) );
     else
-      shellProcess->addArgument( "gcc" );
+      shellProcess->addArgument( prodProc );
     // ... list of products being installed
     shellProcess->addArgument( prodSequence.join( " " ) );
     // ... sources directory
     shellProcess->addArgument( QDir::cleanDirPath( getSrcPath() ) );
     // ... remove sources and tmp files or not?
-    if ( installType == Compile && removeSrcBtn->state() == QButton::On )
+    if ( installType == Compile && removeSrcBtn->isOn() )
       shellProcess->addArgument( "TRUE" );
     else 
       shellProcess->addArgument( "FALSE" );
-    // ... install MED with GUI or not?
-    if ( installGuiBtn->state() != QButton::On && prodProc == "MED" && 
-        (installType == Binaries || installType == Compile) )
-      shellProcess->addArgument( "FALSE" );
+    // ... binaries directory
+    shellProcess->addArgument( binDir );
+    // ... install SALOME with GUI or not?
+    if ( woGuiModules.find( prodProc ) != woGuiModules.end() )
+      ( installGuiBtn->state() != QButton::On && woGuiModules[ prodProc ] == True ) ? 
+       shellProcess->addArgument( "FALSE" ) : 
+       shellProcess->addArgument( "TRUE" );
+    // ... single installation directory for SALOME modules, if this option was selected
+    if ( oneModDirBtn->isChecked() ) {
+      MapProducts::Iterator mapIter;
+      for ( mapIter = productsMap.begin(); mapIter != productsMap.end(); ++mapIter )
+       if ( mapIter.data().getName() == prodProc && mapIter.data().getType() == "component" ) {
+         shellProcess->addArgument( oneModDirName );
+         break;
+       }
+    }
+    // ... single installation directory for prerequisites, if this option was selected
+    if ( oneProdDirBtn->isChecked() ) {
+      if ( prodProc == "DebianLibsForSalome" )
+       shellProcess->addArgument( oneProdDirName );
+      else {
+       MapProducts::Iterator mapIter;
+       for ( mapIter = productsMap.begin(); mapIter != productsMap.end(); ++mapIter )
+         if ( mapIter.data().getName() == prodProc && mapIter.data().getType() == "prerequisite" ) {
+           shellProcess->addArgument( oneProdDirName );
+           break;
+         }
+      }
+    }
+    
     // run script
     if ( !shellProcess->start() ) {
       // error handling can be here
@@ -1919,7 +2148,7 @@ void SALOME_InstallWizard::launchScript()
   // all products are installed successfully
   MapProducts::Iterator mapIter;
   ___MESSAGE___( "starting pick-up environment" );
-  QString depproducts = QUOTE( DefineDependeces(productsMap).prepend( "gcc " ) );
+  QString depproducts = QUOTE( getAllProducts(productsMap).prepend( QStringList( extraProducts.keys() ).join(" ") + " " ) );
   for ( mapIter = productsMap.begin(); mapIter != productsMap.end(); ++mapIter ) {
     QCheckListItem* item = mapIter.key();
     Dependancies dep = mapIter.data();
@@ -1942,24 +2171,17 @@ void SALOME_InstallWizard::launchScript()
       }
     }
   }
-  
+
   if ( installType == Binaries ) {
-    // Check Fortran libraries
-    // ... update status label
-    statusLab->setText( tr( "Check Fortran libraries..." ) );
-    // ... search "not found" libraries
-    checkFLibProc->setWorkingDirectory( QDir::cleanDirPath( QFileInfo( "./config_files/" ).absFilePath() ) );
-    checkFLibProc->addArgument( "checkFortran.sh" );
-    checkFLibProc->addArgument( "find_libraries" );
-    checkFLibProc->addArgument( QDir::cleanDirPath( QFileInfo( targetFolder->text().stripWhiteSpace() ).absFilePath() ) );
-    // ... run script
-    if ( !checkFLibProc->start() ) {
-      ___MESSAGE___( "Error: process could not start!" );
-    }
+    if ( oneModDirBtn->isChecked() )
+      runModifyLaFiles();
+    else
+      runCheckFLib();
   }
-  else
+  else {
     // Update GUI and check installation errors
     completeInstallation();
+  }
   
 }
 // ================================================================
@@ -2021,7 +2243,8 @@ void SALOME_InstallWizard::onInstallGuiBtn()
       }
       else {
        QString itemName = itProd.data().getName();
-       if ( itemName != "KERNEL" && itemName != "MED" && itemName != "SAMPLES" ) {
+       if ( woGuiModules.find( itemName ) == woGuiModules.end() || 
+            woGuiModules[ itemName ] == False ) {
          itProd.key()->setOn( false );
          itProd.key()->setEnabled( false );
        }
@@ -2189,7 +2412,7 @@ void SALOME_InstallWizard::clean(bool rmDir)
   QString script = "cd ./config_files/; remove_tmp.sh '";
   script += tempFolder->text().stripWhiteSpace() + TEMPDIRNAME;
   script += "' ";
-  script += QUOTE(DefineDependeces(productsMap));
+  script += QUOTE(getAllProducts(productsMap));
   script += " > /dev/null";
   ___MESSAGE___( "script = " << script.latin1() );
   if ( system( script.latin1() ) ) {
@@ -2228,9 +2451,10 @@ void SALOME_InstallWizard::pageChanged( const QString & mytitle)
   if ( aPage == typePage ) {
     // installation type page
     if ( buttonGrp->id( buttonGrp->selected() ) == -1 )
-      binBtn->animateClick(); // set default installation type
+      // set default installation type
+      forceSrc ? srcCompileBtn->animateClick() : binBtn->animateClick();
   }
-  if ( aPage == platformsPage ) {
+  else if ( aPage == platformsPage ) {
     // installation platforms page
     MapXmlFiles::Iterator it;
     if ( previousPage == typePage ) {
@@ -2240,6 +2464,8 @@ void SALOME_InstallWizard::pageChanged( const QString & mytitle)
        if ( installType == Binaries ) {
          QFileInfo fib( QDir::cleanDirPath( getBinPath() + "/" + plat ) );
          rb->setEnabled( fib.exists() );
+         if ( platBtnGrp->id( platBtnGrp->selected() ) == -1 && plat == getBasePlatform() )
+           rb->animateClick();
        }
        else {
          QFileInfo fis( QDir::cleanDirPath( getSrcPath() ) );
@@ -2252,7 +2478,7 @@ void SALOME_InstallWizard::pageChanged( const QString & mytitle)
   }
   else  if ( aPage == dirPage ) {
     // installation and temporary directories page
-    if ( ( indexOf( platformsPage ) != -1 ? 
+    if ( ( ( this->indexOf( platformsPage ) != -1 && this->appropriate( platformsPage ) ) ? 
           previousPage == platformsPage : previousPage == typePage ) 
         && stateChanged ) {
       // clear global variables before reading XML file
@@ -2267,6 +2493,18 @@ void SALOME_InstallWizard::pageChanged( const QString & mytitle)
       if ( tempFolder->text().isEmpty() )
        parser->setTempDir( tempFolder );
       parser->readXmlFile( xmlFileName );
+      // create a map of SALOME modules names, that can support installation without GUI mode
+      if ( woGuiModules.isEmpty() ) {
+       MapProducts::Iterator mapIter;
+       for ( mapIter = productsMap.begin(); mapIter != productsMap.end(); mapIter++ ) {
+         Dependancies dep = mapIter.data();
+         if ( dep.getType() == "component" && dep.supportWoGuiMode() != NotDefined )
+           woGuiModules[ dep.getName() ] = dep.supportWoGuiMode();
+       }
+      }
+  
+      // update required size for each product
+      updateSizeColumn();
       // take into account command line parameters
       if ( !myTargetPath.isEmpty() )
        targetFolder->setText( myTargetPath );
@@ -2278,7 +2516,17 @@ void SALOME_InstallWizard::pageChanged( const QString & mytitle)
       if ( modulesView->childCount() > 0 && !modulesView->selectedItem() )
        modulesView->setSelected( modulesView->firstChild(), true );
       stateChanged = false;
+    } 
+    else if ( rmSrcPrevState != removeSrcBtn->isChecked() ) {
+      // only update required size for each product
+      updateSizeColumn();
+      rmSrcPrevState = removeSrcBtn->isChecked();
     }
+    // add extra products to install list
+    extraProducts.clear();
+    extraProducts.insert( "gcc", "gcc-common.sh" );
+    if ( refPlatform == commonPlatform && installType == Binaries )
+      extraProducts.insert( "DebianLibsForSalome", "DEBIANFORSALOME-3.1.sh" );
   }
   else if ( aPage == productsPage ) {
     // products page
@@ -2346,16 +2594,20 @@ void SALOME_InstallWizard::onButtonGroup( int rbIndex )
     installType = InstallationType( rbIndex );
     // management of the <Remove source and tmp files> check-box
     removeSrcBtn->setEnabled( installType == Compile );
+    oneModDirBtn->setEnabled( installType == Binaries /*|| installType == Compile*/ );
+    oneProdDirBtn->setEnabled( installType == Binaries || installType == Compile );
   }
   else if ( aPage == platformsPage ) {
     refPlatform = platBtnGrp->find( rbIndex )->name();
     xmlFileName = platformsMap[ refPlatform ];
-    cout << xmlFileName << endl;
+//     cout << xmlFileName << endl;
     setNextEnabled( platformsPage, true );
   }
   if ( prevType != installType || 
        ( indexOf( platformsPage ) != -1 ? prevPlat != getPlatform() : false ) ) {
     stateChanged = true;
+    oneModDirBtn->setChecked( false );
+    oneProdDirBtn->setChecked( false );
   }
 }
 // ================================================================
@@ -2423,10 +2675,10 @@ void SALOME_InstallWizard::directoryChanged( const QString& /*text*/ )
 // ================================================================
 void SALOME_InstallWizard::onStart()
 {
-  cout << "" << endl;
   if ( nextButton()->text() == tr( "&Stop" ) ) {
     statusLab->setText( tr( "Aborting installation..." ) );
     shellProcess->kill();
+    modifyLaProc->kill();
     while( shellProcess->isRunning() );
     statusLab->setText( tr( "Installation has been aborted by user" ) );
     return;
@@ -2445,8 +2697,8 @@ void SALOME_InstallWizard::onStart()
   // clear lists of products
   toInstall.clear();
   notInstall.clear();
+  toInstall += extraProducts.keys();
   // ... and fill it for new process
-  toInstall.append( "gcc" );
   QCheckListItem* item = (QCheckListItem*)( prereqsView->firstChild() );
   while( item ) {
     if ( productsMap.contains( item ) ) {
@@ -2475,6 +2727,7 @@ void SALOME_InstallWizard::onStart()
       statusLab->setText( tr( "Check Fortran compiler..." ) );
       // check Fortran compiler.
       QString script = "./config_files/checkFortran.sh find_compilers";
+      script += " " + QUOTE( QFileInfo( QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + TEMPDIRNAME ).absFilePath() );
       ___MESSAGE___( "script = " << script.latin1() );
       if ( system( script ) ) {
        QMessageBox::critical( this,
@@ -2517,12 +2770,12 @@ void SALOME_InstallWizard::onStart()
     ProgressViewItem* progressItem;
     // set status for installed products
     for ( int i = 0; i < (int)toInstall.count(); i++ ) {
-      if ( toInstall[i] != "gcc" ) {
+      if ( !extraProducts.contains( toInstall[i] ) ) {
        item = findItem( toInstall[i] );
        progressView->addProduct( item->text(0), item->text(2) );
        continue;
       }
-      progressItem = progressView->addProduct( "gcc", "gcc-common.sh" );
+      progressItem = progressView->addProduct( toInstall[i], extraProducts[toInstall[i]] );
       progressItem->setVisible( false );
     }
     // set status for not installed products
@@ -2534,7 +2787,7 @@ void SALOME_InstallWizard::onStart()
     // get specified list of products being installed
     prodSequence.clear();
     for (int i = 0; i<(int)toInstall.count(); i++ ) {
-      if ( toInstall[i] == "gcc" ) {
+      if ( extraProducts.contains( toInstall[i] ) ) {
        prodSequence.append( toInstall[i] );
        continue;
       }
@@ -2686,12 +2939,15 @@ void SALOME_InstallWizard::tryTerminate()
 void SALOME_InstallWizard::onCancel()
 {
   shellProcess->kill();
+  modifyLaProc->kill();
+  checkFLibProc->kill();
   reject();
 }
 // ================================================================
 /*!
  *  SALOME_InstallWizard::onSelectionChanged
  *  Called when selection is changed in the products list view
+ *  to fill in the 'Information about product' text box
  */
 // ================================================================
 void SALOME_InstallWizard::onSelectionChanged()
@@ -2700,11 +2956,9 @@ void SALOME_InstallWizard::onSelectionChanged()
   QListViewItem* item = modulesView->selectedItem();
   if ( snd == prereqsView )
     item = prereqsView->selectedItem();
-  else if ( snd != modulesView )
-    return;
-  productInfo->clear();
   if ( !item )
     return;
+  productInfo->clear();
   QCheckListItem* anItem = (QCheckListItem*)item;
   if ( !productsMap.contains( anItem ) )
     return;
@@ -2716,14 +2970,13 @@ void SALOME_InstallWizard::onSelectionChanged()
   if ( !dep.getDescription().isEmpty() ) {
     text += "<i>" + dep.getDescription() + "</i><br><br>";
   }
-  long totSize = 0, tempSize = 0;
-  if ( installType == Compile && removeSrcBtn->state() == QButton::On )
-    totSize = dep.getSize( Binaries );
-  else
-    totSize = dep.getSize( installType );
-  tempSize = dep.getTempSize( installType );
-  text += tr( "Disk space required" ) + ": " + QString::number( totSize ) + " KB<br>";
-  text += tr( "Disk space for tmp files required" ) + ": " + QString::number( tempSize ) + " KB<br>";
+  /* AKL: 07/08/28 - hide required disk space for tmp files for each product ==>
+     long tempSize = 0;
+     tempSize = dep.getTempSize( installType );
+     text += tr( "Disk space for tmp files required" ) + ": " + QString::number( tempSize ) + " KB<br>";
+     AKL: 07/08/28 - hide required disk space for tmp files for each product <==
+  */
+  text += tr( "Disk space required" ) + ": " + item->text(1) + "<br>";
   text += "<br>";
   QString req = ( dep.getDependancies().count() > 0 ? dep.getDependancies().join(", ") : tr( "none" ) );
   text +=  tr( "Prerequisites" ) + ": " + req;
@@ -2766,11 +3019,12 @@ void SALOME_InstallWizard::wroteToStdin( )
 void SALOME_InstallWizard::readFromStdout( )
 {
   ___MESSAGE___( "Something was sent to stdout" );
-  while ( shellProcess->canReadLineStdout() ) {
-    installInfo->append( QString( shellProcess->readLineStdout() ) );
+  QProcess* theProcess = ( QProcess* )sender();
+  while ( theProcess->canReadLineStdout() ) {
+    installInfo->append( QString( theProcess->readLineStdout() ) );
     installInfo->scrollToBottom();
   }
-  QString str( shellProcess->readStdout() );
+  QString str( theProcess->readStdout() );
   if ( !str.isEmpty() ) {
     installInfo->append( str );
     installInfo->scrollToBottom();
@@ -2788,12 +3042,13 @@ void SALOME_InstallWizard::readFromStdout( )
 void SALOME_InstallWizard::readFromStderr( )
 {
   ___MESSAGE___( "Something was sent to stderr" );
-  while ( shellProcess->canReadLineStderr() ) {
-    installInfo->append( OUTLINE_TEXT( QString( shellProcess->readLineStderr() ) ) );
+  QProcess* theProcess = ( QProcess* )sender();
+  while ( theProcess->canReadLineStderr() ) {
+    installInfo->append( OUTLINE_TEXT( QString( theProcess->readLineStderr() ) ) );
     installInfo->scrollToBottom();
     hasErrors = true;
   }
-  QString str( shellProcess->readStderr() );
+  QString str( theProcess->readStderr() );
   if ( !str.isEmpty() ) {
     installInfo->append( OUTLINE_TEXT( str ) );
     installInfo->scrollToBottom();
@@ -2876,6 +3131,7 @@ void SALOME_InstallWizard::saveLog()
   QDateTime dt = QDateTime::currentDateTime();
   QString fileName = dt.toString("ddMMyy-hhmm");
   fileName.prepend("install-"); fileName.append(".html");
+  fileName = QFileInfo( QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() ), fileName ).absFilePath();
   fileName = QFileDialog::getSaveFileName( fileName,
                                           QString( "HTML files (*.htm *.html)" ),
                                           this, 0,