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