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