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