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