From: admin Date: Tue, 3 Jun 2003 09:07:12 +0000 (+0000) Subject: This commit was generated by cvs2git to create branch 'IMPORT'. X-Git-Tag: V1_2~4 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=4f2a85d26ed0f108d7f408f55bda7e9a06ea544b;p=modules%2Fkernel.git This commit was generated by cvs2git to create branch 'IMPORT'. Cherrypick from master 2003-06-03 09:07:11 UTC nri 'NRI : Add Loader.': src/Loader/InquireServersQThread.cxx src/Loader/InquireServersQThread.h src/Loader/Makefile.in --- diff --git a/src/Loader/InquireServersQThread.cxx b/src/Loader/InquireServersQThread.cxx new file mode 100644 index 000000000..1102aa39a --- /dev/null +++ b/src/Loader/InquireServersQThread.cxx @@ -0,0 +1,616 @@ +//============================================================================= +// File : InquireServersQThread.cxx +// Created : Mon Oct 21 17:26:42 2002 +// Author : Vasily RUSYAEV +// Project : SALOME +// Copyright : EDF 2001 +// $Header$ +//============================================================================= + +using namespace std; + +#include "InquireServersQThread.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//VRV: porting on Qt 3.0.5 +#if QT_VERSION >= 0x030005 +#include +#endif +//VRV: porting on Qt 3.0.5 + +#include + +#include + +#include "Utils_ORB_INIT.hxx" +#include "Utils_SINGLETON.hxx" +#include "SALOME_NamingService.hxx" +#include "utilities.h" +#include "OpUtil.hxx" + +#include CORBA_CLIENT_HEADER(SALOME_Session) +#include CORBA_CLIENT_HEADER(SALOME_Registry) +#include CORBA_CLIENT_HEADER(SALOMEDS) +#include CORBA_CLIENT_HEADER(SALOME_ModuleCatalog) +#include CORBA_CLIENT_HEADER(SALOME_Component) + +#define MARGIN_SIZE 5 +#define SPACING_SIZE 3 + +static QString findFile( QString filename ); +static QString addSlash( const QString& path ); + +InquireServersGUI::InquireServersGUI() + : QVBox(0, "SFA splash", Qt::WDestructiveClose | Qt::WStyle_Customize | Qt::WStyle_NoBorder ) +{ + myThread = new InquireServersQThread(this); + + // 1. Polish the appearance + setMargin( MARGIN_SIZE ); + setSpacing( SPACING_SIZE ); + setFrameStyle( QFrame::Plain | QFrame::Box ); + setLineWidth( 2 ); + setMinimumSize( 200, 150 ); + + // 2. Splash image + QFrame* frm = new QFrame( this ); + frm->setFrameStyle( QFrame::Box | QFrame::Raised ); + QHBoxLayout* frmLayout = new QHBoxLayout( frm ); + frmLayout->setMargin( MARGIN_SIZE ); + QLabel* splash = 0; + splash = new QLabel( frm, "splash" ); + frmLayout->addWidget( splash ); + // setting pixmap + QString path = findFile( "Application-Splash.png" ); + splash->setPixmap( QPixmap( path ) ); + + // 3. Progress bar + myPrgBar = new QProgressBar( this, "QProgressBar" ); + myPrgBar->setFixedWidth( splash->pixmap()->isNull() ? 180 : splash->sizeHint().width() ); + //Sets the total number of steps . + myPrgBar->setTotalSteps ( myThread->getInquiredServers() ); + myPrgBar->setProgress( 0 ); + + // 4. Info label + QWidget* aWgt1 = new QWidget( this ); + QHBoxLayout* aHBoxLayout1 = new QHBoxLayout( aWgt1 ); + myLabel = new QLabel( tr( "Loading:" ), aWgt1 ); + myLabel->setFixedWidth( splash->pixmap()->isNull() ? 180 : splash->sizeHint().width() ); + myLabel->setAlignment( AlignLeft ); + QFont theFont = myLabel->font(); + theFont.setBold(true); + myLabel->setFont( theFont ); + aHBoxLayout1->addItem( new QSpacerItem( 0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum ) ); + aHBoxLayout1->addWidget( myLabel ); + aHBoxLayout1->addItem( new QSpacerItem( 0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum ) ); + + // 5. button + QWidget* aWgt = new QWidget( this ); + QHBoxLayout* aHBoxLayout = new QHBoxLayout( aWgt ); + QPushButton* myCancelBtn = new QPushButton( tr( "Cancel" ), aWgt ); + connect( myCancelBtn, SIGNAL( clicked() ), this, SLOT( ClickOnCancel() ) ) ; + aHBoxLayout->addItem( new QSpacerItem( 0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum ) ); + aHBoxLayout->addWidget( myCancelBtn ); + aHBoxLayout->addItem( new QSpacerItem( 0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum ) ); + + //Center widget +#if QT_VERSION >= 0x030005 + QDesktopWidget *d = QApplication::desktop(); +#else + QWidget *d = QApplication::desktop(); +#endif +//VRV: porting on Qt 3.0.5 + + int w = d->width(); // returns desktop width + int h = d->height(); // returns desktop height + QSize mySize = sizeHint (); // returns widget size + int Xc = ( w - mySize.width() ) / 2; + int Yc = ( h - mySize.height() ) / 2; + move( Xc, Yc ); + + myThread->start(); +} + +InquireServersGUI::~InquireServersGUI() +{ + delete myThread; +} + +void InquireServersGUI::getArgs( int& _argc, char *** _argv) +{ + _argc = qApp->argc(); + *_argv = qApp->argv(); +} + +//================================================================================= +// function : ClickOnCancel() +// purpose : cancel loading of SALOME +//================================================================================= +void InquireServersGUI::ClickOnCancel() +{ + //it's necessary to stop asking servers + myThread->stop(); + //Also we should send QCloseEvent in order to close this widget (and remove from screen) + //QThread::postEvent ( this, new QCloseEvent() ); + qApp->exit(1); +} + +void InquireServersGUI::closeEvent ( QCloseEvent * pe) +{ + //default implementation calls e->accept(), which hides this widget. + //See the QCloseEvent documentation for more details. + pe->accept(); + QApplication::flushX (); + QApplication::syncX (); + qApp->exit(); +} + +void InquireServersGUI::customEvent( QCustomEvent* pe ) +{ + switch( pe->type() ) + { + case InquireEvent::ProgressEvent: + { + int* value = ( int* )(( InquireEvent*)pe)->data(); + myPrgBar->setProgress( *value ); + break; + } + case InquireEvent::ProgressEventLabel: + { + QString* myString = ( QString* )(( InquireEvent*)pe)->data(); + myLabel->setText( *myString ); + break; + } + case InquireEvent::ProgressEventError: + { + QString* myErrDesc = ( QString* )(( InquireEvent*)pe)->data(); + QString appName = "SALOME Professional"; + QString error = "An internal error occurred.\n"+ *myErrDesc + "\n"; + QMessageBox myMsgBox(appName,error,QMessageBox::Critical,QMessageBox::Ok,QMessageBox::NoButton, + QMessageBox::NoButton,0,"MY",TRUE,WStyle_DialogBorder|WStyle_StaysOnTop); + myMsgBox.exec(); + ClickOnCancel(); + break; + } + default: + { + ; + } + } +} + +int InquireServersGUI::getExitStatus() +{ + myThread->getExitStatus(); +} + +InquireServersQThread::InquireServersQThread( InquireServersGUI* r ) + : receiver(r), myExitStatus(0) +{ + char* cenv; + + IsChecking = true; + myServersCount = 8; + //how many times we should repeat attempts to get response from all needed for launching SALOME servers + myRepeat = 30; // default value, user can change it by setting CSF_RepeatServerRequest env.variable + cenv = getenv( "CSF_RepeatServerRequest" ); + if ( cenv ) { + int val = atoi( cenv ); + if ( val > 0 ) + myRepeat = val; + } + //define delay time between two attempts + myDelay = 1000000; // 1 second + QString str = "Loading: "; + myMessages[0] = "Checking naming service..."; + myMessages[1] = str + "SALOME_Registry_Server" + "..."; + myMessages[2] = str + "SALOMEDS_Server" + "..."; + myMessages[3] = str + "SALOME_ModuleCatalog_Server" + "..."; + myMessages[4] = str + "SALOME_Session_Server" + "..."; + myMessages[5] = ""; + myMessages[6] = ""; + myMessages[7] = ""; + + r->getArgs( _argc, &_argv); + + // NRI : Temporary solution for SuperVisionContainer + for ( int i=1; i<=_argc; i++) { + if (strcmp(_argv[i],"CPP")==0) + myMessages[5] = str + "SALOME_Container FactoryServer" + "..."; + if (strcmp(_argv[i],"PYTHON")==0) + myMessages[6] = str + "SALOME_ContainerPy.py FactoryServerPy" + "..."; + if (strcmp(_argv[i],"SUPERV")==0) + myMessages[7] = str + "SALOME_Container SuperVisionContainer" + "..."; + } +} + +void InquireServersQThread::run() +{ +while (IsChecking) + { + for (int i=1; i<=myServersCount; i++) + { + if ( myMessages[i-1].isEmpty() ) continue; + QString *message = new QString(myMessages[i-1]); + QThread::postEvent( receiver, new InquireEvent( ( QEvent::Type )InquireEvent::ProgressEventLabel, message ) ); + QThread::usleep(200000); + QString *errMsg; + bool result = AskServer(i,&errMsg); + if (result) + { + QThread::postEvent( receiver, new InquireEvent( ( QEvent::Type )InquireEvent::ProgressEvent, new int( i ) ) ); + if (i==myServersCount) + { + IsChecking = false; + //myExitStatus should be 0 because all servers exist and work + myExitStatus = 0; + //we should send QCloseEvent in order to close this widget (and remove from screen) + QThread::postEvent ( receiver , new QCloseEvent() ); + } + } + else + { + QThread::postEvent( receiver, new InquireEvent( ( QEvent::Type )InquireEvent::ProgressEventError, errMsg ) ); + //myExitStatus should be 1 because we didn't receive response from server + myExitStatus = 1; + return; + } + } + } +} + +bool InquireServersQThread::AskServer(int iteration, QString ** errMessage) +{ + ASSERT(iteration<=myServersCount); + //will be set true if we get response from server + bool IsPassed = false; + QString errDescription; + switch (iteration) + { + case 1: + //First checking - existence of Naming Service + for (int i = myRepeat; i ; i--) + { + try + { + CORBA::ORB_var orb = CORBA::ORB_init(_argc,_argv) ; + CORBA::Object_var obj = orb->resolve_initial_references("NameService"); + CosNaming::NamingContext_var _root_context = CosNaming::NamingContext::_narrow(obj); + if (CORBA::is_nil(_root_context)) + continue; + else + IsPassed = true; + break; + } + catch(CORBA::COMM_FAILURE&) + { + MESSAGE("CORBA::COMM_FAILURE: unable to contact the naming service"); + } + catch(...) + { + MESSAGE("Unknown Exception: unable to contact the naming service"); + } + QThread::usleep(myDelay); + } + if (!IsPassed) + *errMessage = new QString("unable to contact the naming service"); + break; + case 2: + //checking - existence of SALOME_Registry_Server + case 3: + //checking - existence of SALOMEDS_Server + case 4: + //checking - existence of SALOME_ModuleCatalog_Server + case 5: + //checking - existence of SALOME_Session_Server + case 6: + //checking - existence of SALOME_Container FactoryServer + case 7: + //checking - existence of SALOME_ContainerPy.py FactoryServerPy + case 8: + //checking - existence of SALOME_Container SuperVisionContainer + IsPassed = pingServer(iteration, errDescription); + if (!IsPassed) + *errMessage = new QString(errDescription); + break; + } +return IsPassed; +} + +bool InquireServersQThread::pingServer(int iteration, QString& errMessage) +{ + ASSERT(iteration<=myServersCount); + bool result = false; + QString errorDescr; + for (int i = myRepeat; i ; i--) + { + try + { + CORBA::ORB_var orb = CORBA::ORB_init(_argc,_argv) ; + SALOME_NamingService &NS = *SINGLETON_::Instance() ; + ASSERT(SINGLETON_::IsAlreadyExisting()) ; + NS.init_orb( orb ) ; + switch (iteration) + { + case 2: + { + CORBA::Object_var obj = NS.Resolve("/Registry"); + Registry::Components_var registry = Registry::Components::_narrow(obj) ; + if (!CORBA::is_nil(registry)) + { + MESSAGE("/Registry is found"); + registry->ping(); + result = true; + MESSAGE("Registry was activated"); + return result; + } + } + break; + case 3: + { + CORBA::Object_var obj = NS.Resolve("/myStudyManager"); + SALOMEDS::StudyManager_var studyManager = SALOMEDS::StudyManager::_narrow(obj) ; + if (!CORBA::is_nil(studyManager)) + { + MESSAGE("/myStudyManager is found"); + studyManager->ping(); + result = true; + MESSAGE("StudyManager was activated"); + return result; + } + } + break; + case 4: + { + CORBA::Object_var obj = NS.Resolve("Kernel/ModulCatalog"); + SALOME_ModuleCatalog::ModuleCatalog_var catalog = SALOME_ModuleCatalog::ModuleCatalog::_narrow(obj) ; + if (!CORBA::is_nil(catalog)) + { + MESSAGE("/Kernel/ModulCatalog is found"); + catalog->ping(); + result = true; + MESSAGE("ModuleCatalog was activated"); + return result; + } + } + break; + case 5: + { + CORBA::Object_var obj = NS.Resolve("Kernel/Session"); + SALOME::Session_var session = SALOME::Session::_narrow(obj) ; + if (!CORBA::is_nil(session)) + { + MESSAGE("/Kernel/Session is found"); + session->ping(); + result = true; + MESSAGE("SALOME_Session was activated"); + return result; + } + } + break; + case 6: + { + string hostname = GetHostname(); + string containerName = "/Containers/"; + containerName += hostname; + containerName += "/FactoryServer"; + + CORBA::Object_var obj = NS.Resolve(containerName.c_str()); + Engines::Container_var FScontainer = Engines::Container::_narrow(obj) ; + if (!CORBA::is_nil(FScontainer)) + { + FScontainer->ping(); + result = true; + MESSAGE("FactoryServer container was activated"); + return result; + } + } + break; + case 7: + { + string hostname = GetHostname(); + string containerName = "/Containers/"; + containerName += hostname; + containerName += "/FactoryServerPy"; + + CORBA::Object_var obj = NS.Resolve(containerName.c_str()); + Engines::Container_var FSPcontainer = Engines::Container::_narrow(obj) ; + if (!CORBA::is_nil(FSPcontainer)) + { + FSPcontainer->ping(); + result = true; + MESSAGE("FactoryServerPy container was activated"); + return result; + } + } + break; + case 8: + { + string hostname = GetHostname(); + string containerName = "/Containers/"; + containerName += hostname; + containerName += "/SuperVisionContainer"; + + CORBA::Object_var obj = NS.Resolve(containerName.c_str()); + Engines::Container_var SVcontainer = Engines::Container::_narrow(obj) ; + if (!CORBA::is_nil(SVcontainer)) + { + SVcontainer->ping(); + result = true; + MESSAGE("SuperVisionContainer container was activated"); + return result; + } + } + break; + } + } + catch (ServiceUnreachable&) + { + MESSAGE("Caught exception: Naming Service Unreachable"); + errorDescr = "Caught exception: Naming Service Unreachable"; + } + catch (CORBA::COMM_FAILURE&) + { + MESSAGE("Caught CORBA::SystemException CommFailure."); + errorDescr = "Caught CORBA::SystemException CommFailure"; + } + catch (CORBA::SystemException&) + { + MESSAGE("Caught CORBA::SystemException."); + errorDescr = "Caught CORBA::SystemException"; + } + catch (CORBA::Exception&) + { + MESSAGE("Caught CORBA::Exception."); + errorDescr = "Caught CORBA::Exception"; + } + catch (...) + { + MESSAGE("Caught unknown exception."); + errorDescr = "Caught unknown exception"; + } + QThread::usleep(myDelay); + } + if (!result) + { + QString serverName; + switch (iteration) + { + case 2: + serverName = "SALOME_Registry_Server is not loaded. "; + break; + case 3: + serverName = "SALOMEDS_Server is not loaded. "; + break; + case 4: + serverName = "SALOME_ModuleCatalog_Server is not loaded. "; + break; + case 5: + serverName = "SALOME_Session_Server is not loaded. "; + break; + case 6: + serverName = "SALOME_Container FactoryServer is not loaded. "; + break; + case 7: + serverName = "SALOME_ContainerPy.py FactoryServerPy is not loaded. "; + break; + case 8: + serverName = "SALOME_Container SuperVisionContainer is not loaded. "; + break; + } + errMessage = serverName + errorDescr; + } + return result; +} + +static const char* SEPARATOR = ":"; + +QString findFile( QString filename ) +{ + QString dir; + char* cenv; + + // Try ${SALOME_ROOT_DIR}/share/salome/resources directory + cenv = getenv( "KERNEL_ROOT_DIR" ); + if ( cenv ) { + dir.sprintf( "%s", cenv ); + if ( !dir.isEmpty() ) { + dir = addSlash(dir) ; + dir = dir + "share" ; + dir = addSlash(dir) ; + dir = dir + "salome" ; + dir = addSlash(dir) ; + dir = dir + "resources" ; + dir = addSlash(dir) ; + QFileInfo fileInfo( dir + filename ); + if ( fileInfo.isFile() && fileInfo.exists() ) + return fileInfo.filePath(); + } + } + // Try CSF_ResourcesDefaults env.var directory ( or directory list ) + cenv = getenv( "CSF_ResourcesDefaults" ); + if ( cenv ) { + dir.sprintf( "%s", cenv ); + if ( !dir.isEmpty() ) { + QStringList dirList = QStringList::split( SEPARATOR, dir, false ); // skip empty entries + for ( int i = 0; i < dirList.count(); i++ ) { + QFileInfo fileInfo( addSlash( dirList[ i ] ) + filename ); + if ( fileInfo.isFile() && fileInfo.exists() ) + return fileInfo.filePath(); + } + } + } + // Try ${HOME}/.salome/resources directory + cenv = getenv( "HOME" ); + if ( cenv ) { + dir.sprintf( "%s", cenv ); + if ( !dir.isEmpty() ) { + dir = addSlash(dir) ; + dir = dir + ".salome" ; + dir = addSlash(dir) ; + dir = dir + "resources" ; + dir = addSlash(dir) ; + QFileInfo fileInfo( dir + filename ); + if ( fileInfo.isFile() && fileInfo.exists() ) + return fileInfo.filePath(); + } + } + // Try ${SALOME_SITE_DIR}/share/salome/resources directory + cenv = getenv( "SALOME_SITE_DIR" ); + if ( cenv ) { + dir.sprintf( "%s", cenv ); + if ( !dir.isEmpty() ) { + dir = addSlash(dir) ; + dir = dir + "share" ; + dir = addSlash(dir) ; + dir = dir + "salome" ; + dir = addSlash(dir) ; + dir = dir + "resources" ; + dir = addSlash(dir) ; + QFileInfo fileInfo( dir + filename ); + if ( fileInfo.isFile() && fileInfo.exists() ) + return fileInfo.filePath(); + } + } + // Try ${SALOME_ROOT_DIR}/share/salome/resources directory + cenv = getenv( "SALOME_ROOT_DIR" ); + if ( cenv ) { + dir.sprintf( "%s", cenv ); + if ( !dir.isEmpty() ) { + dir = addSlash(dir) ; + dir = dir + "share" ; + dir = addSlash(dir) ; + dir = dir + "salome" ; + dir = addSlash(dir) ; + dir = dir + "resources" ; + dir = addSlash(dir) ; + QFileInfo fileInfo( dir + filename ); + if ( fileInfo.isFile() && fileInfo.exists() ) + return fileInfo.filePath(); + } + } + return filename; +} +QString addSlash( const QString& path ) +{ + if (!path.isNull()) { +#ifdef WNT + QChar slash ('\\'); +#else + QChar slash ('/'); +#endif + if ( path.at(path.length()-1) != slash ) + return path + slash; + } + return path; +} diff --git a/src/Loader/InquireServersQThread.h b/src/Loader/InquireServersQThread.h new file mode 100644 index 000000000..b67983b76 --- /dev/null +++ b/src/Loader/InquireServersQThread.h @@ -0,0 +1,111 @@ +//============================================================================= +// File : InquireServersQThread.h +// Created : Mon Oct 21 17:26:42 2002 +// Author : Vasily RUSYAEV +// Project : SALOME +// Copyright : EDF 2001 +// $Header$ +//============================================================================= + +#include +#include +#include +#include +#include + +/********************************************************** +** Class: InquireEvent +** Descr: Contains QCustomEvents for posting to InquireServersQThread +** Level: Private +***********************************************************/ + +class InquireEvent : public QCustomEvent +{ +public: + + enum myCustomEvents{ ProgressEvent = QEvent::User + 10, ProgressEventLabel, ProgressEventError }; + + InquireEvent( QEvent::Type type , void* data = 0 ) + : QCustomEvent( type, data ) {} + ~InquireEvent() + { + type() == (QEvent::Type)ProgressEvent ? + delete ( int* )data() : delete ( QString* )data(); + } +}; + +class InquireServersGUI; + +class InquireServersQThread : public QThread +{ +public: + InquireServersQThread( InquireServersGUI* r ); + + //the main loop of this thread + virtual void run() ; + //stop to ask servers + void stop() + { + IsChecking = false; + myExitStatus = 1; + } + //return exit status: 0 - OK, >0 - BAD (some servers doesn't exists or user click cancel button) + int getExitStatus() { return myExitStatus;} + //return count of inquired servers + int getInquiredServers() { return myServersCount; } + +private: + +//functions: + + bool AskServer(int iteration, QString ** message); + bool pingServer(int iteration, QString& errMessage); + +//variables: + + InquireServersGUI* receiver; + int _argc ; + char ** _argv; + //this variable is true if we are checking servers + bool IsChecking; + //count of inquired servers + int myServersCount; + //how many times we should repeat attempt to get response from all needed for launching SALOME servers + int myRepeat; + //define delay time between two attempts in microseconds + int myDelay; + //this strings' array contains messages for each server (e.g. "Loading: SALOMEDS_Server") + QString myMessages[8]; + //exit status: 0 - OK, >0 - BAD (some servers doesn't exists or user click cancel button) + int myExitStatus; + +} ; + +class InquireServersGUI : public QVBox +{ + Q_OBJECT + +public: + InquireServersGUI() ; + ~InquireServersGUI(); + + //returns arguments of QApplication + //they are needed for CORBA servers initialization + void getArgs( int& _argc, char *** _argv); + //return exit status: 0 - OK, >0 - BAD (some servers doesn't exists or user click cancel button) + int getExitStatus(); + +protected: + virtual void customEvent( QCustomEvent* ); + virtual void closeEvent ( QCloseEvent * ); + +private: + InquireServersQThread* myThread; + QProgressBar* myPrgBar; + //this string contains description of currently asked server + QLabel* myLabel; + +private slots: + + void ClickOnCancel(); +} ; diff --git a/src/Loader/Makefile.in b/src/Loader/Makefile.in new file mode 100644 index 000000000..ec05f0465 --- /dev/null +++ b/src/Loader/Makefile.in @@ -0,0 +1,40 @@ +#============================================================================== +# File : Makefile.in +# Created : mar jui 3 12:59:20 CEST 2001 +# Author : Paul RASCLE, EDF +# Project : SALOME +# Copyright : EDF 2001 +# $Header$ +#============================================================================== + +# source path +top_srcdir=@top_srcdir@ +top_builddir=../.. +srcdir=@srcdir@ +VPATH=.:@srcdir@:@top_srcdir@/idl + + +@COMMENCE@ + +# Executables targets +BIN = SALOME_Session_Loader + +BIN_MOC = InquireServersQThread.h +BIN_SRC = InquireServersQThread.cxx + +BIN_CLIENT_IDL = SALOME_Session.idl \ + SALOMEDS.idl \ + SALOMEDS_Attributes.idl \ + SALOME_Component.idl \ + SALOME_ModuleCatalog.idl \ + SALOME_Registry.idl \ + SALOME_Exception.idl + + +CPPFLAGS+=$(QT_MT_INCLUDES) +CXXFLAGS+=$(OCC_CXXFLAGS) +LDFLAGS+=$(QT_MT_LIBS) -lSalomeNS -lOpUtil -lSalomeLoggerServer + + +@CONCLUDE@ +