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