1 // Copyright (C) 2003 CEA/DEN, EDF R&D
5 // File : InquireServersQThread.cxx
6 // Author : Vasily RUSYAEV
11 #include "InquireServersQThread.h"
14 #include <qpushbutton.h>
15 #include <qabstractlayout.h>
19 #include <qmessagebox.h>
21 #include <qfileinfo.h>
22 #include <qstringlist.h>
24 //VRV: porting on Qt 3.0.5
25 #if QT_VERSION >= 0x030005
26 #include <qdesktopwidget.h>
28 //VRV: porting on Qt 3.0.5
32 #include <SALOMEconfig.h>
34 #include "Utils_ORB_INIT.hxx"
35 #include "Utils_SINGLETON.hxx"
36 #include "SALOME_NamingService.hxx"
37 #include "utilities.h"
40 #include CORBA_CLIENT_HEADER(SALOME_Session)
41 #include CORBA_CLIENT_HEADER(SALOME_Registry)
42 #include CORBA_CLIENT_HEADER(SALOMEDS)
43 #include CORBA_CLIENT_HEADER(SALOME_ModuleCatalog)
44 #include CORBA_CLIENT_HEADER(SALOME_Component)
47 #define SPACING_SIZE 3
49 static QString findFile( QString filename );
50 static QString addSlash( const QString& path );
52 InquireServersGUI::InquireServersGUI()
53 : QVBox(0, "SFA splash", Qt::WDestructiveClose | Qt::WStyle_Customize | Qt::WStyle_NoBorder )
55 myThread = new InquireServersQThread(this);
57 // 1. Polish the appearance
58 setMargin( MARGIN_SIZE );
59 setSpacing( SPACING_SIZE );
60 setFrameStyle( QFrame::Plain | QFrame::Box );
62 setMinimumSize( 200, 150 );
65 QFrame* frm = new QFrame( this );
66 frm->setFrameStyle( QFrame::Box | QFrame::Raised );
67 QHBoxLayout* frmLayout = new QHBoxLayout( frm );
68 frmLayout->setMargin( MARGIN_SIZE );
70 splash = new QLabel( frm, "splash" );
71 frmLayout->addWidget( splash );
73 QString path = findFile( "Application-Splash.png" );
74 splash->setPixmap( QPixmap( path ) );
77 myPrgBar = new QProgressBar( this, "QProgressBar" );
78 myPrgBar->setFixedWidth( splash->pixmap()->isNull() ? 180 : splash->sizeHint().width() );
79 //Sets the total number of steps .
80 myPrgBar->setTotalSteps ( myThread->getInquiredServers() );
81 myPrgBar->setProgress( 0 );
84 QWidget* aWgt1 = new QWidget( this );
85 QHBoxLayout* aHBoxLayout1 = new QHBoxLayout( aWgt1 );
86 myLabel = new QLabel( tr( "Loading:" ), aWgt1 );
87 myLabel->setFixedWidth( splash->pixmap()->isNull() ? 180 : splash->sizeHint().width() );
88 myLabel->setAlignment( AlignLeft );
89 QFont theFont = myLabel->font();
90 theFont.setBold(true);
91 myLabel->setFont( theFont );
92 aHBoxLayout1->addItem( new QSpacerItem( 0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum ) );
93 aHBoxLayout1->addWidget( myLabel );
94 aHBoxLayout1->addItem( new QSpacerItem( 0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum ) );
97 QWidget* aWgt = new QWidget( this );
98 QHBoxLayout* aHBoxLayout = new QHBoxLayout( aWgt );
99 QPushButton* myCancelBtn = new QPushButton( tr( "Cancel" ), aWgt );
100 connect( myCancelBtn, SIGNAL( clicked() ), this, SLOT( ClickOnCancel() ) ) ;
101 aHBoxLayout->addItem( new QSpacerItem( 0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum ) );
102 aHBoxLayout->addWidget( myCancelBtn );
103 aHBoxLayout->addItem( new QSpacerItem( 0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum ) );
106 #if QT_VERSION >= 0x030005
107 QDesktopWidget *d = QApplication::desktop();
109 QWidget *d = QApplication::desktop();
111 //VRV: porting on Qt 3.0.5
113 int w = d->width(); // returns desktop width
114 int h = d->height(); // returns desktop height
115 QSize mySize = sizeHint (); // returns widget size
116 int Xc = ( w - mySize.width() ) / 2;
117 int Yc = ( h - mySize.height() ) / 2;
123 InquireServersGUI::~InquireServersGUI()
128 void InquireServersGUI::getArgs( int& _argc, char *** _argv)
130 _argc = qApp->argc();
131 *_argv = qApp->argv();
134 //=================================================================================
135 // function : ClickOnCancel()
136 // purpose : cancel loading of SALOME
137 //=================================================================================
138 void InquireServersGUI::ClickOnCancel()
140 //it's necessary to stop asking servers
142 //Also we should send QCloseEvent in order to close this widget (and remove from screen)
143 //QThread::postEvent ( this, new QCloseEvent() );
147 void InquireServersGUI::closeEvent ( QCloseEvent * pe)
149 //default implementation calls e->accept(), which hides this widget.
150 //See the QCloseEvent documentation for more details.
152 QApplication::flushX ();
153 QApplication::syncX ();
157 void InquireServersGUI::customEvent( QCustomEvent* pe )
161 case InquireEvent::ProgressEvent:
163 int* value = ( int* )(( InquireEvent*)pe)->data();
164 myPrgBar->setProgress( *value );
167 case InquireEvent::ProgressEventLabel:
169 QString* myString = ( QString* )(( InquireEvent*)pe)->data();
170 myLabel->setText( *myString );
173 case InquireEvent::ProgressEventError:
175 QString* myErrDesc = ( QString* )(( InquireEvent*)pe)->data();
176 QString appName = "SALOME Professional";
177 QString error = "An internal error occurred.\n"+ *myErrDesc + "\n";
178 QMessageBox myMsgBox(appName,error,QMessageBox::Critical,QMessageBox::Ok,QMessageBox::NoButton,
179 QMessageBox::NoButton,0,"MY",TRUE,WStyle_DialogBorder|WStyle_StaysOnTop);
191 int InquireServersGUI::getExitStatus()
193 myThread->getExitStatus();
196 InquireServersQThread::InquireServersQThread( InquireServersGUI* r )
197 : receiver(r), myExitStatus(0)
203 //how many times we should repeat attempts to get response from all needed for launching SALOME servers
204 myRepeat = 30; // default value, user can change it by setting CSF_RepeatServerRequest env.variable
205 cenv = getenv( "CSF_RepeatServerRequest" );
207 int val = atoi( cenv );
211 //define delay time between two attempts
212 myDelay = 1000000; // 1 second
213 QString str = "Loading: ";
214 myMessages[0] = "Checking naming service...";
215 myMessages[1] = str + "SALOME_Registry_Server" + "...";
216 myMessages[2] = str + "SALOME_Container SuperVisionContainer" + "...";
217 myMessages[3] = str + "SALOME_ModuleCatalog_Server" + "...";
218 myMessages[4] = str + "SALOME_ContainerPy.py FactoryServerPy" + "...";
219 myMessages[5] = str + "SALOME_Container FactoryServer" + "...";
220 myMessages[6] = str + "SALOMEDS_Server" + "...";
221 myMessages[7] = str + "SALOME_Session_Server" + "...";
223 r->getArgs( _argc, &_argv);
227 void InquireServersQThread::run()
231 for (int i=1; i<=myServersCount; i++)
233 QString *message = new QString(myMessages[i-1]);
234 QThread::postEvent( receiver, new InquireEvent( ( QEvent::Type )InquireEvent::ProgressEventLabel, message ) );
235 QThread::usleep(200000);
237 bool result = AskServer(i,&errMsg);
240 QThread::postEvent( receiver, new InquireEvent( ( QEvent::Type )InquireEvent::ProgressEvent, new int( i ) ) );
241 if (i==myServersCount)
244 //myExitStatus should be 0 because all servers exist and work
246 //we should send QCloseEvent in order to close this widget (and remove from screen)
247 QThread::postEvent ( receiver , new QCloseEvent() );
252 QThread::postEvent( receiver, new InquireEvent( ( QEvent::Type )InquireEvent::ProgressEventError, errMsg ) );
253 //myExitStatus should be 1 because we didn't receive response from server
261 bool InquireServersQThread::AskServer(int iteration, QString ** errMessage)
263 ASSERT(iteration<=myServersCount);
264 //will be set true if we get response from server
265 bool IsPassed = false;
266 QString errDescription;
270 //First checking - existence of Naming Service
271 for (int i = myRepeat; i ; i--)
275 CORBA::ORB_var orb = CORBA::ORB_init(_argc,_argv) ;
276 CORBA::Object_var obj = orb->resolve_initial_references("NameService");
277 CosNaming::NamingContext_var _root_context = CosNaming::NamingContext::_narrow(obj);
278 if (CORBA::is_nil(_root_context))
284 catch(CORBA::COMM_FAILURE&)
286 MESSAGE("CORBA::COMM_FAILURE: unable to contact the naming service");
290 MESSAGE("Unknown Exception: unable to contact the naming service");
292 QThread::usleep(myDelay);
295 *errMessage = new QString("unable to contact the naming service");
298 //checking - existence of SALOME_Registry_Server
300 //checking - existence of SALOME_Container SuperVisionContainer
302 //checking - existence of SALOME_ModuleCatalog_Server
304 //checking - existence of SALOME_ContainerPy.py FactoryServerPy
306 //checking - existence of SALOME_Container FactoryServer
308 //checking - existence of SALOMEDS_Server
310 //checking - existence of SALOME_Session_Server
313 IsPassed = pingServer(iteration, errDescription);
315 *errMessage = new QString(errDescription);
321 bool InquireServersQThread::pingServer(int iteration, QString& errMessage)
323 ASSERT(iteration<=myServersCount);
326 for (int i = myRepeat; i ; i--)
330 CORBA::ORB_var orb = CORBA::ORB_init(_argc,_argv) ;
331 SALOME_NamingService &NS = *SINGLETON_<SALOME_NamingService>::Instance() ;
332 ASSERT(SINGLETON_<SALOME_NamingService>::IsAlreadyExisting()) ;
338 CORBA::Object_var obj = NS.Resolve("/Registry");
339 Registry::Components_var registry = Registry::Components::_narrow(obj) ;
340 if (!CORBA::is_nil(registry))
342 MESSAGE("/Registry is found");
345 MESSAGE("Registry was activated");
352 string hostname = GetHostname();
353 string containerName = "/Containers/";
354 containerName += hostname;
355 containerName += "/SuperVisionContainer";
357 CORBA::Object_var obj = NS.Resolve(containerName.c_str());
358 Engines::Container_var SVcontainer = Engines::Container::_narrow(obj) ;
359 if (!CORBA::is_nil(SVcontainer))
363 MESSAGE("SuperVisionContainer container was activated");
370 CORBA::Object_var obj = NS.Resolve("Kernel/ModulCatalog");
371 SALOME_ModuleCatalog::ModuleCatalog_var catalog = SALOME_ModuleCatalog::ModuleCatalog::_narrow(obj) ;
372 if (!CORBA::is_nil(catalog))
374 MESSAGE("/Kernel/ModulCatalog is found");
377 MESSAGE("ModuleCatalog was activated");
384 CORBA::Object_var obj = NS.Resolve("Kernel/Session");
385 SALOME::Session_var session = SALOME::Session::_narrow(obj) ;
386 if (!CORBA::is_nil(session))
388 MESSAGE("/Kernel/Session is found");
391 MESSAGE("SALOME_Session was activated");
398 string hostname = GetHostname();
399 string containerName = "/Containers/";
400 containerName += hostname;
401 containerName += "/FactoryServer";
403 CORBA::Object_var obj = NS.Resolve(containerName.c_str());
404 Engines::Container_var FScontainer = Engines::Container::_narrow(obj) ;
405 if (!CORBA::is_nil(FScontainer))
409 MESSAGE("FactoryServer container was activated");
416 string hostname = GetHostname();
417 string containerName = "/Containers/";
418 containerName += hostname;
419 containerName += "/FactoryServerPy";
421 CORBA::Object_var obj = NS.Resolve(containerName.c_str());
422 Engines::Container_var FSPcontainer = Engines::Container::_narrow(obj) ;
423 if (!CORBA::is_nil(FSPcontainer))
425 FSPcontainer->ping();
427 MESSAGE("FactoryServerPy container was activated");
434 CORBA::Object_var obj = NS.Resolve("/myStudyManager");
435 SALOMEDS::StudyManager_var studyManager = SALOMEDS::StudyManager::_narrow(obj) ;
436 if (!CORBA::is_nil(studyManager))
438 MESSAGE("/myStudyManager is found");
439 studyManager->ping();
441 MESSAGE("StudyManager was activated");
448 catch (ServiceUnreachable&)
450 MESSAGE("Caught exception: Naming Service Unreachable");
451 errorDescr = "Caught exception: Naming Service Unreachable";
453 catch (CORBA::COMM_FAILURE&)
455 MESSAGE("Caught CORBA::SystemException CommFailure.");
456 errorDescr = "Caught CORBA::SystemException CommFailure";
458 catch (CORBA::SystemException&)
460 MESSAGE("Caught CORBA::SystemException.");
461 errorDescr = "Caught CORBA::SystemException";
463 catch (CORBA::Exception&)
465 MESSAGE("Caught CORBA::Exception.");
466 errorDescr = "Caught CORBA::Exception";
470 MESSAGE("Caught unknown exception.");
471 errorDescr = "Caught unknown exception";
473 QThread::usleep(myDelay);
481 serverName = "SALOME_Registry_Server is not loaded. ";
484 serverName = "SALOMEDS_Server is not loaded. ";
487 serverName = "SALOME_ModuleCatalog_Server is not loaded. ";
490 serverName = "SALOME_Session_Server is not loaded. ";
493 serverName = "SALOME_Container FactoryServer is not loaded. ";
496 serverName = "SALOME_ContainerPy.py FactoryServerPy is not loaded. ";
499 serverName = "SALOME_Container SuperVisionContainer is not loaded. ";
502 errMessage = serverName + errorDescr;
507 static const char* SEPARATOR = ":";
509 QString findFile( QString filename )
514 // Try CSF_ResourcesDefaults env.var directory ( or directory list )
515 cenv = getenv( "CSF_ResourcesDefaults" );
517 dir.sprintf( "%s", cenv );
518 if ( !dir.isEmpty() ) {
519 QStringList dirList = QStringList::split( SEPARATOR, dir, false ); // skip empty entries
520 for ( int i = 0; i < dirList.count(); i++ ) {
521 QFileInfo fileInfo( addSlash( dirList[ i ] ) + filename );
522 if ( fileInfo.isFile() && fileInfo.exists() )
523 return fileInfo.filePath();
527 // Try ${HOME}/.salome/resources directory
528 cenv = getenv( "HOME" );
530 dir.sprintf( "%s", cenv );
531 if ( !dir.isEmpty() ) {
532 dir = addSlash(dir) ;
533 dir = dir + ".salome" ;
534 dir = addSlash(dir) ;
535 dir = dir + "resources" ;
536 dir = addSlash(dir) ;
537 QFileInfo fileInfo( dir + filename );
538 if ( fileInfo.isFile() && fileInfo.exists() )
539 return fileInfo.filePath();
542 // Try ${SALOME_SITE_DIR}/share/salome/resources directory
543 cenv = getenv( "SALOME_SITE_DIR" );
545 dir.sprintf( "%s", cenv );
546 if ( !dir.isEmpty() ) {
547 dir = addSlash(dir) ;
548 dir = dir + "share" ;
549 dir = addSlash(dir) ;
550 dir = dir + "salome" ;
551 dir = addSlash(dir) ;
552 dir = dir + "resources" ;
553 dir = addSlash(dir) ;
554 QFileInfo fileInfo( dir + filename );
555 if ( fileInfo.isFile() && fileInfo.exists() )
556 return fileInfo.filePath();
559 // Try ${SALOME_ROOT_DIR}/share/salome/resources directory
560 cenv = getenv( "SALOME_ROOT_DIR" );
562 dir.sprintf( "%s", cenv );
563 if ( !dir.isEmpty() ) {
564 dir = addSlash(dir) ;
565 dir = dir + "share" ;
566 dir = addSlash(dir) ;
567 dir = dir + "salome" ;
568 dir = addSlash(dir) ;
569 dir = dir + "resources" ;
570 dir = addSlash(dir) ;
571 QFileInfo fileInfo( dir + filename );
572 if ( fileInfo.isFile() && fileInfo.exists() )
573 return fileInfo.filePath();
578 QString addSlash( const QString& path )
580 if (!path.isNull()) {
586 if ( path.at(path.length()-1) != slash )