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