]> SALOME platform Git repositories - tools/install.git/blob - src/SALOME_InstallWizard.cxx
Salome HOME
1) add possibility to install binaries of the SALOME modules into single directory;
[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   // ... 'single installation directory' check-boxes
1144   oneModDirBtn = new QMyCheckBox( tr( "Install modules to a single directory" ), productsPage );
1145   setAboutInfo( oneModDirBtn, tr( "Check this box if you want to install binaries of\nthe selected SALOME modules into a single directory" ) );
1146   oneProdDirBtn = new QMyCheckBox( tr( "Install prerequisites to a single directory" ), productsPage );
1147   setAboutInfo( oneProdDirBtn, tr( "Check this box if you want to install binaries of\nthe selected prerequisites into a single directory" ) );
1148   QFrame* split_line = new QFrame( productsPage, "split_line" );
1149   split_line->setFrameStyle( QFrame::HLine | QFrame::Sunken );
1150
1151   // layout common widgets
1152   pageLayout->addMultiCellLayout( leftBoxLayout, 0, 4, 0, 0 );
1153   pageLayout->addWidget         ( productInfo,   0,    1    );
1154   pageLayout->addLayout         ( sizeLayout,    1,    1    );
1155   pageLayout->addWidget         ( split_line,    2,    1    );
1156   pageLayout->addWidget         ( oneModDirBtn,  3,    1    );
1157   pageLayout->addWidget         ( oneProdDirBtn, 4,    1    );
1158
1159   // adding page
1160   addPage( productsPage, tr( "Choice of the products to be installed" ) );
1161
1162   // connecting signals
1163   connect( modulesView,   SIGNAL( selectionChanged() ),
1164            this, SLOT( onSelectionChanged() ) );
1165   connect( prereqsView,   SIGNAL( selectionChanged() ),
1166            this, SLOT( onSelectionChanged() ) );
1167   connect( modulesView,   SIGNAL( clicked ( QListViewItem * item ) ),
1168            this, SLOT( onSelectionChanged() ) );
1169   connect( prereqsView,   SIGNAL( clicked ( QListViewItem * item ) ),
1170            this, SLOT( onSelectionChanged() ) );
1171   connect( modulesView,   SIGNAL( itemToggled( QCheckListItem* ) ),
1172            this, SLOT( onItemToggled( QCheckListItem* ) ) );
1173   connect( prereqsView,   SIGNAL( itemToggled( QCheckListItem* ) ),
1174            this, SLOT( onItemToggled( QCheckListItem* ) ) );
1175   connect( installGuiBtn, SIGNAL( toggled( bool ) ), 
1176            this, SLOT( onInstallGuiBtn() ) );
1177   connect( moreBtn, SIGNAL( clicked() ), this, SLOT( onMoreBtn() ) );
1178   // start on default - non-advanced mode
1179   prereqsView->hide();
1180 }
1181 // ================================================================
1182 /*!
1183  *  SALOME_InstallWizard::setupCheckPage
1184  *  Creates prestart page
1185  */
1186 // ================================================================
1187 void SALOME_InstallWizard::setupCheckPage()
1188 {
1189   // create page
1190   prestartPage = new QWidget( this, "PrestartPage" );
1191   QVBoxLayout* pageLayout = new QVBoxLayout( prestartPage );
1192   pageLayout->setMargin( 0 ); pageLayout->setSpacing( 6 );
1193   // choice text view
1194   choices = new QTextEdit( prestartPage );
1195   choices->setReadOnly( true );
1196   choices->setTextFormat( RichText );
1197   choices->setUndoRedoEnabled ( false );
1198   setAboutInfo( choices, tr( "Information about the installation choice you have made" ) );
1199   choices->setPaletteBackgroundColor( prestartPage->paletteBackgroundColor() );
1200   choices->setMinimumHeight( 10 );
1201   // layouting
1202   pageLayout->addWidget( choices );
1203   pageLayout->setStretchFactor( choices, 5 );
1204   // adding page
1205   addPage( prestartPage, tr( "Check your choice" ) );
1206 }
1207 // ================================================================
1208 /*!
1209  *  SALOME_InstallWizard::setupProgressPage
1210  *  Creates progress page
1211  */
1212 // ================================================================
1213 void SALOME_InstallWizard::setupProgressPage()
1214 {
1215   // create page
1216   progressPage = new QWidget( this, "progressPage" );
1217   QGridLayout* pageLayout = new QGridLayout( progressPage );
1218   pageLayout->setMargin( 0 ); pageLayout->setSpacing( 6 );
1219   // top splitter
1220   splitter = new QSplitter( Vertical, progressPage );
1221   splitter->setOpaqueResize( true );
1222   // the parent for the widgets
1223   QWidget* widget = new QWidget( splitter );
1224   QGridLayout* layout = new QGridLayout( widget );
1225   layout->setMargin( 0 ); layout->setSpacing( 6 );
1226   // installation progress view box
1227   installInfo = new InstallInfo( widget );
1228   installInfo->setReadOnly( true );
1229   installInfo->setTextFormat( RichText );
1230   installInfo->setUndoRedoEnabled ( false );
1231   installInfo->setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Expanding ) );
1232   installInfo->setMinimumSize( 100, 10 );
1233   setAboutInfo( installInfo, tr( "Installation process output" ) );
1234   // parameters for the script
1235   parametersLab = new QLabel( tr( "Enter your answer here:" ), widget );
1236   passedParams = new QLineEdit ( widget );
1237   setAboutInfo( passedParams, tr( "Use this field to enter the answer\nfor the running script when it is necessary") );
1238   // VSR: 10/11/05 - disable answer mode ==>
1239   parametersLab->hide();
1240   passedParams->hide();
1241   // VSR: 10/11/05 - disable answer mode <==
1242   // layouting
1243   layout->addWidget( installInfo,   0, 0 );
1244   layout->addWidget( parametersLab, 1, 0 );
1245   layout->addWidget( passedParams,  2, 0 );
1246   layout->addRowSpacing( 3, 6 );
1247   // the parent for the widgets
1248   widget = new QWidget( splitter );
1249   layout = new QGridLayout( widget );
1250   layout->setMargin( 0 ); layout->setSpacing( 6 );
1251   // installation results view box
1252   QLabel* resultLab = new QLabel( tr( "Installation Status:" ), widget );
1253   progressView = new ProgressView( widget );
1254   progressView->setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Expanding ) );
1255   progressView->setMinimumSize( 100, 10 );
1256   statusLab = new QLabel( widget );
1257   statusLab->setFrameShape( QButtonGroup::LineEditPanel );
1258   setAboutInfo( progressView, tr( "Installation status on the selected products" ) );
1259   // layouting
1260   layout->addRowSpacing( 0, 6 );
1261   layout->addWidget( resultLab,    1, 0 );
1262   layout->addWidget( progressView, 2, 0 );
1263   layout->addWidget( statusLab,    3, 0 );
1264   // layouting
1265   pageLayout->addWidget( splitter,  0, 0 );
1266   // adding page
1267   addPage( progressPage, tr( "Installation progress" ) );
1268   // connect signals
1269   connect( passedParams, SIGNAL( returnPressed() ), this, SLOT( onReturnPressed() ) ) ;
1270 }
1271 // ================================================================
1272 /*!
1273  *  SALOME_InstallWizard::setupReadmePage
1274  *  Creates readme page
1275  */
1276 // ================================================================
1277 void SALOME_InstallWizard::setupReadmePage()
1278 {
1279   // create page
1280   readmePage = new QWidget( this, "readmePage" );
1281   QVBoxLayout* pageLayout = new QVBoxLayout( readmePage );
1282   pageLayout->setMargin( 0 ); pageLayout->setSpacing( 6 );
1283   // README info text box
1284   readme = new QTextEdit( readmePage );
1285   readme->setReadOnly( true );
1286   readme->setTextFormat( PlainText );
1287   readme->setFont( QFont( "Fixed", 12 ) );
1288   readme->setUndoRedoEnabled ( false );
1289   setAboutInfo( readme, tr( "README information" ) );
1290   readme->setPaletteBackgroundColor( readmePage->paletteBackgroundColor() );
1291   readme->setMinimumHeight( 10 );
1292
1293   pageLayout->addWidget( readme );
1294   pageLayout->setStretchFactor( readme, 5 );
1295
1296   // Operation buttons
1297   QHBoxLayout* hLayout = new QHBoxLayout( -1, "finishButtons" );
1298   hLayout->setMargin( 0 ); hLayout->setSpacing( 6 );
1299   hLayout->addStretch();
1300   pageLayout->addLayout( hLayout );
1301
1302   // loading README file
1303   QString readmeFile = QDir::currentDirPath() + "/README";
1304   QString text;
1305   if ( readFile( readmeFile, text ) )
1306     readme->setText( text );
1307   else
1308     readme->setText( tr( "README file has not been found" ) );
1309
1310   // adding page
1311   addPage( readmePage, tr( "Finish installation" ) );
1312 }
1313 // ================================================================
1314 /*!
1315  *  SALOME_InstallWizard::showChoiceInfo
1316  *  Displays choice info
1317  */
1318 // ================================================================
1319 void SALOME_InstallWizard::showChoiceInfo()
1320 {
1321   choices->clear();
1322
1323   long totSize, tempSize;
1324   checkSize( &totSize, &tempSize );
1325   int nbProd = 0;
1326   QString text;
1327
1328   text += tr( "Current Linux platform" )+ ": <b>" + (!curPlatform.isEmpty() ? curPlatform : QString( "Unknown" )) + "</b><br>";
1329   if ( !refPlatform.isEmpty() )
1330     text += tr( "Reference Linux platform" ) + ": <b>" + refPlatform + "</b><br>";
1331   text += "<br>";
1332
1333   text += tr( "Target directory:" ) + " <b>" + QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() ) + "</b><br>";
1334   text += tr( "Temporary directory:" ) + " <b>" + QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + "</b><br>";
1335   text += "<br>";
1336
1337   text += tr( "SALOME modules to be installed" ) + ":<ul>";
1338   QCheckListItem* item = (QCheckListItem*)( modulesView->firstChild() );
1339   while( item ) {
1340     if ( productsMap.contains( item ) ) {
1341       if ( item->isOn() ) {
1342         text += "<li><b>" + item->text() + "</b><br>";
1343         nbProd++;
1344       }
1345     }
1346     item = (QCheckListItem*)( item->nextSibling() );
1347   }
1348   if ( nbProd == 0 ) {
1349     text += "<li><b>" + tr( "none" ) + "</b><br>";
1350   }
1351   text += "</ul>";
1352   nbProd = 0;
1353   text += tr( "Prerequisites to be installed" ) + ":<ul>";
1354   item = (QCheckListItem*)( prereqsView->firstChild() );
1355   while( item ) {
1356     if ( productsMap.contains( item ) ) {
1357       if ( item->isOn() ) {
1358         text += "<li><b>" + item->text() + " " + productsMap[ item ].getVersion() + "</b><br>";
1359         nbProd++;
1360       }
1361     }
1362     item = (QCheckListItem*)( item->nextSibling() );
1363   }
1364   if ( nbProd == 0 ) {
1365     text += "<li><b>" + tr( "none" ) + "</b><br>";
1366   }
1367   text += "</ul>";
1368   text += tr( "Total disk space required:" ) + " <b>" + QString::number( totSize ) + " KB</b><br>" ;
1369   text += tr( "Space for temporary files required:" ) + " <b>" + QString::number( tempSize ) + " KB</b><br>" ;
1370   choices->setText( text );
1371 }
1372 // ================================================================
1373 /*!
1374  *  SALOME_InstallWizard::acceptData
1375  *  Validates page when <Next> button is clicked
1376  */
1377 // ================================================================
1378 bool SALOME_InstallWizard::acceptData( const QString& pageTitle )
1379 {
1380   QString tmpstr;
1381   QWidget* aPage = InstallWizard::page( pageTitle );
1382   if ( aPage == typePage ) {
1383     // installation type page
1384     warnLab3->show();
1385     this->setAppropriate( platformsPage, false );
1386     if ( installType == Binaries ) { // 'Binary' installation type
1387       // check binaries directory
1388       QFileInfo fib( QDir::cleanDirPath( getBinPath() ) );
1389       if ( !fib.exists() ) {
1390         QMessageBox::warning( this,
1391                               tr( "Warning" ),
1392                               tr( "The directory %1 doesn't exist.\n"
1393                                   "This directory must contains another one directory with binary archives for current platform.").arg( fib.absFilePath() ),
1394                               QMessageBox::Ok,
1395                               QMessageBox::NoButton, 
1396                               QMessageBox::NoButton );
1397         return false;
1398       }
1399       if ( platformsMap.find( curPlatform ) == platformsMap.end() ) {
1400         // Unknown platform case
1401         QString aMsg = warnMsg + tr( ".\nBy default the universal binary package will be installed." );
1402         aMsg += tr( "\nIf you want to select another one, please use the following list:" );
1403         warnLab->setText( aMsg );
1404         warnLab3->hide();
1405         this->setAppropriate( platformsPage, true );
1406       }
1407       else {
1408         // Supported platform case
1409         QString aPlatform = curPlatform;
1410         if ( curPlatform != getBasePlatform() ) {
1411           refPlatform = getBasePlatform();
1412           xmlFileName = platformsMap[ refPlatform ];
1413           aPlatform = getPlatform();
1414         }
1415         QFileInfo fibp( QDir::cleanDirPath( getBinPath() + "/" + aPlatform ) );
1416         if ( !fibp.isDir() ) {
1417           warnLab->setText( tr( "Binaries are absent for current platform." ) );
1418           this->setAppropriate( platformsPage, true );
1419         }
1420       }
1421
1422       // check sources directory
1423       QFileInfo fis( QDir::cleanDirPath( getSrcPath() ) );
1424       if ( !fis.exists() )
1425         if ( QMessageBox::warning( this,
1426                                    tr( "Warning" ),
1427                                    tr( "The directory %1 doesn't exist.\n"
1428                                        "This directory must contains sources archives.\n"
1429                                        "Continue?" ).arg( fis.absFilePath() ),
1430                                    tr( "&Yes" ),
1431                                    tr( "&No" ), 
1432                                    QString::null, 1, 1 ) == 1 )
1433           return false;
1434     }
1435     else { // 'Source' or 'Compile' installation type
1436       // check sources directory
1437       QFileInfo fis( QDir::cleanDirPath( getSrcPath() ) );
1438       if ( !fis.exists() ) {
1439         QMessageBox::warning( this,
1440                               tr( "Warning" ),
1441                               tr( "The directory %1 doesn't exist.\n"
1442                                   "This directory must contains sources archives.\n" ).arg( fis.absFilePath() ),
1443                               QMessageBox::Ok,
1444                               QMessageBox::NoButton, 
1445                               QMessageBox::NoButton );
1446         return false;
1447       }
1448       if ( platformsMap.find( curPlatform ) == platformsMap.end() ) {
1449         QString aMsg = warnMsg + ".";
1450         if ( installType == Compile )
1451           aMsg = warnMsg + tr( " and compilation is not tested on this one." );
1452         warnLab->setText( aMsg );
1453         this->setAppropriate( platformsPage, true );
1454       }
1455     }
1456   }
1457
1458   else if ( aPage == platformsPage ) {
1459     // installation platform page
1460     if ( platBtnGrp->id( platBtnGrp->selected() ) == -1 ) {
1461       QMessageBox::warning( this,
1462                             tr( "Warning" ),
1463                             tr( "Select installation platform before" ),
1464                             QMessageBox::Ok,
1465                             QMessageBox::NoButton,
1466                             QMessageBox::NoButton );
1467       return false;
1468     }
1469   }
1470
1471   else if ( aPage == dirPage ) {
1472     // installation directory page
1473     // ########## check target and temp directories (existence and available disk space)
1474     // get dirs
1475     QString targetDir = QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() );
1476     QString tempDir   = QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() );
1477     // check target directory
1478     if ( targetDir.isEmpty() ) {
1479       QMessageBox::warning( this,
1480                             tr( "Warning" ),
1481                             tr( "Please, enter valid target directory path" ),
1482                             QMessageBox::Ok,
1483                             QMessageBox::NoButton,
1484                             QMessageBox::NoButton );
1485       return false;
1486     }
1487     QFileInfo fi( QDir::cleanDirPath( targetDir ) );
1488     if ( !fi.exists() ) {
1489       bool toCreate =
1490         QMessageBox::warning( this,
1491                               tr( "Warning" ),
1492                               tr( "The directory %1 doesn't exist.\n"
1493                                   "Create directory?" ).arg( fi.absFilePath() ),
1494                               QMessageBox::Yes,
1495                               QMessageBox::No,
1496                               QMessageBox::NoButton ) == QMessageBox::Yes;
1497       if ( !toCreate)
1498         return false;
1499       if ( !makeDir( fi.absFilePath(), tmpstr ) ) {
1500         QMessageBox::critical( this,
1501                                tr( "Error" ),
1502                                tr( "Can't create the directory\n%1").arg( fi.absFilePath() ),
1503                                QMessageBox::Ok,
1504                                QMessageBox::NoButton,
1505                                QMessageBox::NoButton );
1506         return false;
1507       }
1508     }
1509     if ( !fi.isDir() ) {
1510       QMessageBox::warning( this,
1511                             tr( "Warning" ),
1512                             tr( "%1 is not a directory.\n"
1513                                 "Please, enter valid target directory path" ).arg( fi.absFilePath() ),
1514                             QMessageBox::Ok,
1515                             QMessageBox::NoButton,
1516                             QMessageBox::NoButton );
1517       return false;
1518     }
1519     if ( !fi.isWritable() ) {
1520       QMessageBox::warning( this,
1521                             tr( "Warning" ),
1522                             tr( "The directory %1 is not writable.\n"
1523                                 "Please, enter valid target directory path or change permissions" ).arg( fi.absFilePath() ),
1524                             QMessageBox::Ok,
1525                             QMessageBox::NoButton,
1526                             QMessageBox::NoButton );
1527       return false;
1528     }
1529     if ( hasSpace( fi.absFilePath() ) &&
1530          QMessageBox::warning( this,
1531                                tr( "Warning" ),
1532                                tr( "The target directory contains space symbols.\n"
1533                                    "This may cause problems with compiling or installing of products.\n\n"
1534                                    "Do you want to continue?"),
1535                                QMessageBox::Yes,
1536                                QMessageBox::No,
1537                                QMessageBox::NoButton ) == QMessageBox::No ) {
1538       return false;
1539     }
1540     // check temp directory
1541     if ( tempDir.isEmpty() ) {
1542       QMessageBox::warning( this,
1543                             tr( "Warning" ),
1544                             tr( "Please, enter valid temporary directory path" ),
1545                             QMessageBox::Ok,
1546                             QMessageBox::NoButton,
1547                             QMessageBox::NoButton );
1548       return false;
1549     }
1550     QFileInfo fit( QDir::cleanDirPath( tempDir ) );
1551     if ( !makeDir( fit.absFilePath() + TEMPDIRNAME, tmpCreated ) ) {
1552       QMessageBox::critical( this,
1553                              tr( "Error" ),
1554                              tr( "Can't use temporary directory.\nCheck permissions for the %1 directory.").arg( fit.absFilePath() ),
1555                              QMessageBox::Ok,
1556                              QMessageBox::NoButton,
1557                              QMessageBox::NoButton );
1558       return false;
1559     }
1560   }
1561
1562   else if ( aPage == productsPage ) {
1563     // products page
1564     // ########## check if any products are selected to be installed
1565     long totSize, tempSize;
1566     bool anySelected = checkSize( &totSize, &tempSize );
1567     if ( installType == Compile && removeSrcBtn->isOn() ) {
1568       totSize += tempSize;
1569     }
1570     if ( !anySelected ) {
1571       QMessageBox::warning( this,
1572                             tr( "Warning" ),
1573                             tr( "Select one or more products to install" ),
1574                             QMessageBox::Ok,
1575                             QMessageBox::NoButton,
1576                             QMessageBox::NoButton );
1577       return false;
1578     }
1579     // run script that checks available disk space for installing of products    // returns 1 in case of error
1580     QFileInfo fi( QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() ) );
1581     QString script = "./config_files/checkSize.sh '";
1582     script += fi.absFilePath();
1583     script += "' ";
1584     script += QString( "%1" ).arg( totSize );
1585     ___MESSAGE___( "script = " << script.latin1() );
1586     if ( system( script ) ) {
1587       QMessageBox::critical( this,
1588                              tr( "Out of space" ),
1589                              tr( "There is no available disk space for installing of selected products" ),
1590                              QMessageBox::Ok,
1591                              QMessageBox::NoButton,
1592                              QMessageBox::NoButton );
1593       return false;
1594     }
1595     // AKL: 13/08/07 - skip tmp disk space checking (all files are unpacked into installation directory) ==>
1596     /*
1597     // run script that check available disk space for temporary files
1598     // returns 1 in case of error
1599     QFileInfo fit( QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) );
1600     QString tscript = "./config_files/checkSize.sh '";
1601     tscript += fit.absFilePath();
1602     tscript += "' ";
1603     tscript += QString( "%1" ).arg( tempSize );
1604     ___MESSAGE___( "script = " << tscript.latin1() );
1605     if ( system( tscript ) ) {
1606       QMessageBox::critical( this,
1607                              tr( "Out of space" ),
1608                              tr( "There is no available disk space for the temporary files" ),
1609                              QMessageBox::Ok,
1610                              QMessageBox::NoButton,
1611                              QMessageBox::NoButton );
1612       return false;
1613       }
1614     */
1615     // AKL: 13/08/07 - skip tmp disk space checking (all files are unpacked into installation directory) <==
1616
1617     // ########## check installation scripts
1618     QCheckListItem* item;
1619     ProductsView* prodsView = modulesView;
1620     for ( int i = 0; i < 2; i++ ) {
1621       item = (QCheckListItem*)( prodsView->firstChild() );
1622       while( item ) {
1623         if ( productsMap.contains( item ) && item->isOn() ) {
1624           // check installation script definition
1625           if ( item->text(2).isEmpty() || item->text(2).isNull() ) {
1626             QMessageBox::warning( this,
1627                                   tr( "Error" ),
1628                                   tr( "The installation script for %1 is not defined.").arg(item->text(0)),
1629                                   QMessageBox::Ok,
1630                                   QMessageBox::NoButton,
1631                                   QMessageBox::NoButton );
1632             if ( !moreMode ) onMoreBtn();
1633             QListView* listView = item->listView();
1634             listView->setCurrentItem( item );
1635             listView->setSelected( item, true );
1636             listView->ensureItemVisible( item );
1637             return false;
1638           }
1639           // check installation script existence
1640           else {
1641             QFileInfo fi( QString("./config_files/") + item->text(2) );
1642             if ( !fi.exists() || !fi.isExecutable() ) {
1643               QMessageBox::warning( this,
1644                                     tr( "Error" ),
1645                                     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)),
1646                                     QMessageBox::Ok,
1647                                     QMessageBox::NoButton,
1648                                     QMessageBox::NoButton );
1649               if ( !moreMode ) onMoreBtn();
1650               QListView* listView = item->listView();
1651               listView->setCurrentItem( item );
1652               listView->setSelected( item, true );
1653               listView->ensureItemVisible( item );
1654               return false;
1655             }
1656           }
1657           // check installation scripts dependencies
1658           QStringList dependOn = productsMap[ item ].getDependancies();
1659           QString version = productsMap[ item ].getVersion();
1660           for ( int i = 0; i < (int)dependOn.count(); i++ ) {
1661             QCheckListItem* depitem = findItem( dependOn[ i ] );
1662             if ( !depitem ) {
1663               QMessageBox::warning( this,
1664                                     tr( "Error" ),
1665                                     tr( "%1 is required for %2 %3 installation.\n"
1666                                         "This product is missing in the configuration file %4.").arg(dependOn[ i ]).arg(item->text(0)).arg(version).arg(xmlFileName),
1667                                     QMessageBox::Ok,
1668                                     QMessageBox::NoButton,
1669                                     QMessageBox::NoButton );
1670               return false;
1671             }
1672           }
1673         }
1674         item = (QCheckListItem*)( item->nextSibling() );
1675       }
1676       prodsView = prereqsView;
1677     }
1678 //     return true; // return in order to avoid default postValidateEvent() action
1679   }
1680   return InstallWizard::acceptData( pageTitle );
1681 }
1682 // ================================================================
1683 /*!
1684  *  SALOME_InstallWizard::checkSize
1685  *  Calculates disk space required for the installation
1686  */
1687 // ================================================================
1688 bool SALOME_InstallWizard::checkSize( long* totSize, long* tempSize )
1689 {
1690   long tots = 0, temps = 0;
1691   long maxSrcTmp = 0;
1692   int nbSelected = 0;
1693
1694   MapProducts::Iterator mapIter;
1695   for ( mapIter = productsMap.begin(); mapIter != productsMap.end(); ++mapIter ) {
1696     QCheckListItem* item = mapIter.key();
1697     Dependancies dep = mapIter.data();
1698     if ( !item->isOn() )
1699       continue;
1700     tots += ( QStringList::split( " ", item->text(1) )[0] ).toLong();
1701     maxSrcTmp = max( maxSrcTmp, dep.getSize( Compile ) - dep.getSize( Binaries ) );
1702     temps += dep.getTempSize( installType );
1703     nbSelected++;
1704   }
1705
1706   if ( totSize )
1707     if ( installType == Compile && removeSrcBtn->isOn() )
1708       temps += maxSrcTmp;
1709     *totSize = tots;
1710   if ( tempSize )
1711     *tempSize = temps;
1712   return ( nbSelected > 0 );
1713 }
1714 // ================================================================
1715 /*!
1716  *  SALOME_InstallWizard::updateAvailableSpace
1717  *  Slot to update 'Available disk space' field
1718  */
1719 // ================================================================
1720 void SALOME_InstallWizard::updateAvailableSpace()
1721 {
1722   if ( diskSpaceProc->normalExit() )
1723     availableSize->setText( diskSpaceProc->readLineStdout() + " KB");
1724 }
1725 // ================================================================
1726 /*!
1727  *  SALOME_InstallWizard::checkFLibResult
1728  *  Slot to take result of Fortran libraries checking
1729  */
1730 // ================================================================
1731 void SALOME_InstallWizard::checkFLibResult()
1732 {
1733   if ( checkFLibProc->normalExit() && checkFLibProc->exitStatus() == 1 ) {
1734     QStringList notFoundLibsList;
1735     QString record = "";
1736     while ( checkFLibProc->canReadLineStdout() ) {
1737       record = checkFLibProc->readLineStdout();
1738       if ( !record.isEmpty() && !notFoundLibsList.contains( record ) )
1739         notFoundLibsList.append( record );
1740     }
1741     QMessageBox::warning( this,
1742                           tr( "Warning" ),
1743                           tr( "The following libraries are absent on current system:\n"
1744                           "%1").arg( notFoundLibsList.join( "\n" ) ),
1745                           QMessageBox::Ok,
1746                           QMessageBox::NoButton,
1747                           QMessageBox::NoButton );
1748   }
1749   // Update GUI and check installation errors
1750   completeInstallation();
1751 }
1752 // ================================================================
1753 /*!
1754  *  SALOME_InstallWizard::updateSizeColumn
1755  *  Sets required size for each product according to 
1756  *  installation type and 'Remove SRC & TMP' checkbox state
1757  */
1758 // ================================================================
1759 void SALOME_InstallWizard::updateSizeColumn()
1760 {
1761   long prodSize = 0;
1762   bool removeSrc = removeSrcBtn->isChecked();
1763   MapProducts::Iterator mapIter;
1764   for ( mapIter = productsMap.begin(); mapIter != productsMap.end(); ++mapIter ) {
1765     QCheckListItem* item = mapIter.key();
1766     Dependancies dep = mapIter.data();
1767     // get required size for current product
1768     long binSize = dep.getSize( Binaries );
1769     long srcSize = dep.getSize( Sources );
1770     long bldSize = dep.getSize( Compile );
1771     InstallationType instType = getInstType();
1772     if ( instType == Binaries ) {
1773       if ( dep.getType() == "component" )
1774         prodSize = binSize + srcSize;
1775       else
1776         prodSize = ( binSize != 0 ? binSize : srcSize );
1777     }
1778     else if ( instType == Sources )
1779       prodSize = srcSize;
1780     else
1781       if ( removeSrc )
1782         prodSize = ( binSize != 0 ? binSize : srcSize );
1783       else {
1784         prodSize = ( bldSize != 0 ? bldSize : srcSize );
1785       }
1786     // fill in 'Size' field
1787     item->setText( 1, QString::number( prodSize )+" KB" );
1788   }
1789 }
1790 // ================================================================
1791 /*!
1792  *  SALOME_InstallWizard::checkProductPage
1793  *  Checks products page validity (directories and products selection) and
1794  *  enabled/disables "Next" button for the Products page
1795  */
1796 // ================================================================
1797 void SALOME_InstallWizard::checkProductPage()
1798 {
1799   if ( this->currentPage() != productsPage )
1800     return;
1801   long tots = 0, temps = 0;
1802   // check if any product is selected;
1803   bool isAnyProductSelected = checkSize( &tots, &temps );
1804
1805   // update required size information
1806   requiredSize->setText( QString::number( tots )  + " KB");
1807   requiredTemp->setText( QString::number( temps ) + " KB");
1808
1809   // update available size information
1810   QFileInfo fi( QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() ) );
1811   if ( fi.exists() ) {
1812     diskSpaceProc->clearArguments();
1813     QString script = "./config_files/diskSpace.sh";
1814     diskSpaceProc->addArgument( script );
1815     diskSpaceProc->addArgument( fi.absFilePath() );
1816     // run script
1817     diskSpaceProc->start();
1818   }
1819
1820   // enable/disable "Next" button
1821   setNextEnabled( productsPage, isAnyProductSelected );
1822 }
1823 // ================================================================
1824 /*!
1825  *  SALOME_InstallWizard::setPrerequisites
1826  *  Sets the product and all products this one depends on to be checked ( recursively )
1827  */
1828 // ================================================================
1829 void SALOME_InstallWizard::setPrerequisites( QCheckListItem* item )
1830 {
1831   if ( !productsMap.contains( item ) )
1832     return;
1833   if ( !item->isOn() )
1834     return;
1835   // get all prerequisites
1836   QStringList dependOn = productsMap[ item ].getDependancies();
1837   // install MED without GUI case
1838   if ( installGuiBtn->state() != QButton::On && item->text(0) == "MED" ) {
1839     dependOn.remove( "GUI" );
1840   }
1841   // setting prerequisites
1842   for ( int i = 0; i < (int)dependOn.count(); i++ ) {
1843     MapProducts::Iterator itProd;
1844     for ( itProd = productsMap.begin(); itProd != productsMap.end(); ++itProd ) {
1845       if ( itProd.data().getName() == dependOn[ i ] ) {
1846         if ( itProd.data().getType() == "component" && !itProd.key()->isOn() )
1847           itProd.key()->setOn( true );
1848         else if ( itProd.data().getType() == "prerequisite" ) {
1849           itProd.key()->setOn( true );
1850           itProd.key()->setEnabled( false );
1851         }
1852       }
1853     }
1854   }
1855 }
1856 // ================================================================
1857 /*!
1858  *  SALOME_InstallWizard::unsetPrerequisites
1859  *  Unsets all modules which depend of the unchecked product ( recursively )
1860  */
1861 // ================================================================
1862 void SALOME_InstallWizard::unsetPrerequisites( QCheckListItem* item )
1863 {
1864   if ( !productsMap.contains( item ) )
1865     return;
1866   if ( item->isOn() )
1867     return;
1868
1869 // uncheck dependent products
1870   QString itemName = productsMap[ item ].getName();
1871   MapProducts::Iterator itProd;
1872   for ( itProd = productsMap.begin(); itProd != productsMap.end(); ++itProd ) {
1873     if ( itProd.data().getType() == productsMap[ item ].getType() ) {
1874       QStringList dependOn = itProd.data().getDependancies();
1875       // install MED without GUI case
1876       if ( installGuiBtn->state() != QButton::On && itemName == "GUI" ) {
1877         dependOn.remove( "MED" );
1878       }
1879       for ( int i = 0; i < (int)dependOn.count(); i++ ) {
1880         if ( dependOn[ i ] == itemName ) {
1881           if ( itProd.key()->isOn() ) {
1882             itProd.key()->setOn( false );
1883           }
1884         }
1885       }
1886     }
1887   }
1888
1889 // uncheck prerequisites
1890   int nbDependents;
1891 //   cout << "item name = " << productsMap[ item ].getName() << endl;
1892   QStringList dependOnList = productsMap[ item ].getDependancies();
1893   for ( int j = 0; j < (int)dependOnList.count(); j++ ) {
1894     nbDependents = 0;
1895     MapProducts::Iterator itProd1;
1896     for ( itProd1 = productsMap.begin(); itProd1 != productsMap.end(); ++itProd1 ) {
1897       if ( itProd1.data().getName() == dependOnList[ j ] ) {
1898         if ( itProd1.data().getType() == "prerequisite" ) {
1899           MapProducts::Iterator itProd2;
1900           for ( itProd2 = productsMap.begin(); itProd2 != productsMap.end(); ++itProd2 ) {
1901             if ( itProd2.key()->isOn() ) {
1902               QStringList prereqsList = productsMap[ itProd2.key() ].getDependancies();
1903               for ( int k = 0; k < (int)prereqsList.count(); k++ ) {
1904                 if ( prereqsList[ k ] == itProd1.data().getName() ) {
1905                   nbDependents++;
1906                 }
1907               }
1908             }
1909           }
1910           if ( nbDependents == 0 ) {
1911             itProd1.key()->setEnabled( true );
1912             itProd1.key()->setOn( false );
1913           }
1914         }
1915       }
1916     }
1917   }
1918 }
1919 // ================================================================
1920 /*!
1921  *  SALOME_InstallWizard::launchScript
1922  *  Runs installation script
1923  */
1924 // ================================================================
1925 void SALOME_InstallWizard::launchScript()
1926 {
1927   // try to find product being processed now
1928   QString prodProc = progressView->findStatus( Processing );
1929   if ( !prodProc.isNull() ) {
1930     ___MESSAGE___( "Found <Processing>: " );
1931
1932     // if found - set status to "completed"
1933     progressView->setStatus( prodProc, Completed );
1934     // ... clear status label
1935     statusLab->clear();
1936     // ... and call this method again
1937     launchScript();
1938     return;
1939   }
1940   // else try to find next product which is not processed yet
1941   prodProc = progressView->findStatus( Waiting );
1942   if ( !prodProc.isNull() ) {
1943     ___MESSAGE___( "Found <Waiting>: " << prodProc.latin1() );
1944     // if found - set status to "processed" and run script
1945     progressView->setStatus( prodProc, Processing );
1946     progressView->ensureVisible( prodProc );
1947     
1948     QCheckListItem* item;
1949     // fill in script parameters
1950     shellProcess->clearArguments();
1951     // ... script name
1952     shellProcess->setWorkingDirectory( QDir::cleanDirPath( QFileInfo( "./config_files/" ).absFilePath() ) );
1953     if ( !extraProducts.contains( prodProc ) ) {
1954       item = findItem( prodProc );
1955       shellProcess->addArgument( item->text(2) );
1956     }
1957     else
1958       shellProcess->addArgument( extraProducts[ prodProc ] );
1959
1960     // ... get folder with binaries
1961     QString binDir = QDir::cleanDirPath( getBinPath() );
1962     QString OS = getPlatform();
1963     if ( refPlatform.isEmpty() && singleBinPlts.contains(curPlatform) == 0 )
1964       OS = commonPlatform;
1965     binDir += "/" + OS;
1966     // ... temp folder
1967     QString tmpFolder = QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + TEMPDIRNAME;
1968     //if( !tempFolder->isEnabled() )
1969     //  tmpFolder = "/tmp";
1970
1971     // ... not install : try to find preinstalled
1972     if ( notInstall.contains( prodProc ) || prodProc == "gcc" ) {
1973       shellProcess->addArgument( "try_preinstalled" );
1974       shellProcess->addArgument( QFileInfo( tmpFolder ).absFilePath() );
1975       shellProcess->addArgument( QDir::currentDirPath() + "/Products" );
1976       statusLab->setText( tr( "Collecting environment for '" ) + prodProc + "'..." );
1977     }
1978     // ... binaries ?
1979     else if ( installType == Binaries ) {
1980       shellProcess->addArgument( "install_binary" );
1981       shellProcess->addArgument( QFileInfo( tmpFolder ).absFilePath() );
1982       shellProcess->addArgument( binDir );
1983       statusLab->setText( tr( "Installing '" ) + prodProc + "'..." );
1984     }
1985     // ... sources or sources_and_compilation ?
1986     else {
1987       shellProcess->addArgument( installType == Sources ? "install_source" : 
1988                                  "install_source_and_build" );
1989       shellProcess->addArgument( QFileInfo( tmpFolder ).absFilePath() );
1990       shellProcess->addArgument( QDir::cleanDirPath( getSrcPath() ) );
1991       statusLab->setText( tr( "Installing '" ) + prodProc + "'..." );
1992     }
1993     // ... target folder
1994     QString tgtFolder = QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() );
1995     shellProcess->addArgument( QFileInfo( tgtFolder ).absFilePath() );
1996     // ... list of all products
1997     QString depproducts = DefineDependeces(productsMap);
1998     depproducts.prepend( QStringList( extraProducts.keys() ).join(" ") + " " );
1999     ___MESSAGE___( "Dependancies"<< depproducts.latin1() );
2000     shellProcess->addArgument( depproducts );
2001     // ... product name - currently installed product
2002     if ( !extraProducts.contains( prodProc ) )
2003       shellProcess->addArgument( item->text(0) );
2004     else
2005       shellProcess->addArgument( prodProc );
2006     // ... list of products being installed
2007     shellProcess->addArgument( prodSequence.join( " " ) );
2008     // ... sources directory
2009     shellProcess->addArgument( QDir::cleanDirPath( getSrcPath() ) );
2010     // ... remove sources and tmp files or not?
2011     if ( installType == Compile && removeSrcBtn->isOn() )
2012       shellProcess->addArgument( "TRUE" );
2013     else 
2014       shellProcess->addArgument( "FALSE" );
2015     // ... binaries directory
2016     shellProcess->addArgument( binDir );
2017     // ... install MED with GUI or not?
2018     if ( prodProc == "MED" ) {
2019       if ( installGuiBtn->state() != QButton::On && prodProc == "MED" )
2020         shellProcess->addArgument( "FALSE" );
2021       else
2022         shellProcess->addArgument( "TRUE" );
2023     }
2024     // ... single installation directory for SALOME modules, if this option was selected
2025     if ( oneModDirBtn->isChecked() ) {
2026       MapProducts::Iterator mapIter;
2027       for ( mapIter = productsMap.begin(); mapIter != productsMap.end(); ++mapIter )
2028         if ( mapIter.data().getName() == prodProc && mapIter.data().getType() == "component" )
2029           shellProcess->addArgument( "SALOME" );
2030     }
2031     // ... single installation directory for prerequisites, if this option was selected
2032     if ( oneProdDirBtn->isChecked() ) {
2033       if ( prodProc == "DebianLibsForSalome" )
2034         shellProcess->addArgument( "PRODUCTS" );
2035       else {
2036         MapProducts::Iterator mapIter;
2037         for ( mapIter = productsMap.begin(); mapIter != productsMap.end(); ++mapIter )
2038           if ( mapIter.data().getName() == prodProc && mapIter.data().getType() == "prerequisite" )
2039             shellProcess->addArgument( "PRODUCTS" );
2040       }
2041     }
2042     
2043     // run script
2044     if ( !shellProcess->start() ) {
2045       // error handling can be here
2046       ___MESSAGE___( "error" );
2047     }
2048     return;
2049   }
2050   ___MESSAGE___( "All products have been installed successfully" );
2051   // all products are installed successfully
2052   MapProducts::Iterator mapIter;
2053   ___MESSAGE___( "starting pick-up environment" );
2054   QString depproducts = QUOTE( DefineDependeces(productsMap).prepend( QStringList( extraProducts.keys() ).join(" ") + " " ) );
2055   for ( mapIter = productsMap.begin(); mapIter != productsMap.end(); ++mapIter ) {
2056     QCheckListItem* item = mapIter.key();
2057     Dependancies dep = mapIter.data();
2058     if ( item->isOn() && dep.pickUpEnvironment() ) {
2059       statusLab->setText( tr( "Pick-up products environment for " ) + dep.getName().latin1() + "..." );
2060       ___MESSAGE___( "... for " << dep.getName().latin1() );
2061       QString script;
2062       script += "cd " + QUOTE( QFileInfo( QDir::cleanDirPath( "./config_files/" ) ).absFilePath() ) + "; ";
2063       script += item->text(2) + " ";
2064       script += "pickup_env ";
2065       script += QUOTE( QFileInfo( QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + TEMPDIRNAME ).absFilePath() ) + " ";
2066       script += QUOTE( QFileInfo( QDir::cleanDirPath( QDir::currentDirPath() + "/Products" ) ).absFilePath() ) + " ";
2067       script += QUOTE( QFileInfo( QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() ) ).absFilePath() ) + " ";
2068       script += depproducts + " ";
2069       script += item->text(0) + " ";
2070       script += QUOTE( prodSequence.join( " " ) );
2071       ___MESSAGE___( "... --> " << script.latin1() );
2072       if ( system( script.latin1() ) ) {
2073         ___MESSAGE___( "ERROR" );
2074       }
2075     }
2076   }
2077   
2078   if ( installType == Binaries ) {
2079     // Check Fortran libraries
2080     // ... update status label
2081     statusLab->setText( tr( "Check Fortran libraries..." ) );
2082     // ... search "not found" libraries
2083     checkFLibProc->setWorkingDirectory( QDir::cleanDirPath( QFileInfo( "./config_files/" ).absFilePath() ) );
2084     checkFLibProc->addArgument( "checkFortran.sh" );
2085     checkFLibProc->addArgument( "find_libraries" );
2086     checkFLibProc->addArgument( QDir::cleanDirPath( QFileInfo( targetFolder->text().stripWhiteSpace() ).absFilePath() ) );
2087     // ... run script
2088     if ( !checkFLibProc->start() ) {
2089       ___MESSAGE___( "Error: process could not start!" );
2090     }
2091   }
2092   else
2093     // Update GUI and check installation errors
2094     completeInstallation();
2095   
2096 }
2097 // ================================================================
2098 /*!
2099  *  SALOME_InstallWizard::completeInstallation
2100  *  Update GUI and check installation errors
2101  */
2102 // ================================================================
2103 void SALOME_InstallWizard::completeInstallation()
2104 {
2105   // update status label
2106   statusLab->setText( tr( "Installation completed" ) );
2107   // <Next> button
2108   setNextEnabled( true );
2109   nextButton()->setText( tr( "&Next >" ) );
2110   setAboutInfo( nextButton(), tr( "Move to the next step of the installation procedure" ) );
2111   disconnect( this, SIGNAL( nextClicked() ), this, SLOT( next() ) );
2112   disconnect( this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
2113   connect(    this, SIGNAL( nextClicked() ), this, SLOT( next() ) );
2114   // <Back> button
2115   setBackEnabled( true );
2116   // script parameters
2117   passedParams->clear();
2118   passedParams->setEnabled( false );
2119   QFont f = parametersLab->font(); f.setBold( false ); parametersLab->setFont( f );
2120   installInfo->setFinished( true );
2121   if ( isMinimized() )
2122     showNormal();
2123   raise();
2124   if ( hasErrors ) {
2125     if ( QMessageBox::warning( this,
2126                                tr( "Warning" ),
2127                                tr( "There were some errors and/or warnings during the installation.\n"
2128                                    "Do you want to save the installation log?" ),
2129                                tr( "&Save" ),
2130                                tr( "&Cancel" ),
2131                                QString::null,
2132                                0,
2133                                1 ) == 0 )
2134       saveLog();
2135   }
2136   hasErrors = false;
2137
2138 }
2139 // ================================================================
2140 /*!
2141  *  SALOME_InstallWizard::onInstallGuiBtn
2142  *  <Installation with GUI> check-box slot
2143  */
2144 // ================================================================
2145 void SALOME_InstallWizard::onInstallGuiBtn()
2146 {
2147   MapProducts::Iterator itProd;
2148   for ( itProd = productsMap.begin(); itProd != productsMap.end(); ++itProd ) {
2149     if ( itProd.data().getType() == "component" ) {
2150       if ( installGuiBtn->state() == QButton::On ) {
2151         itProd.key()->setEnabled( true );
2152         itProd.key()->setOn( true );
2153       }
2154       else {
2155         QString itemName = itProd.data().getName();
2156         if ( itemName != "KERNEL" && itemName != "MED" && 
2157              itemName != "SAMPLES" && itemName != "DOCUMENTATION" ) {
2158           itProd.key()->setOn( false );
2159           itProd.key()->setEnabled( false );
2160         }
2161         else
2162           itProd.key()->setOn( true );
2163       }
2164     }
2165   }
2166 }
2167 // ================================================================
2168 /*!
2169  *  SALOME_InstallWizard::onMoreBtn
2170  *  <More...> button slot
2171  */
2172 // ================================================================
2173 void SALOME_InstallWizard::onMoreBtn()
2174 {
2175   if ( moreMode ) {
2176     prereqsView->hide();
2177     moreBtn->setText( tr( "Show prerequisites..." ) );
2178     setAboutInfo( moreBtn, tr( "Show list of prerequisites" ) );
2179   }
2180   else {
2181     prereqsView->show();
2182     moreBtn->setText( tr( "Hide prerequisites" ) );
2183     setAboutInfo( moreBtn, tr( "Hide list of prerequisites" ) );
2184   }
2185   qApp->processEvents();
2186   moreMode = !moreMode;
2187   InstallWizard::layOut();
2188   qApp->processEvents();
2189   if ( !isMaximized() ) {
2190     qApp->processEvents();
2191   }
2192   checkProductPage();
2193 }
2194 // ================================================================
2195 /*!
2196  *  SALOME_InstallWizard::onFinishButton
2197  *  Operation buttons slot
2198  */
2199 // ================================================================
2200 void SALOME_InstallWizard::onFinishButton()
2201 {
2202   const QObject* btn = sender();
2203   ButtonList::Iterator it;
2204   for ( it = buttons.begin(); it != buttons.end(); ++it ) {
2205     if ( (*it).button() && (*it).button() == btn ) {
2206       QString script;
2207       script += "( cd " + QUOTE( QFileInfo( QDir::cleanDirPath( "./config_files/" ) ).absFilePath() ) + "; ";
2208       script +=  + (*it).script();
2209       script += " execute ";
2210       script += QUOTE( QFileInfo( QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() ) ).absFilePath() ) + " ";
2211       script += QUOTE( QFileInfo( QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + TEMPDIRNAME ).absFilePath() ) + " ";
2212       script += " > /dev/null )";
2213       ___MESSAGE___( "script: " << script.latin1() );
2214       if ( (*it).script().isEmpty() || system( script.latin1() ) ) {
2215         QMessageBox::warning( this,
2216                               tr( "Error" ),
2217                               tr( "Can't perform action!"),
2218                               QMessageBox::Ok,
2219                               QMessageBox::NoButton,
2220                               QMessageBox::NoButton );
2221       }
2222       return;
2223     }
2224   }
2225 }
2226 // ================================================================
2227 /*!
2228  *  SALOME_InstallWizard::onAbout
2229  *  <About> button slot: shows <About> dialog box
2230  */
2231 // ================================================================
2232 void SALOME_InstallWizard::onAbout()
2233 {
2234   AboutDlg d( this );
2235   d.exec();
2236 }
2237
2238 // ================================================================
2239 /*!
2240  *  SALOME_InstallWizard::findItem
2241  *  Searches product listview item with given symbolic name
2242  */
2243 // ================================================================
2244 QCheckListItem* SALOME_InstallWizard::findItem( const QString& sName )
2245 {
2246   MapProducts::Iterator mapIter;
2247   for ( mapIter = productsMap.begin(); mapIter != productsMap.end(); ++mapIter ) {
2248     if ( mapIter.data().getName() == sName )
2249       return mapIter.key();
2250   }
2251   return 0;
2252 }
2253 // ================================================================
2254 /*!
2255  *  SALOME_InstallWizard::abort
2256  *  Sets progress state to Aborted
2257  */
2258 // ================================================================
2259 void SALOME_InstallWizard::abort()
2260 {
2261   QString prod = progressView->findStatus( Processing );
2262   while ( !prod.isNull() ) {
2263     progressView->setStatus( prod, Aborted );
2264     prod = progressView->findStatus( Processing );
2265   }
2266   prod = progressView->findStatus( Waiting );
2267   while ( !prod.isNull() ) {
2268     progressView->setStatus( prod, Aborted );
2269     prod = progressView->findStatus( Waiting );
2270   }
2271 }
2272 // ================================================================
2273 /*!
2274  *  SALOME_InstallWizard::reject
2275  *  Reject slot, clears temporary directory and closes application
2276  */
2277 // ================================================================
2278 void SALOME_InstallWizard::reject()
2279 {
2280   ___MESSAGE___( "REJECTED" );
2281   if ( !exitConfirmed ) {
2282     if ( QMessageBox::information( this,
2283                                    tr( "Exit" ),
2284                                    tr( "Do you want to quit %1?" ).arg( getIWName() ),
2285                                    tr( "&Yes" ),
2286                                    tr( "&No" ),
2287                                    QString::null,
2288                                    0,
2289                                    1 ) == 1 ) {
2290       return;
2291     }
2292     exitConfirmed = true;
2293   }
2294   clean(true);
2295   InstallWizard::reject();
2296 }
2297 // ================================================================
2298 /*!
2299  *  SALOME_InstallWizard::accept
2300  *  Accept slot, clears temporary directory and closes application
2301  */
2302 // ================================================================
2303 void SALOME_InstallWizard::accept()
2304 {
2305   ___MESSAGE___( "ACCEPTED" );
2306   clean(true);
2307   InstallWizard::accept();
2308 }
2309 // ================================================================
2310 /*!
2311  *  SALOME_InstallWizard::clean
2312  *  Clears and (optionally) removes temporary directory
2313  */
2314 // ================================================================
2315 void SALOME_InstallWizard::clean(bool rmDir)
2316 {
2317   WarnDialog::showWarnDlg( 0, false );
2318   myThread->clearCommands();
2319   myWC.wakeAll();
2320   while ( myThread->running() );
2321   // first remove temporary files
2322   QString script = "cd ./config_files/; remove_tmp.sh '";
2323   script += tempFolder->text().stripWhiteSpace() + TEMPDIRNAME;
2324   script += "' ";
2325   script += QUOTE(DefineDependeces(productsMap));
2326   script += " > /dev/null";
2327   ___MESSAGE___( "script = " << script.latin1() );
2328   if ( system( script.latin1() ) ) {
2329   }
2330   // then try to remove created temporary directory
2331   //script = "rm -rf " + QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + TEMPDIRNAME;
2332   if ( rmDir && !tmpCreated.isNull() ) {
2333     script = "rm -rf " + tmpCreated;
2334     script += " > /dev/null";
2335     if ( system( script.latin1() ) ) {
2336     }
2337     ___MESSAGE___( "script = " << script.latin1() );
2338   }
2339 }
2340 // ================================================================
2341 /*!
2342  *  SALOME_InstallWizard::pageChanged
2343  *  Called when user moves from page to page
2344  */
2345 // ================================================================
2346 void SALOME_InstallWizard::pageChanged( const QString & mytitle)
2347 {
2348   nextButton()->setText( tr( "&Next >" ) );
2349   setAboutInfo( nextButton(), tr( "Move to the next step of the installation procedure" ) );
2350   disconnect( this, SIGNAL( nextClicked() ), this, SLOT( next() ) );
2351   disconnect( this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
2352   connect(    this, SIGNAL( nextClicked() ), this, SLOT( next() ) );
2353   cancelButton()->disconnect();
2354   connect( cancelButton(), SIGNAL( clicked()), this, SLOT( reject() ) );
2355
2356   QWidget* aPage = InstallWizard::page( mytitle );
2357   if ( !aPage )
2358     return;
2359   updateCaption();
2360
2361   if ( aPage == typePage ) {
2362     // installation type page
2363     if ( buttonGrp->id( buttonGrp->selected() ) == -1 )
2364       binBtn->animateClick(); // set default installation type
2365   }
2366   else if ( aPage == platformsPage ) {
2367     // installation platforms page
2368     MapXmlFiles::Iterator it;
2369     if ( previousPage == typePage ) {
2370       for ( it = platformsMap.begin(); it != platformsMap.end(); ++it ) {
2371         QString plat = it.key();
2372         QRadioButton* rb = ( (QRadioButton*) platBtnGrp->child( plat ) );
2373         if ( installType == Binaries ) {
2374           QFileInfo fib( QDir::cleanDirPath( getBinPath() + "/" + plat ) );
2375           rb->setEnabled( fib.exists() );
2376           if ( platBtnGrp->id( platBtnGrp->selected() ) == -1 && plat == getBasePlatform() )
2377             rb->animateClick();
2378         }
2379         else {
2380           QFileInfo fis( QDir::cleanDirPath( getSrcPath() ) );
2381           rb->setEnabled( fis.exists() );
2382         }
2383         rb->setChecked( rb->isChecked() && rb->isEnabled() );
2384       }
2385       setNextEnabled( platformsPage, platBtnGrp->id( platBtnGrp->selected() ) != -1 );
2386     }
2387   }
2388   else  if ( aPage == dirPage ) {
2389     // installation and temporary directories page
2390     if ( ( ( this->indexOf( platformsPage ) != -1 && this->appropriate( platformsPage ) ) ? 
2391            previousPage == platformsPage : previousPage == typePage ) 
2392          && stateChanged ) {
2393       // clear global variables before reading XML file
2394       modulesView->clear();
2395       prereqsView->clear();
2396       productsMap.clear();
2397       // read XML file
2398       StructureParser* parser = new StructureParser( this );
2399       parser->setProductsLists( modulesView, prereqsView );
2400       if ( targetFolder->text().isEmpty() )
2401         parser->setTargetDir( targetFolder );
2402       if ( tempFolder->text().isEmpty() )
2403         parser->setTempDir( tempFolder );
2404       parser->readXmlFile( xmlFileName );
2405       // update required size for each product
2406       updateSizeColumn();
2407       // take into account command line parameters
2408       if ( !myTargetPath.isEmpty() )
2409         targetFolder->setText( myTargetPath );
2410       if ( !myTmpPath.isEmpty() )
2411         tempFolder->setText( myTmpPath );
2412       // set all modules to be checked and first module to be selected
2413       installGuiBtn->setState( QButton::Off );
2414       installGuiBtn->setState( QButton::On );
2415       if ( modulesView->childCount() > 0 && !modulesView->selectedItem() )
2416         modulesView->setSelected( modulesView->firstChild(), true );
2417       stateChanged = false;
2418     } 
2419     else if ( rmSrcPrevState != removeSrcBtn->isChecked() ) {
2420       // only update required size for each product
2421       updateSizeColumn();
2422       rmSrcPrevState = removeSrcBtn->isChecked();
2423     }
2424     // add extra products to install list
2425     extraProducts.clear();
2426     extraProducts.insert( "gcc", "gcc-common.sh" );
2427     if ( refPlatform == commonPlatform && installType == Binaries )
2428       extraProducts.insert( "DebianLibsForSalome", "DEBIANFORSALOME-3.1.sh" );
2429   }
2430   else if ( aPage == productsPage ) {
2431     // products page
2432     onSelectionChanged();
2433     checkProductPage();
2434   }
2435   else if ( aPage == prestartPage ) {
2436     // prestart page
2437     showChoiceInfo();
2438   }
2439   else if ( aPage == progressPage ) {
2440     if ( previousPage == prestartPage ) {
2441       // progress page
2442       statusLab->clear();
2443       progressView->clear();
2444       installInfo->clear();
2445       installInfo->setFinished( false );
2446       passedParams->clear();
2447       passedParams->setEnabled( false );
2448       QFont f = parametersLab->font(); f.setBold( false ); parametersLab->setFont( f );
2449       nextButton()->setText( tr( "&Start" ) );
2450       setAboutInfo( nextButton(), tr( "Start installation process" ) );
2451       // reconnect Next button - to use it as Start button
2452       disconnect( this, SIGNAL( nextClicked() ), this, SLOT( next() ) );
2453       disconnect( this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
2454       connect(    this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
2455       setNextEnabled( true );
2456       // reconnect Cancel button to terminate process
2457       cancelButton()->disconnect();
2458       connect( cancelButton(), SIGNAL( clicked() ), this, SLOT( tryTerminate() ) );
2459     }
2460   }
2461   else if ( aPage == readmePage ) {
2462     ButtonList::Iterator it;
2463     for ( it = buttons.begin(); it != buttons.end(); ++it ) {
2464       if ( (*it).button() ) {
2465         QString script;
2466         script += "( cd " + QUOTE( QFileInfo( QDir::cleanDirPath( "./config_files/" ) ).absFilePath() ) + "; ";
2467         script +=  + (*it).script();
2468         script += " check_enabled ";
2469         script += QUOTE( QFileInfo( QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() ) ).absFilePath() ) + " ";
2470         script += QUOTE( QFileInfo( QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + TEMPDIRNAME ).absFilePath() ) + " ";
2471         script += " > /dev/null )";
2472         ___MESSAGE___( "script: " << script.latin1() );
2473         (*it).button()->setEnabled( !(*it).script().isEmpty() && !system( script.latin1() ) );
2474       }
2475     }
2476     finishButton()->setEnabled( true );
2477   }
2478   previousPage = aPage;
2479   ___MESSAGE___( "previousPage = " << previousPage );
2480 }
2481 // ================================================================
2482 /*!
2483  *  SALOME_InstallWizard::onButtonGroup
2484  *  Called when user selected either installation type or installation platform
2485  */
2486 // ================================================================
2487 void SALOME_InstallWizard::onButtonGroup( int rbIndex )
2488 {
2489   int prevType = installType;
2490   QString prevPlat = getPlatform();
2491   QWidget* aPage = InstallWizard::currentPage();
2492   if ( aPage == typePage ) {
2493     installType = InstallationType( rbIndex );
2494     // management of the <Remove source and tmp files> check-box
2495     removeSrcBtn->setEnabled( installType == Compile );
2496     oneModDirBtn->setEnabled( installType == Binaries || installType == Compile );
2497     oneProdDirBtn->setEnabled( installType == Binaries || installType == Compile );
2498   }
2499   else if ( aPage == platformsPage ) {
2500     refPlatform = platBtnGrp->find( rbIndex )->name();
2501     xmlFileName = platformsMap[ refPlatform ];
2502 //     cout << xmlFileName << endl;
2503     setNextEnabled( platformsPage, true );
2504   }
2505   if ( prevType != installType || 
2506        ( indexOf( platformsPage ) != -1 ? prevPlat != getPlatform() : false ) ) {
2507     stateChanged = true;
2508     oneModDirBtn->setChecked( false );
2509     oneProdDirBtn->setChecked( false );
2510   }
2511 }
2512 // ================================================================
2513 /*!
2514  *  SALOME_InstallWizard::helpClicked
2515  *  Shows help window
2516  */
2517 // ================================================================
2518 void SALOME_InstallWizard::helpClicked()
2519 {
2520   if ( helpWindow == NULL ) {
2521     helpWindow = HelpWindow::openHelp( this );
2522     if ( helpWindow ) {
2523       helpWindow->show();
2524       helpWindow->installEventFilter( this );
2525     }
2526     else {
2527       QMessageBox::warning( this,
2528                             tr( "Help file not found" ),
2529                             tr( "Sorry, help is unavailable" ) );
2530     }
2531   }
2532   else {
2533     helpWindow->raise();
2534     helpWindow->setActiveWindow();
2535   }
2536 }
2537 // ================================================================
2538 /*!
2539  *  SALOME_InstallWizard::browseDirectory
2540  *  Shows directory selection dialog
2541  */
2542 // ================================================================
2543 void SALOME_InstallWizard::browseDirectory()
2544 {
2545   const QObject* theSender = sender();
2546   QLineEdit* theFolder;
2547   if ( theSender == targetBtn )
2548     theFolder = targetFolder;
2549   else if (theSender == tempBtn)
2550     theFolder = tempFolder;
2551   else
2552     return;
2553   QString typedDir = QFileDialog::getExistingDirectory( QDir::cleanDirPath( theFolder->text().stripWhiteSpace() ), this );
2554   if ( !typedDir.isNull() ) {
2555     theFolder->setText( typedDir );
2556     theFolder->end( false );
2557   }
2558 }
2559 // ================================================================
2560 /*!
2561  *  SALOME_InstallWizard::directoryChanged
2562  *  Called when directory path (target or temp) is changed
2563  */
2564 // ================================================================
2565 void SALOME_InstallWizard::directoryChanged( const QString& /*text*/ )
2566 {
2567   checkProductPage();
2568 }
2569 // ================================================================
2570 /*!
2571  *  SALOME_InstallWizard::onStart
2572  *  <Start> button's slot - runs installation
2573  */
2574 // ================================================================
2575 void SALOME_InstallWizard::onStart()
2576 {
2577   if ( nextButton()->text() == tr( "&Stop" ) ) {
2578     statusLab->setText( tr( "Aborting installation..." ) );
2579     shellProcess->kill();
2580     while( shellProcess->isRunning() );
2581     statusLab->setText( tr( "Installation has been aborted by user" ) );
2582     return;
2583   }
2584
2585   hasErrors = false;
2586   progressView->clear();
2587   installInfo->clear();
2588   installInfo->setFinished( false );
2589   passedParams->clear();
2590   passedParams->setEnabled( false );
2591   QFont f = parametersLab->font(); f.setBold( false ); parametersLab->setFont( f );
2592
2593   // update status label
2594   statusLab->setText( tr( "Preparing for installation..." ) );
2595   // clear lists of products
2596   toInstall.clear();
2597   notInstall.clear();
2598   toInstall += extraProducts.keys();
2599   // ... and fill it for new process
2600   QCheckListItem* item = (QCheckListItem*)( prereqsView->firstChild() );
2601   while( item ) {
2602     if ( productsMap.contains( item ) ) {
2603       if ( item->isOn() )
2604         toInstall.append( productsMap[item].getName() );
2605       else
2606         notInstall.append( productsMap[item].getName() );
2607     }
2608     item = (QCheckListItem*)( item->nextSibling() );
2609   }
2610   item = (QCheckListItem*)( modulesView->firstChild() );
2611   while( item ) {
2612     if ( productsMap.contains( item ) ) {
2613       if ( item->isOn() )
2614         toInstall.append( productsMap[item].getName() );
2615       else
2616         notInstall.append( productsMap[item].getName() );
2617     }
2618     item = (QCheckListItem*)( item->nextSibling() );
2619   }
2620   // if something at all is selected
2621   if ( (int)toInstall.count() > 1 ) {
2622
2623     if ( installType == Compile ) {
2624       // update status label
2625       statusLab->setText( tr( "Check Fortran compiler..." ) );
2626       // check Fortran compiler.
2627       QString script = "./config_files/checkFortran.sh find_compilers";
2628       script += " " + QUOTE( QFileInfo( QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + TEMPDIRNAME ).absFilePath() );
2629       ___MESSAGE___( "script = " << script.latin1() );
2630       if ( system( script ) ) {
2631         QMessageBox::critical( this,
2632                                tr( "Error" ),
2633                                tr( "Fortran compiler was not found at current system!\n"
2634                                    "Installation can not be continued!"),
2635                                QMessageBox::Ok,
2636                                QMessageBox::NoButton,
2637                                QMessageBox::NoButton );
2638         // installation aborted
2639         abort();
2640         statusLab->setText( tr( "Installation has been aborted" ) );
2641         // enable <Next> button
2642         setNextEnabled( true );
2643         nextButton()->setText( tr( "&Start" ) );
2644         setAboutInfo( nextButton(), tr( "Start installation process" ) );
2645         // reconnect Next button - to use it as Start button
2646         disconnect( this, SIGNAL( nextClicked() ), this, SLOT( next() ) );
2647         disconnect( this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
2648         connect(    this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
2649         // enable <Back> button
2650         setBackEnabled( true );
2651         return;
2652       }
2653     }  
2654     
2655     // update status label
2656     statusLab->setText( tr( "Preparing for installation..." ) );
2657
2658     clean(false); // VSR 07/02/05 - bug fix: first we should clear temporary directory
2659     // disable <Next> button
2660     //setNextEnabled( false );
2661     nextButton()->setText( tr( "&Stop" ) );
2662     setAboutInfo( nextButton(), tr( "Abort installation process" ) );
2663     // disable <Back> button
2664     setBackEnabled( false );
2665     // enable script parameters line edit
2666     // VSR commented: 18/09/03: passedParams->setEnabled( true );
2667     // VSR commented: 18/09/03: passedParams->setFocus();
2668     ProgressViewItem* progressItem;
2669     // set status for installed products
2670     for ( int i = 0; i < (int)toInstall.count(); i++ ) {
2671       if ( !extraProducts.contains( toInstall[i] ) ) {
2672         item = findItem( toInstall[i] );
2673         progressView->addProduct( item->text(0), item->text(2) );
2674         continue;
2675       }
2676       progressItem = progressView->addProduct( toInstall[i], extraProducts[toInstall[i]] );
2677       progressItem->setVisible( false );
2678     }
2679     // set status for not installed products
2680     for ( int i = 0; i < (int)notInstall.count(); i++ ) {
2681       item = findItem( notInstall[i] );
2682       progressItem = progressView->addProduct( item->text(0), item->text(2) );
2683       progressItem->setVisible( false );
2684     }
2685     // get specified list of products being installed
2686     prodSequence.clear();
2687     for (int i = 0; i<(int)toInstall.count(); i++ ) {
2688       if ( extraProducts.contains( toInstall[i] ) ) {
2689         prodSequence.append( toInstall[i] );
2690         continue;
2691       }
2692       if ( installType == Binaries ) {
2693         prodSequence.append( toInstall[i] );
2694         QString prodType;
2695         MapProducts::Iterator mapIter;
2696         for ( mapIter = productsMap.begin(); mapIter != productsMap.end(); ++mapIter ) {
2697           if ( mapIter.data().getName() == toInstall[i] && mapIter.data().getType() == "component" ) {
2698             prodSequence.append( toInstall[i] + "_src" );
2699             break;
2700           }
2701         }
2702       }
2703       else if ( installType == Sources )
2704         prodSequence.append( toInstall[i] + "_src" );
2705       else {
2706         prodSequence.append( toInstall[i] );
2707         prodSequence.append( toInstall[i] + "_src" );
2708       }
2709     }
2710
2711     // create a backup of 'env_build.csh', 'env_build.sh', 'env_products.csh', 'env_products.sh'
2712     // ( backup of 'salome.csh' and 'salome.sh' is made if pick-up environment is called )
2713     QString script = "./config_files/backupEnv.sh ";
2714     script += QUOTE( QFileInfo( QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() ) ).absFilePath() );
2715     ___MESSAGE___( "script = " << script.latin1() );
2716     if ( system( script ) ) {
2717       if ( QMessageBox::warning( this,
2718                                  tr( "Warning" ),
2719                                  tr( "Backup environment files have not been created.\n"
2720                                      "Do you want to continue an installation process?" ),
2721                                  tr( "&Yes" ),
2722                                  tr( "&No" ), 
2723                                  QString::null, 0, 1 ) == 1 ) {
2724         // installation aborted
2725         abort();
2726         statusLab->setText( tr( "Installation has been aborted by user" ) );
2727         // enable <Next> button
2728         setNextEnabled( true );
2729         nextButton()->setText( tr( "&Start" ) );
2730         setAboutInfo( nextButton(), tr( "Start installation process" ) );
2731         // reconnect Next button - to use it as Start button
2732         disconnect( this, SIGNAL( nextClicked() ), this, SLOT( next() ) );
2733         disconnect( this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
2734         connect(    this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
2735         // enable <Back> button
2736         setBackEnabled( true );
2737         return;
2738       }
2739     }
2740
2741     // launch install script
2742     launchScript();
2743   }
2744 }
2745 // ================================================================
2746 /*!
2747  *  SALOME_InstallWizard::onReturnPressed
2748  *  Called when users tries to pass parameters for the script
2749  */
2750 // ================================================================
2751 void SALOME_InstallWizard::onReturnPressed()
2752 {
2753   QString txt = passedParams->text();
2754   installInfo->append( txt );
2755   txt += "\n";
2756   shellProcess->writeToStdin( txt );
2757   passedParams->clear();
2758   progressView->setFocus();
2759   passedParams->setEnabled( false );
2760   QFont f = parametersLab->font(); f.setBold( false ); parametersLab->setFont( f );
2761 }
2762 /*!
2763   Callback function - as response for the script finishing
2764 */
2765 void SALOME_InstallWizard::productInstalled()
2766 {
2767   ___MESSAGE___( "process exited" );
2768   if ( shellProcess->normalExit() ) {
2769     ___MESSAGE___( "...normal exit" );
2770     // normal exit - try to proceed installation further
2771     launchScript();
2772   }
2773   else {
2774     ___MESSAGE___( "...abnormal exit" );
2775     statusLab->setText( tr( "Installation has been aborted" ) );
2776     // installation aborted
2777     abort();
2778     // clear script passed parameters lineedit
2779     passedParams->clear();
2780     passedParams->setEnabled( false );
2781     QFont f = parametersLab->font(); f.setBold( false ); parametersLab->setFont( f );
2782     installInfo->setFinished( true );
2783     // enable <Next> button
2784     setNextEnabled( true );
2785     nextButton()->setText( tr( "&Start" ) );
2786     setAboutInfo( nextButton(), tr( "Start installation process" ) );
2787     // reconnect Next button - to use it as Start button
2788     disconnect( this, SIGNAL( nextClicked() ), this, SLOT( next() ) );
2789     disconnect( this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
2790     connect(    this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
2791     //nextButton()->setText( tr( "&Next >" ) );
2792     //setAboutInfo( nextButton(), tr( "Move to the next step of the installation procedure" ) );
2793     //disconnect( this, SIGNAL( nextClicked() ), this, SLOT( next() ) );
2794     //disconnect( this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
2795     //connect(    this, SIGNAL( nextClicked() ), this, SLOT( next() ) );
2796     // enable <Back> button
2797     setBackEnabled( true );
2798   }
2799 }
2800 // ================================================================
2801 /*!
2802  *  SALOME_InstallWizard::tryTerminate
2803  *  Slot, called when <Cancel> button is clicked during installation script running
2804  */
2805 // ================================================================
2806 void SALOME_InstallWizard::tryTerminate()
2807 {
2808   if ( shellProcess->isRunning() ) {
2809     if ( QMessageBox::information( this,
2810                                    tr( "Exit" ),
2811                                    tr( "Do you want to quit %1?" ).arg( getIWName() ),
2812                                    tr( "&Yes" ),
2813                                    tr( "&No" ),
2814                                    QString::null,
2815                                    0,
2816                                    1 ) == 1 ) {
2817       return;
2818     }
2819     exitConfirmed = true;
2820     // if process still running try to terminate it first
2821     shellProcess->tryTerminate();
2822     abort();
2823     //QTimer::singleShot( 3000, this, SLOT( onCancel() ) );
2824     connect( shellProcess, SIGNAL( processExited() ), this, SLOT( onCancel() ) );
2825   }
2826   else {
2827     // else just quit install wizard
2828     reject();
2829   }
2830 }
2831 // ================================================================
2832 /*!
2833  *  SALOME_InstallWizard::onCancel
2834  *  Kills installation process and quits application
2835  */
2836 // ================================================================
2837 void SALOME_InstallWizard::onCancel()
2838 {
2839   shellProcess->kill();
2840   reject();
2841 }
2842 // ================================================================
2843 /*!
2844  *  SALOME_InstallWizard::onSelectionChanged
2845  *  Called when selection is changed in the products list view
2846  *  to fill in the 'Information about product' text box
2847  */
2848 // ================================================================
2849 void SALOME_InstallWizard::onSelectionChanged()
2850 {
2851   const QObject* snd = sender();
2852   QListViewItem* item = modulesView->selectedItem();
2853   if ( snd == prereqsView )
2854     item = prereqsView->selectedItem();
2855   if ( !item )
2856     return;
2857   productInfo->clear();
2858   QCheckListItem* anItem = (QCheckListItem*)item;
2859   if ( !productsMap.contains( anItem ) )
2860     return;
2861   Dependancies dep = productsMap[ anItem ];
2862   QString text = "<b>" + anItem->text(0) + "</b>" + "<br>";
2863   if ( !dep.getVersion().isEmpty() )
2864     text += tr( "Version" ) + ": " + dep.getVersion() + "<br>";
2865   text += "<br>";
2866   if ( !dep.getDescription().isEmpty() ) {
2867     text += "<i>" + dep.getDescription() + "</i><br><br>";
2868   }
2869   /* AKL: 07/08/28 - hide required disk space for tmp files for each product ==>
2870      long tempSize = 0;
2871      tempSize = dep.getTempSize( installType );
2872      text += tr( "Disk space for tmp files required" ) + ": " + QString::number( tempSize ) + " KB<br>";
2873      AKL: 07/08/28 - hide required disk space for tmp files for each product <==
2874   */
2875   text += tr( "Disk space required" ) + ": " + item->text(1) + "<br>";
2876   text += "<br>";
2877   QString req = ( dep.getDependancies().count() > 0 ? dep.getDependancies().join(", ") : tr( "none" ) );
2878   text +=  tr( "Prerequisites" ) + ": " + req;
2879   productInfo->setText( text );
2880 }
2881 // ================================================================
2882 /*!
2883  *  SALOME_InstallWizard::onItemToggled
2884  *  Called when user checks/unchecks any product item
2885  *  Recursively sets all prerequisites and updates "Next" button state
2886  */
2887 // ================================================================
2888 void SALOME_InstallWizard::onItemToggled( QCheckListItem* item )
2889 {
2890   if ( productsMap.contains( item ) ) {
2891     if ( item->isOn() )
2892       setPrerequisites( item );
2893     else 
2894       unsetPrerequisites( item );
2895   }
2896   onSelectionChanged();
2897   checkProductPage();
2898 }
2899 // ================================================================
2900 /*!
2901  *  SALOME_InstallWizard::wroteToStdin
2902  *  QProcess slot: -->something was written to stdin
2903  */
2904 // ================================================================
2905 void SALOME_InstallWizard::wroteToStdin( )
2906 {
2907   ___MESSAGE___( "Something was sent to stdin" );
2908 }
2909 // ================================================================
2910 /*!
2911  *  SALOME_InstallWizard::readFromStdout
2912  *  QProcess slot: -->something was written to stdout
2913  */
2914 // ================================================================
2915 void SALOME_InstallWizard::readFromStdout( )
2916 {
2917   ___MESSAGE___( "Something was sent to stdout" );
2918   while ( shellProcess->canReadLineStdout() ) {
2919     installInfo->append( QString( shellProcess->readLineStdout() ) );
2920     installInfo->scrollToBottom();
2921   }
2922   QString str( shellProcess->readStdout() );
2923   if ( !str.isEmpty() ) {
2924     installInfo->append( str );
2925     installInfo->scrollToBottom();
2926   }
2927 }
2928
2929 #define OUTLINE_TEXT(x) QString( "<font color=#FF0000><b>" ) + QString( x ) + QString( "</b></font>" )
2930
2931 // ================================================================
2932 /*!
2933  *  SALOME_InstallWizard::readFromStderr
2934  *  QProcess slot: -->something was written to stderr
2935  */
2936 // ================================================================
2937 void SALOME_InstallWizard::readFromStderr( )
2938 {
2939   ___MESSAGE___( "Something was sent to stderr" );
2940   while ( shellProcess->canReadLineStderr() ) {
2941     installInfo->append( OUTLINE_TEXT( QString( shellProcess->readLineStderr() ) ) );
2942     installInfo->scrollToBottom();
2943     hasErrors = true;
2944   }
2945   QString str( shellProcess->readStderr() );
2946   if ( !str.isEmpty() ) {
2947     installInfo->append( OUTLINE_TEXT( str ) );
2948     installInfo->scrollToBottom();
2949     hasErrors = true;
2950   }
2951   // VSR: 10/11/05 - disable answer mode ==>
2952   // passedParams->setEnabled( true );
2953   // passedParams->setFocus();
2954   // QFont f = parametersLab->font(); f.setBold( true ); parametersLab->setFont( f );
2955   // VSR: 10/11/05 - disable answer mode <==
2956 }
2957 // ================================================================
2958 /*!
2959  *  SALOME_InstallWizard::setDependancies
2960  *  Sets dependancies for the product item
2961  */
2962 // ================================================================
2963 void SALOME_InstallWizard::setDependancies( QCheckListItem* item, Dependancies dep)
2964 {
2965   productsMap[item] = dep;
2966 }
2967 // ================================================================
2968 /*!
2969  *  SALOME_InstallWizard::addFinishButton
2970  *  Add button for the <Finish> page.
2971  *  Clear list of buttons if <toClear> flag is true.
2972  */
2973 // ================================================================
2974 void SALOME_InstallWizard::addFinishButton( const QString& label,
2975                                             const QString& tooltip,
2976                                             const QString& script,
2977                                             bool toClear )
2978 {
2979   ButtonList btns;
2980   if ( toClear ) {
2981     btns = buttons;
2982     buttons.clear();
2983   }
2984   buttons.append( Button( label, tooltip, script ) );
2985   // create finish buttons
2986   QButton* b = new QPushButton( tr( buttons.last().label() ), readmePage );
2987   if ( !buttons.last().tootip().isEmpty() )
2988     setAboutInfo( b, tr( buttons.last().tootip() ) );
2989   QHBoxLayout* hLayout = (QHBoxLayout*)readmePage->layout()->child("finishButtons");
2990   if ( toClear ) {
2991     // remove previous buttons
2992     ButtonList::Iterator it;
2993     for ( it = btns.begin(); it != btns.end(); ++it ) {
2994       hLayout->removeChild( (*it).button() );
2995       delete (*it).button();
2996     }
2997   }
2998   // add buttons to finish page
2999   hLayout->insertWidget( buttons.count()-1, b );
3000   buttons.last().setButton( b );
3001   connect( b, SIGNAL( clicked() ), this, SLOT( onFinishButton() ) );
3002 }
3003 // ================================================================
3004 /*!
3005  *  SALOME_InstallWizard::polish
3006  *  Polishing of the widget - to set right initial size
3007  */
3008 // ================================================================
3009 void SALOME_InstallWizard::polish()
3010 {
3011   resize( 0, 0 );
3012   InstallWizard::polish();
3013 }
3014 // ================================================================
3015 /*!
3016  *  SALOME_InstallWizard::saveLog
3017  *  Save installation log to file
3018  */
3019 // ================================================================
3020 void SALOME_InstallWizard::saveLog()
3021 {
3022   QString txt = installInfo->text();
3023   if ( txt.length() <= 0 )
3024     return;
3025   QDateTime dt = QDateTime::currentDateTime();
3026   QString fileName = dt.toString("ddMMyy-hhmm");
3027   fileName.prepend("install-"); fileName.append(".html");
3028   fileName = QFileInfo( QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() ), fileName ).absFilePath();
3029   fileName = QFileDialog::getSaveFileName( fileName,
3030                                            QString( "HTML files (*.htm *.html)" ),
3031                                            this, 0,
3032                                            tr( "Save Log file" ) );
3033   if ( !fileName.isEmpty() ) {
3034     QFile f( fileName );
3035     if ( f.open( IO_WriteOnly ) ) {
3036       QTextStream stream( &f );
3037       stream << txt;
3038       f.close();
3039     }
3040     else {
3041       QMessageBox::critical( this,
3042                              tr( "Error" ),
3043                              tr( "Can't save file %1.\nCheck path and permissions.").arg( fileName ),
3044                              QMessageBox::Ok,
3045                              QMessageBox::NoButton,
3046                              QMessageBox::NoButton );
3047     }
3048   }
3049 }
3050 // ================================================================
3051 /*!
3052  *  SALOME_InstallWizard::updateCaption
3053  *  Updates caption according to the current page number
3054  */
3055 // ================================================================
3056 void SALOME_InstallWizard::updateCaption()
3057 {
3058   QWidget* aPage = InstallWizard::currentPage();
3059   if ( !aPage )
3060     return;
3061   InstallWizard::setCaption( tr( myCaption ) + " " +
3062                              tr( getIWName() ) + " - " +
3063                              tr( "Step %1 of %2").arg( QString::number( this->indexOf( aPage )+1 ) ).arg( QString::number( this->pageCount() ) ) );
3064 }
3065
3066 // ================================================================
3067 /*!
3068  *  SALOME_InstallWizard::processValidateEvent
3069  *  Processes validation event (<val> is validation code)
3070  */
3071 // ================================================================
3072 void SALOME_InstallWizard::processValidateEvent( const int val, void* data )
3073 {
3074   QWidget* aPage = InstallWizard::currentPage();
3075   if ( aPage != productsPage ) {
3076     InstallWizard::processValidateEvent( val, data );
3077     return;
3078   }
3079   myMutex.lock();
3080   myMutex.unlock();
3081   if ( val > 0 ) {
3082   }
3083   if ( myThread->hasCommands() )
3084     myWC.wakeAll();
3085   else {
3086     WarnDialog::showWarnDlg( 0, false );
3087     InstallWizard::processValidateEvent( val, data );
3088   }
3089 }