]> SALOME platform Git repositories - tools/install.git/blob - src/SALOME_InstallWizard.cxx
Salome HOME
Update SALOME version
[tools/install.git] / src / SALOME_InstallWizard.cxx
1 //  File      : SALOME_InstallWizard.cxx
2 //  Created   : Thu Dec 18 12:01:00 2002
3 //  Author    : Vadim SANDLER, Open CASCADE SAS (vadim.sandler@opencascade.com)
4 //  Project   : SALOME
5 //  Module    : Installation Wizard
6 //  Copyright : 2002-2012 CEA
7
8 #include "globals.h"
9
10 #include "SALOME_InstallWizard.hxx"
11 #include "SALOME_ProductsView.hxx"
12 #include "SALOME_ProgressView.hxx"
13 #include "SALOME_XmlHandler.hxx"
14 #include "SALOME_HelpWindow.hxx"
15
16 #include "icons.h"
17
18 #include <qlineedit.h>
19 #include <qpushbutton.h>
20 #include <qlistview.h>
21 #include <qlabel.h>
22 #include <qtextedit.h>
23 #include <qtextbrowser.h>
24 #include <qprocess.h>
25 #include <qcheckbox.h>
26 #include <qsplitter.h>
27 #include <qlayout.h>
28 #include <qfiledialog.h>
29 #include <qapplication.h>
30 #include <qfileinfo.h>
31 #include <qmessagebox.h>
32 #include <qtimer.h>
33 #include <qvbox.h>
34 #include <qwhatsthis.h>
35 #include <qtooltip.h>
36 #include <qfile.h>
37 #include <qthread.h>
38 #include <qwaitcondition.h>
39 #include <qmutex.h>
40 #include <qstringlist.h>
41 #include <qpopupmenu.h>
42 #include <qregexp.h>
43 #include <qradiobutton.h>
44 #include <qbuttongroup.h>
45 #include <qregexp.h>
46 #include <qdir.h>
47
48 #ifdef WNT
49 #include <iostream.h>
50 #include <process.h>
51 #else
52 #include <unistd.h>
53 #include <algo.h>
54 #include <sys/utsname.h>
55 #endif
56
57 #ifdef WNT
58 #define max( x, y ) ( x ) > ( y ) ? ( x ) : ( y )
59 #endif
60
61 QString tmpDirName() { return QString(  "/INSTALLWORK" ) + QString::number( getpid() ); }
62 #define TEMPDIRNAME tmpDirName()
63
64 // uncomment next line to redirect all shell output (usually for errors) to /dev/null device
65 // #define USE_DEV_NULL
66
67 // ================================================================
68 /*!
69  *  Script
70  *  Helper class to generate shell command
71  */
72 // ================================================================
73 class Script
74 {
75 public:
76   Script( const QString& cmd = QString::null, const QString& sep = " " ) : mySeparator( sep )
77   {
78     append( cmd );
79   }
80   void append( const QString& cmd )
81   {
82     if ( !cmd.isEmpty() ) myList.append( cmd );
83   }
84   Script& operator<<( const QString& cmd )
85   {
86     append( cmd );
87     return *this;
88   }
89   QString script() const
90   {
91     return myList.join( mySeparator );
92   }
93   void clear()
94   {
95     myList.clear();
96   }
97 private:
98   QStringList myList;
99   QString     mySeparator;
100 };
101
102 // ================================================================
103 /*!
104  *  ProcessThread
105  *  Class for executing system commands
106  */
107 // ================================================================
108 static QMutex myMutex(false);
109 static QWaitCondition myWC;
110 class ProcessThread: public QThread
111 {
112   typedef QPtrList<QCheckListItem> ItemList;
113 public:
114   ProcessThread( SALOME_InstallWizard* iw ) : QThread(), myWizard( iw ) { myItems.setAutoDelete( false ); }
115
116   void addCommand( QCheckListItem* item, const QString& cmd ) {
117     myItems.append( item );
118     myCommands.push_back( cmd );
119   }
120
121   bool hasCommands() const { return myCommands.count() > 0; }
122   void clearCommands()     { myCommands.clear(); myItems.clear(); }
123
124   virtual void run() {
125     while ( hasCommands() ) {
126       ___MESSAGE___( "ProcessThread::run - Processing command : " << myCommands[ 0 ].latin1() );
127       int result = system( myCommands[ 0 ] ) / 256; // return code is <errno> * 256
128       ___MESSAGE___( "ProcessThread::run - Result : " << result );
129       QCheckListItem* item = myItems.first();
130       myCommands.pop_front();
131       myItems.removeFirst();
132       myMutex.lock();
133       SALOME_InstallWizard::postValidateEvent( myWizard, result, (void*)item );
134       if ( hasCommands() )
135         myWC.wait(&myMutex);
136       myMutex.unlock();
137     };
138   }
139
140 private:
141   QStringList           myCommands;
142   ItemList              myItems;
143   SALOME_InstallWizard* myWizard;
144 };
145
146 // ================================================================
147 /*!
148  *  WarnDialog
149  *  Warning dialog box
150  */
151 // ================================================================
152 class WarnDialog: public QDialog
153 {
154   static WarnDialog* myDlg;
155   bool myCloseFlag;
156
157   WarnDialog( QWidget* parent )
158   : QDialog( parent, "WarnDialog", true, WDestructiveClose ) {
159     setCaption( tr( "Information" ) );
160     myCloseFlag = false;
161     QLabel* lab = new QLabel( tr( "Please, wait while checking native products configuration ..." ), this );
162     lab->setAlignment( AlignCenter );
163     lab->setFrameStyle( QFrame::Box | QFrame::Plain );
164     QVBoxLayout* l = new QVBoxLayout( this );
165     l->setMargin( 0 );
166     l->add( lab );
167     this->setFixedSize( lab->sizeHint().width()  + 50,
168                         lab->sizeHint().height() * 5 );
169   }
170   void accept() { return; }
171   void reject() { return; }
172   void closeEvent( QCloseEvent* e )
173   { if ( !myCloseFlag ) return;
174     e->accept();
175     QDialog::closeEvent( e );
176   }
177   ~WarnDialog() { myDlg = 0; }
178 public:
179   static void showWarnDlg( QWidget* parent, bool show ) {
180     if ( show ) {
181       if ( !myDlg ) {
182         myDlg = new WarnDialog( parent );
183         QSize sh = myDlg->size();
184         myDlg->move( parent->x() + (parent->width()-sh.width())/2,
185                      parent->y() + (parent->height()-sh.height())/2 );
186         myDlg->show();
187       }
188       myDlg->raise();
189       myDlg->setFocus();
190     }
191     else {
192       if ( myDlg ) {
193         myDlg->myCloseFlag = true;
194         myDlg->close();
195       }
196     }
197   }
198   static bool isWarnDlgShown() { return myDlg != 0; }
199 };
200 WarnDialog* WarnDialog::myDlg = 0;
201
202 // ================================================================
203 /*!
204  *  InstallInfo
205  *  Installation progress info window class
206  */
207 // ================================================================
208 class InstallInfo : public QTextEdit
209 {
210 public:
211   InstallInfo( QWidget* parent ) : QTextEdit( parent ), finished( false ) {}
212   void setFinished( const bool f ) { finished = f; }
213 protected:
214   QPopupMenu* createPopupMenu( const QPoint& )
215   {
216     int para1, col1, para2, col2;
217     getSelection(&para1, &col1, &para2, &col2);
218     bool allSelected = hasSelectedText() &&
219       para1 == 0 && para2 == paragraphs()-1 && col1 == 0 && col2 == paragraphLength(para2);
220     QPopupMenu* popup = new QPopupMenu( this );
221     int id = popup->insertItem( tr( "&Copy" ) );
222     popup->setItemEnabled( id, hasSelectedText() );
223     popup->connectItem ( id, this, SLOT( copy() ) );
224     id = popup->insertItem( tr( "Select &All" ) );
225     popup->setItemEnabled( id, (bool)text().length() && !allSelected );
226     popup->connectItem ( id, this, SLOT( selectAll() ) );
227     if ( finished ) {
228       QWidget* p = parentWidget();
229       while ( p && !p->inherits( "SALOME_InstallWizard" ) )
230         p = p->parentWidget();
231       if ( p && p->inherits( "SALOME_InstallWizard" ) ) {
232         popup->insertSeparator();
233         id = popup->insertItem( tr( "&Save Log" ) );
234         popup->setItemEnabled( id, (bool)text().length() );
235         popup->connectItem ( id, (SALOME_InstallWizard*)p, SLOT( saveLog() ) );
236       }
237     }
238     return popup;
239   }
240 private:
241   bool finished;
242 };
243
244 // ================================================================
245 /*!
246  *  getAllProducts [ static ]
247  *  Defines list of all products as a string separated by space symbols
248  */
249 // ================================================================
250 static QString getAllProducts(MapProducts& theProductsMap)
251 {
252   QStringList aModules, aPrereqs;
253   for ( MapProducts::Iterator mapIter = theProductsMap.begin(); mapIter != theProductsMap.end(); ++mapIter ) {
254     QCheckListItem* item = mapIter.key();
255     Dependancies dep = mapIter.data();
256     QString curModule = item->text(0);
257     if ( !aModules.contains( curModule ) && !aPrereqs.contains( curModule ) ) {
258       if ( dep.getType() == "component" ) {
259         aModules.append( curModule );
260         aModules.append( curModule + "_src" );
261       }
262       else {
263         aPrereqs.append( curModule );
264         aPrereqs.append( curModule + "_src" );
265       }
266     }
267   }
268   return QStringList(aPrereqs+aModules).join(" ");
269 }
270
271 // ================================================================
272 /*!
273  *  setAboutInfo [ static ]
274  *  Sets 'what's this' and 'tooltip' information for the widget
275  */
276 // ================================================================
277 static void setAboutInfo( QWidget* widget, const QString& tip )
278 {
279   QWhatsThis::add( widget, tip );
280   QToolTip::add  ( widget, tip );
281 }
282
283 #define QUOTE(arg) QString("'") + QString(arg) + QString("'")
284
285 /* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
286                T H E   O L D   I M P L E M E N T A T I O N
287 static QString DefineDependeces(MapProducts& theProductsMap, QCheckListItem* product ){
288   QStringList aProducts;
289   if ( theProductsMap.contains( product ) ) {
290     Dependancies dep = theProductsMap[ product ];
291     QStringList deps = dep.getDependancies();
292     for (int i = 0; i<(int)deps.count(); i++ ) {
293       aProducts.append( deps[i] );
294     }
295   }
296   return QString("\"") + aProducts.join(" ") + QString("\"");
297 }
298 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */
299
300 // ================================================================
301 /*!
302  *  makeDir [ static ]
303  *  Makes directory recursively, returns false if not succedes
304  */
305 // ================================================================
306 static bool makeDir( const QString& theDir, QString& theCreated )
307 {
308   if ( theDir.isEmpty() )
309     return false;
310   QString aDir = QDir::cleanDirPath( QFileInfo( theDir ).absFilePath() );
311   int start = 1;
312   while ( start > 0 ) {
313     start = aDir.find( QDir::separator(), start );
314     if ( start > 0 ) {
315       QFileInfo fi( aDir.left( start ) );
316       if ( !fi.exists() ) {
317         // VSR: Create directory and set permissions to allow other users to remove it
318         Script script;
319         script << "mkdir" << QUOTE( fi.absFilePath() );
320 #ifdef USE_DEV_NULL
321         script << ">& /dev/null";
322 #endif
323         script << "&&";
324         script << "chmod 777" << QUOTE( fi.absFilePath() );
325 #ifdef USE_DEV_NULL
326         script << ">& /dev/null";
327 #endif
328         ___MESSAGE___( "script = " << script.script().latin1() );
329         if ( system( script.script().latin1() ) )
330           return false;
331         // VSR: Remember the top of the created directory (to remove it in the end of the installation)
332         if ( theCreated.isNull() )
333           theCreated = fi.absFilePath();
334       }
335     }
336     start++;
337   }
338   if ( !QFileInfo( aDir ).exists() ) {
339     // VSR: Create directory, other users should NOT have possibility to remove it!!!
340     Script script;
341     script << "mkdir" << QUOTE( aDir );
342 #ifdef USE_DEV_NULL
343     script << ">& /dev/null";
344 #endif
345     ___MESSAGE___( "script = " << script.script().latin1() );
346     if ( system( script.script().latin1() ) )
347       return false;
348     // VSR: Remember the top of the created directory (to remove it in the end of the installation)
349     if ( theCreated.isNull() )
350       theCreated = aDir;
351   }
352   return true;
353 }
354 // ================================================================
355 /*!
356  *  readFile [ static ]
357  *  Reads the file, returns false if can't open it
358  */
359 // ================================================================
360 static bool readFile( const QString& fileName, QString& text )
361 {
362   if ( QFile::exists( fileName ) ) {
363     QFile file( fileName );
364     if ( file.open( IO_ReadOnly ) ) {
365       QTextStream stream( &file );
366       QString line;
367       while ( !stream.eof() ) {
368         line = stream.readLine(); // line of text excluding '\n'
369         text += line + "\n";
370       }
371       file.close();
372       return true;
373     }
374   }
375   return false;
376 }
377 // ================================================================
378 /*!
379  *  hasSpace [ static ]
380  *  Checks if string contains spaces; used to check directory paths
381  */
382 // ================================================================
383 static bool hasSpace( const QString& dir )
384 {
385   for ( int i = 0; i < (int)dir.length(); i++ ) {
386     if ( dir[ i ].isSpace() )
387       return true;
388   }
389   return false;
390 }
391
392 // ================================================================
393 /*!
394  *  makeTitle
395  *  Creates HTML-wrapped title text
396  */
397 // ================================================================
398 static QString makeTitle( const QString& text, const QString& separator = " ", bool fl = true )
399 {
400   QStringList words = QStringList::split( separator, text );
401   if ( fl ) {
402     for ( uint i = 0; i < words.count(); i++ )
403       words[i] = QString( "<font color=red>%1</font>" ).arg( words[i].left(1) ) + words[i].mid(1);
404   }
405   else {
406     if ( words.count() > 0 )
407       words[0] = QString( "<font color=red>%1</font>" ).arg( words[0] );
408     if ( words.count() > 1 )
409       words[words.count()-1] = QString( "<font color=red>%1</font>" ).arg( words[words.count()-1] );
410   }
411   QString res = words.join( separator );
412   if ( !res.isEmpty() )
413     res = QString( "<b>%1</b>" ).arg( res );
414   return res;
415 }
416
417 // ================================================================
418 /*!
419  *  QMyCheckBox class : custom check box
420  *  The only goal is to give access to the protected setState() method
421  */
422 // ================================================================
423 class QMyCheckBox: public QCheckBox
424 {
425 public:
426   QMyCheckBox( const QString& text, QWidget* parent, const char* name = 0 ) : QCheckBox ( text, parent, name ) {}
427   void setState ( ToggleState s ) { QCheckBox::setState( s ); }
428 };
429
430 // ================================================================
431 /*!
432  *  AboutDlg
433  *  "About dialog box.
434  */
435 // ================================================================
436 class AboutDlg: public QDialog
437 {
438 public:
439   AboutDlg( SALOME_InstallWizard* parent ) : QDialog( parent, "About dialog box", true )
440   {
441     // caption
442     setCaption( tr( "About %1" ).arg( parent->getIWName() ) );
443     // palette
444     QPalette pal = palette();
445     QColorGroup cg = pal.active();
446     cg.setColor( QColorGroup::Foreground, Qt::darkBlue );
447     cg.setColor( QColorGroup::Background, Qt::white );
448     pal.setActive( cg ); pal.setInactive( cg ); pal.setDisabled( cg );
449     setPalette( pal );
450     // layout
451     QGridLayout* main = new QGridLayout( this, 1, 1, 11, 6 );
452     // image
453     QLabel* logo = new QLabel( this, "logo" );
454     logo->setFixedSize( 24, 24 );
455     logo->setFrameStyle( QLabel::NoFrame | QLabel::Plain );
456     logo->setPixmap( pixmap( pxAbout ) );
457     logo->setScaledContents( false );
458     logo->setAlignment( QLabel::AlignCenter );
459     // contents
460     QLabel* title = new QLabel( this, "title" );
461     QString tlt = parent->getIWName();
462     title->setText( makeTitle( tlt ) );
463     QLabel* version = new QLabel( this, "version" );
464     version->setText( QString( "<b>Version</b>: %1.%1.%1" )
465                       .arg( __IW_VERSION_MAJOR__ )
466                       .arg( __IW_VERSION_MINOR__ )
467                       .arg( __IW_VERSION_PATCH__ ) );
468     QLabel* copyright = new QLabel( this, "copyright" );
469     copyright->setText( "<b>Copyright</b> &copy; 2002-2012 CEA" );
470     QFont font = title->font();
471     font.setPointSize( (int)( font.pointSize() * 1.8 ) );
472     title->setFont( font );
473     QFrame* line = new QFrame( this, "line" );
474     line->setFrameStyle( QFrame::HLine | QFrame::Sunken );
475     QLabel* url = new QLabel( this, "url" );
476     url->setText( makeTitle( "www.salome-platform.org", ".", false ) );
477     url->setAlignment( AlignRight );
478     font = version->font();
479     font.setPointSize( (int)( font.pointSize() / 1.2 ) );
480     version->setFont( font );
481     copyright->setFont( font );
482     url->setFont( font );
483     // layout
484     main->addWidget( logo, 0, 0 );
485     main->addWidget( title, 0, 1 );
486     main->addWidget( version, 1, 1 );
487     main->addWidget( copyright, 2, 1 );
488     main->addWidget( line, 3, 1 );
489     main->addWidget( url, 4, 1 );
490     // resize
491     QFontMetrics fm( title->font() );
492     int width = (int)( fm.width( tlt ) * 1.5 );
493     title->setMinimumWidth( width );
494   }
495   void mousePressEvent( QMouseEvent* )
496   {
497     accept();
498   }
499 };
500
501 // ================================================================
502 /*!
503  *  SALOME_InstallWizard::SALOME_InstallWizard
504  *  Constructor
505  */
506 // ================================================================
507 SALOME_InstallWizard::SALOME_InstallWizard(const QString& aXmlFileName,
508                                            const QString& aTargetDir,
509                                            const QString& aTmpDir,
510                                            const bool     aForceSrc,
511                                            const bool     aSingleDir)
512      : InstallWizard( qApp->desktop(), "SALOME_InstallWizard", false, 0 ),
513        helpWindow( NULL ),
514        moreMode( false ),
515        previousPage( 0 ),
516        exitConfirmed( false ),
517        hasErrors( false )
518 {
519   myIWName     = tr( "Installation Wizard" );
520   tmpCreated   = QString::null;
521   xmlFileName  = aXmlFileName;
522   myTargetPath = aTargetDir;
523   myTmpPath    = aTmpDir;
524   forceSrc     = aForceSrc;
525   singleDir    = aSingleDir;
526   stateChanged = true;
527
528   QDir rootDir( rootDirPath() );
529   binPath = rootDir.filePath( "Products/BINARIES" );
530   srcPath = rootDir.filePath( "Products/SOURCES" );
531   oneProdDirName = "PRODUCTS";
532   
533   commonPlatform = "Debian 3.1";
534   
535   //
536   // get XML filename and current platform
537   //
538   // ... get current platform
539   curPlatform = currentPlatform().join(" ");
540   //cout << "curOS = " << curPlatform << endl;
541   refPlatform = "";
542   // ... check XML and platform definition
543   getXmlAndPlatform();
544
545   // set application font
546   QFont fnt = font();
547   fnt.setPointSize( 14 );
548   fnt.setBold( true );
549   setTitleFont( fnt );
550
551   // set icon
552   setIcon( pixmap( pxIcon ) );
553   // enable sizegrip
554   setSizeGripEnabled( true );
555
556   // add logo
557   addLogo( pixmap( pxLogo ) );
558
559   // set defaults
560   setVersion( "7.0.0" );
561   setCaption( tr( "SALOME %1" ).arg( myVersion ) );
562   setCopyright( tr( "<h5>Copyright &copy; 2007-2012 CEA/DEN, EDF R&amp;D, OPEN CASCADE<br></h5>"
563                 "<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>" ));
564   setLicense( tr( "<h5>GNU LGPL</h5>" ) );
565
566   ___MESSAGE___( "Configuration file : " << xmlFileName.latin1() );
567   ___MESSAGE___( "Target directory   : " << myTargetPath.latin1() );
568   ___MESSAGE___( "Temporary directory: " << myTmpPath.latin1() );
569
570   //
571   // xml reader
572   //
573   StructureParser* parser = new StructureParser( this );
574   parser->readXmlFile(xmlFileName);
575
576   // create instance of class for starting shell script to get available disk space
577   diskSpaceProc = new QProcess( this, "procDiskSpace" );
578   // create instance of class for starting shell install script
579   shellProcess = new QProcess( this, "shellProcess" );
580   // create instance of class for starting shell script to modify SALOME *.la files
581   modifyLaProc = new QProcess( this, "modifyLaProc" );
582   // create instance of class for starting shell script to check Fortran libraries
583   checkFLibProc = new QProcess( this, "checkFLibProc" );
584
585   // create introduction page
586   setupIntroPage();
587   // create page to select installation type
588   setupTypePage();
589   // create page to select the reference installation platform (if necessary)
590   setupPlatformPage();
591   // create directories page
592   setupDirPage();
593   // create products page
594   setupProductsPage();
595   // create prestart page
596   setupCheckPage();
597   // create progress page
598   setupProgressPage();
599   // create readme page
600   setupReadmePage();
601
602   // common buttons
603   setAboutInfo( backButton(),   tr( "Return to the previous step\nof the installation procedure" ) );
604   setAboutInfo( nextButton(),   tr( "Move to the next step\nof the installation procedure" ) );
605   setAboutInfo( finishButton(), tr( "Finish the installation and quit the program" ) );
606   setAboutInfo( cancelButton(), tr( "Cancel the installation and quit the program" ) );
607   setAboutInfo( helpButton(),   tr( "Show the help information" ) );
608
609   // common signals connections
610   connect( this, SIGNAL( selected( const QString& ) ),
611                                            this, SLOT( pageChanged( const QString& ) ) );
612   connect( this, SIGNAL( helpClicked() ),  this, SLOT( helpClicked() ) );
613   connect( this, SIGNAL( aboutClicked() ), this, SLOT( onAbout() ) );
614
615   // catch signals from launched diskSpaceProc
616   connect( diskSpaceProc, SIGNAL( processExited() ), this, SLOT( updateAvailableSpace() ) );
617   // catch signals from launched shellProcess
618   connect(shellProcess, SIGNAL( readyReadStdout() ), this, SLOT( readFromStdout() ) );
619   connect(shellProcess, SIGNAL( readyReadStderr() ), this, SLOT( readFromStderr() ) );
620   connect(shellProcess, SIGNAL( processExited() ),   this, SLOT( productInstalled() ) );
621   connect(shellProcess, SIGNAL( wroteToStdin() ),    this, SLOT( wroteToStdin() ) );
622   // catch signals from launched modifyLaProc
623   connect(modifyLaProc, SIGNAL( readyReadStdout() ), this, SLOT( readFromStdout() ) );
624   connect(modifyLaProc, SIGNAL( readyReadStderr() ), this, SLOT( readFromStderr() ) );
625   connect(modifyLaProc, SIGNAL( processExited() ), this, SLOT( checkModifyLaResult() ) );
626   // catch signals from launched checkFLibProc
627   connect(checkFLibProc, SIGNAL( processExited() ), this, SLOT( checkFLibResult() ) );
628
629   // create validation thread
630   myThread = new ProcessThread( this );
631
632   // show about button
633   setAboutIcon( pixmap( pxAbout ) );
634   showAboutBtn( true );
635 }
636 // ================================================================
637 /*!
638  *  SALOME_InstallWizard::~SALOME_InstallWizard
639  *  Destructor
640  */
641 // ================================================================
642 SALOME_InstallWizard::~SALOME_InstallWizard()
643 {
644   shellProcess->kill(); // kill it for sure
645   int PID = (int)shellProcess->processIdentifier();
646   if ( PID > 0 ) {
647     Script script;
648     script << "kill -9" << QString::number( PID );
649 #ifdef USE_DEV_NULL
650     script << ">& /dev/null";
651 #endif
652     ___MESSAGE___( "script: " << script.script().latin1() );
653     if ( system( script.script().latin1() ) ) {
654       // error
655     }
656   }
657   delete myThread;
658 }
659 // ================================================================
660 /*!
661  *  SALOME_InstallWizard::getBasePlatform
662  *  Determine the base platform for binaries installation
663  */
664 // ================================================================
665 QString SALOME_InstallWizard::getBasePlatform()
666 {
667   QString aBasePlt = "";
668   if ( platformsMap.find( curPlatform ) != platformsMap.end() )
669     aBasePlt = curPlatform;
670   else
671     aBasePlt = commonPlatform;
672   return aBasePlt;
673 }
674 // ================================================================
675 /*!
676  *  SALOME_InstallWizard::currentPlatform
677  *  Tries to determine the current user's operating system
678  */
679 // ================================================================
680 QStringList SALOME_InstallWizard::currentPlatform()
681 {
682   // file parsing
683   QString platName, platVersion, platArch;
684   QString osFileName = "/etc/issue";
685   if ( QFile::exists( osFileName ) ) {
686     QFile file( osFileName );
687     if ( file.open( IO_ReadOnly ) ) {
688       QTextStream stream( &file );
689       QStringList lines = QStringList::split( "\n", stream.read() );
690       file.close();
691       for ( uint i = 0; i < lines.count(); i++ ) {
692         QString str = lines[i];
693         if ( str.isEmpty() ) continue;
694         // parse line
695         QRegExp regvar = QRegExp( "(.*)\\s+[^\\s]*[R|r]elease[^\\s]*\\s+([\\d.]*)" );
696         int pos = regvar.search( str );
697         if ( pos == -1 ) {
698           regvar = QRegExp( "(.*)\\s+[^\\s]*[L|l][I|i][N|n][U|u][X|x][^\\s]*(.*)\\s+([\\d.]*)\\s+" );
699           pos = regvar.search( str );
700         }
701         if ( pos >= 0 ) {
702           QStringList name;
703           for ( int i = 1; i < regvar.numCaptures(); i++ )
704             name.append( regvar.cap( i ) );
705
706           // retrieve platform name
707           platName = QStringList::split( " ", name.join( " " ) ).join( " " );
708           platName = platName.replace( "Linux", "" ).replace( "linux", "" ).replace( "LINUX", "" ).stripWhiteSpace();
709           platName = platName.replace( "Welcome to", "" ).stripWhiteSpace();
710           platName = QStringList::split( " ", platName ).join( " " );
711           // retrieve platform version number
712           platVersion = regvar.cap( regvar.numCaptures() );
713           // retrieve platform 
714           utsname uname_data;
715           uname( &uname_data );
716           if ( QString( uname_data.machine ) == "x86_64" )
717             platArch = "64bit";
718           break;
719         }
720       }
721     }
722   }
723   QStringList vals;
724   if ( !platName.isEmpty() )    vals.append( platName ); 
725   if ( !platVersion.isEmpty() ) vals.append( platVersion ); 
726   if ( !platArch.isEmpty() )    vals.append( platArch ); 
727   return vals;
728 }
729
730 // ================================================================
731 /*!
732  *  SALOME_InstallWizard::rootDirPath
733  *  Get application root dir
734  */
735 // ================================================================
736 QString SALOME_InstallWizard::rootDirPath()
737 {
738   static QString rootDir;
739   if ( rootDir.isEmpty() ) {
740     QDir appDir( qApp->applicationDirPath() );
741     appDir.cdUp();
742     rootDir = appDir.absPath();
743   }
744   return rootDir;
745 }
746
747 // ================================================================
748 /*!
749  *  SALOME_InstallWizard::getPlatformBinPath
750  *  Get platform binaries path
751  */
752 // ================================================================
753 QString SALOME_InstallWizard::getPlatformBinPath( const QString& plt ) const
754 {
755   return QDir::cleanDirPath( getBinPath() + "/" + QStringList::split( " ", plt ).join( "_" ) );
756 }
757
758 // ================================================================
759 /*!
760  *  SALOME_InstallWizard::getXmlMap
761  *  Creates a map of the supported operating systems and 
762  *  corresponding XML files.
763  */
764 // ================================================================
765 MapXmlFiles SALOME_InstallWizard::getXmlMap( const QString& aXmlFileName )
766 {
767   MapXmlFiles xmlMap;
768   QStringList xmlList;
769   if ( !aXmlFileName.isEmpty() )
770     xmlList.append( QFileInfo( aXmlFileName ).absFilePath() );
771   else {
772     QDir dir( rootDirPath() );
773     QStringList entries = dir.entryList( "*.xml", QDir::Files | QDir::Readable );
774     if ( entries.remove( "config.xml" ) )
775       entries.append( "config.xml" );
776     for ( uint i = 0; i < entries.count(); i++ )
777       xmlList.append( QDir( rootDirPath() ).filePath( entries[i] ) ); 
778   }
779   // XML files parsing
780   QFile file;
781   QDomDocument doc( "xml_doc" );
782   QDomElement docElem;
783   QDomNodeList nodeList;
784   QDomNode node;
785   QDomElement elem;
786   QString platforms = "";
787   QStringList platList;
788   for ( uint i = 0; i < xmlList.count(); i++ ) {
789     file.setName( xmlList[i] );
790     if ( !doc.setContent( &file ) ) {
791       file.close();
792       continue;
793     }
794     file.close();
795     
796     docElem = doc.documentElement();
797     nodeList = docElem.elementsByTagName( "config" );
798     if ( nodeList.count() == 0 )
799       continue;      
800     node = nodeList.item( 0 );
801     if ( node.isElement() ) {
802       elem = node.toElement();
803       if ( elem.attribute( "platforms" ) ) {
804         platforms = elem.attribute( "platforms" ).stripWhiteSpace();
805         QStringList platList = QStringList::split( ",", platforms );
806         for ( uint j = 0; j < platList.count(); j++ ) {
807           QString platform = platList[j].stripWhiteSpace();
808           if ( !platform.isEmpty() && xmlMap.find( platform ) == xmlMap.end() )
809             xmlMap[ platList[j] ] = xmlList[i];
810         }
811       }
812     }
813   }
814   return xmlMap;
815 }
816 // ================================================================
817 /*!
818  *  SALOME_InstallWizard::checkXmlAndPlatform
819  *  Check XML file and current platform definition
820  */
821 // ================================================================
822 void SALOME_InstallWizard::getXmlAndPlatform()
823 {
824   MapXmlFiles xmlMap;
825   if ( xmlFileName.isEmpty() ) {
826     xmlMap = getXmlMap();
827     if ( !curPlatform.isEmpty() ) {
828       // try to get XML file for current platform
829       if ( xmlMap.find( curPlatform ) != xmlMap.end() ) {
830         xmlFileName = xmlMap[ curPlatform ];
831         QFileInfo fibp( getPlatformBinPath( curPlatform ) );
832         if ( !fibp.isDir() ) {
833           warnMsg = tr( "Binaries are absent for current platform" );
834         }
835         platformsMap = xmlMap;
836       }
837       else {
838         platformsMap = xmlMap;
839         warnMsg = tr( "Your Linux platform is not supported by this SALOME package" );
840       }
841     }
842     else {
843       // get all supported platforms
844       platformsMap = xmlMap;
845       warnMsg = tr( "Installation Wizard can't identify target Linux platform" );
846     }
847   }
848   else {
849     xmlMap = getXmlMap( xmlFileName );
850     if ( !curPlatform.isEmpty() ) {
851       // check that the user's XML file supports current platform
852       if ( xmlMap.find( curPlatform ) == xmlMap.end() ) {
853         platformsMap = getXmlMap();
854         MapXmlFiles::Iterator it;
855         for ( it = xmlMap.begin(); it != xmlMap.end(); ++it )
856           platformsMap.insert( it.key(), it.data(), true );
857         warnMsg = tr( "The given configuration file doesn't support your Linux platform" );
858       }
859       else {
860         platformsMap = xmlMap;
861       }
862     }
863     else {
864       // get all supported platforms
865       platformsMap = getXmlMap();
866       MapXmlFiles::Iterator it;
867       for ( it = xmlMap.begin(); it != xmlMap.end(); ++it )
868         platformsMap.insert( it.key(), it.data(), true );
869       warnMsg = tr( "Installation Wizard can't define your Linux platform" );
870     }
871   }
872 }
873 // ================================================================
874 /*!
875  *  SALOME_InstallWizard::eventFilter
876  *  Event filter, spies for Help window closing
877  */
878 // ================================================================
879 bool SALOME_InstallWizard::eventFilter( QObject* object, QEvent* event )
880 {
881   if ( object && object == helpWindow && event->type() == QEvent::Close )
882     helpWindow = NULL;
883   return InstallWizard::eventFilter( object, event );
884 }
885 // ================================================================
886 /*!
887  *  SALOME_InstallWizard::closeEvent
888  *  Close event handler
889  */
890 // ================================================================
891 void SALOME_InstallWizard::closeEvent( QCloseEvent* ce )
892 {
893   if ( WarnDialog::isWarnDlgShown() ) {
894     ce->ignore();
895     return;
896   }
897   if ( !exitConfirmed ) {
898     if ( QMessageBox::information( this,
899                                    tr( "Exit" ),
900                                    tr( "Do you want to quit %1?" ).arg( getIWName() ),
901                                    tr( "&Yes" ),
902                                    tr( "&No" ),
903                                    QString::null,
904                                    0,
905                                    1 ) == 1 ) {
906       ce->ignore();
907     }
908     else {
909       ce->accept();
910       exitConfirmed = true;
911       reject();
912     }
913   }
914 }
915 // ================================================================
916 /*!
917  *  SALOME_InstallWizard::setupIntroPage
918  *  Creates introduction page
919  */
920 // ================================================================
921 void SALOME_InstallWizard::setupIntroPage()
922 {
923   // create page
924   introPage = new QWidget( this, "IntroPage" );
925   QGridLayout* pageLayout = new QGridLayout( introPage );
926   pageLayout->setMargin( 0 ); pageLayout->setSpacing( 6 );
927   // create logo picture
928   logoLab = new QLabel( introPage );
929   logoLab->setPixmap( pixmap( pxBigLogo ) );
930   logoLab->setScaledContents( true );
931   logoLab->setFrameStyle( QLabel::Plain | QLabel::NoFrame );
932   logoLab->setAlignment( AlignCenter );
933   // create version box
934   QVBox* versionBox = new QVBox( introPage ); versionBox->setSpacing( 6 );
935   versionBox->setFrameStyle( QVBox::Panel | QVBox::Sunken );
936   QWidget* stretch1 = new QWidget( versionBox ); versionBox->setStretchFactor( stretch1, 5 );
937   versionLab = new QLabel( QString("%1 %2").arg( tr( "Version" ) ).arg(myVersion), versionBox );
938   versionLab->setAlignment( AlignCenter );
939   copyrightLab = new QLabel( myCopyright, versionBox );
940   copyrightLab->setAlignment( AlignCenter );
941   licenseLab = new QLabel( myLicense, versionBox );
942   licenseLab->setAlignment( AlignCenter );
943   QWidget* stretch2 = new QWidget( versionBox ); versionBox->setStretchFactor( stretch2, 5 );
944   // create info box
945   info = new QLabel( introPage );
946   info->setText( tr( "This program will install <b>%1</b>."
947                      "<br><br>The wizard will also help you to install all products "
948                      "which are necessary for <b>%2</b> and setup "
949                      "your environment.<br><br>Click <code>Cancel</code> button to abort "
950                      "installation and quit. Click <code>Next</code> button to continue with the "
951                      "installation program." ).arg( myCaption ).arg( myCaption ) );
952   info->setFrameStyle( QLabel::WinPanel | QLabel::Sunken );
953   info->setMargin( 6 );
954   info->setAlignment( WordBreak );
955   info->setMinimumWidth( 250 );
956   QPalette pal = info->palette();
957   pal.setColor( QColorGroup::Background, QApplication::palette().active().base() );
958   info->setPalette( pal );
959   info->setLineWidth( 2 );
960   // layouting
961   pageLayout->addWidget( logoLab, 0, 0 );
962   pageLayout->addWidget( versionBox, 1, 0 );
963   pageLayout->addMultiCellWidget( info, 0, 1, 1, 1 );
964   pageLayout->setColStretch( 1, 5 );
965   pageLayout->setRowStretch( 1, 5 );
966   // adding page
967   addPage( introPage, tr( "Introduction" ) );
968 }
969 // ================================================================
970 /*!
971  *  SALOME_InstallWizard::setupTypePage
972  *  Creates installation types page
973  */
974 // ================================================================
975 void SALOME_InstallWizard::setupTypePage()
976 {
977   // create page
978   typePage = new QWidget( this, "TypePage" );
979   QGridLayout* pageLayout = new QGridLayout( typePage );
980   pageLayout->setMargin( 0 ); pageLayout->setSpacing( 6 );
981   // create installation type button group
982   buttonGrp = new QButtonGroup( typePage );
983   buttonGrp->setFrameShape(QButtonGroup::NoFrame);
984   QGridLayout* buttonGrpLayout = new QGridLayout( buttonGrp );
985   buttonGrpLayout->setMargin( 0 ); buttonGrpLayout->setSpacing( 6 );
986   QSpacerItem* spacer1 = new QSpacerItem( 16, 50, QSizePolicy::Minimum, QSizePolicy::Expanding );
987   QSpacerItem* spacer2 = new QSpacerItem( 16, 50, QSizePolicy::Minimum, QSizePolicy::Expanding );
988   QLabel* selectLab = new QLabel( tr( "Select a type of the installation:" ), buttonGrp );
989   QSpacerItem* spacer3 = new QSpacerItem( 20, 20, QSizePolicy::Fixed, QSizePolicy::Minimum );
990   // ... 'install binaries' layout
991   QGridLayout* binLayout = new QGridLayout( 2, 2, 0 );
992   binBtn = new QRadioButton( tr( "Install binaries" ), buttonGrp );
993   QFont rbFont = binBtn->font();
994   rbFont.setBold( true );
995   binBtn->setFont( rbFont );
996   QSpacerItem* spacer4 = new QSpacerItem( 16, 16, QSizePolicy::Fixed, QSizePolicy::Minimum );
997   QLabel* binLab = new QLabel( tr( "- all the binaries and sources of the chosen SALOME modules will be installed.\n"
998                                    "- all the binaries of the chosen prerequisites will be installed." ), 
999                                buttonGrp );
1000   binLayout->addMultiCellWidget( binBtn,  0, 0, 0, 1 );
1001   binLayout->addItem           ( spacer4, 1,    0    );
1002   binLayout->addWidget         ( binLab,  1,    1    );
1003   // ... 'install sources' layout
1004   QGridLayout* srcLayout = new QGridLayout( 2, 2, 0 );
1005   srcBtn = new QRadioButton( tr( "Install sources" ), buttonGrp );
1006   srcBtn->setFont( rbFont );
1007   QSpacerItem* spacer5 = new QSpacerItem( 16, 16, QSizePolicy::Fixed, QSizePolicy::Minimum );
1008   QLabel* srcLab = new QLabel( tr( "- all the sources of the chosen modules and prerequisites will be installed without\ncompilation." ), 
1009                                buttonGrp );
1010   srcLayout->addMultiCellWidget( srcBtn,  0, 0, 0, 1 );
1011   srcLayout->addItem           ( spacer5, 1,    0    );
1012   srcLayout->addWidget         ( srcLab,  1,    1    );
1013   // ... 'install sources and make compilation' layout
1014   QGridLayout* srcCompileLayout = new QGridLayout( 3, 3, 0 );
1015   srcCompileBtn = new QRadioButton( tr( "Install sources and make a compilation" ), buttonGrp );
1016   srcCompileBtn->setFont( rbFont );
1017   QSpacerItem* spacer6 = new QSpacerItem( 16, 16, QSizePolicy::Fixed, QSizePolicy::Minimum );
1018   QLabel* srcCompileLab1 = new QLabel( tr( "- all the sources of the chosen modules and prerequisites will be installed and\ncompiled." ), 
1019                                        buttonGrp );
1020   QLabel* srcCompileLab2 = new QLabel( tr( "Note:" ), 
1021                                        buttonGrp );
1022   QFont noteFont = srcCompileLab2->font();
1023   noteFont.setUnderline( true );
1024   srcCompileLab2->setFont( noteFont );
1025   srcCompileLab2->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Preferred ) );
1026   srcCompileLab2->setAlignment( Qt::AlignHCenter | Qt::AlignTop );
1027   QLabel* srcCompileLab3 = new QLabel( " " + 
1028                                        tr( "it is a long time operation and it can take more than 24 hours depending\n on the computer." ), 
1029                                        buttonGrp );
1030   removeSrcBtn = new QCheckBox( tr( "Remove sources and temporary files after compilation" ), typePage );
1031   setAboutInfo( removeSrcBtn, tr( "Check this option if you want to remove sources of the products\nwith all the temporary files after build finishing" ) );
1032   removeSrcBtn->setChecked( false );
1033   removeSrcBtn->setEnabled( false );
1034   rmSrcPrevState = removeSrcBtn->isChecked();
1035
1036   srcCompileLayout->addMultiCellWidget( srcCompileBtn,  0, 0, 0, 2 );
1037   srcCompileLayout->addMultiCell      ( spacer6,        1, 2, 0, 0 );
1038   srcCompileLayout->addMultiCellWidget( srcCompileLab1, 1, 1, 1, 2 );
1039   srcCompileLayout->addWidget         ( srcCompileLab2, 2,    1    );
1040   srcCompileLayout->addWidget         ( srcCompileLab3, 2,    2    );
1041   srcCompileLayout->addMultiCellWidget( removeSrcBtn,   3, 3, 1, 2 );
1042   // layout widgets in the button group
1043   buttonGrpLayout->addItem           ( spacer1,          0,    1    );
1044   buttonGrpLayout->addMultiCellWidget( selectLab,        1, 1, 0, 1 );
1045   buttonGrpLayout->addMultiCell      ( spacer3,          2, 4, 0, 0 );
1046   buttonGrpLayout->addLayout         ( binLayout,        2,    1    );
1047   buttonGrpLayout->addLayout         ( srcLayout,        3,    1    );
1048   buttonGrpLayout->addLayout         ( srcCompileLayout, 4,    1    );
1049   buttonGrpLayout->addItem           ( spacer2,          5,    1    );
1050   // layout button group at the page
1051   pageLayout->addWidget( buttonGrp, 0, 0 );
1052   // connecting signals
1053   connect( buttonGrp, SIGNAL( clicked(int) ), this, SLOT ( onButtonGroup(int) ) );
1054   // adding page
1055   addPage( typePage, tr( "Installation type" ) );
1056 }
1057 // ================================================================
1058 /*!
1059  *  SALOME_InstallWizard::setupPlatformPage
1060  *  Creates platforms page, if necessary
1061  */
1062 // ================================================================
1063 void SALOME_InstallWizard::setupPlatformPage()
1064 {
1065   // create page
1066   platformsPage = new QWidget( this, "PlatformsPage" );
1067   QGridLayout* pageLayout = new QGridLayout( platformsPage );
1068   pageLayout->setMargin( 0 ); pageLayout->setSpacing( 6 );
1069   // create warning labels
1070   QLabel* warnLab2 = new QLabel( tr( "WARNING!" ), platformsPage );
1071   warnLab2->setAlignment( Qt::AlignHCenter );
1072   QFont fnt = warnLab2->font();
1073   fnt.setBold( true );
1074   warnLab2->setFont( fnt );
1075   warnLab = new QLabel( warnMsg, platformsPage );
1076   warnLab->setAlignment( Qt::AlignHCenter | Qt::WordBreak );
1077   warnLab3 = new QLabel( tr( "If you want to proceed anyway, please select platform from the following list:" ), 
1078                                  platformsPage );
1079   warnLab3->setAlignment( Qt::AlignHCenter | Qt::WordBreak );
1080   // create button group
1081   platBtnGrp = new QButtonGroup( platformsPage );
1082   platBtnGrp->setFrameShape(QButtonGroup::LineEditPanel);
1083   platBtnGrp->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Preferred ) );
1084   QVBoxLayout* platBtnGrpLayout = new QVBoxLayout( platBtnGrp );
1085   platBtnGrpLayout->setMargin( 11 ); platBtnGrpLayout->setSpacing( 6 );
1086   // create platforms radio-buttons
1087   QString plat;
1088   MapXmlFiles::Iterator it;
1089   for ( it = platformsMap.begin(); it != platformsMap.end(); ++it ) {
1090     plat = it.key();
1091     QRadioButton* rb = new QRadioButton( plat, platBtnGrp, plat );
1092     platBtnGrpLayout->addWidget( rb );
1093   }
1094   // create spacers
1095   QSpacerItem* spacer1 = new QSpacerItem( 16, 20, QSizePolicy::Minimum, QSizePolicy::Expanding );
1096   QSpacerItem* spacer2 = new QSpacerItem( 16, 20, QSizePolicy::Minimum, QSizePolicy::Expanding );
1097
1098   // layout widgets on page
1099   pageLayout->addItem           ( spacer1,    0,    0    );
1100   pageLayout->addWidget         ( warnLab2,   1,    0    );
1101   pageLayout->addWidget         ( warnLab,    2,    0    );
1102   pageLayout->addWidget         ( warnLab3,   3,    0    );
1103   pageLayout->addItem           ( spacer2,    4,    0    );
1104   pageLayout->addMultiCellWidget( platBtnGrp, 0, 4, 1, 1 );
1105
1106   // connecting signals
1107   connect( platBtnGrp, SIGNAL( clicked(int) ), this, SLOT ( onButtonGroup(int) ) );
1108
1109   // adding page
1110   addPage( platformsPage, tr( "Installation platform" ) );
1111 }
1112 // ================================================================
1113 /*!
1114  *  SALOME_InstallWizard::setupDirPage
1115  *  Creates directories page
1116  */
1117 // ================================================================
1118 void SALOME_InstallWizard::setupDirPage()
1119 {
1120   // create page
1121   dirPage = new QWidget( this, "DirPage" );
1122   QGridLayout* pageLayout = new QGridLayout( dirPage );
1123   pageLayout->setMargin( 0 ); pageLayout->setSpacing( 6 );
1124   QSpacerItem* spacer1 = new QSpacerItem( 16, 50, QSizePolicy::Minimum, QSizePolicy::Expanding );
1125   QSpacerItem* spacer2 = new QSpacerItem( 16, 50, QSizePolicy::Minimum, QSizePolicy::Expanding );
1126   // target directory
1127   QGridLayout* targetLayout = new QGridLayout( 2, 2, 0 );
1128   QLabel* targetLab = new QLabel( tr( "Set a target directory to install SALOME platform:" ), dirPage );
1129   targetFolder = new QLineEdit( dirPage );
1130   targetBtn = new QPushButton( tr( "Browse..." ), dirPage );
1131   setAboutInfo( targetBtn, tr( "Click this button to browse\nthe installation directory" ) );
1132   targetLayout->addMultiCellWidget( targetLab,    0, 0, 0, 1 );
1133   targetLayout->addWidget         ( targetFolder, 1,    0    );
1134   targetLayout->addWidget         ( targetBtn,    1,    1    );
1135   // temporary directory
1136   QGridLayout* tempLayout = new QGridLayout( 2, 2, 0 );
1137   QLabel* tempLab = new QLabel( tr( "Set a directory that should be used for temporary SALOME files:" ), dirPage );
1138   tempFolder = new QLineEdit( dirPage );
1139   tempBtn = new QPushButton( tr( "Browse..." ), dirPage );
1140   setAboutInfo( tempBtn, tr( "Click this button to browse\nthe temporary directory" ) );
1141   tempLayout->addMultiCellWidget( tempLab,    0, 0, 0, 1 );
1142   tempLayout->addWidget         ( tempFolder, 1,    0    );
1143   tempLayout->addWidget         ( tempBtn,    1,    1    );
1144   // AKL: 13/08/07 - disable temporary directory setting in GUI ==>
1145   tempLab->hide();
1146   tempFolder->hide();
1147   tempBtn->hide();
1148   // AKL: 13/08/07 - disable temporary directory setting in GUI <==
1149   // layout widgets
1150   pageLayout->addItem  ( spacer1,      0, 0 );
1151   pageLayout->addLayout( targetLayout, 1, 0 );
1152   pageLayout->addLayout( tempLayout,   2, 0 );
1153   pageLayout->addItem  ( spacer2,      3, 0 );
1154   // connecting signals
1155   connect( targetFolder,  SIGNAL( textChanged( const QString& ) ),
1156            this,          SLOT( directoryChanged( const QString& ) ) );
1157   connect( targetBtn,     SIGNAL( clicked() ), 
1158            this,          SLOT( browseDirectory() ) );
1159   connect( tempFolder,    SIGNAL( textChanged( const QString& ) ),
1160            this,          SLOT( directoryChanged( const QString& ) ) );
1161   connect( tempBtn,       SIGNAL( clicked() ), this, SLOT( browseDirectory() ) );
1162
1163   // adding page
1164   addPage( dirPage, tr( "Installation directory" ) );
1165 }
1166 // ================================================================
1167 /*!
1168  *  SALOME_InstallWizard::setupProductsPage
1169  *  Creates products page
1170  */
1171 // ================================================================
1172 void SALOME_InstallWizard::setupProductsPage()
1173 {
1174   // create page
1175   productsPage = new QWidget( this, "ProductsPage" );
1176   QGridLayout* pageLayout = new QGridLayout( productsPage );
1177   pageLayout->setMargin( 0 ); pageLayout->setSpacing( 6 );
1178   //
1179   // create left column widgets
1180   //
1181   QVBoxLayout* leftBoxLayout = new QVBoxLayout;
1182   leftBoxLayout->setMargin( 0 ); leftBoxLayout->setSpacing( 6 );
1183   // ... modules list
1184   modulesView = new ProductsView( productsPage, "modulesView" );
1185   setAboutInfo( modulesView, tr( "The modules available for the installation" ) );
1186   modulesView->setColumnAlignment( 1, Qt::AlignRight );
1187   leftBoxLayout->addWidget( modulesView );
1188   // ... 'Installation with GUI' checkbox
1189   installGuiBtn = new QMyCheckBox( tr( "Installation with GUI" ), productsPage );
1190   setAboutInfo( installGuiBtn, tr( "Check this option if you want\nto install SALOME with GUI" ) );
1191   leftBoxLayout->addWidget( installGuiBtn );
1192   // ... prerequisites list
1193   prereqsView = new ProductsView( productsPage, "prereqsView" );
1194   prereqsView->renameColumn( 0, "Prerequisite" );
1195   setAboutInfo( prereqsView, tr( "The prerequisites that can be installed" ) );
1196   prereqsView->setColumnAlignment( 1, Qt::AlignRight );
1197   leftBoxLayout->addWidget( prereqsView );
1198   // ... 'Show/Hide prerequisites' button
1199   moreBtn = new QPushButton( tr( "Show prerequisites..." ), productsPage );
1200   setAboutInfo( moreBtn, tr( "Click to show list of prerequisites" ) );
1201   leftBoxLayout->addWidget( moreBtn );
1202   //
1203   // create right column widgets
1204   //
1205   // ... info box
1206   productInfo = new QTextBrowser( productsPage );
1207   productInfo->setFrameShape( QFrame::LineEditPanel );
1208   productInfo->setPaletteBackgroundColor( productsPage->paletteBackgroundColor() );
1209   setAboutInfo( productInfo, tr( "Short information about the product being selected" ) );
1210   // ... disk space labels
1211   QLabel* reqLab1 = new QLabel( tr( "Disk space required:" ), productsPage );
1212   setAboutInfo( reqLab1, tr( "Total disk space required for the installation\nof the selected products" ) );
1213   requiredSize = new QLabel( productsPage );
1214   setAboutInfo( requiredSize, tr( "Total disk space required for the installation\nof the selected products" ) );
1215   requiredSize->setAlignment( Qt::AlignRight );
1216   QLabel* reqLab2 = new QLabel( tr( "Space for temporary files:" ), productsPage );
1217   setAboutInfo( reqLab2, tr( "Disk space required for the temporary files" ) );
1218   requiredTemp = new QLabel( productsPage );
1219   setAboutInfo( requiredTemp, tr( "Disk space required for the temporary files" ) );
1220   requiredTemp->setAlignment( Qt::AlignRight );
1221   QLabel* reqLab3 = new QLabel( tr( "Available disk space:" ), productsPage );
1222   setAboutInfo( reqLab3, tr( "Disk space available on the selected device" ) );
1223   availableSize = new QLabel( productsPage );
1224   setAboutInfo( availableSize, tr( "Disk space available on the selected device" ) );
1225   availableSize->setAlignment( Qt::AlignRight );
1226   // layout size widgets
1227   QGridLayout* sizeLayout = new QGridLayout; sizeLayout->setMargin( 0 ); sizeLayout->setSpacing( 6 );
1228   sizeLayout->addWidget( reqLab1,       0, 0 );
1229   sizeLayout->addWidget( requiredSize,  0, 1 );
1230   sizeLayout->addWidget( reqLab2,       1, 0 );
1231   sizeLayout->addWidget( requiredTemp,  1, 1 );
1232   sizeLayout->addWidget( reqLab3,       2, 0 );
1233   sizeLayout->addWidget( availableSize, 2, 1 );
1234   // ... 'single installation directory' check-boxes
1235   oneModDirBtn = new QMyCheckBox( tr( "Install modules to a single directory" ), productsPage );
1236   setAboutInfo( oneModDirBtn, tr( "Check this box if you want to install binaries of\nthe selected SALOME modules into a single directory" ) );
1237   oneProdDirBtn = new QMyCheckBox( tr( "Install prerequisites to a single directory" ), productsPage );
1238   setAboutInfo( oneProdDirBtn, tr( "Check this box if you want to install binaries of\nthe selected prerequisites into a single directory" ) );
1239   oneProdDirBtn->hide(); // temporarily! waiting for correct prerequisites availability
1240   QFrame* split_line = new QFrame( productsPage, "split_line" );
1241   split_line->setFrameStyle( QFrame::HLine | QFrame::Sunken );
1242
1243   // layout common widgets
1244   pageLayout->addMultiCellLayout( leftBoxLayout, 0, 4, 0, 0 );
1245   pageLayout->addWidget         ( productInfo,   0,    1    );
1246   pageLayout->addLayout         ( sizeLayout,    1,    1    );
1247   pageLayout->addWidget         ( split_line,    2,    1    );
1248   pageLayout->addWidget         ( oneModDirBtn,  3,    1    );
1249   pageLayout->addWidget         ( oneProdDirBtn, 4,    1    );
1250
1251   // adding page
1252   addPage( productsPage, tr( "Choice of the products to be installed" ) );
1253
1254   // connecting signals
1255   connect( modulesView,   SIGNAL( selectionChanged() ),
1256            this, SLOT( onSelectionChanged() ) );
1257   connect( prereqsView,   SIGNAL( selectionChanged() ),
1258            this, SLOT( onSelectionChanged() ) );
1259   connect( modulesView,   SIGNAL( clicked ( QListViewItem * item ) ),
1260            this, SLOT( onSelectionChanged() ) );
1261   connect( prereqsView,   SIGNAL( clicked ( QListViewItem * item ) ),
1262            this, SLOT( onSelectionChanged() ) );
1263   connect( modulesView,   SIGNAL( itemToggled( QCheckListItem* ) ),
1264            this, SLOT( onItemToggled( QCheckListItem* ) ) );
1265   connect( prereqsView,   SIGNAL( itemToggled( QCheckListItem* ) ),
1266            this, SLOT( onItemToggled( QCheckListItem* ) ) );
1267   connect( installGuiBtn, SIGNAL( toggled( bool ) ), 
1268            this, SLOT( onInstallGuiBtn() ) );
1269   connect( moreBtn, SIGNAL( clicked() ), this, SLOT( onMoreBtn() ) );
1270   // start on default - non-advanced mode
1271   prereqsView->hide();
1272 }
1273 // ================================================================
1274 /*!
1275  *  SALOME_InstallWizard::setupCheckPage
1276  *  Creates prestart page
1277  */
1278 // ================================================================
1279 void SALOME_InstallWizard::setupCheckPage()
1280 {
1281   // create page
1282   prestartPage = new QWidget( this, "PrestartPage" );
1283   QVBoxLayout* pageLayout = new QVBoxLayout( prestartPage );
1284   pageLayout->setMargin( 0 ); pageLayout->setSpacing( 6 );
1285   // choice text view
1286   choices = new QTextEdit( prestartPage );
1287   choices->setReadOnly( true );
1288   choices->setTextFormat( RichText );
1289   choices->setUndoRedoEnabled ( false );
1290   setAboutInfo( choices, tr( "Information about the installation choice you have made" ) );
1291   choices->setPaletteBackgroundColor( prestartPage->paletteBackgroundColor() );
1292   choices->setMinimumHeight( 10 );
1293   // layouting
1294   pageLayout->addWidget( choices );
1295   pageLayout->setStretchFactor( choices, 5 );
1296   // adding page
1297   addPage( prestartPage, tr( "Check your choice" ) );
1298 }
1299 // ================================================================
1300 /*!
1301  *  SALOME_InstallWizard::setupProgressPage
1302  *  Creates progress page
1303  */
1304 // ================================================================
1305 void SALOME_InstallWizard::setupProgressPage()
1306 {
1307   // create page
1308   progressPage = new QWidget( this, "progressPage" );
1309   QGridLayout* pageLayout = new QGridLayout( progressPage );
1310   pageLayout->setMargin( 0 ); pageLayout->setSpacing( 6 );
1311   // top splitter
1312   splitter = new QSplitter( Vertical, progressPage );
1313   splitter->setOpaqueResize( true );
1314   // the parent for the widgets
1315   QWidget* widget = new QWidget( splitter );
1316   QGridLayout* layout = new QGridLayout( widget );
1317   layout->setMargin( 0 ); layout->setSpacing( 6 );
1318   // installation progress view box
1319   installInfo = new InstallInfo( widget );
1320   installInfo->setReadOnly( true );
1321   installInfo->setTextFormat( RichText );
1322   installInfo->setUndoRedoEnabled ( false );
1323   installInfo->setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Expanding ) );
1324   installInfo->setMinimumSize( 100, 10 );
1325   setAboutInfo( installInfo, tr( "Installation process output" ) );
1326   // parameters for the script
1327   parametersLab = new QLabel( tr( "Enter your answer here:" ), widget );
1328   passedParams = new QLineEdit ( widget );
1329   setAboutInfo( passedParams, tr( "Use this field to enter the answer\nfor the running script when it is necessary") );
1330   // VSR: 10/11/05 - disable answer mode ==>
1331   parametersLab->hide();
1332   passedParams->hide();
1333   // VSR: 10/11/05 - disable answer mode <==
1334   // layouting
1335   layout->addWidget( installInfo,   0, 0 );
1336   layout->addWidget( parametersLab, 1, 0 );
1337   layout->addWidget( passedParams,  2, 0 );
1338   layout->addRowSpacing( 3, 6 );
1339   // the parent for the widgets
1340   widget = new QWidget( splitter );
1341   layout = new QGridLayout( widget );
1342   layout->setMargin( 0 ); layout->setSpacing( 6 );
1343   // installation results view box
1344   QLabel* resultLab = new QLabel( tr( "Installation Status:" ), widget );
1345   progressView = new ProgressView( widget );
1346   progressView->setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Expanding ) );
1347   progressView->setMinimumSize( 100, 10 );
1348   // possibility to ignore all errors
1349   ignoreErrCBox = new QCheckBox( tr( "Ignore errors" ), widget );
1350   setAboutInfo( ignoreErrCBox, tr( "Check this option if you want to proceed installation \nprocess even there will be some errors" ) );
1351   ignoreErrCBox->setChecked( false );
1352   // product installation status bar
1353   statusLab = new QLabel( widget );
1354   statusLab->setFrameShape( QButtonGroup::LineEditPanel );
1355   setAboutInfo( progressView, tr( "Installation status on the selected products" ) );
1356   // layouting
1357   layout->addRowSpacing( 0, 6 );
1358   layout->addWidget( resultLab,     1, 0 );
1359   layout->addWidget( progressView,  2, 0 );
1360   layout->addWidget( ignoreErrCBox, 3, 0 );
1361   layout->addWidget( statusLab,     4, 0 );
1362   // layouting
1363   pageLayout->addWidget( splitter,  0, 0 );
1364   // adding page
1365   addPage( progressPage, tr( "Installation progress" ) );
1366   // connect signals
1367   connect( passedParams, SIGNAL( returnPressed() ), this, SLOT( onReturnPressed() ) ) ;
1368 }
1369 // ================================================================
1370 /*!
1371  *  SALOME_InstallWizard::setupReadmePage
1372  *  Creates readme page
1373  */
1374 // ================================================================
1375 void SALOME_InstallWizard::setupReadmePage()
1376 {
1377   // create page
1378   readmePage = new QWidget( this, "readmePage" );
1379   QVBoxLayout* pageLayout = new QVBoxLayout( readmePage );
1380   pageLayout->setMargin( 0 ); pageLayout->setSpacing( 6 );
1381   // README info text box
1382   readme = new QTextEdit( readmePage );
1383   readme->setReadOnly( true );
1384   readme->setTextFormat( PlainText );
1385   readme->setFont( QFont( "Fixed", 12 ) );
1386   readme->setUndoRedoEnabled ( false );
1387   setAboutInfo( readme, tr( "README information" ) );
1388   readme->setPaletteBackgroundColor( readmePage->paletteBackgroundColor() );
1389   readme->setMinimumHeight( 10 );
1390
1391   pageLayout->addWidget( readme );
1392   pageLayout->setStretchFactor( readme, 5 );
1393
1394   // Operation buttons
1395   QHBoxLayout* hLayout = new QHBoxLayout( -1, "finishButtons" );
1396   hLayout->setMargin( 0 ); hLayout->setSpacing( 6 );
1397   hLayout->addStretch();
1398   pageLayout->addLayout( hLayout );
1399
1400   // loading README file
1401   QString readmeFile = QDir( rootDirPath() ).filePath( "README" );
1402   QString text;
1403   if ( readFile( readmeFile, text ) )
1404     readme->setText( text );
1405   else
1406     readme->setText( tr( "README file has not been found" ) );
1407
1408   // adding page
1409   addPage( readmePage, tr( "Finish installation" ) );
1410 }
1411 // ================================================================
1412 /*!
1413  *  SALOME_InstallWizard::showChoiceInfo
1414  *  Displays choice info
1415  */
1416 // ================================================================
1417 void SALOME_InstallWizard::showChoiceInfo()
1418 {
1419   choices->clear();
1420
1421   long totSize, tempSize;
1422   checkSize( &totSize, &tempSize );
1423   int nbProd = 0;
1424   QString text;
1425
1426   text += tr( "Current Linux platform" )+ ": <b>" + (!curPlatform.isEmpty() ? curPlatform : QString( "Unknown" )) + "</b><br>";
1427   if ( !refPlatform.isEmpty() )
1428     text += tr( "Reference Linux platform" ) + ": <b>" + refPlatform + "</b><br>";
1429   text += "<br>";
1430
1431   text += tr( "Target directory:" ) + " <b>" + QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() ) + "</b><br>";
1432   text += tr( "Temporary directory:" ) + " <b>" + QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + "</b><br>";
1433   text += "<br>";
1434
1435   text += tr( "SALOME modules to be installed" ) + ":<ul>";
1436   QCheckListItem* item = (QCheckListItem*)( modulesView->firstChild() );
1437   while( item ) {
1438     if ( productsMap.contains( item ) ) {
1439       if ( item->isOn() ) {
1440         text += "<li><b>" + item->text() + "</b><br>";
1441         nbProd++;
1442       }
1443     }
1444     item = (QCheckListItem*)( item->nextSibling() );
1445   }
1446   if ( nbProd == 0 ) {
1447     text += "<li><b>" + tr( "none" ) + "</b><br>";
1448   }
1449   text += "</ul>";
1450   nbProd = 0;
1451   text += tr( "Prerequisites to be installed" ) + ":<ul>";
1452   item = (QCheckListItem*)( prereqsView->firstChild() );
1453   while( item ) {
1454     if ( productsMap.contains( item ) ) {
1455       if ( item->isOn() ) {
1456         text += "<li><b>" + item->text() + " " + productsMap[ item ].getVersion() + "</b><br>";
1457         nbProd++;
1458       }
1459     }
1460     item = (QCheckListItem*)( item->nextSibling() );
1461   }
1462   if ( nbProd == 0 ) {
1463     text += "<li><b>" + tr( "none" ) + "</b><br>";
1464   }
1465   text += "</ul>";
1466   text += tr( "Total disk space required:" ) + " <b>" + QString::number( totSize ) + " KB</b><br>" ;
1467   text += tr( "Space for temporary files required:" ) + " <b>" + QString::number( tempSize ) + " KB</b><br>" ;
1468   choices->setText( text );
1469 }
1470 // ================================================================
1471 /*!
1472  *  SALOME_InstallWizard::acceptData
1473  *  Validates page when <Next> button is clicked
1474  */
1475 // ================================================================
1476 bool SALOME_InstallWizard::acceptData( const QString& pageTitle )
1477 {
1478   QString tmpstr;
1479   QWidget* aPage = InstallWizard::page( pageTitle );
1480   if ( aPage == typePage ) {
1481     // installation type page
1482     warnLab3->show();
1483     this->setAppropriate( platformsPage, false );
1484     if ( installType == Binaries ) { // 'Binary' installation type
1485       // check binaries directory
1486       QFileInfo fib( QDir::cleanDirPath( getBinPath() ) );
1487       if ( !fib.isDir() ) {
1488         QMessageBox::warning( this,
1489                               tr( "Warning" ),
1490                               tr( "The directory %1 doesn't exist.\n"
1491                                   "This directory must contains another one directory with binary archives for current platform.").arg( fib.absFilePath() ),
1492                               QMessageBox::Ok,
1493                               QMessageBox::NoButton, 
1494                               QMessageBox::NoButton );
1495         return false;
1496       }
1497       if ( platformsMap.find( curPlatform ) == platformsMap.end() ) {
1498         // Unknown platform case
1499         QString aMsg = warnMsg + tr( ".\nBy default the universal binary package will be installed." );
1500         aMsg += tr( "\nIf you want to select another one, please use the following list:" );
1501         warnLab->setText( aMsg );
1502         warnLab3->hide();
1503         this->setAppropriate( platformsPage, true );
1504       }
1505       else {
1506         // Supported platform case
1507         QFileInfo fibp( getPlatformBinPath( curPlatform ) );
1508         if ( !fibp.isDir() ) {
1509           warnLab->setText( tr( "Binaries are absent for current platform." ) );
1510           this->setAppropriate( platformsPage, true );
1511         }
1512       }
1513
1514       // check sources directory
1515       QFileInfo fis( QDir::cleanDirPath( getSrcPath() ) );
1516       if ( !fis.isDir() )
1517         if ( QMessageBox::warning( this,
1518                                    tr( "Warning" ),
1519                                    tr( "The directory %1 doesn't exist.\n"
1520                                        "This directory must contains sources archives.\n"
1521                                        "Continue?" ).arg( fis.absFilePath() ),
1522                                    tr( "&Yes" ),
1523                                    tr( "&No" ), 
1524                                    QString::null, 1, 1 ) == 1 )
1525           return false;
1526     }
1527     else { // 'Source' or 'Compile' installation type
1528       // check sources directory
1529       QFileInfo fis( QDir::cleanDirPath( getSrcPath() ) );
1530       if ( !fis.isDir() ) {
1531         QMessageBox::warning( this,
1532                               tr( "Warning" ),
1533                               tr( "The directory %1 doesn't exist.\n"
1534                                   "This directory must contains sources archives.\n" ).arg( fis.absFilePath() ),
1535                               QMessageBox::Ok,
1536                               QMessageBox::NoButton, 
1537                               QMessageBox::NoButton );
1538         return false;
1539       }
1540       else if ( !QDir( fis.filePath(), "*.tar.gz" ).count() ) {
1541         QMessageBox::warning( this,
1542                               tr( "Warning" ),
1543                               tr( "The directory %1 doesn't contain source archives.\n" ).arg( fis.absFilePath() ),
1544                               QMessageBox::Ok,
1545                               QMessageBox::NoButton, 
1546                               QMessageBox::NoButton );
1547         return false;
1548       }
1549       if ( platformsMap.find( curPlatform ) == platformsMap.end() ) {
1550         QString aMsg = warnMsg + ".";
1551         if ( installType == Compile )
1552           aMsg = warnMsg + tr( " and compilation is not tested on this one." );
1553         warnLab->setText( aMsg );
1554         this->setAppropriate( platformsPage, true );
1555       }
1556     }
1557   }
1558
1559   else if ( aPage == platformsPage ) {
1560     // installation platform page
1561     if ( platBtnGrp->id( platBtnGrp->selected() ) == -1 ) {
1562       QMessageBox::warning( this,
1563                             tr( "Warning" ),
1564                             tr( "Select installation platform before" ),
1565                             QMessageBox::Ok,
1566                             QMessageBox::NoButton,
1567                             QMessageBox::NoButton );
1568       return false;
1569     }
1570     else if ( installType == Binaries ) {
1571       QString aPlatform = platBtnGrp->selected()->name();
1572       QFileInfo fib( getPlatformBinPath( aPlatform ) );
1573       if ( !fib.isDir() ) {
1574         QMessageBox::warning( this,
1575                               tr( "Warning" ),
1576                               tr( "The directory %1 doesn't exist.\n"
1577                                   "This directory must contains binary archives.\n" ).arg( fib.absFilePath() ),
1578                               QMessageBox::Ok,
1579                               QMessageBox::NoButton, 
1580                               QMessageBox::NoButton );
1581         return false;
1582       }
1583       else if ( QDir( fib.filePath(), "*.tar.gz" ).count() == 0 ) {
1584         QMessageBox::warning( this,
1585                               tr( "Warning" ),
1586                               tr( "The directory %1 doesn't contain binary archives.\n" ).arg( fib.absFilePath() ),
1587                               QMessageBox::Ok,
1588                               QMessageBox::NoButton, 
1589                               QMessageBox::NoButton );
1590         return false;
1591       }
1592     }
1593   }
1594
1595   else if ( aPage == dirPage ) {
1596     // installation directory page
1597     // ########## check target and temp directories (existence and available disk space)
1598     // get dirs
1599     QString targetDir = QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() );
1600     QString tempDir   = QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() );
1601     // check target directory
1602     if ( targetDir.isEmpty() ) {
1603       QMessageBox::warning( this,
1604                             tr( "Warning" ),
1605                             tr( "Please, enter valid target directory path" ),
1606                             QMessageBox::Ok,
1607                             QMessageBox::NoButton,
1608                             QMessageBox::NoButton );
1609       return false;
1610     }
1611     QFileInfo fi( QDir::cleanDirPath( targetDir ) );
1612     if ( !fi.isDir() ) {
1613       bool toCreate =
1614         QMessageBox::warning( this,
1615                               tr( "Warning" ),
1616                               tr( "The directory %1 doesn't exist.\n"
1617                                   "Create directory?" ).arg( fi.absFilePath() ),
1618                               QMessageBox::Yes,
1619                               QMessageBox::No,
1620                               QMessageBox::NoButton ) == QMessageBox::Yes;
1621       if ( !toCreate)
1622         return false;
1623       if ( !makeDir( fi.absFilePath(), tmpstr ) ) {
1624         QMessageBox::critical( this,
1625                                tr( "Error" ),
1626                                tr( "Can't create the directory\n%1").arg( fi.absFilePath() ),
1627                                QMessageBox::Ok,
1628                                QMessageBox::NoButton,
1629                                QMessageBox::NoButton );
1630         return false;
1631       }
1632     }
1633     if ( !fi.isDir() ) {
1634       QMessageBox::warning( this,
1635                             tr( "Warning" ),
1636                             tr( "%1 is not a directory.\n"
1637                                 "Please, enter valid target directory path" ).arg( fi.absFilePath() ),
1638                             QMessageBox::Ok,
1639                             QMessageBox::NoButton,
1640                             QMessageBox::NoButton );
1641       return false;
1642     }
1643     if ( !fi.isWritable() ) {
1644       QMessageBox::warning( this,
1645                             tr( "Warning" ),
1646                             tr( "The directory %1 is not writable.\n"
1647                                 "Please, enter valid target directory path or change permissions" ).arg( fi.absFilePath() ),
1648                             QMessageBox::Ok,
1649                             QMessageBox::NoButton,
1650                             QMessageBox::NoButton );
1651       return false;
1652     }
1653     if ( hasSpace( fi.absFilePath() ) &&
1654          QMessageBox::warning( this,
1655                                tr( "Warning" ),
1656                                tr( "The target directory contains space symbols.\n"
1657                                    "This may cause problems with compiling or installing of products.\n\n"
1658                                    "Do you want to continue?"),
1659                                QMessageBox::Yes,
1660                                QMessageBox::No,
1661                                QMessageBox::NoButton ) == QMessageBox::No ) {
1662       return false;
1663     }
1664     // check temp directory
1665     if ( tempDir.isEmpty() ) {
1666       QMessageBox::warning( this,
1667                             tr( "Warning" ),
1668                             tr( "Please, enter valid temporary directory path" ),
1669                             QMessageBox::Ok,
1670                             QMessageBox::NoButton,
1671                             QMessageBox::NoButton );
1672       return false;
1673     }
1674     QFileInfo fit( QDir::cleanDirPath( tempDir ) );
1675     if ( !makeDir( fit.absFilePath() + TEMPDIRNAME, tmpCreated ) ) {
1676       QMessageBox::critical( this,
1677                              tr( "Error" ),
1678                              tr( "Can't use temporary directory.\nCheck permissions for the %1 directory.").arg( fit.absFilePath() ),
1679                              QMessageBox::Ok,
1680                              QMessageBox::NoButton,
1681                              QMessageBox::NoButton );
1682       return false;
1683     }
1684   }
1685
1686   else if ( aPage == productsPage ) {
1687     // products page
1688     // ########## check if any products are selected to be installed
1689     long totSize, tempSize;
1690     bool anySelected = checkSize( &totSize, &tempSize );
1691     if ( installType == Compile && removeSrcBtn->isOn() ) {
1692       totSize += tempSize;
1693     }
1694     if ( !anySelected ) {
1695       QMessageBox::warning( this,
1696                             tr( "Warning" ),
1697                             tr( "Select one or more products to install" ),
1698                             QMessageBox::Ok,
1699                             QMessageBox::NoButton,
1700                             QMessageBox::NoButton );
1701       return false;
1702     }
1703     // run script that checks available disk space for installing of products    // returns 1 in case of error
1704     QDir rd( rootDirPath() );
1705     QFileInfo fi( QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() ) );
1706     Script script;
1707     script << QUOTE( rd.filePath( "config_files/checkSize.sh" ) );
1708     script << QUOTE( fi.absFilePath() ) << QString::number( totSize );
1709     ___MESSAGE___( "script = " << script.script().latin1() );
1710     if ( system( script.script().latin1() ) ) {
1711       QMessageBox::critical( this,
1712                              tr( "Out of space" ),
1713                              tr( "There is no available disk space for installing of selected products" ),
1714                              QMessageBox::Ok,
1715                              QMessageBox::NoButton,
1716                              QMessageBox::NoButton );
1717       return false;
1718     }
1719     // AKL: 13/08/07 - skip tmp disk space checking (all files are unpacked into installation directory) ==>
1720     /*
1721     // run script that check available disk space for temporary files
1722     // returns 1 in case of error
1723     QFileInfo fit( QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) );
1724     Script tscript;
1725     tscript << QUOTE( rd.filePath( "config_files/checkSize.sh" ) );
1726     tscript << QUOTE( fit.absFilePath() ) << QString::number( tempSize );
1727     ___MESSAGE___( "script = " << tscript.script().latin1() );
1728     if ( system( tscript.script().latin1() ) ) {
1729       QMessageBox::critical( this,
1730                              tr( "Out of space" ),
1731                              tr( "There is no available disk space for the temporary files" ),
1732                              QMessageBox::Ok,
1733                              QMessageBox::NoButton,
1734                              QMessageBox::NoButton );
1735       return false;
1736       }
1737     */
1738     // AKL: 13/08/07 - skip tmp disk space checking (all files are unpacked into installation directory) <==
1739
1740     // ########## check installation scripts
1741     QCheckListItem* item;
1742     ProductsView* prodsView = modulesView;
1743     for ( int i = 0; i < 2; i++ ) {
1744       item = (QCheckListItem*)( prodsView->firstChild() );
1745       while( item ) {
1746         if ( productsMap.contains( item ) && item->isOn() ) {
1747           // check installation script definition
1748           if ( item->text(2).isEmpty() || item->text(2).isNull() ) {
1749             QMessageBox::warning( this,
1750                                   tr( "Error" ),
1751                                   tr( "The installation script for %1 is not defined.").arg(item->text(0)),
1752                                   QMessageBox::Ok,
1753                                   QMessageBox::NoButton,
1754                                   QMessageBox::NoButton );
1755             if ( !moreMode ) onMoreBtn();
1756             QListView* listView = item->listView();
1757             listView->setCurrentItem( item );
1758             listView->setSelected( item, true );
1759             listView->ensureItemVisible( item );
1760             return false;
1761           }
1762           // check installation script existence
1763           else {
1764             QDir rd( rootDirPath() );
1765             QFileInfo fi( rd.filePath( QString( "config_files/%1" ).arg( item->text(2) ) ) );
1766             if ( !fi.exists() || !fi.isExecutable() ) {
1767               QMessageBox::warning( this,
1768                                     tr( "Error" ),
1769                                     tr( "The script %1 required for %2 doesn't exist or doesn't have execute permissions.").arg(fi.filePath()).arg(item->text(0)),
1770                                     QMessageBox::Ok,
1771                                     QMessageBox::NoButton,
1772                                     QMessageBox::NoButton );
1773               if ( !moreMode ) onMoreBtn();
1774               QListView* listView = item->listView();
1775               listView->setCurrentItem( item );
1776               listView->setSelected( item, true );
1777               listView->ensureItemVisible( item );
1778               return false;
1779             }
1780           }
1781           // check installation scripts dependencies
1782           QStringList dependOn = productsMap[ item ].getDependancies();
1783           QString version = productsMap[ item ].getVersion();
1784           for ( int i = 0; i < (int)dependOn.count(); i++ ) {
1785             QCheckListItem* depitem = findItem( dependOn[ i ] );
1786             if ( !depitem ) {
1787               QMessageBox::warning( this,
1788                                     tr( "Error" ),
1789                                     tr( "%1 is required for %2 %3 installation.\n"
1790                                         "This product is missing in the configuration file %4.").arg(dependOn[ i ]).arg(item->text(0)).arg(version).arg(xmlFileName),
1791                                     QMessageBox::Ok,
1792                                     QMessageBox::NoButton,
1793                                     QMessageBox::NoButton );
1794               return false;
1795             }
1796           }
1797         }
1798         item = (QCheckListItem*)( item->nextSibling() );
1799       }
1800       prodsView = prereqsView;
1801     }
1802 //     return true; // return in order to avoid default postValidateEvent() action
1803   }
1804   return InstallWizard::acceptData( pageTitle );
1805 }
1806 // ================================================================
1807 /*!
1808  *  SALOME_InstallWizard::checkSize
1809  *  Calculates disk space required for the installation
1810  */
1811 // ================================================================
1812 bool SALOME_InstallWizard::checkSize( long* totSize, long* tempSize )
1813 {
1814   long tots = 0, temps = 0;
1815   long maxSrcTmp = 0;
1816   int nbSelected = 0;
1817
1818   MapProducts::Iterator mapIter;
1819   for ( mapIter = productsMap.begin(); mapIter != productsMap.end(); ++mapIter ) {
1820     QCheckListItem* item = mapIter.key();
1821     Dependancies dep = mapIter.data();
1822     if ( !item->isOn() )
1823       continue;
1824     tots += ( QStringList::split( " ", item->text(1) )[0] ).toLong();
1825     maxSrcTmp = max( maxSrcTmp, dep.getSize( Compile ) - dep.getSize( Binaries ) );
1826     temps += dep.getTempSize( installType );
1827     nbSelected++;
1828   }
1829
1830   if ( totSize )
1831     if ( installType == Compile && removeSrcBtn->isOn() )
1832       temps += maxSrcTmp;
1833     *totSize = tots;
1834   if ( tempSize )
1835     *tempSize = temps;
1836   return ( nbSelected > 0 );
1837 }
1838 // ================================================================
1839 /*!
1840  *  SALOME_InstallWizard::updateAvailableSpace
1841  *  Slot to update 'Available disk space' field
1842  */
1843 // ================================================================
1844 void SALOME_InstallWizard::updateAvailableSpace()
1845 {
1846   if ( diskSpaceProc->normalExit() )
1847     availableSize->setText( diskSpaceProc->readLineStdout() + " KB");
1848 }
1849 // ================================================================
1850 /*!
1851  *  SALOME_InstallWizard::runModifyLaFiles
1852  *  Run the modification of SALOME *.la files
1853  */
1854 // ================================================================
1855 void SALOME_InstallWizard::runModifyLaFiles()
1856 {
1857   modifyLaProc->clearArguments();
1858   // ... update status label
1859   statusLab->setText( tr( "Modification of *.la files of SALOME modules..." ) );
1860   // set process arguments
1861   modifyLaProc->setWorkingDirectory( QDir( rootDirPath() ).filePath( "config_files" ) );
1862   modifyLaProc->addArgument( "modifyLaFiles.sh" );
1863   modifyLaProc->addArgument( "modify_la_files" );
1864   modifyLaProc->addArgument( QDir::cleanDirPath( QFileInfo( targetFolder->text().stripWhiteSpace() ).absFilePath() ) );
1865   // ... run script
1866   if ( !modifyLaProc->start() )
1867     ___MESSAGE___( "Error: process could not start!" );
1868 }
1869 // ================================================================
1870 /*!
1871  *  SALOME_InstallWizard::checkModifyLaResult
1872  *  Slot to take result of modification SALOME *.la files
1873  */
1874 // ================================================================
1875 void SALOME_InstallWizard::checkModifyLaResult()
1876 {
1877   if ( modifyLaProc->normalExit() && modifyLaProc->exitStatus() == 1 )
1878     runCheckFLib();
1879   else {
1880     // abort of the current installation
1881     abort();
1882     statusLab->setText( tr( "Installation has been aborted" ) );
1883     QMessageBox::critical( this,
1884                            tr( "Error" ),
1885                            tr( "Modification of *.la SALOME files has not been completed."),
1886                            QMessageBox::Ok,
1887                            QMessageBox::NoButton,
1888                            QMessageBox::NoButton );
1889     // enable <Next> button
1890     setNextEnabled( true );
1891     doPostActions( tr( "&Start" ), tr( "Start installation process" ) );
1892     connect(    this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
1893     // enable <Back> button
1894     setBackEnabled( true );
1895   }
1896 }
1897 // ================================================================
1898 /*!
1899  *  SALOME_InstallWizard::runCheckFLib
1900  *  Run the Fortran and other required libraries checking
1901  */
1902 // ================================================================
1903 void SALOME_InstallWizard::runCheckFLib()
1904 {
1905   // Check Fortran libraries
1906   checkFLibProc->clearArguments();
1907   // ... update status label
1908   statusLab->setText( tr( "Check Fortran and other required libraries..." ) );
1909   // ... search "not found" libraries
1910   checkFLibProc->setWorkingDirectory( QDir( rootDirPath() ).filePath( "config_files" ) );
1911   checkFLibProc->addArgument( "checkFortran.sh" );
1912   checkFLibProc->addArgument( "find_libraries" );
1913   checkFLibProc->addArgument( QDir::cleanDirPath( QFileInfo( targetFolder->text().stripWhiteSpace() ).absFilePath() ) );
1914   // ... run script
1915   if ( !checkFLibProc->start() )
1916     ___MESSAGE___( "Error: process could not start!" );
1917 }
1918 // ================================================================
1919 /*!
1920  *  SALOME_InstallWizard::checkFLibResult
1921  *  Slot to take result of Fortran and other required libraries checking
1922  */
1923 // ================================================================
1924 void SALOME_InstallWizard::checkFLibResult()
1925 {
1926   if ( checkFLibProc->normalExit() && checkFLibProc->exitStatus() == 1 ) {
1927     QStringList notFoundLibsList, notFoundOptLibsList;
1928     QString record = "";
1929     QStringList prefOptLibs = getOptionalLibs();
1930     // create list of strings with all 'not found' libraries
1931     while ( checkFLibProc->canReadLineStdout() ) {
1932       record = checkFLibProc->readLineStdout().stripWhiteSpace();
1933       if ( !record.isEmpty() ) {
1934         record = QStringList::split( " ", record )[0];
1935         if ( !notFoundLibsList.contains( record ) && 
1936              !notFoundOptLibsList.contains( record ) ) {
1937           bool isOptional = false;
1938           QStringList::Iterator it_opt;
1939           for ( it_opt = prefOptLibs.begin(); it_opt != prefOptLibs.end(); ++it_opt )
1940             if ( record.startsWith( (*it_opt).stripWhiteSpace(), false ) ) {
1941               isOptional = true;
1942               break;
1943             }
1944           isOptional ? notFoundOptLibsList.append( record )             \
1945             : notFoundLibsList.append( record );
1946         }
1947       }
1948     }
1949     QString msg = tr( "Some libraries are absent!<br><br>" );
1950     if ( !notFoundLibsList.isEmpty() ) {
1951       msg += tr( "One or several <b>mandatory</b> libraries listed below are not found. SALOME <u>may not work</u> properly.<br>" );
1952       msg += notFoundLibsList.join( "<br>" );
1953       msg += "<br><br>";
1954     }
1955     if ( !notFoundOptLibsList.isEmpty() ) {
1956       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>" );
1957       msg += notFoundOptLibsList.join( "<br>" );
1958     }
1959     if ( !notFoundLibsList.isEmpty() )
1960       QMessageBox::warning( this,
1961                             tr( "Warning" ),
1962                             msg,
1963                             QMessageBox::Ok,
1964                             QMessageBox::NoButton,
1965                             QMessageBox::NoButton );
1966     else if ( !notFoundOptLibsList.isEmpty() )
1967       QMessageBox::information( this,
1968                                 tr( "Information" ),
1969                                 msg,
1970                                 QMessageBox::Ok,
1971                                 QMessageBox::NoButton,
1972                                 QMessageBox::NoButton );
1973   }
1974   // Update GUI and check installation errors
1975   completeInstallation();
1976 }
1977 // ================================================================
1978 /*!
1979  *  SALOME_InstallWizard::updateSizeColumn
1980  *  Sets required size for each product according to 
1981  *  installation type and 'Remove SRC & TMP' checkbox state
1982  */
1983 // ================================================================
1984 void SALOME_InstallWizard::updateSizeColumn()
1985 {
1986   long prodSize = 0;
1987   bool removeSrc = removeSrcBtn->isChecked();
1988   MapProducts::Iterator mapIter;
1989   for ( mapIter = productsMap.begin(); mapIter != productsMap.end(); ++mapIter ) {
1990     QCheckListItem* item = mapIter.key();
1991     Dependancies dep = mapIter.data();
1992     // get required size for current product
1993     long binSize = dep.getSize( Binaries );
1994     long srcSize = dep.getSize( Sources );
1995     long bldSize = dep.getSize( Compile );
1996     InstallationType instType = getInstType();
1997     if ( instType == Binaries ) {
1998       if ( dep.getType() == "component" )
1999         prodSize = binSize + srcSize;
2000       else
2001         prodSize = ( binSize != 0 ? binSize : srcSize );
2002     }
2003     else if ( instType == Sources )
2004       prodSize = srcSize;
2005     else
2006       if ( removeSrc )
2007         prodSize = ( binSize != 0 ? binSize : srcSize );
2008       else {
2009         prodSize = ( bldSize != 0 ? bldSize : srcSize );
2010       }
2011     // fill in 'Size' field
2012     item->setText( 1, QString::number( prodSize )+" KB" );
2013   }
2014 }
2015 // ================================================================
2016 /*!
2017  *  SALOME_InstallWizard::checkProductPage
2018  *  Checks products page validity (directories and products selection) and
2019  *  enabled/disables "Next" button for the Products page
2020  */
2021 // ================================================================
2022 void SALOME_InstallWizard::checkProductPage()
2023 {
2024   if ( this->currentPage() != productsPage )
2025     return;
2026   long tots = 0, temps = 0;
2027   // check if any product is selected;
2028   bool isAnyProductSelected = checkSize( &tots, &temps );
2029
2030   // update required size information
2031   requiredSize->setText( QString::number( tots )  + " KB");
2032   requiredTemp->setText( QString::number( temps ) + " KB");
2033
2034   // update available size information
2035   QFileInfo fi( QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() ) );
2036   if ( fi.exists() ) {
2037     diskSpaceProc->clearArguments();
2038     diskSpaceProc->setWorkingDirectory( QDir( rootDirPath() ).filePath( "config_files" ) );
2039     diskSpaceProc->addArgument( "diskSpace.sh" );
2040     diskSpaceProc->addArgument( fi.absFilePath() );
2041     // run script
2042     diskSpaceProc->start();
2043   }
2044
2045   // enable/disable "Next" button
2046   setNextEnabled( productsPage, isAnyProductSelected );
2047 }
2048 // ================================================================
2049 /*!
2050  *  SALOME_InstallWizard::setPrerequisites
2051  *  Sets the product and all products this one depends on to be checked ( recursively )
2052  */
2053 // ================================================================
2054 void SALOME_InstallWizard::setPrerequisites( QCheckListItem* item )
2055 {
2056   if ( !productsMap.contains( item ) )
2057     return;
2058   if ( !item->isOn() )
2059     return;
2060   // get all prerequisites
2061   QStringList dependOn = productsMap[ item ].getDependancies();
2062   // install SALOME without GUI case
2063   if ( installGuiBtn->state() != QButton::On && 
2064        woGuiModules.find( item->text(0) ) != woGuiModules.end() && 
2065        woGuiModules[item->text(0)] == True ) {
2066     dependOn.remove( "GUI" );
2067   }
2068   // setting prerequisites
2069   for ( int i = 0; i < (int)dependOn.count(); i++ ) {
2070     MapProducts::Iterator itProd;
2071     for ( itProd = productsMap.begin(); itProd != productsMap.end(); ++itProd ) {
2072       if ( itProd.data().getName() == dependOn[ i ] ) {
2073         if ( itProd.data().getType() == "component" && !itProd.key()->isOn() )
2074           itProd.key()->setOn( true );
2075         else if ( itProd.data().getType() == "prerequisite" ) {
2076           itProd.key()->setOn( true );
2077           itProd.key()->setEnabled( false );
2078         }
2079         break;
2080       }
2081     }
2082   }
2083 }
2084 // ================================================================
2085 /*!
2086  *  SALOME_InstallWizard::unsetPrerequisites
2087  *  Unsets all modules which depend of the unchecked product ( recursively )
2088  */
2089 // ================================================================
2090 void SALOME_InstallWizard::unsetPrerequisites( QCheckListItem* item )
2091 {
2092   if ( !productsMap.contains( item ) )
2093     return;
2094   if ( item->isOn() )
2095     return;
2096
2097 // uncheck dependent products
2098   QString itemName = productsMap[ item ].getName();
2099   MapProducts::Iterator itProd;
2100   for ( itProd = productsMap.begin(); itProd != productsMap.end(); ++itProd ) {
2101     if ( itProd.data().getType() == productsMap[ item ].getType() ) {
2102       QStringList dependOn = itProd.data().getDependancies();
2103       for ( int i = 0; i < (int)dependOn.count(); i++ ) {
2104         if ( dependOn[ i ] == itemName ) {
2105           if ( itProd.key()->isOn() ) {
2106             itProd.key()->setOn( false );
2107           }
2108         }
2109       }
2110     }
2111   }
2112
2113 // uncheck prerequisites
2114   int nbDependents;
2115 //   cout << "item name = " << productsMap[ item ].getName() << endl;
2116   QStringList dependOnList = productsMap[ item ].getDependancies();
2117   for ( int j = 0; j < (int)dependOnList.count(); j++ ) {
2118     nbDependents = 0;
2119     MapProducts::Iterator itProd1;
2120     for ( itProd1 = productsMap.begin(); itProd1 != productsMap.end(); ++itProd1 ) {
2121       if ( itProd1.data().getName() == dependOnList[ j ] ) {
2122         if ( itProd1.data().getType() == "prerequisite" ) {
2123           MapProducts::Iterator itProd2;
2124           for ( itProd2 = productsMap.begin(); itProd2 != productsMap.end(); ++itProd2 ) {
2125             if ( itProd2.key()->isOn() ) {
2126               QStringList prereqsList = productsMap[ itProd2.key() ].getDependancies();
2127               for ( int k = 0; k < (int)prereqsList.count(); k++ ) {
2128                 if ( prereqsList[ k ] == itProd1.data().getName() ) {
2129                   nbDependents++;
2130                   break;
2131                 }
2132               }
2133             }
2134           }
2135           if ( nbDependents == 0 ) {
2136             itProd1.key()->setEnabled( true );
2137             itProd1.key()->setOn( false );
2138           }
2139         }
2140         break;
2141       }
2142     }
2143   }
2144 }
2145 // ================================================================
2146 /*!
2147  *  SALOME_InstallWizard::launchScript
2148  *  Runs installation script
2149  */
2150 // ================================================================
2151 void SALOME_InstallWizard::launchScript()
2152 {
2153   // try to find product being processed now
2154   QString prodProc = progressView->findStatus( Processing );
2155   if ( !prodProc.isNull() ) {
2156     ___MESSAGE___( "Found <Processing>: " );
2157
2158     // if found - set status to "completed"
2159     progressView->setStatus( prodProc, Completed );
2160     // ... clear status label
2161     statusLab->clear();
2162     // ... and call this method again
2163     launchScript();
2164     return;
2165   }
2166   // else try to find next product which is not processed yet
2167   prodProc = progressView->findStatus( Waiting );
2168   if ( !prodProc.isNull() ) {
2169     ___MESSAGE___( "Found <Waiting>: " << prodProc.latin1() );
2170     // if found - set status to "processed" and run script
2171     progressView->setStatus( prodProc, Processing );
2172     progressView->ensureVisible( prodProc );
2173     
2174     QCheckListItem* item = 0;
2175     // fill in script parameters
2176     shellProcess->clearArguments();
2177     // ... script name
2178     shellProcess->setWorkingDirectory( QDir( rootDirPath() ).filePath( "config_files" ) );
2179     if ( !extraProducts.contains( prodProc ) ) {
2180       item = findItem( prodProc );
2181       shellProcess->addArgument( item->text(2) );
2182     }
2183     else
2184       shellProcess->addArgument( extraProducts[ prodProc ] );
2185
2186     // ... get folder with binaries
2187     QString OS = getPlatform();
2188     if ( refPlatform.isEmpty() && platformsMap.find( curPlatform ) == platformsMap.end() )
2189       OS = commonPlatform;
2190     QString binDir = getPlatformBinPath( OS );
2191     // ... temp folder
2192     QString tmpFolder = QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + TEMPDIRNAME;
2193     //if( !tempFolder->isEnabled() )
2194     //  tmpFolder = "/tmp";
2195
2196     // ... not install : try to find preinstalled
2197     if ( notInstall.contains( prodProc ) || prodProc == "gcc" ) {
2198       shellProcess->addArgument( "try_preinstalled" );
2199       shellProcess->addArgument( QFileInfo( tmpFolder ).absFilePath() );
2200       shellProcess->addArgument( QDir( rootDirPath() ).filePath( "Products" ) );
2201       statusLab->setText( tr( "Collecting environment for '" ) + prodProc + "'..." );
2202     }
2203     // ... binaries ?
2204     else if ( installType == Binaries ) {
2205       shellProcess->addArgument( "install_binary" );
2206       shellProcess->addArgument( QFileInfo( tmpFolder ).absFilePath() );
2207       shellProcess->addArgument( binDir );
2208       statusLab->setText( tr( "Installing '" ) + prodProc + "'..." );
2209     }
2210     // ... sources or sources_and_compilation ?
2211     else {
2212       shellProcess->addArgument( installType == Sources ? "install_source" : 
2213                                  "install_source_and_build" );
2214       shellProcess->addArgument( QFileInfo( tmpFolder ).absFilePath() );
2215       shellProcess->addArgument( QDir::cleanDirPath( getSrcPath() ) );
2216       statusLab->setText( tr( "Installing '" ) + prodProc + "'..." );
2217     }
2218     // ... target folder
2219     QString tgtFolder = QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() );
2220     shellProcess->addArgument( QFileInfo( tgtFolder ).absFilePath() );
2221     // ... list of all products
2222     QString depproducts = getAllProducts(productsMap);
2223     depproducts.prepend( QStringList( extraProducts.keys() ).join(" ") + " " );
2224     ___MESSAGE___( "Dependancies"<< depproducts.latin1() );
2225     shellProcess->addArgument( depproducts );
2226     // ... product name - currently installed product
2227     if ( !extraProducts.contains( prodProc ) )
2228       shellProcess->addArgument( item->text(0) );
2229     else
2230       shellProcess->addArgument( prodProc );
2231     // ... list of products being installed
2232     shellProcess->addArgument( prodSequence.join( " " ) );
2233     // ... sources directory
2234     shellProcess->addArgument( QDir::cleanDirPath( getSrcPath() ) );
2235     // ... remove sources and tmp files or not?
2236     if ( installType == Compile && removeSrcBtn->isOn() )
2237       shellProcess->addArgument( "TRUE" );
2238     else 
2239       shellProcess->addArgument( "FALSE" );
2240     // ... binaries directory
2241     shellProcess->addArgument( binDir );
2242     // ... install SALOME with GUI or not?
2243     if ( woGuiModules.find( prodProc ) != woGuiModules.end() )
2244       ( installGuiBtn->state() != QButton::On && woGuiModules[ prodProc ] == True ) ? 
2245         shellProcess->addArgument( "FALSE" ) : 
2246         shellProcess->addArgument( "TRUE" );
2247     // ... single installation directory for SALOME modules, if this option was selected
2248     if ( oneModDirBtn->isChecked() ) {
2249       MapProducts::Iterator mapIter;
2250       for ( mapIter = productsMap.begin(); mapIter != productsMap.end(); ++mapIter )
2251         if ( mapIter.data().getName() == prodProc && mapIter.data().getType() == "component" ) {
2252           shellProcess->addArgument( "TRUE" );
2253           break;
2254         }
2255     }
2256     // ... single installation directory for prerequisites, if this option was selected
2257     if ( oneProdDirBtn->isChecked() ) {
2258       if ( prodProc == "DebianLibsForSalome" )
2259         shellProcess->addArgument( oneProdDirName );
2260       else {
2261         MapProducts::Iterator mapIter;
2262         for ( mapIter = productsMap.begin(); mapIter != productsMap.end(); ++mapIter )
2263           if ( mapIter.data().getName() == prodProc && mapIter.data().getType() == "prerequisite" ) {
2264             shellProcess->addArgument( oneProdDirName );
2265             break;
2266           }
2267       }
2268     }
2269     
2270     // run script
2271     if ( !shellProcess->start() ) {
2272       // error handling can be here
2273       QStringList args = shellProcess->arguments();
2274       ___MESSAGE___( "error" );
2275       ___MESSAGE___( "cmd: " << args.join(" ").latin1() );
2276     }
2277     return;
2278   }
2279
2280   // else try to find aborted product
2281   prodProc = progressView->findStatus( Aborted );
2282   if ( !prodProc.isNull() )
2283     return; // installation has been aborted
2284
2285   ___MESSAGE___( "All products have been installed successfully" );
2286   // all products are installed successfully
2287   MapProducts::Iterator mapIter;
2288   ___MESSAGE___( "starting pick-up environment" );
2289   QString depproducts = QUOTE( getAllProducts(productsMap).prepend( QStringList( extraProducts.keys() ).join(" ") + " " ) );
2290   for ( mapIter = productsMap.begin(); mapIter != productsMap.end(); ++mapIter ) {
2291     QCheckListItem* item = mapIter.key();
2292     Dependancies dep = mapIter.data();
2293     if ( item->isOn() && dep.pickUpEnvironment() ) {
2294       statusLab->setText( tr( "Pick-up products environment for " ) + dep.getName().latin1() + "..." );
2295       ___MESSAGE___( "... for " << dep.getName().latin1() );
2296       QDir rd( rootDirPath() );
2297       Script script;
2298       script << "cd" << QUOTE( rd.filePath( "config_files" ) ) << ";";
2299       script << item->text(2) << "pickup_env";
2300       script << QUOTE( QFileInfo( QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + TEMPDIRNAME ).absFilePath() );
2301       script << QUOTE( QFileInfo( QDir::cleanDirPath( QDir( rootDirPath() ).filePath( "Products" ) ) ).absFilePath() );
2302       script << QUOTE( QFileInfo( QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() ) ).absFilePath() );
2303       script << depproducts << item->text(0) << QUOTE( prodSequence.join( " " ) );
2304       ___MESSAGE___( "... --> " << script.script().latin1() );
2305       if ( system( script.script().latin1() ) ) {
2306         ___MESSAGE___( "ERROR" );
2307       }
2308     }
2309   }
2310
2311   if ( installType == Binaries ) {
2312     if ( oneModDirBtn->isChecked() )
2313       runModifyLaFiles();
2314     else
2315       runCheckFLib();
2316   }
2317   else {
2318     // Update GUI and check installation errors
2319     completeInstallation();
2320   }
2321   
2322 }
2323 // ================================================================
2324 /*!
2325  *  SALOME_InstallWizard::completeInstallation
2326  *  Update GUI and check installation errors
2327  */
2328 // ================================================================
2329 void SALOME_InstallWizard::completeInstallation()
2330 {
2331   // update status label
2332   statusLab->setText( tr( "Installation completed" ) );
2333   // <Next> button
2334   setNextEnabled( true );
2335   doPostActions( tr( "&Next >" ), tr( "Move to the next step of the installation procedure" ) );
2336   connect(    this, SIGNAL( nextClicked() ), this, SLOT( next() ) );
2337   // <Back> button
2338   setBackEnabled( true );
2339   // script parameters
2340   passedParams->clear();
2341   passedParams->setEnabled( false );
2342   QFont f = parametersLab->font(); f.setBold( false ); parametersLab->setFont( f );
2343   installInfo->setFinished( true );
2344   if ( isMinimized() )
2345     showNormal();
2346   raise();
2347   if ( hasErrors ) {
2348     if ( QMessageBox::warning( this,
2349                                tr( "Warning" ),
2350                                tr( "There were some errors during the installation.\n"
2351                                    "Do you want to save the installation log?" ),
2352                                tr( "&Save" ),
2353                                tr( "&Cancel" ),
2354                                QString::null,
2355                                0,
2356                                1 ) == 0 )
2357       saveLog();
2358   }
2359   hasErrors = false;
2360
2361 }
2362 // ================================================================
2363 /*!
2364  *  SALOME_InstallWizard::onInstallGuiBtn
2365  *  <Installation with GUI> check-box slot
2366  */
2367 // ================================================================
2368 void SALOME_InstallWizard::onInstallGuiBtn()
2369 {
2370   MapProducts::Iterator itProd;
2371   for ( itProd = productsMap.begin(); itProd != productsMap.end(); ++itProd ) {
2372     if ( itProd.data().getType() == "component" ) {
2373       if ( installGuiBtn->state() == QButton::On ) {
2374         itProd.key()->setEnabled( true );
2375         itProd.key()->setOn( true );
2376       }
2377       else {
2378         QString itemName = itProd.data().getName();
2379         if ( woGuiModules.find( itemName ) == woGuiModules.end() || 
2380              woGuiModules[ itemName ] == False ) {
2381           itProd.key()->setOn( false );
2382           itProd.key()->setEnabled( false );
2383         }
2384         else
2385           itProd.key()->setOn( true );
2386       }
2387     }
2388   }
2389 }
2390 // ================================================================
2391 /*!
2392  *  SALOME_InstallWizard::onMoreBtn
2393  *  <More...> button slot
2394  */
2395 // ================================================================
2396 void SALOME_InstallWizard::onMoreBtn()
2397 {
2398   if ( moreMode ) {
2399     prereqsView->hide();
2400     moreBtn->setText( tr( "Show prerequisites..." ) );
2401     setAboutInfo( moreBtn, tr( "Show list of prerequisites" ) );
2402   }
2403   else {
2404     prereqsView->show();
2405     moreBtn->setText( tr( "Hide prerequisites" ) );
2406     setAboutInfo( moreBtn, tr( "Hide list of prerequisites" ) );
2407   }
2408   qApp->processEvents();
2409   moreMode = !moreMode;
2410   InstallWizard::layOut();
2411   qApp->processEvents();
2412   if ( !isMaximized() ) {
2413     qApp->processEvents();
2414   }
2415   checkProductPage();
2416 }
2417 // ================================================================
2418 /*!
2419  *  SALOME_InstallWizard::onFinishButton
2420  *  Operation buttons slot
2421  */
2422 // ================================================================
2423 void SALOME_InstallWizard::onFinishButton()
2424 {
2425   const QObject* btn = sender();
2426   ButtonList::Iterator it;
2427   for ( it = buttons.begin(); it != buttons.end(); ++it ) {
2428     if ( (*it).button() && (*it).button() == btn ) {
2429       QDir rd( rootDirPath() );
2430       Script script;
2431       script << "cd" << QUOTE( rd.filePath( "config_files" ) ) << ";";
2432       script << (*it).script() << "execute";
2433       script << QUOTE( QFileInfo( QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() ) ).absFilePath() );
2434       script << QUOTE( QFileInfo( QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + TEMPDIRNAME ).absFilePath() );
2435 #ifdef USE_DEV_NULL
2436       script << ">& /dev/null";
2437 #endif
2438       ___MESSAGE___( "script: " << script.script().latin1() );
2439       if ( (*it).script().isEmpty() || system( script.script().latin1() ) ) {
2440         QMessageBox::warning( this,
2441                               tr( "Error" ),
2442                               tr( "Can't perform action!"),
2443                               QMessageBox::Ok,
2444                               QMessageBox::NoButton,
2445                               QMessageBox::NoButton );
2446       }
2447       return;
2448     }
2449   }
2450 }
2451 // ================================================================
2452 /*!
2453  *  SALOME_InstallWizard::onAbout
2454  *  <About> button slot: shows <About> dialog box
2455  */
2456 // ================================================================
2457 void SALOME_InstallWizard::onAbout()
2458 {
2459   AboutDlg d( this );
2460   d.exec();
2461 }
2462
2463 // ================================================================
2464 /*!
2465  *  SALOME_InstallWizard::findItem
2466  *  Searches product listview item with given symbolic name
2467  */
2468 // ================================================================
2469 QCheckListItem* SALOME_InstallWizard::findItem( const QString& sName )
2470 {
2471   MapProducts::Iterator mapIter;
2472   for ( mapIter = productsMap.begin(); mapIter != productsMap.end(); ++mapIter ) {
2473     if ( mapIter.data().getName() == sName )
2474       return mapIter.key();
2475   }
2476   return 0;
2477 }
2478 // ================================================================
2479 /*!
2480  *  SALOME_InstallWizard::abort
2481  *  Sets progress state to Aborted
2482  */
2483 // ================================================================
2484 void SALOME_InstallWizard::abort()
2485 {
2486   QString prod = progressView->findStatus( Processing );
2487   while ( !prod.isNull() ) {
2488     progressView->setStatus( prod, Aborted );
2489     prod = progressView->findStatus( Processing );
2490   }
2491   prod = progressView->findStatus( Waiting );
2492   while ( !prod.isNull() ) {
2493     progressView->setStatus( prod, Aborted );
2494     prod = progressView->findStatus( Waiting );
2495   }
2496 }
2497 // ================================================================
2498 /*!
2499  *  SALOME_InstallWizard::reject
2500  *  Reject slot, clears temporary directory and closes application
2501  */
2502 // ================================================================
2503 void SALOME_InstallWizard::reject()
2504 {
2505   ___MESSAGE___( "REJECTED" );
2506   if ( !exitConfirmed ) {
2507     if ( QMessageBox::information( this,
2508                                    tr( "Exit" ),
2509                                    tr( "Do you want to quit %1?" ).arg( getIWName() ),
2510                                    tr( "&Yes" ),
2511                                    tr( "&No" ),
2512                                    QString::null,
2513                                    0,
2514                                    1 ) == 1 ) {
2515       return;
2516     }
2517     exitConfirmed = true;
2518   }
2519   clean(true);
2520   InstallWizard::reject();
2521 }
2522 // ================================================================
2523 /*!
2524  *  SALOME_InstallWizard::accept
2525  *  Accept slot, clears temporary directory and closes application
2526  */
2527 // ================================================================
2528 void SALOME_InstallWizard::accept()
2529 {
2530   ___MESSAGE___( "ACCEPTED" );
2531   clean(true);
2532   InstallWizard::accept();
2533 }
2534 // ================================================================
2535 /*!
2536  *  SALOME_InstallWizard::clean
2537  *  Clears and (optionally) removes temporary directory
2538  */
2539 // ================================================================
2540 void SALOME_InstallWizard::clean(bool rmDir)
2541 {
2542   WarnDialog::showWarnDlg( 0, false );
2543   myThread->clearCommands();
2544   myWC.wakeAll();
2545   while ( myThread->running() );
2546   // first remove temporary files
2547   QDir rd( rootDirPath() );
2548   Script script;
2549   script << "cd" << QUOTE( rd.filePath( "config_files" ) ) << ";";
2550   script << "remove_tmp.sh" << QUOTE( tempFolder->text().stripWhiteSpace() + TEMPDIRNAME );
2551   script << QUOTE( getAllProducts( productsMap ) );
2552 #ifdef USE_DEV_NULL
2553   script << ">& /dev/null";
2554 #endif
2555   ___MESSAGE___( "script = " << script.script().latin1() );
2556   if ( system( script.script().latin1() ) ) {
2557     // error
2558   }
2559   // then try to remove created temporary directory
2560   //script = "rm -rf " + QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + TEMPDIRNAME;
2561   if ( rmDir && !tmpCreated.isNull() ) {
2562     script.clear();
2563     script << "rm -rf" << QUOTE( tmpCreated );
2564 #ifdef USE_DEV_NULL
2565     script << ">& /dev/null";
2566 #endif
2567     if ( system( script.script().latin1() ) ) {
2568       // error
2569     }
2570     ___MESSAGE___( "script = " << script.script().latin1() );
2571   }
2572 }
2573 // ================================================================
2574 /*!
2575  *  SALOME_InstallWizard::pageChanged
2576  *  Called when user moves from page to page
2577  */
2578 // ================================================================
2579 void SALOME_InstallWizard::pageChanged( const QString & mytitle)
2580 {
2581   doPostActions( tr( "&Next >" ), tr( "Move to the next step of the installation procedure" ) );
2582   connect(    this, SIGNAL( nextClicked() ), this, SLOT( next() ) );
2583   cancelButton()->disconnect();
2584   connect( cancelButton(), SIGNAL( clicked()), this, SLOT( reject() ) );
2585
2586   QWidget* aPage = InstallWizard::page( mytitle );
2587   if ( !aPage )
2588     return;
2589   updateCaption();
2590
2591   if ( aPage == typePage ) {
2592     // installation type page
2593     if ( buttonGrp->id( buttonGrp->selected() ) == -1 )
2594       // set default installation type
2595       forceSrc ? srcCompileBtn->animateClick() : binBtn->animateClick();
2596     else
2597       buttonGrp->selected()->animateClick();
2598   }
2599   else if ( aPage == platformsPage ) {
2600     // installation platforms page
2601     MapXmlFiles::Iterator it;
2602     if ( previousPage == typePage ) {
2603       for ( it = platformsMap.begin(); it != platformsMap.end(); ++it ) {
2604         QString plat = it.key();
2605         QRadioButton* rb = ( (QRadioButton*) platBtnGrp->child( plat ) );
2606         if ( installType == Binaries ) {
2607           QFileInfo fib( getPlatformBinPath( plat ) );
2608           rb->setEnabled( true/*fib.isDir()*/ );
2609           if ( platBtnGrp->id( platBtnGrp->selected() ) == -1 && plat == getBasePlatform() )
2610             rb->animateClick();
2611         }
2612 //      rb->setChecked( rb->isChecked() && rb->isEnabled() );
2613         if ( rb->isChecked() && rb->isEnabled() )
2614           rb->animateClick();
2615       }
2616       setNextEnabled( platformsPage, platBtnGrp->id( platBtnGrp->selected() ) != -1 );
2617     }
2618   }
2619   else  if ( aPage == dirPage ) {
2620     // installation and temporary directories page
2621     if ( ( ( this->indexOf( platformsPage ) != -1 && this->appropriate( platformsPage ) ) ? 
2622            previousPage == platformsPage : previousPage == typePage ) 
2623          && stateChanged ) {
2624       // clear global variables before reading XML file
2625       modulesView->clear();
2626       prereqsView->clear();
2627       productsMap.clear();
2628       // read XML file
2629       StructureParser* parser = new StructureParser( this );
2630       parser->setProductsLists( modulesView, prereqsView );
2631       if ( targetFolder->text().isEmpty() )
2632         parser->setTargetDir( targetFolder );
2633       if ( tempFolder->text().isEmpty() )
2634         parser->setTempDir( tempFolder );
2635       parser->readXmlFile( xmlFileName );
2636       // create a map of SALOME modules names, that can support installation without GUI mode
2637       if ( woGuiModules.isEmpty() ) {
2638         MapProducts::Iterator mapIter;
2639         for ( mapIter = productsMap.begin(); mapIter != productsMap.end(); mapIter++ ) {
2640           Dependancies dep = mapIter.data();
2641           if ( dep.getType() == "component" && dep.supportWoGuiMode() != NotDefined )
2642             woGuiModules[ dep.getName() ] = dep.supportWoGuiMode();
2643         }
2644       }
2645   
2646       // update required size for each product
2647       updateSizeColumn();
2648       // take into account command line parameters
2649       if ( !myTargetPath.isEmpty() )
2650         targetFolder->setText( myTargetPath );
2651       if ( !myTmpPath.isEmpty() )
2652         tempFolder->setText( myTmpPath );
2653       // set all modules to be checked and first module to be selected
2654       installGuiBtn->setState( QButton::Off );
2655       installGuiBtn->setState( QButton::On );
2656       if ( modulesView->childCount() > 0 && !modulesView->selectedItem() )
2657         modulesView->setSelected( modulesView->firstChild(), true );
2658       stateChanged = false;
2659     } 
2660     else if ( rmSrcPrevState != removeSrcBtn->isChecked() ) {
2661       // only update required size for each product
2662       updateSizeColumn();
2663       rmSrcPrevState = removeSrcBtn->isChecked();
2664     }
2665     // add extra products to install list
2666     extraProducts.clear();
2667     //extraProducts.insert( "gcc", "gcc-common.sh" );
2668     if ( refPlatform == commonPlatform && installType == Binaries )
2669       extraProducts.insert( "DebianLibsForSalome", "DEBIANFORSALOME-3.1.sh" );
2670   }
2671   else if ( aPage == productsPage ) {
2672     // products page
2673     onSelectionChanged();
2674     checkProductPage();
2675   }
2676   else if ( aPage == prestartPage ) {
2677     // prestart page
2678     showChoiceInfo();
2679   }
2680   else if ( aPage == progressPage ) {
2681     if ( previousPage == prestartPage ) {
2682       // progress page
2683       statusLab->clear();
2684       progressView->clear();
2685       installInfo->clear();
2686       installInfo->setFinished( false );
2687       passedParams->clear();
2688       passedParams->setEnabled( false );
2689       QFont f = parametersLab->font(); f.setBold( false ); parametersLab->setFont( f );
2690       doPostActions( tr( "&Start" ), tr( "Start installation process" ) );
2691       connect(    this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
2692       setNextEnabled( true );
2693       // reconnect Cancel button to terminate process
2694       cancelButton()->disconnect();
2695       connect( cancelButton(), SIGNAL( clicked() ), this, SLOT( tryTerminate() ) );
2696     }
2697   }
2698   else if ( aPage == readmePage ) {
2699     ButtonList::Iterator it;
2700     for ( it = buttons.begin(); it != buttons.end(); ++it ) {
2701       if ( (*it).button() ) {
2702         QDir rd( rootDirPath() );
2703         Script script;
2704         script << "cd" << QUOTE( rd.filePath( "config_files" ) ) << ";";
2705         script << (*it).script() << "check_enabled";
2706         script << QUOTE( QFileInfo( QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() ) ).absFilePath() );
2707         script << QUOTE( QFileInfo( QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + TEMPDIRNAME ).absFilePath() );
2708 #ifdef USE_DEV_NULL
2709         script << ">& /dev/null";
2710 #endif
2711         ___MESSAGE___( "script: " << script.script().latin1() );
2712         (*it).button()->setEnabled( !(*it).script().isEmpty() && !system( script.script().latin1() ) );
2713       }
2714     }
2715     finishButton()->setEnabled( true );
2716   }
2717   previousPage = aPage;
2718   ___MESSAGE___( "previousPage = " << previousPage );
2719 }
2720 // ================================================================
2721 /*!
2722  *  SALOME_InstallWizard::onButtonGroup
2723  *  Called when user selected either installation type or installation platform
2724  */
2725 // ================================================================
2726 void SALOME_InstallWizard::onButtonGroup( int rbIndex )
2727 {
2728   int prevType = installType;
2729   QString prevPlat = getPlatform();
2730   QWidget* aPage = InstallWizard::currentPage();
2731   if ( aPage == typePage ) {
2732     installType = InstallationType( rbIndex );
2733     // management of the <Remove source and tmp files> check-box
2734     removeSrcBtn->setEnabled( installType == Compile );
2735     oneModDirBtn->setEnabled( installType == Binaries /*|| installType == Compile*/ );
2736     oneProdDirBtn->setEnabled( installType == Binaries || installType == Compile );
2737     refPlatform = "";
2738     xmlFileName = getXmlFile( curPlatform );
2739   }
2740   else if ( aPage == platformsPage ) {
2741     refPlatform = platBtnGrp->find( rbIndex )->name();
2742     xmlFileName = getXmlFile( refPlatform );
2743     setNextEnabled( platformsPage, true );
2744   }
2745   if ( prevType != installType || 
2746        ( indexOf( platformsPage ) != -1 ? prevPlat != getPlatform() : false ) ) {
2747     stateChanged = true;
2748     oneModDirBtn->setChecked( installType == Binaries && singleDir );
2749     oneProdDirBtn->setChecked( false );
2750   }
2751 }
2752 // ================================================================
2753 /*!
2754  *  SALOME_InstallWizard::helpClicked
2755  *  Shows help window
2756  */
2757 // ================================================================
2758 void SALOME_InstallWizard::helpClicked()
2759 {
2760   if ( helpWindow == NULL ) {
2761     helpWindow = HelpWindow::openHelp( this );
2762     if ( helpWindow ) {
2763       helpWindow->show();
2764       helpWindow->installEventFilter( this );
2765     }
2766     else {
2767       QMessageBox::warning( this,
2768                             tr( "Help file not found" ),
2769                             tr( "Sorry, help is unavailable" ) );
2770     }
2771   }
2772   else {
2773     helpWindow->raise();
2774     helpWindow->setActiveWindow();
2775   }
2776 }
2777 // ================================================================
2778 /*!
2779  *  SALOME_InstallWizard::browseDirectory
2780  *  Shows directory selection dialog
2781  */
2782 // ================================================================
2783 void SALOME_InstallWizard::browseDirectory()
2784 {
2785   const QObject* theSender = sender();
2786   QLineEdit* theFolder;
2787   if ( theSender == targetBtn )
2788     theFolder = targetFolder;
2789   else if (theSender == tempBtn)
2790     theFolder = tempFolder;
2791   else
2792     return;
2793   QString typedDir = QFileDialog::getExistingDirectory( QDir::cleanDirPath( theFolder->text().stripWhiteSpace() ), this );
2794   if ( !typedDir.isNull() ) {
2795     theFolder->setText( typedDir );
2796     theFolder->end( false );
2797   }
2798 }
2799 // ================================================================
2800 /*!
2801  *  SALOME_InstallWizard::directoryChanged
2802  *  Called when directory path (target or temp) is changed
2803  */
2804 // ================================================================
2805 void SALOME_InstallWizard::directoryChanged( const QString& /*text*/ )
2806 {
2807   checkProductPage();
2808 }
2809 // ================================================================
2810 /*!
2811  *  SALOME_InstallWizard::onStart
2812  *  <Start> button's slot - runs installation
2813  */
2814 // ================================================================
2815 void SALOME_InstallWizard::onStart()
2816 {
2817   if ( nextButton()->text() == tr( "&Stop" ) ) {
2818     statusLab->setText( tr( "Aborting installation..." ) );
2819     shellProcess->kill();
2820     modifyLaProc->kill();
2821     while( shellProcess->isRunning() );
2822     statusLab->setText( tr( "Installation has been aborted by user" ) );
2823     return;
2824   }
2825
2826   hasErrors = false;
2827   progressView->clear();
2828   installInfo->clear();
2829   installInfo->setFinished( false );
2830   passedParams->clear();
2831   passedParams->setEnabled( false );
2832   // disable 'Ignore errors' checkbox during installation process
2833   ignoreErrCBox->setEnabled( false );
2834   QFont f = parametersLab->font(); f.setBold( false ); parametersLab->setFont( f );
2835
2836   // update status label
2837   statusLab->setText( tr( "Preparing for installation..." ) );
2838   // clear lists of products
2839   toInstall.clear();
2840   notInstall.clear();
2841   toInstall += extraProducts.keys();
2842   // ... and fill it for new process
2843   QCheckListItem* item = (QCheckListItem*)( prereqsView->firstChild() );
2844   while( item ) {
2845     if ( productsMap.contains( item ) ) {
2846       if ( item->isOn() )
2847         toInstall.append( productsMap[item].getName() );
2848       else
2849         notInstall.append( productsMap[item].getName() );
2850     }
2851     item = (QCheckListItem*)( item->nextSibling() );
2852   }
2853   item = (QCheckListItem*)( modulesView->firstChild() );
2854   while( item ) {
2855     if ( productsMap.contains( item ) ) {
2856       if ( item->isOn() )
2857         toInstall.append( productsMap[item].getName() );
2858       else
2859         notInstall.append( productsMap[item].getName() );
2860     }
2861     item = (QCheckListItem*)( item->nextSibling() );
2862   }
2863   // if something at all is selected
2864   if ( (int)toInstall.count() > 0 ) {
2865
2866     if ( installType == Compile ) {
2867       // update status label
2868       statusLab->setText( tr( "Check Fortran compiler..." ) );
2869       // check Fortran compiler.
2870       QDir rd( rootDirPath() );
2871       Script script;
2872       script << QUOTE( rd.filePath( "config_files/checkFortran.sh" ) ) << "find_compilers";
2873       script << QUOTE( QFileInfo( QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + TEMPDIRNAME ).absFilePath() );
2874       ___MESSAGE___( "script = " << script.script().latin1() );
2875       if ( system( script.script().latin1() ) ) {
2876         QMessageBox::critical( this,
2877                                tr( "Error" ),
2878                                tr( "Fortran compiler was not found at current system!\n"
2879                                    "Installation can not be continued!"),
2880                                QMessageBox::Ok,
2881                                QMessageBox::NoButton,
2882                                QMessageBox::NoButton );
2883         // installation aborted
2884         abort();
2885         statusLab->setText( tr( "Installation has been aborted" ) );
2886         // enable <Next> button
2887         setNextEnabled( true );
2888         doPostActions( tr( "&Start" ), tr( "Start installation process" ) );
2889         connect(    this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
2890         // enable <Back> button
2891         setBackEnabled( true );
2892         return;
2893       }
2894     }  
2895     
2896     // update status label
2897     statusLab->setText( tr( "Preparing for installation..." ) );
2898
2899     clean(false); // VSR 07/02/05 - bug fix: first we should clear temporary directory
2900     // disable <Next> button
2901     //setNextEnabled( false );
2902     nextButton()->setText( tr( "&Stop" ) );
2903     setAboutInfo( nextButton(), tr( "Abort installation process" ) );
2904     // disable <Back> button
2905     setBackEnabled( false );
2906     // enable script parameters line edit
2907     // VSR commented: 18/09/03: passedParams->setEnabled( true );
2908     // VSR commented: 18/09/03: passedParams->setFocus();
2909     ProgressViewItem* progressItem;
2910     // set status for installed products
2911     for ( int i = 0; i < (int)toInstall.count(); i++ ) {
2912       if ( !extraProducts.contains( toInstall[i] ) ) {
2913         item = findItem( toInstall[i] );
2914         progressView->addProduct( item->text(0), item->text(2) );
2915         continue;
2916       }
2917       progressItem = progressView->addProduct( toInstall[i], extraProducts[toInstall[i]] );
2918       progressItem->setVisible( false );
2919     }
2920     // set status for not installed products
2921     for ( int i = 0; i < (int)notInstall.count(); i++ ) {
2922       item = findItem( notInstall[i] );
2923       progressItem = progressView->addProduct( item->text(0), item->text(2) );
2924       progressItem->setVisible( false );
2925     }
2926     // get specified list of products being installed
2927     prodSequence.clear();
2928     for (int i = 0; i<(int)toInstall.count(); i++ ) {
2929       if ( extraProducts.contains( toInstall[i] ) ) {
2930         prodSequence.append( toInstall[i] );
2931         continue;
2932       }
2933       if ( installType == Binaries ) {
2934         prodSequence.append( toInstall[i] );
2935         QString prodType;
2936         MapProducts::Iterator mapIter;
2937         for ( mapIter = productsMap.begin(); mapIter != productsMap.end(); ++mapIter ) {
2938           if ( mapIter.data().getName() == toInstall[i] && mapIter.data().getType() == "component" ) {
2939             prodSequence.append( toInstall[i] + "_src" );
2940             break;
2941           }
2942         }
2943       }
2944       else if ( installType == Sources )
2945         prodSequence.append( toInstall[i] + "_src" );
2946       else {
2947         prodSequence.append( toInstall[i] );
2948         prodSequence.append( toInstall[i] + "_src" );
2949       }
2950     }
2951
2952     // create a backup of 'env_build.csh', 'env_build.sh', 'env_products.csh', 'env_products.sh'
2953     // ( backup of 'salome.csh' and 'salome.sh' is made if pick-up environment is called )
2954     QDir rd( rootDirPath() );
2955     Script script;
2956     script << QUOTE( rd.filePath( "config_files/backupEnv.sh" ) );
2957     script << QUOTE( QFileInfo( QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() ) ).absFilePath() );
2958     ___MESSAGE___( "script = " << script.script().latin1() );
2959     if ( system( script.script().latin1() ) ) {
2960       if ( QMessageBox::warning( this,
2961                                  tr( "Warning" ),
2962                                  tr( "Backup environment files have not been created.\n"
2963                                      "Do you want to continue an installation process?" ),
2964                                  tr( "&Yes" ),
2965                                  tr( "&No" ), 
2966                                  QString::null, 0, 1 ) == 1 ) {
2967         // installation aborted
2968         abort();
2969         statusLab->setText( tr( "Installation has been aborted by user" ) );
2970         // update <Next> button
2971         setNextEnabled( true );
2972         doPostActions( tr( "&Start" ), tr( "Start installation process" ) );
2973         connect(    this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
2974         // enable <Back> button
2975         setBackEnabled( true );
2976         return;
2977       }
2978     }
2979
2980     // launch install script
2981     launchScript();
2982   }
2983 }
2984 // ================================================================
2985 /*!
2986  *  SALOME_InstallWizard::onReturnPressed
2987  *  Called when users tries to pass parameters for the script
2988  */
2989 // ================================================================
2990 void SALOME_InstallWizard::onReturnPressed()
2991 {
2992   QString txt = passedParams->text();
2993   installInfo->append( txt );
2994   txt += "\n";
2995   shellProcess->writeToStdin( txt );
2996   passedParams->clear();
2997   progressView->setFocus();
2998   passedParams->setEnabled( false );
2999   QFont f = parametersLab->font(); f.setBold( false ); parametersLab->setFont( f );
3000 }
3001 /*!
3002   Callback function - as response for the script finishing
3003 */
3004 void SALOME_InstallWizard::productInstalled()
3005 {
3006   ___MESSAGE___( "process exited" );
3007   if ( shellProcess->normalExit() ) {
3008     ___MESSAGE___( "...normal exit" );
3009     // normal exit - try to proceed installation further
3010     launchScript();
3011   }
3012   else {
3013     ___MESSAGE___( "...abnormal exit" );
3014     statusLab->setText( tr( "Installation has been aborted" ) );
3015     // installation aborted
3016     abort();
3017     // clear script passed parameters lineedit
3018     passedParams->clear();
3019     passedParams->setEnabled( false );
3020     QFont f = parametersLab->font(); f.setBold( false ); parametersLab->setFont( f );
3021     installInfo->setFinished( true );
3022     // enable <Next> button
3023     setNextEnabled( true );
3024     doPostActions( tr( "&Start" ), tr( "Start installation process" ) );
3025     connect(    this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
3026     //doPostActions( tr( "&Next >" ), tr( "Move to the next step of the installation procedure" ) );
3027     //connect(    this, SIGNAL( nextClicked() ), this, SLOT( next() ) );
3028     // enable <Back> button
3029     setBackEnabled( true );
3030   }
3031 }
3032 // ================================================================
3033 /*!
3034  *  SALOME_InstallWizard::tryTerminate
3035  *  Slot, called when <Cancel> button is clicked during installation script running
3036  */
3037 // ================================================================
3038 void SALOME_InstallWizard::tryTerminate()
3039 {
3040   if ( shellProcess->isRunning() ) {
3041     if ( QMessageBox::information( this,
3042                                    tr( "Exit" ),
3043                                    tr( "Do you want to quit %1?" ).arg( getIWName() ),
3044                                    tr( "&Yes" ),
3045                                    tr( "&No" ),
3046                                    QString::null,
3047                                    0,
3048                                    1 ) == 1 ) {
3049       return;
3050     }
3051     exitConfirmed = true;
3052     // if process still running try to terminate it first
3053     shellProcess->tryTerminate();
3054     abort();
3055     //QTimer::singleShot( 3000, this, SLOT( onCancel() ) );
3056     connect( shellProcess, SIGNAL( processExited() ), this, SLOT( onCancel() ) );
3057   }
3058   else {
3059     // else just quit install wizard
3060     reject();
3061   }
3062 }
3063 // ================================================================
3064 /*!
3065  *  SALOME_InstallWizard::onCancel
3066  *  Kills installation process and quits application
3067  */
3068 // ================================================================
3069 void SALOME_InstallWizard::onCancel()
3070 {
3071   shellProcess->kill();
3072   modifyLaProc->kill();
3073   checkFLibProc->kill();
3074   reject();
3075 }
3076 // ================================================================
3077 /*!
3078  *  SALOME_InstallWizard::onSelectionChanged
3079  *  Called when selection is changed in the products list view
3080  *  to fill in the 'Information about product' text box
3081  */
3082 // ================================================================
3083 void SALOME_InstallWizard::onSelectionChanged()
3084 {
3085   const QObject* snd = sender();
3086   QListViewItem* item = modulesView->selectedItem();
3087   if ( snd == prereqsView )
3088     item = prereqsView->selectedItem();
3089   if ( !item )
3090     return;
3091   productInfo->clear();
3092   QCheckListItem* anItem = (QCheckListItem*)item;
3093   if ( !productsMap.contains( anItem ) )
3094     return;
3095   Dependancies dep = productsMap[ anItem ];
3096   QString text = "<b>" + anItem->text(0) + "</b>" + "<br>";
3097   if ( !dep.getVersion().isEmpty() )
3098     text += tr( "Version" ) + ": " + dep.getVersion() + "<br>";
3099   text += "<br>";
3100   if ( !dep.getDescription().isEmpty() ) {
3101     text += "<i>" + dep.getDescription() + "</i><br><br>";
3102   }
3103   /* AKL: 07/08/28 - hide required disk space for tmp files for each product ==>
3104      long tempSize = 0;
3105      tempSize = dep.getTempSize( installType );
3106      text += tr( "Disk space for tmp files required" ) + ": " + QString::number( tempSize ) + " KB<br>";
3107      AKL: 07/08/28 - hide required disk space for tmp files for each product <==
3108   */
3109   text += tr( "Disk space required" ) + ": " + item->text(1) + "<br>";
3110   text += "<br>";
3111   QString req = ( dep.getDependancies().count() > 0 ? dep.getDependancies().join(", ") : tr( "none" ) );
3112   text +=  tr( "Prerequisites" ) + ": " + req;
3113   productInfo->setText( text );
3114 }
3115 // ================================================================
3116 /*!
3117  *  SALOME_InstallWizard::onItemToggled
3118  *  Called when user checks/unchecks any product item
3119  *  Recursively sets all prerequisites and updates "Next" button state
3120  */
3121 // ================================================================
3122 void SALOME_InstallWizard::onItemToggled( QCheckListItem* item )
3123 {
3124   if ( productsMap.contains( item ) ) {
3125     if ( item->isOn() )
3126       setPrerequisites( item );
3127     else 
3128       unsetPrerequisites( item );
3129   }
3130   onSelectionChanged();
3131   checkProductPage();
3132 }
3133 // ================================================================
3134 /*!
3135  *  SALOME_InstallWizard::wroteToStdin
3136  *  QProcess slot: -->something was written to stdin
3137  */
3138 // ================================================================
3139 void SALOME_InstallWizard::wroteToStdin( )
3140 {
3141   ___MESSAGE___( "Something was sent to stdin" );
3142 }
3143 // ================================================================
3144 /*!
3145  *  SALOME_InstallWizard::readFromStdout
3146  *  QProcess slot: -->something was written to stdout
3147  */
3148 // ================================================================
3149 void SALOME_InstallWizard::readFromStdout( )
3150 {
3151   ___MESSAGE___( "Something was sent to stdout" );
3152   QProcess* theProcess = ( QProcess* )sender();
3153   while ( theProcess->canReadLineStdout() ) {
3154     installInfo->append( QString( theProcess->readLineStdout() ) );
3155     installInfo->scrollToBottom();
3156   }
3157   QString str( theProcess->readStdout() );
3158   if ( !str.isEmpty() ) {
3159     installInfo->append( str );
3160     installInfo->scrollToBottom();
3161   }
3162 }
3163
3164 #define OUTLINE_TEXT(x) QString( "<font color=#FF0000><b>" ) + QString( x ) + QString( "</b></font>" )
3165
3166 // ================================================================
3167 /*!
3168  *  SALOME_InstallWizard::readFromStderr
3169  *  QProcess slot: -->something was written to stderr
3170  */
3171 // ================================================================
3172 void SALOME_InstallWizard::readFromStderr( )
3173 {
3174   ___MESSAGE___( "Something was sent to stderr" );
3175   QProcess* theProcess = ( QProcess* )sender();
3176   while ( theProcess->canReadLineStderr() ) {
3177     installInfo->append( OUTLINE_TEXT( QString( theProcess->readLineStderr() ) ) );
3178     installInfo->scrollToBottom();
3179     hasErrors = true;
3180   }
3181   QString str( theProcess->readStderr() );
3182   if ( !str.isEmpty() ) {
3183     installInfo->append( OUTLINE_TEXT( str ) );
3184     installInfo->scrollToBottom();
3185     hasErrors = true;
3186   }
3187
3188   // stop or proceed installation process
3189   manageInstProc();
3190
3191   // VSR: 10/11/05 - disable answer mode ==>
3192   // passedParams->setEnabled( true );
3193   // passedParams->setFocus();
3194   // QFont f = parametersLab->font(); f.setBold( true ); parametersLab->setFont( f );
3195   // VSR: 10/11/05 - disable answer mode <==
3196 }
3197 // ================================================================
3198 /*!
3199  *  SALOME_InstallWizard::manageInstProc
3200  *  QProcess slot: -->stop installation if there is an error in stderr
3201  */
3202 // ================================================================
3203 void SALOME_InstallWizard::manageInstProc()
3204 {
3205   if ( !hasErrors || ignoreErrCBox->isChecked() )
3206     return; //proceed installation process
3207   
3208   // abort the current installation
3209   statusLab->setText( tr( "Aborting installation..." ) );
3210   abort();
3211   statusLab->setText( tr( "Installation has been aborted because some errors" ) );
3212   if ( QMessageBox::critical( this,
3213                               tr( "Error" ),
3214                               tr( "Installation process has been stopped, because an error occured \n"
3215                                   "during an installation of the current product!\n"
3216                                   "Please see the installation progress view for more details about the error.\n\n"
3217                                   "Do you want to save the installation log?" ),
3218                               tr( "&Save" ),
3219                               tr( "&Cancel" ),
3220                               QString::null,
3221                               0,
3222                               1 ) == 0 )
3223     saveLog();
3224   // enable <Next> button
3225   setNextEnabled( true );
3226   doPostActions( tr( "&Start" ), tr( "Start installation process" ) );
3227   connect( this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
3228   // enable <Back> button
3229   setBackEnabled( true );
3230   installInfo->setFinished( true );
3231 }
3232 // ================================================================
3233 /*!
3234  *  SALOME_InstallWizard::setDependancies
3235  *  Sets dependancies for the product item
3236  */
3237 // ================================================================
3238 void SALOME_InstallWizard::setDependancies( QCheckListItem* item, Dependancies dep)
3239 {
3240   productsMap[item] = dep;
3241 }
3242 // ================================================================
3243 /*!
3244  *  SALOME_InstallWizard::doPostActions
3245  *  Executes some actions after finish of installation process (successful or not)
3246  */
3247 // ================================================================
3248 void SALOME_InstallWizard::doPostActions( const QString& btnText,
3249                                           const QString& btnAboutInfo )
3250 {
3251   // update <Next> button
3252   nextButton()->setText( btnText );
3253   setAboutInfo( nextButton(), btnAboutInfo );
3254   // reconnect Next button - to use it as Start button
3255   disconnect( this, SIGNAL( nextClicked() ), this, SLOT( next() ) );
3256   disconnect( this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
3257   // enable 'Ignore errors' checkbox
3258   ignoreErrCBox->setEnabled( true );
3259 }
3260 // ================================================================
3261 /*!
3262  *  SALOME_InstallWizard::addFinishButton
3263  *  Add button for the <Finish> page.
3264  *  Clear list of buttons if <toClear> flag is true.
3265  */
3266 // ================================================================
3267 void SALOME_InstallWizard::addFinishButton( const QString& label,
3268                                             const QString& tooltip,
3269                                             const QString& script,
3270                                             bool toClear )
3271 {
3272   ButtonList btns;
3273   if ( toClear ) {
3274     btns = buttons;
3275     buttons.clear();
3276   }
3277   buttons.append( Button( label, tooltip, script ) );
3278   // create finish buttons
3279   QButton* b = new QPushButton( tr( buttons.last().label() ), readmePage );
3280   if ( !buttons.last().tootip().isEmpty() )
3281     setAboutInfo( b, tr( buttons.last().tootip() ) );
3282   QHBoxLayout* hLayout = (QHBoxLayout*)readmePage->layout()->child("finishButtons");
3283   if ( toClear ) {
3284     // remove previous buttons
3285     ButtonList::Iterator it;
3286     for ( it = btns.begin(); it != btns.end(); ++it ) {
3287       hLayout->removeChild( (*it).button() );
3288       delete (*it).button();
3289     }
3290   }
3291   // add buttons to finish page
3292   hLayout->insertWidget( buttons.count()-1, b );
3293   buttons.last().setButton( b );
3294   connect( b, SIGNAL( clicked() ), this, SLOT( onFinishButton() ) );
3295 }
3296 // ================================================================
3297 /*!
3298  *  SALOME_InstallWizard::polish
3299  *  Polishing of the widget - to set right initial size
3300  */
3301 // ================================================================
3302 void SALOME_InstallWizard::polish()
3303 {
3304   resize( 0, 0 );
3305   InstallWizard::polish();
3306 }
3307 // ================================================================
3308 /*!
3309  *  SALOME_InstallWizard::saveLog
3310  *  Save installation log to file
3311  */
3312 // ================================================================
3313 void SALOME_InstallWizard::saveLog()
3314 {
3315   QString txt = installInfo->text();
3316   if ( txt.length() <= 0 )
3317     return;
3318   QDateTime dt = QDateTime::currentDateTime();
3319   QString fileName = dt.toString("ddMMyy-hhmm");
3320   fileName.prepend("install-"); fileName.append(".html");
3321   fileName = QFileInfo( QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() ), fileName ).absFilePath();
3322   fileName = QFileDialog::getSaveFileName( fileName,
3323                                            QString( "HTML files (*.htm *.html)" ),
3324                                            this, 0,
3325                                            tr( "Save Log file" ) );
3326   if ( !fileName.isEmpty() ) {
3327     QFile f( fileName );
3328     if ( f.open( IO_WriteOnly ) ) {
3329       QTextStream stream( &f );
3330       stream << txt;
3331       f.close();
3332     }
3333     else {
3334       QMessageBox::critical( this,
3335                              tr( "Error" ),
3336                              tr( "Can't save file %1.\nCheck path and permissions.").arg( fileName ),
3337                              QMessageBox::Ok,
3338                              QMessageBox::NoButton,
3339                              QMessageBox::NoButton );
3340     }
3341   }
3342 }
3343 // ================================================================
3344 /*!
3345  *  SALOME_InstallWizard::updateCaption
3346  *  Updates caption according to the current page number
3347  */
3348 // ================================================================
3349 void SALOME_InstallWizard::updateCaption()
3350 {
3351   QWidget* aPage = InstallWizard::currentPage();
3352   if ( !aPage )
3353     return;
3354   InstallWizard::setCaption( tr( myCaption ) + " " +
3355                              tr( getIWName() ) + " - " +
3356                              tr( "Step %1 of %2").arg( QString::number( this->indexOf( aPage )+1 ) ).arg( QString::number( this->pageCount() ) ) );
3357 }
3358
3359 // ================================================================
3360 /*!
3361  *  SALOME_InstallWizard::processValidateEvent
3362  *  Processes validation event (<val> is validation code)
3363  */
3364 // ================================================================
3365 void SALOME_InstallWizard::processValidateEvent( const int val, void* data )
3366 {
3367   QWidget* aPage = InstallWizard::currentPage();
3368   if ( aPage != productsPage ) {
3369     InstallWizard::processValidateEvent( val, data );
3370     return;
3371   }
3372   myMutex.lock();
3373   myMutex.unlock();
3374   if ( val > 0 ) {
3375   }
3376   if ( myThread->hasCommands() )
3377     myWC.wakeAll();
3378   else {
3379     WarnDialog::showWarnDlg( 0, false );
3380     InstallWizard::processValidateEvent( val, data );
3381   }
3382 }