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