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