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