1 // File : SALOME_InstallWizard.cxx
2 // Created : Thu Dec 18 12:01:00 2002
3 // Author : Vadim SANDLER, Open CASCADE SAS (vadim.sandler@opencascade.com)
5 // Module : Installation Wizard
6 // Copyright : 2002-2015 CEA
10 #include "SALOME_InstallWizard.hxx"
11 #include "SALOME_ProductsView.hxx"
12 #include "SALOME_ProgressView.hxx"
13 #include "SALOME_XmlHandler.hxx"
14 #include "SALOME_HelpWindow.hxx"
18 #include <qlineedit.h>
19 #include <qpushbutton.h>
20 #include <qlistview.h>
22 #include <qtextedit.h>
23 #include <qtextbrowser.h>
25 #include <qcheckbox.h>
26 #include <qsplitter.h>
28 #include <qfiledialog.h>
29 #include <qapplication.h>
30 #include <qfileinfo.h>
31 #include <qmessagebox.h>
34 #include <qwhatsthis.h>
38 #include <qwaitcondition.h>
40 #include <qstringlist.h>
41 #include <qpopupmenu.h>
43 #include <qradiobutton.h>
44 #include <qbuttongroup.h>
54 #include <sys/utsname.h>
58 #define max( x, y ) ( x ) > ( y ) ? ( x ) : ( y )
61 QString tmpDirName() { return QString( "/INSTALLWORK" ) + QString::number( getpid() ); }
62 #define TEMPDIRNAME tmpDirName()
64 // uncomment next line to redirect all shell output (usually for errors) to /dev/null device
65 // #define USE_DEV_NULL
67 // ================================================================
70 * Helper class to generate shell command
72 // ================================================================
76 Script( const QString& cmd = QString::null, const QString& sep = " " ) : mySeparator( sep )
80 void append( const QString& cmd )
82 if ( !cmd.isEmpty() ) myList.append( cmd );
84 Script& operator<<( const QString& cmd )
89 QString script() const
91 return myList.join( mySeparator );
102 // ================================================================
105 * Class for executing system commands
107 // ================================================================
108 static QMutex myMutex(false);
109 static QWaitCondition myWC;
110 class ProcessThread: public QThread
112 typedef QPtrList<QCheckListItem> ItemList;
114 ProcessThread( SALOME_InstallWizard* iw ) : QThread(), myWizard( iw ) { myItems.setAutoDelete( false ); }
116 void addCommand( QCheckListItem* item, const QString& cmd ) {
117 myItems.append( item );
118 myCommands.push_back( cmd );
121 bool hasCommands() const { return myCommands.count() > 0; }
122 void clearCommands() { myCommands.clear(); myItems.clear(); }
125 while ( hasCommands() ) {
126 ___MESSAGE___( "ProcessThread::run - Processing command : " << myCommands[ 0 ].latin1() );
127 int result = system( myCommands[ 0 ] ) / 256; // return code is <errno> * 256
128 ___MESSAGE___( "ProcessThread::run - Result : " << result );
129 QCheckListItem* item = myItems.first();
130 myCommands.pop_front();
131 myItems.removeFirst();
133 SALOME_InstallWizard::postValidateEvent( myWizard, result, (void*)item );
141 QStringList myCommands;
143 SALOME_InstallWizard* myWizard;
146 // ================================================================
151 // ================================================================
152 class WarnDialog: public QDialog
154 static WarnDialog* myDlg;
157 WarnDialog( QWidget* parent )
158 : QDialog( parent, "WarnDialog", true, WDestructiveClose ) {
159 setCaption( tr( "Information" ) );
161 QLabel* lab = new QLabel( tr( "Please, wait while checking native products configuration ..." ), this );
162 lab->setAlignment( AlignCenter );
163 lab->setFrameStyle( QFrame::Box | QFrame::Plain );
164 QVBoxLayout* l = new QVBoxLayout( this );
167 this->setFixedSize( lab->sizeHint().width() + 50,
168 lab->sizeHint().height() * 5 );
170 void accept() { return; }
171 void reject() { return; }
172 void closeEvent( QCloseEvent* e )
173 { if ( !myCloseFlag ) return;
175 QDialog::closeEvent( e );
177 ~WarnDialog() { myDlg = 0; }
179 static void showWarnDlg( QWidget* parent, bool show ) {
182 myDlg = new WarnDialog( parent );
183 QSize sh = myDlg->size();
184 myDlg->move( parent->x() + (parent->width()-sh.width())/2,
185 parent->y() + (parent->height()-sh.height())/2 );
193 myDlg->myCloseFlag = true;
198 static bool isWarnDlgShown() { return myDlg != 0; }
200 WarnDialog* WarnDialog::myDlg = 0;
202 // ================================================================
205 * Installation progress info window class
207 // ================================================================
208 class InstallInfo : public QTextEdit
211 InstallInfo( QWidget* parent ) : QTextEdit( parent ), finished( false ) {}
212 void setFinished( const bool f ) { finished = f; }
214 QPopupMenu* createPopupMenu( const QPoint& )
216 int para1, col1, para2, col2;
217 getSelection(¶1, &col1, ¶2, &col2);
218 bool allSelected = hasSelectedText() &&
219 para1 == 0 && para2 == paragraphs()-1 && col1 == 0 && col2 == paragraphLength(para2);
220 QPopupMenu* popup = new QPopupMenu( this );
221 int id = popup->insertItem( tr( "&Copy" ) );
222 popup->setItemEnabled( id, hasSelectedText() );
223 popup->connectItem ( id, this, SLOT( copy() ) );
224 id = popup->insertItem( tr( "Select &All" ) );
225 popup->setItemEnabled( id, (bool)text().length() && !allSelected );
226 popup->connectItem ( id, this, SLOT( selectAll() ) );
228 QWidget* p = parentWidget();
229 while ( p && !p->inherits( "SALOME_InstallWizard" ) )
230 p = p->parentWidget();
231 if ( p && p->inherits( "SALOME_InstallWizard" ) ) {
232 popup->insertSeparator();
233 id = popup->insertItem( tr( "&Save Log" ) );
234 popup->setItemEnabled( id, (bool)text().length() );
235 popup->connectItem ( id, (SALOME_InstallWizard*)p, SLOT( saveLog() ) );
244 // ================================================================
246 * getAllProducts [ static ]
247 * Defines list of all products as a string separated by space symbols
249 // ================================================================
250 static QString getAllProducts(MapProducts& theProductsMap)
252 QStringList aModules, aPrereqs;
253 for ( MapProducts::Iterator mapIter = theProductsMap.begin(); mapIter != theProductsMap.end(); ++mapIter ) {
254 QCheckListItem* item = mapIter.key();
255 Dependancies dep = mapIter.data();
256 QString curModule = item->text(0);
257 if ( !aModules.contains( curModule ) && !aPrereqs.contains( curModule ) ) {
258 if ( dep.getType() == "component" ) {
259 aModules.append( curModule );
260 aModules.append( curModule + "_src" );
263 aPrereqs.append( curModule );
264 aPrereqs.append( curModule + "_src" );
268 return QStringList(aPrereqs+aModules).join(" ");
271 // ================================================================
273 * setAboutInfo [ static ]
274 * Sets 'what's this' and 'tooltip' information for the widget
276 // ================================================================
277 static void setAboutInfo( QWidget* widget, const QString& tip )
279 QWhatsThis::add( widget, tip );
280 QToolTip::add ( widget, tip );
283 #define QUOTE(arg) QString("'") + QString(arg) + QString("'")
285 /* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
286 T H E O L D I M P L E M E N T A T I O N
287 static QString DefineDependeces(MapProducts& theProductsMap, QCheckListItem* product ){
288 QStringList aProducts;
289 if ( theProductsMap.contains( product ) ) {
290 Dependancies dep = theProductsMap[ product ];
291 QStringList deps = dep.getDependancies();
292 for (int i = 0; i<(int)deps.count(); i++ ) {
293 aProducts.append( deps[i] );
296 return QString("\"") + aProducts.join(" ") + QString("\"");
298 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */
300 // ================================================================
303 * Makes directory recursively, returns false if not succedes
305 // ================================================================
306 static bool makeDir( const QString& theDir, QString& theCreated )
308 if ( theDir.isEmpty() )
310 QString aDir = QDir::cleanDirPath( QFileInfo( theDir ).absFilePath() );
312 while ( start > 0 ) {
313 start = aDir.find( QDir::separator(), start );
315 QFileInfo fi( aDir.left( start ) );
316 if ( !fi.exists() ) {
317 // VSR: Create directory and set permissions to allow other users to remove it
319 script << "mkdir" << QUOTE( fi.absFilePath() );
321 script << ">& /dev/null";
324 script << "chmod 777" << QUOTE( fi.absFilePath() );
326 script << ">& /dev/null";
328 ___MESSAGE___( "script = " << script.script().latin1() );
329 if ( system( script.script().latin1() ) )
331 // VSR: Remember the top of the created directory (to remove it in the end of the installation)
332 if ( theCreated.isNull() )
333 theCreated = fi.absFilePath();
338 if ( !QFileInfo( aDir ).exists() ) {
339 // VSR: Create directory, other users should NOT have possibility to remove it!!!
341 script << "mkdir" << QUOTE( aDir );
343 script << ">& /dev/null";
345 ___MESSAGE___( "script = " << script.script().latin1() );
346 if ( system( script.script().latin1() ) )
348 // VSR: Remember the top of the created directory (to remove it in the end of the installation)
349 if ( theCreated.isNull() )
354 // ================================================================
356 * readFile [ static ]
357 * Reads the file, returns false if can't open it
359 // ================================================================
360 static bool readFile( const QString& fileName, QString& text )
362 if ( QFile::exists( fileName ) ) {
363 QFile file( fileName );
364 if ( file.open( IO_ReadOnly ) ) {
365 QTextStream stream( &file );
367 while ( !stream.eof() ) {
368 line = stream.readLine(); // line of text excluding '\n'
377 // ================================================================
379 * hasSpace [ static ]
380 * Checks if string contains spaces; used to check directory paths
382 // ================================================================
383 static bool hasSpace( const QString& dir )
385 for ( int i = 0; i < (int)dir.length(); i++ ) {
386 if ( dir[ i ].isSpace() )
392 // ================================================================
395 * Creates HTML-wrapped title text
397 // ================================================================
398 static QString makeTitle( const QString& text, const QString& separator = " ", bool fl = true )
400 QStringList words = QStringList::split( separator, text );
402 for ( uint i = 0; i < words.count(); i++ )
403 words[i] = QString( "<font color=red>%1</font>" ).arg( words[i].left(1) ) + words[i].mid(1);
406 if ( words.count() > 0 )
407 words[0] = QString( "<font color=red>%1</font>" ).arg( words[0] );
408 if ( words.count() > 1 )
409 words[words.count()-1] = QString( "<font color=red>%1</font>" ).arg( words[words.count()-1] );
411 QString res = words.join( separator );
412 if ( !res.isEmpty() )
413 res = QString( "<b>%1</b>" ).arg( res );
417 // ================================================================
419 * QMyCheckBox class : custom check box
420 * The only goal is to give access to the protected setState() method
422 // ================================================================
423 class QMyCheckBox: public QCheckBox
426 QMyCheckBox( const QString& text, QWidget* parent, const char* name = 0 ) : QCheckBox ( text, parent, name ) {}
427 void setState ( ToggleState s ) { QCheckBox::setState( s ); }
430 // ================================================================
435 // ================================================================
436 class AboutDlg: public QDialog
439 AboutDlg( SALOME_InstallWizard* parent ) : QDialog( parent, "About dialog box", true )
442 setCaption( tr( "About %1" ).arg( parent->getIWName() ) );
444 QPalette pal = palette();
445 QColorGroup cg = pal.active();
446 cg.setColor( QColorGroup::Foreground, Qt::darkBlue );
447 cg.setColor( QColorGroup::Background, Qt::white );
448 pal.setActive( cg ); pal.setInactive( cg ); pal.setDisabled( cg );
451 QGridLayout* main = new QGridLayout( this, 1, 1, 11, 6 );
453 QLabel* logo = new QLabel( this, "logo" );
454 logo->setFixedSize( 24, 24 );
455 logo->setFrameStyle( QLabel::NoFrame | QLabel::Plain );
456 logo->setPixmap( pixmap( pxAbout ) );
457 logo->setScaledContents( false );
458 logo->setAlignment( QLabel::AlignCenter );
460 QLabel* title = new QLabel( this, "title" );
461 QString tlt = parent->getIWName();
462 title->setText( makeTitle( tlt ) );
463 QLabel* version = new QLabel( this, "version" );
464 version->setText( QString( "<b>Version</b>: %1.%1.%1" )
465 .arg( __IW_VERSION_MAJOR__ )
466 .arg( __IW_VERSION_MINOR__ )
467 .arg( __IW_VERSION_PATCH__ ) );
468 QLabel* copyright = new QLabel( this, "copyright" );
469 copyright->setText( "<b>Copyright</b> © 2002-2015 CEA" );
470 QFont font = title->font();
471 font.setPointSize( (int)( font.pointSize() * 1.8 ) );
472 title->setFont( font );
473 QFrame* line = new QFrame( this, "line" );
474 line->setFrameStyle( QFrame::HLine | QFrame::Sunken );
475 QLabel* url = new QLabel( this, "url" );
476 url->setText( makeTitle( "www.salome-platform.org", ".", false ) );
477 url->setAlignment( AlignRight );
478 font = version->font();
479 font.setPointSize( (int)( font.pointSize() / 1.2 ) );
480 version->setFont( font );
481 copyright->setFont( font );
482 url->setFont( font );
484 main->addWidget( logo, 0, 0 );
485 main->addWidget( title, 0, 1 );
486 main->addWidget( version, 1, 1 );
487 main->addWidget( copyright, 2, 1 );
488 main->addWidget( line, 3, 1 );
489 main->addWidget( url, 4, 1 );
491 QFontMetrics fm( title->font() );
492 int width = (int)( fm.width( tlt ) * 1.5 );
493 title->setMinimumWidth( width );
495 void mousePressEvent( QMouseEvent* )
501 // ================================================================
503 * SALOME_InstallWizard::SALOME_InstallWizard
506 // ================================================================
507 SALOME_InstallWizard::SALOME_InstallWizard(const QString& aXmlFileName,
508 const QString& aTargetDir,
509 const QString& aTmpDir,
510 const bool aForceSrc,
511 const bool aSingleDir)
512 : InstallWizard( qApp->desktop(), "SALOME_InstallWizard", false, 0 ),
516 exitConfirmed( false ),
519 myIWName = tr( "Installation Wizard" );
520 tmpCreated = QString::null;
521 xmlFileName = aXmlFileName;
522 myTargetPath = aTargetDir;
524 forceSrc = aForceSrc;
525 singleDir = aSingleDir;
528 QDir rootDir( rootDirPath() );
529 binPath = rootDir.filePath( "Products/BINARIES" );
530 srcPath = rootDir.filePath( "Products/SOURCES" );
531 oneProdDirName = "PRODUCTS";
533 commonPlatform = "Debian 3.1";
536 // get XML filename and current platform
538 // ... get current platform
539 curPlatform = currentPlatform().join(" ");
540 //cout << "curOS = " << curPlatform << endl;
542 // ... check XML and platform definition
545 // set application font
547 fnt.setPointSize( 14 );
552 setIcon( pixmap( pxIcon ) );
554 setSizeGripEnabled( true );
557 addLogo( pixmap( pxLogo ) );
560 setVersion( "7.5.1" );
561 setCaption( tr( "SALOME %1" ).arg( myVersion ) );
562 setCopyright( tr( "<h5>Copyright © 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE<br></h5>"
563 "<h5>Copyright © 2003-2007 OPEN CASCADE,<br>EADS/CCR, LIP6, CEA/DEN, CEDRAT, EDF R&D,<br>LEG, PRINCIPIA R&D, BUREAU VERITAS</h5>" ));
564 setLicense( tr( "<h5>GNU LGPL</h5>" ) );
566 ___MESSAGE___( "Configuration file : " << xmlFileName.latin1() );
567 ___MESSAGE___( "Target directory : " << myTargetPath.latin1() );
568 ___MESSAGE___( "Temporary directory: " << myTmpPath.latin1() );
573 StructureParser* parser = new StructureParser( this );
574 parser->readXmlFile(xmlFileName);
576 // create instance of class for starting shell script to get available disk space
577 diskSpaceProc = new QProcess( this, "procDiskSpace" );
578 // create instance of class for starting shell install script
579 shellProcess = new QProcess( this, "shellProcess" );
580 // create instance of class for starting shell script to modify SALOME *.la files
581 modifyLaProc = new QProcess( this, "modifyLaProc" );
582 // create instance of class for starting shell script to check Fortran libraries
583 checkFLibProc = new QProcess( this, "checkFLibProc" );
585 // create introduction page
587 // create page to select installation type
589 // create page to select the reference installation platform (if necessary)
591 // create directories page
593 // create products page
595 // create prestart page
597 // create progress page
599 // create readme page
603 setAboutInfo( backButton(), tr( "Return to the previous step\nof the installation procedure" ) );
604 setAboutInfo( nextButton(), tr( "Move to the next step\nof the installation procedure" ) );
605 setAboutInfo( finishButton(), tr( "Finish the installation and quit the program" ) );
606 setAboutInfo( cancelButton(), tr( "Cancel the installation and quit the program" ) );
607 setAboutInfo( helpButton(), tr( "Show the help information" ) );
609 // common signals connections
610 connect( this, SIGNAL( selected( const QString& ) ),
611 this, SLOT( pageChanged( const QString& ) ) );
612 connect( this, SIGNAL( helpClicked() ), this, SLOT( helpClicked() ) );
613 connect( this, SIGNAL( aboutClicked() ), this, SLOT( onAbout() ) );
615 // catch signals from launched diskSpaceProc
616 connect( diskSpaceProc, SIGNAL( processExited() ), this, SLOT( updateAvailableSpace() ) );
617 // catch signals from launched shellProcess
618 connect(shellProcess, SIGNAL( readyReadStdout() ), this, SLOT( readFromStdout() ) );
619 connect(shellProcess, SIGNAL( readyReadStderr() ), this, SLOT( readFromStderr() ) );
620 connect(shellProcess, SIGNAL( processExited() ), this, SLOT( productInstalled() ) );
621 connect(shellProcess, SIGNAL( wroteToStdin() ), this, SLOT( wroteToStdin() ) );
622 // catch signals from launched modifyLaProc
623 connect(modifyLaProc, SIGNAL( readyReadStdout() ), this, SLOT( readFromStdout() ) );
624 connect(modifyLaProc, SIGNAL( readyReadStderr() ), this, SLOT( readFromStderr() ) );
625 connect(modifyLaProc, SIGNAL( processExited() ), this, SLOT( checkModifyLaResult() ) );
626 // catch signals from launched checkFLibProc
627 connect(checkFLibProc, SIGNAL( processExited() ), this, SLOT( checkFLibResult() ) );
629 // create validation thread
630 myThread = new ProcessThread( this );
633 setAboutIcon( pixmap( pxAbout ) );
634 showAboutBtn( true );
636 // ================================================================
638 * SALOME_InstallWizard::~SALOME_InstallWizard
641 // ================================================================
642 SALOME_InstallWizard::~SALOME_InstallWizard()
644 shellProcess->kill(); // kill it for sure
645 int PID = (int)shellProcess->processIdentifier();
648 script << "kill -9" << QString::number( PID );
650 script << ">& /dev/null";
652 ___MESSAGE___( "script: " << script.script().latin1() );
653 if ( system( script.script().latin1() ) ) {
659 // ================================================================
661 * SALOME_InstallWizard::getBasePlatform
662 * Determine the base platform for binaries installation
664 // ================================================================
665 QString SALOME_InstallWizard::getBasePlatform()
667 QString aBasePlt = "";
668 if ( platformsMap.find( curPlatform ) != platformsMap.end() )
669 aBasePlt = curPlatform;
671 aBasePlt = commonPlatform;
674 // ================================================================
676 * SALOME_InstallWizard::currentPlatform
677 * Tries to determine the current user's operating system
679 // ================================================================
680 QStringList SALOME_InstallWizard::currentPlatform()
683 QString platName, platVersion, platArch;
684 QString osFileName = "/etc/issue";
685 if ( QFile::exists( osFileName ) ) {
686 QFile file( osFileName );
687 if ( file.open( IO_ReadOnly ) ) {
688 QTextStream stream( &file );
689 QStringList lines = QStringList::split( "\n", stream.read() );
691 for ( uint i = 0; i < lines.count(); i++ ) {
692 QString str = lines[i];
693 if ( str.isEmpty() ) continue;
695 QRegExp regvar = QRegExp( "(.*)\\s+[^\\s]*[R|r]elease[^\\s]*\\s+([\\d.]*)" );
696 int pos = regvar.search( str );
698 regvar = QRegExp( "(.*)\\s+[^\\s]*[L|l][I|i][N|n][U|u][X|x][^\\s]*(.*)\\s+([\\d.]*)\\s+" );
699 pos = regvar.search( str );
702 regvar = QRegExp( "([A-Za-z]+)\\s+([0-9.]+)\\s+.*" );
703 pos = regvar.search( str );
707 for ( int i = 1; i < regvar.numCaptures(); i++ )
708 name.append( regvar.cap( i ) );
710 // retrieve platform name
711 platName = QStringList::split( " ", name.join( " " ) ).join( " " );
712 platName = platName.replace( "Linux", "" ).replace( "linux", "" ).replace( "LINUX", "" ).stripWhiteSpace();
713 platName = platName.replace( "Welcome to", "" ).stripWhiteSpace();
714 platName = QStringList::split( " ", platName ).join( " " );
715 // retrieve platform version number
716 platVersion = regvar.cap( regvar.numCaptures() );
719 uname( &uname_data );
720 if ( QString( uname_data.machine ) == "x86_64" )
728 if ( !platName.isEmpty() ) vals.append( platName );
729 if ( !platVersion.isEmpty() ) vals.append( platVersion );
730 if ( !platArch.isEmpty() ) vals.append( platArch );
734 // ================================================================
736 * SALOME_InstallWizard::rootDirPath
737 * Get application root dir
739 // ================================================================
740 QString SALOME_InstallWizard::rootDirPath()
742 static QString rootDir;
743 if ( rootDir.isEmpty() ) {
744 QDir appDir( qApp->applicationDirPath() );
746 rootDir = appDir.absPath();
751 // ================================================================
753 * SALOME_InstallWizard::getPlatformBinPath
754 * Get platform binaries path
756 // ================================================================
757 QString SALOME_InstallWizard::getPlatformBinPath( const QString& plt ) const
759 return QDir::cleanDirPath( getBinPath() + "/" + QStringList::split( " ", plt ).join( "_" ) );
762 // ================================================================
764 * SALOME_InstallWizard::getXmlMap
765 * Creates a map of the supported operating systems and
766 * corresponding XML files.
768 // ================================================================
769 MapXmlFiles SALOME_InstallWizard::getXmlMap( const QString& aXmlFileName )
773 if ( !aXmlFileName.isEmpty() )
774 xmlList.append( QFileInfo( aXmlFileName ).absFilePath() );
776 QDir dir( rootDirPath() );
777 QStringList entries = dir.entryList( "*.xml", QDir::Files | QDir::Readable );
778 if ( entries.remove( "config.xml" ) )
779 entries.append( "config.xml" );
780 for ( uint i = 0; i < entries.count(); i++ )
781 xmlList.append( QDir( rootDirPath() ).filePath( entries[i] ) );
785 QDomDocument doc( "xml_doc" );
787 QDomNodeList nodeList;
790 QString platforms = "";
791 QStringList platList;
792 for ( uint i = 0; i < xmlList.count(); i++ ) {
793 file.setName( xmlList[i] );
794 if ( !doc.setContent( &file ) ) {
800 docElem = doc.documentElement();
801 nodeList = docElem.elementsByTagName( "config" );
802 if ( nodeList.count() == 0 )
804 node = nodeList.item( 0 );
805 if ( node.isElement() ) {
806 elem = node.toElement();
807 if ( elem.attribute( "platforms" ) ) {
808 platforms = elem.attribute( "platforms" ).stripWhiteSpace();
809 QStringList platList = QStringList::split( ",", platforms );
810 for ( uint j = 0; j < platList.count(); j++ ) {
811 QString platform = platList[j].stripWhiteSpace();
812 if ( !platform.isEmpty() && xmlMap.find( platform ) == xmlMap.end() )
813 xmlMap[ platList[j] ] = xmlList[i];
820 // ================================================================
822 * SALOME_InstallWizard::checkXmlAndPlatform
823 * Check XML file and current platform definition
825 // ================================================================
826 void SALOME_InstallWizard::getXmlAndPlatform()
829 if ( xmlFileName.isEmpty() ) {
830 xmlMap = getXmlMap();
831 if ( !curPlatform.isEmpty() ) {
832 // try to get XML file for current platform
833 if ( xmlMap.find( curPlatform ) != xmlMap.end() ) {
834 xmlFileName = xmlMap[ curPlatform ];
835 QFileInfo fibp( getPlatformBinPath( curPlatform ) );
836 if ( !fibp.isDir() ) {
837 warnMsg = tr( "Binaries are absent for current platform" );
839 platformsMap = xmlMap;
842 platformsMap = xmlMap;
843 warnMsg = tr( "Your Linux platform is not supported by this SALOME package" );
847 // get all supported platforms
848 platformsMap = xmlMap;
849 warnMsg = tr( "Installation Wizard can't identify target Linux platform" );
853 xmlMap = getXmlMap( xmlFileName );
854 if ( !curPlatform.isEmpty() ) {
855 // check that the user's XML file supports current platform
856 if ( xmlMap.find( curPlatform ) == xmlMap.end() ) {
857 platformsMap = getXmlMap();
858 MapXmlFiles::Iterator it;
859 for ( it = xmlMap.begin(); it != xmlMap.end(); ++it )
860 platformsMap.insert( it.key(), it.data(), true );
861 warnMsg = tr( "The given configuration file doesn't support your Linux platform" );
864 platformsMap = xmlMap;
868 // get all supported platforms
869 platformsMap = getXmlMap();
870 MapXmlFiles::Iterator it;
871 for ( it = xmlMap.begin(); it != xmlMap.end(); ++it )
872 platformsMap.insert( it.key(), it.data(), true );
873 warnMsg = tr( "Installation Wizard can't define your Linux platform" );
877 // ================================================================
879 * SALOME_InstallWizard::eventFilter
880 * Event filter, spies for Help window closing
882 // ================================================================
883 bool SALOME_InstallWizard::eventFilter( QObject* object, QEvent* event )
885 if ( object && object == helpWindow && event->type() == QEvent::Close )
887 return InstallWizard::eventFilter( object, event );
889 // ================================================================
891 * SALOME_InstallWizard::closeEvent
892 * Close event handler
894 // ================================================================
895 void SALOME_InstallWizard::closeEvent( QCloseEvent* ce )
897 if ( WarnDialog::isWarnDlgShown() ) {
901 if ( !exitConfirmed ) {
902 if ( QMessageBox::information( this,
904 tr( "Do you want to quit %1?" ).arg( getIWName() ),
914 exitConfirmed = true;
919 // ================================================================
921 * SALOME_InstallWizard::setupIntroPage
922 * Creates introduction page
924 // ================================================================
925 void SALOME_InstallWizard::setupIntroPage()
928 introPage = new QWidget( this, "IntroPage" );
929 QGridLayout* pageLayout = new QGridLayout( introPage );
930 pageLayout->setMargin( 0 ); pageLayout->setSpacing( 6 );
931 // create logo picture
932 logoLab = new QLabel( introPage );
933 logoLab->setPixmap( pixmap( pxBigLogo ) );
934 logoLab->setScaledContents( true );
935 logoLab->setFrameStyle( QLabel::Plain | QLabel::NoFrame );
936 logoLab->setAlignment( AlignCenter );
937 // create version box
938 QVBox* versionBox = new QVBox( introPage ); versionBox->setSpacing( 6 );
939 versionBox->setFrameStyle( QVBox::Panel | QVBox::Sunken );
940 QWidget* stretch1 = new QWidget( versionBox ); versionBox->setStretchFactor( stretch1, 5 );
941 versionLab = new QLabel( QString("%1 %2").arg( tr( "Version" ) ).arg(myVersion), versionBox );
942 versionLab->setAlignment( AlignCenter );
943 copyrightLab = new QLabel( myCopyright, versionBox );
944 copyrightLab->setAlignment( AlignCenter );
945 licenseLab = new QLabel( myLicense, versionBox );
946 licenseLab->setAlignment( AlignCenter );
947 QWidget* stretch2 = new QWidget( versionBox ); versionBox->setStretchFactor( stretch2, 5 );
949 info = new QLabel( introPage );
950 info->setText( tr( "This program will install <b>%1</b>."
951 "<br><br>The wizard will also help you to install all products "
952 "which are necessary for <b>%2</b> and setup "
953 "your environment.<br><br>Click <code>Cancel</code> button to abort "
954 "installation and quit. Click <code>Next</code> button to continue with the "
955 "installation program." ).arg( myCaption ).arg( myCaption ) );
956 info->setFrameStyle( QLabel::WinPanel | QLabel::Sunken );
957 info->setMargin( 6 );
958 info->setAlignment( WordBreak );
959 info->setMinimumWidth( 250 );
960 QPalette pal = info->palette();
961 pal.setColor( QColorGroup::Background, QApplication::palette().active().base() );
962 info->setPalette( pal );
963 info->setLineWidth( 2 );
965 pageLayout->addWidget( logoLab, 0, 0 );
966 pageLayout->addWidget( versionBox, 1, 0 );
967 pageLayout->addMultiCellWidget( info, 0, 1, 1, 1 );
968 pageLayout->setColStretch( 1, 5 );
969 pageLayout->setRowStretch( 1, 5 );
971 addPage( introPage, tr( "Introduction" ) );
973 // ================================================================
975 * SALOME_InstallWizard::setupTypePage
976 * Creates installation types page
978 // ================================================================
979 void SALOME_InstallWizard::setupTypePage()
982 typePage = new QWidget( this, "TypePage" );
983 QGridLayout* pageLayout = new QGridLayout( typePage );
984 pageLayout->setMargin( 0 ); pageLayout->setSpacing( 6 );
985 // create installation type button group
986 buttonGrp = new QButtonGroup( typePage );
987 buttonGrp->setFrameShape(QButtonGroup::NoFrame);
988 QGridLayout* buttonGrpLayout = new QGridLayout( buttonGrp );
989 buttonGrpLayout->setMargin( 0 ); buttonGrpLayout->setSpacing( 6 );
990 QSpacerItem* spacer1 = new QSpacerItem( 16, 50, QSizePolicy::Minimum, QSizePolicy::Expanding );
991 QSpacerItem* spacer2 = new QSpacerItem( 16, 50, QSizePolicy::Minimum, QSizePolicy::Expanding );
992 QLabel* selectLab = new QLabel( tr( "Select a type of the installation:" ), buttonGrp );
993 QSpacerItem* spacer3 = new QSpacerItem( 20, 20, QSizePolicy::Fixed, QSizePolicy::Minimum );
994 // ... 'install binaries' layout
995 QGridLayout* binLayout = new QGridLayout( 2, 2, 0 );
996 binBtn = new QRadioButton( tr( "Install binaries" ), buttonGrp );
997 QFont rbFont = binBtn->font();
998 rbFont.setBold( true );
999 binBtn->setFont( rbFont );
1000 QSpacerItem* spacer4 = new QSpacerItem( 16, 16, QSizePolicy::Fixed, QSizePolicy::Minimum );
1001 QLabel* binLab = new QLabel( tr( "- all the binaries and sources of the chosen SALOME modules will be installed.\n"
1002 "- all the binaries of the chosen prerequisites will be installed." ),
1004 binLayout->addMultiCellWidget( binBtn, 0, 0, 0, 1 );
1005 binLayout->addItem ( spacer4, 1, 0 );
1006 binLayout->addWidget ( binLab, 1, 1 );
1007 // ... 'install sources' layout
1008 QGridLayout* srcLayout = new QGridLayout( 2, 2, 0 );
1009 srcBtn = new QRadioButton( tr( "Install sources" ), buttonGrp );
1010 srcBtn->setFont( rbFont );
1011 QSpacerItem* spacer5 = new QSpacerItem( 16, 16, QSizePolicy::Fixed, QSizePolicy::Minimum );
1012 QLabel* srcLab = new QLabel( tr( "- all the sources of the chosen modules and prerequisites will be installed without\ncompilation." ),
1014 srcLayout->addMultiCellWidget( srcBtn, 0, 0, 0, 1 );
1015 srcLayout->addItem ( spacer5, 1, 0 );
1016 srcLayout->addWidget ( srcLab, 1, 1 );
1017 // ... 'install sources and make compilation' layout
1018 QGridLayout* srcCompileLayout = new QGridLayout( 3, 3, 0 );
1019 srcCompileBtn = new QRadioButton( tr( "Install sources and make a compilation" ), buttonGrp );
1020 srcCompileBtn->setFont( rbFont );
1021 QSpacerItem* spacer6 = new QSpacerItem( 16, 16, QSizePolicy::Fixed, QSizePolicy::Minimum );
1022 QLabel* srcCompileLab1 = new QLabel( tr( "- all the sources of the chosen modules and prerequisites will be installed and\ncompiled." ),
1024 QLabel* srcCompileLab2 = new QLabel( tr( "Note:" ),
1026 QFont noteFont = srcCompileLab2->font();
1027 noteFont.setUnderline( true );
1028 srcCompileLab2->setFont( noteFont );
1029 srcCompileLab2->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Preferred ) );
1030 srcCompileLab2->setAlignment( Qt::AlignHCenter | Qt::AlignTop );
1031 QLabel* srcCompileLab3 = new QLabel( " " +
1032 tr( "it is a long time operation and it can take more than 24 hours depending\n on the computer." ),
1034 removeSrcBtn = new QCheckBox( tr( "Remove sources and temporary files after compilation" ), typePage );
1035 setAboutInfo( removeSrcBtn, tr( "Check this option if you want to remove sources of the products\nwith all the temporary files after build finishing" ) );
1036 removeSrcBtn->setChecked( false );
1037 removeSrcBtn->setEnabled( false );
1038 rmSrcPrevState = removeSrcBtn->isChecked();
1040 srcCompileLayout->addMultiCellWidget( srcCompileBtn, 0, 0, 0, 2 );
1041 srcCompileLayout->addMultiCell ( spacer6, 1, 2, 0, 0 );
1042 srcCompileLayout->addMultiCellWidget( srcCompileLab1, 1, 1, 1, 2 );
1043 srcCompileLayout->addWidget ( srcCompileLab2, 2, 1 );
1044 srcCompileLayout->addWidget ( srcCompileLab3, 2, 2 );
1045 srcCompileLayout->addMultiCellWidget( removeSrcBtn, 3, 3, 1, 2 );
1046 // layout widgets in the button group
1047 buttonGrpLayout->addItem ( spacer1, 0, 1 );
1048 buttonGrpLayout->addMultiCellWidget( selectLab, 1, 1, 0, 1 );
1049 buttonGrpLayout->addMultiCell ( spacer3, 2, 4, 0, 0 );
1050 buttonGrpLayout->addLayout ( binLayout, 2, 1 );
1051 buttonGrpLayout->addLayout ( srcLayout, 3, 1 );
1052 buttonGrpLayout->addLayout ( srcCompileLayout, 4, 1 );
1053 buttonGrpLayout->addItem ( spacer2, 5, 1 );
1054 // layout button group at the page
1055 pageLayout->addWidget( buttonGrp, 0, 0 );
1056 // connecting signals
1057 connect( buttonGrp, SIGNAL( clicked(int) ), this, SLOT ( onButtonGroup(int) ) );
1059 addPage( typePage, tr( "Installation type" ) );
1061 // ================================================================
1063 * SALOME_InstallWizard::setupPlatformPage
1064 * Creates platforms page, if necessary
1066 // ================================================================
1067 void SALOME_InstallWizard::setupPlatformPage()
1070 platformsPage = new QWidget( this, "PlatformsPage" );
1071 QGridLayout* pageLayout = new QGridLayout( platformsPage );
1072 pageLayout->setMargin( 0 ); pageLayout->setSpacing( 6 );
1073 // create warning labels
1074 QLabel* warnLab2 = new QLabel( tr( "WARNING!" ), platformsPage );
1075 warnLab2->setAlignment( Qt::AlignHCenter );
1076 QFont fnt = warnLab2->font();
1077 fnt.setBold( true );
1078 warnLab2->setFont( fnt );
1079 warnLab = new QLabel( warnMsg, platformsPage );
1080 warnLab->setAlignment( Qt::AlignHCenter | Qt::WordBreak );
1081 warnLab3 = new QLabel( tr( "If you want to proceed anyway, please select platform from the following list:" ),
1083 warnLab3->setAlignment( Qt::AlignHCenter | Qt::WordBreak );
1084 // create button group
1085 platBtnGrp = new QButtonGroup( platformsPage );
1086 platBtnGrp->setFrameShape(QButtonGroup::LineEditPanel);
1087 platBtnGrp->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Preferred ) );
1088 QVBoxLayout* platBtnGrpLayout = new QVBoxLayout( platBtnGrp );
1089 platBtnGrpLayout->setMargin( 11 ); platBtnGrpLayout->setSpacing( 6 );
1090 // create platforms radio-buttons
1092 MapXmlFiles::Iterator it;
1093 for ( it = platformsMap.begin(); it != platformsMap.end(); ++it ) {
1095 QRadioButton* rb = new QRadioButton( plat, platBtnGrp, plat );
1096 platBtnGrpLayout->addWidget( rb );
1099 QSpacerItem* spacer1 = new QSpacerItem( 16, 20, QSizePolicy::Minimum, QSizePolicy::Expanding );
1100 QSpacerItem* spacer2 = new QSpacerItem( 16, 20, QSizePolicy::Minimum, QSizePolicy::Expanding );
1102 // layout widgets on page
1103 pageLayout->addItem ( spacer1, 0, 0 );
1104 pageLayout->addWidget ( warnLab2, 1, 0 );
1105 pageLayout->addWidget ( warnLab, 2, 0 );
1106 pageLayout->addWidget ( warnLab3, 3, 0 );
1107 pageLayout->addItem ( spacer2, 4, 0 );
1108 pageLayout->addMultiCellWidget( platBtnGrp, 0, 4, 1, 1 );
1110 // connecting signals
1111 connect( platBtnGrp, SIGNAL( clicked(int) ), this, SLOT ( onButtonGroup(int) ) );
1114 addPage( platformsPage, tr( "Installation platform" ) );
1116 // ================================================================
1118 * SALOME_InstallWizard::setupDirPage
1119 * Creates directories page
1121 // ================================================================
1122 void SALOME_InstallWizard::setupDirPage()
1125 dirPage = new QWidget( this, "DirPage" );
1126 QGridLayout* pageLayout = new QGridLayout( dirPage );
1127 pageLayout->setMargin( 0 ); pageLayout->setSpacing( 6 );
1128 QSpacerItem* spacer1 = new QSpacerItem( 16, 50, QSizePolicy::Minimum, QSizePolicy::Expanding );
1129 QSpacerItem* spacer2 = new QSpacerItem( 16, 50, QSizePolicy::Minimum, QSizePolicy::Expanding );
1131 QGridLayout* targetLayout = new QGridLayout( 2, 2, 0 );
1132 QLabel* targetLab = new QLabel( tr( "Set a target directory to install SALOME platform:" ), dirPage );
1133 targetFolder = new QLineEdit( dirPage );
1134 targetBtn = new QPushButton( tr( "Browse..." ), dirPage );
1135 setAboutInfo( targetBtn, tr( "Click this button to browse\nthe installation directory" ) );
1136 targetLayout->addMultiCellWidget( targetLab, 0, 0, 0, 1 );
1137 targetLayout->addWidget ( targetFolder, 1, 0 );
1138 targetLayout->addWidget ( targetBtn, 1, 1 );
1139 // temporary directory
1140 QGridLayout* tempLayout = new QGridLayout( 2, 2, 0 );
1141 QLabel* tempLab = new QLabel( tr( "Set a directory that should be used for temporary SALOME files:" ), dirPage );
1142 tempFolder = new QLineEdit( dirPage );
1143 tempBtn = new QPushButton( tr( "Browse..." ), dirPage );
1144 setAboutInfo( tempBtn, tr( "Click this button to browse\nthe temporary directory" ) );
1145 tempLayout->addMultiCellWidget( tempLab, 0, 0, 0, 1 );
1146 tempLayout->addWidget ( tempFolder, 1, 0 );
1147 tempLayout->addWidget ( tempBtn, 1, 1 );
1148 // AKL: 13/08/07 - disable temporary directory setting in GUI ==>
1152 // AKL: 13/08/07 - disable temporary directory setting in GUI <==
1154 pageLayout->addItem ( spacer1, 0, 0 );
1155 pageLayout->addLayout( targetLayout, 1, 0 );
1156 pageLayout->addLayout( tempLayout, 2, 0 );
1157 pageLayout->addItem ( spacer2, 3, 0 );
1158 // connecting signals
1159 connect( targetFolder, SIGNAL( textChanged( const QString& ) ),
1160 this, SLOT( directoryChanged( const QString& ) ) );
1161 connect( targetBtn, SIGNAL( clicked() ),
1162 this, SLOT( browseDirectory() ) );
1163 connect( tempFolder, SIGNAL( textChanged( const QString& ) ),
1164 this, SLOT( directoryChanged( const QString& ) ) );
1165 connect( tempBtn, SIGNAL( clicked() ), this, SLOT( browseDirectory() ) );
1168 addPage( dirPage, tr( "Installation directory" ) );
1170 // ================================================================
1172 * SALOME_InstallWizard::setupProductsPage
1173 * Creates products page
1175 // ================================================================
1176 void SALOME_InstallWizard::setupProductsPage()
1179 productsPage = new QWidget( this, "ProductsPage" );
1180 QGridLayout* pageLayout = new QGridLayout( productsPage );
1181 pageLayout->setMargin( 0 ); pageLayout->setSpacing( 6 );
1183 // create left column widgets
1185 QVBoxLayout* leftBoxLayout = new QVBoxLayout;
1186 leftBoxLayout->setMargin( 0 ); leftBoxLayout->setSpacing( 6 );
1188 modulesView = new ProductsView( productsPage, "modulesView" );
1189 setAboutInfo( modulesView, tr( "The modules available for the installation" ) );
1190 modulesView->setColumnAlignment( 1, Qt::AlignRight );
1191 leftBoxLayout->addWidget( modulesView );
1192 // ... 'Installation with GUI' checkbox
1193 installGuiBtn = new QMyCheckBox( tr( "Installation with GUI" ), productsPage );
1194 setAboutInfo( installGuiBtn, tr( "Check this option if you want\nto install SALOME with GUI" ) );
1195 leftBoxLayout->addWidget( installGuiBtn );
1196 // ... prerequisites list
1197 prereqsView = new ProductsView( productsPage, "prereqsView" );
1198 prereqsView->renameColumn( 0, "Prerequisite" );
1199 setAboutInfo( prereqsView, tr( "The prerequisites that can be installed" ) );
1200 prereqsView->setColumnAlignment( 1, Qt::AlignRight );
1201 leftBoxLayout->addWidget( prereqsView );
1202 // ... 'Show/Hide prerequisites' button
1203 moreBtn = new QPushButton( tr( "Show prerequisites..." ), productsPage );
1204 setAboutInfo( moreBtn, tr( "Click to show list of prerequisites" ) );
1205 leftBoxLayout->addWidget( moreBtn );
1207 // create right column widgets
1210 productInfo = new QTextBrowser( productsPage );
1211 productInfo->setFrameShape( QFrame::LineEditPanel );
1212 productInfo->setPaletteBackgroundColor( productsPage->paletteBackgroundColor() );
1213 setAboutInfo( productInfo, tr( "Short information about the product being selected" ) );
1214 // ... disk space labels
1215 QLabel* reqLab1 = new QLabel( tr( "Disk space required:" ), productsPage );
1216 setAboutInfo( reqLab1, tr( "Total disk space required for the installation\nof the selected products" ) );
1217 requiredSize = new QLabel( productsPage );
1218 setAboutInfo( requiredSize, tr( "Total disk space required for the installation\nof the selected products" ) );
1219 requiredSize->setAlignment( Qt::AlignRight );
1220 QLabel* reqLab2 = new QLabel( tr( "Space for temporary files:" ), productsPage );
1221 setAboutInfo( reqLab2, tr( "Disk space required for the temporary files" ) );
1222 requiredTemp = new QLabel( productsPage );
1223 setAboutInfo( requiredTemp, tr( "Disk space required for the temporary files" ) );
1224 requiredTemp->setAlignment( Qt::AlignRight );
1225 QLabel* reqLab3 = new QLabel( tr( "Available disk space:" ), productsPage );
1226 setAboutInfo( reqLab3, tr( "Disk space available on the selected device" ) );
1227 availableSize = new QLabel( productsPage );
1228 setAboutInfo( availableSize, tr( "Disk space available on the selected device" ) );
1229 availableSize->setAlignment( Qt::AlignRight );
1230 // layout size widgets
1231 QGridLayout* sizeLayout = new QGridLayout; sizeLayout->setMargin( 0 ); sizeLayout->setSpacing( 6 );
1232 sizeLayout->addWidget( reqLab1, 0, 0 );
1233 sizeLayout->addWidget( requiredSize, 0, 1 );
1234 sizeLayout->addWidget( reqLab2, 1, 0 );
1235 sizeLayout->addWidget( requiredTemp, 1, 1 );
1236 sizeLayout->addWidget( reqLab3, 2, 0 );
1237 sizeLayout->addWidget( availableSize, 2, 1 );
1238 // ... 'single installation directory' check-boxes
1239 oneModDirBtn = new QMyCheckBox( tr( "Install modules to a single directory" ), productsPage );
1240 setAboutInfo( oneModDirBtn, tr( "Check this box if you want to install binaries of\nthe selected SALOME modules into a single directory" ) );
1241 oneProdDirBtn = new QMyCheckBox( tr( "Install prerequisites to a single directory" ), productsPage );
1242 setAboutInfo( oneProdDirBtn, tr( "Check this box if you want to install binaries of\nthe selected prerequisites into a single directory" ) );
1243 oneProdDirBtn->hide(); // temporarily! waiting for correct prerequisites availability
1244 QFrame* split_line = new QFrame( productsPage, "split_line" );
1245 split_line->setFrameStyle( QFrame::HLine | QFrame::Sunken );
1247 // layout common widgets
1248 pageLayout->addMultiCellLayout( leftBoxLayout, 0, 4, 0, 0 );
1249 pageLayout->addWidget ( productInfo, 0, 1 );
1250 pageLayout->addLayout ( sizeLayout, 1, 1 );
1251 pageLayout->addWidget ( split_line, 2, 1 );
1252 pageLayout->addWidget ( oneModDirBtn, 3, 1 );
1253 pageLayout->addWidget ( oneProdDirBtn, 4, 1 );
1256 addPage( productsPage, tr( "Choice of the products to be installed" ) );
1258 // connecting signals
1259 connect( modulesView, SIGNAL( selectionChanged() ),
1260 this, SLOT( onSelectionChanged() ) );
1261 connect( prereqsView, SIGNAL( selectionChanged() ),
1262 this, SLOT( onSelectionChanged() ) );
1263 connect( modulesView, SIGNAL( clicked ( QListViewItem * item ) ),
1264 this, SLOT( onSelectionChanged() ) );
1265 connect( prereqsView, SIGNAL( clicked ( QListViewItem * item ) ),
1266 this, SLOT( onSelectionChanged() ) );
1267 connect( modulesView, SIGNAL( itemToggled( QCheckListItem* ) ),
1268 this, SLOT( onItemToggled( QCheckListItem* ) ) );
1269 connect( prereqsView, SIGNAL( itemToggled( QCheckListItem* ) ),
1270 this, SLOT( onItemToggled( QCheckListItem* ) ) );
1271 connect( installGuiBtn, SIGNAL( toggled( bool ) ),
1272 this, SLOT( onInstallGuiBtn() ) );
1273 connect( moreBtn, SIGNAL( clicked() ), this, SLOT( onMoreBtn() ) );
1274 // start on default - non-advanced mode
1275 prereqsView->hide();
1277 // ================================================================
1279 * SALOME_InstallWizard::setupCheckPage
1280 * Creates prestart page
1282 // ================================================================
1283 void SALOME_InstallWizard::setupCheckPage()
1286 prestartPage = new QWidget( this, "PrestartPage" );
1287 QVBoxLayout* pageLayout = new QVBoxLayout( prestartPage );
1288 pageLayout->setMargin( 0 ); pageLayout->setSpacing( 6 );
1290 choices = new QTextEdit( prestartPage );
1291 choices->setReadOnly( true );
1292 choices->setTextFormat( RichText );
1293 choices->setUndoRedoEnabled ( false );
1294 setAboutInfo( choices, tr( "Information about the installation choice you have made" ) );
1295 choices->setPaletteBackgroundColor( prestartPage->paletteBackgroundColor() );
1296 choices->setMinimumHeight( 10 );
1298 pageLayout->addWidget( choices );
1299 pageLayout->setStretchFactor( choices, 5 );
1301 addPage( prestartPage, tr( "Check your choice" ) );
1303 // ================================================================
1305 * SALOME_InstallWizard::setupProgressPage
1306 * Creates progress page
1308 // ================================================================
1309 void SALOME_InstallWizard::setupProgressPage()
1312 progressPage = new QWidget( this, "progressPage" );
1313 QGridLayout* pageLayout = new QGridLayout( progressPage );
1314 pageLayout->setMargin( 0 ); pageLayout->setSpacing( 6 );
1316 splitter = new QSplitter( Vertical, progressPage );
1317 splitter->setOpaqueResize( true );
1318 // the parent for the widgets
1319 QWidget* widget = new QWidget( splitter );
1320 QGridLayout* layout = new QGridLayout( widget );
1321 layout->setMargin( 0 ); layout->setSpacing( 6 );
1322 // installation progress view box
1323 installInfo = new InstallInfo( widget );
1324 installInfo->setReadOnly( true );
1325 installInfo->setTextFormat( RichText );
1326 installInfo->setUndoRedoEnabled ( false );
1327 installInfo->setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Expanding ) );
1328 installInfo->setMinimumSize( 100, 10 );
1329 setAboutInfo( installInfo, tr( "Installation process output" ) );
1330 // parameters for the script
1331 parametersLab = new QLabel( tr( "Enter your answer here:" ), widget );
1332 passedParams = new QLineEdit ( widget );
1333 setAboutInfo( passedParams, tr( "Use this field to enter the answer\nfor the running script when it is necessary") );
1334 // VSR: 10/11/05 - disable answer mode ==>
1335 parametersLab->hide();
1336 passedParams->hide();
1337 // VSR: 10/11/05 - disable answer mode <==
1339 layout->addWidget( installInfo, 0, 0 );
1340 layout->addWidget( parametersLab, 1, 0 );
1341 layout->addWidget( passedParams, 2, 0 );
1342 layout->addRowSpacing( 3, 6 );
1343 // the parent for the widgets
1344 widget = new QWidget( splitter );
1345 layout = new QGridLayout( widget );
1346 layout->setMargin( 0 ); layout->setSpacing( 6 );
1347 // installation results view box
1348 QLabel* resultLab = new QLabel( tr( "Installation Status:" ), widget );
1349 progressView = new ProgressView( widget );
1350 progressView->setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Expanding ) );
1351 progressView->setMinimumSize( 100, 10 );
1352 // possibility to ignore all errors
1353 ignoreErrCBox = new QCheckBox( tr( "Ignore errors" ), widget );
1354 setAboutInfo( ignoreErrCBox, tr( "Check this option if you want to proceed installation \nprocess even there will be some errors" ) );
1355 ignoreErrCBox->setChecked( false );
1356 // product installation status bar
1357 statusLab = new QLabel( widget );
1358 statusLab->setFrameShape( QButtonGroup::LineEditPanel );
1359 setAboutInfo( progressView, tr( "Installation status on the selected products" ) );
1361 layout->addRowSpacing( 0, 6 );
1362 layout->addWidget( resultLab, 1, 0 );
1363 layout->addWidget( progressView, 2, 0 );
1364 layout->addWidget( ignoreErrCBox, 3, 0 );
1365 layout->addWidget( statusLab, 4, 0 );
1367 pageLayout->addWidget( splitter, 0, 0 );
1369 addPage( progressPage, tr( "Installation progress" ) );
1371 connect( passedParams, SIGNAL( returnPressed() ), this, SLOT( onReturnPressed() ) ) ;
1373 // ================================================================
1375 * SALOME_InstallWizard::setupReadmePage
1376 * Creates readme page
1378 // ================================================================
1379 void SALOME_InstallWizard::setupReadmePage()
1382 readmePage = new QWidget( this, "readmePage" );
1383 QVBoxLayout* pageLayout = new QVBoxLayout( readmePage );
1384 pageLayout->setMargin( 0 ); pageLayout->setSpacing( 6 );
1385 // README info text box
1386 readme = new QTextEdit( readmePage );
1387 readme->setReadOnly( true );
1388 readme->setTextFormat( PlainText );
1389 readme->setFont( QFont( "Fixed", 12 ) );
1390 readme->setUndoRedoEnabled ( false );
1391 setAboutInfo( readme, tr( "README information" ) );
1392 readme->setPaletteBackgroundColor( readmePage->paletteBackgroundColor() );
1393 readme->setMinimumHeight( 10 );
1395 pageLayout->addWidget( readme );
1396 pageLayout->setStretchFactor( readme, 5 );
1398 // Operation buttons
1399 QHBoxLayout* hLayout = new QHBoxLayout( -1, "finishButtons" );
1400 hLayout->setMargin( 0 ); hLayout->setSpacing( 6 );
1401 hLayout->addStretch();
1402 pageLayout->addLayout( hLayout );
1404 // loading README file
1405 QString readmeFile = QDir( rootDirPath() ).filePath( "README" );
1407 if ( readFile( readmeFile, text ) )
1408 readme->setText( text );
1410 readme->setText( tr( "README file has not been found" ) );
1413 addPage( readmePage, tr( "Finish installation" ) );
1415 // ================================================================
1417 * SALOME_InstallWizard::showChoiceInfo
1418 * Displays choice info
1420 // ================================================================
1421 void SALOME_InstallWizard::showChoiceInfo()
1425 long totSize, tempSize;
1426 checkSize( &totSize, &tempSize );
1430 text += tr( "Current Linux platform" )+ ": <b>" + (!curPlatform.isEmpty() ? curPlatform : QString( "Unknown" )) + "</b><br>";
1431 if ( !refPlatform.isEmpty() )
1432 text += tr( "Reference Linux platform" ) + ": <b>" + refPlatform + "</b><br>";
1435 text += tr( "Target directory:" ) + " <b>" + QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() ) + "</b><br>";
1436 text += tr( "Temporary directory:" ) + " <b>" + QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + "</b><br>";
1439 text += tr( "SALOME modules to be installed" ) + ":<ul>";
1440 QCheckListItem* item = (QCheckListItem*)( modulesView->firstChild() );
1442 if ( productsMap.contains( item ) ) {
1443 if ( item->isOn() ) {
1444 text += "<li><b>" + item->text() + "</b><br>";
1448 item = (QCheckListItem*)( item->nextSibling() );
1450 if ( nbProd == 0 ) {
1451 text += "<li><b>" + tr( "none" ) + "</b><br>";
1455 text += tr( "Prerequisites to be installed" ) + ":<ul>";
1456 item = (QCheckListItem*)( prereqsView->firstChild() );
1458 if ( productsMap.contains( item ) ) {
1459 if ( item->isOn() ) {
1460 text += "<li><b>" + item->text() + " " + productsMap[ item ].getVersion() + "</b><br>";
1464 item = (QCheckListItem*)( item->nextSibling() );
1466 if ( nbProd == 0 ) {
1467 text += "<li><b>" + tr( "none" ) + "</b><br>";
1470 text += tr( "Total disk space required:" ) + " <b>" + QString::number( totSize ) + " KB</b><br>" ;
1471 text += tr( "Space for temporary files required:" ) + " <b>" + QString::number( tempSize ) + " KB</b><br>" ;
1472 choices->setText( text );
1474 // ================================================================
1476 * SALOME_InstallWizard::acceptData
1477 * Validates page when <Next> button is clicked
1479 // ================================================================
1480 bool SALOME_InstallWizard::acceptData( const QString& pageTitle )
1483 QWidget* aPage = InstallWizard::page( pageTitle );
1484 if ( aPage == typePage ) {
1485 // installation type page
1487 this->setAppropriate( platformsPage, false );
1488 if ( installType == Binaries ) { // 'Binary' installation type
1489 // check binaries directory
1490 QFileInfo fib( QDir::cleanDirPath( getBinPath() ) );
1491 if ( !fib.isDir() ) {
1492 QMessageBox::warning( this,
1494 tr( "The directory %1 doesn't exist.\n"
1495 "This directory must contains another one directory with binary archives for current platform.").arg( fib.absFilePath() ),
1497 QMessageBox::NoButton,
1498 QMessageBox::NoButton );
1501 if ( platformsMap.find( curPlatform ) == platformsMap.end() ) {
1502 // Unknown platform case
1503 QString aMsg = warnMsg + tr( ".\nBy default the universal binary package will be installed." );
1504 aMsg += tr( "\nIf you want to select another one, please use the following list:" );
1505 warnLab->setText( aMsg );
1507 this->setAppropriate( platformsPage, true );
1510 // Supported platform case
1511 QFileInfo fibp( getPlatformBinPath( curPlatform ) );
1512 if ( !fibp.isDir() ) {
1513 warnLab->setText( tr( "Binaries are absent for current platform." ) );
1514 this->setAppropriate( platformsPage, true );
1518 // check sources directory
1519 QFileInfo fis( QDir::cleanDirPath( getSrcPath() ) );
1521 if ( QMessageBox::warning( this,
1523 tr( "The directory %1 doesn't exist.\n"
1524 "This directory must contains sources archives.\n"
1525 "Continue?" ).arg( fis.absFilePath() ),
1528 QString::null, 1, 1 ) == 1 )
1531 else { // 'Source' or 'Compile' installation type
1532 // check sources directory
1533 QFileInfo fis( QDir::cleanDirPath( getSrcPath() ) );
1534 if ( !fis.isDir() ) {
1535 QMessageBox::warning( this,
1537 tr( "The directory %1 doesn't exist.\n"
1538 "This directory must contains sources archives.\n" ).arg( fis.absFilePath() ),
1540 QMessageBox::NoButton,
1541 QMessageBox::NoButton );
1544 else if ( !QDir( fis.filePath(), "*.tar.gz" ).count() ) {
1545 QMessageBox::warning( this,
1547 tr( "The directory %1 doesn't contain source archives.\n" ).arg( fis.absFilePath() ),
1549 QMessageBox::NoButton,
1550 QMessageBox::NoButton );
1553 if ( platformsMap.find( curPlatform ) == platformsMap.end() ) {
1554 QString aMsg = warnMsg + ".";
1555 if ( installType == Compile )
1556 aMsg = warnMsg + tr( " and compilation is not tested on this one." );
1557 warnLab->setText( aMsg );
1558 this->setAppropriate( platformsPage, true );
1563 else if ( aPage == platformsPage ) {
1564 // installation platform page
1565 if ( platBtnGrp->id( platBtnGrp->selected() ) == -1 ) {
1566 QMessageBox::warning( this,
1568 tr( "Select installation platform before" ),
1570 QMessageBox::NoButton,
1571 QMessageBox::NoButton );
1574 else if ( installType == Binaries ) {
1575 QString aPlatform = platBtnGrp->selected()->name();
1576 QFileInfo fib( getPlatformBinPath( aPlatform ) );
1577 if ( !fib.isDir() ) {
1578 QMessageBox::warning( this,
1580 tr( "The directory %1 doesn't exist.\n"
1581 "This directory must contains binary archives.\n" ).arg( fib.absFilePath() ),
1583 QMessageBox::NoButton,
1584 QMessageBox::NoButton );
1587 else if ( QDir( fib.filePath(), "*.tar.gz" ).count() == 0 ) {
1588 QMessageBox::warning( this,
1590 tr( "The directory %1 doesn't contain binary archives.\n" ).arg( fib.absFilePath() ),
1592 QMessageBox::NoButton,
1593 QMessageBox::NoButton );
1599 else if ( aPage == dirPage ) {
1600 // installation directory page
1601 // ########## check target and temp directories (existence and available disk space)
1603 QString targetDir = QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() );
1604 QString tempDir = QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() );
1605 // check target directory
1606 if ( targetDir.isEmpty() ) {
1607 QMessageBox::warning( this,
1609 tr( "Please, enter valid target directory path" ),
1611 QMessageBox::NoButton,
1612 QMessageBox::NoButton );
1615 QFileInfo fi( QDir::cleanDirPath( targetDir ) );
1616 if ( !fi.isDir() ) {
1618 QMessageBox::warning( this,
1620 tr( "The directory %1 doesn't exist.\n"
1621 "Create directory?" ).arg( fi.absFilePath() ),
1624 QMessageBox::NoButton ) == QMessageBox::Yes;
1627 if ( !makeDir( fi.absFilePath(), tmpstr ) ) {
1628 QMessageBox::critical( this,
1630 tr( "Can't create the directory\n%1").arg( fi.absFilePath() ),
1632 QMessageBox::NoButton,
1633 QMessageBox::NoButton );
1637 if ( !fi.isDir() ) {
1638 QMessageBox::warning( this,
1640 tr( "%1 is not a directory.\n"
1641 "Please, enter valid target directory path" ).arg( fi.absFilePath() ),
1643 QMessageBox::NoButton,
1644 QMessageBox::NoButton );
1647 if ( !fi.isWritable() ) {
1648 QMessageBox::warning( this,
1650 tr( "The directory %1 is not writable.\n"
1651 "Please, enter valid target directory path or change permissions" ).arg( fi.absFilePath() ),
1653 QMessageBox::NoButton,
1654 QMessageBox::NoButton );
1657 if ( hasSpace( fi.absFilePath() ) &&
1658 QMessageBox::warning( this,
1660 tr( "The target directory contains space symbols.\n"
1661 "This may cause problems with compiling or installing of products.\n\n"
1662 "Do you want to continue?"),
1665 QMessageBox::NoButton ) == QMessageBox::No ) {
1668 // check temp directory
1669 if ( tempDir.isEmpty() ) {
1670 QMessageBox::warning( this,
1672 tr( "Please, enter valid temporary directory path" ),
1674 QMessageBox::NoButton,
1675 QMessageBox::NoButton );
1678 QFileInfo fit( QDir::cleanDirPath( tempDir ) );
1679 if ( !makeDir( fit.absFilePath() + TEMPDIRNAME, tmpCreated ) ) {
1680 QMessageBox::critical( this,
1682 tr( "Can't use temporary directory.\nCheck permissions for the %1 directory.").arg( fit.absFilePath() ),
1684 QMessageBox::NoButton,
1685 QMessageBox::NoButton );
1690 else if ( aPage == productsPage ) {
1692 // ########## check if any products are selected to be installed
1693 long totSize, tempSize;
1694 bool anySelected = checkSize( &totSize, &tempSize );
1695 if ( installType == Compile && removeSrcBtn->isOn() ) {
1696 totSize += tempSize;
1698 if ( !anySelected ) {
1699 QMessageBox::warning( this,
1701 tr( "Select one or more products to install" ),
1703 QMessageBox::NoButton,
1704 QMessageBox::NoButton );
1707 // run script that checks available disk space for installing of products // returns 1 in case of error
1708 QDir rd( rootDirPath() );
1709 QFileInfo fi( QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() ) );
1711 script << QUOTE( rd.filePath( "config_files/checkSize.sh" ) );
1712 script << QUOTE( fi.absFilePath() ) << QString::number( totSize );
1713 ___MESSAGE___( "script = " << script.script().latin1() );
1714 if ( system( script.script().latin1() ) ) {
1715 QMessageBox::critical( this,
1716 tr( "Out of space" ),
1717 tr( "There is no available disk space for installing of selected products" ),
1719 QMessageBox::NoButton,
1720 QMessageBox::NoButton );
1723 // AKL: 13/08/07 - skip tmp disk space checking (all files are unpacked into installation directory) ==>
1725 // run script that check available disk space for temporary files
1726 // returns 1 in case of error
1727 QFileInfo fit( QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) );
1729 tscript << QUOTE( rd.filePath( "config_files/checkSize.sh" ) );
1730 tscript << QUOTE( fit.absFilePath() ) << QString::number( tempSize );
1731 ___MESSAGE___( "script = " << tscript.script().latin1() );
1732 if ( system( tscript.script().latin1() ) ) {
1733 QMessageBox::critical( this,
1734 tr( "Out of space" ),
1735 tr( "There is no available disk space for the temporary files" ),
1737 QMessageBox::NoButton,
1738 QMessageBox::NoButton );
1742 // AKL: 13/08/07 - skip tmp disk space checking (all files are unpacked into installation directory) <==
1744 // ########## check installation scripts
1745 QCheckListItem* item;
1746 ProductsView* prodsView = modulesView;
1747 for ( int i = 0; i < 2; i++ ) {
1748 item = (QCheckListItem*)( prodsView->firstChild() );
1750 if ( productsMap.contains( item ) && item->isOn() ) {
1751 // check installation script definition
1752 if ( item->text(2).isEmpty() || item->text(2).isNull() ) {
1753 QMessageBox::warning( this,
1755 tr( "The installation script for %1 is not defined.").arg(item->text(0)),
1757 QMessageBox::NoButton,
1758 QMessageBox::NoButton );
1759 if ( !moreMode ) onMoreBtn();
1760 QListView* listView = item->listView();
1761 listView->setCurrentItem( item );
1762 listView->setSelected( item, true );
1763 listView->ensureItemVisible( item );
1766 // check installation script existence
1768 QDir rd( rootDirPath() );
1769 QFileInfo fi( rd.filePath( QString( "config_files/%1" ).arg( item->text(2) ) ) );
1770 if ( !fi.exists() || !fi.isExecutable() ) {
1771 QMessageBox::warning( this,
1773 tr( "The script %1 required for %2 doesn't exist or doesn't have execute permissions.").arg(fi.filePath()).arg(item->text(0)),
1775 QMessageBox::NoButton,
1776 QMessageBox::NoButton );
1777 if ( !moreMode ) onMoreBtn();
1778 QListView* listView = item->listView();
1779 listView->setCurrentItem( item );
1780 listView->setSelected( item, true );
1781 listView->ensureItemVisible( item );
1785 // check installation scripts dependencies
1786 QStringList dependOn = productsMap[ item ].getDependancies();
1787 QString version = productsMap[ item ].getVersion();
1788 for ( int i = 0; i < (int)dependOn.count(); i++ ) {
1789 QCheckListItem* depitem = findItem( dependOn[ i ] );
1791 QMessageBox::warning( this,
1793 tr( "%1 is required for %2 %3 installation.\n"
1794 "This product is missing in the configuration file %4.").arg(dependOn[ i ]).arg(item->text(0)).arg(version).arg(xmlFileName),
1796 QMessageBox::NoButton,
1797 QMessageBox::NoButton );
1802 item = (QCheckListItem*)( item->nextSibling() );
1804 prodsView = prereqsView;
1806 // return true; // return in order to avoid default postValidateEvent() action
1808 return InstallWizard::acceptData( pageTitle );
1810 // ================================================================
1812 * SALOME_InstallWizard::checkSize
1813 * Calculates disk space required for the installation
1815 // ================================================================
1816 bool SALOME_InstallWizard::checkSize( long* totSize, long* tempSize )
1818 long tots = 0, temps = 0;
1822 MapProducts::Iterator mapIter;
1823 for ( mapIter = productsMap.begin(); mapIter != productsMap.end(); ++mapIter ) {
1824 QCheckListItem* item = mapIter.key();
1825 Dependancies dep = mapIter.data();
1826 if ( !item->isOn() )
1828 tots += ( QStringList::split( " ", item->text(1) )[0] ).toLong();
1829 maxSrcTmp = max( maxSrcTmp, dep.getSize( Compile ) - dep.getSize( Binaries ) );
1830 temps += dep.getTempSize( installType );
1835 if ( installType == Compile && removeSrcBtn->isOn() )
1840 return ( nbSelected > 0 );
1842 // ================================================================
1844 * SALOME_InstallWizard::updateAvailableSpace
1845 * Slot to update 'Available disk space' field
1847 // ================================================================
1848 void SALOME_InstallWizard::updateAvailableSpace()
1850 if ( diskSpaceProc->normalExit() )
1851 availableSize->setText( diskSpaceProc->readLineStdout() + " KB");
1853 // ================================================================
1855 * SALOME_InstallWizard::runModifyLaFiles
1856 * Run the modification of SALOME *.la files
1858 // ================================================================
1859 void SALOME_InstallWizard::runModifyLaFiles()
1861 modifyLaProc->clearArguments();
1862 // ... update status label
1863 statusLab->setText( tr( "Modification of *.la files of SALOME modules..." ) );
1864 // set process arguments
1865 modifyLaProc->setWorkingDirectory( QDir( rootDirPath() ).filePath( "config_files" ) );
1866 modifyLaProc->addArgument( "modifyLaFiles.sh" );
1867 modifyLaProc->addArgument( "modify_la_files" );
1868 modifyLaProc->addArgument( QDir::cleanDirPath( QFileInfo( targetFolder->text().stripWhiteSpace() ).absFilePath() ) );
1870 if ( !modifyLaProc->start() )
1871 ___MESSAGE___( "Error: process could not start!" );
1873 // ================================================================
1875 * SALOME_InstallWizard::checkModifyLaResult
1876 * Slot to take result of modification SALOME *.la files
1878 // ================================================================
1879 void SALOME_InstallWizard::checkModifyLaResult()
1881 if ( modifyLaProc->normalExit() && modifyLaProc->exitStatus() == 1 )
1884 // abort of the current installation
1886 statusLab->setText( tr( "Installation has been aborted" ) );
1887 QMessageBox::critical( this,
1889 tr( "Modification of *.la SALOME files has not been completed."),
1891 QMessageBox::NoButton,
1892 QMessageBox::NoButton );
1893 // enable <Next> button
1894 setNextEnabled( true );
1895 doPostActions( tr( "&Start" ), tr( "Start installation process" ) );
1896 connect( this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
1897 // enable <Back> button
1898 setBackEnabled( true );
1901 // ================================================================
1903 * SALOME_InstallWizard::runCheckFLib
1904 * Run the Fortran and other required libraries checking
1906 // ================================================================
1907 void SALOME_InstallWizard::runCheckFLib()
1909 // Check Fortran libraries
1910 checkFLibProc->clearArguments();
1911 // ... update status label
1912 statusLab->setText( tr( "Check Fortran and other required libraries..." ) );
1913 // ... search "not found" libraries
1914 checkFLibProc->setWorkingDirectory( QDir( rootDirPath() ).filePath( "config_files" ) );
1915 checkFLibProc->addArgument( "checkFortran.sh" );
1916 checkFLibProc->addArgument( "find_libraries" );
1917 checkFLibProc->addArgument( QDir::cleanDirPath( QFileInfo( targetFolder->text().stripWhiteSpace() ).absFilePath() ) );
1919 if ( !checkFLibProc->start() )
1920 ___MESSAGE___( "Error: process could not start!" );
1922 // ================================================================
1924 * SALOME_InstallWizard::checkFLibResult
1925 * Slot to take result of Fortran and other required libraries checking
1927 // ================================================================
1928 void SALOME_InstallWizard::checkFLibResult()
1930 if ( checkFLibProc->normalExit() && checkFLibProc->exitStatus() == 1 ) {
1931 QStringList notFoundLibsList, notFoundOptLibsList;
1932 QString record = "";
1933 QStringList prefOptLibs = getOptionalLibs();
1934 // create list of strings with all 'not found' libraries
1935 while ( checkFLibProc->canReadLineStdout() ) {
1936 record = checkFLibProc->readLineStdout().stripWhiteSpace();
1937 if ( !record.isEmpty() ) {
1938 record = QStringList::split( " ", record )[0];
1939 if ( !notFoundLibsList.contains( record ) &&
1940 !notFoundOptLibsList.contains( record ) ) {
1941 bool isOptional = false;
1942 QStringList::Iterator it_opt;
1943 for ( it_opt = prefOptLibs.begin(); it_opt != prefOptLibs.end(); ++it_opt )
1944 if ( record.startsWith( (*it_opt).stripWhiteSpace(), false ) ) {
1948 isOptional ? notFoundOptLibsList.append( record ) \
1949 : notFoundLibsList.append( record );
1953 QString msg = tr( "Some libraries are absent!<br><br>" );
1954 if ( !notFoundLibsList.isEmpty() ) {
1955 msg += tr( "One or several <b>mandatory</b> libraries listed below are not found. SALOME <u>may not work</u> properly.<br>" );
1956 msg += notFoundLibsList.join( "<br>" );
1959 if ( !notFoundOptLibsList.isEmpty() ) {
1960 msg += tr( "One or several <b>optional</b> libraries listed below are not found. This <u>does not affect</u> on the correct work of SALOME platform.<br>" );
1961 msg += notFoundOptLibsList.join( "<br>" );
1963 if ( !notFoundLibsList.isEmpty() )
1964 QMessageBox::warning( this,
1968 QMessageBox::NoButton,
1969 QMessageBox::NoButton );
1970 else if ( !notFoundOptLibsList.isEmpty() )
1971 QMessageBox::information( this,
1972 tr( "Information" ),
1975 QMessageBox::NoButton,
1976 QMessageBox::NoButton );
1978 // Update GUI and check installation errors
1979 completeInstallation();
1981 // ================================================================
1983 * SALOME_InstallWizard::updateSizeColumn
1984 * Sets required size for each product according to
1985 * installation type and 'Remove SRC & TMP' checkbox state
1987 // ================================================================
1988 void SALOME_InstallWizard::updateSizeColumn()
1991 bool removeSrc = removeSrcBtn->isChecked();
1992 MapProducts::Iterator mapIter;
1993 for ( mapIter = productsMap.begin(); mapIter != productsMap.end(); ++mapIter ) {
1994 QCheckListItem* item = mapIter.key();
1995 Dependancies dep = mapIter.data();
1996 // get required size for current product
1997 long binSize = dep.getSize( Binaries );
1998 long srcSize = dep.getSize( Sources );
1999 long bldSize = dep.getSize( Compile );
2000 InstallationType instType = getInstType();
2001 if ( instType == Binaries ) {
2002 if ( dep.getType() == "component" )
2003 prodSize = binSize + srcSize;
2005 prodSize = ( binSize != 0 ? binSize : srcSize );
2007 else if ( instType == Sources )
2011 prodSize = ( binSize != 0 ? binSize : srcSize );
2013 prodSize = ( bldSize != 0 ? bldSize : srcSize );
2015 // fill in 'Size' field
2016 item->setText( 1, QString::number( prodSize )+" KB" );
2019 // ================================================================
2021 * SALOME_InstallWizard::checkProductPage
2022 * Checks products page validity (directories and products selection) and
2023 * enabled/disables "Next" button for the Products page
2025 // ================================================================
2026 void SALOME_InstallWizard::checkProductPage()
2028 if ( this->currentPage() != productsPage )
2030 long tots = 0, temps = 0;
2031 // check if any product is selected;
2032 bool isAnyProductSelected = checkSize( &tots, &temps );
2034 // update required size information
2035 requiredSize->setText( QString::number( tots ) + " KB");
2036 requiredTemp->setText( QString::number( temps ) + " KB");
2038 // update available size information
2039 QFileInfo fi( QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() ) );
2040 if ( fi.exists() ) {
2041 diskSpaceProc->clearArguments();
2042 diskSpaceProc->setWorkingDirectory( QDir( rootDirPath() ).filePath( "config_files" ) );
2043 diskSpaceProc->addArgument( "diskSpace.sh" );
2044 diskSpaceProc->addArgument( fi.absFilePath() );
2046 diskSpaceProc->start();
2049 // enable/disable "Next" button
2050 setNextEnabled( productsPage, isAnyProductSelected );
2052 // ================================================================
2054 * SALOME_InstallWizard::setPrerequisites
2055 * Sets the product and all products this one depends on to be checked ( recursively )
2057 // ================================================================
2058 void SALOME_InstallWizard::setPrerequisites( QCheckListItem* item )
2060 if ( !productsMap.contains( item ) )
2062 if ( !item->isOn() )
2064 // get all prerequisites
2065 QStringList dependOn = productsMap[ item ].getDependancies();
2066 // install SALOME without GUI case
2067 if ( installGuiBtn->state() != QButton::On &&
2068 woGuiModules.find( item->text(0) ) != woGuiModules.end() &&
2069 woGuiModules[item->text(0)] == True ) {
2070 dependOn.remove( "GUI" );
2072 // setting prerequisites
2073 for ( int i = 0; i < (int)dependOn.count(); i++ ) {
2074 MapProducts::Iterator itProd;
2075 for ( itProd = productsMap.begin(); itProd != productsMap.end(); ++itProd ) {
2076 if ( itProd.data().getName() == dependOn[ i ] ) {
2077 if ( itProd.data().getType() == "component" && !itProd.key()->isOn() )
2078 itProd.key()->setOn( true );
2079 else if ( itProd.data().getType() == "prerequisite" ) {
2080 itProd.key()->setOn( true );
2081 itProd.key()->setEnabled( false );
2088 // ================================================================
2090 * SALOME_InstallWizard::unsetPrerequisites
2091 * Unsets all modules which depend of the unchecked product ( recursively )
2093 // ================================================================
2094 void SALOME_InstallWizard::unsetPrerequisites( QCheckListItem* item )
2096 if ( !productsMap.contains( item ) )
2101 // uncheck dependent products
2102 QString itemName = productsMap[ item ].getName();
2103 MapProducts::Iterator itProd;
2104 for ( itProd = productsMap.begin(); itProd != productsMap.end(); ++itProd ) {
2105 if ( itProd.data().getType() == productsMap[ item ].getType() ) {
2106 QStringList dependOn = itProd.data().getDependancies();
2107 for ( int i = 0; i < (int)dependOn.count(); i++ ) {
2108 if ( dependOn[ i ] == itemName ) {
2109 if ( itProd.key()->isOn() ) {
2110 itProd.key()->setOn( false );
2117 // uncheck prerequisites
2119 // cout << "item name = " << productsMap[ item ].getName() << endl;
2120 QStringList dependOnList = productsMap[ item ].getDependancies();
2121 for ( int j = 0; j < (int)dependOnList.count(); j++ ) {
2123 MapProducts::Iterator itProd1;
2124 for ( itProd1 = productsMap.begin(); itProd1 != productsMap.end(); ++itProd1 ) {
2125 if ( itProd1.data().getName() == dependOnList[ j ] ) {
2126 if ( itProd1.data().getType() == "prerequisite" ) {
2127 MapProducts::Iterator itProd2;
2128 for ( itProd2 = productsMap.begin(); itProd2 != productsMap.end(); ++itProd2 ) {
2129 if ( itProd2.key()->isOn() ) {
2130 QStringList prereqsList = productsMap[ itProd2.key() ].getDependancies();
2131 for ( int k = 0; k < (int)prereqsList.count(); k++ ) {
2132 if ( prereqsList[ k ] == itProd1.data().getName() ) {
2139 if ( nbDependents == 0 ) {
2140 itProd1.key()->setEnabled( true );
2141 itProd1.key()->setOn( false );
2149 // ================================================================
2151 * SALOME_InstallWizard::launchScript
2152 * Runs installation script
2154 // ================================================================
2155 void SALOME_InstallWizard::launchScript()
2157 // try to find product being processed now
2158 QString prodProc = progressView->findStatus( Processing );
2159 if ( !prodProc.isNull() ) {
2160 ___MESSAGE___( "Found <Processing>: " );
2162 // if found - set status to "completed"
2163 progressView->setStatus( prodProc, Completed );
2164 // ... clear status label
2166 // ... and call this method again
2170 // else try to find next product which is not processed yet
2171 prodProc = progressView->findStatus( Waiting );
2172 if ( !prodProc.isNull() ) {
2173 ___MESSAGE___( "Found <Waiting>: " << prodProc.latin1() );
2174 // if found - set status to "processed" and run script
2175 progressView->setStatus( prodProc, Processing );
2176 progressView->ensureVisible( prodProc );
2178 QCheckListItem* item = 0;
2179 // fill in script parameters
2180 shellProcess->clearArguments();
2182 shellProcess->setWorkingDirectory( QDir( rootDirPath() ).filePath( "config_files" ) );
2183 if ( !extraProducts.contains( prodProc ) ) {
2184 item = findItem( prodProc );
2185 shellProcess->addArgument( item->text(2) );
2188 shellProcess->addArgument( extraProducts[ prodProc ] );
2190 // ... get folder with binaries
2191 QString OS = getPlatform();
2192 if ( refPlatform.isEmpty() && platformsMap.find( curPlatform ) == platformsMap.end() )
2193 OS = commonPlatform;
2194 QString binDir = getPlatformBinPath( OS );
2196 QString tmpFolder = QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + TEMPDIRNAME;
2197 //if( !tempFolder->isEnabled() )
2198 // tmpFolder = "/tmp";
2200 // ... not install : try to find preinstalled
2201 if ( notInstall.contains( prodProc ) || prodProc == "gcc" ) {
2202 shellProcess->addArgument( "try_preinstalled" );
2203 shellProcess->addArgument( QFileInfo( tmpFolder ).absFilePath() );
2204 shellProcess->addArgument( QDir( rootDirPath() ).filePath( "Products" ) );
2205 statusLab->setText( tr( "Collecting environment for '" ) + prodProc + "'..." );
2208 else if ( installType == Binaries ) {
2209 shellProcess->addArgument( "install_binary" );
2210 shellProcess->addArgument( QFileInfo( tmpFolder ).absFilePath() );
2211 shellProcess->addArgument( binDir );
2212 statusLab->setText( tr( "Installing '" ) + prodProc + "'..." );
2214 // ... sources or sources_and_compilation ?
2216 shellProcess->addArgument( installType == Sources ? "install_source" :
2217 "install_source_and_build" );
2218 shellProcess->addArgument( QFileInfo( tmpFolder ).absFilePath() );
2219 shellProcess->addArgument( QDir::cleanDirPath( getSrcPath() ) );
2220 statusLab->setText( tr( "Installing '" ) + prodProc + "'..." );
2222 // ... target folder
2223 QString tgtFolder = QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() );
2224 shellProcess->addArgument( QFileInfo( tgtFolder ).absFilePath() );
2225 // ... list of all products
2226 QString depproducts = getAllProducts(productsMap);
2227 depproducts.prepend( QStringList( extraProducts.keys() ).join(" ") + " " );
2228 ___MESSAGE___( "Dependancies"<< depproducts.latin1() );
2229 shellProcess->addArgument( depproducts );
2230 // ... product name - currently installed product
2231 if ( !extraProducts.contains( prodProc ) )
2232 shellProcess->addArgument( item->text(0) );
2234 shellProcess->addArgument( prodProc );
2235 // ... list of products being installed
2236 shellProcess->addArgument( prodSequence.join( " " ) );
2237 // ... sources directory
2238 shellProcess->addArgument( QDir::cleanDirPath( getSrcPath() ) );
2239 // ... remove sources and tmp files or not?
2240 if ( installType == Compile && removeSrcBtn->isOn() )
2241 shellProcess->addArgument( "TRUE" );
2243 shellProcess->addArgument( "FALSE" );
2244 // ... binaries directory
2245 shellProcess->addArgument( binDir );
2246 // ... install SALOME with GUI or not?
2247 if ( woGuiModules.find( prodProc ) != woGuiModules.end() )
2248 ( installGuiBtn->state() != QButton::On && woGuiModules[ prodProc ] == True ) ?
2249 shellProcess->addArgument( "FALSE" ) :
2250 shellProcess->addArgument( "TRUE" );
2251 // ... single installation directory for SALOME modules, if this option was selected
2252 if ( oneModDirBtn->isChecked() ) {
2253 MapProducts::Iterator mapIter;
2254 for ( mapIter = productsMap.begin(); mapIter != productsMap.end(); ++mapIter )
2255 if ( mapIter.data().getName() == prodProc && mapIter.data().getType() == "component" ) {
2256 shellProcess->addArgument( "TRUE" );
2260 // ... single installation directory for prerequisites, if this option was selected
2261 if ( oneProdDirBtn->isChecked() ) {
2262 if ( prodProc == "DebianLibsForSalome" )
2263 shellProcess->addArgument( oneProdDirName );
2265 MapProducts::Iterator mapIter;
2266 for ( mapIter = productsMap.begin(); mapIter != productsMap.end(); ++mapIter )
2267 if ( mapIter.data().getName() == prodProc && mapIter.data().getType() == "prerequisite" ) {
2268 shellProcess->addArgument( oneProdDirName );
2275 if ( !shellProcess->start() ) {
2276 // error handling can be here
2277 QStringList args = shellProcess->arguments();
2278 ___MESSAGE___( "error" );
2279 ___MESSAGE___( "cmd: " << args.join(" ").latin1() );
2284 // else try to find aborted product
2285 prodProc = progressView->findStatus( Aborted );
2286 if ( !prodProc.isNull() )
2287 return; // installation has been aborted
2289 ___MESSAGE___( "All products have been installed successfully" );
2290 // all products are installed successfully
2291 MapProducts::Iterator mapIter;
2292 ___MESSAGE___( "starting pick-up environment" );
2293 QString depproducts = QUOTE( getAllProducts(productsMap).prepend( QStringList( extraProducts.keys() ).join(" ") + " " ) );
2294 for ( mapIter = productsMap.begin(); mapIter != productsMap.end(); ++mapIter ) {
2295 QCheckListItem* item = mapIter.key();
2296 Dependancies dep = mapIter.data();
2297 if ( item->isOn() && dep.pickUpEnvironment() ) {
2298 statusLab->setText( tr( "Pick-up products environment for " ) + dep.getName().latin1() + "..." );
2299 ___MESSAGE___( "... for " << dep.getName().latin1() );
2300 QDir rd( rootDirPath() );
2302 script << "cd" << QUOTE( rd.filePath( "config_files" ) ) << ";";
2303 script << item->text(2) << "pickup_env";
2304 script << QUOTE( QFileInfo( QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + TEMPDIRNAME ).absFilePath() );
2305 script << QUOTE( QFileInfo( QDir::cleanDirPath( QDir( rootDirPath() ).filePath( "Products" ) ) ).absFilePath() );
2306 script << QUOTE( QFileInfo( QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() ) ).absFilePath() );
2307 script << depproducts << item->text(0) << QUOTE( prodSequence.join( " " ) );
2308 ___MESSAGE___( "... --> " << script.script().latin1() );
2309 if ( system( script.script().latin1() ) ) {
2310 ___MESSAGE___( "ERROR" );
2315 if ( installType == Binaries ) {
2316 if ( oneModDirBtn->isChecked() )
2322 // Update GUI and check installation errors
2323 completeInstallation();
2327 // ================================================================
2329 * SALOME_InstallWizard::completeInstallation
2330 * Update GUI and check installation errors
2332 // ================================================================
2333 void SALOME_InstallWizard::completeInstallation()
2335 // update status label
2336 statusLab->setText( tr( "Installation completed" ) );
2338 setNextEnabled( true );
2339 doPostActions( tr( "&Next >" ), tr( "Move to the next step of the installation procedure" ) );
2340 connect( this, SIGNAL( nextClicked() ), this, SLOT( next() ) );
2342 setBackEnabled( true );
2343 // script parameters
2344 passedParams->clear();
2345 passedParams->setEnabled( false );
2346 QFont f = parametersLab->font(); f.setBold( false ); parametersLab->setFont( f );
2347 installInfo->setFinished( true );
2348 if ( isMinimized() )
2352 if ( QMessageBox::warning( this,
2354 tr( "There were some errors during the installation.\n"
2355 "Do you want to save the installation log?" ),
2366 // ================================================================
2368 * SALOME_InstallWizard::onInstallGuiBtn
2369 * <Installation with GUI> check-box slot
2371 // ================================================================
2372 void SALOME_InstallWizard::onInstallGuiBtn()
2374 MapProducts::Iterator itProd;
2375 for ( itProd = productsMap.begin(); itProd != productsMap.end(); ++itProd ) {
2376 if ( itProd.data().getType() == "component" ) {
2377 if ( installGuiBtn->state() == QButton::On ) {
2378 itProd.key()->setEnabled( true );
2379 itProd.key()->setOn( true );
2382 QString itemName = itProd.data().getName();
2383 if ( woGuiModules.find( itemName ) == woGuiModules.end() ||
2384 woGuiModules[ itemName ] == False ) {
2385 itProd.key()->setOn( false );
2386 itProd.key()->setEnabled( false );
2389 itProd.key()->setOn( true );
2394 // ================================================================
2396 * SALOME_InstallWizard::onMoreBtn
2397 * <More...> button slot
2399 // ================================================================
2400 void SALOME_InstallWizard::onMoreBtn()
2403 prereqsView->hide();
2404 moreBtn->setText( tr( "Show prerequisites..." ) );
2405 setAboutInfo( moreBtn, tr( "Show list of prerequisites" ) );
2408 prereqsView->show();
2409 moreBtn->setText( tr( "Hide prerequisites" ) );
2410 setAboutInfo( moreBtn, tr( "Hide list of prerequisites" ) );
2412 qApp->processEvents();
2413 moreMode = !moreMode;
2414 InstallWizard::layOut();
2415 qApp->processEvents();
2416 if ( !isMaximized() ) {
2417 qApp->processEvents();
2421 // ================================================================
2423 * SALOME_InstallWizard::onFinishButton
2424 * Operation buttons slot
2426 // ================================================================
2427 void SALOME_InstallWizard::onFinishButton()
2429 const QObject* btn = sender();
2430 ButtonList::Iterator it;
2431 for ( it = buttons.begin(); it != buttons.end(); ++it ) {
2432 if ( (*it).button() && (*it).button() == btn ) {
2433 QDir rd( rootDirPath() );
2435 script << "cd" << QUOTE( rd.filePath( "config_files" ) ) << ";";
2436 script << (*it).script() << "execute";
2437 script << QUOTE( QFileInfo( QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() ) ).absFilePath() );
2438 script << QUOTE( QFileInfo( QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + TEMPDIRNAME ).absFilePath() );
2440 script << ">& /dev/null";
2442 ___MESSAGE___( "script: " << script.script().latin1() );
2443 if ( (*it).script().isEmpty() || system( script.script().latin1() ) ) {
2444 QMessageBox::warning( this,
2446 tr( "Can't perform action!"),
2448 QMessageBox::NoButton,
2449 QMessageBox::NoButton );
2455 // ================================================================
2457 * SALOME_InstallWizard::onAbout
2458 * <About> button slot: shows <About> dialog box
2460 // ================================================================
2461 void SALOME_InstallWizard::onAbout()
2467 // ================================================================
2469 * SALOME_InstallWizard::findItem
2470 * Searches product listview item with given symbolic name
2472 // ================================================================
2473 QCheckListItem* SALOME_InstallWizard::findItem( const QString& sName )
2475 MapProducts::Iterator mapIter;
2476 for ( mapIter = productsMap.begin(); mapIter != productsMap.end(); ++mapIter ) {
2477 if ( mapIter.data().getName() == sName )
2478 return mapIter.key();
2482 // ================================================================
2484 * SALOME_InstallWizard::abort
2485 * Sets progress state to Aborted
2487 // ================================================================
2488 void SALOME_InstallWizard::abort()
2490 QString prod = progressView->findStatus( Processing );
2491 while ( !prod.isNull() ) {
2492 progressView->setStatus( prod, Aborted );
2493 prod = progressView->findStatus( Processing );
2495 prod = progressView->findStatus( Waiting );
2496 while ( !prod.isNull() ) {
2497 progressView->setStatus( prod, Aborted );
2498 prod = progressView->findStatus( Waiting );
2501 // ================================================================
2503 * SALOME_InstallWizard::reject
2504 * Reject slot, clears temporary directory and closes application
2506 // ================================================================
2507 void SALOME_InstallWizard::reject()
2509 ___MESSAGE___( "REJECTED" );
2510 if ( !exitConfirmed ) {
2511 if ( QMessageBox::information( this,
2513 tr( "Do you want to quit %1?" ).arg( getIWName() ),
2521 exitConfirmed = true;
2524 InstallWizard::reject();
2526 // ================================================================
2528 * SALOME_InstallWizard::accept
2529 * Accept slot, clears temporary directory and closes application
2531 // ================================================================
2532 void SALOME_InstallWizard::accept()
2534 ___MESSAGE___( "ACCEPTED" );
2536 InstallWizard::accept();
2538 // ================================================================
2540 * SALOME_InstallWizard::clean
2541 * Clears and (optionally) removes temporary directory
2543 // ================================================================
2544 void SALOME_InstallWizard::clean(bool rmDir)
2546 WarnDialog::showWarnDlg( 0, false );
2547 myThread->clearCommands();
2549 while ( myThread->running() );
2550 // first remove temporary files
2551 QDir rd( rootDirPath() );
2553 script << "cd" << QUOTE( rd.filePath( "config_files" ) ) << ";";
2554 script << "remove_tmp.sh" << QUOTE( tempFolder->text().stripWhiteSpace() + TEMPDIRNAME );
2555 script << QUOTE( getAllProducts( productsMap ) );
2557 script << ">& /dev/null";
2559 ___MESSAGE___( "script = " << script.script().latin1() );
2560 if ( system( script.script().latin1() ) ) {
2563 // then try to remove created temporary directory
2564 //script = "rm -rf " + QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + TEMPDIRNAME;
2565 if ( rmDir && !tmpCreated.isNull() ) {
2567 script << "rm -rf" << QUOTE( tmpCreated );
2569 script << ">& /dev/null";
2571 if ( system( script.script().latin1() ) ) {
2574 ___MESSAGE___( "script = " << script.script().latin1() );
2577 // ================================================================
2579 * SALOME_InstallWizard::pageChanged
2580 * Called when user moves from page to page
2582 // ================================================================
2583 void SALOME_InstallWizard::pageChanged( const QString & mytitle)
2585 doPostActions( tr( "&Next >" ), tr( "Move to the next step of the installation procedure" ) );
2586 connect( this, SIGNAL( nextClicked() ), this, SLOT( next() ) );
2587 cancelButton()->disconnect();
2588 connect( cancelButton(), SIGNAL( clicked()), this, SLOT( reject() ) );
2590 QWidget* aPage = InstallWizard::page( mytitle );
2595 if ( aPage == typePage ) {
2596 // installation type page
2597 if ( buttonGrp->id( buttonGrp->selected() ) == -1 )
2598 // set default installation type
2599 forceSrc ? srcCompileBtn->animateClick() : binBtn->animateClick();
2601 buttonGrp->selected()->animateClick();
2603 else if ( aPage == platformsPage ) {
2604 // installation platforms page
2605 MapXmlFiles::Iterator it;
2606 if ( previousPage == typePage ) {
2607 for ( it = platformsMap.begin(); it != platformsMap.end(); ++it ) {
2608 QString plat = it.key();
2609 QRadioButton* rb = ( (QRadioButton*) platBtnGrp->child( plat ) );
2610 if ( installType == Binaries ) {
2611 QFileInfo fib( getPlatformBinPath( plat ) );
2612 rb->setEnabled( true/*fib.isDir()*/ );
2613 if ( platBtnGrp->id( platBtnGrp->selected() ) == -1 && plat == getBasePlatform() )
2616 // rb->setChecked( rb->isChecked() && rb->isEnabled() );
2617 if ( rb->isChecked() && rb->isEnabled() )
2620 setNextEnabled( platformsPage, platBtnGrp->id( platBtnGrp->selected() ) != -1 );
2623 else if ( aPage == dirPage ) {
2624 // installation and temporary directories page
2625 if ( ( ( this->indexOf( platformsPage ) != -1 && this->appropriate( platformsPage ) ) ?
2626 previousPage == platformsPage : previousPage == typePage )
2628 // clear global variables before reading XML file
2629 modulesView->clear();
2630 prereqsView->clear();
2631 productsMap.clear();
2633 StructureParser* parser = new StructureParser( this );
2634 parser->setProductsLists( modulesView, prereqsView );
2635 if ( targetFolder->text().isEmpty() )
2636 parser->setTargetDir( targetFolder );
2637 if ( tempFolder->text().isEmpty() )
2638 parser->setTempDir( tempFolder );
2639 parser->readXmlFile( xmlFileName );
2640 // create a map of SALOME modules names, that can support installation without GUI mode
2641 if ( woGuiModules.isEmpty() ) {
2642 MapProducts::Iterator mapIter;
2643 for ( mapIter = productsMap.begin(); mapIter != productsMap.end(); mapIter++ ) {
2644 Dependancies dep = mapIter.data();
2645 if ( dep.getType() == "component" && dep.supportWoGuiMode() != NotDefined )
2646 woGuiModules[ dep.getName() ] = dep.supportWoGuiMode();
2650 // update required size for each product
2652 // take into account command line parameters
2653 if ( !myTargetPath.isEmpty() )
2654 targetFolder->setText( myTargetPath );
2655 if ( !myTmpPath.isEmpty() )
2656 tempFolder->setText( myTmpPath );
2657 // set all modules to be checked and first module to be selected
2658 installGuiBtn->setState( QButton::Off );
2659 installGuiBtn->setState( QButton::On );
2660 if ( modulesView->childCount() > 0 && !modulesView->selectedItem() )
2661 modulesView->setSelected( modulesView->firstChild(), true );
2662 stateChanged = false;
2664 else if ( rmSrcPrevState != removeSrcBtn->isChecked() ) {
2665 // only update required size for each product
2667 rmSrcPrevState = removeSrcBtn->isChecked();
2669 // add extra products to install list
2670 extraProducts.clear();
2671 if ( refPlatform == commonPlatform && installType == Binaries )
2672 extraProducts.insert( "DebianLibsForSalome", "DEBIANFORSALOME-3.1.sh" );
2674 else if ( aPage == productsPage ) {
2676 onSelectionChanged();
2679 else if ( aPage == prestartPage ) {
2683 else if ( aPage == progressPage ) {
2684 if ( previousPage == prestartPage ) {
2687 progressView->clear();
2688 installInfo->clear();
2689 installInfo->setFinished( false );
2690 passedParams->clear();
2691 passedParams->setEnabled( false );
2692 QFont f = parametersLab->font(); f.setBold( false ); parametersLab->setFont( f );
2693 doPostActions( tr( "&Start" ), tr( "Start installation process" ) );
2694 connect( this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
2695 setNextEnabled( true );
2696 // reconnect Cancel button to terminate process
2697 cancelButton()->disconnect();
2698 connect( cancelButton(), SIGNAL( clicked() ), this, SLOT( tryTerminate() ) );
2701 else if ( aPage == readmePage ) {
2702 ButtonList::Iterator it;
2703 for ( it = buttons.begin(); it != buttons.end(); ++it ) {
2704 if ( (*it).button() ) {
2705 QDir rd( rootDirPath() );
2707 script << "cd" << QUOTE( rd.filePath( "config_files" ) ) << ";";
2708 script << (*it).script() << "check_enabled";
2709 script << QUOTE( QFileInfo( QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() ) ).absFilePath() );
2710 script << QUOTE( QFileInfo( QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + TEMPDIRNAME ).absFilePath() );
2712 script << ">& /dev/null";
2714 ___MESSAGE___( "script: " << script.script().latin1() );
2715 (*it).button()->setEnabled( !(*it).script().isEmpty() && !system( script.script().latin1() ) );
2718 finishButton()->setEnabled( true );
2720 previousPage = aPage;
2721 ___MESSAGE___( "previousPage = " << previousPage );
2723 // ================================================================
2725 * SALOME_InstallWizard::onButtonGroup
2726 * Called when user selected either installation type or installation platform
2728 // ================================================================
2729 void SALOME_InstallWizard::onButtonGroup( int rbIndex )
2731 int prevType = installType;
2732 QString prevPlat = getPlatform();
2733 QWidget* aPage = InstallWizard::currentPage();
2734 if ( aPage == typePage ) {
2735 installType = InstallationType( rbIndex );
2736 // management of the <Remove source and tmp files> check-box
2737 removeSrcBtn->setEnabled( installType == Compile );
2738 oneModDirBtn->setEnabled( installType == Binaries /*|| installType == Compile*/ );
2739 oneProdDirBtn->setEnabled( installType == Binaries || installType == Compile );
2741 xmlFileName = getXmlFile( curPlatform );
2743 else if ( aPage == platformsPage ) {
2744 refPlatform = platBtnGrp->find( rbIndex )->name();
2745 xmlFileName = getXmlFile( refPlatform );
2746 setNextEnabled( platformsPage, true );
2748 if ( prevType != installType ||
2749 ( indexOf( platformsPage ) != -1 ? prevPlat != getPlatform() : false ) ) {
2750 stateChanged = true;
2751 oneModDirBtn->setChecked( installType == Binaries && singleDir );
2752 oneProdDirBtn->setChecked( false );
2755 // ================================================================
2757 * SALOME_InstallWizard::helpClicked
2760 // ================================================================
2761 void SALOME_InstallWizard::helpClicked()
2763 if ( helpWindow == NULL ) {
2764 helpWindow = HelpWindow::openHelp( this );
2767 helpWindow->installEventFilter( this );
2770 QMessageBox::warning( this,
2771 tr( "Help file not found" ),
2772 tr( "Sorry, help is unavailable" ) );
2776 helpWindow->raise();
2777 helpWindow->setActiveWindow();
2780 // ================================================================
2782 * SALOME_InstallWizard::browseDirectory
2783 * Shows directory selection dialog
2785 // ================================================================
2786 void SALOME_InstallWizard::browseDirectory()
2788 const QObject* theSender = sender();
2789 QLineEdit* theFolder;
2790 if ( theSender == targetBtn )
2791 theFolder = targetFolder;
2792 else if (theSender == tempBtn)
2793 theFolder = tempFolder;
2796 QString typedDir = QFileDialog::getExistingDirectory( QDir::cleanDirPath( theFolder->text().stripWhiteSpace() ), this );
2797 if ( !typedDir.isNull() ) {
2798 theFolder->setText( typedDir );
2799 theFolder->end( false );
2802 // ================================================================
2804 * SALOME_InstallWizard::directoryChanged
2805 * Called when directory path (target or temp) is changed
2807 // ================================================================
2808 void SALOME_InstallWizard::directoryChanged( const QString& /*text*/ )
2812 // ================================================================
2814 * SALOME_InstallWizard::onStart
2815 * <Start> button's slot - runs installation
2817 // ================================================================
2818 void SALOME_InstallWizard::onStart()
2820 if ( nextButton()->text() == tr( "&Stop" ) ) {
2821 statusLab->setText( tr( "Aborting installation..." ) );
2822 shellProcess->kill();
2823 modifyLaProc->kill();
2824 while( shellProcess->isRunning() );
2825 statusLab->setText( tr( "Installation has been aborted by user" ) );
2830 progressView->clear();
2831 installInfo->clear();
2832 installInfo->setFinished( false );
2833 passedParams->clear();
2834 passedParams->setEnabled( false );
2835 // disable 'Ignore errors' checkbox during installation process
2836 ignoreErrCBox->setEnabled( false );
2837 QFont f = parametersLab->font(); f.setBold( false ); parametersLab->setFont( f );
2839 // update status label
2840 statusLab->setText( tr( "Preparing for installation..." ) );
2841 // clear lists of products
2844 toInstall += extraProducts.keys();
2845 // ... and fill it for new process
2846 QCheckListItem* item = (QCheckListItem*)( prereqsView->firstChild() );
2848 if ( productsMap.contains( item ) ) {
2850 toInstall.append( productsMap[item].getName() );
2852 notInstall.append( productsMap[item].getName() );
2854 item = (QCheckListItem*)( item->nextSibling() );
2856 item = (QCheckListItem*)( modulesView->firstChild() );
2858 if ( productsMap.contains( item ) ) {
2860 toInstall.append( productsMap[item].getName() );
2862 notInstall.append( productsMap[item].getName() );
2864 item = (QCheckListItem*)( item->nextSibling() );
2866 // if something at all is selected
2867 if ( (int)toInstall.count() > 0 ) {
2869 if ( installType == Compile ) {
2870 // update status label
2871 statusLab->setText( tr( "Check Fortran compiler..." ) );
2872 // check Fortran compiler.
2873 QDir rd( rootDirPath() );
2875 script << QUOTE( rd.filePath( "config_files/checkFortran.sh" ) ) << "find_compilers";
2876 script << QUOTE( QFileInfo( QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + TEMPDIRNAME ).absFilePath() );
2877 ___MESSAGE___( "script = " << script.script().latin1() );
2878 if ( system( script.script().latin1() ) ) {
2879 QMessageBox::critical( this,
2881 tr( "Fortran compiler was not found at current system!\n"
2882 "Installation can not be continued!"),
2884 QMessageBox::NoButton,
2885 QMessageBox::NoButton );
2886 // installation aborted
2888 statusLab->setText( tr( "Installation has been aborted" ) );
2889 // enable <Next> button
2890 setNextEnabled( true );
2891 doPostActions( tr( "&Start" ), tr( "Start installation process" ) );
2892 connect( this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
2893 // enable <Back> button
2894 setBackEnabled( true );
2899 // update status label
2900 statusLab->setText( tr( "Preparing for installation..." ) );
2902 clean(false); // VSR 07/02/05 - bug fix: first we should clear temporary directory
2903 // disable <Next> button
2904 //setNextEnabled( false );
2905 nextButton()->setText( tr( "&Stop" ) );
2906 setAboutInfo( nextButton(), tr( "Abort installation process" ) );
2907 // disable <Back> button
2908 setBackEnabled( false );
2909 // enable script parameters line edit
2910 // VSR commented: 18/09/03: passedParams->setEnabled( true );
2911 // VSR commented: 18/09/03: passedParams->setFocus();
2912 ProgressViewItem* progressItem;
2913 // set status for installed products
2914 for ( int i = 0; i < (int)toInstall.count(); i++ ) {
2915 if ( !extraProducts.contains( toInstall[i] ) ) {
2916 item = findItem( toInstall[i] );
2917 progressView->addProduct( item->text(0), item->text(2) );
2920 progressItem = progressView->addProduct( toInstall[i], extraProducts[toInstall[i]] );
2921 progressItem->setVisible( false );
2923 // set status for not installed products
2924 for ( int i = 0; i < (int)notInstall.count(); i++ ) {
2925 item = findItem( notInstall[i] );
2926 progressItem = progressView->addProduct( item->text(0), item->text(2) );
2927 progressItem->setVisible( false );
2929 // get specified list of products being installed
2930 prodSequence.clear();
2931 for (int i = 0; i<(int)toInstall.count(); i++ ) {
2932 if ( extraProducts.contains( toInstall[i] ) ) {
2933 prodSequence.append( toInstall[i] );
2936 if ( installType == Binaries ) {
2937 prodSequence.append( toInstall[i] );
2939 MapProducts::Iterator mapIter;
2940 for ( mapIter = productsMap.begin(); mapIter != productsMap.end(); ++mapIter ) {
2941 if ( mapIter.data().getName() == toInstall[i] && mapIter.data().getType() == "component" ) {
2942 prodSequence.append( toInstall[i] + "_src" );
2947 else if ( installType == Sources )
2948 prodSequence.append( toInstall[i] + "_src" );
2950 prodSequence.append( toInstall[i] );
2951 prodSequence.append( toInstall[i] + "_src" );
2955 // create a backup of 'env_build.csh', 'env_build.sh', 'env_products.csh', 'env_products.sh'
2956 // ( backup of 'salome.csh' and 'salome.sh' is made if pick-up environment is called )
2957 QDir rd( rootDirPath() );
2959 script << QUOTE( rd.filePath( "config_files/backupEnv.sh" ) );
2960 script << QUOTE( QFileInfo( QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() ) ).absFilePath() );
2961 ___MESSAGE___( "script = " << script.script().latin1() );
2962 if ( system( script.script().latin1() ) ) {
2963 if ( QMessageBox::warning( this,
2965 tr( "Backup environment files have not been created.\n"
2966 "Do you want to continue an installation process?" ),
2969 QString::null, 0, 1 ) == 1 ) {
2970 // installation aborted
2972 statusLab->setText( tr( "Installation has been aborted by user" ) );
2973 // update <Next> button
2974 setNextEnabled( true );
2975 doPostActions( tr( "&Start" ), tr( "Start installation process" ) );
2976 connect( this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
2977 // enable <Back> button
2978 setBackEnabled( true );
2983 // launch install script
2987 // ================================================================
2989 * SALOME_InstallWizard::onReturnPressed
2990 * Called when users tries to pass parameters for the script
2992 // ================================================================
2993 void SALOME_InstallWizard::onReturnPressed()
2995 QString txt = passedParams->text();
2996 installInfo->append( txt );
2998 shellProcess->writeToStdin( txt );
2999 passedParams->clear();
3000 progressView->setFocus();
3001 passedParams->setEnabled( false );
3002 QFont f = parametersLab->font(); f.setBold( false ); parametersLab->setFont( f );
3005 Callback function - as response for the script finishing
3007 void SALOME_InstallWizard::productInstalled()
3009 ___MESSAGE___( "process exited" );
3010 if ( shellProcess->normalExit() ) {
3011 ___MESSAGE___( "...normal exit" );
3012 // normal exit - try to proceed installation further
3016 ___MESSAGE___( "...abnormal exit" );
3017 statusLab->setText( tr( "Installation has been aborted" ) );
3018 // installation aborted
3020 // clear script passed parameters lineedit
3021 passedParams->clear();
3022 passedParams->setEnabled( false );
3023 QFont f = parametersLab->font(); f.setBold( false ); parametersLab->setFont( f );
3024 installInfo->setFinished( true );
3025 // enable <Next> button
3026 setNextEnabled( true );
3027 doPostActions( tr( "&Start" ), tr( "Start installation process" ) );
3028 connect( this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
3029 //doPostActions( tr( "&Next >" ), tr( "Move to the next step of the installation procedure" ) );
3030 //connect( this, SIGNAL( nextClicked() ), this, SLOT( next() ) );
3031 // enable <Back> button
3032 setBackEnabled( true );
3035 // ================================================================
3037 * SALOME_InstallWizard::tryTerminate
3038 * Slot, called when <Cancel> button is clicked during installation script running
3040 // ================================================================
3041 void SALOME_InstallWizard::tryTerminate()
3043 if ( shellProcess->isRunning() ) {
3044 if ( QMessageBox::information( this,
3046 tr( "Do you want to quit %1?" ).arg( getIWName() ),
3054 exitConfirmed = true;
3055 // if process still running try to terminate it first
3056 shellProcess->tryTerminate();
3058 //QTimer::singleShot( 3000, this, SLOT( onCancel() ) );
3059 connect( shellProcess, SIGNAL( processExited() ), this, SLOT( onCancel() ) );
3062 // else just quit install wizard
3066 // ================================================================
3068 * SALOME_InstallWizard::onCancel
3069 * Kills installation process and quits application
3071 // ================================================================
3072 void SALOME_InstallWizard::onCancel()
3074 shellProcess->kill();
3075 modifyLaProc->kill();
3076 checkFLibProc->kill();
3079 // ================================================================
3081 * SALOME_InstallWizard::onSelectionChanged
3082 * Called when selection is changed in the products list view
3083 * to fill in the 'Information about product' text box
3085 // ================================================================
3086 void SALOME_InstallWizard::onSelectionChanged()
3088 const QObject* snd = sender();
3089 QListViewItem* item = modulesView->selectedItem();
3090 if ( snd == prereqsView )
3091 item = prereqsView->selectedItem();
3094 productInfo->clear();
3095 QCheckListItem* anItem = (QCheckListItem*)item;
3096 if ( !productsMap.contains( anItem ) )
3098 Dependancies dep = productsMap[ anItem ];
3099 QString text = "<b>" + anItem->text(0) + "</b>" + "<br>";
3100 if ( !dep.getVersion().isEmpty() )
3101 text += tr( "Version" ) + ": " + dep.getVersion() + "<br>";
3103 if ( !dep.getDescription().isEmpty() ) {
3104 text += "<i>" + dep.getDescription() + "</i><br><br>";
3106 /* AKL: 07/08/28 - hide required disk space for tmp files for each product ==>
3108 tempSize = dep.getTempSize( installType );
3109 text += tr( "Disk space for tmp files required" ) + ": " + QString::number( tempSize ) + " KB<br>";
3110 AKL: 07/08/28 - hide required disk space for tmp files for each product <==
3112 text += tr( "Disk space required" ) + ": " + item->text(1) + "<br>";
3114 QString req = ( dep.getDependancies().count() > 0 ? dep.getDependancies().join(", ") : tr( "none" ) );
3115 text += tr( "Prerequisites" ) + ": " + req;
3116 productInfo->setText( text );
3118 // ================================================================
3120 * SALOME_InstallWizard::onItemToggled
3121 * Called when user checks/unchecks any product item
3122 * Recursively sets all prerequisites and updates "Next" button state
3124 // ================================================================
3125 void SALOME_InstallWizard::onItemToggled( QCheckListItem* item )
3127 if ( productsMap.contains( item ) ) {
3129 setPrerequisites( item );
3131 unsetPrerequisites( item );
3133 onSelectionChanged();
3136 // ================================================================
3138 * SALOME_InstallWizard::wroteToStdin
3139 * QProcess slot: -->something was written to stdin
3141 // ================================================================
3142 void SALOME_InstallWizard::wroteToStdin( )
3144 ___MESSAGE___( "Something was sent to stdin" );
3146 // ================================================================
3148 * SALOME_InstallWizard::readFromStdout
3149 * QProcess slot: -->something was written to stdout
3151 // ================================================================
3152 void SALOME_InstallWizard::readFromStdout( )
3154 ___MESSAGE___( "Something was sent to stdout" );
3155 QProcess* theProcess = ( QProcess* )sender();
3156 while ( theProcess->canReadLineStdout() ) {
3157 installInfo->append( QString( theProcess->readLineStdout() ) );
3158 installInfo->scrollToBottom();
3160 QString str( theProcess->readStdout() );
3161 if ( !str.isEmpty() ) {
3162 installInfo->append( str );
3163 installInfo->scrollToBottom();
3167 #define OUTLINE_TEXT(x) QString( "<font color=#FF0000><b>" ) + QString( x ) + QString( "</b></font>" )
3169 // ================================================================
3171 * SALOME_InstallWizard::readFromStderr
3172 * QProcess slot: -->something was written to stderr
3174 // ================================================================
3175 void SALOME_InstallWizard::readFromStderr( )
3177 ___MESSAGE___( "Something was sent to stderr" );
3178 QProcess* theProcess = ( QProcess* )sender();
3179 while ( theProcess->canReadLineStderr() ) {
3180 installInfo->append( OUTLINE_TEXT( QString( theProcess->readLineStderr() ) ) );
3181 installInfo->scrollToBottom();
3184 QString str( theProcess->readStderr() );
3185 if ( !str.isEmpty() ) {
3186 installInfo->append( OUTLINE_TEXT( str ) );
3187 installInfo->scrollToBottom();
3191 // stop or proceed installation process
3194 // VSR: 10/11/05 - disable answer mode ==>
3195 // passedParams->setEnabled( true );
3196 // passedParams->setFocus();
3197 // QFont f = parametersLab->font(); f.setBold( true ); parametersLab->setFont( f );
3198 // VSR: 10/11/05 - disable answer mode <==
3200 // ================================================================
3202 * SALOME_InstallWizard::manageInstProc
3203 * QProcess slot: -->stop installation if there is an error in stderr
3205 // ================================================================
3206 void SALOME_InstallWizard::manageInstProc()
3208 if ( !hasErrors || ignoreErrCBox->isChecked() )
3209 return; //proceed installation process
3211 // abort the current installation
3212 statusLab->setText( tr( "Aborting installation..." ) );
3214 statusLab->setText( tr( "Installation has been aborted because some errors" ) );
3215 if ( QMessageBox::critical( this,
3217 tr( "Installation process has been stopped, because an error occured \n"
3218 "during an installation of the current product!\n"
3219 "Please see the installation progress view for more details about the error.\n\n"
3220 "Do you want to save the installation log?" ),
3227 // enable <Next> button
3228 setNextEnabled( true );
3229 doPostActions( tr( "&Start" ), tr( "Start installation process" ) );
3230 connect( this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
3231 // enable <Back> button
3232 setBackEnabled( true );
3233 installInfo->setFinished( true );
3235 // ================================================================
3237 * SALOME_InstallWizard::setDependancies
3238 * Sets dependancies for the product item
3240 // ================================================================
3241 void SALOME_InstallWizard::setDependancies( QCheckListItem* item, Dependancies dep)
3243 productsMap[item] = dep;
3245 // ================================================================
3247 * SALOME_InstallWizard::doPostActions
3248 * Executes some actions after finish of installation process (successful or not)
3250 // ================================================================
3251 void SALOME_InstallWizard::doPostActions( const QString& btnText,
3252 const QString& btnAboutInfo )
3254 // update <Next> button
3255 nextButton()->setText( btnText );
3256 setAboutInfo( nextButton(), btnAboutInfo );
3257 // reconnect Next button - to use it as Start button
3258 disconnect( this, SIGNAL( nextClicked() ), this, SLOT( next() ) );
3259 disconnect( this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
3260 // enable 'Ignore errors' checkbox
3261 ignoreErrCBox->setEnabled( true );
3263 // ================================================================
3265 * SALOME_InstallWizard::addFinishButton
3266 * Add button for the <Finish> page.
3267 * Clear list of buttons if <toClear> flag is true.
3269 // ================================================================
3270 void SALOME_InstallWizard::addFinishButton( const QString& label,
3271 const QString& tooltip,
3272 const QString& script,
3280 buttons.append( Button( label, tooltip, script ) );
3281 // create finish buttons
3282 QButton* b = new QPushButton( tr( buttons.last().label() ), readmePage );
3283 if ( !buttons.last().tootip().isEmpty() )
3284 setAboutInfo( b, tr( buttons.last().tootip() ) );
3285 QHBoxLayout* hLayout = (QHBoxLayout*)readmePage->layout()->child("finishButtons");
3287 // remove previous buttons
3288 ButtonList::Iterator it;
3289 for ( it = btns.begin(); it != btns.end(); ++it ) {
3290 hLayout->removeChild( (*it).button() );
3291 delete (*it).button();
3294 // add buttons to finish page
3295 hLayout->insertWidget( buttons.count()-1, b );
3296 buttons.last().setButton( b );
3297 connect( b, SIGNAL( clicked() ), this, SLOT( onFinishButton() ) );
3299 // ================================================================
3301 * SALOME_InstallWizard::polish
3302 * Polishing of the widget - to set right initial size
3304 // ================================================================
3305 void SALOME_InstallWizard::polish()
3308 InstallWizard::polish();
3310 // ================================================================
3312 * SALOME_InstallWizard::saveLog
3313 * Save installation log to file
3315 // ================================================================
3316 void SALOME_InstallWizard::saveLog()
3318 QString txt = installInfo->text();
3319 if ( txt.length() <= 0 )
3321 QDateTime dt = QDateTime::currentDateTime();
3322 QString fileName = dt.toString("ddMMyy-hhmm");
3323 fileName.prepend("install-"); fileName.append(".html");
3324 fileName = QFileInfo( QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() ), fileName ).absFilePath();
3325 fileName = QFileDialog::getSaveFileName( fileName,
3326 QString( "HTML files (*.htm *.html)" ),
3328 tr( "Save Log file" ) );
3329 if ( !fileName.isEmpty() ) {
3330 QFile f( fileName );
3331 if ( f.open( IO_WriteOnly ) ) {
3332 QTextStream stream( &f );
3337 QMessageBox::critical( this,
3339 tr( "Can't save file %1.\nCheck path and permissions.").arg( fileName ),
3341 QMessageBox::NoButton,
3342 QMessageBox::NoButton );
3346 // ================================================================
3348 * SALOME_InstallWizard::updateCaption
3349 * Updates caption according to the current page number
3351 // ================================================================
3352 void SALOME_InstallWizard::updateCaption()
3354 QWidget* aPage = InstallWizard::currentPage();
3357 InstallWizard::setCaption( tr( myCaption ) + " " +
3358 tr( getIWName() ) + " - " +
3359 tr( "Step %1 of %2").arg( QString::number( this->indexOf( aPage )+1 ) ).arg( QString::number( this->pageCount() ) ) );
3362 // ================================================================
3364 * SALOME_InstallWizard::processValidateEvent
3365 * Processes validation event (<val> is validation code)
3367 // ================================================================
3368 void SALOME_InstallWizard::processValidateEvent( const int val, void* data )
3370 QWidget* aPage = InstallWizard::currentPage();
3371 if ( aPage != productsPage ) {
3372 InstallWizard::processValidateEvent( val, data );
3379 if ( myThread->hasCommands() )
3382 WarnDialog::showWarnDlg( 0, false );
3383 InstallWizard::processValidateEvent( val, data );