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