Salome HOME
a0f3de5f34c01722b89a3a45048aec9019db0f4f
[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( 200, 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::setProductOn
1045  *  Sets the product and all products this one depends on to be checked ( recursively )
1046  */
1047 // ================================================================
1048 void SALOME_InstallWizard::setProductOn( QCheckListItem* item, int install )
1049 {
1050   if ( !productsMap.contains( item ) )
1051     return;
1052   if ( productsView->isNone( item ) ) {
1053     if ( install == 1 )
1054       productsView->setBinaries( item );
1055     else if ( install == 0 )
1056       productsView->setSources( item );
1057     else if ( install == 2 )
1058       productsView->setNative( item );
1059   }
1060   // get all prerequisites
1061   QStringList dependOn = productsMap[ item ].getDependancies();
1062   for ( int i = 0; i < (int)dependOn.count(); i++ ) {
1063     MapProducts::Iterator itProd;
1064     for ( itProd = productsMap.begin(); itProd != productsMap.end(); ++itProd ) {
1065       if ( itProd.data().getName() == dependOn[ i ] )
1066         setProductOn( itProd.key(), 1 );
1067     }
1068   }
1069 }
1070 // ================================================================
1071 /*!
1072  *  SALOME_InstallWizard::launchScript
1073  *  Runs installation script
1074  */
1075 // ================================================================
1076 void SALOME_InstallWizard::launchScript()
1077 {
1078   // try to find product being processed now
1079   QString prodProc = progressView->findStatus( Processing );
1080   if ( !prodProc.isNull() ) {
1081 #ifdef DEBUG
1082     cout << "Found <Processing>: " << prodProc.latin1() << endl;
1083 #endif
1084
1085     // if found - set status to "completed"
1086     progressView->setStatus( prodProc, Completed );
1087     // ... and call this method again
1088     launchScript();
1089     return;
1090   }
1091   // else try to find next product which is not processed yet
1092   prodProc = progressView->findStatus( Waiting );
1093   if ( !prodProc.isNull() ) {
1094 #ifdef DEBUG
1095     cout << "Found <Waiting>: " << prodProc.latin1() << endl;
1096 #endif
1097     // if found - set status to "processed" and run script
1098     progressView->setStatus( prodProc, Processing );
1099     progressView->ensureVisible( prodProc );
1100
1101     QCheckListItem* item = findItem( prodProc );
1102     Dependancies dep = productsMap[ item ];
1103     // fill in script parameters
1104     shellProcess->clearArguments();
1105     // ... script name
1106     shellProcess->setWorkingDirectory( QDir::cleanDirPath( QFileInfo( "./config_files/" ).absFilePath() ) );
1107     shellProcess->addArgument( item->text(2) );
1108
1109     // ... temp folder
1110     QString tmpFolder = QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + TEMPDIRNAME;
1111     if( !tempFolder->isEnabled() )
1112       tmpFolder = "/tmp";
1113
1114     // ... binaries ?
1115     if ( productsView->isBinaries( item ) ) {
1116       shellProcess->addArgument( "install_binary" );
1117       shellProcess->addArgument( QFileInfo( tmpFolder ).absFilePath() );
1118       QString binDir = QDir::currentDirPath() + "/Products/BINARIES";
1119       if ( !myOS.isEmpty() )
1120         binDir += "/" + myOS;
1121       shellProcess->addArgument( binDir );
1122     }
1123     // ... sources ?
1124     else if ( productsView->isSources( item ) ) {
1125       shellProcess->addArgument( "install_source" );
1126       shellProcess->addArgument( QFileInfo( tmpFolder ).absFilePath() );
1127       shellProcess->addArgument( QDir::currentDirPath() + "/Products/SOURCES" );
1128     }
1129     // ... native ?
1130     else if ( productsView->isNative( item ) ) {
1131       shellProcess->addArgument( "try_native" );
1132       shellProcess->addArgument( QFileInfo( tmpFolder ).absFilePath() );
1133       shellProcess->addArgument( QDir::currentDirPath() + "/Products" );
1134     }
1135     // ... not install : try to find preinstalled
1136     else {
1137       shellProcess->addArgument( "try_preinstalled" );
1138       shellProcess->addArgument( QFileInfo( tmpFolder ).absFilePath() );
1139       shellProcess->addArgument( QDir::currentDirPath() + "/Products" );
1140     }
1141     // ... target folder
1142     QString tgtFolder = QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() );
1143     shellProcess->addArgument( QFileInfo( tgtFolder ).absFilePath() );
1144     
1145
1146     QString depproducts = DefineDependeces(productsMap); 
1147 #ifdef DEBUG
1148     cout << "Dependancies"<< depproducts.latin1() << endl;
1149 #endif
1150
1151     shellProcess->addArgument( depproducts );
1152     // ... product name - currently instaled product
1153     shellProcess->addArgument( item->text(0) );
1154
1155     // run script
1156     if ( !shellProcess->start() ) {
1157       // error handling can be here
1158 #ifdef DEBUG
1159       cout << "error" << endl;
1160 #endif
1161     }
1162     return;
1163   }
1164 #ifdef DEBUG
1165   cout << "All products have been installed successfully" << endl;
1166 #endif
1167   // all products installed successfully
1168   // <Next> button
1169   nextButton()->setEnabled( true );
1170   nextButton()->setText( tr( "&Next >" ) );
1171   QWhatsThis::add( nextButton(), tr( "Moves to the next step of the installation procedure" ) );
1172   QToolTip::add  ( nextButton(), tr( "Moves to the next step of the installation procedure" ) );
1173   nextButton()->disconnect();
1174   connect( nextButton(), SIGNAL( clicked() ), this, SLOT( next() ) );
1175   // <Back> button
1176   backButton()->setEnabled( true );
1177   // script parameters
1178   passedParams->clear();
1179   passedParams->setEnabled( false );
1180   QFont f = parametersLab->font(); f.setBold( false ); parametersLab->setFont( f );
1181   if ( isMinimized() )
1182     showNormal();
1183   raise();
1184 }
1185 // ================================================================
1186 /*!
1187  *  SALOME_InstallWizard::onMoreBtn
1188  *  <More...> button slot
1189  */
1190 // ================================================================
1191 void SALOME_InstallWizard::onMoreBtn()
1192 {
1193   if ( moreMode ) {
1194     moreBox->hide();
1195     moreBtn->setText( tr( "More..." ) );
1196   }
1197   else {
1198     moreBox->show();
1199     moreBtn->setText( tr( "Less..." ) );
1200   }
1201   qApp->processEvents();
1202   moreMode = !moreMode;
1203   InstallWizard::layOut();
1204   qApp->processEvents();
1205   if ( !isMaximized() ) {
1206     //setGeometry( geometry().x(), geometry().y(), geometry().width(), 0 );
1207     resize( geometry().width(), 0 );
1208     qApp->processEvents();
1209   }
1210   checkProductPage();
1211 }
1212 // ================================================================
1213 /*!
1214  *  SALOME_InstallWizard::onLaunchSalome
1215  *  <Launch Salome> button slot
1216  */
1217 // ================================================================
1218 void SALOME_InstallWizard::onLaunchSalome()
1219 {
1220   QCheckListItem* item = 0;
1221   if ( ( item = findItem( "SalomePro-Bin" ) ) ) {
1222     QFileInfo fi( targetFolder->text() + "/SalomePro-" + item->text(1) + "/salome" );
1223     if ( fi.exists() ) {
1224       QString script;
1225       script += "cd " + targetFolder->text() + "/SalomePro-" + item->text(1) + "; ";
1226       script += "source salome.csh; ";
1227       //script += "cd bin; ";
1228       //script += "runSalome > /dev/null";
1229       script += "salome -g > /dev/null";
1230       script = "(csh -c '" + script + "')";
1231 #ifdef DEBUG
1232       cout << script.latin1() << endl;
1233 #endif
1234       if ( system( script.latin1() ) ){
1235         QMessageBox::warning( this, 
1236                               tr( "Error" ), 
1237                               tr( "Can't launch SALOME" ), 
1238                               QMessageBox::Ok, 
1239                               QMessageBox::NoButton,
1240                               QMessageBox::NoButton );
1241       }
1242       return;
1243     }
1244   }
1245   QMessageBox::warning( this, 
1246                         tr( "Error" ), 
1247                         tr( "You don't have SALOME binaries installed in the %1 directory!" ).arg( targetFolder->text() ), 
1248                         QMessageBox::Ok, 
1249                         QMessageBox::NoButton,
1250                         QMessageBox::NoButton );
1251 }
1252 // ================================================================
1253 /*!
1254  *  SALOME_InstallWizard::findItem
1255  *  Searches product listview item with given symbolic name 
1256  */
1257 // ================================================================
1258 QCheckListItem* SALOME_InstallWizard::findItem( const QString& sName )
1259 {
1260   MapProducts::Iterator mapIter;
1261   for ( mapIter = productsMap.begin(); mapIter != productsMap.end(); ++mapIter ) {
1262     if ( mapIter.data().getName() == sName )
1263       return mapIter.key();
1264   }
1265   return 0;
1266 }
1267 // ================================================================
1268 /*!
1269  *  SALOME_InstallWizard::abort
1270  *  Sets progress state to Aborted
1271  */
1272 // ================================================================
1273 void SALOME_InstallWizard::abort()
1274 {
1275   QString prod = progressView->findStatus( Processing );
1276   while ( !prod.isNull() ) {
1277     progressView->setStatus( prod, Aborted );
1278     prod = progressView->findStatus( Processing );
1279   }
1280   prod = progressView->findStatus( Waiting );
1281   while ( !prod.isNull() ) {
1282     progressView->setStatus( prod, Aborted );
1283     prod = progressView->findStatus( Waiting );
1284   }
1285 }
1286 // ================================================================
1287 /*!
1288  *  SALOME_InstallWizard::reject
1289  *  Reject slot, clears temporary directory and closes application
1290  */
1291 // ================================================================
1292 void SALOME_InstallWizard::reject()
1293 {
1294 #ifdef DEBUG
1295   cout << "REJECTED" << endl;
1296 #endif
1297   if ( !exitConfirmed ) {
1298     if ( QMessageBox::information( this, 
1299                                    tr( "Exit" ), 
1300                                    tr( "Do you want to quit %1?" ).arg( getIWName() ), 
1301                                    tr( "&Yes" ), 
1302                                    tr( "&No" ),
1303                                    QString::null,
1304                                    0,
1305                                    1 ) == 1 ) {
1306       return;
1307     }
1308     exitConfirmed = true;
1309   }
1310   clean();
1311   InstallWizard::reject();
1312 }
1313 // ================================================================
1314 /*!
1315  *  SALOME_InstallWizard::accept
1316  *  Accept slot, clears temporary directory and closes application
1317  */
1318 // ================================================================
1319 void SALOME_InstallWizard::accept()
1320 {
1321 #ifdef DEBUG
1322   cout << "ACCEPTED" << endl;
1323 #endif
1324   clean();
1325   InstallWizard::accept();
1326 }
1327 // ================================================================
1328 /*!
1329  *  SALOME_InstallWizard::clean
1330  *  Clears and removes temporary directory
1331  */
1332 // ================================================================
1333 void SALOME_InstallWizard::clean()
1334 {
1335   // VSR: first remove temporary files
1336   QString script = "cd ./config_files/; remove_tmp.sh '";
1337   script += tempFolder->text().stripWhiteSpace();
1338   script += "' ";
1339   script += QUOTE(DefineDependeces(productsMap));
1340   script += " > /dev/null";
1341 #ifdef DEBUG
1342   cout << "script = " << script << endl;
1343 #endif
1344   if ( system( script.latin1() ) ) {
1345   }
1346   // VSR: then try to remove created temporary directory
1347   //script = "rm -rf " + QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + TEMPDIRNAME;
1348   if ( !tmpCreated.isNull() ) {
1349     script = "rm -rf " + tmpCreated;
1350     script += " > /dev/null";
1351     if ( system( script.latin1() ) ) {
1352     }
1353 #ifdef DEBUG
1354     cout << "script = " << script << endl;
1355 #endif
1356   }
1357 }
1358 // ================================================================
1359 /*!
1360  *  SALOME_InstallWizard::pageChanged
1361  *  Called when user moves from page to page
1362  */
1363 // ================================================================
1364 void SALOME_InstallWizard::pageChanged( const QString & mytitle)
1365 {
1366   nextButton()->setText( tr( "&Next >" ) );
1367   QWhatsThis::add( nextButton(), tr( "Moves to the next step of the installation procedure" ) );
1368   QToolTip::add  ( nextButton(), tr( "Moves to the next step of the installation procedure" ) );
1369   nextButton()->disconnect();
1370   connect( nextButton(), SIGNAL( clicked() ), this, SLOT( next() ) );
1371   cancelButton()->disconnect();
1372   connect( cancelButton(), SIGNAL( clicked()), this, SLOT( reject() ) );
1373
1374   QWidget* aPage = InstallWizard::page( mytitle );
1375   if ( !aPage )
1376     return;
1377   updateCaption();
1378   if ( aPage == productsPage ) {
1379     // products page
1380     onSelectionChanged();
1381     checkProductPage();
1382   }
1383   else if ( aPage == prestartPage ) {
1384     // prestart page
1385     showChoiceInfo();
1386   }
1387   else if ( aPage == progressPage ) {
1388     if ( previousPage == prestartPage ) {
1389       // progress page
1390       progressView->clear();
1391       installInfo->clear();
1392       passedParams->clear();
1393       passedParams->setEnabled( false );
1394       QFont f = parametersLab->font(); f.setBold( false ); parametersLab->setFont( f );
1395       nextButton()->setText( tr( "&Start" ) );
1396       QWhatsThis::add( nextButton(), tr( "Starts installation process" ) );
1397       QToolTip::add  ( nextButton(), tr( "Starts installation process" ) );
1398       // reconnect Next button - to use it as Start button
1399       nextButton()->disconnect();
1400       connect( nextButton(), SIGNAL( clicked() ), this, SLOT( onStart() ) );
1401       nextButton()->setEnabled( true );
1402       // reconnect Cancel button to terminate process
1403       cancelButton()->disconnect();
1404       connect( cancelButton(), SIGNAL( clicked() ), this, SLOT( tryTerminate() ) );
1405     }
1406   }
1407   else if ( aPage == readmePage ) {
1408     QCheckListItem* item = 0;
1409     runSalomeBtn->setEnabled( ( item = findItem( "SalomePro-Bin" ) ) && 
1410                               QFileInfo( targetFolder->text() + "/SalomePro-" + item->text(1) + "/salome" ).exists() );
1411     finishButton()->setEnabled( true );
1412   }
1413   previousPage = aPage;
1414 #ifdef DEBUG
1415   cout << "previousPage = " << previousPage << endl;
1416 #endif
1417 }
1418 // ================================================================
1419 /*!
1420  *  SALOME_InstallWizard::helpClicked
1421  *  Shows help window
1422  */
1423 // ================================================================
1424 void SALOME_InstallWizard::helpClicked()
1425 {
1426   if ( helpWindow == NULL ) {
1427     helpWindow = HelpWindow::openHelp( this );
1428     if ( helpWindow ) {
1429       helpWindow->show();
1430       helpWindow->installEventFilter( this );
1431     }
1432     else {
1433       QMessageBox::warning( this, 
1434                             tr( "Help file not found" ), 
1435                             tr( "Sorry, help is unavailable" ) );
1436     }
1437   }
1438   else {
1439     helpWindow->raise();
1440     helpWindow->setActiveWindow();
1441   }
1442 }
1443 // ================================================================
1444 /*!
1445  *  SALOME_InstallWizard::browseDirectory
1446  *  Shows directory selection dialog
1447  */
1448 // ================================================================
1449 void SALOME_InstallWizard::browseDirectory()
1450 {
1451   const QObject* theSender = sender();
1452   QLineEdit* theFolder;
1453   if ( theSender == targetBtn )
1454     theFolder = targetFolder;
1455   else if (theSender == tempBtn)
1456     theFolder = tempFolder;
1457   else
1458     return;
1459   QString typedDir = QFileDialog::getExistingDirectory( QDir::cleanDirPath( theFolder->text().stripWhiteSpace() ), this );
1460   if ( !typedDir.isNull() ) {
1461     theFolder->setText( typedDir );
1462     theFolder->end( false );
1463   }
1464   checkProductPage();
1465 }
1466 // ================================================================
1467 /*!
1468  *  SALOME_InstallWizard::directoryChanged
1469  *  Called when directory path (target or temp) is changed
1470  */
1471 // ================================================================
1472 void SALOME_InstallWizard::directoryChanged( const QString& /*text*/ )
1473 {
1474   checkProductPage();
1475 }
1476 // ================================================================
1477 /*!
1478  *  SALOME_InstallWizard::onStart
1479  *  <Start> button's slot - runs installation
1480  */
1481 // ================================================================
1482 void SALOME_InstallWizard::onStart()
1483 {
1484   // clear list of products to install ...
1485   toInstall.clear();
1486   // ... and fill it for new process
1487   QCheckListItem* item = (QCheckListItem*)( productsView->firstChild() );
1488   while( item ) {
1489 //    if ( productsView->isBinaries( item ) || productsView->isSources( item ) || productsView->isNative( item ) ) {
1490       if ( productsMap.contains( item ) )
1491         toInstall.append( productsMap[item].getName() );
1492 //    }
1493     item = (QCheckListItem*)( item->nextSibling() );
1494   }
1495   // if something at all is selected
1496   if ( !toInstall.isEmpty() ) {
1497     // disable <Next> button
1498     nextButton()->setEnabled( false );
1499     // disable <Back> button
1500     backButton()->setEnabled ( false );
1501     // enable script parameters line edit
1502     // VSR commented: 18/09/03: passedParams->setEnabled( true );
1503     // VSR commented: 18/09/03: passedParams->setFocus();
1504     // set status for all products
1505     for ( int i = 0; i < (int)toInstall.count(); i++ ) {
1506       item = findItem( toInstall[ i ] );
1507       QString type = "";
1508       if ( productsView->isBinaries( item ) )
1509         type = tr( "binaries" );
1510       else if ( productsView->isSources( item ) )
1511         type = tr( "sources" );
1512       else if ( productsView->isNative( item ) )
1513         type = tr( "native" );
1514       else 
1515         type = tr( "not install" );
1516       progressView->addProduct( item->text(0), type, item->text(2) );
1517     }
1518     // launch install script
1519     launchScript();
1520   }
1521 }
1522 // ================================================================
1523 /*!
1524  *  SALOME_InstallWizard::onReturnPressed
1525  *  Called when users tries to pass parameters for the script
1526  */
1527 // ================================================================
1528 void SALOME_InstallWizard::onReturnPressed()
1529 {
1530   QString txt = passedParams->text();
1531   installInfo->append( txt );
1532   txt += "\n";
1533   shellProcess->writeToStdin( txt );
1534   passedParams->clear();
1535   progressView->setFocus();
1536   passedParams->setEnabled( false );
1537   QFont f = parametersLab->font(); f.setBold( false ); parametersLab->setFont( f );
1538 }
1539 /*!
1540   Callback function - as response for the script finishing
1541 */
1542 void SALOME_InstallWizard::productInstalled( )
1543 {
1544 #ifdef DEBUG
1545   cout << "process exited" << endl;
1546 #endif
1547   if ( shellProcess->normalExit() ) {
1548 #ifdef DEBUG
1549     cout << "...normal exit" << endl;
1550 #endif
1551     // normal exit - try to proceed installation further
1552     launchScript();
1553   }
1554   else {
1555 #ifdef DEBUG
1556     cout << "...abnormal exit" << endl;
1557 #endif
1558     // installation aborted
1559     abort();
1560     // clear script passed parameters lineedit
1561     passedParams->clear();
1562     passedParams->setEnabled( false );
1563     QFont f = parametersLab->font(); f.setBold( false ); parametersLab->setFont( f );
1564     // enable <Next> button
1565     nextButton()->setEnabled( true );
1566     nextButton()->setText( tr( "&Next >" ) );
1567     QWhatsThis::add( nextButton(), tr( "Moves to the next step of the installation procedure" ) );
1568     QToolTip::add  ( nextButton(), tr( "Moves to the next step of the installation procedure" ) );
1569     nextButton()->disconnect();
1570     connect( nextButton(), SIGNAL( clicked() ), this, SLOT( next() ) );
1571     // enable <Back> button
1572     backButton()->setEnabled( true );
1573   }
1574 }
1575 // ================================================================
1576 /*!
1577  *  SALOME_InstallWizard::tryTerminate
1578  *  Slot, called when <Cancel> button is clicked during installation script running
1579  */
1580 // ================================================================
1581 void SALOME_InstallWizard::tryTerminate()
1582 {
1583   if ( shellProcess->isRunning() ) {
1584     if ( QMessageBox::information( this, 
1585                                    tr( "Exit" ), 
1586                                    tr( "Do you want to quit %1?" ).arg( getIWName() ), 
1587                                    tr( "&Yes" ), 
1588                                    tr( "&No" ),
1589                                    QString::null,
1590                                    0,
1591                                    1 ) == 1 ) {
1592       return;
1593     }
1594     exitConfirmed = true;
1595     // if process still running try to terminate it first
1596     shellProcess->tryTerminate();
1597     abort();
1598     //QTimer::singleShot( 3000, this, SLOT( onCancel() ) );
1599     connect( shellProcess, SIGNAL( processExited() ), this, SLOT( onCancel() ) );
1600   }
1601   else {
1602     // else just quit install wizard
1603     reject();
1604   }
1605 }
1606 // ================================================================
1607 /*!
1608  *  SALOME_InstallWizard::onCancel
1609  *  Kills installation process and quits application
1610  */
1611 // ================================================================
1612 void SALOME_InstallWizard::onCancel()
1613 {
1614   shellProcess->kill();
1615   reject();
1616 }
1617 // ================================================================
1618 /*!
1619  *  SALOME_InstallWizard::onSelectionChanged
1620  *  Called when selection is changed in the products list view
1621  */
1622 // ================================================================
1623 void SALOME_InstallWizard::onSelectionChanged()
1624 {
1625   productsInfo->clear();
1626   QListViewItem* item = productsView->selectedItem();
1627   if ( !item )
1628     return;
1629   if ( item->parent() )
1630     item = item->parent();
1631   QCheckListItem* aItem = (QCheckListItem*)item;
1632   if ( !productsMap.contains( aItem ) )
1633     return;
1634   Dependancies dep = productsMap[ aItem ];
1635   QString text = "<b>" + aItem->text(0) + "</b>" + "<br>";
1636   if ( !aItem->text(1).stripWhiteSpace().isEmpty() )
1637     text += tr( "Version" ) + ": " + aItem->text(1) + "<br>";
1638   text += "<br>";
1639   text += tr( "User choice" ) + ": ";
1640   long totSize = 0, tempSize = 0;
1641   if ( productsView->isBinaries( aItem ) ) {
1642     text += "<b>" + tr( "install binaries" ) + "</b>" + "<br>";
1643     totSize = dep.getSize();
1644   }
1645   else if ( productsView->isSources( aItem ) ) {
1646     text += "<b>" + tr( "install sources" ) + "</b>" + "<br>";
1647     totSize = dep.getSize( true );
1648     tempSize = dep.getTempSize();
1649   }
1650   else if ( productsView->isNative( aItem ) ) {
1651     text += "<b>" + tr( "use native" ) + "</b>" + "<br>";
1652   }
1653   else {
1654     text += "<b>" + tr( "not install" ) + "</b>" + "<br>";
1655   }
1656   
1657   text += tr( "Disk space required" ) + ": " + QString::number( totSize ) + " Kb<br>";
1658   text += tr( "Disk space for tmp files required" ) + ": " + QString::number( tempSize ) + " Kb<br>";
1659   text += "<br>";
1660   QString req = ( dep.getDependancies().count() > 0 ? dep.getDependancies().join(", ") : tr( "none" ) );
1661   text +=  tr( "Prerequisites" ) + ": " + req;
1662   productsInfo->setText( text );
1663 }
1664 // ================================================================
1665 /*!
1666  *  SALOME_InstallWizard::onItemToggled
1667  *  Called when user checks/unchecks any product item
1668  *  Recursively sets all prerequisites and updates "Next" button state
1669  */
1670 // ================================================================
1671 void SALOME_InstallWizard::onItemToggled( QCheckListItem* item )
1672 {
1673   if ( prerequisites->isChecked() ) {
1674     if ( item->parent() )
1675       item = (QCheckListItem*)( item->parent() );
1676     if ( productsMap.contains( item ) ) {
1677       productsView->blockSignals( true );
1678       if ( productsView->isNative( item ) )
1679         setProductOn( item, 2 );
1680       else if ( productsView->isBinaries( item ) )
1681         setProductOn( item, 1 );
1682       else if ( productsView->isSources( item ) )
1683         setProductOn( item, 0 );
1684       productsView->blockSignals( false );
1685     }
1686   }
1687   onSelectionChanged();
1688   checkProductPage();
1689 }
1690 // ================================================================
1691 /*!
1692  *  SALOME_InstallWizard::onProdBtn
1693  *  This slot is called when user clicks one of <Select Sources>,
1694  *  <Select Binaries>, <Unselect All> buttons ( products page )
1695  */
1696 // ================================================================
1697 void SALOME_InstallWizard::onProdBtn()
1698 {
1699   const QObject* snd = sender();
1700   productsView->blockSignals( true );
1701   if ( snd == unselectBtn ) {
1702     QCheckListItem* item = (QCheckListItem*)( productsView->firstChild() );
1703     while( item ) {
1704       productsView->setNone( item );
1705       item = (QCheckListItem*)( item->nextSibling() );
1706     }
1707   }
1708   productsView->blockSignals( false );
1709   onSelectionChanged();
1710   checkProductPage();
1711 }
1712 // ================================================================
1713 /*!
1714  *  SALOME_InstallWizard::wroteToStdin
1715  *  QProcess slot: -->something was written to stdin
1716  */
1717 // ================================================================
1718 void SALOME_InstallWizard::wroteToStdin( )
1719 {
1720 #ifdef DEBUG
1721   cout << "Something was sent to stdin" << endl;
1722 #endif
1723 }
1724 // ================================================================
1725 /*!
1726  *  SALOME_InstallWizard::readFromStdout
1727  *  QProcess slot: -->something was written to stdout
1728  */
1729 // ================================================================
1730 void SALOME_InstallWizard::readFromStdout( )
1731 {
1732 #ifdef DEBUG
1733   cout << "Something was sent to stdout" << endl;
1734 #endif
1735   while ( shellProcess->canReadLineStdout() ) {
1736     installInfo->append( QString( shellProcess->readLineStdout() ) );
1737     installInfo->scrollToBottom();
1738   }
1739   QString str( shellProcess->readStdout() );
1740   if ( !str.isEmpty() ) {
1741     installInfo->append( str );
1742     installInfo->scrollToBottom();
1743   }
1744 }
1745 // ================================================================
1746 /*!
1747  *  SALOME_InstallWizard::readFromStderr
1748  *  QProcess slot: -->something was written to stderr
1749  */
1750 // ================================================================
1751 void SALOME_InstallWizard::readFromStderr( )
1752 {
1753 #ifdef DEBUG
1754   cout << "Something was sent to stderr" << endl;
1755 #endif
1756   while ( shellProcess->canReadLineStderr() ) {
1757     installInfo->append( QString( shellProcess->readLineStderr() ) );
1758     installInfo->scrollToBottom();
1759   }
1760   QString str( shellProcess->readStderr() );
1761   if ( !str.isEmpty() ) {
1762     installInfo->append( str );
1763     installInfo->scrollToBottom();
1764   }
1765   passedParams->setEnabled( true );
1766   passedParams->setFocus();
1767   QFont f = parametersLab->font(); f.setBold( true ); parametersLab->setFont( f );
1768 }
1769 // ================================================================
1770 /*!
1771  *  SALOME_InstallWizard::setDependancies
1772  *  Sets dependancies for the product item
1773  */
1774 // ================================================================
1775 void SALOME_InstallWizard::setDependancies( QCheckListItem* item, Dependancies dep)
1776 {
1777   productsMap[item] = dep;
1778 }
1779 // ================================================================
1780 /*!
1781  *  SALOME_InstallWizard::polish
1782  *  Polishing of the widget - to set right initial size
1783  */
1784 // ================================================================
1785 void SALOME_InstallWizard::polish()
1786 {
1787   resize( 0, 0 );
1788   InstallWizard::polish();
1789 }
1790 // ================================================================
1791 /*!
1792  *  SALOME_InstallWizard::updateCaption
1793  *  Updates caption according to the current page number
1794  */
1795 // ================================================================
1796 void SALOME_InstallWizard::updateCaption()
1797 {
1798   QWidget* aPage = InstallWizard::currentPage();
1799   if ( !aPage ) 
1800     return;
1801   InstallWizard::setCaption( tr( myCaption ) + " " +
1802                              tr( getIWName() ) + " - " +
1803                              tr( "Step %1 of %2").arg( QString::number( this->indexOf( aPage )+1 ) ).arg( QString::number( this->pageCount() ) ) );
1804 }