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