]> SALOME platform Git repositories - tools/install.git/blob - src/SALOME_InstallWizard.cxx
Salome HOME
09c1be3bbc5e86fbbd606e116ccbe7b9312559cc
[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 QString tmpDirName() { return QString(  "/INSTALLWORK" ) + QString::number( getpid() ); }
50 #define TEMPDIRNAME tmpDirName()
51
52 // ================================================================
53 /*!
54  *  DefineDependeces [ static ]
55  *  Defines list of dependancies as string separated by space symbols
56  */
57 // ================================================================
58 static QString DefineDependeces(MapProducts& theProductsMap) {
59   QStringList aProducts;
60   for ( MapProducts::Iterator mapIter = theProductsMap.begin(); mapIter != theProductsMap.end(); ++mapIter ) {
61     QCheckListItem* item = mapIter.key();
62     Dependancies dep = mapIter.data();
63     QStringList deps = dep.getDependancies();
64     for (int i = 0; i<(int)deps.count(); i++ ) {
65       if ( !aProducts.contains( deps[i] ) )
66         aProducts.append( deps[i] );
67     }
68     if ( !aProducts.contains( item->text(0) ) )
69       aProducts.append( item->text(0) );
70   }
71   return aProducts.join(" ");
72 }
73
74 #define QUOTE(arg) QString("'") + QString(arg) + QString("'")
75
76 /* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
77                T H E   O L D   I M P L E M E N T A T I O N 
78 static QString DefineDependeces(MapProducts& theProductsMap, QCheckListItem* product ){
79   QStringList aProducts;
80   if ( theProductsMap.contains( product ) ) {
81     Dependancies dep = theProductsMap[ product ];
82     QStringList deps = dep.getDependancies();
83     for (int i = 0; i<(int)deps.count(); i++ ) {
84       aProducts.append( deps[i] );
85     }
86   }
87   return QString("\"") + aProducts.join(" ") + QString("\"");
88 }
89 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */
90
91 // ================================================================
92 /*!
93  *  makeDir [ static ]
94  *  Makes directory recursively, returns false if not succedes
95  */
96 // ================================================================
97 static bool makeDir( const QString& theDir, QString& theCreated )
98 {
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         tempDir = "/tmp";
858         tempFolder->setText( tempDir );
859       }
860     }
861     QFileInfo fit( QDir::cleanDirPath( tempDir ) );
862     if ( !makeDir( fit.absFilePath() + TEMPDIRNAME, tmpCreated ) ) {
863       QMessageBox::critical( this, 
864                              tr( "Error" ), 
865                              tr( "Can't use temporary directory.\nCheck permissions for the %1 directory.").arg( fit.absFilePath() ), 
866                              QMessageBox::Ok, 
867                              QMessageBox::NoButton, 
868                              QMessageBox::NoButton );
869       return false;
870     }
871     // run script that check available disk space for temporary files
872     // returns 1 in case of error
873     QString tscript = "./config_files/checkSize.sh '";
874     tscript += fit.absFilePath();
875     tscript += "' ";
876     tscript += QString( "%1" ).arg( tempSize );
877 #ifdef DEBUG
878     cout << "script = " << tscript << endl;
879 #endif
880     if ( system( tscript ) ) {
881       QMessageBox::critical( this, 
882                              tr( "Out of space" ), 
883                              tr( "There is not available disk space for the temporary files" ), 
884                              QMessageBox::Ok, 
885                              QMessageBox::NoButton, 
886                              QMessageBox::NoButton );
887       return false;
888     }
889 // VSR: <------------------------------------------------------------------------------
890     // ########## check native products
891     QCheckListItem* item = (QCheckListItem*)( productsView->firstChild() );
892     QStringList natives;
893     while( item ) {
894       if ( productsMap.contains( item ) ) {
895         if ( item->childCount() > 0 ) {
896           if ( !productsView->isNone( item ) ) {
897             if ( item->text(2).isEmpty() || item->text(2).isNull() ) {
898               QMessageBox::warning( this, 
899                                     tr( "Warning" ), 
900                                     tr( "You don't have a defined script for %1").arg(item->text(0)), 
901                                     QMessageBox::Ok, 
902                                     QMessageBox::NoButton, 
903                                     QMessageBox::NoButton );
904               productsView->setNone( item );
905               return false;
906             } else {
907               QFileInfo fi( QString("./config_files/") + item->text(2) );
908               if ( !fi.exists() ) {
909                 QMessageBox::warning( this, 
910                                       tr( "Warning" ),  
911                                       tr( "%1 required for %2 doesn't exist.").arg("./config_files/" + item->text(2)).arg(item->text(0)),  
912                                       QMessageBox::Ok, 
913                                       QMessageBox::NoButton, 
914                                       QMessageBox::NoButton );
915                 productsView->setNone( item );
916                 return false;
917               }       
918             }
919           }
920           // collect native products
921           if ( productsView->isNative( item ) ) {
922             if ( natives.find( item->text(0) ) == natives.end() )
923               natives.append( item->text(0) );
924           } 
925           else if ( productsView->isBinaries( item ) || productsView->isSources( item ) ) {
926             QStringList dependOn = productsMap[ item ].getDependancies();
927             for ( int i = 0; i < (int)dependOn.count(); i++ ) {
928               QCheckListItem* depitem = findItem( dependOn[ i ] );
929               if ( depitem ) {
930                 if ( productsView->isNative( depitem ) && natives.find( depitem->text(0) ) == natives.end() )
931                   natives.append( depitem->text(0) );
932               } 
933               else {
934                 QMessageBox::warning( this, 
935                                       tr( "Warning" ), 
936                                       tr( "%1 is required for %2 %3 installation.\n"
937                                           "Please, add this product in config.xml file.").arg(dependOn[ i ]).arg(item->text(0)).arg(item->text(1)), 
938                                       QMessageBox::Ok, 
939                                       QMessageBox::NoButton, 
940                                       QMessageBox::NoButton );
941                 return false;
942               }
943             }
944           }
945         }
946       }
947       item = (QCheckListItem*)( item->nextSibling() );
948     }
949     QString tmpFolder = QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + TEMPDIRNAME;
950     QString tgtFolder = QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() );
951     for ( unsigned i = 0; i < natives.count(); i++ ) {
952       item = findItem( natives[ i ] );
953       if ( item ) {
954         QString script = "cd ./config_files/;" + item->text(2) + " try_native " +
955                 QFileInfo( tmpFolder ).absFilePath() + " " + QDir::currentDirPath() + "/Products " + QFileInfo( tgtFolder ).absFilePath() + " " +
956                 QUOTE(DefineDependeces(productsMap)) + " " + item->text(0);
957
958 #ifdef DEBUG
959         cout << "1. Script : " << script << endl;
960 #endif
961         if ( system( script ) ) {
962           QMessageBox::warning( this, 
963                                 tr( "Warning" ), 
964                                 tr( "You don't have native %1 %2 installed").arg(item->text(0)).arg(item->text(1)), 
965                                 QMessageBox::Ok, 
966                                 QMessageBox::NoButton, 
967                                 QMessageBox::NoButton );
968           productsView->setNone( item );
969           return false;
970         }
971       }
972       else {
973         QMessageBox::warning( this, 
974                               tr( "Warning" ), 
975                               tr( "%The product %1 %2 required for installation.\n"
976                                   "Please, add this product in config.xml file.").arg(item->text(0)).arg(item->text(1)),
977                               QMessageBox::Ok, 
978                               QMessageBox::NoButton, 
979                               QMessageBox::NoButton );
980         return false;
981       }
982     }
983   }
984   return InstallWizard::acceptData( pageTitle );
985 }
986 // ================================================================
987 /*!
988  *  SALOME_InstallWizard::checkSize
989  *  Calculates disk space required for the installation
990  */
991 // ================================================================
992 bool SALOME_InstallWizard::checkSize( long* totSize, long* tempSize )
993 {
994   long tots = 0, temps = 0;
995   int nbSelected = 0;
996
997   MapProducts::Iterator mapIter;
998   for ( mapIter = productsMap.begin(); mapIter != productsMap.end(); ++mapIter ) {
999     QCheckListItem* item = mapIter.key();
1000     Dependancies dep = mapIter.data();
1001     if ( productsView->isBinaries( item ) ) {
1002       tots += dep.getSize();
1003     }
1004     else if ( productsView->isSources( item ) ) {
1005       tots += dep.getSize(true);
1006       temps = max( temps, dep.getTempSize() );
1007     }
1008     if ( !productsView->isNone( item ) )
1009       nbSelected++;
1010   }
1011  
1012   if ( totSize )
1013     *totSize = tots;
1014   if ( tempSize )
1015     *tempSize = temps;
1016   return ( nbSelected > 0 );
1017 }
1018 // ================================================================
1019 /*!
1020  *  SALOME_InstallWizard::checkProductPage
1021  *  Checks products page validity (directories and products selection) and
1022  *  enabled/disables "Next" button for the Products page
1023  */
1024 // ================================================================
1025 void SALOME_InstallWizard::checkProductPage()
1026 {
1027   long tots = 0, temps = 0;
1028
1029   // check if any product is selected;
1030   bool isAnyProductSelected = checkSize( &tots, &temps );
1031   // check if target directory is valid
1032   bool isTargetDirValid = !targetFolder->text().stripWhiteSpace().isEmpty();
1033   // check if temp directory is valid
1034   bool isTempDirValid = !moreMode || !tempFolder->text().stripWhiteSpace().isEmpty();
1035
1036   // update required size information
1037   requiredSize->setText( QString::number( tots )  + " Kb");
1038   requiredTemp->setText( QString::number( temps ) + " Kb");
1039
1040   // enable/disable "Next" button
1041   setNextEnabled( productsPage, isAnyProductSelected && isTargetDirValid && isTempDirValid );
1042 }
1043 // ================================================================
1044 /*!
1045  *  SALOME_InstallWizard::setPrerequisites
1046  *  Sets the product and all products this one depends on to be checked ( recursively )
1047  */
1048 // ================================================================
1049 void SALOME_InstallWizard::setPrerequisites( QCheckListItem* item )
1050 {
1051   if ( !productsMap.contains( item ) )
1052     return;
1053   if ( productsView->isNone( item ) )
1054     return;
1055   // get all prerequisites
1056   QStringList dependOn = productsMap[ item ].getDependancies();
1057   for ( int i = 0; i < (int)dependOn.count(); i++ ) {
1058     MapProducts::Iterator itProd;
1059     for ( itProd = productsMap.begin(); itProd != productsMap.end(); ++itProd ) {
1060       if ( itProd.data().getName() == dependOn[ i ] ) {
1061         if ( productsView->isNone( itProd.key() ) ) {
1062           QString defMode = itProd.data().getDefault();
1063           if ( defMode.isEmpty() )
1064             defMode = tr( "install binaries" );
1065           if ( defMode == tr( "install binaries" ) )
1066             productsView->setBinaries( itProd.key() );
1067           else if ( defMode == tr( "install sources" ) )
1068             productsView->setSources( itProd.key() );
1069           else if ( defMode == tr( "use native" ) )
1070             productsView->setNative( itProd.key() );
1071           setPrerequisites( itProd.key() );
1072         }
1073       }
1074     }
1075   }
1076 }
1077 // ================================================================
1078 /*!
1079  *  SALOME_InstallWizard::launchScript
1080  *  Runs installation script
1081  */
1082 // ================================================================
1083 void SALOME_InstallWizard::launchScript()
1084 {
1085   // try to find product being processed now
1086   QString prodProc = progressView->findStatus( Processing );
1087   if ( !prodProc.isNull() ) {
1088 #ifdef DEBUG
1089     cout << "Found <Processing>: " << prodProc.latin1() << endl;
1090 #endif
1091
1092     // if found - set status to "completed"
1093     progressView->setStatus( prodProc, Completed );
1094     // ... and call this method again
1095     launchScript();
1096     return;
1097   }
1098   // else try to find next product which is not processed yet
1099   prodProc = progressView->findStatus( Waiting );
1100   if ( !prodProc.isNull() ) {
1101 #ifdef DEBUG
1102     cout << "Found <Waiting>: " << prodProc.latin1() << endl;
1103 #endif
1104     // if found - set status to "processed" and run script
1105     progressView->setStatus( prodProc, Processing );
1106     progressView->ensureVisible( prodProc );
1107
1108     QCheckListItem* item = findItem( prodProc );
1109     Dependancies dep = productsMap[ item ];
1110     // fill in script parameters
1111     shellProcess->clearArguments();
1112     // ... script name
1113     shellProcess->setWorkingDirectory( QDir::cleanDirPath( QFileInfo( "./config_files/" ).absFilePath() ) );
1114     shellProcess->addArgument( item->text(2) );
1115
1116     // ... temp folder
1117     QString tmpFolder = QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + TEMPDIRNAME;
1118     //if( !tempFolder->isEnabled() )
1119     //tmpFolder = "/tmp";
1120
1121     // ... binaries ?
1122     if ( productsView->isBinaries( item ) ) {
1123       shellProcess->addArgument( "install_binary" );
1124       shellProcess->addArgument( QFileInfo( tmpFolder ).absFilePath() );
1125       QString binDir = QDir::currentDirPath() + "/Products/BINARIES";
1126       if ( !myOS.isEmpty() )
1127         binDir += "/" + myOS;
1128       shellProcess->addArgument( binDir );
1129     }
1130     // ... sources ?
1131     else if ( productsView->isSources( item ) ) {
1132       shellProcess->addArgument( "install_source" );
1133       shellProcess->addArgument( QFileInfo( tmpFolder ).absFilePath() );
1134       shellProcess->addArgument( QDir::currentDirPath() + "/Products/SOURCES" );
1135     }
1136     // ... native ?
1137     else if ( productsView->isNative( item ) ) {
1138       shellProcess->addArgument( "try_native" );
1139       shellProcess->addArgument( QFileInfo( tmpFolder ).absFilePath() );
1140       shellProcess->addArgument( QDir::currentDirPath() + "/Products" );
1141     }
1142     // ... not install : try to find preinstalled
1143     else {
1144       shellProcess->addArgument( "try_preinstalled" );
1145       shellProcess->addArgument( QFileInfo( tmpFolder ).absFilePath() );
1146       shellProcess->addArgument( QDir::currentDirPath() + "/Products" );
1147     }
1148     // ... target folder
1149     QString tgtFolder = QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() );
1150     shellProcess->addArgument( QFileInfo( tgtFolder ).absFilePath() );
1151     
1152
1153     QString depproducts = DefineDependeces(productsMap); 
1154 #ifdef DEBUG
1155     cout << "Dependancies"<< depproducts.latin1() << endl;
1156 #endif
1157
1158     shellProcess->addArgument( depproducts );
1159     // ... product name - currently instaled product
1160     shellProcess->addArgument( item->text(0) );
1161
1162     // run script
1163     if ( !shellProcess->start() ) {
1164       // error handling can be here
1165 #ifdef DEBUG
1166       cout << "error" << endl;
1167 #endif
1168     }
1169     return;
1170   }
1171 #ifdef DEBUG
1172   cout << "All products have been installed successfully" << endl;
1173 #endif
1174   // all products are installed successfully
1175   QString workDir = QDir::cleanDirPath( QFileInfo( "./config_files/" ).absFilePath() );
1176   MapProducts::Iterator mapIter;
1177 #ifdef DEBUG
1178   cout << "starting pick-up environment" << endl;
1179 #endif
1180   for ( mapIter = productsMap.begin(); mapIter != productsMap.end(); ++mapIter ) {
1181     QCheckListItem* item = mapIter.key();
1182     Dependancies dep = mapIter.data();
1183     QString depproducts = QUOTE( DefineDependeces(productsMap) ); 
1184     if ( dep.pickUpEnvironment() ) {
1185 #ifdef DEBUG
1186       cout << "... for " << dep.getName() << endl;
1187 #endif
1188       QString script;
1189       script += "cd " + QUOTE( QFileInfo( QDir::cleanDirPath( "./config_files/" ) ).absFilePath() ) + "; ";
1190       script += item->text(2) + " ";
1191       script += "pickup_env ";
1192       script += QUOTE( QFileInfo( QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + TEMPDIRNAME ).absFilePath() ) + " ";
1193       script += QUOTE( QFileInfo( QDir::cleanDirPath( QDir::currentDirPath() + "/Products" ) ).absFilePath() ) + " ";
1194       script += QUOTE( QFileInfo( QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() ) ).absFilePath() ) + " ";
1195       script += depproducts + " ";
1196       script += item->text(0);
1197 #ifdef DEBUG
1198       cout << "... --> " << script.latin1() << endl;
1199 #endif
1200       if ( system( script.latin1() ) ) { 
1201 #ifdef DEBUG
1202         cout << "ERROR" << endl; 
1203 #endif
1204       }
1205     }
1206   }
1207   // <Next> button
1208   nextButton()->setEnabled( true );
1209   nextButton()->setText( tr( "&Next >" ) );
1210   QWhatsThis::add( nextButton(), tr( "Moves to the next step of the installation procedure" ) );
1211   QToolTip::add  ( nextButton(), tr( "Moves to the next step of the installation procedure" ) );
1212   nextButton()->disconnect();
1213   connect( nextButton(), SIGNAL( clicked() ), this, SLOT( next() ) );
1214   // <Back> button
1215   backButton()->setEnabled( true );
1216   // script parameters
1217   passedParams->clear();
1218   passedParams->setEnabled( false );
1219   QFont f = parametersLab->font(); f.setBold( false ); parametersLab->setFont( f );
1220   if ( isMinimized() )
1221     showNormal();
1222   raise();
1223 }
1224 // ================================================================
1225 /*!
1226  *  SALOME_InstallWizard::onMoreBtn
1227  *  <More...> button slot
1228  */
1229 // ================================================================
1230 void SALOME_InstallWizard::onMoreBtn()
1231 {
1232   if ( moreMode ) {
1233     moreBox->hide();
1234     moreBtn->setText( tr( "More..." ) );
1235   }
1236   else {
1237     moreBox->show();
1238     moreBtn->setText( tr( "Less..." ) );
1239   }
1240   qApp->processEvents();
1241   moreMode = !moreMode;
1242   InstallWizard::layOut();
1243   qApp->processEvents();
1244   if ( !isMaximized() ) {
1245     //setGeometry( geometry().x(), geometry().y(), geometry().width(), 0 );
1246     resize( geometry().width(), 0 );
1247     qApp->processEvents();
1248   }
1249   checkProductPage();
1250 }
1251 // ================================================================
1252 /*!
1253  *  SALOME_InstallWizard::onLaunchSalome
1254  *  <Launch Salome> button slot
1255  */
1256 // ================================================================
1257 void SALOME_InstallWizard::onLaunchSalome()
1258 {
1259   QString msg = tr( "You don't have SALOME binaries installed in the %1 directory!" ).arg( targetFolder->text() );
1260
1261   QCheckListItem* item = findItem( "KERNEL-Bin" );
1262   if ( item ) {
1263     QFileInfo fi( targetFolder->text() + "/KERNEL_" + item->text(1) + "/bin/salome/runSalome" );
1264     QFileInfo fienv( targetFolder->text() + "/KERNEL_" + item->text(1) + "/salome.csh" );
1265     if ( fienv.exists() ) {
1266       if ( fi.exists() ) {
1267         QString script;
1268         script += "cd " + targetFolder->text() + "/KERNEL_" + item->text(1) + "; ";
1269         script += "source salome.csh; ";
1270         script += "cd bin/salome; ";
1271         script += "runSalome > /dev/null";
1272         script = "(csh -c '" + script + "')";
1273 #ifdef DEBUG
1274         cout << script.latin1() << endl;
1275 #endif
1276         if ( !system( script.latin1() ) )
1277           return;
1278         else
1279           msg = tr( "Can't launch SALOME." );
1280       }
1281       else
1282         msg = tr( "Can't launch SALOME." ) + "\n" + tr( "runSalome file can not be found." );
1283     }
1284     else
1285       msg = tr( "Can't launch SALOME." ) + "\n" + tr( "Can't find environment file." );
1286   }
1287   QMessageBox::warning( this, 
1288                         tr( "Error" ), 
1289                         msg,
1290                         QMessageBox::Ok, 
1291                         QMessageBox::NoButton,
1292                         QMessageBox::NoButton );
1293 }
1294 // ================================================================
1295 /*!
1296  *  SALOME_InstallWizard::findItem
1297  *  Searches product listview item with given symbolic name 
1298  */
1299 // ================================================================
1300 QCheckListItem* SALOME_InstallWizard::findItem( const QString& sName )
1301 {
1302   MapProducts::Iterator mapIter;
1303   for ( mapIter = productsMap.begin(); mapIter != productsMap.end(); ++mapIter ) {
1304     if ( mapIter.data().getName() == sName )
1305       return mapIter.key();
1306   }
1307   return 0;
1308 }
1309 // ================================================================
1310 /*!
1311  *  SALOME_InstallWizard::abort
1312  *  Sets progress state to Aborted
1313  */
1314 // ================================================================
1315 void SALOME_InstallWizard::abort()
1316 {
1317   QString prod = progressView->findStatus( Processing );
1318   while ( !prod.isNull() ) {
1319     progressView->setStatus( prod, Aborted );
1320     prod = progressView->findStatus( Processing );
1321   }
1322   prod = progressView->findStatus( Waiting );
1323   while ( !prod.isNull() ) {
1324     progressView->setStatus( prod, Aborted );
1325     prod = progressView->findStatus( Waiting );
1326   }
1327 }
1328 // ================================================================
1329 /*!
1330  *  SALOME_InstallWizard::reject
1331  *  Reject slot, clears temporary directory and closes application
1332  */
1333 // ================================================================
1334 void SALOME_InstallWizard::reject()
1335 {
1336 #ifdef DEBUG
1337   cout << "REJECTED" << endl;
1338 #endif
1339   if ( !exitConfirmed ) {
1340     if ( QMessageBox::information( this, 
1341                                    tr( "Exit" ), 
1342                                    tr( "Do you want to quit %1?" ).arg( getIWName() ), 
1343                                    tr( "&Yes" ), 
1344                                    tr( "&No" ),
1345                                    QString::null,
1346                                    0,
1347                                    1 ) == 1 ) {
1348       return;
1349     }
1350     exitConfirmed = true;
1351   }
1352   clean();
1353   InstallWizard::reject();
1354 }
1355 // ================================================================
1356 /*!
1357  *  SALOME_InstallWizard::accept
1358  *  Accept slot, clears temporary directory and closes application
1359  */
1360 // ================================================================
1361 void SALOME_InstallWizard::accept()
1362 {
1363 #ifdef DEBUG
1364   cout << "ACCEPTED" << endl;
1365 #endif
1366   clean();
1367   InstallWizard::accept();
1368 }
1369 // ================================================================
1370 /*!
1371  *  SALOME_InstallWizard::clean
1372  *  Clears and removes temporary directory
1373  */
1374 // ================================================================
1375 void SALOME_InstallWizard::clean()
1376 {
1377   // VSR: first remove temporary files
1378   QString script = "cd ./config_files/; remove_tmp.sh '";
1379   script += tempFolder->text().stripWhiteSpace() + TEMPDIRNAME;
1380   script += "' ";
1381   script += QUOTE(DefineDependeces(productsMap));
1382   script += " > /dev/null";
1383 #ifdef DEBUG
1384   cout << "script = " << script << endl;
1385 #endif
1386   if ( system( script.latin1() ) ) {
1387   }
1388   // VSR: then try to remove created temporary directory
1389   //script = "rm -rf " + QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + TEMPDIRNAME;
1390   if ( !tmpCreated.isNull() ) {
1391     script = "rm -rf " + tmpCreated;
1392     script += " > /dev/null";
1393     if ( system( script.latin1() ) ) {
1394     }
1395 #ifdef DEBUG
1396     cout << "script = " << script << endl;
1397 #endif
1398   }
1399 }
1400 // ================================================================
1401 /*!
1402  *  SALOME_InstallWizard::pageChanged
1403  *  Called when user moves from page to page
1404  */
1405 // ================================================================
1406 void SALOME_InstallWizard::pageChanged( const QString & mytitle)
1407 {
1408   nextButton()->setText( tr( "&Next >" ) );
1409   QWhatsThis::add( nextButton(), tr( "Moves to the next step of the installation procedure" ) );
1410   QToolTip::add  ( nextButton(), tr( "Moves to the next step of the installation procedure" ) );
1411   nextButton()->disconnect();
1412   connect( nextButton(), SIGNAL( clicked() ), this, SLOT( next() ) );
1413   cancelButton()->disconnect();
1414   connect( cancelButton(), SIGNAL( clicked()), this, SLOT( reject() ) );
1415
1416   QWidget* aPage = InstallWizard::page( mytitle );
1417   if ( !aPage )
1418     return;
1419   updateCaption();
1420   if ( aPage == productsPage ) {
1421     // products page
1422     onSelectionChanged();
1423     checkProductPage();
1424   }
1425   else if ( aPage == prestartPage ) {
1426     // prestart page
1427     showChoiceInfo();
1428   }
1429   else if ( aPage == progressPage ) {
1430     if ( previousPage == prestartPage ) {
1431       // progress page
1432       progressView->clear();
1433       installInfo->clear();
1434       passedParams->clear();
1435       passedParams->setEnabled( false );
1436       QFont f = parametersLab->font(); f.setBold( false ); parametersLab->setFont( f );
1437       nextButton()->setText( tr( "&Start" ) );
1438       QWhatsThis::add( nextButton(), tr( "Starts installation process" ) );
1439       QToolTip::add  ( nextButton(), tr( "Starts installation process" ) );
1440       // reconnect Next button - to use it as Start button
1441       nextButton()->disconnect();
1442       connect( nextButton(), SIGNAL( clicked() ), this, SLOT( onStart() ) );
1443       nextButton()->setEnabled( true );
1444       // reconnect Cancel button to terminate process
1445       cancelButton()->disconnect();
1446       connect( cancelButton(), SIGNAL( clicked() ), this, SLOT( tryTerminate() ) );
1447     }
1448   }
1449   else if ( aPage == readmePage ) {
1450     QCheckListItem* item = findItem( "KERNEL-Bin" );
1451     runSalomeBtn->setEnabled( item &&
1452                               QFileInfo( targetFolder->text() + "/KERNEL_" + item->text(1) + "/bin/salome/runSalome" ).exists() &&
1453                               QFileInfo( targetFolder->text() + "/KERNEL_" + item->text(1) + "/salome.csh" ).exists() );
1454     finishButton()->setEnabled( true );
1455   }
1456   previousPage = aPage;
1457 #ifdef DEBUG
1458   cout << "previousPage = " << previousPage << endl;
1459 #endif
1460 }
1461 // ================================================================
1462 /*!
1463  *  SALOME_InstallWizard::helpClicked
1464  *  Shows help window
1465  */
1466 // ================================================================
1467 void SALOME_InstallWizard::helpClicked()
1468 {
1469   if ( helpWindow == NULL ) {
1470     helpWindow = HelpWindow::openHelp( this );
1471     if ( helpWindow ) {
1472       helpWindow->show();
1473       helpWindow->installEventFilter( this );
1474     }
1475     else {
1476       QMessageBox::warning( this, 
1477                             tr( "Help file not found" ), 
1478                             tr( "Sorry, help is unavailable" ) );
1479     }
1480   }
1481   else {
1482     helpWindow->raise();
1483     helpWindow->setActiveWindow();
1484   }
1485 }
1486 // ================================================================
1487 /*!
1488  *  SALOME_InstallWizard::browseDirectory
1489  *  Shows directory selection dialog
1490  */
1491 // ================================================================
1492 void SALOME_InstallWizard::browseDirectory()
1493 {
1494   const QObject* theSender = sender();
1495   QLineEdit* theFolder;
1496   if ( theSender == targetBtn )
1497     theFolder = targetFolder;
1498   else if (theSender == tempBtn)
1499     theFolder = tempFolder;
1500   else
1501     return;
1502   QString typedDir = QFileDialog::getExistingDirectory( QDir::cleanDirPath( theFolder->text().stripWhiteSpace() ), this );
1503   if ( !typedDir.isNull() ) {
1504     theFolder->setText( typedDir );
1505     theFolder->end( false );
1506   }
1507   checkProductPage();
1508 }
1509 // ================================================================
1510 /*!
1511  *  SALOME_InstallWizard::directoryChanged
1512  *  Called when directory path (target or temp) is changed
1513  */
1514 // ================================================================
1515 void SALOME_InstallWizard::directoryChanged( const QString& /*text*/ )
1516 {
1517   checkProductPage();
1518 }
1519 // ================================================================
1520 /*!
1521  *  SALOME_InstallWizard::onStart
1522  *  <Start> button's slot - runs installation
1523  */
1524 // ================================================================
1525 void SALOME_InstallWizard::onStart()
1526 {
1527   // clear list of products to install ...
1528   toInstall.clear();
1529   // ... and fill it for new process
1530   QCheckListItem* item = (QCheckListItem*)( productsView->firstChild() );
1531   while( item ) {
1532 //    if ( productsView->isBinaries( item ) || productsView->isSources( item ) || productsView->isNative( item ) ) {
1533       if ( productsMap.contains( item ) )
1534         toInstall.append( productsMap[item].getName() );
1535 //    }
1536     item = (QCheckListItem*)( item->nextSibling() );
1537   }
1538   // if something at all is selected
1539   if ( !toInstall.isEmpty() ) {
1540     // disable <Next> button
1541     nextButton()->setEnabled( false );
1542     // disable <Back> button
1543     backButton()->setEnabled ( false );
1544     // enable script parameters line edit
1545     // VSR commented: 18/09/03: passedParams->setEnabled( true );
1546     // VSR commented: 18/09/03: passedParams->setFocus();
1547     // set status for all products
1548     for ( int i = 0; i < (int)toInstall.count(); i++ ) {
1549       item = findItem( toInstall[ i ] );
1550       QString type = "";
1551       if ( productsView->isBinaries( item ) )
1552         type = tr( "binaries" );
1553       else if ( productsView->isSources( item ) )
1554         type = tr( "sources" );
1555       else if ( productsView->isNative( item ) )
1556         type = tr( "native" );
1557       else 
1558         type = tr( "not install" );
1559       progressView->addProduct( item->text(0), type, item->text(2) );
1560     }
1561     // launch install script
1562     launchScript();
1563   }
1564 }
1565 // ================================================================
1566 /*!
1567  *  SALOME_InstallWizard::onReturnPressed
1568  *  Called when users tries to pass parameters for the script
1569  */
1570 // ================================================================
1571 void SALOME_InstallWizard::onReturnPressed()
1572 {
1573   QString txt = passedParams->text();
1574   installInfo->append( txt );
1575   txt += "\n";
1576   shellProcess->writeToStdin( txt );
1577   passedParams->clear();
1578   progressView->setFocus();
1579   passedParams->setEnabled( false );
1580   QFont f = parametersLab->font(); f.setBold( false ); parametersLab->setFont( f );
1581 }
1582 /*!
1583   Callback function - as response for the script finishing
1584 */
1585 void SALOME_InstallWizard::productInstalled( )
1586 {
1587 #ifdef DEBUG
1588   cout << "process exited" << endl;
1589 #endif
1590   if ( shellProcess->normalExit() ) {
1591 #ifdef DEBUG
1592     cout << "...normal exit" << endl;
1593 #endif
1594     // normal exit - try to proceed installation further
1595     launchScript();
1596   }
1597   else {
1598 #ifdef DEBUG
1599     cout << "...abnormal exit" << endl;
1600 #endif
1601     // installation aborted
1602     abort();
1603     // clear script passed parameters lineedit
1604     passedParams->clear();
1605     passedParams->setEnabled( false );
1606     QFont f = parametersLab->font(); f.setBold( false ); parametersLab->setFont( f );
1607     // enable <Next> button
1608     nextButton()->setEnabled( true );
1609     nextButton()->setText( tr( "&Next >" ) );
1610     QWhatsThis::add( nextButton(), tr( "Moves to the next step of the installation procedure" ) );
1611     QToolTip::add  ( nextButton(), tr( "Moves to the next step of the installation procedure" ) );
1612     nextButton()->disconnect();
1613     connect( nextButton(), SIGNAL( clicked() ), this, SLOT( next() ) );
1614     // enable <Back> button
1615     backButton()->setEnabled( true );
1616   }
1617 }
1618 // ================================================================
1619 /*!
1620  *  SALOME_InstallWizard::tryTerminate
1621  *  Slot, called when <Cancel> button is clicked during installation script running
1622  */
1623 // ================================================================
1624 void SALOME_InstallWizard::tryTerminate()
1625 {
1626   if ( shellProcess->isRunning() ) {
1627     if ( QMessageBox::information( this, 
1628                                    tr( "Exit" ), 
1629                                    tr( "Do you want to quit %1?" ).arg( getIWName() ), 
1630                                    tr( "&Yes" ), 
1631                                    tr( "&No" ),
1632                                    QString::null,
1633                                    0,
1634                                    1 ) == 1 ) {
1635       return;
1636     }
1637     exitConfirmed = true;
1638     // if process still running try to terminate it first
1639     shellProcess->tryTerminate();
1640     abort();
1641     //QTimer::singleShot( 3000, this, SLOT( onCancel() ) );
1642     connect( shellProcess, SIGNAL( processExited() ), this, SLOT( onCancel() ) );
1643   }
1644   else {
1645     // else just quit install wizard
1646     reject();
1647   }
1648 }
1649 // ================================================================
1650 /*!
1651  *  SALOME_InstallWizard::onCancel
1652  *  Kills installation process and quits application
1653  */
1654 // ================================================================
1655 void SALOME_InstallWizard::onCancel()
1656 {
1657   shellProcess->kill();
1658   reject();
1659 }
1660 // ================================================================
1661 /*!
1662  *  SALOME_InstallWizard::onSelectionChanged
1663  *  Called when selection is changed in the products list view
1664  */
1665 // ================================================================
1666 void SALOME_InstallWizard::onSelectionChanged()
1667 {
1668   productsInfo->clear();
1669   QListViewItem* item = productsView->selectedItem();
1670   if ( !item )
1671     return;
1672   if ( item->parent() )
1673     item = item->parent();
1674   QCheckListItem* aItem = (QCheckListItem*)item;
1675   if ( !productsMap.contains( aItem ) )
1676     return;
1677   Dependancies dep = productsMap[ aItem ];
1678   QString text = "<b>" + aItem->text(0) + "</b>" + "<br>";
1679   if ( !aItem->text(1).stripWhiteSpace().isEmpty() )
1680     text += tr( "Version" ) + ": " + aItem->text(1) + "<br>";
1681   text += "<br>";
1682   if ( !dep.getDescription().isEmpty() ) {
1683     text += "<i>" + dep.getDescription() + "</i><br><br>";
1684   }
1685   text += tr( "User choice" ) + ": ";
1686   long totSize = 0, tempSize = 0;
1687   if ( productsView->isBinaries( aItem ) ) {
1688     text += "<b>" + tr( "install binaries" ) + "</b>" + "<br>";
1689     totSize = dep.getSize();
1690   }
1691   else if ( productsView->isSources( aItem ) ) {
1692     text += "<b>" + tr( "install sources" ) + "</b>" + "<br>";
1693     totSize = dep.getSize( true );
1694     tempSize = dep.getTempSize();
1695   }
1696   else if ( productsView->isNative( aItem ) ) {
1697     text += "<b>" + tr( "use native" ) + "</b>" + "<br>";
1698   }
1699   else {
1700     text += "<b>" + tr( "not install" ) + "</b>" + "<br>";
1701   }
1702   
1703   text += tr( "Disk space required" ) + ": " + QString::number( totSize ) + " Kb<br>";
1704   text += tr( "Disk space for tmp files required" ) + ": " + QString::number( tempSize ) + " Kb<br>";
1705   text += "<br>";
1706   QString req = ( dep.getDependancies().count() > 0 ? dep.getDependancies().join(", ") : tr( "none" ) );
1707   text +=  tr( "Prerequisites" ) + ": " + req;
1708   productsInfo->setText( text );
1709 }
1710 // ================================================================
1711 /*!
1712  *  SALOME_InstallWizard::onItemToggled
1713  *  Called when user checks/unchecks any product item
1714  *  Recursively sets all prerequisites and updates "Next" button state
1715  */
1716 // ================================================================
1717 void SALOME_InstallWizard::onItemToggled( QCheckListItem* item )
1718 {
1719   if ( prerequisites->isChecked() ) {
1720     if ( item->parent() )
1721       item = (QCheckListItem*)( item->parent() );
1722     if ( productsMap.contains( item ) ) {
1723       productsView->blockSignals( true );
1724       setPrerequisites( item );
1725       productsView->blockSignals( false );
1726     }
1727   }
1728   onSelectionChanged();
1729   checkProductPage();
1730 }
1731 // ================================================================
1732 /*!
1733  *  SALOME_InstallWizard::onProdBtn
1734  *  This slot is called when user clicks one of <Select Sources>,
1735  *  <Select Binaries>, <Unselect All> buttons ( products page )
1736  */
1737 // ================================================================
1738 void SALOME_InstallWizard::onProdBtn()
1739 {
1740   const QObject* snd = sender();
1741   productsView->blockSignals( true );
1742   if ( snd == unselectBtn ) {
1743     QCheckListItem* item = (QCheckListItem*)( productsView->firstChild() );
1744     while( item ) {
1745       productsView->setNone( item );
1746       item = (QCheckListItem*)( item->nextSibling() );
1747     }
1748   }
1749   productsView->blockSignals( false );
1750   onSelectionChanged();
1751   checkProductPage();
1752 }
1753 // ================================================================
1754 /*!
1755  *  SALOME_InstallWizard::wroteToStdin
1756  *  QProcess slot: -->something was written to stdin
1757  */
1758 // ================================================================
1759 void SALOME_InstallWizard::wroteToStdin( )
1760 {
1761 #ifdef DEBUG
1762   cout << "Something was sent to stdin" << endl;
1763 #endif
1764 }
1765 // ================================================================
1766 /*!
1767  *  SALOME_InstallWizard::readFromStdout
1768  *  QProcess slot: -->something was written to stdout
1769  */
1770 // ================================================================
1771 void SALOME_InstallWizard::readFromStdout( )
1772 {
1773 #ifdef DEBUG
1774   cout << "Something was sent to stdout" << endl;
1775 #endif
1776   while ( shellProcess->canReadLineStdout() ) {
1777     installInfo->append( QString( shellProcess->readLineStdout() ) );
1778     installInfo->scrollToBottom();
1779   }
1780   QString str( shellProcess->readStdout() );
1781   if ( !str.isEmpty() ) {
1782     installInfo->append( str );
1783     installInfo->scrollToBottom();
1784   }
1785 }
1786 // ================================================================
1787 /*!
1788  *  SALOME_InstallWizard::readFromStderr
1789  *  QProcess slot: -->something was written to stderr
1790  */
1791 // ================================================================
1792 void SALOME_InstallWizard::readFromStderr( )
1793 {
1794 #ifdef DEBUG
1795   cout << "Something was sent to stderr" << endl;
1796 #endif
1797   while ( shellProcess->canReadLineStderr() ) {
1798     installInfo->append( QString( shellProcess->readLineStderr() ) );
1799     installInfo->scrollToBottom();
1800   }
1801   QString str( shellProcess->readStderr() );
1802   if ( !str.isEmpty() ) {
1803     installInfo->append( str );
1804     installInfo->scrollToBottom();
1805   }
1806   passedParams->setEnabled( true );
1807   passedParams->setFocus();
1808   QFont f = parametersLab->font(); f.setBold( true ); parametersLab->setFont( f );
1809 }
1810 // ================================================================
1811 /*!
1812  *  SALOME_InstallWizard::setDependancies
1813  *  Sets dependancies for the product item
1814  */
1815 // ================================================================
1816 void SALOME_InstallWizard::setDependancies( QCheckListItem* item, Dependancies dep)
1817 {
1818   productsMap[item] = dep;
1819 }
1820 // ================================================================
1821 /*!
1822  *  SALOME_InstallWizard::polish
1823  *  Polishing of the widget - to set right initial size
1824  */
1825 // ================================================================
1826 void SALOME_InstallWizard::polish()
1827 {
1828   resize( 0, 0 );
1829   InstallWizard::polish();
1830 }
1831 // ================================================================
1832 /*!
1833  *  SALOME_InstallWizard::updateCaption
1834  *  Updates caption according to the current page number
1835  */
1836 // ================================================================
1837 void SALOME_InstallWizard::updateCaption()
1838 {
1839   QWidget* aPage = InstallWizard::currentPage();
1840   if ( !aPage ) 
1841     return;
1842   InstallWizard::setCaption( tr( myCaption ) + " " +
1843                              tr( getIWName() ) + " - " +
1844                              tr( "Step %1 of %2").arg( QString::number( this->indexOf( aPage )+1 ) ).arg( QString::number( this->pageCount() ) ) );
1845 }