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