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-2012 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-2012 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( "6.5.0" );
561 setCaption( tr( "SALOME %1" ).arg( myVersion ) );
562 setCopyright( tr( "<h5>Copyright © 2007-2012 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 );
703 for ( int i = 1; i < regvar.numCaptures(); i++ )
704 name.append( regvar.cap( i ) );
706 // retrieve platform name
707 platName = QStringList::split( " ", name.join( " " ) ).join( " " );
708 platName = platName.replace( "Linux", "" ).replace( "linux", "" ).replace( "LINUX", "" ).stripWhiteSpace();
709 platName = platName.replace( "Welcome to", "" ).stripWhiteSpace();
710 platName = QStringList::split( " ", platName ).join( " " );
711 // retrieve platform version number
712 platVersion = regvar.cap( regvar.numCaptures() );
715 uname( &uname_data );
716 if ( QString( uname_data.machine ) == "x86_64" )
724 if ( !platName.isEmpty() ) vals.append( platName );
725 if ( !platVersion.isEmpty() ) vals.append( platVersion );
726 if ( !platArch.isEmpty() ) vals.append( platArch );
730 // ================================================================
732 * SALOME_InstallWizard::rootDirPath
733 * Get application root dir
735 // ================================================================
736 QString SALOME_InstallWizard::rootDirPath()
738 static QString rootDir;
739 if ( rootDir.isEmpty() ) {
740 QDir appDir( qApp->applicationDirPath() );
742 rootDir = appDir.absPath();
747 // ================================================================
749 * SALOME_InstallWizard::getPlatformBinPath
750 * Get platform binaries path
752 // ================================================================
753 QString SALOME_InstallWizard::getPlatformBinPath( const QString& plt ) const
755 return QDir::cleanDirPath( getBinPath() + "/" + QStringList::split( " ", plt ).join( "_" ) );
758 // ================================================================
760 * SALOME_InstallWizard::getXmlMap
761 * Creates a map of the supported operating systems and
762 * corresponding XML files.
764 // ================================================================
765 MapXmlFiles SALOME_InstallWizard::getXmlMap( const QString& aXmlFileName )
769 if ( !aXmlFileName.isEmpty() )
770 xmlList.append( QFileInfo( aXmlFileName ).absFilePath() );
772 QDir dir( rootDirPath() );
773 QStringList entries = dir.entryList( "*.xml", QDir::Files | QDir::Readable );
774 if ( entries.remove( "config.xml" ) )
775 entries.append( "config.xml" );
776 for ( uint i = 0; i < entries.count(); i++ )
777 xmlList.append( QDir( rootDirPath() ).filePath( entries[i] ) );
781 QDomDocument doc( "xml_doc" );
783 QDomNodeList nodeList;
786 QString platforms = "";
787 QStringList platList;
788 for ( uint i = 0; i < xmlList.count(); i++ ) {
789 file.setName( xmlList[i] );
790 if ( !doc.setContent( &file ) ) {
796 docElem = doc.documentElement();
797 nodeList = docElem.elementsByTagName( "config" );
798 if ( nodeList.count() == 0 )
800 node = nodeList.item( 0 );
801 if ( node.isElement() ) {
802 elem = node.toElement();
803 if ( elem.attribute( "platforms" ) ) {
804 platforms = elem.attribute( "platforms" ).stripWhiteSpace();
805 QStringList platList = QStringList::split( ",", platforms );
806 for ( uint j = 0; j < platList.count(); j++ ) {
807 QString platform = platList[j].stripWhiteSpace();
808 if ( !platform.isEmpty() && xmlMap.find( platform ) == xmlMap.end() )
809 xmlMap[ platList[j] ] = xmlList[i];
816 // ================================================================
818 * SALOME_InstallWizard::checkXmlAndPlatform
819 * Check XML file and current platform definition
821 // ================================================================
822 void SALOME_InstallWizard::getXmlAndPlatform()
825 if ( xmlFileName.isEmpty() ) {
826 xmlMap = getXmlMap();
827 if ( !curPlatform.isEmpty() ) {
828 // try to get XML file for current platform
829 if ( xmlMap.find( curPlatform ) != xmlMap.end() ) {
830 xmlFileName = xmlMap[ curPlatform ];
831 QFileInfo fibp( getPlatformBinPath( curPlatform ) );
832 if ( !fibp.isDir() ) {
833 warnMsg = tr( "Binaries are absent for current platform" );
835 platformsMap = xmlMap;
838 platformsMap = xmlMap;
839 warnMsg = tr( "Your Linux platform is not supported by this SALOME package" );
843 // get all supported platforms
844 platformsMap = xmlMap;
845 warnMsg = tr( "Installation Wizard can't identify target Linux platform" );
849 xmlMap = getXmlMap( xmlFileName );
850 if ( !curPlatform.isEmpty() ) {
851 // check that the user's XML file supports current platform
852 if ( xmlMap.find( curPlatform ) == xmlMap.end() ) {
853 platformsMap = getXmlMap();
854 MapXmlFiles::Iterator it;
855 for ( it = xmlMap.begin(); it != xmlMap.end(); ++it )
856 platformsMap.insert( it.key(), it.data(), true );
857 warnMsg = tr( "The given configuration file doesn't support your Linux platform" );
860 platformsMap = xmlMap;
864 // get all supported platforms
865 platformsMap = getXmlMap();
866 MapXmlFiles::Iterator it;
867 for ( it = xmlMap.begin(); it != xmlMap.end(); ++it )
868 platformsMap.insert( it.key(), it.data(), true );
869 warnMsg = tr( "Installation Wizard can't define your Linux platform" );
873 // ================================================================
875 * SALOME_InstallWizard::eventFilter
876 * Event filter, spies for Help window closing
878 // ================================================================
879 bool SALOME_InstallWizard::eventFilter( QObject* object, QEvent* event )
881 if ( object && object == helpWindow && event->type() == QEvent::Close )
883 return InstallWizard::eventFilter( object, event );
885 // ================================================================
887 * SALOME_InstallWizard::closeEvent
888 * Close event handler
890 // ================================================================
891 void SALOME_InstallWizard::closeEvent( QCloseEvent* ce )
893 if ( WarnDialog::isWarnDlgShown() ) {
897 if ( !exitConfirmed ) {
898 if ( QMessageBox::information( this,
900 tr( "Do you want to quit %1?" ).arg( getIWName() ),
910 exitConfirmed = true;
915 // ================================================================
917 * SALOME_InstallWizard::setupIntroPage
918 * Creates introduction page
920 // ================================================================
921 void SALOME_InstallWizard::setupIntroPage()
924 introPage = new QWidget( this, "IntroPage" );
925 QGridLayout* pageLayout = new QGridLayout( introPage );
926 pageLayout->setMargin( 0 ); pageLayout->setSpacing( 6 );
927 // create logo picture
928 logoLab = new QLabel( introPage );
929 logoLab->setPixmap( pixmap( pxBigLogo ) );
930 logoLab->setScaledContents( true );
931 logoLab->setFrameStyle( QLabel::Plain | QLabel::NoFrame );
932 logoLab->setAlignment( AlignCenter );
933 // create version box
934 QVBox* versionBox = new QVBox( introPage ); versionBox->setSpacing( 6 );
935 versionBox->setFrameStyle( QVBox::Panel | QVBox::Sunken );
936 QWidget* stretch1 = new QWidget( versionBox ); versionBox->setStretchFactor( stretch1, 5 );
937 versionLab = new QLabel( QString("%1 %2").arg( tr( "Version" ) ).arg(myVersion), versionBox );
938 versionLab->setAlignment( AlignCenter );
939 copyrightLab = new QLabel( myCopyright, versionBox );
940 copyrightLab->setAlignment( AlignCenter );
941 licenseLab = new QLabel( myLicense, versionBox );
942 licenseLab->setAlignment( AlignCenter );
943 QWidget* stretch2 = new QWidget( versionBox ); versionBox->setStretchFactor( stretch2, 5 );
945 info = new QLabel( introPage );
946 info->setText( tr( "This program will install <b>%1</b>."
947 "<br><br>The wizard will also help you to install all products "
948 "which are necessary for <b>%2</b> and setup "
949 "your environment.<br><br>Click <code>Cancel</code> button to abort "
950 "installation and quit. Click <code>Next</code> button to continue with the "
951 "installation program." ).arg( myCaption ).arg( myCaption ) );
952 info->setFrameStyle( QLabel::WinPanel | QLabel::Sunken );
953 info->setMargin( 6 );
954 info->setAlignment( WordBreak );
955 info->setMinimumWidth( 250 );
956 QPalette pal = info->palette();
957 pal.setColor( QColorGroup::Background, QApplication::palette().active().base() );
958 info->setPalette( pal );
959 info->setLineWidth( 2 );
961 pageLayout->addWidget( logoLab, 0, 0 );
962 pageLayout->addWidget( versionBox, 1, 0 );
963 pageLayout->addMultiCellWidget( info, 0, 1, 1, 1 );
964 pageLayout->setColStretch( 1, 5 );
965 pageLayout->setRowStretch( 1, 5 );
967 addPage( introPage, tr( "Introduction" ) );
969 // ================================================================
971 * SALOME_InstallWizard::setupTypePage
972 * Creates installation types page
974 // ================================================================
975 void SALOME_InstallWizard::setupTypePage()
978 typePage = new QWidget( this, "TypePage" );
979 QGridLayout* pageLayout = new QGridLayout( typePage );
980 pageLayout->setMargin( 0 ); pageLayout->setSpacing( 6 );
981 // create installation type button group
982 buttonGrp = new QButtonGroup( typePage );
983 buttonGrp->setFrameShape(QButtonGroup::NoFrame);
984 QGridLayout* buttonGrpLayout = new QGridLayout( buttonGrp );
985 buttonGrpLayout->setMargin( 0 ); buttonGrpLayout->setSpacing( 6 );
986 QSpacerItem* spacer1 = new QSpacerItem( 16, 50, QSizePolicy::Minimum, QSizePolicy::Expanding );
987 QSpacerItem* spacer2 = new QSpacerItem( 16, 50, QSizePolicy::Minimum, QSizePolicy::Expanding );
988 QLabel* selectLab = new QLabel( tr( "Select a type of the installation:" ), buttonGrp );
989 QSpacerItem* spacer3 = new QSpacerItem( 20, 20, QSizePolicy::Fixed, QSizePolicy::Minimum );
990 // ... 'install binaries' layout
991 QGridLayout* binLayout = new QGridLayout( 2, 2, 0 );
992 binBtn = new QRadioButton( tr( "Install binaries" ), buttonGrp );
993 QFont rbFont = binBtn->font();
994 rbFont.setBold( true );
995 binBtn->setFont( rbFont );
996 QSpacerItem* spacer4 = new QSpacerItem( 16, 16, QSizePolicy::Fixed, QSizePolicy::Minimum );
997 QLabel* binLab = new QLabel( tr( "- all the binaries and sources of the chosen SALOME modules will be installed.\n"
998 "- all the binaries of the chosen prerequisites will be installed." ),
1000 binLayout->addMultiCellWidget( binBtn, 0, 0, 0, 1 );
1001 binLayout->addItem ( spacer4, 1, 0 );
1002 binLayout->addWidget ( binLab, 1, 1 );
1003 // ... 'install sources' layout
1004 QGridLayout* srcLayout = new QGridLayout( 2, 2, 0 );
1005 srcBtn = new QRadioButton( tr( "Install sources" ), buttonGrp );
1006 srcBtn->setFont( rbFont );
1007 QSpacerItem* spacer5 = new QSpacerItem( 16, 16, QSizePolicy::Fixed, QSizePolicy::Minimum );
1008 QLabel* srcLab = new QLabel( tr( "- all the sources of the chosen modules and prerequisites will be installed without\ncompilation." ),
1010 srcLayout->addMultiCellWidget( srcBtn, 0, 0, 0, 1 );
1011 srcLayout->addItem ( spacer5, 1, 0 );
1012 srcLayout->addWidget ( srcLab, 1, 1 );
1013 // ... 'install sources and make compilation' layout
1014 QGridLayout* srcCompileLayout = new QGridLayout( 3, 3, 0 );
1015 srcCompileBtn = new QRadioButton( tr( "Install sources and make a compilation" ), buttonGrp );
1016 srcCompileBtn->setFont( rbFont );
1017 QSpacerItem* spacer6 = new QSpacerItem( 16, 16, QSizePolicy::Fixed, QSizePolicy::Minimum );
1018 QLabel* srcCompileLab1 = new QLabel( tr( "- all the sources of the chosen modules and prerequisites will be installed and\ncompiled." ),
1020 QLabel* srcCompileLab2 = new QLabel( tr( "Note:" ),
1022 QFont noteFont = srcCompileLab2->font();
1023 noteFont.setUnderline( true );
1024 srcCompileLab2->setFont( noteFont );
1025 srcCompileLab2->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Preferred ) );
1026 srcCompileLab2->setAlignment( Qt::AlignHCenter | Qt::AlignTop );
1027 QLabel* srcCompileLab3 = new QLabel( " " +
1028 tr( "it is a long time operation and it can take more than 24 hours depending\n on the computer." ),
1030 removeSrcBtn = new QCheckBox( tr( "Remove sources and temporary files after compilation" ), typePage );
1031 setAboutInfo( removeSrcBtn, tr( "Check this option if you want to remove sources of the products\nwith all the temporary files after build finishing" ) );
1032 removeSrcBtn->setChecked( false );
1033 removeSrcBtn->setEnabled( false );
1034 rmSrcPrevState = removeSrcBtn->isChecked();
1036 srcCompileLayout->addMultiCellWidget( srcCompileBtn, 0, 0, 0, 2 );
1037 srcCompileLayout->addMultiCell ( spacer6, 1, 2, 0, 0 );
1038 srcCompileLayout->addMultiCellWidget( srcCompileLab1, 1, 1, 1, 2 );
1039 srcCompileLayout->addWidget ( srcCompileLab2, 2, 1 );
1040 srcCompileLayout->addWidget ( srcCompileLab3, 2, 2 );
1041 srcCompileLayout->addMultiCellWidget( removeSrcBtn, 3, 3, 1, 2 );
1042 // layout widgets in the button group
1043 buttonGrpLayout->addItem ( spacer1, 0, 1 );
1044 buttonGrpLayout->addMultiCellWidget( selectLab, 1, 1, 0, 1 );
1045 buttonGrpLayout->addMultiCell ( spacer3, 2, 4, 0, 0 );
1046 buttonGrpLayout->addLayout ( binLayout, 2, 1 );
1047 buttonGrpLayout->addLayout ( srcLayout, 3, 1 );
1048 buttonGrpLayout->addLayout ( srcCompileLayout, 4, 1 );
1049 buttonGrpLayout->addItem ( spacer2, 5, 1 );
1050 // layout button group at the page
1051 pageLayout->addWidget( buttonGrp, 0, 0 );
1052 // connecting signals
1053 connect( buttonGrp, SIGNAL( clicked(int) ), this, SLOT ( onButtonGroup(int) ) );
1055 addPage( typePage, tr( "Installation type" ) );
1057 // ================================================================
1059 * SALOME_InstallWizard::setupPlatformPage
1060 * Creates platforms page, if necessary
1062 // ================================================================
1063 void SALOME_InstallWizard::setupPlatformPage()
1066 platformsPage = new QWidget( this, "PlatformsPage" );
1067 QGridLayout* pageLayout = new QGridLayout( platformsPage );
1068 pageLayout->setMargin( 0 ); pageLayout->setSpacing( 6 );
1069 // create warning labels
1070 QLabel* warnLab2 = new QLabel( tr( "WARNING!" ), platformsPage );
1071 warnLab2->setAlignment( Qt::AlignHCenter );
1072 QFont fnt = warnLab2->font();
1073 fnt.setBold( true );
1074 warnLab2->setFont( fnt );
1075 warnLab = new QLabel( warnMsg, platformsPage );
1076 warnLab->setAlignment( Qt::AlignHCenter | Qt::WordBreak );
1077 warnLab3 = new QLabel( tr( "If you want to proceed anyway, please select platform from the following list:" ),
1079 warnLab3->setAlignment( Qt::AlignHCenter | Qt::WordBreak );
1080 // create button group
1081 platBtnGrp = new QButtonGroup( platformsPage );
1082 platBtnGrp->setFrameShape(QButtonGroup::LineEditPanel);
1083 platBtnGrp->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Preferred ) );
1084 QVBoxLayout* platBtnGrpLayout = new QVBoxLayout( platBtnGrp );
1085 platBtnGrpLayout->setMargin( 11 ); platBtnGrpLayout->setSpacing( 6 );
1086 // create platforms radio-buttons
1088 MapXmlFiles::Iterator it;
1089 for ( it = platformsMap.begin(); it != platformsMap.end(); ++it ) {
1091 QRadioButton* rb = new QRadioButton( plat, platBtnGrp, plat );
1092 platBtnGrpLayout->addWidget( rb );
1095 QSpacerItem* spacer1 = new QSpacerItem( 16, 20, QSizePolicy::Minimum, QSizePolicy::Expanding );
1096 QSpacerItem* spacer2 = new QSpacerItem( 16, 20, QSizePolicy::Minimum, QSizePolicy::Expanding );
1098 // layout widgets on page
1099 pageLayout->addItem ( spacer1, 0, 0 );
1100 pageLayout->addWidget ( warnLab2, 1, 0 );
1101 pageLayout->addWidget ( warnLab, 2, 0 );
1102 pageLayout->addWidget ( warnLab3, 3, 0 );
1103 pageLayout->addItem ( spacer2, 4, 0 );
1104 pageLayout->addMultiCellWidget( platBtnGrp, 0, 4, 1, 1 );
1106 // connecting signals
1107 connect( platBtnGrp, SIGNAL( clicked(int) ), this, SLOT ( onButtonGroup(int) ) );
1110 addPage( platformsPage, tr( "Installation platform" ) );
1112 // ================================================================
1114 * SALOME_InstallWizard::setupDirPage
1115 * Creates directories page
1117 // ================================================================
1118 void SALOME_InstallWizard::setupDirPage()
1121 dirPage = new QWidget( this, "DirPage" );
1122 QGridLayout* pageLayout = new QGridLayout( dirPage );
1123 pageLayout->setMargin( 0 ); pageLayout->setSpacing( 6 );
1124 QSpacerItem* spacer1 = new QSpacerItem( 16, 50, QSizePolicy::Minimum, QSizePolicy::Expanding );
1125 QSpacerItem* spacer2 = new QSpacerItem( 16, 50, QSizePolicy::Minimum, QSizePolicy::Expanding );
1127 QGridLayout* targetLayout = new QGridLayout( 2, 2, 0 );
1128 QLabel* targetLab = new QLabel( tr( "Set a target directory to install SALOME platform:" ), dirPage );
1129 targetFolder = new QLineEdit( dirPage );
1130 targetBtn = new QPushButton( tr( "Browse..." ), dirPage );
1131 setAboutInfo( targetBtn, tr( "Click this button to browse\nthe installation directory" ) );
1132 targetLayout->addMultiCellWidget( targetLab, 0, 0, 0, 1 );
1133 targetLayout->addWidget ( targetFolder, 1, 0 );
1134 targetLayout->addWidget ( targetBtn, 1, 1 );
1135 // temporary directory
1136 QGridLayout* tempLayout = new QGridLayout( 2, 2, 0 );
1137 QLabel* tempLab = new QLabel( tr( "Set a directory that should be used for temporary SALOME files:" ), dirPage );
1138 tempFolder = new QLineEdit( dirPage );
1139 tempBtn = new QPushButton( tr( "Browse..." ), dirPage );
1140 setAboutInfo( tempBtn, tr( "Click this button to browse\nthe temporary directory" ) );
1141 tempLayout->addMultiCellWidget( tempLab, 0, 0, 0, 1 );
1142 tempLayout->addWidget ( tempFolder, 1, 0 );
1143 tempLayout->addWidget ( tempBtn, 1, 1 );
1144 // AKL: 13/08/07 - disable temporary directory setting in GUI ==>
1148 // AKL: 13/08/07 - disable temporary directory setting in GUI <==
1150 pageLayout->addItem ( spacer1, 0, 0 );
1151 pageLayout->addLayout( targetLayout, 1, 0 );
1152 pageLayout->addLayout( tempLayout, 2, 0 );
1153 pageLayout->addItem ( spacer2, 3, 0 );
1154 // connecting signals
1155 connect( targetFolder, SIGNAL( textChanged( const QString& ) ),
1156 this, SLOT( directoryChanged( const QString& ) ) );
1157 connect( targetBtn, SIGNAL( clicked() ),
1158 this, SLOT( browseDirectory() ) );
1159 connect( tempFolder, SIGNAL( textChanged( const QString& ) ),
1160 this, SLOT( directoryChanged( const QString& ) ) );
1161 connect( tempBtn, SIGNAL( clicked() ), this, SLOT( browseDirectory() ) );
1164 addPage( dirPage, tr( "Installation directory" ) );
1166 // ================================================================
1168 * SALOME_InstallWizard::setupProductsPage
1169 * Creates products page
1171 // ================================================================
1172 void SALOME_InstallWizard::setupProductsPage()
1175 productsPage = new QWidget( this, "ProductsPage" );
1176 QGridLayout* pageLayout = new QGridLayout( productsPage );
1177 pageLayout->setMargin( 0 ); pageLayout->setSpacing( 6 );
1179 // create left column widgets
1181 QVBoxLayout* leftBoxLayout = new QVBoxLayout;
1182 leftBoxLayout->setMargin( 0 ); leftBoxLayout->setSpacing( 6 );
1184 modulesView = new ProductsView( productsPage, "modulesView" );
1185 setAboutInfo( modulesView, tr( "The modules available for the installation" ) );
1186 modulesView->setColumnAlignment( 1, Qt::AlignRight );
1187 leftBoxLayout->addWidget( modulesView );
1188 // ... 'Installation with GUI' checkbox
1189 installGuiBtn = new QMyCheckBox( tr( "Installation with GUI" ), productsPage );
1190 setAboutInfo( installGuiBtn, tr( "Check this option if you want\nto install SALOME with GUI" ) );
1191 leftBoxLayout->addWidget( installGuiBtn );
1192 // ... prerequisites list
1193 prereqsView = new ProductsView( productsPage, "prereqsView" );
1194 prereqsView->renameColumn( 0, "Prerequisite" );
1195 setAboutInfo( prereqsView, tr( "The prerequisites that can be installed" ) );
1196 prereqsView->setColumnAlignment( 1, Qt::AlignRight );
1197 leftBoxLayout->addWidget( prereqsView );
1198 // ... 'Show/Hide prerequisites' button
1199 moreBtn = new QPushButton( tr( "Show prerequisites..." ), productsPage );
1200 setAboutInfo( moreBtn, tr( "Click to show list of prerequisites" ) );
1201 leftBoxLayout->addWidget( moreBtn );
1203 // create right column widgets
1206 productInfo = new QTextBrowser( productsPage );
1207 productInfo->setFrameShape( QFrame::LineEditPanel );
1208 productInfo->setPaletteBackgroundColor( productsPage->paletteBackgroundColor() );
1209 setAboutInfo( productInfo, tr( "Short information about the product being selected" ) );
1210 // ... disk space labels
1211 QLabel* reqLab1 = new QLabel( tr( "Disk space required:" ), productsPage );
1212 setAboutInfo( reqLab1, tr( "Total disk space required for the installation\nof the selected products" ) );
1213 requiredSize = new QLabel( productsPage );
1214 setAboutInfo( requiredSize, tr( "Total disk space required for the installation\nof the selected products" ) );
1215 requiredSize->setAlignment( Qt::AlignRight );
1216 QLabel* reqLab2 = new QLabel( tr( "Space for temporary files:" ), productsPage );
1217 setAboutInfo( reqLab2, tr( "Disk space required for the temporary files" ) );
1218 requiredTemp = new QLabel( productsPage );
1219 setAboutInfo( requiredTemp, tr( "Disk space required for the temporary files" ) );
1220 requiredTemp->setAlignment( Qt::AlignRight );
1221 QLabel* reqLab3 = new QLabel( tr( "Available disk space:" ), productsPage );
1222 setAboutInfo( reqLab3, tr( "Disk space available on the selected device" ) );
1223 availableSize = new QLabel( productsPage );
1224 setAboutInfo( availableSize, tr( "Disk space available on the selected device" ) );
1225 availableSize->setAlignment( Qt::AlignRight );
1226 // layout size widgets
1227 QGridLayout* sizeLayout = new QGridLayout; sizeLayout->setMargin( 0 ); sizeLayout->setSpacing( 6 );
1228 sizeLayout->addWidget( reqLab1, 0, 0 );
1229 sizeLayout->addWidget( requiredSize, 0, 1 );
1230 sizeLayout->addWidget( reqLab2, 1, 0 );
1231 sizeLayout->addWidget( requiredTemp, 1, 1 );
1232 sizeLayout->addWidget( reqLab3, 2, 0 );
1233 sizeLayout->addWidget( availableSize, 2, 1 );
1234 // ... 'single installation directory' check-boxes
1235 oneModDirBtn = new QMyCheckBox( tr( "Install modules to a single directory" ), productsPage );
1236 setAboutInfo( oneModDirBtn, tr( "Check this box if you want to install binaries of\nthe selected SALOME modules into a single directory" ) );
1237 oneProdDirBtn = new QMyCheckBox( tr( "Install prerequisites to a single directory" ), productsPage );
1238 setAboutInfo( oneProdDirBtn, tr( "Check this box if you want to install binaries of\nthe selected prerequisites into a single directory" ) );
1239 oneProdDirBtn->hide(); // temporarily! waiting for correct prerequisites availability
1240 QFrame* split_line = new QFrame( productsPage, "split_line" );
1241 split_line->setFrameStyle( QFrame::HLine | QFrame::Sunken );
1243 // layout common widgets
1244 pageLayout->addMultiCellLayout( leftBoxLayout, 0, 4, 0, 0 );
1245 pageLayout->addWidget ( productInfo, 0, 1 );
1246 pageLayout->addLayout ( sizeLayout, 1, 1 );
1247 pageLayout->addWidget ( split_line, 2, 1 );
1248 pageLayout->addWidget ( oneModDirBtn, 3, 1 );
1249 pageLayout->addWidget ( oneProdDirBtn, 4, 1 );
1252 addPage( productsPage, tr( "Choice of the products to be installed" ) );
1254 // connecting signals
1255 connect( modulesView, SIGNAL( selectionChanged() ),
1256 this, SLOT( onSelectionChanged() ) );
1257 connect( prereqsView, SIGNAL( selectionChanged() ),
1258 this, SLOT( onSelectionChanged() ) );
1259 connect( modulesView, SIGNAL( clicked ( QListViewItem * item ) ),
1260 this, SLOT( onSelectionChanged() ) );
1261 connect( prereqsView, SIGNAL( clicked ( QListViewItem * item ) ),
1262 this, SLOT( onSelectionChanged() ) );
1263 connect( modulesView, SIGNAL( itemToggled( QCheckListItem* ) ),
1264 this, SLOT( onItemToggled( QCheckListItem* ) ) );
1265 connect( prereqsView, SIGNAL( itemToggled( QCheckListItem* ) ),
1266 this, SLOT( onItemToggled( QCheckListItem* ) ) );
1267 connect( installGuiBtn, SIGNAL( toggled( bool ) ),
1268 this, SLOT( onInstallGuiBtn() ) );
1269 connect( moreBtn, SIGNAL( clicked() ), this, SLOT( onMoreBtn() ) );
1270 // start on default - non-advanced mode
1271 prereqsView->hide();
1273 // ================================================================
1275 * SALOME_InstallWizard::setupCheckPage
1276 * Creates prestart page
1278 // ================================================================
1279 void SALOME_InstallWizard::setupCheckPage()
1282 prestartPage = new QWidget( this, "PrestartPage" );
1283 QVBoxLayout* pageLayout = new QVBoxLayout( prestartPage );
1284 pageLayout->setMargin( 0 ); pageLayout->setSpacing( 6 );
1286 choices = new QTextEdit( prestartPage );
1287 choices->setReadOnly( true );
1288 choices->setTextFormat( RichText );
1289 choices->setUndoRedoEnabled ( false );
1290 setAboutInfo( choices, tr( "Information about the installation choice you have made" ) );
1291 choices->setPaletteBackgroundColor( prestartPage->paletteBackgroundColor() );
1292 choices->setMinimumHeight( 10 );
1294 pageLayout->addWidget( choices );
1295 pageLayout->setStretchFactor( choices, 5 );
1297 addPage( prestartPage, tr( "Check your choice" ) );
1299 // ================================================================
1301 * SALOME_InstallWizard::setupProgressPage
1302 * Creates progress page
1304 // ================================================================
1305 void SALOME_InstallWizard::setupProgressPage()
1308 progressPage = new QWidget( this, "progressPage" );
1309 QGridLayout* pageLayout = new QGridLayout( progressPage );
1310 pageLayout->setMargin( 0 ); pageLayout->setSpacing( 6 );
1312 splitter = new QSplitter( Vertical, progressPage );
1313 splitter->setOpaqueResize( true );
1314 // the parent for the widgets
1315 QWidget* widget = new QWidget( splitter );
1316 QGridLayout* layout = new QGridLayout( widget );
1317 layout->setMargin( 0 ); layout->setSpacing( 6 );
1318 // installation progress view box
1319 installInfo = new InstallInfo( widget );
1320 installInfo->setReadOnly( true );
1321 installInfo->setTextFormat( RichText );
1322 installInfo->setUndoRedoEnabled ( false );
1323 installInfo->setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Expanding ) );
1324 installInfo->setMinimumSize( 100, 10 );
1325 setAboutInfo( installInfo, tr( "Installation process output" ) );
1326 // parameters for the script
1327 parametersLab = new QLabel( tr( "Enter your answer here:" ), widget );
1328 passedParams = new QLineEdit ( widget );
1329 setAboutInfo( passedParams, tr( "Use this field to enter the answer\nfor the running script when it is necessary") );
1330 // VSR: 10/11/05 - disable answer mode ==>
1331 parametersLab->hide();
1332 passedParams->hide();
1333 // VSR: 10/11/05 - disable answer mode <==
1335 layout->addWidget( installInfo, 0, 0 );
1336 layout->addWidget( parametersLab, 1, 0 );
1337 layout->addWidget( passedParams, 2, 0 );
1338 layout->addRowSpacing( 3, 6 );
1339 // the parent for the widgets
1340 widget = new QWidget( splitter );
1341 layout = new QGridLayout( widget );
1342 layout->setMargin( 0 ); layout->setSpacing( 6 );
1343 // installation results view box
1344 QLabel* resultLab = new QLabel( tr( "Installation Status:" ), widget );
1345 progressView = new ProgressView( widget );
1346 progressView->setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Expanding ) );
1347 progressView->setMinimumSize( 100, 10 );
1348 // possibility to ignore all errors
1349 ignoreErrCBox = new QCheckBox( tr( "Ignore errors" ), widget );
1350 setAboutInfo( ignoreErrCBox, tr( "Check this option if you want to proceed installation \nprocess even there will be some errors" ) );
1351 ignoreErrCBox->setChecked( false );
1352 // product installation status bar
1353 statusLab = new QLabel( widget );
1354 statusLab->setFrameShape( QButtonGroup::LineEditPanel );
1355 setAboutInfo( progressView, tr( "Installation status on the selected products" ) );
1357 layout->addRowSpacing( 0, 6 );
1358 layout->addWidget( resultLab, 1, 0 );
1359 layout->addWidget( progressView, 2, 0 );
1360 layout->addWidget( ignoreErrCBox, 3, 0 );
1361 layout->addWidget( statusLab, 4, 0 );
1363 pageLayout->addWidget( splitter, 0, 0 );
1365 addPage( progressPage, tr( "Installation progress" ) );
1367 connect( passedParams, SIGNAL( returnPressed() ), this, SLOT( onReturnPressed() ) ) ;
1369 // ================================================================
1371 * SALOME_InstallWizard::setupReadmePage
1372 * Creates readme page
1374 // ================================================================
1375 void SALOME_InstallWizard::setupReadmePage()
1378 readmePage = new QWidget( this, "readmePage" );
1379 QVBoxLayout* pageLayout = new QVBoxLayout( readmePage );
1380 pageLayout->setMargin( 0 ); pageLayout->setSpacing( 6 );
1381 // README info text box
1382 readme = new QTextEdit( readmePage );
1383 readme->setReadOnly( true );
1384 readme->setTextFormat( PlainText );
1385 readme->setFont( QFont( "Fixed", 12 ) );
1386 readme->setUndoRedoEnabled ( false );
1387 setAboutInfo( readme, tr( "README information" ) );
1388 readme->setPaletteBackgroundColor( readmePage->paletteBackgroundColor() );
1389 readme->setMinimumHeight( 10 );
1391 pageLayout->addWidget( readme );
1392 pageLayout->setStretchFactor( readme, 5 );
1394 // Operation buttons
1395 QHBoxLayout* hLayout = new QHBoxLayout( -1, "finishButtons" );
1396 hLayout->setMargin( 0 ); hLayout->setSpacing( 6 );
1397 hLayout->addStretch();
1398 pageLayout->addLayout( hLayout );
1400 // loading README file
1401 QString readmeFile = QDir( rootDirPath() ).filePath( "README" );
1403 if ( readFile( readmeFile, text ) )
1404 readme->setText( text );
1406 readme->setText( tr( "README file has not been found" ) );
1409 addPage( readmePage, tr( "Finish installation" ) );
1411 // ================================================================
1413 * SALOME_InstallWizard::showChoiceInfo
1414 * Displays choice info
1416 // ================================================================
1417 void SALOME_InstallWizard::showChoiceInfo()
1421 long totSize, tempSize;
1422 checkSize( &totSize, &tempSize );
1426 text += tr( "Current Linux platform" )+ ": <b>" + (!curPlatform.isEmpty() ? curPlatform : QString( "Unknown" )) + "</b><br>";
1427 if ( !refPlatform.isEmpty() )
1428 text += tr( "Reference Linux platform" ) + ": <b>" + refPlatform + "</b><br>";
1431 text += tr( "Target directory:" ) + " <b>" + QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() ) + "</b><br>";
1432 text += tr( "Temporary directory:" ) + " <b>" + QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + "</b><br>";
1435 text += tr( "SALOME modules to be installed" ) + ":<ul>";
1436 QCheckListItem* item = (QCheckListItem*)( modulesView->firstChild() );
1438 if ( productsMap.contains( item ) ) {
1439 if ( item->isOn() ) {
1440 text += "<li><b>" + item->text() + "</b><br>";
1444 item = (QCheckListItem*)( item->nextSibling() );
1446 if ( nbProd == 0 ) {
1447 text += "<li><b>" + tr( "none" ) + "</b><br>";
1451 text += tr( "Prerequisites to be installed" ) + ":<ul>";
1452 item = (QCheckListItem*)( prereqsView->firstChild() );
1454 if ( productsMap.contains( item ) ) {
1455 if ( item->isOn() ) {
1456 text += "<li><b>" + item->text() + " " + productsMap[ item ].getVersion() + "</b><br>";
1460 item = (QCheckListItem*)( item->nextSibling() );
1462 if ( nbProd == 0 ) {
1463 text += "<li><b>" + tr( "none" ) + "</b><br>";
1466 text += tr( "Total disk space required:" ) + " <b>" + QString::number( totSize ) + " KB</b><br>" ;
1467 text += tr( "Space for temporary files required:" ) + " <b>" + QString::number( tempSize ) + " KB</b><br>" ;
1468 choices->setText( text );
1470 // ================================================================
1472 * SALOME_InstallWizard::acceptData
1473 * Validates page when <Next> button is clicked
1475 // ================================================================
1476 bool SALOME_InstallWizard::acceptData( const QString& pageTitle )
1479 QWidget* aPage = InstallWizard::page( pageTitle );
1480 if ( aPage == typePage ) {
1481 // installation type page
1483 this->setAppropriate( platformsPage, false );
1484 if ( installType == Binaries ) { // 'Binary' installation type
1485 // check binaries directory
1486 QFileInfo fib( QDir::cleanDirPath( getBinPath() ) );
1487 if ( !fib.isDir() ) {
1488 QMessageBox::warning( this,
1490 tr( "The directory %1 doesn't exist.\n"
1491 "This directory must contains another one directory with binary archives for current platform.").arg( fib.absFilePath() ),
1493 QMessageBox::NoButton,
1494 QMessageBox::NoButton );
1497 if ( platformsMap.find( curPlatform ) == platformsMap.end() ) {
1498 // Unknown platform case
1499 QString aMsg = warnMsg + tr( ".\nBy default the universal binary package will be installed." );
1500 aMsg += tr( "\nIf you want to select another one, please use the following list:" );
1501 warnLab->setText( aMsg );
1503 this->setAppropriate( platformsPage, true );
1506 // Supported platform case
1507 QFileInfo fibp( getPlatformBinPath( curPlatform ) );
1508 if ( !fibp.isDir() ) {
1509 warnLab->setText( tr( "Binaries are absent for current platform." ) );
1510 this->setAppropriate( platformsPage, true );
1514 // check sources directory
1515 QFileInfo fis( QDir::cleanDirPath( getSrcPath() ) );
1517 if ( QMessageBox::warning( this,
1519 tr( "The directory %1 doesn't exist.\n"
1520 "This directory must contains sources archives.\n"
1521 "Continue?" ).arg( fis.absFilePath() ),
1524 QString::null, 1, 1 ) == 1 )
1527 else { // 'Source' or 'Compile' installation type
1528 // check sources directory
1529 QFileInfo fis( QDir::cleanDirPath( getSrcPath() ) );
1530 if ( !fis.isDir() ) {
1531 QMessageBox::warning( this,
1533 tr( "The directory %1 doesn't exist.\n"
1534 "This directory must contains sources archives.\n" ).arg( fis.absFilePath() ),
1536 QMessageBox::NoButton,
1537 QMessageBox::NoButton );
1540 else if ( !QDir( fis.filePath(), "*.tar.gz" ).count() ) {
1541 QMessageBox::warning( this,
1543 tr( "The directory %1 doesn't contain source archives.\n" ).arg( fis.absFilePath() ),
1545 QMessageBox::NoButton,
1546 QMessageBox::NoButton );
1549 if ( platformsMap.find( curPlatform ) == platformsMap.end() ) {
1550 QString aMsg = warnMsg + ".";
1551 if ( installType == Compile )
1552 aMsg = warnMsg + tr( " and compilation is not tested on this one." );
1553 warnLab->setText( aMsg );
1554 this->setAppropriate( platformsPage, true );
1559 else if ( aPage == platformsPage ) {
1560 // installation platform page
1561 if ( platBtnGrp->id( platBtnGrp->selected() ) == -1 ) {
1562 QMessageBox::warning( this,
1564 tr( "Select installation platform before" ),
1566 QMessageBox::NoButton,
1567 QMessageBox::NoButton );
1570 else if ( installType == Binaries ) {
1571 QString aPlatform = platBtnGrp->selected()->name();
1572 QFileInfo fib( getPlatformBinPath( aPlatform ) );
1573 if ( !fib.isDir() ) {
1574 QMessageBox::warning( this,
1576 tr( "The directory %1 doesn't exist.\n"
1577 "This directory must contains binary archives.\n" ).arg( fib.absFilePath() ),
1579 QMessageBox::NoButton,
1580 QMessageBox::NoButton );
1583 else if ( QDir( fib.filePath(), "*.tar.gz" ).count() == 0 ) {
1584 QMessageBox::warning( this,
1586 tr( "The directory %1 doesn't contain binary archives.\n" ).arg( fib.absFilePath() ),
1588 QMessageBox::NoButton,
1589 QMessageBox::NoButton );
1595 else if ( aPage == dirPage ) {
1596 // installation directory page
1597 // ########## check target and temp directories (existence and available disk space)
1599 QString targetDir = QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() );
1600 QString tempDir = QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() );
1601 // check target directory
1602 if ( targetDir.isEmpty() ) {
1603 QMessageBox::warning( this,
1605 tr( "Please, enter valid target directory path" ),
1607 QMessageBox::NoButton,
1608 QMessageBox::NoButton );
1611 QFileInfo fi( QDir::cleanDirPath( targetDir ) );
1612 if ( !fi.isDir() ) {
1614 QMessageBox::warning( this,
1616 tr( "The directory %1 doesn't exist.\n"
1617 "Create directory?" ).arg( fi.absFilePath() ),
1620 QMessageBox::NoButton ) == QMessageBox::Yes;
1623 if ( !makeDir( fi.absFilePath(), tmpstr ) ) {
1624 QMessageBox::critical( this,
1626 tr( "Can't create the directory\n%1").arg( fi.absFilePath() ),
1628 QMessageBox::NoButton,
1629 QMessageBox::NoButton );
1633 if ( !fi.isDir() ) {
1634 QMessageBox::warning( this,
1636 tr( "%1 is not a directory.\n"
1637 "Please, enter valid target directory path" ).arg( fi.absFilePath() ),
1639 QMessageBox::NoButton,
1640 QMessageBox::NoButton );
1643 if ( !fi.isWritable() ) {
1644 QMessageBox::warning( this,
1646 tr( "The directory %1 is not writable.\n"
1647 "Please, enter valid target directory path or change permissions" ).arg( fi.absFilePath() ),
1649 QMessageBox::NoButton,
1650 QMessageBox::NoButton );
1653 if ( hasSpace( fi.absFilePath() ) &&
1654 QMessageBox::warning( this,
1656 tr( "The target directory contains space symbols.\n"
1657 "This may cause problems with compiling or installing of products.\n\n"
1658 "Do you want to continue?"),
1661 QMessageBox::NoButton ) == QMessageBox::No ) {
1664 // check temp directory
1665 if ( tempDir.isEmpty() ) {
1666 QMessageBox::warning( this,
1668 tr( "Please, enter valid temporary directory path" ),
1670 QMessageBox::NoButton,
1671 QMessageBox::NoButton );
1674 QFileInfo fit( QDir::cleanDirPath( tempDir ) );
1675 if ( !makeDir( fit.absFilePath() + TEMPDIRNAME, tmpCreated ) ) {
1676 QMessageBox::critical( this,
1678 tr( "Can't use temporary directory.\nCheck permissions for the %1 directory.").arg( fit.absFilePath() ),
1680 QMessageBox::NoButton,
1681 QMessageBox::NoButton );
1686 else if ( aPage == productsPage ) {
1688 // ########## check if any products are selected to be installed
1689 long totSize, tempSize;
1690 bool anySelected = checkSize( &totSize, &tempSize );
1691 if ( installType == Compile && removeSrcBtn->isOn() ) {
1692 totSize += tempSize;
1694 if ( !anySelected ) {
1695 QMessageBox::warning( this,
1697 tr( "Select one or more products to install" ),
1699 QMessageBox::NoButton,
1700 QMessageBox::NoButton );
1703 // run script that checks available disk space for installing of products // returns 1 in case of error
1704 QDir rd( rootDirPath() );
1705 QFileInfo fi( QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() ) );
1707 script << QUOTE( rd.filePath( "config_files/checkSize.sh" ) );
1708 script << QUOTE( fi.absFilePath() ) << QString::number( totSize );
1709 ___MESSAGE___( "script = " << script.script().latin1() );
1710 if ( system( script.script().latin1() ) ) {
1711 QMessageBox::critical( this,
1712 tr( "Out of space" ),
1713 tr( "There is no available disk space for installing of selected products" ),
1715 QMessageBox::NoButton,
1716 QMessageBox::NoButton );
1719 // AKL: 13/08/07 - skip tmp disk space checking (all files are unpacked into installation directory) ==>
1721 // run script that check available disk space for temporary files
1722 // returns 1 in case of error
1723 QFileInfo fit( QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) );
1725 tscript << QUOTE( rd.filePath( "config_files/checkSize.sh" ) );
1726 tscript << QUOTE( fit.absFilePath() ) << QString::number( tempSize );
1727 ___MESSAGE___( "script = " << tscript.script().latin1() );
1728 if ( system( tscript.script().latin1() ) ) {
1729 QMessageBox::critical( this,
1730 tr( "Out of space" ),
1731 tr( "There is no available disk space for the temporary files" ),
1733 QMessageBox::NoButton,
1734 QMessageBox::NoButton );
1738 // AKL: 13/08/07 - skip tmp disk space checking (all files are unpacked into installation directory) <==
1740 // ########## check installation scripts
1741 QCheckListItem* item;
1742 ProductsView* prodsView = modulesView;
1743 for ( int i = 0; i < 2; i++ ) {
1744 item = (QCheckListItem*)( prodsView->firstChild() );
1746 if ( productsMap.contains( item ) && item->isOn() ) {
1747 // check installation script definition
1748 if ( item->text(2).isEmpty() || item->text(2).isNull() ) {
1749 QMessageBox::warning( this,
1751 tr( "The installation script for %1 is not defined.").arg(item->text(0)),
1753 QMessageBox::NoButton,
1754 QMessageBox::NoButton );
1755 if ( !moreMode ) onMoreBtn();
1756 QListView* listView = item->listView();
1757 listView->setCurrentItem( item );
1758 listView->setSelected( item, true );
1759 listView->ensureItemVisible( item );
1762 // check installation script existence
1764 QDir rd( rootDirPath() );
1765 QFileInfo fi( rd.filePath( QString( "config_files/%1" ).arg( item->text(2) ) ) );
1766 if ( !fi.exists() || !fi.isExecutable() ) {
1767 QMessageBox::warning( this,
1769 tr( "The script %1 required for %2 doesn't exist or doesn't have execute permissions.").arg(fi.filePath()).arg(item->text(0)),
1771 QMessageBox::NoButton,
1772 QMessageBox::NoButton );
1773 if ( !moreMode ) onMoreBtn();
1774 QListView* listView = item->listView();
1775 listView->setCurrentItem( item );
1776 listView->setSelected( item, true );
1777 listView->ensureItemVisible( item );
1781 // check installation scripts dependencies
1782 QStringList dependOn = productsMap[ item ].getDependancies();
1783 QString version = productsMap[ item ].getVersion();
1784 for ( int i = 0; i < (int)dependOn.count(); i++ ) {
1785 QCheckListItem* depitem = findItem( dependOn[ i ] );
1787 QMessageBox::warning( this,
1789 tr( "%1 is required for %2 %3 installation.\n"
1790 "This product is missing in the configuration file %4.").arg(dependOn[ i ]).arg(item->text(0)).arg(version).arg(xmlFileName),
1792 QMessageBox::NoButton,
1793 QMessageBox::NoButton );
1798 item = (QCheckListItem*)( item->nextSibling() );
1800 prodsView = prereqsView;
1802 // return true; // return in order to avoid default postValidateEvent() action
1804 return InstallWizard::acceptData( pageTitle );
1806 // ================================================================
1808 * SALOME_InstallWizard::checkSize
1809 * Calculates disk space required for the installation
1811 // ================================================================
1812 bool SALOME_InstallWizard::checkSize( long* totSize, long* tempSize )
1814 long tots = 0, temps = 0;
1818 MapProducts::Iterator mapIter;
1819 for ( mapIter = productsMap.begin(); mapIter != productsMap.end(); ++mapIter ) {
1820 QCheckListItem* item = mapIter.key();
1821 Dependancies dep = mapIter.data();
1822 if ( !item->isOn() )
1824 tots += ( QStringList::split( " ", item->text(1) )[0] ).toLong();
1825 maxSrcTmp = max( maxSrcTmp, dep.getSize( Compile ) - dep.getSize( Binaries ) );
1826 temps += dep.getTempSize( installType );
1831 if ( installType == Compile && removeSrcBtn->isOn() )
1836 return ( nbSelected > 0 );
1838 // ================================================================
1840 * SALOME_InstallWizard::updateAvailableSpace
1841 * Slot to update 'Available disk space' field
1843 // ================================================================
1844 void SALOME_InstallWizard::updateAvailableSpace()
1846 if ( diskSpaceProc->normalExit() )
1847 availableSize->setText( diskSpaceProc->readLineStdout() + " KB");
1849 // ================================================================
1851 * SALOME_InstallWizard::runModifyLaFiles
1852 * Run the modification of SALOME *.la files
1854 // ================================================================
1855 void SALOME_InstallWizard::runModifyLaFiles()
1857 modifyLaProc->clearArguments();
1858 // ... update status label
1859 statusLab->setText( tr( "Modification of *.la files of SALOME modules..." ) );
1860 // set process arguments
1861 modifyLaProc->setWorkingDirectory( QDir( rootDirPath() ).filePath( "config_files" ) );
1862 modifyLaProc->addArgument( "modifyLaFiles.sh" );
1863 modifyLaProc->addArgument( "modify_la_files" );
1864 modifyLaProc->addArgument( QDir::cleanDirPath( QFileInfo( targetFolder->text().stripWhiteSpace() ).absFilePath() ) );
1866 if ( !modifyLaProc->start() )
1867 ___MESSAGE___( "Error: process could not start!" );
1869 // ================================================================
1871 * SALOME_InstallWizard::checkModifyLaResult
1872 * Slot to take result of modification SALOME *.la files
1874 // ================================================================
1875 void SALOME_InstallWizard::checkModifyLaResult()
1877 if ( modifyLaProc->normalExit() && modifyLaProc->exitStatus() == 1 )
1880 // abort of the current installation
1882 statusLab->setText( tr( "Installation has been aborted" ) );
1883 QMessageBox::critical( this,
1885 tr( "Modification of *.la SALOME files has not been completed."),
1887 QMessageBox::NoButton,
1888 QMessageBox::NoButton );
1889 // enable <Next> button
1890 setNextEnabled( true );
1891 doPostActions( tr( "&Start" ), tr( "Start installation process" ) );
1892 connect( this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
1893 // enable <Back> button
1894 setBackEnabled( true );
1897 // ================================================================
1899 * SALOME_InstallWizard::runCheckFLib
1900 * Run the Fortran and other required libraries checking
1902 // ================================================================
1903 void SALOME_InstallWizard::runCheckFLib()
1905 // Check Fortran libraries
1906 checkFLibProc->clearArguments();
1907 // ... update status label
1908 statusLab->setText( tr( "Check Fortran and other required libraries..." ) );
1909 // ... search "not found" libraries
1910 checkFLibProc->setWorkingDirectory( QDir( rootDirPath() ).filePath( "config_files" ) );
1911 checkFLibProc->addArgument( "checkFortran.sh" );
1912 checkFLibProc->addArgument( "find_libraries" );
1913 checkFLibProc->addArgument( QDir::cleanDirPath( QFileInfo( targetFolder->text().stripWhiteSpace() ).absFilePath() ) );
1915 if ( !checkFLibProc->start() )
1916 ___MESSAGE___( "Error: process could not start!" );
1918 // ================================================================
1920 * SALOME_InstallWizard::checkFLibResult
1921 * Slot to take result of Fortran and other required libraries checking
1923 // ================================================================
1924 void SALOME_InstallWizard::checkFLibResult()
1926 if ( checkFLibProc->normalExit() && checkFLibProc->exitStatus() == 1 ) {
1927 QStringList notFoundLibsList, notFoundOptLibsList;
1928 QString record = "";
1929 QStringList prefOptLibs = getOptionalLibs();
1930 // create list of strings with all 'not found' libraries
1931 while ( checkFLibProc->canReadLineStdout() ) {
1932 record = checkFLibProc->readLineStdout().stripWhiteSpace();
1933 if ( !record.isEmpty() ) {
1934 record = QStringList::split( " ", record )[0];
1935 if ( !notFoundLibsList.contains( record ) &&
1936 !notFoundOptLibsList.contains( record ) ) {
1937 bool isOptional = false;
1938 QStringList::Iterator it_opt;
1939 for ( it_opt = prefOptLibs.begin(); it_opt != prefOptLibs.end(); ++it_opt )
1940 if ( record.startsWith( (*it_opt).stripWhiteSpace(), false ) ) {
1944 isOptional ? notFoundOptLibsList.append( record ) \
1945 : notFoundLibsList.append( record );
1949 QString msg = tr( "Some libraries are absent!<br><br>" );
1950 if ( !notFoundLibsList.isEmpty() ) {
1951 msg += tr( "One or several <b>mandatory</b> libraries listed below are not found. SALOME <u>may not work</u> properly.<br>" );
1952 msg += notFoundLibsList.join( "<br>" );
1955 if ( !notFoundOptLibsList.isEmpty() ) {
1956 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>" );
1957 msg += notFoundOptLibsList.join( "<br>" );
1959 if ( !notFoundLibsList.isEmpty() )
1960 QMessageBox::warning( this,
1964 QMessageBox::NoButton,
1965 QMessageBox::NoButton );
1966 else if ( !notFoundOptLibsList.isEmpty() )
1967 QMessageBox::information( this,
1968 tr( "Information" ),
1971 QMessageBox::NoButton,
1972 QMessageBox::NoButton );
1974 // Update GUI and check installation errors
1975 completeInstallation();
1977 // ================================================================
1979 * SALOME_InstallWizard::updateSizeColumn
1980 * Sets required size for each product according to
1981 * installation type and 'Remove SRC & TMP' checkbox state
1983 // ================================================================
1984 void SALOME_InstallWizard::updateSizeColumn()
1987 bool removeSrc = removeSrcBtn->isChecked();
1988 MapProducts::Iterator mapIter;
1989 for ( mapIter = productsMap.begin(); mapIter != productsMap.end(); ++mapIter ) {
1990 QCheckListItem* item = mapIter.key();
1991 Dependancies dep = mapIter.data();
1992 // get required size for current product
1993 long binSize = dep.getSize( Binaries );
1994 long srcSize = dep.getSize( Sources );
1995 long bldSize = dep.getSize( Compile );
1996 InstallationType instType = getInstType();
1997 if ( instType == Binaries ) {
1998 if ( dep.getType() == "component" )
1999 prodSize = binSize + srcSize;
2001 prodSize = ( binSize != 0 ? binSize : srcSize );
2003 else if ( instType == Sources )
2007 prodSize = ( binSize != 0 ? binSize : srcSize );
2009 prodSize = ( bldSize != 0 ? bldSize : srcSize );
2011 // fill in 'Size' field
2012 item->setText( 1, QString::number( prodSize )+" KB" );
2015 // ================================================================
2017 * SALOME_InstallWizard::checkProductPage
2018 * Checks products page validity (directories and products selection) and
2019 * enabled/disables "Next" button for the Products page
2021 // ================================================================
2022 void SALOME_InstallWizard::checkProductPage()
2024 if ( this->currentPage() != productsPage )
2026 long tots = 0, temps = 0;
2027 // check if any product is selected;
2028 bool isAnyProductSelected = checkSize( &tots, &temps );
2030 // update required size information
2031 requiredSize->setText( QString::number( tots ) + " KB");
2032 requiredTemp->setText( QString::number( temps ) + " KB");
2034 // update available size information
2035 QFileInfo fi( QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() ) );
2036 if ( fi.exists() ) {
2037 diskSpaceProc->clearArguments();
2038 diskSpaceProc->setWorkingDirectory( QDir( rootDirPath() ).filePath( "config_files" ) );
2039 diskSpaceProc->addArgument( "diskSpace.sh" );
2040 diskSpaceProc->addArgument( fi.absFilePath() );
2042 diskSpaceProc->start();
2045 // enable/disable "Next" button
2046 setNextEnabled( productsPage, isAnyProductSelected );
2048 // ================================================================
2050 * SALOME_InstallWizard::setPrerequisites
2051 * Sets the product and all products this one depends on to be checked ( recursively )
2053 // ================================================================
2054 void SALOME_InstallWizard::setPrerequisites( QCheckListItem* item )
2056 if ( !productsMap.contains( item ) )
2058 if ( !item->isOn() )
2060 // get all prerequisites
2061 QStringList dependOn = productsMap[ item ].getDependancies();
2062 // install SALOME without GUI case
2063 if ( installGuiBtn->state() != QButton::On &&
2064 woGuiModules.find( item->text(0) ) != woGuiModules.end() &&
2065 woGuiModules[item->text(0)] == True ) {
2066 dependOn.remove( "GUI" );
2068 // setting prerequisites
2069 for ( int i = 0; i < (int)dependOn.count(); i++ ) {
2070 MapProducts::Iterator itProd;
2071 for ( itProd = productsMap.begin(); itProd != productsMap.end(); ++itProd ) {
2072 if ( itProd.data().getName() == dependOn[ i ] ) {
2073 if ( itProd.data().getType() == "component" && !itProd.key()->isOn() )
2074 itProd.key()->setOn( true );
2075 else if ( itProd.data().getType() == "prerequisite" ) {
2076 itProd.key()->setOn( true );
2077 itProd.key()->setEnabled( false );
2084 // ================================================================
2086 * SALOME_InstallWizard::unsetPrerequisites
2087 * Unsets all modules which depend of the unchecked product ( recursively )
2089 // ================================================================
2090 void SALOME_InstallWizard::unsetPrerequisites( QCheckListItem* item )
2092 if ( !productsMap.contains( item ) )
2097 // uncheck dependent products
2098 QString itemName = productsMap[ item ].getName();
2099 MapProducts::Iterator itProd;
2100 for ( itProd = productsMap.begin(); itProd != productsMap.end(); ++itProd ) {
2101 if ( itProd.data().getType() == productsMap[ item ].getType() ) {
2102 QStringList dependOn = itProd.data().getDependancies();
2103 for ( int i = 0; i < (int)dependOn.count(); i++ ) {
2104 if ( dependOn[ i ] == itemName ) {
2105 if ( itProd.key()->isOn() ) {
2106 itProd.key()->setOn( false );
2113 // uncheck prerequisites
2115 // cout << "item name = " << productsMap[ item ].getName() << endl;
2116 QStringList dependOnList = productsMap[ item ].getDependancies();
2117 for ( int j = 0; j < (int)dependOnList.count(); j++ ) {
2119 MapProducts::Iterator itProd1;
2120 for ( itProd1 = productsMap.begin(); itProd1 != productsMap.end(); ++itProd1 ) {
2121 if ( itProd1.data().getName() == dependOnList[ j ] ) {
2122 if ( itProd1.data().getType() == "prerequisite" ) {
2123 MapProducts::Iterator itProd2;
2124 for ( itProd2 = productsMap.begin(); itProd2 != productsMap.end(); ++itProd2 ) {
2125 if ( itProd2.key()->isOn() ) {
2126 QStringList prereqsList = productsMap[ itProd2.key() ].getDependancies();
2127 for ( int k = 0; k < (int)prereqsList.count(); k++ ) {
2128 if ( prereqsList[ k ] == itProd1.data().getName() ) {
2135 if ( nbDependents == 0 ) {
2136 itProd1.key()->setEnabled( true );
2137 itProd1.key()->setOn( false );
2145 // ================================================================
2147 * SALOME_InstallWizard::launchScript
2148 * Runs installation script
2150 // ================================================================
2151 void SALOME_InstallWizard::launchScript()
2153 // try to find product being processed now
2154 QString prodProc = progressView->findStatus( Processing );
2155 if ( !prodProc.isNull() ) {
2156 ___MESSAGE___( "Found <Processing>: " );
2158 // if found - set status to "completed"
2159 progressView->setStatus( prodProc, Completed );
2160 // ... clear status label
2162 // ... and call this method again
2166 // else try to find next product which is not processed yet
2167 prodProc = progressView->findStatus( Waiting );
2168 if ( !prodProc.isNull() ) {
2169 ___MESSAGE___( "Found <Waiting>: " << prodProc.latin1() );
2170 // if found - set status to "processed" and run script
2171 progressView->setStatus( prodProc, Processing );
2172 progressView->ensureVisible( prodProc );
2174 QCheckListItem* item = 0;
2175 // fill in script parameters
2176 shellProcess->clearArguments();
2178 shellProcess->setWorkingDirectory( QDir( rootDirPath() ).filePath( "config_files" ) );
2179 if ( !extraProducts.contains( prodProc ) ) {
2180 item = findItem( prodProc );
2181 shellProcess->addArgument( item->text(2) );
2184 shellProcess->addArgument( extraProducts[ prodProc ] );
2186 // ... get folder with binaries
2187 QString OS = getPlatform();
2188 if ( refPlatform.isEmpty() && platformsMap.find( curPlatform ) == platformsMap.end() )
2189 OS = commonPlatform;
2190 QString binDir = getPlatformBinPath( OS );
2192 QString tmpFolder = QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + TEMPDIRNAME;
2193 //if( !tempFolder->isEnabled() )
2194 // tmpFolder = "/tmp";
2196 // ... not install : try to find preinstalled
2197 if ( notInstall.contains( prodProc ) || prodProc == "gcc" ) {
2198 shellProcess->addArgument( "try_preinstalled" );
2199 shellProcess->addArgument( QFileInfo( tmpFolder ).absFilePath() );
2200 shellProcess->addArgument( QDir( rootDirPath() ).filePath( "Products" ) );
2201 statusLab->setText( tr( "Collecting environment for '" ) + prodProc + "'..." );
2204 else if ( installType == Binaries ) {
2205 shellProcess->addArgument( "install_binary" );
2206 shellProcess->addArgument( QFileInfo( tmpFolder ).absFilePath() );
2207 shellProcess->addArgument( binDir );
2208 statusLab->setText( tr( "Installing '" ) + prodProc + "'..." );
2210 // ... sources or sources_and_compilation ?
2212 shellProcess->addArgument( installType == Sources ? "install_source" :
2213 "install_source_and_build" );
2214 shellProcess->addArgument( QFileInfo( tmpFolder ).absFilePath() );
2215 shellProcess->addArgument( QDir::cleanDirPath( getSrcPath() ) );
2216 statusLab->setText( tr( "Installing '" ) + prodProc + "'..." );
2218 // ... target folder
2219 QString tgtFolder = QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() );
2220 shellProcess->addArgument( QFileInfo( tgtFolder ).absFilePath() );
2221 // ... list of all products
2222 QString depproducts = getAllProducts(productsMap);
2223 depproducts.prepend( QStringList( extraProducts.keys() ).join(" ") + " " );
2224 ___MESSAGE___( "Dependancies"<< depproducts.latin1() );
2225 shellProcess->addArgument( depproducts );
2226 // ... product name - currently installed product
2227 if ( !extraProducts.contains( prodProc ) )
2228 shellProcess->addArgument( item->text(0) );
2230 shellProcess->addArgument( prodProc );
2231 // ... list of products being installed
2232 shellProcess->addArgument( prodSequence.join( " " ) );
2233 // ... sources directory
2234 shellProcess->addArgument( QDir::cleanDirPath( getSrcPath() ) );
2235 // ... remove sources and tmp files or not?
2236 if ( installType == Compile && removeSrcBtn->isOn() )
2237 shellProcess->addArgument( "TRUE" );
2239 shellProcess->addArgument( "FALSE" );
2240 // ... binaries directory
2241 shellProcess->addArgument( binDir );
2242 // ... install SALOME with GUI or not?
2243 if ( woGuiModules.find( prodProc ) != woGuiModules.end() )
2244 ( installGuiBtn->state() != QButton::On && woGuiModules[ prodProc ] == True ) ?
2245 shellProcess->addArgument( "FALSE" ) :
2246 shellProcess->addArgument( "TRUE" );
2247 // ... single installation directory for SALOME modules, if this option was selected
2248 if ( oneModDirBtn->isChecked() ) {
2249 MapProducts::Iterator mapIter;
2250 for ( mapIter = productsMap.begin(); mapIter != productsMap.end(); ++mapIter )
2251 if ( mapIter.data().getName() == prodProc && mapIter.data().getType() == "component" ) {
2252 shellProcess->addArgument( "TRUE" );
2256 // ... single installation directory for prerequisites, if this option was selected
2257 if ( oneProdDirBtn->isChecked() ) {
2258 if ( prodProc == "DebianLibsForSalome" )
2259 shellProcess->addArgument( oneProdDirName );
2261 MapProducts::Iterator mapIter;
2262 for ( mapIter = productsMap.begin(); mapIter != productsMap.end(); ++mapIter )
2263 if ( mapIter.data().getName() == prodProc && mapIter.data().getType() == "prerequisite" ) {
2264 shellProcess->addArgument( oneProdDirName );
2271 if ( !shellProcess->start() ) {
2272 // error handling can be here
2273 QStringList args = shellProcess->arguments();
2274 ___MESSAGE___( "error" );
2275 ___MESSAGE___( "cmd: " << args.join(" ").latin1() );
2280 // else try to find aborted product
2281 prodProc = progressView->findStatus( Aborted );
2282 if ( !prodProc.isNull() )
2283 return; // installation has been aborted
2285 ___MESSAGE___( "All products have been installed successfully" );
2286 // all products are installed successfully
2287 MapProducts::Iterator mapIter;
2288 ___MESSAGE___( "starting pick-up environment" );
2289 QString depproducts = QUOTE( getAllProducts(productsMap).prepend( QStringList( extraProducts.keys() ).join(" ") + " " ) );
2290 for ( mapIter = productsMap.begin(); mapIter != productsMap.end(); ++mapIter ) {
2291 QCheckListItem* item = mapIter.key();
2292 Dependancies dep = mapIter.data();
2293 if ( item->isOn() && dep.pickUpEnvironment() ) {
2294 statusLab->setText( tr( "Pick-up products environment for " ) + dep.getName().latin1() + "..." );
2295 ___MESSAGE___( "... for " << dep.getName().latin1() );
2296 QDir rd( rootDirPath() );
2298 script << "cd" << QUOTE( rd.filePath( "config_files" ) ) << ";";
2299 script << item->text(2) << "pickup_env";
2300 script << QUOTE( QFileInfo( QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + TEMPDIRNAME ).absFilePath() );
2301 script << QUOTE( QFileInfo( QDir::cleanDirPath( QDir( rootDirPath() ).filePath( "Products" ) ) ).absFilePath() );
2302 script << QUOTE( QFileInfo( QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() ) ).absFilePath() );
2303 script << depproducts << item->text(0) << QUOTE( prodSequence.join( " " ) );
2304 ___MESSAGE___( "... --> " << script.script().latin1() );
2305 if ( system( script.script().latin1() ) ) {
2306 ___MESSAGE___( "ERROR" );
2311 if ( installType == Binaries ) {
2312 if ( oneModDirBtn->isChecked() )
2318 // Update GUI and check installation errors
2319 completeInstallation();
2323 // ================================================================
2325 * SALOME_InstallWizard::completeInstallation
2326 * Update GUI and check installation errors
2328 // ================================================================
2329 void SALOME_InstallWizard::completeInstallation()
2331 // update status label
2332 statusLab->setText( tr( "Installation completed" ) );
2334 setNextEnabled( true );
2335 doPostActions( tr( "&Next >" ), tr( "Move to the next step of the installation procedure" ) );
2336 connect( this, SIGNAL( nextClicked() ), this, SLOT( next() ) );
2338 setBackEnabled( true );
2339 // script parameters
2340 passedParams->clear();
2341 passedParams->setEnabled( false );
2342 QFont f = parametersLab->font(); f.setBold( false ); parametersLab->setFont( f );
2343 installInfo->setFinished( true );
2344 if ( isMinimized() )
2348 if ( QMessageBox::warning( this,
2350 tr( "There were some errors during the installation.\n"
2351 "Do you want to save the installation log?" ),
2362 // ================================================================
2364 * SALOME_InstallWizard::onInstallGuiBtn
2365 * <Installation with GUI> check-box slot
2367 // ================================================================
2368 void SALOME_InstallWizard::onInstallGuiBtn()
2370 MapProducts::Iterator itProd;
2371 for ( itProd = productsMap.begin(); itProd != productsMap.end(); ++itProd ) {
2372 if ( itProd.data().getType() == "component" ) {
2373 if ( installGuiBtn->state() == QButton::On ) {
2374 itProd.key()->setEnabled( true );
2375 itProd.key()->setOn( true );
2378 QString itemName = itProd.data().getName();
2379 if ( woGuiModules.find( itemName ) == woGuiModules.end() ||
2380 woGuiModules[ itemName ] == False ) {
2381 itProd.key()->setOn( false );
2382 itProd.key()->setEnabled( false );
2385 itProd.key()->setOn( true );
2390 // ================================================================
2392 * SALOME_InstallWizard::onMoreBtn
2393 * <More...> button slot
2395 // ================================================================
2396 void SALOME_InstallWizard::onMoreBtn()
2399 prereqsView->hide();
2400 moreBtn->setText( tr( "Show prerequisites..." ) );
2401 setAboutInfo( moreBtn, tr( "Show list of prerequisites" ) );
2404 prereqsView->show();
2405 moreBtn->setText( tr( "Hide prerequisites" ) );
2406 setAboutInfo( moreBtn, tr( "Hide list of prerequisites" ) );
2408 qApp->processEvents();
2409 moreMode = !moreMode;
2410 InstallWizard::layOut();
2411 qApp->processEvents();
2412 if ( !isMaximized() ) {
2413 qApp->processEvents();
2417 // ================================================================
2419 * SALOME_InstallWizard::onFinishButton
2420 * Operation buttons slot
2422 // ================================================================
2423 void SALOME_InstallWizard::onFinishButton()
2425 const QObject* btn = sender();
2426 ButtonList::Iterator it;
2427 for ( it = buttons.begin(); it != buttons.end(); ++it ) {
2428 if ( (*it).button() && (*it).button() == btn ) {
2429 QDir rd( rootDirPath() );
2431 script << "cd" << QUOTE( rd.filePath( "config_files" ) ) << ";";
2432 script << (*it).script() << "execute";
2433 script << QUOTE( QFileInfo( QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() ) ).absFilePath() );
2434 script << QUOTE( QFileInfo( QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + TEMPDIRNAME ).absFilePath() );
2436 script << ">& /dev/null";
2438 ___MESSAGE___( "script: " << script.script().latin1() );
2439 if ( (*it).script().isEmpty() || system( script.script().latin1() ) ) {
2440 QMessageBox::warning( this,
2442 tr( "Can't perform action!"),
2444 QMessageBox::NoButton,
2445 QMessageBox::NoButton );
2451 // ================================================================
2453 * SALOME_InstallWizard::onAbout
2454 * <About> button slot: shows <About> dialog box
2456 // ================================================================
2457 void SALOME_InstallWizard::onAbout()
2463 // ================================================================
2465 * SALOME_InstallWizard::findItem
2466 * Searches product listview item with given symbolic name
2468 // ================================================================
2469 QCheckListItem* SALOME_InstallWizard::findItem( const QString& sName )
2471 MapProducts::Iterator mapIter;
2472 for ( mapIter = productsMap.begin(); mapIter != productsMap.end(); ++mapIter ) {
2473 if ( mapIter.data().getName() == sName )
2474 return mapIter.key();
2478 // ================================================================
2480 * SALOME_InstallWizard::abort
2481 * Sets progress state to Aborted
2483 // ================================================================
2484 void SALOME_InstallWizard::abort()
2486 QString prod = progressView->findStatus( Processing );
2487 while ( !prod.isNull() ) {
2488 progressView->setStatus( prod, Aborted );
2489 prod = progressView->findStatus( Processing );
2491 prod = progressView->findStatus( Waiting );
2492 while ( !prod.isNull() ) {
2493 progressView->setStatus( prod, Aborted );
2494 prod = progressView->findStatus( Waiting );
2497 // ================================================================
2499 * SALOME_InstallWizard::reject
2500 * Reject slot, clears temporary directory and closes application
2502 // ================================================================
2503 void SALOME_InstallWizard::reject()
2505 ___MESSAGE___( "REJECTED" );
2506 if ( !exitConfirmed ) {
2507 if ( QMessageBox::information( this,
2509 tr( "Do you want to quit %1?" ).arg( getIWName() ),
2517 exitConfirmed = true;
2520 InstallWizard::reject();
2522 // ================================================================
2524 * SALOME_InstallWizard::accept
2525 * Accept slot, clears temporary directory and closes application
2527 // ================================================================
2528 void SALOME_InstallWizard::accept()
2530 ___MESSAGE___( "ACCEPTED" );
2532 InstallWizard::accept();
2534 // ================================================================
2536 * SALOME_InstallWizard::clean
2537 * Clears and (optionally) removes temporary directory
2539 // ================================================================
2540 void SALOME_InstallWizard::clean(bool rmDir)
2542 WarnDialog::showWarnDlg( 0, false );
2543 myThread->clearCommands();
2545 while ( myThread->running() );
2546 // first remove temporary files
2547 QDir rd( rootDirPath() );
2549 script << "cd" << QUOTE( rd.filePath( "config_files" ) ) << ";";
2550 script << "remove_tmp.sh" << QUOTE( tempFolder->text().stripWhiteSpace() + TEMPDIRNAME );
2551 script << QUOTE( getAllProducts( productsMap ) );
2553 script << ">& /dev/null";
2555 ___MESSAGE___( "script = " << script.script().latin1() );
2556 if ( system( script.script().latin1() ) ) {
2559 // then try to remove created temporary directory
2560 //script = "rm -rf " + QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + TEMPDIRNAME;
2561 if ( rmDir && !tmpCreated.isNull() ) {
2563 script << "rm -rf" << QUOTE( tmpCreated );
2565 script << ">& /dev/null";
2567 if ( system( script.script().latin1() ) ) {
2570 ___MESSAGE___( "script = " << script.script().latin1() );
2573 // ================================================================
2575 * SALOME_InstallWizard::pageChanged
2576 * Called when user moves from page to page
2578 // ================================================================
2579 void SALOME_InstallWizard::pageChanged( const QString & mytitle)
2581 doPostActions( tr( "&Next >" ), tr( "Move to the next step of the installation procedure" ) );
2582 connect( this, SIGNAL( nextClicked() ), this, SLOT( next() ) );
2583 cancelButton()->disconnect();
2584 connect( cancelButton(), SIGNAL( clicked()), this, SLOT( reject() ) );
2586 QWidget* aPage = InstallWizard::page( mytitle );
2591 if ( aPage == typePage ) {
2592 // installation type page
2593 if ( buttonGrp->id( buttonGrp->selected() ) == -1 )
2594 // set default installation type
2595 forceSrc ? srcCompileBtn->animateClick() : binBtn->animateClick();
2597 buttonGrp->selected()->animateClick();
2599 else if ( aPage == platformsPage ) {
2600 // installation platforms page
2601 MapXmlFiles::Iterator it;
2602 if ( previousPage == typePage ) {
2603 for ( it = platformsMap.begin(); it != platformsMap.end(); ++it ) {
2604 QString plat = it.key();
2605 QRadioButton* rb = ( (QRadioButton*) platBtnGrp->child( plat ) );
2606 if ( installType == Binaries ) {
2607 QFileInfo fib( getPlatformBinPath( plat ) );
2608 rb->setEnabled( true/*fib.isDir()*/ );
2609 if ( platBtnGrp->id( platBtnGrp->selected() ) == -1 && plat == getBasePlatform() )
2612 // rb->setChecked( rb->isChecked() && rb->isEnabled() );
2613 if ( rb->isChecked() && rb->isEnabled() )
2616 setNextEnabled( platformsPage, platBtnGrp->id( platBtnGrp->selected() ) != -1 );
2619 else if ( aPage == dirPage ) {
2620 // installation and temporary directories page
2621 if ( ( ( this->indexOf( platformsPage ) != -1 && this->appropriate( platformsPage ) ) ?
2622 previousPage == platformsPage : previousPage == typePage )
2624 // clear global variables before reading XML file
2625 modulesView->clear();
2626 prereqsView->clear();
2627 productsMap.clear();
2629 StructureParser* parser = new StructureParser( this );
2630 parser->setProductsLists( modulesView, prereqsView );
2631 if ( targetFolder->text().isEmpty() )
2632 parser->setTargetDir( targetFolder );
2633 if ( tempFolder->text().isEmpty() )
2634 parser->setTempDir( tempFolder );
2635 parser->readXmlFile( xmlFileName );
2636 // create a map of SALOME modules names, that can support installation without GUI mode
2637 if ( woGuiModules.isEmpty() ) {
2638 MapProducts::Iterator mapIter;
2639 for ( mapIter = productsMap.begin(); mapIter != productsMap.end(); mapIter++ ) {
2640 Dependancies dep = mapIter.data();
2641 if ( dep.getType() == "component" && dep.supportWoGuiMode() != NotDefined )
2642 woGuiModules[ dep.getName() ] = dep.supportWoGuiMode();
2646 // update required size for each product
2648 // take into account command line parameters
2649 if ( !myTargetPath.isEmpty() )
2650 targetFolder->setText( myTargetPath );
2651 if ( !myTmpPath.isEmpty() )
2652 tempFolder->setText( myTmpPath );
2653 // set all modules to be checked and first module to be selected
2654 installGuiBtn->setState( QButton::Off );
2655 installGuiBtn->setState( QButton::On );
2656 if ( modulesView->childCount() > 0 && !modulesView->selectedItem() )
2657 modulesView->setSelected( modulesView->firstChild(), true );
2658 stateChanged = false;
2660 else if ( rmSrcPrevState != removeSrcBtn->isChecked() ) {
2661 // only update required size for each product
2663 rmSrcPrevState = removeSrcBtn->isChecked();
2665 // add extra products to install list
2666 extraProducts.clear();
2667 //extraProducts.insert( "gcc", "gcc-common.sh" );
2668 if ( refPlatform == commonPlatform && installType == Binaries )
2669 extraProducts.insert( "DebianLibsForSalome", "DEBIANFORSALOME-3.1.sh" );
2671 else if ( aPage == productsPage ) {
2673 onSelectionChanged();
2676 else if ( aPage == prestartPage ) {
2680 else if ( aPage == progressPage ) {
2681 if ( previousPage == prestartPage ) {
2684 progressView->clear();
2685 installInfo->clear();
2686 installInfo->setFinished( false );
2687 passedParams->clear();
2688 passedParams->setEnabled( false );
2689 QFont f = parametersLab->font(); f.setBold( false ); parametersLab->setFont( f );
2690 doPostActions( tr( "&Start" ), tr( "Start installation process" ) );
2691 connect( this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
2692 setNextEnabled( true );
2693 // reconnect Cancel button to terminate process
2694 cancelButton()->disconnect();
2695 connect( cancelButton(), SIGNAL( clicked() ), this, SLOT( tryTerminate() ) );
2698 else if ( aPage == readmePage ) {
2699 ButtonList::Iterator it;
2700 for ( it = buttons.begin(); it != buttons.end(); ++it ) {
2701 if ( (*it).button() ) {
2702 QDir rd( rootDirPath() );
2704 script << "cd" << QUOTE( rd.filePath( "config_files" ) ) << ";";
2705 script << (*it).script() << "check_enabled";
2706 script << QUOTE( QFileInfo( QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() ) ).absFilePath() );
2707 script << QUOTE( QFileInfo( QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + TEMPDIRNAME ).absFilePath() );
2709 script << ">& /dev/null";
2711 ___MESSAGE___( "script: " << script.script().latin1() );
2712 (*it).button()->setEnabled( !(*it).script().isEmpty() && !system( script.script().latin1() ) );
2715 finishButton()->setEnabled( true );
2717 previousPage = aPage;
2718 ___MESSAGE___( "previousPage = " << previousPage );
2720 // ================================================================
2722 * SALOME_InstallWizard::onButtonGroup
2723 * Called when user selected either installation type or installation platform
2725 // ================================================================
2726 void SALOME_InstallWizard::onButtonGroup( int rbIndex )
2728 int prevType = installType;
2729 QString prevPlat = getPlatform();
2730 QWidget* aPage = InstallWizard::currentPage();
2731 if ( aPage == typePage ) {
2732 installType = InstallationType( rbIndex );
2733 // management of the <Remove source and tmp files> check-box
2734 removeSrcBtn->setEnabled( installType == Compile );
2735 oneModDirBtn->setEnabled( installType == Binaries /*|| installType == Compile*/ );
2736 oneProdDirBtn->setEnabled( installType == Binaries || installType == Compile );
2738 xmlFileName = getXmlFile( curPlatform );
2740 else if ( aPage == platformsPage ) {
2741 refPlatform = platBtnGrp->find( rbIndex )->name();
2742 xmlFileName = getXmlFile( refPlatform );
2743 setNextEnabled( platformsPage, true );
2745 if ( prevType != installType ||
2746 ( indexOf( platformsPage ) != -1 ? prevPlat != getPlatform() : false ) ) {
2747 stateChanged = true;
2748 oneModDirBtn->setChecked( installType == Binaries && singleDir );
2749 oneProdDirBtn->setChecked( false );
2752 // ================================================================
2754 * SALOME_InstallWizard::helpClicked
2757 // ================================================================
2758 void SALOME_InstallWizard::helpClicked()
2760 if ( helpWindow == NULL ) {
2761 helpWindow = HelpWindow::openHelp( this );
2764 helpWindow->installEventFilter( this );
2767 QMessageBox::warning( this,
2768 tr( "Help file not found" ),
2769 tr( "Sorry, help is unavailable" ) );
2773 helpWindow->raise();
2774 helpWindow->setActiveWindow();
2777 // ================================================================
2779 * SALOME_InstallWizard::browseDirectory
2780 * Shows directory selection dialog
2782 // ================================================================
2783 void SALOME_InstallWizard::browseDirectory()
2785 const QObject* theSender = sender();
2786 QLineEdit* theFolder;
2787 if ( theSender == targetBtn )
2788 theFolder = targetFolder;
2789 else if (theSender == tempBtn)
2790 theFolder = tempFolder;
2793 QString typedDir = QFileDialog::getExistingDirectory( QDir::cleanDirPath( theFolder->text().stripWhiteSpace() ), this );
2794 if ( !typedDir.isNull() ) {
2795 theFolder->setText( typedDir );
2796 theFolder->end( false );
2799 // ================================================================
2801 * SALOME_InstallWizard::directoryChanged
2802 * Called when directory path (target or temp) is changed
2804 // ================================================================
2805 void SALOME_InstallWizard::directoryChanged( const QString& /*text*/ )
2809 // ================================================================
2811 * SALOME_InstallWizard::onStart
2812 * <Start> button's slot - runs installation
2814 // ================================================================
2815 void SALOME_InstallWizard::onStart()
2817 if ( nextButton()->text() == tr( "&Stop" ) ) {
2818 statusLab->setText( tr( "Aborting installation..." ) );
2819 shellProcess->kill();
2820 modifyLaProc->kill();
2821 while( shellProcess->isRunning() );
2822 statusLab->setText( tr( "Installation has been aborted by user" ) );
2827 progressView->clear();
2828 installInfo->clear();
2829 installInfo->setFinished( false );
2830 passedParams->clear();
2831 passedParams->setEnabled( false );
2832 // disable 'Ignore errors' checkbox during installation process
2833 ignoreErrCBox->setEnabled( false );
2834 QFont f = parametersLab->font(); f.setBold( false ); parametersLab->setFont( f );
2836 // update status label
2837 statusLab->setText( tr( "Preparing for installation..." ) );
2838 // clear lists of products
2841 toInstall += extraProducts.keys();
2842 // ... and fill it for new process
2843 QCheckListItem* item = (QCheckListItem*)( prereqsView->firstChild() );
2845 if ( productsMap.contains( item ) ) {
2847 toInstall.append( productsMap[item].getName() );
2849 notInstall.append( productsMap[item].getName() );
2851 item = (QCheckListItem*)( item->nextSibling() );
2853 item = (QCheckListItem*)( modulesView->firstChild() );
2855 if ( productsMap.contains( item ) ) {
2857 toInstall.append( productsMap[item].getName() );
2859 notInstall.append( productsMap[item].getName() );
2861 item = (QCheckListItem*)( item->nextSibling() );
2863 // if something at all is selected
2864 if ( (int)toInstall.count() > 0 ) {
2866 if ( installType == Compile ) {
2867 // update status label
2868 statusLab->setText( tr( "Check Fortran compiler..." ) );
2869 // check Fortran compiler.
2870 QDir rd( rootDirPath() );
2872 script << QUOTE( rd.filePath( "config_files/checkFortran.sh" ) ) << "find_compilers";
2873 script << QUOTE( QFileInfo( QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + TEMPDIRNAME ).absFilePath() );
2874 ___MESSAGE___( "script = " << script.script().latin1() );
2875 if ( system( script.script().latin1() ) ) {
2876 QMessageBox::critical( this,
2878 tr( "Fortran compiler was not found at current system!\n"
2879 "Installation can not be continued!"),
2881 QMessageBox::NoButton,
2882 QMessageBox::NoButton );
2883 // installation aborted
2885 statusLab->setText( tr( "Installation has been aborted" ) );
2886 // enable <Next> button
2887 setNextEnabled( true );
2888 doPostActions( tr( "&Start" ), tr( "Start installation process" ) );
2889 connect( this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
2890 // enable <Back> button
2891 setBackEnabled( true );
2896 // update status label
2897 statusLab->setText( tr( "Preparing for installation..." ) );
2899 clean(false); // VSR 07/02/05 - bug fix: first we should clear temporary directory
2900 // disable <Next> button
2901 //setNextEnabled( false );
2902 nextButton()->setText( tr( "&Stop" ) );
2903 setAboutInfo( nextButton(), tr( "Abort installation process" ) );
2904 // disable <Back> button
2905 setBackEnabled( false );
2906 // enable script parameters line edit
2907 // VSR commented: 18/09/03: passedParams->setEnabled( true );
2908 // VSR commented: 18/09/03: passedParams->setFocus();
2909 ProgressViewItem* progressItem;
2910 // set status for installed products
2911 for ( int i = 0; i < (int)toInstall.count(); i++ ) {
2912 if ( !extraProducts.contains( toInstall[i] ) ) {
2913 item = findItem( toInstall[i] );
2914 progressView->addProduct( item->text(0), item->text(2) );
2917 progressItem = progressView->addProduct( toInstall[i], extraProducts[toInstall[i]] );
2918 progressItem->setVisible( false );
2920 // set status for not installed products
2921 for ( int i = 0; i < (int)notInstall.count(); i++ ) {
2922 item = findItem( notInstall[i] );
2923 progressItem = progressView->addProduct( item->text(0), item->text(2) );
2924 progressItem->setVisible( false );
2926 // get specified list of products being installed
2927 prodSequence.clear();
2928 for (int i = 0; i<(int)toInstall.count(); i++ ) {
2929 if ( extraProducts.contains( toInstall[i] ) ) {
2930 prodSequence.append( toInstall[i] );
2933 if ( installType == Binaries ) {
2934 prodSequence.append( toInstall[i] );
2936 MapProducts::Iterator mapIter;
2937 for ( mapIter = productsMap.begin(); mapIter != productsMap.end(); ++mapIter ) {
2938 if ( mapIter.data().getName() == toInstall[i] && mapIter.data().getType() == "component" ) {
2939 prodSequence.append( toInstall[i] + "_src" );
2944 else if ( installType == Sources )
2945 prodSequence.append( toInstall[i] + "_src" );
2947 prodSequence.append( toInstall[i] );
2948 prodSequence.append( toInstall[i] + "_src" );
2952 // create a backup of 'env_build.csh', 'env_build.sh', 'env_products.csh', 'env_products.sh'
2953 // ( backup of 'salome.csh' and 'salome.sh' is made if pick-up environment is called )
2954 QDir rd( rootDirPath() );
2956 script << QUOTE( rd.filePath( "config_files/backupEnv.sh" ) );
2957 script << QUOTE( QFileInfo( QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() ) ).absFilePath() );
2958 ___MESSAGE___( "script = " << script.script().latin1() );
2959 if ( system( script.script().latin1() ) ) {
2960 if ( QMessageBox::warning( this,
2962 tr( "Backup environment files have not been created.\n"
2963 "Do you want to continue an installation process?" ),
2966 QString::null, 0, 1 ) == 1 ) {
2967 // installation aborted
2969 statusLab->setText( tr( "Installation has been aborted by user" ) );
2970 // update <Next> button
2971 setNextEnabled( true );
2972 doPostActions( tr( "&Start" ), tr( "Start installation process" ) );
2973 connect( this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
2974 // enable <Back> button
2975 setBackEnabled( true );
2980 // launch install script
2984 // ================================================================
2986 * SALOME_InstallWizard::onReturnPressed
2987 * Called when users tries to pass parameters for the script
2989 // ================================================================
2990 void SALOME_InstallWizard::onReturnPressed()
2992 QString txt = passedParams->text();
2993 installInfo->append( txt );
2995 shellProcess->writeToStdin( txt );
2996 passedParams->clear();
2997 progressView->setFocus();
2998 passedParams->setEnabled( false );
2999 QFont f = parametersLab->font(); f.setBold( false ); parametersLab->setFont( f );
3002 Callback function - as response for the script finishing
3004 void SALOME_InstallWizard::productInstalled()
3006 ___MESSAGE___( "process exited" );
3007 if ( shellProcess->normalExit() ) {
3008 ___MESSAGE___( "...normal exit" );
3009 // normal exit - try to proceed installation further
3013 ___MESSAGE___( "...abnormal exit" );
3014 statusLab->setText( tr( "Installation has been aborted" ) );
3015 // installation aborted
3017 // clear script passed parameters lineedit
3018 passedParams->clear();
3019 passedParams->setEnabled( false );
3020 QFont f = parametersLab->font(); f.setBold( false ); parametersLab->setFont( f );
3021 installInfo->setFinished( true );
3022 // enable <Next> button
3023 setNextEnabled( true );
3024 doPostActions( tr( "&Start" ), tr( "Start installation process" ) );
3025 connect( this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
3026 //doPostActions( tr( "&Next >" ), tr( "Move to the next step of the installation procedure" ) );
3027 //connect( this, SIGNAL( nextClicked() ), this, SLOT( next() ) );
3028 // enable <Back> button
3029 setBackEnabled( true );
3032 // ================================================================
3034 * SALOME_InstallWizard::tryTerminate
3035 * Slot, called when <Cancel> button is clicked during installation script running
3037 // ================================================================
3038 void SALOME_InstallWizard::tryTerminate()
3040 if ( shellProcess->isRunning() ) {
3041 if ( QMessageBox::information( this,
3043 tr( "Do you want to quit %1?" ).arg( getIWName() ),
3051 exitConfirmed = true;
3052 // if process still running try to terminate it first
3053 shellProcess->tryTerminate();
3055 //QTimer::singleShot( 3000, this, SLOT( onCancel() ) );
3056 connect( shellProcess, SIGNAL( processExited() ), this, SLOT( onCancel() ) );
3059 // else just quit install wizard
3063 // ================================================================
3065 * SALOME_InstallWizard::onCancel
3066 * Kills installation process and quits application
3068 // ================================================================
3069 void SALOME_InstallWizard::onCancel()
3071 shellProcess->kill();
3072 modifyLaProc->kill();
3073 checkFLibProc->kill();
3076 // ================================================================
3078 * SALOME_InstallWizard::onSelectionChanged
3079 * Called when selection is changed in the products list view
3080 * to fill in the 'Information about product' text box
3082 // ================================================================
3083 void SALOME_InstallWizard::onSelectionChanged()
3085 const QObject* snd = sender();
3086 QListViewItem* item = modulesView->selectedItem();
3087 if ( snd == prereqsView )
3088 item = prereqsView->selectedItem();
3091 productInfo->clear();
3092 QCheckListItem* anItem = (QCheckListItem*)item;
3093 if ( !productsMap.contains( anItem ) )
3095 Dependancies dep = productsMap[ anItem ];
3096 QString text = "<b>" + anItem->text(0) + "</b>" + "<br>";
3097 if ( !dep.getVersion().isEmpty() )
3098 text += tr( "Version" ) + ": " + dep.getVersion() + "<br>";
3100 if ( !dep.getDescription().isEmpty() ) {
3101 text += "<i>" + dep.getDescription() + "</i><br><br>";
3103 /* AKL: 07/08/28 - hide required disk space for tmp files for each product ==>
3105 tempSize = dep.getTempSize( installType );
3106 text += tr( "Disk space for tmp files required" ) + ": " + QString::number( tempSize ) + " KB<br>";
3107 AKL: 07/08/28 - hide required disk space for tmp files for each product <==
3109 text += tr( "Disk space required" ) + ": " + item->text(1) + "<br>";
3111 QString req = ( dep.getDependancies().count() > 0 ? dep.getDependancies().join(", ") : tr( "none" ) );
3112 text += tr( "Prerequisites" ) + ": " + req;
3113 productInfo->setText( text );
3115 // ================================================================
3117 * SALOME_InstallWizard::onItemToggled
3118 * Called when user checks/unchecks any product item
3119 * Recursively sets all prerequisites and updates "Next" button state
3121 // ================================================================
3122 void SALOME_InstallWizard::onItemToggled( QCheckListItem* item )
3124 if ( productsMap.contains( item ) ) {
3126 setPrerequisites( item );
3128 unsetPrerequisites( item );
3130 onSelectionChanged();
3133 // ================================================================
3135 * SALOME_InstallWizard::wroteToStdin
3136 * QProcess slot: -->something was written to stdin
3138 // ================================================================
3139 void SALOME_InstallWizard::wroteToStdin( )
3141 ___MESSAGE___( "Something was sent to stdin" );
3143 // ================================================================
3145 * SALOME_InstallWizard::readFromStdout
3146 * QProcess slot: -->something was written to stdout
3148 // ================================================================
3149 void SALOME_InstallWizard::readFromStdout( )
3151 ___MESSAGE___( "Something was sent to stdout" );
3152 QProcess* theProcess = ( QProcess* )sender();
3153 while ( theProcess->canReadLineStdout() ) {
3154 installInfo->append( QString( theProcess->readLineStdout() ) );
3155 installInfo->scrollToBottom();
3157 QString str( theProcess->readStdout() );
3158 if ( !str.isEmpty() ) {
3159 installInfo->append( str );
3160 installInfo->scrollToBottom();
3164 #define OUTLINE_TEXT(x) QString( "<font color=#FF0000><b>" ) + QString( x ) + QString( "</b></font>" )
3166 // ================================================================
3168 * SALOME_InstallWizard::readFromStderr
3169 * QProcess slot: -->something was written to stderr
3171 // ================================================================
3172 void SALOME_InstallWizard::readFromStderr( )
3174 ___MESSAGE___( "Something was sent to stderr" );
3175 QProcess* theProcess = ( QProcess* )sender();
3176 while ( theProcess->canReadLineStderr() ) {
3177 installInfo->append( OUTLINE_TEXT( QString( theProcess->readLineStderr() ) ) );
3178 installInfo->scrollToBottom();
3181 QString str( theProcess->readStderr() );
3182 if ( !str.isEmpty() ) {
3183 installInfo->append( OUTLINE_TEXT( str ) );
3184 installInfo->scrollToBottom();
3188 // stop or proceed installation process
3191 // VSR: 10/11/05 - disable answer mode ==>
3192 // passedParams->setEnabled( true );
3193 // passedParams->setFocus();
3194 // QFont f = parametersLab->font(); f.setBold( true ); parametersLab->setFont( f );
3195 // VSR: 10/11/05 - disable answer mode <==
3197 // ================================================================
3199 * SALOME_InstallWizard::manageInstProc
3200 * QProcess slot: -->stop installation if there is an error in stderr
3202 // ================================================================
3203 void SALOME_InstallWizard::manageInstProc()
3205 if ( !hasErrors || ignoreErrCBox->isChecked() )
3206 return; //proceed installation process
3208 // abort the current installation
3209 statusLab->setText( tr( "Aborting installation..." ) );
3211 statusLab->setText( tr( "Installation has been aborted because some errors" ) );
3212 if ( QMessageBox::critical( this,
3214 tr( "Installation process has been stopped, because an error occured \n"
3215 "during an installation of the current product!\n"
3216 "Please see the installation progress view for more details about the error.\n\n"
3217 "Do you want to save the installation log?" ),
3224 // enable <Next> button
3225 setNextEnabled( true );
3226 doPostActions( tr( "&Start" ), tr( "Start installation process" ) );
3227 connect( this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
3228 // enable <Back> button
3229 setBackEnabled( true );
3230 installInfo->setFinished( true );
3232 // ================================================================
3234 * SALOME_InstallWizard::setDependancies
3235 * Sets dependancies for the product item
3237 // ================================================================
3238 void SALOME_InstallWizard::setDependancies( QCheckListItem* item, Dependancies dep)
3240 productsMap[item] = dep;
3242 // ================================================================
3244 * SALOME_InstallWizard::doPostActions
3245 * Executes some actions after finish of installation process (successful or not)
3247 // ================================================================
3248 void SALOME_InstallWizard::doPostActions( const QString& btnText,
3249 const QString& btnAboutInfo )
3251 // update <Next> button
3252 nextButton()->setText( btnText );
3253 setAboutInfo( nextButton(), btnAboutInfo );
3254 // reconnect Next button - to use it as Start button
3255 disconnect( this, SIGNAL( nextClicked() ), this, SLOT( next() ) );
3256 disconnect( this, SIGNAL( nextClicked() ), this, SLOT( onStart() ) );
3257 // enable 'Ignore errors' checkbox
3258 ignoreErrCBox->setEnabled( true );
3260 // ================================================================
3262 * SALOME_InstallWizard::addFinishButton
3263 * Add button for the <Finish> page.
3264 * Clear list of buttons if <toClear> flag is true.
3266 // ================================================================
3267 void SALOME_InstallWizard::addFinishButton( const QString& label,
3268 const QString& tooltip,
3269 const QString& script,
3277 buttons.append( Button( label, tooltip, script ) );
3278 // create finish buttons
3279 QButton* b = new QPushButton( tr( buttons.last().label() ), readmePage );
3280 if ( !buttons.last().tootip().isEmpty() )
3281 setAboutInfo( b, tr( buttons.last().tootip() ) );
3282 QHBoxLayout* hLayout = (QHBoxLayout*)readmePage->layout()->child("finishButtons");
3284 // remove previous buttons
3285 ButtonList::Iterator it;
3286 for ( it = btns.begin(); it != btns.end(); ++it ) {
3287 hLayout->removeChild( (*it).button() );
3288 delete (*it).button();
3291 // add buttons to finish page
3292 hLayout->insertWidget( buttons.count()-1, b );
3293 buttons.last().setButton( b );
3294 connect( b, SIGNAL( clicked() ), this, SLOT( onFinishButton() ) );
3296 // ================================================================
3298 * SALOME_InstallWizard::polish
3299 * Polishing of the widget - to set right initial size
3301 // ================================================================
3302 void SALOME_InstallWizard::polish()
3305 InstallWizard::polish();
3307 // ================================================================
3309 * SALOME_InstallWizard::saveLog
3310 * Save installation log to file
3312 // ================================================================
3313 void SALOME_InstallWizard::saveLog()
3315 QString txt = installInfo->text();
3316 if ( txt.length() <= 0 )
3318 QDateTime dt = QDateTime::currentDateTime();
3319 QString fileName = dt.toString("ddMMyy-hhmm");
3320 fileName.prepend("install-"); fileName.append(".html");
3321 fileName = QFileInfo( QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() ), fileName ).absFilePath();
3322 fileName = QFileDialog::getSaveFileName( fileName,
3323 QString( "HTML files (*.htm *.html)" ),
3325 tr( "Save Log file" ) );
3326 if ( !fileName.isEmpty() ) {
3327 QFile f( fileName );
3328 if ( f.open( IO_WriteOnly ) ) {
3329 QTextStream stream( &f );
3334 QMessageBox::critical( this,
3336 tr( "Can't save file %1.\nCheck path and permissions.").arg( fileName ),
3338 QMessageBox::NoButton,
3339 QMessageBox::NoButton );
3343 // ================================================================
3345 * SALOME_InstallWizard::updateCaption
3346 * Updates caption according to the current page number
3348 // ================================================================
3349 void SALOME_InstallWizard::updateCaption()
3351 QWidget* aPage = InstallWizard::currentPage();
3354 InstallWizard::setCaption( tr( myCaption ) + " " +
3355 tr( getIWName() ) + " - " +
3356 tr( "Step %1 of %2").arg( QString::number( this->indexOf( aPage )+1 ) ).arg( QString::number( this->pageCount() ) ) );
3359 // ================================================================
3361 * SALOME_InstallWizard::processValidateEvent
3362 * Processes validation event (<val> is validation code)
3364 // ================================================================
3365 void SALOME_InstallWizard::processValidateEvent( const int val, void* data )
3367 QWidget* aPage = InstallWizard::currentPage();
3368 if ( aPage != productsPage ) {
3369 InstallWizard::processValidateEvent( val, data );
3376 if ( myThread->hasCommands() )
3379 WarnDialog::showWarnDlg( 0, false );
3380 InstallWizard::processValidateEvent( val, data );