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