#include <qhbox.h>
#include <qobjectlist.h>
+#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 ),
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 <---
}
}
*/
bool InstallWizard::acceptData( const QString& )
{
+ postValidateEvent( this );
return TRUE;
}
}
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 );
+}
#include <qwhatsthis.h>
#include <qtooltip.h>
#include <qfile.h>
+#include <qthread.h>
+#include <qwaitcondition.h>
#ifdef WNT
#include <iostream.h>
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<QCheckListItem> 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 <errno> * 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();
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 );
}
// ================================================================
/*!
if ( system( script.latin1() ) ) {
}
}
+ delete myThread;
}
// ================================================================
/*!
// ================================================================
void SALOME_InstallWizard::closeEvent( QCloseEvent* ce )
{
+ if ( WarnDialog::isWarnDlgShown() ) {
+ ce->ignore();
+ return;
+ }
if ( !exitConfirmed ) {
if ( QMessageBox::information( this,
tr( "Exit" ),
QMessageBox::NoButton );
return false;
}
- qApp->sendPostedEvents();
- qApp->processEvents();
// VSR: <------------------------------------------------------------------------------
// ########## check native products
QCheckListItem* item = (QCheckListItem*)( productsView->firstChild() );
}
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 ) {
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 <errno> * 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,
return false;
}
}
+ WarnDialog::showWarnDlg( this, true );
+ myThread->start();
}
return InstallWizard::acceptData( pageTitle );
}
progressView->ensureVisible( prodProc );
QCheckListItem* item = findItem( prodProc );
- Dependancies dep = productsMap[ item ];
// fill in script parameters
shellProcess->clearArguments();
// ... script name
// ================================================================
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;
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 (<val> 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 );
+ }
+}