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