Salome HOME
dab7573f183b5ab1a70e9cb82ecb44e2eda43536
[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->setFont( QFont( "Fixed" ) );
613   readme->setUndoRedoEnabled ( false );
614   QWhatsThis::add( readme, tr( "Displays README information" ) );
615   QToolTip::add  ( readme, tr( "Displays README information" ) );
616   QPalette pal = readme->palette();
617   pal.setColor( QColorGroup::Base, QApplication::palette().active().background() );
618   readme->setPalette( pal );
619   readme->setMinimumHeight( 10 );
620   // <Launch SALOME> button
621   runSalomeBtn = new QPushButton( tr( "Launch SALOME" ), readmePage );
622   QWhatsThis::add( runSalomeBtn, tr( "Click this button to run SALOME desktop" ) );
623   QToolTip::add  ( runSalomeBtn, tr( "Click this button to run SALOME desktop" ) );
624   QHBoxLayout* hLayout = new QHBoxLayout;
625   hLayout->addWidget( runSalomeBtn ); hLayout->addStretch();
626   // layouting
627   pageLayout->addWidget( readme );
628   pageLayout->setStretchFactor( readme, 5 );
629   pageLayout->addLayout( hLayout );
630   // connecting signals
631   connect( runSalomeBtn, SIGNAL( clicked() ), this, SLOT( onLaunchSalome() ) );
632   // loading README file
633   QString readmeFile = QDir::currentDirPath() + "/README";
634   QString text;
635   if ( readFile( readmeFile, text ) )
636     readme->setText( text );
637   else
638     readme->setText( tr( "README file has not been found" ) );
639   // adding page
640   addPage( readmePage, tr( "Finish installation" ) );
641 }
642 // ================================================================
643 /*!
644  *  SALOME_InstallWizard::showChoiceInfo
645  *  Displays choice info
646  */
647 // ================================================================
648 void SALOME_InstallWizard::showChoiceInfo()
649 {
650   choices->clear();
651
652   long totSize, tempSize;
653   checkSize( &totSize, &tempSize );
654   int nbProd = 0;
655   QString text;
656
657   if ( !xmlFileName.isEmpty() ) {
658     text += tr( "Configuration file" )+ ": <b>" + xmlFileName + "</b><br>";
659     text += "<br>";
660   }
661   if ( !myOS.isEmpty() ) {
662     text += tr( "Target platform" ) + ": <b>" + myOS + "</b><br>";
663     text += "<br>";
664   }
665   text += tr( "Products to be used" ) + ":<ul>";
666   QCheckListItem* item = (QCheckListItem*)( productsView->firstChild() );
667   while( item ) {
668     if ( productsMap.contains( item ) ) {
669       if ( item->childCount() > 0 ) {
670         if ( productsView->isNative( item ) ) {
671           text += "<li><b>" + item->text() + "</b> " + tr( "as native" ) + "<br>";
672           nbProd++;
673         }
674       }
675     }
676     item = (QCheckListItem*)( item->nextSibling() );
677   }
678   if ( nbProd == 0 ) {
679     text += "<li><b>" + tr( "none" ) + "</b><br>";
680   }
681   text += "</ul>";
682   nbProd = 0;
683   text += tr( "Products to be installed" ) + ":<ul>";
684   item = (QCheckListItem*)( productsView->firstChild() );
685   while( item ) {
686     if ( productsMap.contains( item ) ) {
687       if ( item->childCount() > 0 ) {
688         if ( productsView->isBinaries( item ) ) {
689           text += "<li><b>" + item->text() + "</b> " + tr( "as binaries" ) + "<br>";
690           nbProd++;
691         }
692         else if ( productsView->isSources( item ) ) {
693           text+= "<li><b>" + item->text() + "</b> " + tr( "as sources" ) + "<br>";
694           nbProd++;
695         }
696       }
697       else if ( item->isOn() ) {
698         text+= "<li><b>" + item->text() + "</b><br>";
699         nbProd++;
700       }
701     }
702     item = (QCheckListItem*)( item->nextSibling() );
703   }
704   if ( nbProd == 0 ) {
705     text += "<li><b>" + tr( "none" ) + "</b><br>";
706   }
707   text += "</ul>";
708   text += tr( "Total disk space required:" ) + " <b>" + QString::number( totSize ) + " Kb</b><br>" ;
709   text += tr( "Space for temporary files required:" ) + " <b>" + QString::number( tempSize ) + " Kb</b><br>" ;
710   text += "<br>";
711   text += tr( "Target directory:" ) + " <b>" + QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() ) + "</b><br>";
712   // VSR: Temporary folder is used always now and it is not necessary to disable it -->
713   // if ( tempSize > 0 )
714   // VSR: <----------------------------------------------------------------------------
715   text += tr( "Temp directory:" ) + " <b>" + QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + "</b><br>";
716   text += "<br>";
717   choices->setText( text );
718 }
719 // ================================================================
720 /*!
721  *  SALOME_InstallWizard::acceptData
722  *  Validates page when <Next> button is clicked
723  */
724 // ================================================================
725 bool SALOME_InstallWizard::acceptData( const QString& pageTitle )
726 {
727   QString tmpstr;
728   QWidget* aPage = InstallWizard::page( pageTitle );
729   if ( aPage == productsPage ) {
730     // ########## check if any products are selected to be installed
731     long totSize, tempSize;
732     bool anySelected = checkSize( &totSize, &tempSize );
733     if ( !anySelected ) {
734       QMessageBox::warning( this, 
735                             tr( "Warning" ), 
736                             tr( "Select one or more products to install" ), 
737                             QMessageBox::Ok, 
738                             QMessageBox::NoButton,
739                             QMessageBox::NoButton );
740       return false;
741     }
742     // ########## check target and temp directories (existence and available disk space)
743     // get dirs
744     QString targetDir = QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() );
745     QString tempDir   = QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() );
746     // directories should differ
747 //    if (!targetDir.isEmpty() && tempDir == targetDir) {
748 //      QMessageBox::warning( this, 
749 //                          tr( "Warning" ), 
750 //                          tr( "Target and temporary directories must be different"), 
751 //                          QMessageBox::Ok, 
752 //                          QMessageBox::NoButton, 
753 //                          QMessageBox::NoButton );
754 //      return false;
755 //    }
756     // check target directory
757     if ( targetDir.isEmpty() ) {
758       QMessageBox::warning( this, 
759                             tr( "Warning" ), 
760                             tr( "Please, enter valid target directory path" ), 
761                             QMessageBox::Ok, 
762                             QMessageBox::NoButton,
763                             QMessageBox::NoButton );
764       return false;
765     }
766     QFileInfo fi( QDir::cleanDirPath( targetDir ) );
767     if ( !fi.exists() ) {
768       bool toCreate = 
769         QMessageBox::warning( this, 
770                               tr( "Warning" ), 
771                               tr( "The directory %1 doesn't exist.\n"
772                                   "Do you want to create directory?" ).arg( fi.absFilePath() ), 
773                               QMessageBox::Yes, 
774                               QMessageBox::No,
775                               QMessageBox::NoButton ) == QMessageBox::Yes;
776       if ( !toCreate) 
777         return false;
778       if ( !makeDir( fi.absFilePath(), tmpstr ) ) {
779         QMessageBox::critical( this, 
780                                tr( "Error" ), 
781                                tr( "Can't create the directory\n%1").arg( fi.absFilePath() ), 
782                                QMessageBox::Ok, 
783                                QMessageBox::NoButton, 
784                                QMessageBox::NoButton );
785         return false;
786       }
787     }
788     if ( !fi.isDir() ) {
789       QMessageBox::warning( this, 
790                             tr( "Warning" ), 
791                             tr( "The directory %1 is not a directory.\n"
792                                 "Please, enter valid target directory path" ).arg( fi.absFilePath() ), 
793                             QMessageBox::Ok, 
794                             QMessageBox::NoButton,
795                             QMessageBox::NoButton );
796       return false;
797     }
798     if ( !fi.isWritable() ) {
799       QMessageBox::warning( this, 
800                             tr( "Warning" ), 
801                             tr( "The directory %1 is not writeable.\n"
802                                 "Please, enter valid target directory path or change permissions" ).arg( fi.absFilePath() ), 
803                             QMessageBox::Ok, 
804                             QMessageBox::NoButton,
805                             QMessageBox::NoButton );
806       return false;
807     }
808     if ( hasSpace( fi.absFilePath() ) &&
809          QMessageBox::warning( this,
810                                tr( "Warning" ),
811                                tr( "The target directory contains space symbols.\n"
812                                    "This may cause problems with compiling or installing of products.\n\n"
813                                    "Do you want to continue?"),
814                                QMessageBox::Yes,
815                                QMessageBox::No,
816                                QMessageBox::NoButton ) == QMessageBox::No ) {
817       return false;
818     }
819     QString binDir = "./Products/BINARIES";
820     if ( !myOS.isEmpty() )
821       binDir += "/" + myOS;
822     QFileInfo fib( QDir::cleanDirPath( binDir ) );
823     if ( !fib.exists() ) {
824       QMessageBox::warning( this, 
825                             tr( "Warning" ), 
826                             tr( "The directory %1 doesn't exist.\n"
827                                 "This directory must contain binaries archives." ).arg( fib.absFilePath() ));
828     }
829     // run script that checks available disk space for installing of products    // returns 1 in case of error
830     QString script = "./config_files/checkSize.sh '";
831     script += fi.absFilePath();
832     script += "' ";
833     script += QString( "%1" ).arg( totSize );
834 #ifdef DEBUG
835     cout << "script = " << script << endl;
836 #endif
837     if ( system( script ) ) {
838       QMessageBox::critical( this, 
839                              tr( "Out of space" ), 
840                              tr( "There is not available disk space for installing of selected products" ), 
841                              QMessageBox::Ok, 
842                              QMessageBox::NoButton, 
843                              QMessageBox::NoButton );
844       return false;
845     }
846     // check temp directory
847     if ( tempDir.isEmpty() ) {
848       if ( moreMode ) {
849         QMessageBox::warning( this, 
850                               tr( "Warning" ), 
851                               tr( "Please, enter valid temp directory path" ), 
852                               QMessageBox::Ok, 
853                               QMessageBox::NoButton,
854                               QMessageBox::NoButton );
855         return false; 
856       }
857       else {
858         tempDir = "/tmp";
859         tempFolder->setText( tempDir );
860       }
861     }
862     QFileInfo fit( QDir::cleanDirPath( tempDir ) );
863     if ( !makeDir( fit.absFilePath() + TEMPDIRNAME, tmpCreated ) ) {
864       QMessageBox::critical( this, 
865                              tr( "Error" ), 
866                              tr( "Can't use temporary directory.\nCheck permissions for the %1 directory.").arg( fit.absFilePath() ), 
867                              QMessageBox::Ok, 
868                              QMessageBox::NoButton, 
869                              QMessageBox::NoButton );
870       return false;
871     }
872     // run script that check available disk space for temporary files
873     // returns 1 in case of error
874     QString tscript = "./config_files/checkSize.sh '";
875     tscript += fit.absFilePath();
876     tscript += "' ";
877     tscript += QString( "%1" ).arg( tempSize );
878 #ifdef DEBUG
879     cout << "script = " << tscript << endl;
880 #endif
881     if ( system( tscript ) ) {
882       QMessageBox::critical( this, 
883                              tr( "Out of space" ), 
884                              tr( "There is not available disk space for the temporary files" ), 
885                              QMessageBox::Ok, 
886                              QMessageBox::NoButton, 
887                              QMessageBox::NoButton );
888       return false;
889     }
890 // VSR: <------------------------------------------------------------------------------
891     // ########## check native products
892     QCheckListItem* item = (QCheckListItem*)( productsView->firstChild() );
893     QStringList natives;
894     while( item ) {
895       if ( productsMap.contains( item ) ) {
896         if ( item->childCount() > 0 ) {
897           if ( !productsView->isNone( item ) ) {
898             if ( item->text(2).isEmpty() || item->text(2).isNull() ) {
899               QMessageBox::warning( this, 
900                                     tr( "Warning" ), 
901                                     tr( "You don't have a defined script for %1").arg(item->text(0)), 
902                                     QMessageBox::Ok, 
903                                     QMessageBox::NoButton, 
904                                     QMessageBox::NoButton );
905               productsView->setNone( item );
906               return false;
907             } else {
908               QFileInfo fi( QString("./config_files/") + item->text(2) );
909               if ( !fi.exists() ) {
910                 QMessageBox::warning( this, 
911                                       tr( "Warning" ),  
912                                       tr( "%1 required for %2 doesn't exist.").arg("./config_files/" + item->text(2)).arg(item->text(0)),  
913                                       QMessageBox::Ok, 
914                                       QMessageBox::NoButton, 
915                                       QMessageBox::NoButton );
916                 productsView->setNone( item );
917                 return false;
918               }       
919             }
920           }
921           // collect native products
922           if ( productsView->isNative( item ) ) {
923             if ( natives.find( item->text(0) ) == natives.end() )
924               natives.append( item->text(0) );
925           } 
926           else if ( productsView->isBinaries( item ) || productsView->isSources( item ) ) {
927             QStringList dependOn = productsMap[ item ].getDependancies();
928             for ( int i = 0; i < (int)dependOn.count(); i++ ) {
929               QCheckListItem* depitem = findItem( dependOn[ i ] );
930               if ( depitem ) {
931                 if ( productsView->isNative( depitem ) && natives.find( depitem->text(0) ) == natives.end() )
932                   natives.append( depitem->text(0) );
933               } 
934               else {
935                 QMessageBox::warning( this, 
936                                       tr( "Warning" ), 
937                                       tr( "%1 is required for %2 %3 installation.\n"
938                                           "Please, add this product in config.xml file.").arg(dependOn[ i ]).arg(item->text(0)).arg(item->text(1)), 
939                                       QMessageBox::Ok, 
940                                       QMessageBox::NoButton, 
941                                       QMessageBox::NoButton );
942                 return false;
943               }
944             }
945           }
946         }
947       }
948       item = (QCheckListItem*)( item->nextSibling() );
949     }
950     QString tmpFolder = QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + TEMPDIRNAME;
951     QString tgtFolder = QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() );
952     for ( unsigned i = 0; i < natives.count(); i++ ) {
953       item = findItem( natives[ i ] );
954       if ( item ) {
955         QString script = "cd ./config_files/;" + item->text(2) + " try_native " +
956                 QFileInfo( tmpFolder ).absFilePath() + " " + QDir::currentDirPath() + "/Products " + QFileInfo( tgtFolder ).absFilePath() + " " +
957                 QUOTE(DefineDependeces(productsMap)) + " " + item->text(0);
958
959 #ifdef DEBUG
960         cout << "1. Script : " << script << endl;
961 #endif
962         if ( system( script ) ) {
963           QMessageBox::warning( this, 
964                                 tr( "Warning" ), 
965                                 tr( "You don't have native %1 %2 installed").arg(item->text(0)).arg(item->text(1)), 
966                                 QMessageBox::Ok, 
967                                 QMessageBox::NoButton, 
968                                 QMessageBox::NoButton );
969           productsView->setNone( item );
970           return false;
971         }
972       }
973       else {
974         QMessageBox::warning( this, 
975                               tr( "Warning" ), 
976                               tr( "%The product %1 %2 required for installation.\n"
977                                   "Please, add this product in config.xml file.").arg(item->text(0)).arg(item->text(1)),
978                               QMessageBox::Ok, 
979                               QMessageBox::NoButton, 
980                               QMessageBox::NoButton );
981         return false;
982       }
983     }
984   }
985   return InstallWizard::acceptData( pageTitle );
986 }
987 // ================================================================
988 /*!
989  *  SALOME_InstallWizard::checkSize
990  *  Calculates disk space required for the installation
991  */
992 // ================================================================
993 bool SALOME_InstallWizard::checkSize( long* totSize, long* tempSize )
994 {
995   long tots = 0, temps = 0;
996   int nbSelected = 0;
997
998   MapProducts::Iterator mapIter;
999   for ( mapIter = productsMap.begin(); mapIter != productsMap.end(); ++mapIter ) {
1000     QCheckListItem* item = mapIter.key();
1001     Dependancies dep = mapIter.data();
1002     if ( productsView->isBinaries( item ) ) {
1003       tots += dep.getSize();
1004     }
1005     else if ( productsView->isSources( item ) ) {
1006       tots += dep.getSize(true);
1007       temps = max( temps, dep.getTempSize() );
1008     }
1009     if ( !productsView->isNone( item ) )
1010       nbSelected++;
1011   }
1012  
1013   if ( totSize )
1014     *totSize = tots;
1015   if ( tempSize )
1016     *tempSize = temps;
1017   return ( nbSelected > 0 );
1018 }
1019 // ================================================================
1020 /*!
1021  *  SALOME_InstallWizard::checkProductPage
1022  *  Checks products page validity (directories and products selection) and
1023  *  enabled/disables "Next" button for the Products page
1024  */
1025 // ================================================================
1026 void SALOME_InstallWizard::checkProductPage()
1027 {
1028   long tots = 0, temps = 0;
1029
1030   // check if any product is selected;
1031   bool isAnyProductSelected = checkSize( &tots, &temps );
1032   // check if target directory is valid
1033   bool isTargetDirValid = !targetFolder->text().stripWhiteSpace().isEmpty();
1034   // check if temp directory is valid
1035   bool isTempDirValid = !moreMode || !tempFolder->text().stripWhiteSpace().isEmpty();
1036
1037   // update required size information
1038   requiredSize->setText( QString::number( tots )  + " Kb");
1039   requiredTemp->setText( QString::number( temps ) + " Kb");
1040
1041   // enable/disable "Next" button
1042   setNextEnabled( productsPage, isAnyProductSelected && isTargetDirValid && isTempDirValid );
1043 }
1044 // ================================================================
1045 /*!
1046  *  SALOME_InstallWizard::setPrerequisites
1047  *  Sets the product and all products this one depends on to be checked ( recursively )
1048  */
1049 // ================================================================
1050 void SALOME_InstallWizard::setPrerequisites( QCheckListItem* item )
1051 {
1052   if ( !productsMap.contains( item ) )
1053     return;
1054   if ( productsView->isNone( item ) )
1055     return;
1056   // get all prerequisites
1057   QStringList dependOn = productsMap[ item ].getDependancies();
1058   for ( int i = 0; i < (int)dependOn.count(); i++ ) {
1059     MapProducts::Iterator itProd;
1060     for ( itProd = productsMap.begin(); itProd != productsMap.end(); ++itProd ) {
1061       if ( itProd.data().getName() == dependOn[ i ] ) {
1062         if ( productsView->isNone( itProd.key() ) ) {
1063           QString defMode = itProd.data().getDefault();
1064           if ( defMode.isEmpty() )
1065             defMode = tr( "install binaries" );
1066           if ( defMode == tr( "install binaries" ) )
1067             productsView->setBinaries( itProd.key() );
1068           else if ( defMode == tr( "install sources" ) )
1069             productsView->setSources( itProd.key() );
1070           else if ( defMode == tr( "use native" ) )
1071             productsView->setNative( itProd.key() );
1072           setPrerequisites( itProd.key() );
1073         }
1074       }
1075     }
1076   }
1077 }
1078 // ================================================================
1079 /*!
1080  *  SALOME_InstallWizard::launchScript
1081  *  Runs installation script
1082  */
1083 // ================================================================
1084 void SALOME_InstallWizard::launchScript()
1085 {
1086   // try to find product being processed now
1087   QString prodProc = progressView->findStatus( Processing );
1088   if ( !prodProc.isNull() ) {
1089 #ifdef DEBUG
1090     cout << "Found <Processing>: " << prodProc.latin1() << endl;
1091 #endif
1092
1093     // if found - set status to "completed"
1094     progressView->setStatus( prodProc, Completed );
1095     // ... and call this method again
1096     launchScript();
1097     return;
1098   }
1099   // else try to find next product which is not processed yet
1100   prodProc = progressView->findStatus( Waiting );
1101   if ( !prodProc.isNull() ) {
1102 #ifdef DEBUG
1103     cout << "Found <Waiting>: " << prodProc.latin1() << endl;
1104 #endif
1105     // if found - set status to "processed" and run script
1106     progressView->setStatus( prodProc, Processing );
1107     progressView->ensureVisible( prodProc );
1108
1109     QCheckListItem* item = findItem( prodProc );
1110     Dependancies dep = productsMap[ item ];
1111     // fill in script parameters
1112     shellProcess->clearArguments();
1113     // ... script name
1114     shellProcess->setWorkingDirectory( QDir::cleanDirPath( QFileInfo( "./config_files/" ).absFilePath() ) );
1115     shellProcess->addArgument( item->text(2) );
1116
1117     // ... temp folder
1118     QString tmpFolder = QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + TEMPDIRNAME;
1119     //if( !tempFolder->isEnabled() )
1120     //tmpFolder = "/tmp";
1121
1122     // ... binaries ?
1123     if ( productsView->isBinaries( item ) ) {
1124       shellProcess->addArgument( "install_binary" );
1125       shellProcess->addArgument( QFileInfo( tmpFolder ).absFilePath() );
1126       QString binDir = QDir::currentDirPath() + "/Products/BINARIES";
1127       if ( !myOS.isEmpty() )
1128         binDir += "/" + myOS;
1129       shellProcess->addArgument( binDir );
1130     }
1131     // ... sources ?
1132     else if ( productsView->isSources( item ) ) {
1133       shellProcess->addArgument( "install_source" );
1134       shellProcess->addArgument( QFileInfo( tmpFolder ).absFilePath() );
1135       shellProcess->addArgument( QDir::currentDirPath() + "/Products/SOURCES" );
1136     }
1137     // ... native ?
1138     else if ( productsView->isNative( item ) ) {
1139       shellProcess->addArgument( "try_native" );
1140       shellProcess->addArgument( QFileInfo( tmpFolder ).absFilePath() );
1141       shellProcess->addArgument( QDir::currentDirPath() + "/Products" );
1142     }
1143     // ... not install : try to find preinstalled
1144     else {
1145       shellProcess->addArgument( "try_preinstalled" );
1146       shellProcess->addArgument( QFileInfo( tmpFolder ).absFilePath() );
1147       shellProcess->addArgument( QDir::currentDirPath() + "/Products" );
1148     }
1149     // ... target folder
1150     QString tgtFolder = QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() );
1151     shellProcess->addArgument( QFileInfo( tgtFolder ).absFilePath() );
1152     
1153
1154     QString depproducts = DefineDependeces(productsMap); 
1155 #ifdef DEBUG
1156     cout << "Dependancies"<< depproducts.latin1() << endl;
1157 #endif
1158
1159     shellProcess->addArgument( depproducts );
1160     // ... product name - currently instaled product
1161     shellProcess->addArgument( item->text(0) );
1162
1163     // run script
1164     if ( !shellProcess->start() ) {
1165       // error handling can be here
1166 #ifdef DEBUG
1167       cout << "error" << endl;
1168 #endif
1169     }
1170     return;
1171   }
1172 #ifdef DEBUG
1173   cout << "All products have been installed successfully" << endl;
1174 #endif
1175   // all products are installed successfully
1176   QString workDir = QDir::cleanDirPath( QFileInfo( "./config_files/" ).absFilePath() );
1177   MapProducts::Iterator mapIter;
1178 #ifdef DEBUG
1179   cout << "starting pick-up environment" << endl;
1180 #endif
1181   for ( mapIter = productsMap.begin(); mapIter != productsMap.end(); ++mapIter ) {
1182     QCheckListItem* item = mapIter.key();
1183     Dependancies dep = mapIter.data();
1184     QString depproducts = QUOTE( DefineDependeces(productsMap) ); 
1185     if ( dep.pickUpEnvironment() ) {
1186 #ifdef DEBUG
1187       cout << "... for " << dep.getName() << endl;
1188 #endif
1189       QString script;
1190       script += "cd " + QUOTE( QFileInfo( QDir::cleanDirPath( "./config_files/" ) ).absFilePath() ) + "; ";
1191       script += item->text(2) + " ";
1192       script += "pickup_env ";
1193       script += QUOTE( QFileInfo( QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + TEMPDIRNAME ).absFilePath() ) + " ";
1194       script += QUOTE( QFileInfo( QDir::cleanDirPath( QDir::currentDirPath() + "/Products" ) ).absFilePath() ) + " ";
1195       script += QUOTE( QFileInfo( QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() ) ).absFilePath() ) + " ";
1196       script += depproducts + " ";
1197       script += item->text(0);
1198 #ifdef DEBUG
1199       cout << "... --> " << script.latin1() << endl;
1200 #endif
1201       if ( system( script.latin1() ) ) { 
1202 #ifdef DEBUG
1203         cout << "ERROR" << endl; 
1204 #endif
1205       }
1206     }
1207   }
1208   // <Next> button
1209   nextButton()->setEnabled( true );
1210   nextButton()->setText( tr( "&Next >" ) );
1211   QWhatsThis::add( nextButton(), tr( "Moves to the next step of the installation procedure" ) );
1212   QToolTip::add  ( nextButton(), tr( "Moves to the next step of the installation procedure" ) );
1213   nextButton()->disconnect();
1214   connect( nextButton(), SIGNAL( clicked() ), this, SLOT( next() ) );
1215   // <Back> button
1216   backButton()->setEnabled( true );
1217   // script parameters
1218   passedParams->clear();
1219   passedParams->setEnabled( false );
1220   QFont f = parametersLab->font(); f.setBold( false ); parametersLab->setFont( f );
1221   if ( isMinimized() )
1222     showNormal();
1223   raise();
1224 }
1225 // ================================================================
1226 /*!
1227  *  SALOME_InstallWizard::onMoreBtn
1228  *  <More...> button slot
1229  */
1230 // ================================================================
1231 void SALOME_InstallWizard::onMoreBtn()
1232 {
1233   if ( moreMode ) {
1234     moreBox->hide();
1235     moreBtn->setText( tr( "More..." ) );
1236   }
1237   else {
1238     moreBox->show();
1239     moreBtn->setText( tr( "Less..." ) );
1240   }
1241   qApp->processEvents();
1242   moreMode = !moreMode;
1243   InstallWizard::layOut();
1244   qApp->processEvents();
1245   if ( !isMaximized() ) {
1246     //setGeometry( geometry().x(), geometry().y(), geometry().width(), 0 );
1247     resize( geometry().width(), 0 );
1248     qApp->processEvents();
1249   }
1250   checkProductPage();
1251 }
1252 // ================================================================
1253 /*!
1254  *  SALOME_InstallWizard::onLaunchSalome
1255  *  <Launch Salome> button slot
1256  */
1257 // ================================================================
1258 void SALOME_InstallWizard::onLaunchSalome()
1259 {
1260   QString msg = tr( "You don't have SALOME binaries installed in the %1 directory!" ).arg( targetFolder->text() );
1261
1262   QCheckListItem* item = findItem( "KERNEL-Bin" );
1263   if ( item ) {
1264     QFileInfo fi( targetFolder->text() + "/KERNEL_" + item->text(1) + "/bin/salome/runSalome" );
1265     QFileInfo fienv( targetFolder->text() + "/KERNEL_" + item->text(1) + "/salome.csh" );
1266     if ( fienv.exists() ) {
1267       if ( fi.exists() ) {
1268         QString script;
1269         script += "cd " + targetFolder->text() + "/KERNEL_" + item->text(1) + "; ";
1270         script += "source salome.csh; ";
1271         script += "cd bin/salome; ";
1272         script += "runSalome > /dev/null";
1273         script = "(csh -c '" + script + "')";
1274 #ifdef DEBUG
1275         cout << script.latin1() << endl;
1276 #endif
1277         if ( !system( script.latin1() ) )
1278           return;
1279         else
1280           msg = tr( "Can't launch SALOME." );
1281       }
1282       else
1283         msg = tr( "Can't launch SALOME." ) + "\n" + tr( "runSalome file can not be found." );
1284     }
1285     else
1286       msg = tr( "Can't launch SALOME." ) + "\n" + tr( "Can't find environment file." );
1287   }
1288   QMessageBox::warning( this, 
1289                         tr( "Error" ), 
1290                         msg,
1291                         QMessageBox::Ok, 
1292                         QMessageBox::NoButton,
1293                         QMessageBox::NoButton );
1294 }
1295 // ================================================================
1296 /*!
1297  *  SALOME_InstallWizard::findItem
1298  *  Searches product listview item with given symbolic name 
1299  */
1300 // ================================================================
1301 QCheckListItem* SALOME_InstallWizard::findItem( const QString& sName )
1302 {
1303   MapProducts::Iterator mapIter;
1304   for ( mapIter = productsMap.begin(); mapIter != productsMap.end(); ++mapIter ) {
1305     if ( mapIter.data().getName() == sName )
1306       return mapIter.key();
1307   }
1308   return 0;
1309 }
1310 // ================================================================
1311 /*!
1312  *  SALOME_InstallWizard::abort
1313  *  Sets progress state to Aborted
1314  */
1315 // ================================================================
1316 void SALOME_InstallWizard::abort()
1317 {
1318   QString prod = progressView->findStatus( Processing );
1319   while ( !prod.isNull() ) {
1320     progressView->setStatus( prod, Aborted );
1321     prod = progressView->findStatus( Processing );
1322   }
1323   prod = progressView->findStatus( Waiting );
1324   while ( !prod.isNull() ) {
1325     progressView->setStatus( prod, Aborted );
1326     prod = progressView->findStatus( Waiting );
1327   }
1328 }
1329 // ================================================================
1330 /*!
1331  *  SALOME_InstallWizard::reject
1332  *  Reject slot, clears temporary directory and closes application
1333  */
1334 // ================================================================
1335 void SALOME_InstallWizard::reject()
1336 {
1337 #ifdef DEBUG
1338   cout << "REJECTED" << endl;
1339 #endif
1340   if ( !exitConfirmed ) {
1341     if ( QMessageBox::information( this, 
1342                                    tr( "Exit" ), 
1343                                    tr( "Do you want to quit %1?" ).arg( getIWName() ), 
1344                                    tr( "&Yes" ), 
1345                                    tr( "&No" ),
1346                                    QString::null,
1347                                    0,
1348                                    1 ) == 1 ) {
1349       return;
1350     }
1351     exitConfirmed = true;
1352   }
1353   clean();
1354   InstallWizard::reject();
1355 }
1356 // ================================================================
1357 /*!
1358  *  SALOME_InstallWizard::accept
1359  *  Accept slot, clears temporary directory and closes application
1360  */
1361 // ================================================================
1362 void SALOME_InstallWizard::accept()
1363 {
1364 #ifdef DEBUG
1365   cout << "ACCEPTED" << endl;
1366 #endif
1367   clean();
1368   InstallWizard::accept();
1369 }
1370 // ================================================================
1371 /*!
1372  *  SALOME_InstallWizard::clean
1373  *  Clears and removes temporary directory
1374  */
1375 // ================================================================
1376 void SALOME_InstallWizard::clean()
1377 {
1378   // VSR: first remove temporary files
1379   QString script = "cd ./config_files/; remove_tmp.sh '";
1380   script += tempFolder->text().stripWhiteSpace() + TEMPDIRNAME;
1381   script += "' ";
1382   script += QUOTE(DefineDependeces(productsMap));
1383   script += " > /dev/null";
1384 #ifdef DEBUG
1385   cout << "script = " << script << endl;
1386 #endif
1387   if ( system( script.latin1() ) ) {
1388   }
1389   // VSR: then try to remove created temporary directory
1390   //script = "rm -rf " + QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + TEMPDIRNAME;
1391   if ( !tmpCreated.isNull() ) {
1392     script = "rm -rf " + tmpCreated;
1393     script += " > /dev/null";
1394     if ( system( script.latin1() ) ) {
1395     }
1396 #ifdef DEBUG
1397     cout << "script = " << script << endl;
1398 #endif
1399   }
1400 }
1401 // ================================================================
1402 /*!
1403  *  SALOME_InstallWizard::pageChanged
1404  *  Called when user moves from page to page
1405  */
1406 // ================================================================
1407 void SALOME_InstallWizard::pageChanged( const QString & mytitle)
1408 {
1409   nextButton()->setText( tr( "&Next >" ) );
1410   QWhatsThis::add( nextButton(), tr( "Moves to the next step of the installation procedure" ) );
1411   QToolTip::add  ( nextButton(), tr( "Moves to the next step of the installation procedure" ) );
1412   nextButton()->disconnect();
1413   connect( nextButton(), SIGNAL( clicked() ), this, SLOT( next() ) );
1414   cancelButton()->disconnect();
1415   connect( cancelButton(), SIGNAL( clicked()), this, SLOT( reject() ) );
1416
1417   QWidget* aPage = InstallWizard::page( mytitle );
1418   if ( !aPage )
1419     return;
1420   updateCaption();
1421   if ( aPage == productsPage ) {
1422     // products page
1423     onSelectionChanged();
1424     checkProductPage();
1425   }
1426   else if ( aPage == prestartPage ) {
1427     // prestart page
1428     showChoiceInfo();
1429   }
1430   else if ( aPage == progressPage ) {
1431     if ( previousPage == prestartPage ) {
1432       // progress page
1433       progressView->clear();
1434       installInfo->clear();
1435       passedParams->clear();
1436       passedParams->setEnabled( false );
1437       QFont f = parametersLab->font(); f.setBold( false ); parametersLab->setFont( f );
1438       nextButton()->setText( tr( "&Start" ) );
1439       QWhatsThis::add( nextButton(), tr( "Starts installation process" ) );
1440       QToolTip::add  ( nextButton(), tr( "Starts installation process" ) );
1441       // reconnect Next button - to use it as Start button
1442       nextButton()->disconnect();
1443       connect( nextButton(), SIGNAL( clicked() ), this, SLOT( onStart() ) );
1444       nextButton()->setEnabled( true );
1445       // reconnect Cancel button to terminate process
1446       cancelButton()->disconnect();
1447       connect( cancelButton(), SIGNAL( clicked() ), this, SLOT( tryTerminate() ) );
1448     }
1449   }
1450   else if ( aPage == readmePage ) {
1451     QCheckListItem* item = findItem( "KERNEL-Bin" );
1452     runSalomeBtn->setEnabled( item &&
1453                               QFileInfo( targetFolder->text() + "/KERNEL_" + item->text(1) + "/bin/salome/runSalome" ).exists() &&
1454                               QFileInfo( targetFolder->text() + "/KERNEL_" + item->text(1) + "/salome.csh" ).exists() );
1455     finishButton()->setEnabled( true );
1456   }
1457   previousPage = aPage;
1458 #ifdef DEBUG
1459   cout << "previousPage = " << previousPage << endl;
1460 #endif
1461 }
1462 // ================================================================
1463 /*!
1464  *  SALOME_InstallWizard::helpClicked
1465  *  Shows help window
1466  */
1467 // ================================================================
1468 void SALOME_InstallWizard::helpClicked()
1469 {
1470   if ( helpWindow == NULL ) {
1471     helpWindow = HelpWindow::openHelp( this );
1472     if ( helpWindow ) {
1473       helpWindow->show();
1474       helpWindow->installEventFilter( this );
1475     }
1476     else {
1477       QMessageBox::warning( this, 
1478                             tr( "Help file not found" ), 
1479                             tr( "Sorry, help is unavailable" ) );
1480     }
1481   }
1482   else {
1483     helpWindow->raise();
1484     helpWindow->setActiveWindow();
1485   }
1486 }
1487 // ================================================================
1488 /*!
1489  *  SALOME_InstallWizard::browseDirectory
1490  *  Shows directory selection dialog
1491  */
1492 // ================================================================
1493 void SALOME_InstallWizard::browseDirectory()
1494 {
1495   const QObject* theSender = sender();
1496   QLineEdit* theFolder;
1497   if ( theSender == targetBtn )
1498     theFolder = targetFolder;
1499   else if (theSender == tempBtn)
1500     theFolder = tempFolder;
1501   else
1502     return;
1503   QString typedDir = QFileDialog::getExistingDirectory( QDir::cleanDirPath( theFolder->text().stripWhiteSpace() ), this );
1504   if ( !typedDir.isNull() ) {
1505     theFolder->setText( typedDir );
1506     theFolder->end( false );
1507   }
1508   checkProductPage();
1509 }
1510 // ================================================================
1511 /*!
1512  *  SALOME_InstallWizard::directoryChanged
1513  *  Called when directory path (target or temp) is changed
1514  */
1515 // ================================================================
1516 void SALOME_InstallWizard::directoryChanged( const QString& /*text*/ )
1517 {
1518   checkProductPage();
1519 }
1520 // ================================================================
1521 /*!
1522  *  SALOME_InstallWizard::onStart
1523  *  <Start> button's slot - runs installation
1524  */
1525 // ================================================================
1526 void SALOME_InstallWizard::onStart()
1527 {
1528   // clear list of products to install ...
1529   toInstall.clear();
1530   // ... and fill it for new process
1531   QCheckListItem* item = (QCheckListItem*)( productsView->firstChild() );
1532   while( item ) {
1533 //    if ( productsView->isBinaries( item ) || productsView->isSources( item ) || productsView->isNative( item ) ) {
1534       if ( productsMap.contains( item ) )
1535         toInstall.append( productsMap[item].getName() );
1536 //    }
1537     item = (QCheckListItem*)( item->nextSibling() );
1538   }
1539   // if something at all is selected
1540   if ( !toInstall.isEmpty() ) {
1541     // disable <Next> button
1542     nextButton()->setEnabled( false );
1543     // disable <Back> button
1544     backButton()->setEnabled ( false );
1545     // enable script parameters line edit
1546     // VSR commented: 18/09/03: passedParams->setEnabled( true );
1547     // VSR commented: 18/09/03: passedParams->setFocus();
1548     // set status for all products
1549     for ( int i = 0; i < (int)toInstall.count(); i++ ) {
1550       item = findItem( toInstall[ i ] );
1551       QString type = "";
1552       if ( productsView->isBinaries( item ) )
1553         type = tr( "binaries" );
1554       else if ( productsView->isSources( item ) )
1555         type = tr( "sources" );
1556       else if ( productsView->isNative( item ) )
1557         type = tr( "native" );
1558       else 
1559         type = tr( "not install" );
1560       progressView->addProduct( item->text(0), type, item->text(2) );
1561     }
1562     // launch install script
1563     launchScript();
1564   }
1565 }
1566 // ================================================================
1567 /*!
1568  *  SALOME_InstallWizard::onReturnPressed
1569  *  Called when users tries to pass parameters for the script
1570  */
1571 // ================================================================
1572 void SALOME_InstallWizard::onReturnPressed()
1573 {
1574   QString txt = passedParams->text();
1575   installInfo->append( txt );
1576   txt += "\n";
1577   shellProcess->writeToStdin( txt );
1578   passedParams->clear();
1579   progressView->setFocus();
1580   passedParams->setEnabled( false );
1581   QFont f = parametersLab->font(); f.setBold( false ); parametersLab->setFont( f );
1582 }
1583 /*!
1584   Callback function - as response for the script finishing
1585 */
1586 void SALOME_InstallWizard::productInstalled( )
1587 {
1588 #ifdef DEBUG
1589   cout << "process exited" << endl;
1590 #endif
1591   if ( shellProcess->normalExit() ) {
1592 #ifdef DEBUG
1593     cout << "...normal exit" << endl;
1594 #endif
1595     // normal exit - try to proceed installation further
1596     launchScript();
1597   }
1598   else {
1599 #ifdef DEBUG
1600     cout << "...abnormal exit" << endl;
1601 #endif
1602     // installation aborted
1603     abort();
1604     // clear script passed parameters lineedit
1605     passedParams->clear();
1606     passedParams->setEnabled( false );
1607     QFont f = parametersLab->font(); f.setBold( false ); parametersLab->setFont( f );
1608     // enable <Next> button
1609     nextButton()->setEnabled( true );
1610     nextButton()->setText( tr( "&Next >" ) );
1611     QWhatsThis::add( nextButton(), tr( "Moves to the next step of the installation procedure" ) );
1612     QToolTip::add  ( nextButton(), tr( "Moves to the next step of the installation procedure" ) );
1613     nextButton()->disconnect();
1614     connect( nextButton(), SIGNAL( clicked() ), this, SLOT( next() ) );
1615     // enable <Back> button
1616     backButton()->setEnabled( true );
1617   }
1618 }
1619 // ================================================================
1620 /*!
1621  *  SALOME_InstallWizard::tryTerminate
1622  *  Slot, called when <Cancel> button is clicked during installation script running
1623  */
1624 // ================================================================
1625 void SALOME_InstallWizard::tryTerminate()
1626 {
1627   if ( shellProcess->isRunning() ) {
1628     if ( QMessageBox::information( this, 
1629                                    tr( "Exit" ), 
1630                                    tr( "Do you want to quit %1?" ).arg( getIWName() ), 
1631                                    tr( "&Yes" ), 
1632                                    tr( "&No" ),
1633                                    QString::null,
1634                                    0,
1635                                    1 ) == 1 ) {
1636       return;
1637     }
1638     exitConfirmed = true;
1639     // if process still running try to terminate it first
1640     shellProcess->tryTerminate();
1641     abort();
1642     //QTimer::singleShot( 3000, this, SLOT( onCancel() ) );
1643     connect( shellProcess, SIGNAL( processExited() ), this, SLOT( onCancel() ) );
1644   }
1645   else {
1646     // else just quit install wizard
1647     reject();
1648   }
1649 }
1650 // ================================================================
1651 /*!
1652  *  SALOME_InstallWizard::onCancel
1653  *  Kills installation process and quits application
1654  */
1655 // ================================================================
1656 void SALOME_InstallWizard::onCancel()
1657 {
1658   shellProcess->kill();
1659   reject();
1660 }
1661 // ================================================================
1662 /*!
1663  *  SALOME_InstallWizard::onSelectionChanged
1664  *  Called when selection is changed in the products list view
1665  */
1666 // ================================================================
1667 void SALOME_InstallWizard::onSelectionChanged()
1668 {
1669   productsInfo->clear();
1670   QListViewItem* item = productsView->selectedItem();
1671   if ( !item )
1672     return;
1673   if ( item->parent() )
1674     item = item->parent();
1675   QCheckListItem* aItem = (QCheckListItem*)item;
1676   if ( !productsMap.contains( aItem ) )
1677     return;
1678   Dependancies dep = productsMap[ aItem ];
1679   QString text = "<b>" + aItem->text(0) + "</b>" + "<br>";
1680   if ( !aItem->text(1).stripWhiteSpace().isEmpty() )
1681     text += tr( "Version" ) + ": " + aItem->text(1) + "<br>";
1682   text += "<br>";
1683   if ( !dep.getDescription().isEmpty() ) {
1684     text += "<i>" + dep.getDescription() + "</i><br><br>";
1685   }
1686   text += tr( "User choice" ) + ": ";
1687   long totSize = 0, tempSize = 0;
1688   if ( productsView->isBinaries( aItem ) ) {
1689     text += "<b>" + tr( "install binaries" ) + "</b>" + "<br>";
1690     totSize = dep.getSize();
1691   }
1692   else if ( productsView->isSources( aItem ) ) {
1693     text += "<b>" + tr( "install sources" ) + "</b>" + "<br>";
1694     totSize = dep.getSize( true );
1695     tempSize = dep.getTempSize();
1696   }
1697   else if ( productsView->isNative( aItem ) ) {
1698     text += "<b>" + tr( "use native" ) + "</b>" + "<br>";
1699   }
1700   else {
1701     text += "<b>" + tr( "not install" ) + "</b>" + "<br>";
1702   }
1703   
1704   text += tr( "Disk space required" ) + ": " + QString::number( totSize ) + " Kb<br>";
1705   text += tr( "Disk space for tmp files required" ) + ": " + QString::number( tempSize ) + " Kb<br>";
1706   text += "<br>";
1707   QString req = ( dep.getDependancies().count() > 0 ? dep.getDependancies().join(", ") : tr( "none" ) );
1708   text +=  tr( "Prerequisites" ) + ": " + req;
1709   productsInfo->setText( text );
1710 }
1711 // ================================================================
1712 /*!
1713  *  SALOME_InstallWizard::onItemToggled
1714  *  Called when user checks/unchecks any product item
1715  *  Recursively sets all prerequisites and updates "Next" button state
1716  */
1717 // ================================================================
1718 void SALOME_InstallWizard::onItemToggled( QCheckListItem* item )
1719 {
1720   if ( prerequisites->isChecked() ) {
1721     if ( item->parent() )
1722       item = (QCheckListItem*)( item->parent() );
1723     if ( productsMap.contains( item ) ) {
1724       productsView->blockSignals( true );
1725       setPrerequisites( item );
1726       productsView->blockSignals( false );
1727     }
1728   }
1729   onSelectionChanged();
1730   checkProductPage();
1731 }
1732 // ================================================================
1733 /*!
1734  *  SALOME_InstallWizard::onProdBtn
1735  *  This slot is called when user clicks one of <Select Sources>,
1736  *  <Select Binaries>, <Unselect All> buttons ( products page )
1737  */
1738 // ================================================================
1739 void SALOME_InstallWizard::onProdBtn()
1740 {
1741   const QObject* snd = sender();
1742   productsView->blockSignals( true );
1743   if ( snd == unselectBtn ) {
1744     QCheckListItem* item = (QCheckListItem*)( productsView->firstChild() );
1745     while( item ) {
1746       productsView->setNone( item );
1747       item = (QCheckListItem*)( item->nextSibling() );
1748     }
1749   }
1750   productsView->blockSignals( false );
1751   onSelectionChanged();
1752   checkProductPage();
1753 }
1754 // ================================================================
1755 /*!
1756  *  SALOME_InstallWizard::wroteToStdin
1757  *  QProcess slot: -->something was written to stdin
1758  */
1759 // ================================================================
1760 void SALOME_InstallWizard::wroteToStdin( )
1761 {
1762 #ifdef DEBUG
1763   cout << "Something was sent to stdin" << endl;
1764 #endif
1765 }
1766 // ================================================================
1767 /*!
1768  *  SALOME_InstallWizard::readFromStdout
1769  *  QProcess slot: -->something was written to stdout
1770  */
1771 // ================================================================
1772 void SALOME_InstallWizard::readFromStdout( )
1773 {
1774 #ifdef DEBUG
1775   cout << "Something was sent to stdout" << endl;
1776 #endif
1777   while ( shellProcess->canReadLineStdout() ) {
1778     installInfo->append( QString( shellProcess->readLineStdout() ) );
1779     installInfo->scrollToBottom();
1780   }
1781   QString str( shellProcess->readStdout() );
1782   if ( !str.isEmpty() ) {
1783     installInfo->append( str );
1784     installInfo->scrollToBottom();
1785   }
1786 }
1787 // ================================================================
1788 /*!
1789  *  SALOME_InstallWizard::readFromStderr
1790  *  QProcess slot: -->something was written to stderr
1791  */
1792 // ================================================================
1793 void SALOME_InstallWizard::readFromStderr( )
1794 {
1795 #ifdef DEBUG
1796   cout << "Something was sent to stderr" << endl;
1797 #endif
1798   while ( shellProcess->canReadLineStderr() ) {
1799     installInfo->append( QString( shellProcess->readLineStderr() ) );
1800     installInfo->scrollToBottom();
1801   }
1802   QString str( shellProcess->readStderr() );
1803   if ( !str.isEmpty() ) {
1804     installInfo->append( str );
1805     installInfo->scrollToBottom();
1806   }
1807   passedParams->setEnabled( true );
1808   passedParams->setFocus();
1809   QFont f = parametersLab->font(); f.setBold( true ); parametersLab->setFont( f );
1810 }
1811 // ================================================================
1812 /*!
1813  *  SALOME_InstallWizard::setDependancies
1814  *  Sets dependancies for the product item
1815  */
1816 // ================================================================
1817 void SALOME_InstallWizard::setDependancies( QCheckListItem* item, Dependancies dep)
1818 {
1819   productsMap[item] = dep;
1820 }
1821 // ================================================================
1822 /*!
1823  *  SALOME_InstallWizard::polish
1824  *  Polishing of the widget - to set right initial size
1825  */
1826 // ================================================================
1827 void SALOME_InstallWizard::polish()
1828 {
1829   resize( 0, 0 );
1830   InstallWizard::polish();
1831 }
1832 // ================================================================
1833 /*!
1834  *  SALOME_InstallWizard::updateCaption
1835  *  Updates caption according to the current page number
1836  */
1837 // ================================================================
1838 void SALOME_InstallWizard::updateCaption()
1839 {
1840   QWidget* aPage = InstallWizard::currentPage();
1841   if ( !aPage ) 
1842     return;
1843   InstallWizard::setCaption( tr( myCaption ) + " " +
1844                              tr( getIWName() ) + " - " +
1845                              tr( "Step %1 of %2").arg( QString::number( this->indexOf( aPage )+1 ) ).arg( QString::number( this->pageCount() ) ) );
1846 }