1 // Copyright (C) 2003 CEA/DEN, EDF R&D
5 // File : InquireServersQThread.cxx
6 // Author : Vasily RUSYAEV
11 #include "InquireServersQThread.h"
13 #include <qapplication.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 InquireServersGUI::InquireServersGUI()
50 : QVBox(0, "SFA splash", Qt::WDestructiveClose | Qt::WStyle_Customize | Qt::WStyle_NoBorder | WType_TopLevel | WStyle_StaysOnTop | WX11BypassWM )
53 myThread = new InquireServersQThread( this );
55 // 1. Polish the appearance
56 setMargin( MARGIN_SIZE );
57 setSpacing( SPACING_SIZE );
58 setFrameStyle( QFrame::Plain | QFrame::Box );
60 setMinimumSize( 200, 150 );
63 QFrame* frm = new QFrame( this );
64 frm->setFrameStyle( QFrame::Box | QFrame::Raised );
65 QHBoxLayout* frmLayout = new QHBoxLayout( frm );
66 frmLayout->setMargin( MARGIN_SIZE );
67 mySplash = new QLabel( frm, "splash" );
68 frmLayout->addWidget( mySplash );
71 //QPixmap pix = SUIT_ResourceMgr( "SalomeApp" ).loadPixmap( "SalomeApp", tr( "ABOUT" ) );
72 //splash->setPixmap( pix );
75 myPrgBar = new QProgressBar( this, "QProgressBar" );
76 myPrgBar->setFixedWidth( 180 );
77 //Sets the total number of steps .
78 myPrgBar->setTotalSteps ( myThread->getInquiredServers() );
79 myPrgBar->setProgress( 0 );
82 QWidget* aWgt1 = new QWidget( this );
83 QHBoxLayout* aHBoxLayout1 = new QHBoxLayout( aWgt1 );
84 myLabel = new QLabel( tr( "Loading:" ), aWgt1 );
85 myLabel->setFixedWidth( 180 );
86 myLabel->setAlignment( AlignLeft );
87 QFont theFont = myLabel->font();
88 theFont.setBold(true);
89 myLabel->setFont( theFont );
90 aHBoxLayout1->addItem( new QSpacerItem( 0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum ) );
91 aHBoxLayout1->addWidget( myLabel );
92 aHBoxLayout1->addItem( new QSpacerItem( 0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum ) );
95 QWidget* aWgt = new QWidget( this );
96 QHBoxLayout* aHBoxLayout = new QHBoxLayout( aWgt );
97 QPushButton* myCancelBtn = new QPushButton( tr( "Cancel" ), aWgt );
98 connect( myCancelBtn, SIGNAL( clicked() ), this, SLOT( ClickOnCancel() ) ) ;
99 aHBoxLayout->addItem( new QSpacerItem( 0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum ) );
100 aHBoxLayout->addWidget( myCancelBtn );
101 aHBoxLayout->addItem( new QSpacerItem( 0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum ) );
104 #if QT_VERSION >= 0x030005
105 QDesktopWidget *d = QApplication::desktop();
107 QWidget *d = QApplication::desktop();
109 //VRV: porting on Qt 3.0.5
111 int w = d->width(); // returns desktop width
112 int h = d->height(); // returns desktop height
113 QSize mySize = sizeHint (); // returns widget size
114 int Xc = ( w - mySize.width() ) / 2;
115 int Yc = ( h - mySize.height() ) / 2;
121 void InquireServersGUI::setPixmap( QPixmap pix )
123 if ( !pix.isNull() ) {
124 mySplash->setPixmap( pix );
125 myPrgBar->setFixedWidth( mySplash->sizeHint().width() );
126 myLabel->setFixedWidth( mySplash->sizeHint().width() );
130 InquireServersGUI::~InquireServersGUI()
132 // Thread deletes itself in the end of run() function
136 void InquireServersGUI::getArgs( int& _argc, char *** _argv)
138 _argc = qApp->argc();
139 *_argv = qApp->argv();
142 //=================================================================================
143 // function : ClickOnCancel()
144 // purpose : cancel loading of SALOME
145 //=================================================================================
146 void InquireServersGUI::ClickOnCancel()
148 //it's necessary to stop asking servers
151 //Also we should send QCloseEvent in order to close this widget (and remove from screen)
152 //QThread::postEvent ( this, new QCloseEvent() );
156 void InquireServersGUI::closeEvent ( QCloseEvent * pe)
158 //default implementation calls e->accept(), which hides this widget.
159 //See the QCloseEvent documentation for more details.
161 QApplication::flushX ();
162 QApplication::syncX ();
166 void InquireServersGUI::customEvent( QCustomEvent* pe )
170 case InquireEvent::ProgressEvent:
172 int* value = ( int* )(( InquireEvent*)pe)->data();
173 myPrgBar->setProgress( *value );
176 case InquireEvent::ProgressEventLabel:
178 QString* myString = ( QString* )(( InquireEvent*)pe)->data();
179 myLabel->setText( *myString );
182 case InquireEvent::ProgressEventError:
184 QString* myErrDesc = ( QString* )(( InquireEvent*)pe)->data();
185 QString appName = "SALOME Professional";
186 QString error = "An internal error occurred.\n"+ *myErrDesc + "\n";
187 QMessageBox myMsgBox(appName,error,QMessageBox::Critical,QMessageBox::Ok,QMessageBox::NoButton,
188 QMessageBox::NoButton,0,"MY",TRUE,WStyle_DialogBorder|WStyle_StaysOnTop);
200 int InquireServersGUI::getExitStatus()
202 return myThread->getExitStatus();
205 InquireServersQThread::InquireServersQThread( InquireServersGUI* r )
206 : receiver(r), myExitStatus(0)
212 //how many times we should repeat attempts to get response from all needed for launching SALOME servers
213 myRepeat = 30; // default value, user can change it by setting CSF_RepeatServerRequest env.variable
214 cenv = getenv( "CSF_RepeatServerRequest" );
216 int val = atoi( cenv );
220 //define delay time between two attempts
221 myDelay = 1000000; // 1 second
222 QString str = "Loading: ";
223 myMessages[0] = "Checking naming service...";
224 myMessages[1] = str + "SALOME_Registry_Server" + "...";
225 myMessages[2] = str + "SALOMEDS_Server" + "...";
226 myMessages[3] = str + "SALOME_ModuleCatalog_Server" + "...";
227 myMessages[4] = str + "SALOME_Session_Server" + "...";
232 r->getArgs( _argc, &_argv);
234 // NRI : Temporary solution for SuperVisionContainer
235 for ( int i=1; i<=(_argc-1); i++) {
236 if (strcmp(_argv[i],"CPP")==0) {
237 myMessages[5] = str + "SALOME_Container FactoryServer" + "...";
240 if (strcmp(_argv[i],"PY")==0) {
241 myMessages[6] = str + "SALOME_ContainerPy.py FactoryServerPy" + "...";
244 if (strcmp(_argv[i],"SUPERV")==0) {
245 myMessages[7] = str + "SALOME_Container SuperVisionContainer" + "...";
248 // if (strcmp(_argv[i],"GUI")==0) {
254 void InquireServersQThread::run()
256 while ( IsChecking && receiver )
258 for (int i=1; i<=8; i++)
260 if ( myMessages[i-1].isEmpty() ) {
263 //myExitStatus should be 0 because all servers exist and work
265 //we should send QCloseEvent in order to close this widget (and remove from screen)
266 qApp->processEvents();
267 sleep( 1 ); // sleep( 1 second ) in order to see 100%. in other case it closes on 85%..
268 QThread::postEvent ( receiver , new QCloseEvent() );
273 QString *message = new QString(myMessages[i-1]);
274 QThread::postEvent( receiver, new InquireEvent( ( QEvent::Type )InquireEvent::ProgressEventLabel, message ) );
275 QThread::usleep(200000);
277 bool result = AskServer(i,&errMsg);
280 QThread::postEvent( receiver, new InquireEvent( ( QEvent::Type )InquireEvent::ProgressEvent, new int( i ) ) );
284 //myExitStatus should be 0 because all servers exist and work
286 //we should send QCloseEvent in order to close this widget (and remove from screen)
287 qApp->processEvents();
288 sleep( 1 ); // sleep( 1 second ) in order to see 100%. in other case it closes on 85%..
289 QThread::postEvent ( receiver , new QCloseEvent() );
295 QThread::postEvent( receiver, new InquireEvent( ( QEvent::Type )InquireEvent::ProgressEventError, errMsg ) );
296 //myExitStatus should be 1 because we didn't receive response from server
303 // this outputs WARNING: QThread object is deleted while still running -- it's OK in our case!
307 InquireServersQThread::~InquireServersQThread()
311 bool InquireServersQThread::AskServer(int iteration, QString ** errMessage)
313 if ( iteration > myServersCount )
314 return true; // we did not launch server with number iteration, so checking for it is not neccessary
316 ASSERT(iteration<=myServersCount);
318 //will be set true if we get response from server
319 bool IsPassed = false;
320 QString errDescription;
324 //First checking - existence of Naming Service
325 for (int i = myRepeat; i ; i--)
329 CORBA::ORB_var orb = CORBA::ORB_init(_argc,_argv) ;
330 CORBA::Object_var obj = orb->resolve_initial_references("NameService");
331 CosNaming::NamingContext_var _root_context = CosNaming::NamingContext::_narrow(obj);
332 if (CORBA::is_nil(_root_context))
338 catch(CORBA::COMM_FAILURE&)
340 MESSAGE("CORBA::COMM_FAILURE: unable to contact the naming service");
344 MESSAGE("Unknown Exception: unable to contact the naming service");
346 QThread::usleep(myDelay);
349 *errMessage = new QString("unable to contact the naming service");
352 //checking - existence of SALOME_Registry_Server
354 //checking - existence of SALOMEDS_Server
356 //checking - existence of SALOME_ModuleCatalog_Server
358 //checking - existence of SALOME_Session_Server
360 //checking - existence of SALOME_Container FactoryServer
362 //checking - existence of SALOME_ContainerPy.py FactoryServerPy
364 //checking - existence of SALOME_Container SuperVisionContainer
367 IsPassed = pingServer(iteration, errDescription);
369 *errMessage = new QString(errDescription);
375 bool InquireServersQThread::pingServer(int iteration, QString& errMessage)
377 ASSERT(iteration<=myServersCount);
380 for (int i = myRepeat; i ; i--)
384 CORBA::ORB_var orb = CORBA::ORB_init(_argc,_argv) ;
385 SALOME_NamingService &NS = *SINGLETON_<SALOME_NamingService>::Instance() ;
386 ASSERT(SINGLETON_<SALOME_NamingService>::IsAlreadyExisting()) ;
392 CORBA::Object_var obj = NS.Resolve("/Registry");
393 Registry::Components_var registry = Registry::Components::_narrow(obj) ;
394 if (!CORBA::is_nil(registry))
396 MESSAGE("/Registry is found");
399 MESSAGE("Registry was activated");
406 CORBA::Object_var obj = NS.Resolve("/myStudyManager");
407 SALOMEDS::StudyManager_var studyManager = SALOMEDS::StudyManager::_narrow(obj) ;
408 if (!CORBA::is_nil(studyManager))
415 MESSAGE("/myStudyManager is found");
416 studyManager->ping();
418 MESSAGE("StudyManager was activated");
425 CORBA::Object_var obj = NS.Resolve("/Kernel/ModulCatalog");
426 SALOME_ModuleCatalog::ModuleCatalog_var catalog = SALOME_ModuleCatalog::ModuleCatalog::_narrow(obj) ;
427 if (!CORBA::is_nil(catalog))
429 MESSAGE("/Kernel/ModulCatalog is found");
432 MESSAGE("ModuleCatalog was activated");
439 CORBA::Object_var obj = NS.Resolve("/Kernel/Session");
440 SALOME::Session_var session = SALOME::Session::_narrow(obj) ;
441 if (!CORBA::is_nil(session))
443 MESSAGE("/Kernel/Session is found");
446 MESSAGE("SALOME_Session was activated");
453 string hostname = GetHostname();
454 string containerName = "/Containers/";
455 containerName += hostname;
456 containerName += "/FactoryServer";
458 CORBA::Object_var obj = NS.Resolve(containerName.c_str());
459 Engines::Container_var FScontainer = Engines::Container::_narrow(obj) ;
460 if (!CORBA::is_nil(FScontainer))
464 MESSAGE("FactoryServer container was activated");
471 string hostname = GetHostname();
472 string containerName = "/Containers/";
473 containerName += hostname;
474 containerName += "/FactoryServerPy";
476 CORBA::Object_var obj = NS.Resolve(containerName.c_str());
477 Engines::Container_var FSPcontainer = Engines::Container::_narrow(obj) ;
478 if (!CORBA::is_nil(FSPcontainer))
480 FSPcontainer->ping();
482 MESSAGE("FactoryServerPy container was activated");
489 string hostname = GetHostname();
490 string containerName = "/Containers/";
491 containerName += hostname;
492 containerName += "/SuperVisionContainer";
494 CORBA::Object_var obj = NS.Resolve(containerName.c_str());
495 Engines::Container_var SVcontainer = Engines::Container::_narrow(obj) ;
496 if (!CORBA::is_nil(SVcontainer))
501 MESSAGE("SuperVisionContainer container was activated");
508 catch (ServiceUnreachable&)
510 MESSAGE("Caught exception: Naming Service Unreachable");
511 errorDescr = "Caught exception: Naming Service Unreachable";
513 catch (CORBA::COMM_FAILURE&)
515 MESSAGE("Caught CORBA::SystemException CommFailure.");
516 errorDescr = "Caught CORBA::SystemException CommFailure";
518 catch (CORBA::SystemException&)
520 MESSAGE("Caught CORBA::SystemException.");
521 errorDescr = "Caught CORBA::SystemException";
523 catch (CORBA::Exception&)
525 MESSAGE("Caught CORBA::Exception.");
526 errorDescr = "Caught CORBA::Exception";
530 MESSAGE("Caught unknown exception.");
531 errorDescr = "Caught unknown exception";
533 QThread::usleep(myDelay);
541 serverName = "SALOME_Registry_Server is not loaded. ";
544 serverName = "SALOMEDS_Server is not loaded. ";
547 serverName = "SALOME_ModuleCatalog_Server is not loaded. ";
550 serverName = "SALOME_Session_Server is not loaded. ";
553 serverName = "SALOME_Container FactoryServer is not loaded. ";
556 serverName = "SALOME_ContainerPy.py FactoryServerPy is not loaded. ";
559 serverName = "SALOME_Container SuperVisionContainer is not loaded. ";
562 errMessage = serverName + errorDescr;