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