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