]> SALOME platform Git repositories - tools/install.git/blob - src/SALOME_InstallWizard.cxx
Salome HOME
ae369fc7e2876a1e67958e13943eb8ba897d4a75
[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
4 //  Project   : PAL/SALOME
5 //  Module    : InstallWizard
6 //  Copyright : 2004 CEA
7 //  $Header$ 
8
9 #include "SALOME_InstallWizard.hxx"
10 #include "SALOME_ProductsView.hxx"
11 #include "SALOME_ProgressView.hxx"
12 #include "SALOME_XmlHandler.hxx"
13 #include "SALOME_HelpWindow.hxx"
14
15 #include "icons.h"
16
17 #include <qlineedit.h>
18 #include <qpushbutton.h>
19 #include <qlistview.h>
20 #include <qlabel.h>
21 #include <qtextedit.h>
22 #include <qtextbrowser.h>
23 #include <qprocess.h>
24 #include <qcheckbox.h>
25 #include <qsplitter.h>
26 #include <qlayout.h>
27 #include <qfiledialog.h> 
28 #include <qapplication.h>
29 #include <qfileinfo.h> 
30 #include <qmessagebox.h> 
31 #include <qtimer.h> 
32 #include <qvbox.h>
33 #include <qwhatsthis.h> 
34 #include <qtooltip.h>
35 #include <qfile.h>
36
37 #ifdef WNT
38 #include <iostream.h>
39 #include <process.h>
40 #else
41 #include <unistd.h>
42 #include <algo.h>
43 #endif
44
45 #ifdef WNT
46 #define max( x, y ) ( x ) > ( y ) ? ( x ) : ( y )
47 #endif
48
49 #define TEMPDIRNAME ( "/INSTALLWORK" + QString::number( getpid() ) )
50
51 // ================================================================
52 /*!
53  *  DefineDependeces [ static ]
54  *  Defines list of dependancies as string separated by space symbols
55  */
56 // ================================================================
57 static QString DefineDependeces(MapProducts& theProductsMap) {
58   QStringList aProducts;
59   for ( MapProducts::Iterator mapIter = theProductsMap.begin(); mapIter != theProductsMap.end(); ++mapIter ) {
60     QCheckListItem* item = mapIter.key();
61     Dependancies dep = mapIter.data();
62     QStringList deps = dep.getDependancies();
63     for (int i = 0; i<(int)deps.count(); i++ ) {
64       if ( !aProducts.contains( deps[i] ) )
65         aProducts.append( deps[i] );
66     }
67     if ( !aProducts.contains( item->text(0) ) )
68       aProducts.append( item->text(0) );
69   }
70   return aProducts.join(" ");
71 }
72
73 #define QUOTE(arg) QString("'") + QString(arg) + QString("'")
74
75 /* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
76                T H E   O L D   I M P L E M E N T A T I O N 
77 static QString DefineDependeces(MapProducts& theProductsMap, QCheckListItem* product ){
78   QStringList aProducts;
79   if ( theProductsMap.contains( product ) ) {
80     Dependancies dep = theProductsMap[ product ];
81     QStringList deps = dep.getDependancies();
82     for (int i = 0; i<(int)deps.count(); i++ ) {
83       aProducts.append( deps[i] );
84     }
85   }
86   return QString("\"") + aProducts.join(" ") + QString("\"");
87 }
88 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */
89
90 // ================================================================
91 /*!
92  *  makeDir [ static ]
93  *  Makes directory recursively, returns false if not succedes
94  */
95 // ================================================================
96 static bool makeDir( const QString& theDir, QString& theCreated )
97 {
98   theCreated = QString::null;
99   if ( theDir.isEmpty() )
100     return false;
101   QString aDir = QDir::cleanDirPath( QFileInfo( theDir ).absFilePath() );
102   int start = 1;
103   while ( start > 0 ) {
104     start = aDir.find( QDir::separator(), start );
105     if ( start > 0 ) {
106       QFileInfo fi( aDir.left( start ) );
107       if ( !fi.exists() ) {
108         // VSR: Create directory and set permissions to allow other users to remove it
109         QString script = "mkdir " + fi.absFilePath();
110         script += "; chmod 777 " + fi.absFilePath();
111         script += " > /dev/null";
112         if ( system( script.latin1() ) )
113           return false;
114         // VSR: Remember the top of the created directory (to remove it in the end of the installation)
115         if ( theCreated.isNull() )
116           theCreated = fi.absFilePath();
117       }
118     }
119     start++;
120   }
121   if ( !QFileInfo( aDir ).exists() ) {
122     // VSR: Create directory, other users should NOT have possibility to remove it!!!
123     QString script = "mkdir " + aDir;
124     script += " > /dev/null";
125     if ( system( script.latin1() ) )
126       return false;
127     // VSR: Remember the top of the created directory (to remove it in the end of the installation)
128     if ( theCreated.isNull() )
129       theCreated = aDir;
130   }
131   return true;
132 }
133 // ================================================================
134 /*!
135  *  readFile [ static ]
136  *  Reads the file, returns false if can't open it
137  */
138 // ================================================================
139 static bool readFile( const QString& fileName, QString& text )
140 {
141   if ( QFile::exists( fileName ) ) {
142     QFile file( fileName );
143     if ( file.open( IO_ReadOnly ) ) {
144       QTextStream stream( &file );
145       QString line;
146       while ( !stream.eof() ) {
147         line = stream.readLine(); // line of text excluding '\n'
148         text += line + "\n";
149       }
150       file.close();
151       return true;
152     }
153   }
154   return false;
155 }
156 // ================================================================
157 /*!
158  *  hasSpace [ static ]
159  *  Checks if string contains spaces; used to check directory paths
160  */
161 // ================================================================
162 static bool hasSpace( const QString& dir )
163 {
164   for ( int i = 0; i < (int)dir.length(); i++ ) {
165     if ( dir[ i ].isSpace() )
166       return true;
167   }
168   return false;
169 }
170
171 // ================================================================
172 /*!
173  *  SALOME_InstallWizard::SALOME_InstallWizard
174  *  Constructor
175  */
176 // ================================================================
177 SALOME_InstallWizard::SALOME_InstallWizard(QString aXmlFileName)
178      : InstallWizard( qApp->desktop(), "SALOME_InstallWizard", false, 0 ), 
179        helpWindow( NULL ), 
180        moreMode( false ), 
181        previousPage( 0 ), 
182        exitConfirmed( false )
183 {
184   myIWName = tr( "Installation Wizard" );
185   tmpCreated = QString::null;
186   xmlFileName = aXmlFileName;
187   QFont fnt = font(); fnt.setPointSize( 14 ); fnt.setBold( true );
188   setTitleFont( fnt );
189
190   // set icon
191   setIcon( QPixmap( ( const char** ) image0_data ) );
192   // enable sizegrip
193   setSizeGripEnabled( true );
194   
195   // add logo
196   addLogo( QPixmap( (const char**)image1_data ) );
197   
198   // set defaults
199   setVersion( "1.2" );
200   setCaption( tr( "PAL/SALOME %1" ).arg( myVersion ) );
201   setCopyright( tr( "Copyright (C) 2004 CEA" ) );
202   setLicense( tr( "All right reserved" ) );
203   setOS( "" );
204
205 #ifdef DEBUG
206   cout << "Config. file : " << xmlFileName << endl;
207 #endif
208
209   // xml reader
210   QFile xmlfile(xmlFileName);
211   if ( xmlfile.exists() ) {
212     QXmlInputSource source( &xmlfile );
213     QXmlSimpleReader reader;
214
215     StructureParser* handler = new StructureParser( this );
216     reader.setContentHandler( handler );
217     reader.parse( source );  
218   }
219
220   // create instance of class for starting shell install script
221   shellProcess = new QProcess( this, "shellProcess" );
222
223   // create introduction page
224   setupIntroPage();
225   // create products page
226   setupProductsPage();
227   // create prestart page
228   setupCheckPage();
229   // create progress page
230   setupProgressPage();
231   // create readme page
232   setupReadmePage();
233   
234   // common buttons
235   QWhatsThis::add( backButton(),   tr( "Returns to the previous step of the installation procedure" ) );
236   QToolTip::add  ( backButton(),   tr( "Returns to the previous step of the installation procedure" ) );
237   QWhatsThis::add( nextButton(),   tr( "Moves to the next step of the installation procedure" ) );
238   QToolTip::add  ( nextButton(),   tr( "Moves to the next step of the installation procedure" ) );
239   QWhatsThis::add( finishButton(), tr( "Finishes installation and quits program" ) );
240   QToolTip::add  ( finishButton(), tr( "Finishes installation and quits program" ) );
241   QWhatsThis::add( cancelButton(), tr( "Cancels installation and quits program" ) );
242   QToolTip::add  ( cancelButton(), tr( "Cancels installation and quits program" ) );
243   QWhatsThis::add( helpButton(),   tr( "Displays help information window" ) );
244   QToolTip::add  ( helpButton(),   tr( "Displays help information window" ) );
245   
246   // common signals connections
247   connect( this, SIGNAL( selected( const QString& ) ),
248                                           this, SLOT( pageChanged( const QString& ) ) );
249   connect( this, SIGNAL( helpClicked() ), this, SLOT( helpClicked() ) );
250   // catch signals from launched script
251   connect(shellProcess, SIGNAL( readyReadStdout() ), this, SLOT( readFromStdout() ) );
252   connect(shellProcess, SIGNAL( readyReadStderr() ), this, SLOT( readFromStderr() ) );
253   connect(shellProcess, SIGNAL( processExited() ),   this, SLOT( productInstalled() ) );
254   connect(shellProcess, SIGNAL( wroteToStdin() ),    this, SLOT( wroteToStdin() ) );
255 }
256 // ================================================================
257 /*!
258  *  SALOME_InstallWizard::~SALOME_InstallWizard
259  *  Destructor
260  */
261 // ================================================================
262 SALOME_InstallWizard::~SALOME_InstallWizard()
263 {
264   shellProcess->kill(); // kill it for sure
265   QString script = "kill -9 ";
266   int PID = (int)shellProcess->processIdentifier();
267   if ( PID > 0 ) {
268     script += QString::number( PID );
269     script += " > /dev/null";
270 #ifdef DEBUG
271     cout << "script: "<< script.latin1() << endl;
272 #endif
273     if ( system( script.latin1() ) ) { 
274     }
275   }
276 }
277 // ================================================================
278 /*!
279  *  SALOME_InstallWizard::eventFilter
280  *  Event filter, spies for Help window closing
281  */
282 // ================================================================
283 bool SALOME_InstallWizard::eventFilter( QObject* object, QEvent* event )
284 {
285   if ( object && object == helpWindow && event->type() == QEvent::Close )
286     helpWindow = NULL;
287   return InstallWizard::eventFilter( object, event );
288 }
289 // ================================================================
290 /*!
291  *  SALOME_InstallWizard::closeEvent
292  *  Close event handler
293  */
294 // ================================================================
295 void SALOME_InstallWizard::closeEvent( QCloseEvent* ce )
296 {
297   if ( !exitConfirmed ) {
298     if ( QMessageBox::information( this, 
299                                    tr( "Exit" ), 
300                                    tr( "Do you want to quit %1?" ).arg( getIWName() ), 
301                                    tr( "&Yes" ), 
302                                    tr( "&No" ),
303                                    QString::null,
304                                    0,
305                                    1 ) == 1 ) {
306       ce->ignore();
307     }
308     else {
309       ce->accept();
310       exitConfirmed = true;
311       reject();
312     }
313   }
314 }
315 // ================================================================
316 /*!
317  *  SALOME_InstallWizard::setupIntroPage
318  *  Creates introduction page
319  */
320 // ================================================================
321 void SALOME_InstallWizard::setupIntroPage()
322 {
323   // create page
324   introPage = new QWidget( this, "IntroPage" );
325   QGridLayout* pageLayout = new QGridLayout( introPage ); 
326   pageLayout->setMargin( 0 ); pageLayout->setSpacing( 6 );
327   // create logo picture
328   QPixmap logo( (const char**)SALOME_Logo_xpm );
329   logoLab = new QLabel( introPage );
330   logoLab->setPixmap( logo );
331   logoLab->setScaledContents( false );
332   logoLab->setFrameStyle( QLabel::Plain | QLabel::Box );
333   logoLab->setAlignment( AlignCenter );
334   // create version box
335   QVBox* versionBox = new QVBox( introPage ); versionBox->setSpacing( 6 );
336   versionBox->setFrameStyle( QVBox::Panel | QVBox::Sunken );
337   QWidget* stretch1 = new QWidget( versionBox ); versionBox->setStretchFactor( stretch1, 5 );
338   versionLab = new QLabel( QString("%1 %2").arg( tr( "Version" ) ).arg(myVersion), versionBox );
339   versionLab->setAlignment( AlignCenter );
340   copyrightLab = new QLabel( myCopyright, versionBox );
341   copyrightLab->setAlignment( AlignCenter );
342   licenseLab = new QLabel( myLicense, versionBox );
343   licenseLab->setAlignment( AlignCenter );
344   QWidget* stretch2 = new QWidget( versionBox ); versionBox->setStretchFactor( stretch2, 5 );
345   // create info box
346   info = new QLabel( introPage );
347   info->setText( tr( "This program will install <b>%1</b>."
348                      "<br><br>The wizard will also help you to install all products "
349                      "which are necessary for <b>%2</b> and setup "
350                      "your environment.<br><br>Click <code>Cancel</code> button to abort "
351                      "installation and quit. Click <code>Next</code> button to continue with the "
352                      "installation program." ).arg( myCaption ).arg( myCaption ) );
353   info->setFrameStyle( QLabel::WinPanel | QLabel::Sunken );
354   info->setMargin( 6 );
355   info->setAlignment( WordBreak );
356   info->setMinimumWidth( 250 );
357   QPalette pal = info->palette();
358   pal.setColor( QColorGroup::Background, QApplication::palette().active().base() );
359   info->setPalette( pal );
360   info->setLineWidth( 2 );
361   // layouting
362   pageLayout->addWidget( logoLab, 0, 0 );
363   pageLayout->addWidget( versionBox, 1, 0 );
364   pageLayout->addMultiCellWidget( info, 0, 1, 1, 1 );
365   pageLayout->setColStretch( 1, 5 );
366   pageLayout->setRowStretch( 1, 5 );
367   // adding page
368   addPage( introPage, tr( "Introduction" ) );
369 }
370 // ================================================================
371 /*!
372  *  SALOME_InstallWizard::setupProductsPage
373  *  Creates products page
374  */
375 // ================================================================
376 void SALOME_InstallWizard::setupProductsPage()
377 {
378   // create page
379   productsPage = new QWidget( this, "ProductsPage" );
380   QGridLayout* pageLayout = new QGridLayout( productsPage ); 
381   pageLayout->setMargin( 0 ); pageLayout->setSpacing( 6 );
382   // target directory
383   QLabel* targetLab = new QLabel( tr( "Type the target directory:" ), productsPage );
384   targetFolder = new QLineEdit( productsPage );
385   QWhatsThis::add( targetFolder, tr( "Enter target root directory where products will be installed" ) );
386   QToolTip::add  ( targetFolder, tr( "Enter target root directory where products will be installed" ) );
387   targetBtn = new QPushButton( tr( "Browse..." ), productsPage );
388   QWhatsThis::add( targetBtn, tr( "Click this to browse target directory" ) );
389   QToolTip::add  ( targetBtn, tr( "Click this to browse target directory" ) );
390   // create advanced mode widgets container
391   moreBox = new QWidget( productsPage );
392   QGridLayout* moreBoxLayout = new QGridLayout( moreBox );
393   moreBoxLayout->setMargin( 0 ); moreBoxLayout->setSpacing( 6 );
394   // temp directory
395   QLabel* tempLab = new QLabel( tr( "Type the directory for the temporary files:" ), moreBox );
396   tempFolder = new QLineEdit( moreBox );
397   //  tempFolder->setText( "/tmp" ); // default is /tmp directory
398   QWhatsThis::add( tempFolder, tr( "Enter directory where to put temporary files" ) );
399   QToolTip::add  ( tempFolder, tr( "Enter directory where to put temporary files" ) );
400   tempBtn = new QPushButton( tr( "Browse..." ), moreBox );
401   tempBtn->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) );
402   QWhatsThis::add( tempBtn, tr( "Click this to browse temporary directory" ) );
403   QToolTip::add  ( tempBtn, tr( "Click this to browse temporary directory" ) );
404   // create products list
405   productsView = new ProductsView( moreBox );
406   productsView->setMinimumSize( 250, 180 );
407   QWhatsThis::add( productsView, tr( "This view lists the products you wish to be installed" ) );
408   QToolTip::add  ( productsView, tr( "This view lists the products you wish to be installed" ) );
409   // products info box
410   productsInfo = new QTextBrowser( moreBox );
411   productsInfo->setMinimumSize( 270, 135 );
412   QWhatsThis::add( productsInfo, tr( "Shows info about the product: required disk space and prerequisites" ) );
413   QToolTip::add  ( productsInfo, tr( "Shows info about the product: required disk space and prerequisites" ) );
414   // disk space labels
415   QLabel* reqLab1 = new QLabel( tr( "Total disk space required:" ), moreBox );
416   QWhatsThis::add( reqLab1, tr( "Shows total disk space required for installing selected products" ) );
417   QToolTip::add  ( reqLab1, tr( "Shows total disk space required for installing selected products" ) );
418   requiredSize = new QLabel( moreBox );
419   requiredSize->setMinimumWidth( 100 );
420   QWhatsThis::add( requiredSize, tr( "Shows total disk space required for installing selected products" ) );
421   QToolTip::add  ( requiredSize, tr( "Shows total disk space required for installing selected products" ) );
422   QLabel* reqLab2 = new QLabel( tr( "Space for temporary files:" ), moreBox );
423   QWhatsThis::add( reqLab2, tr( "Shows additional disk space which is required for temporary files" ) );
424   QToolTip::add  ( reqLab2, tr( "Shows additional disk space which is required for temporary files" ) );
425   requiredTemp = new QLabel( moreBox );
426   requiredTemp->setMinimumWidth( 100 );
427   QWhatsThis::add( requiredTemp, tr( "Shows additional disk space which is required for temporary files" ) );
428   QToolTip::add  ( requiredTemp, tr( "Shows additional disk space which is required for temporary files" ) );
429   QFont fnt = reqLab1->font();
430   fnt.setBold( true );
431   reqLab1->setFont( fnt );
432   requiredSize->setFont( fnt );
433   reqLab2->setFont( fnt );
434   requiredTemp->setFont( fnt );
435   QGridLayout* sizeLayout = new QGridLayout; sizeLayout->setMargin( 0 ); sizeLayout->setSpacing( 6 );
436   sizeLayout->addWidget( reqLab1,      0, 0 );
437   sizeLayout->addWidget( requiredSize, 0, 1 );
438   sizeLayout->addWidget( reqLab2,      1, 0 );
439   sizeLayout->addWidget( requiredTemp, 1, 1 );
440   // prerequisites checkbox
441   prerequisites = new QCheckBox( tr( "Auto set prerequisites products" ), moreBox );
442   prerequisites->setChecked( true );
443   QWhatsThis::add( prerequisites, tr( "Check this if you want prerequisites products to be set on automatically" ) );
444   QToolTip::add  ( prerequisites, tr( "Check this if you want prerequisites products to be set on automatically" ) );
445   // <Unselect All> buttons
446   unselectBtn  = new QPushButton( tr( "&Unselect All" ),    moreBox );
447   QWhatsThis::add( unselectBtn, tr( "Unselects all products" ) );
448   QToolTip::add  ( unselectBtn, tr( "Unselects all products" ) );
449   QVBoxLayout* btnLayout = new QVBoxLayout; btnLayout->setMargin( 0 ); btnLayout->setSpacing( 6 );
450   btnLayout->addWidget( unselectBtn );
451   // layouting advancet mode widgets
452   moreBoxLayout->addMultiCellWidget( tempLab,      0, 0, 0, 2 );
453   moreBoxLayout->addMultiCellWidget( tempFolder,   1, 1, 0, 1 );
454   moreBoxLayout->addWidget         ( tempBtn,      1,    2    );
455   moreBoxLayout->addMultiCellWidget( productsView, 2, 5, 0, 0 );
456   moreBoxLayout->addMultiCellWidget( productsInfo, 2, 2, 1, 2 );
457   moreBoxLayout->addMultiCellWidget( prerequisites,3, 3, 1, 2 );
458   moreBoxLayout->addMultiCellLayout( btnLayout,    4, 4, 1, 2 );
459   moreBoxLayout->addMultiCellLayout( sizeLayout,   5, 5, 1, 2 );
460   // <More...> button
461   moreBtn = new QPushButton( tr( "More..." ), productsPage );
462   // layouting
463   pageLayout->addMultiCellWidget( targetLab,    0, 0, 0, 1 );
464   pageLayout->addWidget         ( targetFolder, 1,    0    );
465   pageLayout->addWidget         ( targetBtn,    1,    1    );
466   pageLayout->addMultiCellWidget( moreBox,      2, 2, 0, 1 );
467   pageLayout->addWidget         ( moreBtn,      3,    1    );
468   pageLayout->setRowStretch( 2, 5 );
469   //pageLayout->addRowSpacing( 6, 10 );
470   // xml reader
471   QFile xmlfile(xmlFileName);
472   if ( xmlfile.exists() ) {
473     QXmlInputSource source( &xmlfile );
474     QXmlSimpleReader reader;
475
476     StructureParser* handler = new StructureParser( this );
477     handler->setProductsList(productsView);
478     handler->setTargetDir(targetFolder);
479     handler->setTempDir(tempFolder);
480     reader.setContentHandler( handler );
481     reader.parse( source );  
482   }
483   // set first item to be selected
484   if ( productsView->childCount() > 0 ) {
485     productsView->setSelected( productsView->firstChild(), true );
486     onSelectionChanged();
487   }
488   // adding page
489   addPage( productsPage, tr( "Installation settings" ) );
490   // connecting signals
491   connect( productsView, SIGNAL( selectionChanged() ), 
492                                               this, SLOT( onSelectionChanged() ) );
493   connect( productsView, SIGNAL( itemToggled( QCheckListItem* ) ), 
494                                               this, SLOT( onItemToggled( QCheckListItem* ) ) );
495   connect( unselectBtn,  SIGNAL( clicked() ), this, SLOT( onProdBtn() ) );
496   // connecting signals
497   connect( targetFolder, SIGNAL( textChanged( const QString& ) ),
498                                               this, SLOT( directoryChanged( const QString& ) ) );
499   connect( targetBtn,    SIGNAL( clicked() ), this, SLOT( browseDirectory() ) );
500   connect( tempFolder,   SIGNAL( textChanged( const QString& ) ),
501                                               this, SLOT( directoryChanged( const QString& ) ) );
502   connect( tempBtn,      SIGNAL( clicked() ), this, SLOT( browseDirectory() ) );
503   connect( moreBtn,      SIGNAL( clicked() ), this, SLOT( onMoreBtn() ) );
504   // start on default - non-advanced - mode
505   moreBox->hide();
506 }
507 // ================================================================
508 /*!
509  *  SALOME_InstallWizard::setupCheckPage
510  *  Creates prestart page
511  */
512 // ================================================================
513 void SALOME_InstallWizard::setupCheckPage()
514 {
515   // create page
516   prestartPage = new QWidget( this, "PrestartPage" );
517   QVBoxLayout* pageLayout = new QVBoxLayout( prestartPage ); 
518   pageLayout->setMargin( 0 ); pageLayout->setSpacing( 6 );
519   // choice text view
520   choices = new QTextEdit( prestartPage );
521   choices->setReadOnly( true );
522   choices->setTextFormat( RichText );
523   choices->setUndoRedoEnabled ( false );
524   QWhatsThis::add( choices, tr( "Displays information about installation settings you made" ) );
525   QToolTip::add  ( choices, tr( "Displays information about installation settings you made" ) );
526   QPalette pal = choices->palette();
527   pal.setColor( QColorGroup::Base, QApplication::palette().active().background() );
528   choices->setPalette( pal );
529   choices->setMinimumHeight( 10 );
530   // layouting
531   pageLayout->addWidget( choices );
532   pageLayout->setStretchFactor( choices, 5 );
533   // adding page
534   addPage( prestartPage, tr( "Check your choice" ) );
535 }
536 // ================================================================
537 /*!
538  *  SALOME_InstallWizard::setupProgressPage
539  *  Creates progress page
540  */
541 // ================================================================
542 void SALOME_InstallWizard::setupProgressPage()
543 {
544   // create page
545   progressPage = new QWidget( this, "progressPage" );
546   QGridLayout* pageLayout = new QGridLayout( progressPage ); 
547   pageLayout->setMargin( 0 ); pageLayout->setSpacing( 6 );
548   // top splitter
549   splitter = new QSplitter( Vertical, progressPage );
550   splitter->setOpaqueResize( true );
551   // the parent for the widgets
552   QWidget* widget = new QWidget( splitter );
553   QGridLayout* layout = new QGridLayout( widget ); 
554   layout->setMargin( 0 ); layout->setSpacing( 6 );
555   // installation progress view box
556   installInfo = new QTextEdit( widget );
557   installInfo->setReadOnly( true );
558   installInfo->setTextFormat( RichText );
559   installInfo->setUndoRedoEnabled ( false );
560   installInfo->setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Expanding ) );
561   installInfo->setMinimumSize( 100, 10 );
562   QWhatsThis::add( installInfo, tr( "Displays installation process" ) );
563   QToolTip::add  ( installInfo, tr( "Displays installation process" ) );
564   // parameters for the script
565   parametersLab = new QLabel( tr( "Enter your answer here:" ), widget );
566   passedParams = new QLineEdit ( widget );
567   QWhatsThis::add( passedParams, tr( "Use this field to enter answer for the running script when it is necessary") );
568   QToolTip::add  ( passedParams, tr( "Use this field to enter answer for the running script when it is necessary") );
569   // layouting
570   layout->addWidget( installInfo,   0, 0 );
571   layout->addWidget( parametersLab, 1, 0 );
572   layout->addWidget( passedParams,  2, 0 );
573   layout->addRowSpacing( 3, 6 );
574   // the parent for the widgets
575   widget = new QWidget( splitter );
576   layout = new QGridLayout( widget ); 
577   layout->setMargin( 0 ); layout->setSpacing( 6 );
578   // installation results view box
579   QLabel* resultLab = new QLabel( tr( "Installation Status:" ), widget );
580   progressView = new ProgressView( widget );
581   progressView->setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Expanding ) );
582   progressView->setMinimumSize( 100, 10 );
583   QWhatsThis::add( progressView, tr( "Displays installation status" ) );
584   QToolTip::add  ( progressView, tr( "Displays installation status" ) );
585   // layouting
586   layout->addRowSpacing( 0, 6 );
587   layout->addWidget( resultLab,    1, 0 );
588   layout->addWidget( progressView, 2, 0 );
589   // layouting
590   pageLayout->addWidget( splitter, 0, 0 );
591   // adding page
592   addPage( progressPage, tr( "Installation progress" ) );
593   // connect signals
594   connect( passedParams, SIGNAL( returnPressed() ), this, SLOT( onReturnPressed() ) ) ;
595 }
596 // ================================================================
597 /*!
598  *  SALOME_InstallWizard::setupReadmePage
599  *  Creates readme page
600  */
601 // ================================================================
602 void SALOME_InstallWizard::setupReadmePage()
603 {
604   // create page
605   readmePage = new QWidget( this, "ReadmePage" );
606   QVBoxLayout* pageLayout = new QVBoxLayout( readmePage ); 
607   pageLayout->setMargin( 0 ); pageLayout->setSpacing( 6 );
608   // README info text box
609   readme = new QTextEdit( readmePage );
610   readme->setReadOnly( true );
611   readme->setTextFormat( PlainText );
612   readme->setUndoRedoEnabled ( false );
613   QWhatsThis::add( readme, tr( "Displays README information" ) );
614   QToolTip::add  ( readme, tr( "Displays README information" ) );
615   QPalette pal = readme->palette();
616   pal.setColor( QColorGroup::Base, QApplication::palette().active().background() );
617   readme->setPalette( pal );
618   readme->setMinimumHeight( 10 );
619   // <Launch SALOME> button
620   runSalomeBtn = new QPushButton( tr( "Launch SALOME" ), readmePage );
621   QWhatsThis::add( runSalomeBtn, tr( "Click this button to run SALOME desktop" ) );
622   QToolTip::add  ( runSalomeBtn, tr( "Click this button to run SALOME desktop" ) );
623   QHBoxLayout* hLayout = new QHBoxLayout;
624   hLayout->addWidget( runSalomeBtn ); hLayout->addStretch();
625   // layouting
626   pageLayout->addWidget( readme );
627   pageLayout->setStretchFactor( readme, 5 );
628   pageLayout->addLayout( hLayout );
629   // connecting signals
630   connect( runSalomeBtn, SIGNAL( clicked() ), this, SLOT( onLaunchSalome() ) );
631   // loading README file
632   QString readmeFile = QDir::currentDirPath() + "/README";
633   QString text;
634   if ( readFile( readmeFile, text ) )
635     readme->setText( text );
636   else
637     readme->setText( tr( "README file has not been found" ) );
638   // adding page
639   addPage( readmePage, tr( "Finish installation" ) );
640 }
641 // ================================================================
642 /*!
643  *  SALOME_InstallWizard::showChoiceInfo
644  *  Displays choice info
645  */
646 // ================================================================
647 void SALOME_InstallWizard::showChoiceInfo()
648 {
649   choices->clear();
650
651   long totSize, tempSize;
652   checkSize( &totSize, &tempSize );
653   int nbProd = 0;
654   QString text;
655
656   if ( !xmlFileName.isEmpty() ) {
657     text += tr( "Configuration file" )+ ": <b>" + xmlFileName + "</b><br>";
658     text += "<br>";
659   }
660   if ( !myOS.isEmpty() ) {
661     text += tr( "Target platform" ) + ": <b>" + myOS + "</b><br>";
662     text += "<br>";
663   }
664   text += tr( "Products to be used" ) + ":<ul>";
665   QCheckListItem* item = (QCheckListItem*)( productsView->firstChild() );
666   while( item ) {
667     if ( productsMap.contains( item ) ) {
668       if ( item->childCount() > 0 ) {
669         if ( productsView->isNative( item ) ) {
670           text += "<li><b>" + item->text() + "</b> " + tr( "as native" ) + "<br>";
671           nbProd++;
672         }
673       }
674     }
675     item = (QCheckListItem*)( item->nextSibling() );
676   }
677   if ( nbProd == 0 ) {
678     text += "<li><b>" + tr( "none" ) + "</b><br>";
679   }
680   text += "</ul>";
681   nbProd = 0;
682   text += tr( "Products to be installed" ) + ":<ul>";
683   item = (QCheckListItem*)( productsView->firstChild() );
684   while( item ) {
685     if ( productsMap.contains( item ) ) {
686       if ( item->childCount() > 0 ) {
687         if ( productsView->isBinaries( item ) ) {
688           text += "<li><b>" + item->text() + "</b> " + tr( "as binaries" ) + "<br>";
689           nbProd++;
690         }
691         else if ( productsView->isSources( item ) ) {
692           text+= "<li><b>" + item->text() + "</b> " + tr( "as sources" ) + "<br>";
693           nbProd++;
694         }
695       }
696       else if ( item->isOn() ) {
697         text+= "<li><b>" + item->text() + "</b><br>";
698         nbProd++;
699       }
700     }
701     item = (QCheckListItem*)( item->nextSibling() );
702   }
703   if ( nbProd == 0 ) {
704     text += "<li><b>" + tr( "none" ) + "</b><br>";
705   }
706   text += "</ul>";
707   text += tr( "Total disk space required:" ) + " <b>" + QString::number( totSize ) + " Kb</b><br>" ;
708   text += tr( "Space for temporary files required:" ) + " <b>" + QString::number( tempSize ) + " Kb</b><br>" ;
709   text += "<br>";
710   text += tr( "Target directory:" ) + " <b>" + QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() ) + "</b><br>";
711   // VSR: Temporary folder is used always now and it is not necessary to disable it -->
712   // if ( tempSize > 0 )
713   // VSR: <----------------------------------------------------------------------------
714   text += tr( "Temp directory:" ) + " <b>" + QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + "</b><br>";
715   text += "<br>";
716   choices->setText( text );
717 }
718 // ================================================================
719 /*!
720  *  SALOME_InstallWizard::acceptData
721  *  Validates page when <Next> button is clicked
722  */
723 // ================================================================
724 bool SALOME_InstallWizard::acceptData( const QString& pageTitle )
725 {
726   QString tmpstr;
727   QWidget* aPage = InstallWizard::page( pageTitle );
728   if ( aPage == productsPage ) {
729     // ########## check if any products are selected to be installed
730     long totSize, tempSize;
731     bool anySelected = checkSize( &totSize, &tempSize );
732     if ( !anySelected ) {
733       QMessageBox::warning( this, 
734                             tr( "Warning" ), 
735                             tr( "Select one or more products to install" ), 
736                             QMessageBox::Ok, 
737                             QMessageBox::NoButton,
738                             QMessageBox::NoButton );
739       return false;
740     }
741     // ########## check target and temp directories (existence and available disk space)
742     // get dirs
743     QString targetDir = QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() );
744     QString tempDir   = QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() );
745     // directories should differ
746 //    if (!targetDir.isEmpty() && tempDir == targetDir) {
747 //      QMessageBox::warning( this, 
748 //                          tr( "Warning" ), 
749 //                          tr( "Target and temporary directories must be different"), 
750 //                          QMessageBox::Ok, 
751 //                          QMessageBox::NoButton, 
752 //                          QMessageBox::NoButton );
753 //      return false;
754 //    }
755     // check target directory
756     if ( targetDir.isEmpty() ) {
757       QMessageBox::warning( this, 
758                             tr( "Warning" ), 
759                             tr( "Please, enter valid target directory path" ), 
760                             QMessageBox::Ok, 
761                             QMessageBox::NoButton,
762                             QMessageBox::NoButton );
763       return false;
764     }
765     QFileInfo fi( QDir::cleanDirPath( targetDir ) );
766     if ( !fi.exists() ) {
767       bool toCreate = 
768         QMessageBox::warning( this, 
769                               tr( "Warning" ), 
770                               tr( "The directory %1 doesn't exist.\n"
771                                   "Do you want to create directory?" ).arg( fi.absFilePath() ), 
772                               QMessageBox::Yes, 
773                               QMessageBox::No,
774                               QMessageBox::NoButton ) == QMessageBox::Yes;
775       if ( !toCreate) 
776         return false;
777       if ( !makeDir( fi.absFilePath(), tmpstr ) ) {
778         QMessageBox::critical( this, 
779                                tr( "Error" ), 
780                                tr( "Can't create the directory\n%1").arg( fi.absFilePath() ), 
781                                QMessageBox::Ok, 
782                                QMessageBox::NoButton, 
783                                QMessageBox::NoButton );
784         return false;
785       }
786     }
787     if ( !fi.isDir() ) {
788       QMessageBox::warning( this, 
789                             tr( "Warning" ), 
790                             tr( "The directory %1 is not a directory.\n"
791                                 "Please, enter valid target directory path" ).arg( fi.absFilePath() ), 
792                             QMessageBox::Ok, 
793                             QMessageBox::NoButton,
794                             QMessageBox::NoButton );
795       return false;
796     }
797     if ( !fi.isWritable() ) {
798       QMessageBox::warning( this, 
799                             tr( "Warning" ), 
800                             tr( "The directory %1 is not writeable.\n"
801                                 "Please, enter valid target directory path or change permissions" ).arg( fi.absFilePath() ), 
802                             QMessageBox::Ok, 
803                             QMessageBox::NoButton,
804                             QMessageBox::NoButton );
805       return false;
806     }
807     if ( hasSpace( fi.absFilePath() ) &&
808          QMessageBox::warning( this,
809                                tr( "Warning" ),
810                                tr( "The target directory contains space symbols.\n"
811                                    "This may cause problems with compiling or installing of products.\n\n"
812                                    "Do you want to continue?"),
813                                QMessageBox::Yes,
814                                QMessageBox::No,
815                                QMessageBox::NoButton ) == QMessageBox::No ) {
816       return false;
817     }
818     QString binDir = "./Products/BINARIES";
819     if ( !myOS.isEmpty() )
820       binDir += "/" + myOS;
821     QFileInfo fib( QDir::cleanDirPath( binDir ) );
822     if ( !fib.exists() ) {
823       QMessageBox::warning( this, 
824                             tr( "Warning" ), 
825                             tr( "The directory %1 doesn't exist.\n"
826                                 "This directory must contain binaries archives." ).arg( fib.absFilePath() ));
827     }
828     // run script that checks available disk space for installing of products    // returns 1 in case of error
829     QString script = "./config_files/checkSize.sh '";
830     script += fi.absFilePath();
831     script += "' ";
832     script += QString( "%1" ).arg( totSize );
833 #ifdef DEBUG
834     cout << "script = " << script << endl;
835 #endif
836     if ( system( script ) ) {
837       QMessageBox::critical( this, 
838                              tr( "Out of space" ), 
839                              tr( "There is not available disk space for installing of selected products" ), 
840                              QMessageBox::Ok, 
841                              QMessageBox::NoButton, 
842                              QMessageBox::NoButton );
843       return false;
844     }
845     // check temp directory
846     if ( tempDir.isEmpty() ) {
847       if ( moreMode ) {
848         QMessageBox::warning( this, 
849                               tr( "Warning" ), 
850                               tr( "Please, enter valid temp directory path" ), 
851                               QMessageBox::Ok, 
852                               QMessageBox::NoButton,
853                               QMessageBox::NoButton );
854         return false; 
855       }
856       else {
857         tempFolder->setText( "/tmp" );
858       }
859     }
860     QFileInfo fit( QDir::cleanDirPath( tempDir ) );
861     if ( !makeDir( fit.absFilePath() + TEMPDIRNAME, tmpCreated ) ) {
862       QMessageBox::critical( this, 
863                              tr( "Error" ), 
864                              tr( "Can't use temporary directory.\nCheck permissions for the %1 directory.").arg( fit.absFilePath() ), 
865                              QMessageBox::Ok, 
866                              QMessageBox::NoButton, 
867                              QMessageBox::NoButton );
868       return false;
869     }
870     // run script that check available disk space for temporary files
871     // returns 1 in case of error
872     QString tscript = "./config_files/checkSize.sh '";
873     tscript += fit.absFilePath();
874     tscript += "' ";
875     tscript += QString( "%1" ).arg( tempSize );
876 #ifdef DEBUG
877     cout << "script = " << tscript << endl;
878 #endif
879     if ( system( tscript ) ) {
880       QMessageBox::critical( this, 
881                              tr( "Out of space" ), 
882                              tr( "There is not available disk space for the temporary files" ), 
883                              QMessageBox::Ok, 
884                              QMessageBox::NoButton, 
885                              QMessageBox::NoButton );
886       return false;
887     }
888 // VSR: <------------------------------------------------------------------------------
889     // ########## check native products
890     QCheckListItem* item = (QCheckListItem*)( productsView->firstChild() );
891     QStringList natives;
892     while( item ) {
893       if ( productsMap.contains( item ) ) {
894         if ( item->childCount() > 0 ) {
895           if ( !productsView->isNone( item ) ) {
896             if ( item->text(2).isEmpty() || item->text(2).isNull() ) {
897               QMessageBox::warning( this, 
898                                     tr( "Warning" ), 
899                                     tr( "You don't have a defined script for %1").arg(item->text(0)), 
900                                     QMessageBox::Ok, 
901                                     QMessageBox::NoButton, 
902                                     QMessageBox::NoButton );
903               productsView->setNone( item );
904               return false;
905             } else {
906               QFileInfo fi( QString("./config_files/") + item->text(2) );
907               if ( !fi.exists() ) {
908                 QMessageBox::warning( this, 
909                                       tr( "Warning" ),  
910                                       tr( "%1 required for %2 doesn't exist.").arg("./config_files/" + item->text(2)).arg(item->text(0)),  
911                                       QMessageBox::Ok, 
912                                       QMessageBox::NoButton, 
913                                       QMessageBox::NoButton );
914                 productsView->setNone( item );
915                 return false;
916               }       
917             }
918           }
919           // collect native products
920           if ( productsView->isNative( item ) ) {
921             if ( natives.find( item->text(0) ) == natives.end() )
922               natives.append( item->text(0) );
923           } 
924           else if ( productsView->isBinaries( item ) || productsView->isSources( item ) ) {
925             QStringList dependOn = productsMap[ item ].getDependancies();
926             for ( int i = 0; i < (int)dependOn.count(); i++ ) {
927               QCheckListItem* depitem = findItem( dependOn[ i ] );
928               if ( depitem ) {
929                 if ( productsView->isNative( depitem ) && natives.find( depitem->text(0) ) == natives.end() )
930                   natives.append( depitem->text(0) );
931               } 
932               else {
933                 QMessageBox::warning( this, 
934                                       tr( "Warning" ), 
935                                       tr( "%1 is required for %2 %3 installation.\n"
936                                           "Please, add this product in config.xml file.").arg(dependOn[ i ]).arg(item->text(0)).arg(item->text(1)), 
937                                       QMessageBox::Ok, 
938                                       QMessageBox::NoButton, 
939                                       QMessageBox::NoButton );
940                 return false;
941               }
942             }
943           }
944         }
945       }
946       item = (QCheckListItem*)( item->nextSibling() );
947     }
948     QString tmpFolder = QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + TEMPDIRNAME;
949     QString tgtFolder = QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() );
950     for ( unsigned i = 0; i < natives.count(); i++ ) {
951       item = findItem( natives[ i ] );
952       if ( item ) {
953         QString script = "cd ./config_files/;" + item->text(2) + " try_native " +
954                 QFileInfo( tmpFolder ).absFilePath() + " " + QDir::currentDirPath() + "/Products " + QFileInfo( tgtFolder ).absFilePath() + " " +
955                 QUOTE(DefineDependeces(productsMap)) + " " + item->text(0);
956
957 #ifdef DEBUG
958         cout << "1. Script : " << script << endl;
959 #endif
960         if ( system( script ) ) {
961           QMessageBox::warning( this, 
962                                 tr( "Warning" ), 
963                                 tr( "You don't have native %1 %2 installed").arg(item->text(0)).arg(item->text(1)), 
964                                 QMessageBox::Ok, 
965                                 QMessageBox::NoButton, 
966                                 QMessageBox::NoButton );
967           productsView->setNone( item );
968           return false;
969         }
970       }
971       else {
972         QMessageBox::warning( this, 
973                               tr( "Warning" ), 
974                               tr( "%The product %1 %2 required for installation.\n"
975                                   "Please, add this product in config.xml file.").arg(item->text(0)).arg(item->text(1)),
976                               QMessageBox::Ok, 
977                               QMessageBox::NoButton, 
978                               QMessageBox::NoButton );
979         return false;
980       }
981     }
982   }
983   return InstallWizard::acceptData( pageTitle );
984 }
985 // ================================================================
986 /*!
987  *  SALOME_InstallWizard::checkSize
988  *  Calculates disk space required for the installation
989  */
990 // ================================================================
991 bool SALOME_InstallWizard::checkSize( long* totSize, long* tempSize )
992 {
993   long tots = 0, temps = 0;
994   int nbSelected = 0;
995
996   MapProducts::Iterator mapIter;
997   for ( mapIter = productsMap.begin(); mapIter != productsMap.end(); ++mapIter ) {
998     QCheckListItem* item = mapIter.key();
999     Dependancies dep = mapIter.data();
1000     if ( productsView->isBinaries( item ) ) {
1001       tots += dep.getSize();
1002     }
1003     else if ( productsView->isSources( item ) ) {
1004       tots += dep.getSize(true);
1005       temps = max( temps, dep.getTempSize() );
1006     }
1007     if ( !productsView->isNone( item ) )
1008       nbSelected++;
1009   }
1010  
1011   if ( totSize )
1012     *totSize = tots;
1013   if ( tempSize )
1014     *tempSize = temps;
1015   return ( nbSelected > 0 );
1016 }
1017 // ================================================================
1018 /*!
1019  *  SALOME_InstallWizard::checkProductPage
1020  *  Checks products page validity (directories and products selection) and
1021  *  enabled/disables "Next" button for the Products page
1022  */
1023 // ================================================================
1024 void SALOME_InstallWizard::checkProductPage()
1025 {
1026   long tots = 0, temps = 0;
1027
1028   // check if any product is selected;
1029   bool isAnyProductSelected = checkSize( &tots, &temps );
1030   // check if target directory is valid
1031   bool isTargetDirValid = !targetFolder->text().stripWhiteSpace().isEmpty();
1032   // check if temp directory is valid
1033   bool isTempDirValid = !moreMode || !tempFolder->text().stripWhiteSpace().isEmpty();
1034
1035   // update required size information
1036   requiredSize->setText( QString::number( tots )  + " Kb");
1037   requiredTemp->setText( QString::number( temps ) + " Kb");
1038
1039   // enable/disable "Next" button
1040   setNextEnabled( productsPage, isAnyProductSelected && isTargetDirValid && isTempDirValid );
1041 }
1042 // ================================================================
1043 /*!
1044  *  SALOME_InstallWizard::setPrerequisites
1045  *  Sets the product and all products this one depends on to be checked ( recursively )
1046  */
1047 // ================================================================
1048 void SALOME_InstallWizard::setPrerequisites( QCheckListItem* item )
1049 {
1050   if ( !productsMap.contains( item ) )
1051     return;
1052   if ( productsView->isNone( item ) )
1053     return;
1054   // get all prerequisites
1055   QStringList dependOn = productsMap[ item ].getDependancies();
1056   for ( int i = 0; i < (int)dependOn.count(); i++ ) {
1057     MapProducts::Iterator itProd;
1058     for ( itProd = productsMap.begin(); itProd != productsMap.end(); ++itProd ) {
1059       if ( itProd.data().getName() == dependOn[ i ] ) {
1060         if ( productsView->isNone( itProd.key() ) ) {
1061           QString defMode = itProd.data().getDefault();
1062           if ( defMode.isEmpty() )
1063             defMode = tr( "install binaries" );
1064           if ( defMode == tr( "install binaries" ) )
1065             productsView->setBinaries( itProd.key() );
1066           else if ( defMode == tr( "install sources" ) )
1067             productsView->setSources( itProd.key() );
1068           else if ( defMode == tr( "use native" ) )
1069             productsView->setNative( itProd.key() );
1070           setPrerequisites( itProd.key() );
1071         }
1072       }
1073     }
1074   }
1075 }
1076 // ================================================================
1077 /*!
1078  *  SALOME_InstallWizard::launchScript
1079  *  Runs installation script
1080  */
1081 // ================================================================
1082 void SALOME_InstallWizard::launchScript()
1083 {
1084   // try to find product being processed now
1085   QString prodProc = progressView->findStatus( Processing );
1086   if ( !prodProc.isNull() ) {
1087 #ifdef DEBUG
1088     cout << "Found <Processing>: " << prodProc.latin1() << endl;
1089 #endif
1090
1091     // if found - set status to "completed"
1092     progressView->setStatus( prodProc, Completed );
1093     // ... and call this method again
1094     launchScript();
1095     return;
1096   }
1097   // else try to find next product which is not processed yet
1098   prodProc = progressView->findStatus( Waiting );
1099   if ( !prodProc.isNull() ) {
1100 #ifdef DEBUG
1101     cout << "Found <Waiting>: " << prodProc.latin1() << endl;
1102 #endif
1103     // if found - set status to "processed" and run script
1104     progressView->setStatus( prodProc, Processing );
1105     progressView->ensureVisible( prodProc );
1106
1107     QCheckListItem* item = findItem( prodProc );
1108     Dependancies dep = productsMap[ item ];
1109     // fill in script parameters
1110     shellProcess->clearArguments();
1111     // ... script name
1112     shellProcess->setWorkingDirectory( QDir::cleanDirPath( QFileInfo( "./config_files/" ).absFilePath() ) );
1113     shellProcess->addArgument( item->text(2) );
1114
1115     // ... temp folder
1116     QString tmpFolder = QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + TEMPDIRNAME;
1117     if( !tempFolder->isEnabled() )
1118       tmpFolder = "/tmp";
1119
1120     // ... binaries ?
1121     if ( productsView->isBinaries( item ) ) {
1122       shellProcess->addArgument( "install_binary" );
1123       shellProcess->addArgument( QFileInfo( tmpFolder ).absFilePath() );
1124       QString binDir = QDir::currentDirPath() + "/Products/BINARIES";
1125       if ( !myOS.isEmpty() )
1126         binDir += "/" + myOS;
1127       shellProcess->addArgument( binDir );
1128     }
1129     // ... sources ?
1130     else if ( productsView->isSources( item ) ) {
1131       shellProcess->addArgument( "install_source" );
1132       shellProcess->addArgument( QFileInfo( tmpFolder ).absFilePath() );
1133       shellProcess->addArgument( QDir::currentDirPath() + "/Products/SOURCES" );
1134     }
1135     // ... native ?
1136     else if ( productsView->isNative( item ) ) {
1137       shellProcess->addArgument( "try_native" );
1138       shellProcess->addArgument( QFileInfo( tmpFolder ).absFilePath() );
1139       shellProcess->addArgument( QDir::currentDirPath() + "/Products" );
1140     }
1141     // ... not install : try to find preinstalled
1142     else {
1143       shellProcess->addArgument( "try_preinstalled" );
1144       shellProcess->addArgument( QFileInfo( tmpFolder ).absFilePath() );
1145       shellProcess->addArgument( QDir::currentDirPath() + "/Products" );
1146     }
1147     // ... target folder
1148     QString tgtFolder = QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() );
1149     shellProcess->addArgument( QFileInfo( tgtFolder ).absFilePath() );
1150     
1151
1152     QString depproducts = DefineDependeces(productsMap); 
1153 #ifdef DEBUG
1154     cout << "Dependancies"<< depproducts.latin1() << endl;
1155 #endif
1156
1157     shellProcess->addArgument( depproducts );
1158     // ... product name - currently instaled product
1159     shellProcess->addArgument( item->text(0) );
1160
1161     // run script
1162     if ( !shellProcess->start() ) {
1163       // error handling can be here
1164 #ifdef DEBUG
1165       cout << "error" << endl;
1166 #endif
1167     }
1168     return;
1169   }
1170 #ifdef DEBUG
1171   cout << "All products have been installed successfully" << endl;
1172 #endif
1173   // all products installed successfully
1174   // <Next> button
1175   nextButton()->setEnabled( true );
1176   nextButton()->setText( tr( "&Next >" ) );
1177   QWhatsThis::add( nextButton(), tr( "Moves to the next step of the installation procedure" ) );
1178   QToolTip::add  ( nextButton(), tr( "Moves to the next step of the installation procedure" ) );
1179   nextButton()->disconnect();
1180   connect( nextButton(), SIGNAL( clicked() ), this, SLOT( next() ) );
1181   // <Back> button
1182   backButton()->setEnabled( true );
1183   // script parameters
1184   passedParams->clear();
1185   passedParams->setEnabled( false );
1186   QFont f = parametersLab->font(); f.setBold( false ); parametersLab->setFont( f );
1187   if ( isMinimized() )
1188     showNormal();
1189   raise();
1190 }
1191 // ================================================================
1192 /*!
1193  *  SALOME_InstallWizard::onMoreBtn
1194  *  <More...> button slot
1195  */
1196 // ================================================================
1197 void SALOME_InstallWizard::onMoreBtn()
1198 {
1199   if ( moreMode ) {
1200     moreBox->hide();
1201     moreBtn->setText( tr( "More..." ) );
1202   }
1203   else {
1204     moreBox->show();
1205     moreBtn->setText( tr( "Less..." ) );
1206   }
1207   qApp->processEvents();
1208   moreMode = !moreMode;
1209   InstallWizard::layOut();
1210   qApp->processEvents();
1211   if ( !isMaximized() ) {
1212     //setGeometry( geometry().x(), geometry().y(), geometry().width(), 0 );
1213     resize( geometry().width(), 0 );
1214     qApp->processEvents();
1215   }
1216   checkProductPage();
1217 }
1218 // ================================================================
1219 /*!
1220  *  SALOME_InstallWizard::onLaunchSalome
1221  *  <Launch Salome> button slot
1222  */
1223 // ================================================================
1224 void SALOME_InstallWizard::onLaunchSalome()
1225 {
1226   QCheckListItem* item = 0;
1227   if ( ( item = findItem( "SalomePro-Bin" ) ) ) {
1228     QFileInfo fi( targetFolder->text() + "/SalomePro-" + item->text(1) + "/salome" );
1229     if ( fi.exists() ) {
1230       QString script;
1231       script += "cd " + targetFolder->text() + "/SalomePro-" + item->text(1) + "; ";
1232       script += "source salome.csh; ";
1233       //script += "cd bin; ";
1234       //script += "runSalome > /dev/null";
1235       script += "salome -g > /dev/null";
1236       script = "(csh -c '" + script + "')";
1237 #ifdef DEBUG
1238       cout << script.latin1() << endl;
1239 #endif
1240       if ( system( script.latin1() ) ){
1241         QMessageBox::warning( this, 
1242                               tr( "Error" ), 
1243                               tr( "Can't launch SALOME" ), 
1244                               QMessageBox::Ok, 
1245                               QMessageBox::NoButton,
1246                               QMessageBox::NoButton );
1247       }
1248       return;
1249     }
1250   }
1251   QMessageBox::warning( this, 
1252                         tr( "Error" ), 
1253                         tr( "You don't have SALOME binaries installed in the %1 directory!" ).arg( targetFolder->text() ), 
1254                         QMessageBox::Ok, 
1255                         QMessageBox::NoButton,
1256                         QMessageBox::NoButton );
1257 }
1258 // ================================================================
1259 /*!
1260  *  SALOME_InstallWizard::findItem
1261  *  Searches product listview item with given symbolic name 
1262  */
1263 // ================================================================
1264 QCheckListItem* SALOME_InstallWizard::findItem( const QString& sName )
1265 {
1266   MapProducts::Iterator mapIter;
1267   for ( mapIter = productsMap.begin(); mapIter != productsMap.end(); ++mapIter ) {
1268     if ( mapIter.data().getName() == sName )
1269       return mapIter.key();
1270   }
1271   return 0;
1272 }
1273 // ================================================================
1274 /*!
1275  *  SALOME_InstallWizard::abort
1276  *  Sets progress state to Aborted
1277  */
1278 // ================================================================
1279 void SALOME_InstallWizard::abort()
1280 {
1281   QString prod = progressView->findStatus( Processing );
1282   while ( !prod.isNull() ) {
1283     progressView->setStatus( prod, Aborted );
1284     prod = progressView->findStatus( Processing );
1285   }
1286   prod = progressView->findStatus( Waiting );
1287   while ( !prod.isNull() ) {
1288     progressView->setStatus( prod, Aborted );
1289     prod = progressView->findStatus( Waiting );
1290   }
1291 }
1292 // ================================================================
1293 /*!
1294  *  SALOME_InstallWizard::reject
1295  *  Reject slot, clears temporary directory and closes application
1296  */
1297 // ================================================================
1298 void SALOME_InstallWizard::reject()
1299 {
1300 #ifdef DEBUG
1301   cout << "REJECTED" << endl;
1302 #endif
1303   if ( !exitConfirmed ) {
1304     if ( QMessageBox::information( this, 
1305                                    tr( "Exit" ), 
1306                                    tr( "Do you want to quit %1?" ).arg( getIWName() ), 
1307                                    tr( "&Yes" ), 
1308                                    tr( "&No" ),
1309                                    QString::null,
1310                                    0,
1311                                    1 ) == 1 ) {
1312       return;
1313     }
1314     exitConfirmed = true;
1315   }
1316   clean();
1317   InstallWizard::reject();
1318 }
1319 // ================================================================
1320 /*!
1321  *  SALOME_InstallWizard::accept
1322  *  Accept slot, clears temporary directory and closes application
1323  */
1324 // ================================================================
1325 void SALOME_InstallWizard::accept()
1326 {
1327 #ifdef DEBUG
1328   cout << "ACCEPTED" << endl;
1329 #endif
1330   clean();
1331   InstallWizard::accept();
1332 }
1333 // ================================================================
1334 /*!
1335  *  SALOME_InstallWizard::clean
1336  *  Clears and removes temporary directory
1337  */
1338 // ================================================================
1339 void SALOME_InstallWizard::clean()
1340 {
1341   // VSR: first remove temporary files
1342   QString script = "cd ./config_files/; remove_tmp.sh '";
1343   script += tempFolder->text().stripWhiteSpace();
1344   script += "' ";
1345   script += QUOTE(DefineDependeces(productsMap));
1346   script += " > /dev/null";
1347 #ifdef DEBUG
1348   cout << "script = " << script << endl;
1349 #endif
1350   if ( system( script.latin1() ) ) {
1351   }
1352   // VSR: then try to remove created temporary directory
1353   //script = "rm -rf " + QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + TEMPDIRNAME;
1354   if ( !tmpCreated.isNull() ) {
1355     script = "rm -rf " + tmpCreated;
1356     script += " > /dev/null";
1357     if ( system( script.latin1() ) ) {
1358     }
1359 #ifdef DEBUG
1360     cout << "script = " << script << endl;
1361 #endif
1362   }
1363 }
1364 // ================================================================
1365 /*!
1366  *  SALOME_InstallWizard::pageChanged
1367  *  Called when user moves from page to page
1368  */
1369 // ================================================================
1370 void SALOME_InstallWizard::pageChanged( const QString & mytitle)
1371 {
1372   nextButton()->setText( tr( "&Next >" ) );
1373   QWhatsThis::add( nextButton(), tr( "Moves to the next step of the installation procedure" ) );
1374   QToolTip::add  ( nextButton(), tr( "Moves to the next step of the installation procedure" ) );
1375   nextButton()->disconnect();
1376   connect( nextButton(), SIGNAL( clicked() ), this, SLOT( next() ) );
1377   cancelButton()->disconnect();
1378   connect( cancelButton(), SIGNAL( clicked()), this, SLOT( reject() ) );
1379
1380   QWidget* aPage = InstallWizard::page( mytitle );
1381   if ( !aPage )
1382     return;
1383   updateCaption();
1384   if ( aPage == productsPage ) {
1385     // products page
1386     onSelectionChanged();
1387     checkProductPage();
1388   }
1389   else if ( aPage == prestartPage ) {
1390     // prestart page
1391     showChoiceInfo();
1392   }
1393   else if ( aPage == progressPage ) {
1394     if ( previousPage == prestartPage ) {
1395       // progress page
1396       progressView->clear();
1397       installInfo->clear();
1398       passedParams->clear();
1399       passedParams->setEnabled( false );
1400       QFont f = parametersLab->font(); f.setBold( false ); parametersLab->setFont( f );
1401       nextButton()->setText( tr( "&Start" ) );
1402       QWhatsThis::add( nextButton(), tr( "Starts installation process" ) );
1403       QToolTip::add  ( nextButton(), tr( "Starts installation process" ) );
1404       // reconnect Next button - to use it as Start button
1405       nextButton()->disconnect();
1406       connect( nextButton(), SIGNAL( clicked() ), this, SLOT( onStart() ) );
1407       nextButton()->setEnabled( true );
1408       // reconnect Cancel button to terminate process
1409       cancelButton()->disconnect();
1410       connect( cancelButton(), SIGNAL( clicked() ), this, SLOT( tryTerminate() ) );
1411     }
1412   }
1413   else if ( aPage == readmePage ) {
1414     QCheckListItem* item = 0;
1415     runSalomeBtn->setEnabled( ( item = findItem( "SalomePro-Bin" ) ) && 
1416                               QFileInfo( targetFolder->text() + "/SalomePro-" + item->text(1) + "/salome" ).exists() );
1417     finishButton()->setEnabled( true );
1418   }
1419   previousPage = aPage;
1420 #ifdef DEBUG
1421   cout << "previousPage = " << previousPage << endl;
1422 #endif
1423 }
1424 // ================================================================
1425 /*!
1426  *  SALOME_InstallWizard::helpClicked
1427  *  Shows help window
1428  */
1429 // ================================================================
1430 void SALOME_InstallWizard::helpClicked()
1431 {
1432   if ( helpWindow == NULL ) {
1433     helpWindow = HelpWindow::openHelp( this );
1434     if ( helpWindow ) {
1435       helpWindow->show();
1436       helpWindow->installEventFilter( this );
1437     }
1438     else {
1439       QMessageBox::warning( this, 
1440                             tr( "Help file not found" ), 
1441                             tr( "Sorry, help is unavailable" ) );
1442     }
1443   }
1444   else {
1445     helpWindow->raise();
1446     helpWindow->setActiveWindow();
1447   }
1448 }
1449 // ================================================================
1450 /*!
1451  *  SALOME_InstallWizard::browseDirectory
1452  *  Shows directory selection dialog
1453  */
1454 // ================================================================
1455 void SALOME_InstallWizard::browseDirectory()
1456 {
1457   const QObject* theSender = sender();
1458   QLineEdit* theFolder;
1459   if ( theSender == targetBtn )
1460     theFolder = targetFolder;
1461   else if (theSender == tempBtn)
1462     theFolder = tempFolder;
1463   else
1464     return;
1465   QString typedDir = QFileDialog::getExistingDirectory( QDir::cleanDirPath( theFolder->text().stripWhiteSpace() ), this );
1466   if ( !typedDir.isNull() ) {
1467     theFolder->setText( typedDir );
1468     theFolder->end( false );
1469   }
1470   checkProductPage();
1471 }
1472 // ================================================================
1473 /*!
1474  *  SALOME_InstallWizard::directoryChanged
1475  *  Called when directory path (target or temp) is changed
1476  */
1477 // ================================================================
1478 void SALOME_InstallWizard::directoryChanged( const QString& /*text*/ )
1479 {
1480   checkProductPage();
1481 }
1482 // ================================================================
1483 /*!
1484  *  SALOME_InstallWizard::onStart
1485  *  <Start> button's slot - runs installation
1486  */
1487 // ================================================================
1488 void SALOME_InstallWizard::onStart()
1489 {
1490   // clear list of products to install ...
1491   toInstall.clear();
1492   // ... and fill it for new process
1493   QCheckListItem* item = (QCheckListItem*)( productsView->firstChild() );
1494   while( item ) {
1495 //    if ( productsView->isBinaries( item ) || productsView->isSources( item ) || productsView->isNative( item ) ) {
1496       if ( productsMap.contains( item ) )
1497         toInstall.append( productsMap[item].getName() );
1498 //    }
1499     item = (QCheckListItem*)( item->nextSibling() );
1500   }
1501   // if something at all is selected
1502   if ( !toInstall.isEmpty() ) {
1503     // disable <Next> button
1504     nextButton()->setEnabled( false );
1505     // disable <Back> button
1506     backButton()->setEnabled ( false );
1507     // enable script parameters line edit
1508     // VSR commented: 18/09/03: passedParams->setEnabled( true );
1509     // VSR commented: 18/09/03: passedParams->setFocus();
1510     // set status for all products
1511     for ( int i = 0; i < (int)toInstall.count(); i++ ) {
1512       item = findItem( toInstall[ i ] );
1513       QString type = "";
1514       if ( productsView->isBinaries( item ) )
1515         type = tr( "binaries" );
1516       else if ( productsView->isSources( item ) )
1517         type = tr( "sources" );
1518       else if ( productsView->isNative( item ) )
1519         type = tr( "native" );
1520       else 
1521         type = tr( "not install" );
1522       progressView->addProduct( item->text(0), type, item->text(2) );
1523     }
1524     // launch install script
1525     launchScript();
1526   }
1527 }
1528 // ================================================================
1529 /*!
1530  *  SALOME_InstallWizard::onReturnPressed
1531  *  Called when users tries to pass parameters for the script
1532  */
1533 // ================================================================
1534 void SALOME_InstallWizard::onReturnPressed()
1535 {
1536   QString txt = passedParams->text();
1537   installInfo->append( txt );
1538   txt += "\n";
1539   shellProcess->writeToStdin( txt );
1540   passedParams->clear();
1541   progressView->setFocus();
1542   passedParams->setEnabled( false );
1543   QFont f = parametersLab->font(); f.setBold( false ); parametersLab->setFont( f );
1544 }
1545 /*!
1546   Callback function - as response for the script finishing
1547 */
1548 void SALOME_InstallWizard::productInstalled( )
1549 {
1550 #ifdef DEBUG
1551   cout << "process exited" << endl;
1552 #endif
1553   if ( shellProcess->normalExit() ) {
1554 #ifdef DEBUG
1555     cout << "...normal exit" << endl;
1556 #endif
1557     // normal exit - try to proceed installation further
1558     launchScript();
1559   }
1560   else {
1561 #ifdef DEBUG
1562     cout << "...abnormal exit" << endl;
1563 #endif
1564     // installation aborted
1565     abort();
1566     // clear script passed parameters lineedit
1567     passedParams->clear();
1568     passedParams->setEnabled( false );
1569     QFont f = parametersLab->font(); f.setBold( false ); parametersLab->setFont( f );
1570     // enable <Next> button
1571     nextButton()->setEnabled( true );
1572     nextButton()->setText( tr( "&Next >" ) );
1573     QWhatsThis::add( nextButton(), tr( "Moves to the next step of the installation procedure" ) );
1574     QToolTip::add  ( nextButton(), tr( "Moves to the next step of the installation procedure" ) );
1575     nextButton()->disconnect();
1576     connect( nextButton(), SIGNAL( clicked() ), this, SLOT( next() ) );
1577     // enable <Back> button
1578     backButton()->setEnabled( true );
1579   }
1580 }
1581 // ================================================================
1582 /*!
1583  *  SALOME_InstallWizard::tryTerminate
1584  *  Slot, called when <Cancel> button is clicked during installation script running
1585  */
1586 // ================================================================
1587 void SALOME_InstallWizard::tryTerminate()
1588 {
1589   if ( shellProcess->isRunning() ) {
1590     if ( QMessageBox::information( this, 
1591                                    tr( "Exit" ), 
1592                                    tr( "Do you want to quit %1?" ).arg( getIWName() ), 
1593                                    tr( "&Yes" ), 
1594                                    tr( "&No" ),
1595                                    QString::null,
1596                                    0,
1597                                    1 ) == 1 ) {
1598       return;
1599     }
1600     exitConfirmed = true;
1601     // if process still running try to terminate it first
1602     shellProcess->tryTerminate();
1603     abort();
1604     //QTimer::singleShot( 3000, this, SLOT( onCancel() ) );
1605     connect( shellProcess, SIGNAL( processExited() ), this, SLOT( onCancel() ) );
1606   }
1607   else {
1608     // else just quit install wizard
1609     reject();
1610   }
1611 }
1612 // ================================================================
1613 /*!
1614  *  SALOME_InstallWizard::onCancel
1615  *  Kills installation process and quits application
1616  */
1617 // ================================================================
1618 void SALOME_InstallWizard::onCancel()
1619 {
1620   shellProcess->kill();
1621   reject();
1622 }
1623 // ================================================================
1624 /*!
1625  *  SALOME_InstallWizard::onSelectionChanged
1626  *  Called when selection is changed in the products list view
1627  */
1628 // ================================================================
1629 void SALOME_InstallWizard::onSelectionChanged()
1630 {
1631   productsInfo->clear();
1632   QListViewItem* item = productsView->selectedItem();
1633   if ( !item )
1634     return;
1635   if ( item->parent() )
1636     item = item->parent();
1637   QCheckListItem* aItem = (QCheckListItem*)item;
1638   if ( !productsMap.contains( aItem ) )
1639     return;
1640   Dependancies dep = productsMap[ aItem ];
1641   QString text = "<b>" + aItem->text(0) + "</b>" + "<br>";
1642   if ( !aItem->text(1).stripWhiteSpace().isEmpty() )
1643     text += tr( "Version" ) + ": " + aItem->text(1) + "<br>";
1644   text += "<br>";
1645   if ( !dep.getDescription().isEmpty() ) {
1646     text += "<i>" + dep.getDescription() + "</i><br><br>";
1647   }
1648   text += tr( "User choice" ) + ": ";
1649   long totSize = 0, tempSize = 0;
1650   if ( productsView->isBinaries( aItem ) ) {
1651     text += "<b>" + tr( "install binaries" ) + "</b>" + "<br>";
1652     totSize = dep.getSize();
1653   }
1654   else if ( productsView->isSources( aItem ) ) {
1655     text += "<b>" + tr( "install sources" ) + "</b>" + "<br>";
1656     totSize = dep.getSize( true );
1657     tempSize = dep.getTempSize();
1658   }
1659   else if ( productsView->isNative( aItem ) ) {
1660     text += "<b>" + tr( "use native" ) + "</b>" + "<br>";
1661   }
1662   else {
1663     text += "<b>" + tr( "not install" ) + "</b>" + "<br>";
1664   }
1665   
1666   text += tr( "Disk space required" ) + ": " + QString::number( totSize ) + " Kb<br>";
1667   text += tr( "Disk space for tmp files required" ) + ": " + QString::number( tempSize ) + " Kb<br>";
1668   text += "<br>";
1669   QString req = ( dep.getDependancies().count() > 0 ? dep.getDependancies().join(", ") : tr( "none" ) );
1670   text +=  tr( "Prerequisites" ) + ": " + req;
1671   productsInfo->setText( text );
1672 }
1673 // ================================================================
1674 /*!
1675  *  SALOME_InstallWizard::onItemToggled
1676  *  Called when user checks/unchecks any product item
1677  *  Recursively sets all prerequisites and updates "Next" button state
1678  */
1679 // ================================================================
1680 void SALOME_InstallWizard::onItemToggled( QCheckListItem* item )
1681 {
1682   if ( prerequisites->isChecked() ) {
1683     if ( item->parent() )
1684       item = (QCheckListItem*)( item->parent() );
1685     if ( productsMap.contains( item ) ) {
1686       productsView->blockSignals( true );
1687       setPrerequisites( item );
1688       productsView->blockSignals( false );
1689     }
1690   }
1691   onSelectionChanged();
1692   checkProductPage();
1693 }
1694 // ================================================================
1695 /*!
1696  *  SALOME_InstallWizard::onProdBtn
1697  *  This slot is called when user clicks one of <Select Sources>,
1698  *  <Select Binaries>, <Unselect All> buttons ( products page )
1699  */
1700 // ================================================================
1701 void SALOME_InstallWizard::onProdBtn()
1702 {
1703   const QObject* snd = sender();
1704   productsView->blockSignals( true );
1705   if ( snd == unselectBtn ) {
1706     QCheckListItem* item = (QCheckListItem*)( productsView->firstChild() );
1707     while( item ) {
1708       productsView->setNone( item );
1709       item = (QCheckListItem*)( item->nextSibling() );
1710     }
1711   }
1712   productsView->blockSignals( false );
1713   onSelectionChanged();
1714   checkProductPage();
1715 }
1716 // ================================================================
1717 /*!
1718  *  SALOME_InstallWizard::wroteToStdin
1719  *  QProcess slot: -->something was written to stdin
1720  */
1721 // ================================================================
1722 void SALOME_InstallWizard::wroteToStdin( )
1723 {
1724 #ifdef DEBUG
1725   cout << "Something was sent to stdin" << endl;
1726 #endif
1727 }
1728 // ================================================================
1729 /*!
1730  *  SALOME_InstallWizard::readFromStdout
1731  *  QProcess slot: -->something was written to stdout
1732  */
1733 // ================================================================
1734 void SALOME_InstallWizard::readFromStdout( )
1735 {
1736 #ifdef DEBUG
1737   cout << "Something was sent to stdout" << endl;
1738 #endif
1739   while ( shellProcess->canReadLineStdout() ) {
1740     installInfo->append( QString( shellProcess->readLineStdout() ) );
1741     installInfo->scrollToBottom();
1742   }
1743   QString str( shellProcess->readStdout() );
1744   if ( !str.isEmpty() ) {
1745     installInfo->append( str );
1746     installInfo->scrollToBottom();
1747   }
1748 }
1749 // ================================================================
1750 /*!
1751  *  SALOME_InstallWizard::readFromStderr
1752  *  QProcess slot: -->something was written to stderr
1753  */
1754 // ================================================================
1755 void SALOME_InstallWizard::readFromStderr( )
1756 {
1757 #ifdef DEBUG
1758   cout << "Something was sent to stderr" << endl;
1759 #endif
1760   while ( shellProcess->canReadLineStderr() ) {
1761     installInfo->append( QString( shellProcess->readLineStderr() ) );
1762     installInfo->scrollToBottom();
1763   }
1764   QString str( shellProcess->readStderr() );
1765   if ( !str.isEmpty() ) {
1766     installInfo->append( str );
1767     installInfo->scrollToBottom();
1768   }
1769   passedParams->setEnabled( true );
1770   passedParams->setFocus();
1771   QFont f = parametersLab->font(); f.setBold( true ); parametersLab->setFont( f );
1772 }
1773 // ================================================================
1774 /*!
1775  *  SALOME_InstallWizard::setDependancies
1776  *  Sets dependancies for the product item
1777  */
1778 // ================================================================
1779 void SALOME_InstallWizard::setDependancies( QCheckListItem* item, Dependancies dep)
1780 {
1781   productsMap[item] = dep;
1782 }
1783 // ================================================================
1784 /*!
1785  *  SALOME_InstallWizard::polish
1786  *  Polishing of the widget - to set right initial size
1787  */
1788 // ================================================================
1789 void SALOME_InstallWizard::polish()
1790 {
1791   resize( 0, 0 );
1792   InstallWizard::polish();
1793 }
1794 // ================================================================
1795 /*!
1796  *  SALOME_InstallWizard::updateCaption
1797  *  Updates caption according to the current page number
1798  */
1799 // ================================================================
1800 void SALOME_InstallWizard::updateCaption()
1801 {
1802   QWidget* aPage = InstallWizard::currentPage();
1803   if ( !aPage ) 
1804     return;
1805   InstallWizard::setCaption( tr( myCaption ) + " " +
1806                              tr( getIWName() ) + " - " +
1807                              tr( "Step %1 of %2").arg( QString::number( this->indexOf( aPage )+1 ) ).arg( QString::number( this->pageCount() ) ) );
1808 }