Salome HOME
Adding HEXABLOCK and HEXABLOCKPLUGIN
[tools/install.git] / src / SALOME_InstallWizard.cxx
index c571e81d52e3a97c509e37ec7a26c5ef8a042e58..7502e00cfb9111f7f1d5b6145810ddd22eb7994a 100644 (file)
@@ -3,7 +3,7 @@
 //  Author    : Vadim SANDLER, Open CASCADE SAS (vadim.sandler@opencascade.com)
 //  Project   : SALOME
 //  Module    : Installation Wizard
-//  Copyright : 2002-2008 CEA
+//  Copyright : 2002-2010 CEA
 
 #include "globals.h"
 
@@ -61,6 +61,9 @@
 QString tmpDirName() { return QString(  "/INSTALLWORK" ) + QString::number( getpid() ); }
 #define TEMPDIRNAME tmpDirName()
 
+// uncomment next line to redirect all shell output (usually for errors) to /dev/null device
+// #define USE_DEV_NULL
+
 // ================================================================
 /*!
  *  Script
@@ -313,8 +316,15 @@ static bool makeDir( const QString& theDir, QString& theCreated )
       if ( !fi.exists() ) {
        // VSR: Create directory and set permissions to allow other users to remove it
        Script script;
-       script << "mkdir"     << QUOTE( fi.absFilePath() ) << ">& /dev/null" << "&&";
-       script << "chmod 777" << QUOTE( fi.absFilePath() ) << ">& /dev/null";
+       script << "mkdir" << QUOTE( fi.absFilePath() );
+#ifdef USE_DEV_NULL
+       script << ">& /dev/null";
+#endif
+       script << "&&";
+       script << "chmod 777" << QUOTE( fi.absFilePath() );
+#ifdef USE_DEV_NULL
+       script << ">& /dev/null";
+#endif
        ___MESSAGE___( "script = " << script.script().latin1() );
        if ( system( script.script().latin1() ) )
          return false;
@@ -328,7 +338,10 @@ static bool makeDir( const QString& theDir, QString& theCreated )
   if ( !QFileInfo( aDir ).exists() ) {
     // VSR: Create directory, other users should NOT have possibility to remove it!!!
     Script script;
-    script << "mkdir" << QUOTE( aDir ) << ">& /dev/null";
+    script << "mkdir" << QUOTE( aDir );
+#ifdef USE_DEV_NULL
+    script << ">& /dev/null";
+#endif
     ___MESSAGE___( "script = " << script.script().latin1() );
     if ( system( script.script().latin1() ) )
       return false;
@@ -465,8 +478,7 @@ public:
                      .arg( __IW_VERSION_MINOR__ ) \
                      .arg( __IW_VERSION_PATCH__ ) );
     QLabel* copyright = new QLabel( this, "copyright" );
-    copyright->setText( "<b>Copyright</b> &copy; 2007-2008 CEA/DEN, EDF R&amp;D, OPEN CASCADE<br><br>"
-                       "<b>Copyright</b> &copy; 2003-2007 OPEN CASCADE,<br>EADS/CCR, LIP6, CEA/DEN, CEDRAT, EDF R&amp;D,<br>LEG, PRINCIPIA R&amp;D, BUREAU VERITAS");
+    copyright->setText( "<b>Copyright</b> &copy; 2007-2011 CEA/DEN" );
     QFont font = title->font();
     font.setPointSize( (int)( font.pointSize() * 1.8 ) );
     title->setFont( font );
@@ -560,9 +572,9 @@ SALOME_InstallWizard::SALOME_InstallWizard(const QString& aXmlFileName,
   addLogo( pixmap( pxLogo ) );
 
   // set defaults
-  setVersion( "5.1.0" );
+  setVersion( "6.3.0" );
   setCaption( tr( "SALOME %1" ).arg( myVersion ) );
-  setCopyright( tr( "<h5>Copyright &copy; 2007-2008 CEA/DEN, EDF R&amp;D, OPEN CASCADE<br></h5>"
+  setCopyright( tr( "<h5>Copyright &copy; 2007-2011 CEA/DEN, EDF R&amp;D, OPEN CASCADE<br></h5>"
                "<h5>Copyright &copy; 2003-2007 OPEN CASCADE,<br>EADS/CCR, LIP6, CEA/DEN, CEDRAT, EDF R&amp;D,<br>LEG, PRINCIPIA R&amp;D, BUREAU VERITAS</h5>" ));
   setLicense( tr( "<h5>GNU LGPL</h5>" ) );
 
@@ -648,7 +660,10 @@ SALOME_InstallWizard::~SALOME_InstallWizard()
   int PID = (int)shellProcess->processIdentifier();
   if ( PID > 0 ) {
     Script script;
-    script << "kill -9" << QString::number( PID ) << ">& /dev/null";
+    script << "kill -9" << QString::number( PID );
+#ifdef USE_DEV_NULL
+    script << ">& /dev/null";
+#endif
     ___MESSAGE___( "script: " << script.script().latin1() );
     if ( system( script.script().latin1() ) ) {
       // error
@@ -771,11 +786,11 @@ MapXmlFiles SALOME_InstallWizard::getXmlMap( const QString& aXmlFileName )
   else {
     QDir dir( rootDirPath() );
     QStringList entries = dir.entryList( "*.xml", QDir::Files | QDir::Readable );
+    if ( entries.remove( "config.xml" ) )
+      entries.append( "config.xml" );
     for ( uint i = 0; i < entries.count(); i++ )
       xmlList.append( QDir( rootDirPath() ).filePath( entries[i] ) ); 
   }
-  if ( xmlList.remove( "config.xml" ) )
-    xmlList.append( "config.xml" );
   // XML files parsing
   QFile file;
   QDomDocument doc( "xml_doc" );
@@ -1345,14 +1360,20 @@ void SALOME_InstallWizard::setupProgressPage()
   progressView = new ProgressView( widget );
   progressView->setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Expanding ) );
   progressView->setMinimumSize( 100, 10 );
+  // possibility to ignore all errors
+  ignoreErrCBox = new QCheckBox( tr( "Ignore errors" ), widget );
+  setAboutInfo( ignoreErrCBox, tr( "Check this option if you want to proceed installation \nprocess even there will be some errors" ) );
+  ignoreErrCBox->setChecked( false );
+  // product installation status bar
   statusLab = new QLabel( widget );
   statusLab->setFrameShape( QButtonGroup::LineEditPanel );
   setAboutInfo( progressView, tr( "Installation status on the selected products" ) );
   // layouting
   layout->addRowSpacing( 0, 6 );
-  layout->addWidget( resultLab,    1, 0 );
-  layout->addWidget( progressView, 2, 0 );
-  layout->addWidget( statusLab,    3, 0 );
+  layout->addWidget( resultLab,     1, 0 );
+  layout->addWidget( progressView,  2, 0 );
+  layout->addWidget( ignoreErrCBox, 3, 0 );
+  layout->addWidget( statusLab,     4, 0 );
   // layouting
   pageLayout->addWidget( splitter,  0, 0 );
   // adding page
@@ -1882,11 +1903,7 @@ void SALOME_InstallWizard::checkModifyLaResult()
                           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() ) );
+    doPostActions( tr( "&Start" ), tr( "Start installation process" ) );
     connect(    this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
     // enable <Back> button
     setBackEnabled( true );
@@ -1895,7 +1912,7 @@ void SALOME_InstallWizard::checkModifyLaResult()
 // ================================================================
 /*!
  *  SALOME_InstallWizard::runCheckFLib
- *  Run the Fortran libraries checking
+ *  Run the Fortran and other required libraries checking
  */
 // ================================================================
 void SALOME_InstallWizard::runCheckFLib()
@@ -1903,7 +1920,7 @@ void SALOME_InstallWizard::runCheckFLib()
   // Check Fortran libraries
   checkFLibProc->clearArguments();
   // ... update status label
-  statusLab->setText( tr( "Check Fortran libraries..." ) );
+  statusLab->setText( tr( "Check Fortran and other required libraries..." ) );
   // ... search "not found" libraries
   checkFLibProc->setWorkingDirectory( QDir( rootDirPath() ).filePath( "config_files" ) );
   checkFLibProc->addArgument( "checkFortran.sh" );
@@ -1916,26 +1933,58 @@ void SALOME_InstallWizard::runCheckFLib()
 // ================================================================
 /*!
  *  SALOME_InstallWizard::checkFLibResult
- *  Slot to take result of Fortran libraries checking
+ *  Slot to take result of Fortran and other required libraries checking
  */
 // ================================================================
 void SALOME_InstallWizard::checkFLibResult()
 {
   if ( checkFLibProc->normalExit() && checkFLibProc->exitStatus() == 1 ) {
-    QStringList notFoundLibsList;
+    QStringList notFoundLibsList, notFoundOptLibsList;
     QString record = "";
+    QStringList prefOptLibs = getOptionalLibs();
+    // create list of strings with all 'not found' libraries
     while ( checkFLibProc->canReadLineStdout() ) {
-      record = checkFLibProc->readLineStdout();
-      if ( !record.isEmpty() && !notFoundLibsList.contains( record ) )
-       notFoundLibsList.append( record );
-    }
-    QMessageBox::warning( this,
-                         tr( "Warning" ),
-                         tr( "The following libraries are absent on current system:\n"
-                         "%1").arg( notFoundLibsList.join( "\n" ) ),
-                         QMessageBox::Ok,
-                         QMessageBox::NoButton,
-                         QMessageBox::NoButton );
+      record = checkFLibProc->readLineStdout().stripWhiteSpace();
+      if ( !record.isEmpty() ) {
+       record = QStringList::split( " ", record )[0];
+       if ( !notFoundLibsList.contains( record ) && 
+            !notFoundOptLibsList.contains( record ) ) {
+         bool isOptional = false;
+         QStringList::Iterator it_opt;
+         for ( it_opt = prefOptLibs.begin(); it_opt != prefOptLibs.end(); ++it_opt )
+           if ( record.startsWith( (*it_opt).stripWhiteSpace(), false ) ) {
+             isOptional = true;
+             break;
+           }
+         isOptional ? notFoundOptLibsList.append( record )             \
+           : notFoundLibsList.append( record );
+       }
+      }
+    }
+    QString msg = tr( "Some libraries are absent!<br><br>" );
+    if ( !notFoundLibsList.isEmpty() ) {
+      msg += tr( "One or several <b>mandatory</b> libraries listed below are not found. SALOME <u>may not work</u> properly.<br>" );
+      msg += notFoundLibsList.join( "<br>" );
+      msg += "<br><br>";
+    }
+    if ( !notFoundOptLibsList.isEmpty() ) {
+      msg += tr( "One or several <b>optional</b> libraries listed below are not found. This <u>does not affect</u> on the correct work of SALOME platform.<br>" );
+      msg += notFoundOptLibsList.join( "<br>" );
+    }
+    if ( !notFoundLibsList.isEmpty() )
+      QMessageBox::warning( this,
+                           tr( "Warning" ),
+                           msg,
+                           QMessageBox::Ok,
+                           QMessageBox::NoButton,
+                           QMessageBox::NoButton );
+    else if ( !notFoundOptLibsList.isEmpty() )
+      QMessageBox::information( this,
+                               tr( "Information" ),
+                               msg,
+                               QMessageBox::Ok,
+                               QMessageBox::NoButton,
+                               QMessageBox::NoButton );
   }
   // Update GUI and check installation errors
   completeInstallation();
@@ -2240,6 +2289,12 @@ void SALOME_InstallWizard::launchScript()
     }
     return;
   }
+
+  // else try to find aborted product
+  prodProc = progressView->findStatus( Aborted );
+  if ( !prodProc.isNull() )
+    return; // installation has been aborted
+
   ___MESSAGE___( "All products have been installed successfully" );
   // all products are installed successfully
   MapProducts::Iterator mapIter;
@@ -2290,10 +2345,7 @@ void SALOME_InstallWizard::completeInstallation()
   statusLab->setText( tr( "Installation completed" ) );
   // <Next> button
   setNextEnabled( true );
-  nextButton()->setText( tr( "&Next >" ) );
-  setAboutInfo( nextButton(), tr( "Move to the next step of the installation procedure" ) );
-  disconnect( this, SIGNAL( nextClicked() ), this, SLOT( next() ) );
-  disconnect( this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
+  doPostActions( tr( "&Next >" ), tr( "Move to the next step of the installation procedure" ) );
   connect(    this, SIGNAL( nextClicked() ), this, SLOT( next() ) );
   // <Back> button
   setBackEnabled( true );
@@ -2308,7 +2360,7 @@ void SALOME_InstallWizard::completeInstallation()
   if ( hasErrors ) {
     if ( QMessageBox::warning( this,
                               tr( "Warning" ),
-                              tr( "There were some errors and/or warnings during the installation.\n"
+                              tr( "There were some errors during the installation.\n"
                                   "Do you want to save the installation log?" ),
                               tr( "&Save" ),
                               tr( "&Cancel" ),
@@ -2393,7 +2445,9 @@ void SALOME_InstallWizard::onFinishButton()
       script << (*it).script() << "execute";
       script << QUOTE( QFileInfo( QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() ) ).absFilePath() );
       script << QUOTE( QFileInfo( QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + TEMPDIRNAME ).absFilePath() );
+#ifdef USE_DEV_NULL
       script << ">& /dev/null";
+#endif
       ___MESSAGE___( "script: " << script.script().latin1() );
       if ( (*it).script().isEmpty() || system( script.script().latin1() ) ) {
        QMessageBox::warning( this,
@@ -2508,7 +2562,9 @@ void SALOME_InstallWizard::clean(bool rmDir)
   script << "cd" << QUOTE( rd.filePath( "config_files" ) ) << ";";
   script << "remove_tmp.sh" << QUOTE( tempFolder->text().stripWhiteSpace() + TEMPDIRNAME );
   script << QUOTE( getAllProducts( productsMap ) );
+#ifdef USE_DEV_NULL
   script << ">& /dev/null";
+#endif
   ___MESSAGE___( "script = " << script.script().latin1() );
   if ( system( script.script().latin1() ) ) {
     // error
@@ -2518,7 +2574,9 @@ void SALOME_InstallWizard::clean(bool rmDir)
   if ( rmDir && !tmpCreated.isNull() ) {
     script.clear();
     script << "rm -rf" << QUOTE( tmpCreated );
+#ifdef USE_DEV_NULL
     script << ">& /dev/null";
+#endif
     if ( system( script.script().latin1() ) ) {
       // error
     }
@@ -2533,10 +2591,7 @@ void SALOME_InstallWizard::clean(bool rmDir)
 // ================================================================
 void SALOME_InstallWizard::pageChanged( const QString & mytitle)
 {
-  nextButton()->setText( tr( "&Next >" ) );
-  setAboutInfo( nextButton(), tr( "Move to the next step of the installation procedure" ) );
-  disconnect( this, SIGNAL( nextClicked() ), this, SLOT( next() ) );
-  disconnect( this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
+  doPostActions( tr( "&Next >" ), tr( "Move to the next step of the installation procedure" ) );
   connect(    this, SIGNAL( nextClicked() ), this, SLOT( next() ) );
   cancelButton()->disconnect();
   connect( cancelButton(), SIGNAL( clicked()), this, SLOT( reject() ) );
@@ -2622,7 +2677,7 @@ void SALOME_InstallWizard::pageChanged( const QString & mytitle)
     }
     // add extra products to install list
     extraProducts.clear();
-    extraProducts.insert( "gcc", "gcc-common.sh" );
+    //extraProducts.insert( "gcc", "gcc-common.sh" );
     if ( refPlatform == commonPlatform && installType == Binaries )
       extraProducts.insert( "DebianLibsForSalome", "DEBIANFORSALOME-3.1.sh" );
   }
@@ -2645,11 +2700,7 @@ void SALOME_InstallWizard::pageChanged( const QString & mytitle)
       passedParams->clear();
       passedParams->setEnabled( false );
       QFont f = parametersLab->font(); f.setBold( false ); parametersLab->setFont( f );
-      nextButton()->setText( tr( "&Start" ) );
-      setAboutInfo( nextButton(), tr( "Start installation process" ) );
-      // reconnect Next button - to use it as Start button
-      disconnect( this, SIGNAL( nextClicked() ), this, SLOT( next() ) );
-      disconnect( this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
+      doPostActions( tr( "&Start" ), tr( "Start installation process" ) );
       connect(    this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
       setNextEnabled( true );
       // reconnect Cancel button to terminate process
@@ -2667,7 +2718,9 @@ void SALOME_InstallWizard::pageChanged( const QString & mytitle)
        script << (*it).script() << "check_enabled";
        script << QUOTE( QFileInfo( QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() ) ).absFilePath() );
        script << QUOTE( QFileInfo( QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + TEMPDIRNAME ).absFilePath() );
+#ifdef USE_DEV_NULL
        script << ">& /dev/null";
+#endif
        ___MESSAGE___( "script: " << script.script().latin1() );
        (*it).button()->setEnabled( !(*it).script().isEmpty() && !system( script.script().latin1() ) );
       }
@@ -2789,6 +2842,8 @@ void SALOME_InstallWizard::onStart()
   installInfo->setFinished( false );
   passedParams->clear();
   passedParams->setEnabled( false );
+  // disable 'Ignore errors' checkbox during installation process
+  ignoreErrCBox->setEnabled( false );
   QFont f = parametersLab->font(); f.setBold( false ); parametersLab->setFont( f );
 
   // update status label
@@ -2819,7 +2874,7 @@ void SALOME_InstallWizard::onStart()
     item = (QCheckListItem*)( item->nextSibling() );
   }
   // if something at all is selected
-  if ( (int)toInstall.count() > 1 ) {
+  if ( (int)toInstall.count() > 0 ) {
 
     if ( installType == Compile ) {
       // update status label
@@ -2843,11 +2898,7 @@ void SALOME_InstallWizard::onStart()
        statusLab->setText( tr( "Installation has been aborted" ) );
        // enable <Next> button
        setNextEnabled( true );
-       nextButton()->setText( tr( "&Start" ) );
-       setAboutInfo( nextButton(), tr( "Start installation process" ) );
-       // reconnect Next button - to use it as Start button
-       disconnect( this, SIGNAL( nextClicked() ), this, SLOT( next() ) );
-       disconnect( this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
+       doPostActions( tr( "&Start" ), tr( "Start installation process" ) );
        connect(    this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
        // enable <Back> button
        setBackEnabled( true );
@@ -2929,13 +2980,9 @@ void SALOME_InstallWizard::onStart()
        // installation aborted
        abort();
        statusLab->setText( tr( "Installation has been aborted by user" ) );
-       // enable <Next> button
+       // update <Next> button
        setNextEnabled( true );
-       nextButton()->setText( tr( "&Start" ) );
-       setAboutInfo( nextButton(), tr( "Start installation process" ) );
-       // reconnect Next button - to use it as Start button
-       disconnect( this, SIGNAL( nextClicked() ), this, SLOT( next() ) );
-       disconnect( this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
+       doPostActions( tr( "&Start" ), tr( "Start installation process" ) );
        connect(    this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
        // enable <Back> button
        setBackEnabled( true );
@@ -2987,16 +3034,9 @@ void SALOME_InstallWizard::productInstalled()
     installInfo->setFinished( true );
     // enable <Next> button
     setNextEnabled( true );
-    nextButton()->setText( tr( "&Start" ) );
-    setAboutInfo( nextButton(), tr( "Start installation process" ) );
-    // reconnect Next button - to use it as Start button
-    disconnect( this, SIGNAL( nextClicked() ), this, SLOT( next() ) );
-    disconnect( this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
+    doPostActions( tr( "&Start" ), tr( "Start installation process" ) );
     connect(    this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
-    //nextButton()->setText( tr( "&Next >" ) );
-    //setAboutInfo( nextButton(), tr( "Move to the next step of the installation procedure" ) );
-    //disconnect( this, SIGNAL( nextClicked() ), this, SLOT( next() ) );
-    //disconnect( this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
+    //doPostActions( tr( "&Next >" ), tr( "Move to the next step of the installation procedure" ) );
     //connect(    this, SIGNAL( nextClicked() ), this, SLOT( next() ) );
     // enable <Back> button
     setBackEnabled( true );
@@ -3157,6 +3197,10 @@ void SALOME_InstallWizard::readFromStderr( )
     installInfo->scrollToBottom();
     hasErrors = true;
   }
+
+  // stop or proceed installation process
+  manageInstProc();
+
   // VSR: 10/11/05 - disable answer mode ==>
   // passedParams->setEnabled( true );
   // passedParams->setFocus();
@@ -3164,6 +3208,41 @@ void SALOME_InstallWizard::readFromStderr( )
   // VSR: 10/11/05 - disable answer mode <==
 }
 // ================================================================
+/*!
+ *  SALOME_InstallWizard::manageInstProc
+ *  QProcess slot: -->stop installation if there is an error in stderr
+ */
+// ================================================================
+void SALOME_InstallWizard::manageInstProc()
+{
+  if ( !hasErrors || ignoreErrCBox->isChecked() )
+    return; //proceed installation process
+  
+  // abort the current installation
+  statusLab->setText( tr( "Aborting installation..." ) );
+  abort();
+  statusLab->setText( tr( "Installation has been aborted because some errors" ) );
+  if ( QMessageBox::critical( this,
+                             tr( "Error" ),
+                             tr( "Installation process has been stopped, because an error occured \n"
+                                 "during an installation of the current product!\n"
+                                 "Please see the installation progress view for more details about the error.\n\n"
+                                 "Do you want to save the installation log?" ),
+                             tr( "&Save" ),
+                             tr( "&Cancel" ),
+                             QString::null,
+                             0,
+                             1 ) == 0 )
+    saveLog();
+  // enable <Next> button
+  setNextEnabled( true );
+  doPostActions( tr( "&Start" ), tr( "Start installation process" ) );
+  connect( this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
+  // enable <Back> button
+  setBackEnabled( true );
+  installInfo->setFinished( true );
+}
+// ================================================================
 /*!
  *  SALOME_InstallWizard::setDependancies
  *  Sets dependancies for the product item
@@ -3174,6 +3253,24 @@ void SALOME_InstallWizard::setDependancies( QCheckListItem* item, Dependancies d
   productsMap[item] = dep;
 }
 // ================================================================
+/*!
+ *  SALOME_InstallWizard::doPostActions
+ *  Executes some actions after finish of installation process (successful or not)
+ */
+// ================================================================
+void SALOME_InstallWizard::doPostActions( const QString& btnText,
+                                         const QString& btnAboutInfo )
+{
+  // update <Next> button
+  nextButton()->setText( btnText );
+  setAboutInfo( nextButton(), btnAboutInfo );
+  // reconnect Next button - to use it as Start button
+  disconnect( this, SIGNAL( nextClicked() ), this, SLOT( next() ) );
+  disconnect( this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
+  // enable 'Ignore errors' checkbox
+  ignoreErrCBox->setEnabled( true );
+}
+// ================================================================
 /*!
  *  SALOME_InstallWizard::addFinishButton
  *  Add button for the <Finish> page.