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