From: vsr Date: Tue, 15 Feb 2005 12:49:06 +0000 (+0000) Subject: Improve SALOME Installation Wizard: show info message when checking native products... X-Git-Tag: SALOME_V_2_2_0~5 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=dd21bfc0dea4040097e16e705441a7626bac6d38;p=tools%2Finstall.git Improve SALOME Installation Wizard: show info message when checking native products and perform all checks in auxillary thread in order to not hang-up the main window. --- diff --git a/src/InstallWizard.cpp b/src/InstallWizard.cpp index ee667f9..28d529a 100644 --- a/src/InstallWizard.cpp +++ b/src/InstallWizard.cpp @@ -49,10 +49,23 @@ #include #include +#define PROCESS_EVENT QEvent::User+100 + +class ProcessEvent : public QCustomEvent +{ +public: + ProcessEvent( int retValue = 0, void* data = 0 ): QCustomEvent( PROCESS_EVENT ), myReturnValue( retValue ), myData( data ) {} + const int returnValue() const { return myReturnValue; } + void* data() const { return myData; } +private: + int myReturnValue; + void* myData; +}; + class InstallWizardPrivate { public: - struct Page { + struct Page { Page( QWidget * widget, const QString & title ): w( widget ), t( title ), backEnabled( TRUE ), nextEnabled( TRUE ), finishEnabled( FALSE ), @@ -356,9 +369,21 @@ void InstallWizard::next() while ( i > 0 && (i >= (int)d->pages.count() || !d->pages.at( i ) ) ) i--; if ( d->pages.at( i ) ) { - if ( d->current && !acceptData( d->current->t ) ) - return; - showPage( d->pages.at( i )->w ); + if ( d->current ) { + nextButton()->setEnabled( false ); + backButton()->setEnabled( false ); + if ( !acceptData( d->current->t ) ) { + nextButton()->setEnabled( true ); + backButton()->setEnabled( true ); + return; + } + } + // VSR : commented 10/02/05 ---> + // Next page will be shown later in processValidateEvent() method + // this allows custom validation, for instance by using external processing threads. + // See SALOME_InstallWizard.cxx for details where it is used. + //showPage( d->pages.at( i )->w ); + // VSR : commented 10/02/05 <--- } } @@ -744,6 +769,7 @@ Should return true in success */ bool InstallWizard::acceptData( const QString& ) { + postValidateEvent( this ); return TRUE; } @@ -882,3 +908,46 @@ void InstallWizard::removeLogos() } delete children; } + +/*! +Posts validation event +*/ +void InstallWizard::postValidateEvent( InstallWizard* iw, const int val, void* data ) +{ + QApplication::postEvent( iw, new ProcessEvent( val, data ) ); +} + +/*! +Processes validation event: default implementation just to show next page +*/ +void InstallWizard::processValidateEvent( const int /* val */, void* /* data */ ) +{ + int i = 0; + while( i < (int)d->pages.count() && d->pages.at( i ) && + d->current && d->pages.at( i )->w != d->current->w ) + i++; + i++; + while( i <= (int)d->pages.count()-1 && + ( !d->pages.at( i ) || !appropriate( d->pages.at( i )->w ) ) ) + i++; + // if we fell of the end of the world, step back + while ( i > 0 && (i >= (int)d->pages.count() || !d->pages.at( i ) ) ) + i--; + if ( d->pages.at( i ) ) { + showPage( d->pages.at( i )->w ); + } + nextButton()->setEnabled( true ); + backButton()->setEnabled( true ); +} + +/*! +Process events received +*/ +bool InstallWizard::event ( QEvent* e ) +{ + if ( e->type() == PROCESS_EVENT ) { + ProcessEvent* pe = (ProcessEvent*)e; + processValidateEvent( pe->returnValue(), pe->data() ); + } + return QDialog::event( e ); +} diff --git a/src/InstallWizard.h b/src/InstallWizard.h index 7600545..34a766a 100644 --- a/src/InstallWizard.h +++ b/src/InstallWizard.h @@ -53,7 +53,13 @@ class InstallWizard : public QDialog public: InstallWizard( QWidget* parent=0, const char* name=0, bool modal=FALSE, WFlags f=0 ); ~InstallWizard(); + + static void postValidateEvent( InstallWizard* iw, const int val = 0, void* data = 0 ); + virtual void processValidateEvent( const int val, void* data ); + + bool event ( QEvent * e ); + void show(); void setFont( const QFont & font ); diff --git a/src/SALOME_InstallWizard.cxx b/src/SALOME_InstallWizard.cxx index 98b8467..40e9481 100644 --- a/src/SALOME_InstallWizard.cxx +++ b/src/SALOME_InstallWizard.cxx @@ -34,6 +34,8 @@ #include #include #include +#include +#include #ifdef WNT #include @@ -50,13 +52,106 @@ QString tmpDirName() { return QString( "/INSTALLWORK" ) + QString::number( getpid() ); } #define TEMPDIRNAME tmpDirName() +// ================================================================ +/*! + * QProcessThread + * Class for executing systen commands + */ +// ================================================================ +QWaitCondition myWC; +class QProcessThread: public QThread +{ + typedef QPtrList ItemList; +public: + QProcessThread( SALOME_InstallWizard* iw ) : QThread(), myWizard( iw ) { myItems.setAutoDelete( false ); } + + void addCommand( QCheckListItem* item, const QString& cmd ) { + myItems.append( item ); + myCommands.push_back( cmd ); + } + + bool hasCommands() const { return myCommands.count() > 0; } + void clearCommands() { myCommands.clear(); myItems.clear(); } + + virtual void run() { + while ( hasCommands() ) { + ___MESSAGE___( "QProcessThread::run - Processing command : " << myCommands[ 0 ].latin1() ); + int result = system( myCommands[ 0 ] ) / 256; // return code is * 256 + ___MESSAGE___( "QProcessThread::run - Result : " << result ); + QCheckListItem* item = myItems.first(); + myCommands.pop_front(); + myItems.removeFirst(); + SALOME_InstallWizard::postValidateEvent( myWizard, result, (void*)item ); + if ( hasCommands() ) + myWC.wait(); + }; + } + +private: + QStringList myCommands; + ItemList myItems; + SALOME_InstallWizard* myWizard; +}; + +// ================================================================ +/*! + * WarnDialog + * Warning dialog box + */ +// ================================================================ +class WarnDialog: public QDialog +{ + static WarnDialog* myDlg; + bool myCloseFlag; + + WarnDialog( QWidget* parent ) + : QDialog( parent, "WarnDialog", true, WDestructiveClose ) { + setCaption( tr( "Information" ) ); + myCloseFlag = false; + QLabel* lab = new QLabel( tr( "Please, wait while checking native products configuration ..." ), this ); + lab->setAlignment( AlignCenter ); + lab->setFrameStyle( QFrame::Box | QFrame::Plain ); + QVBoxLayout* l = new QVBoxLayout( this ); + l->setMargin( 0 ); + l->add( lab ); + this->setFixedSize( lab->sizeHint().width() + 50, + lab->sizeHint().height() * 5 ); + } + void accept() { return; } + void reject() { return; } + void closeEvent( QCloseEvent* e) { if ( !myCloseFlag ) return; QDialog::closeEvent( e ); } + + ~WarnDialog() { myDlg = 0; } +public: + static void showWarnDlg( QWidget* parent, bool show ) { + if ( show ) { + if ( !myDlg ) { + myDlg = new WarnDialog( parent ); + QSize sh = myDlg->size(); + myDlg->move( parent->x() + (parent->width()-sh.width())/2, + parent->y() + (parent->height()-sh.height())/2 ); + myDlg->show(); + } + } + else { + if ( myDlg ) { + myDlg->myCloseFlag = true; + myDlg->close(); + } + } + } + static bool isWarnDlgShown() { return myDlg != 0; } +}; +WarnDialog* WarnDialog::myDlg = 0; + // ================================================================ /*! * DefineDependeces [ static ] * Defines list of dependancies as string separated by space symbols */ // ================================================================ -static QString DefineDependeces(MapProducts& theProductsMap) { +static QString DefineDependeces(MapProducts& theProductsMap) +{ QStringList aProducts; for ( MapProducts::Iterator mapIter = theProductsMap.begin(); mapIter != theProductsMap.end(); ++mapIter ) { QCheckListItem* item = mapIter.key(); @@ -251,6 +346,9 @@ SALOME_InstallWizard::SALOME_InstallWizard(QString aXmlFileName) connect(shellProcess, SIGNAL( readyReadStderr() ), this, SLOT( readFromStderr() ) ); connect(shellProcess, SIGNAL( processExited() ), this, SLOT( productInstalled() ) ); connect(shellProcess, SIGNAL( wroteToStdin() ), this, SLOT( wroteToStdin() ) ); + + // create validation thread + myThread = new QProcessThread( this ); } // ================================================================ /*! @@ -270,6 +368,7 @@ SALOME_InstallWizard::~SALOME_InstallWizard() if ( system( script.latin1() ) ) { } } + delete myThread; } // ================================================================ /*! @@ -291,6 +390,10 @@ bool SALOME_InstallWizard::eventFilter( QObject* object, QEvent* event ) // ================================================================ void SALOME_InstallWizard::closeEvent( QCloseEvent* ce ) { + if ( WarnDialog::isWarnDlgShown() ) { + ce->ignore(); + return; + } if ( !exitConfirmed ) { if ( QMessageBox::information( this, tr( "Exit" ), @@ -880,8 +983,6 @@ bool SALOME_InstallWizard::acceptData( const QString& pageTitle ) QMessageBox::NoButton ); return false; } - qApp->sendPostedEvents(); - qApp->processEvents(); // VSR: <------------------------------------------------------------------------------ // ########## check native products QCheckListItem* item = (QCheckListItem*)( productsView->firstChild() ); @@ -944,6 +1045,9 @@ bool SALOME_InstallWizard::acceptData( const QString& pageTitle ) } QString tmpFolder = QDir::cleanDirPath( tempFolder->text().stripWhiteSpace() ) + TEMPDIRNAME; QString tgtFolder = QDir::cleanDirPath( targetFolder->text().stripWhiteSpace() ); + qApp->sendPostedEvents(); + qApp->processEvents(); + myThread->clearCommands(); for ( unsigned i = 0; i < natives.count(); i++ ) { item = findItem( natives[ i ] ); if ( item ) { @@ -951,31 +1055,7 @@ bool SALOME_InstallWizard::acceptData( const QString& pageTitle ) QFileInfo( tmpFolder ).absFilePath() + " " + QDir::currentDirPath() + "/Products " + QFileInfo( tgtFolder ).absFilePath() + " " + QUOTE(DefineDependeces(productsMap)) + " " + item->text(0); - ___MESSAGE___( "1. Script : " << script ); - int res = system( script ) / 256; // return code is * 256 - ___MESSAGE___( "try_native() : res = " << res ); - if ( res > 0 ) { - if ( res == 2 ) { - // when try_native returns 2 it means that native product version is higher than that is prerequisited - if ( QMessageBox::warning( this, - tr( "Warning" ), - tr( "You have newer version of %1 installed on your computer than that is required (%2).\nContinue?").arg(item->text(0)).arg(item->text(1)), - QMessageBox::Yes, - QMessageBox::No, - QMessageBox::NoButton ) == QMessageBox::No ) - return false; - } - else { - QMessageBox::warning( this, - tr( "Warning" ), - tr( "You don't have native %1 %2 installed").arg(item->text(0)).arg(item->text(1)), - QMessageBox::Ok, - QMessageBox::NoButton, - QMessageBox::NoButton ); - productsView->setNone( item ); - return false; - } - } + myThread->addCommand( item, script ); } else { QMessageBox::warning( this, @@ -988,6 +1068,8 @@ bool SALOME_InstallWizard::acceptData( const QString& pageTitle ) return false; } } + WarnDialog::showWarnDlg( this, true ); + myThread->start(); } return InstallWizard::acceptData( pageTitle ); } @@ -1110,7 +1192,6 @@ void SALOME_InstallWizard::launchScript() progressView->ensureVisible( prodProc ); QCheckListItem* item = findItem( prodProc ); - Dependancies dep = productsMap[ item ]; // fill in script parameters shellProcess->clearArguments(); // ... script name @@ -1358,6 +1439,10 @@ void SALOME_InstallWizard::accept() // ================================================================ void SALOME_InstallWizard::clean(bool rmDir) { + WarnDialog::showWarnDlg( 0, false ); + myThread->clearCommands(); + myWC.wakeAll(); + while ( myThread->running() ); // VSR: first remove temporary files QString script = "cd ./config_files/; remove_tmp.sh '"; script += tempFolder->text().stripWhiteSpace() + TEMPDIRNAME; @@ -1810,3 +1895,49 @@ void SALOME_InstallWizard::updateCaption() tr( getIWName() ) + " - " + tr( "Step %1 of %2").arg( QString::number( this->indexOf( aPage )+1 ) ).arg( QString::number( this->pageCount() ) ) ); } + +// ================================================================ +/*! + * SALOME_InstallWizard::processValidateEvent + * Processes validation event ( is validation code) + */ +// ================================================================ +void SALOME_InstallWizard::processValidateEvent( const int val, void* data ) +{ + QCheckListItem* item = (QCheckListItem*)data; + if ( val > 0 ) { + if ( val == 2 ) { + WarnDialog::showWarnDlg( 0, false ); + // when try_native returns 2 it means that native product version is higher than that is prerequisited + if ( QMessageBox::warning( this, + tr( "Warning" ), + tr( "You have newer version of %1 installed on your computer than that is required (%2).\nContinue?").arg(item->text(0)).arg(item->text(1)), + QMessageBox::Yes, + QMessageBox::No, + QMessageBox::NoButton ) == QMessageBox::No ) { + myThread->clearCommands(); + myWC.wakeAll(); + return; + } + } + else { + WarnDialog::showWarnDlg( 0, false ); + QMessageBox::warning( this, + tr( "Warning" ), + tr( "You don't have native %1 %2 installed").arg(item->text(0)).arg(item->text(1)), + QMessageBox::Ok, + QMessageBox::NoButton, + QMessageBox::NoButton ); + productsView->setNone( item ); + myThread->clearCommands(); + myWC.wakeAll(); + return; + } + } + if ( myThread->hasCommands() ) + myWC.wakeAll(); + else { + WarnDialog::showWarnDlg( 0, false ); + InstallWizard::processValidateEvent( val, data ); + } +} diff --git a/src/SALOME_InstallWizard.hxx b/src/SALOME_InstallWizard.hxx index 8ea1a01..5f38c9f 100644 --- a/src/SALOME_InstallWizard.hxx +++ b/src/SALOME_InstallWizard.hxx @@ -83,6 +83,7 @@ class QProcess; class QCheckBox; class QSplitter; +class QProcessThread; class ProductsView; class ProgressView; class HelpWindow; @@ -108,6 +109,9 @@ class SALOME_InstallWizard: public InstallWizard // set dependancies void setDependancies( QCheckListItem* item, Dependancies dep); + // process validation event ( is validation code) + void processValidateEvent( const int val, void* data ); + public slots: // polishing of the widget void polish(); @@ -272,6 +276,8 @@ class SALOME_InstallWizard: public InstallWizard QWidget* readmePage; // page itself QTextEdit* readme; // Readme information window QPushButton* runSalomeBtn; // buttnon + + QProcessThread* myThread; // validation thread }; #endif