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