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