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