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