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 #include <qprogressbar.h>
26 //VRV: porting on Qt 3.0.5
27 #if QT_VERSION >= 0x030005
28 #include <qdesktopwidget.h>
30 //VRV: porting on Qt 3.0.5
34 #include <SALOMEconfig.h>
36 #include "Utils_ORB_INIT.hxx"
37 #include "Utils_SINGLETON.hxx"
38 #include "SALOME_NamingService.hxx"
39 #include "utilities.h"
42 #include CORBA_CLIENT_HEADER(SALOME_Session)
43 #include CORBA_CLIENT_HEADER(SALOME_Registry)
44 #include CORBA_CLIENT_HEADER(SALOMEDS)
45 #include CORBA_CLIENT_HEADER(SALOME_ModuleCatalog)
46 #include CORBA_CLIENT_HEADER(SALOME_Component)
49 #define SPACING_SIZE 3
51 InquireServersGUI::InquireServersGUI()
52 : QVBox(0, "SFA splash", Qt::WDestructiveClose | Qt::WStyle_Customize | Qt::WStyle_NoBorder | WType_TopLevel | WStyle_StaysOnTop | WX11BypassWM )
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 QPalette pal = palette();
66 QColorGroup cg = pal.active();
67 cg.setColor( QColorGroup::Foreground, Qt::darkBlue );
68 cg.setColor( QColorGroup::Background, Qt::white );
69 pal.setActive( cg ); pal.setInactive( cg ); pal.setDisabled( cg );
73 mySplashFrame = new QFrame( this );
74 mySplashFrame->setFrameStyle( QFrame::Box | QFrame::Raised );
75 QHBoxLayout* frmLayout = new QHBoxLayout( mySplashFrame );
76 frmLayout->setMargin( MARGIN_SIZE );
77 mySplash = new QLabel( mySplashFrame, "splash" );
78 frmLayout->addWidget( mySplash );
81 //QPixmap pix = SUIT_ResourceMgr( "SalomeApp" ).loadPixmap( "SalomeApp", tr( "ABOUT" ) );
82 //splash->setPixmap( pix );
85 myPrgBar = new QProgressBar( this, "QProgressBar" );
86 myPrgBar->setFixedWidth( 180 );
87 //Sets the total number of steps .
88 myPrgBar->setPercentageVisible( false );
89 myPrgBar->setIndicatorFollowsStyle( false );
90 myPrgBar->setFixedHeight( 8 );
91 myPrgBar->setFrameStyle( QFrame::Box | QFrame::Plain );
92 myPrgBar->setMargin( 0 );
93 pal = myPrgBar->palette(); cg = pal.active();
94 cg.setColor( QColorGroup::Highlight, Qt::red );
95 pal.setActive( cg ); pal.setInactive( cg ); pal.setDisabled( cg ); myPrgBar->setPalette( pal );
96 myPrgBar->setTotalSteps ( myThread->getInquiredServers() );
97 myPrgBar->setProgress( 0 );
100 QWidget* aWgt1 = new QWidget( this );
101 QHBoxLayout* aHBoxLayout1 = new QHBoxLayout( aWgt1 );
102 myLabel = new QLabel( tr( "Loading:" ), aWgt1 );
103 myLabel->setFixedWidth( 180 );
104 myLabel->setAlignment( AlignLeft );
105 QFont theFont = myLabel->font();
106 theFont.setBold(true);
107 myLabel->setFont( theFont );
108 aHBoxLayout1->addItem( new QSpacerItem( 0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum ) );
109 aHBoxLayout1->addWidget( myLabel );
110 aHBoxLayout1->addItem( new QSpacerItem( 0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum ) );
112 // 5. <Cancel> button
113 QWidget* aWgt = new QWidget( this );
114 QHBoxLayout* aHBoxLayout = new QHBoxLayout( aWgt );
115 QPushButton* myCancelBtn = new QPushButton( tr( "Cancel" ), aWgt );
116 connect( myCancelBtn, SIGNAL( clicked() ), this, SLOT( ClickOnCancel() ) ) ;
117 aHBoxLayout->addItem( new QSpacerItem( 0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum ) );
118 aHBoxLayout->addWidget( myCancelBtn );
119 aHBoxLayout->addItem( new QSpacerItem( 0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum ) );
122 #if QT_VERSION >= 0x030005
123 QDesktopWidget *d = QApplication::desktop();
125 QWidget *d = QApplication::desktop();
127 //VRV: porting on Qt 3.0.5
129 int w = d->width(); // returns desktop width
130 int h = d->height(); // returns desktop height
131 QSize mySize = sizeHint (); // returns widget size
132 int Xc = ( w - mySize.width() ) / 2;
133 int Yc = ( h - mySize.height() ) / 2;
139 void InquireServersGUI::setPixmap( QPixmap pix )
141 if ( !pix.isNull() ) {
142 mySplash->setPixmap( pix );
143 int w = mySplash->sizeHint().width() + MARGIN_SIZE*2;
144 myPrgBar->setFixedWidth( w );
145 myLabel->setFixedWidth( w );
149 InquireServersGUI::~InquireServersGUI()
151 // Thread deletes itself in the end of run() function
155 void InquireServersGUI::getArgs( int& _argc, char *** _argv)
157 _argc = qApp->argc();
158 *_argv = qApp->argv();
161 //=================================================================================
162 // function : ClickOnCancel()
163 // purpose : cancel loading of SALOME
164 //=================================================================================
165 void InquireServersGUI::ClickOnCancel()
167 //it's necessary to stop asking servers
170 //Also we should send QCloseEvent in order to close this widget (and remove from screen)
171 //QThread::postEvent ( this, new QCloseEvent() );
175 void InquireServersGUI::closeEvent ( QCloseEvent * pe)
177 //default implementation calls e->accept(), which hides this widget.
178 //See the QCloseEvent documentation for more details.
180 QApplication::flushX ();
181 QApplication::syncX ();
185 void InquireServersGUI::customEvent( QCustomEvent* pe )
189 case InquireEvent::ProgressEvent:
191 int* value = ( int* )(( InquireEvent*)pe)->data();
192 myPrgBar->setProgress( *value );
195 case InquireEvent::ProgressEventLabel:
197 QString* myString = ( QString* )(( InquireEvent*)pe)->data();
198 myLabel->setText( *myString );
201 case InquireEvent::ProgressEventError:
203 QString* myErrDesc = ( QString* )(( InquireEvent*)pe)->data();
204 QString appName = "SALOME Professional";
205 QString error = "An internal error occurred.\n"+ *myErrDesc + "\n";
206 QMessageBox myMsgBox(appName,error,QMessageBox::Critical,QMessageBox::Ok,QMessageBox::NoButton,
207 QMessageBox::NoButton,0,"MY",TRUE,WStyle_DialogBorder|WStyle_StaysOnTop);
219 int InquireServersGUI::getExitStatus()
221 return myThread->getExitStatus();
224 InquireServersQThread::InquireServersQThread( InquireServersGUI* r )
225 : receiver(r), myExitStatus(0)
231 //how many times we should repeat attempts to get response from all needed for launching SALOME servers
232 myRepeat = 30; // default value, user can change it by setting CSF_RepeatServerRequest env.variable
233 cenv = getenv( "CSF_RepeatServerRequest" );
235 int val = atoi( cenv );
239 //define delay time between two attempts
240 myDelay = 1000000; // 1 second
241 QString str = "Loading: ";
242 myMessages[0] = "Checking naming service...";
243 myMessages[1] = str + "SALOME_Registry_Server" + "...";
244 myMessages[2] = str + "SALOMEDS_Server" + "...";
245 myMessages[3] = str + "SALOME_ModuleCatalog_Server" + "...";
246 myMessages[4] = str + "SALOME_Session_Server" + "...";
251 r->getArgs( _argc, &_argv);
253 // NRI : Temporary solution for SuperVisionContainer
254 for ( int i=1; i<=(_argc-1); i++) {
255 if (strcmp(_argv[i],"CPP")==0) {
256 myMessages[5] = str + "SALOME_Container FactoryServer" + "...";
259 if (strcmp(_argv[i],"PY")==0) {
260 myMessages[6] = str + "SALOME_ContainerPy.py FactoryServerPy" + "...";
263 if (strcmp(_argv[i],"SUPERV")==0) {
264 myMessages[7] = str + "SALOME_Container SuperVisionContainer" + "...";
267 // if (strcmp(_argv[i],"GUI")==0) {
273 void InquireServersQThread::run()
275 while ( IsChecking && receiver )
277 for (int i=1; i<=8; i++)
279 if ( myMessages[i-1].isEmpty() ) {
282 //myExitStatus should be 0 because all servers exist and work
284 //we should send QCloseEvent in order to close this widget (and remove from screen)
285 qApp->processEvents();
286 sleep( 1 ); // sleep( 1 second ) in order to see 100%. in other case it closes on 85%..
287 QThread::postEvent ( receiver , new QCloseEvent() );
292 QString *message = new QString(myMessages[i-1]);
293 QThread::postEvent( receiver, new InquireEvent( ( QEvent::Type )InquireEvent::ProgressEventLabel, message ) );
294 QThread::usleep(200000);
296 bool result = AskServer(i,&errMsg);
299 QThread::postEvent( receiver, new InquireEvent( ( QEvent::Type )InquireEvent::ProgressEvent, new int( i ) ) );
303 //myExitStatus should be 0 because all servers exist and work
305 //we should send QCloseEvent in order to close this widget (and remove from screen)
306 qApp->processEvents();
307 sleep( 1 ); // sleep( 1 second ) in order to see 100%. in other case it closes on 85%..
308 QThread::postEvent ( receiver , new QCloseEvent() );
314 QThread::postEvent( receiver, new InquireEvent( ( QEvent::Type )InquireEvent::ProgressEventError, errMsg ) );
315 //myExitStatus should be 1 because we didn't receive response from server
322 // this outputs WARNING: QThread object is deleted while still running -- it's OK in our case!
326 InquireServersQThread::~InquireServersQThread()
330 bool InquireServersQThread::AskServer(int iteration, QString ** errMessage)
332 if ( iteration > myServersCount )
333 return true; // we did not launch server with number iteration, so checking for it is not neccessary
335 ASSERT(iteration<=myServersCount);
337 //will be set true if we get response from server
338 bool IsPassed = false;
339 QString errDescription;
343 //First checking - existence of Naming Service
344 for (int i = myRepeat; i ; i--)
348 CORBA::ORB_var orb = CORBA::ORB_init(_argc,_argv) ;
349 CORBA::Object_var obj = orb->resolve_initial_references("NameService");
350 CosNaming::NamingContext_var _root_context = CosNaming::NamingContext::_narrow(obj);
351 if (CORBA::is_nil(_root_context))
357 catch(CORBA::COMM_FAILURE&)
359 MESSAGE("CORBA::COMM_FAILURE: unable to contact the naming service");
363 MESSAGE("Unknown Exception: unable to contact the naming service");
365 QThread::usleep(myDelay);
368 *errMessage = new QString("unable to contact the naming service");
371 //checking - existence of SALOME_Registry_Server
373 //checking - existence of SALOMEDS_Server
375 //checking - existence of SALOME_ModuleCatalog_Server
377 //checking - existence of SALOME_Session_Server
379 //checking - existence of SALOME_Container FactoryServer
381 //checking - existence of SALOME_ContainerPy.py FactoryServerPy
383 //checking - existence of SALOME_Container SuperVisionContainer
386 IsPassed = pingServer(iteration, errDescription);
388 *errMessage = new QString(errDescription);
394 bool InquireServersQThread::pingServer(int iteration, QString& errMessage)
396 ASSERT(iteration<=myServersCount);
399 for (int i = myRepeat; i ; i--)
403 CORBA::ORB_var orb = CORBA::ORB_init(_argc,_argv) ;
404 SALOME_NamingService &NS = *SINGLETON_<SALOME_NamingService>::Instance() ;
405 ASSERT(SINGLETON_<SALOME_NamingService>::IsAlreadyExisting()) ;
411 CORBA::Object_var obj = NS.Resolve("/Registry");
412 Registry::Components_var registry = Registry::Components::_narrow(obj) ;
413 if (!CORBA::is_nil(registry))
415 MESSAGE("/Registry is found");
418 MESSAGE("Registry was activated");
425 CORBA::Object_var obj = NS.Resolve("/myStudyManager");
426 SALOMEDS::StudyManager_var studyManager = SALOMEDS::StudyManager::_narrow(obj) ;
427 if (!CORBA::is_nil(studyManager))
434 MESSAGE("/myStudyManager is found");
435 studyManager->ping();
437 MESSAGE("StudyManager was activated");
444 CORBA::Object_var obj = NS.Resolve("/Kernel/ModulCatalog");
445 SALOME_ModuleCatalog::ModuleCatalog_var catalog = SALOME_ModuleCatalog::ModuleCatalog::_narrow(obj) ;
446 if (!CORBA::is_nil(catalog))
448 MESSAGE("/Kernel/ModulCatalog is found");
451 MESSAGE("ModuleCatalog was activated");
458 CORBA::Object_var obj = NS.Resolve("/Kernel/Session");
459 SALOME::Session_var session = SALOME::Session::_narrow(obj) ;
460 if (!CORBA::is_nil(session))
462 MESSAGE("/Kernel/Session is found");
465 MESSAGE("SALOME_Session was activated");
472 string hostname = GetHostname();
473 string containerName = "/Containers/";
474 containerName += hostname;
475 containerName += "/FactoryServer";
477 CORBA::Object_var obj = NS.Resolve(containerName.c_str());
478 Engines::Container_var FScontainer = Engines::Container::_narrow(obj) ;
479 if (!CORBA::is_nil(FScontainer))
483 MESSAGE("FactoryServer container was activated");
490 string hostname = GetHostname();
491 string containerName = "/Containers/";
492 containerName += hostname;
493 containerName += "/FactoryServerPy";
495 CORBA::Object_var obj = NS.Resolve(containerName.c_str());
496 Engines::Container_var FSPcontainer = Engines::Container::_narrow(obj) ;
497 if (!CORBA::is_nil(FSPcontainer))
499 FSPcontainer->ping();
501 MESSAGE("FactoryServerPy container was activated");
508 string hostname = GetHostname();
509 string containerName = "/Containers/";
510 containerName += hostname;
511 containerName += "/SuperVisionContainer";
513 CORBA::Object_var obj = NS.Resolve(containerName.c_str());
514 Engines::Container_var SVcontainer = Engines::Container::_narrow(obj) ;
515 if (!CORBA::is_nil(SVcontainer))
520 MESSAGE("SuperVisionContainer container was activated");
527 catch (ServiceUnreachable&)
529 MESSAGE("Caught exception: Naming Service Unreachable");
530 errorDescr = "Caught exception: Naming Service Unreachable";
532 catch (CORBA::COMM_FAILURE&)
534 MESSAGE("Caught CORBA::SystemException CommFailure.");
535 errorDescr = "Caught CORBA::SystemException CommFailure";
537 catch (CORBA::SystemException&)
539 MESSAGE("Caught CORBA::SystemException.");
540 errorDescr = "Caught CORBA::SystemException";
542 catch (CORBA::Exception&)
544 MESSAGE("Caught CORBA::Exception.");
545 errorDescr = "Caught CORBA::Exception";
549 MESSAGE("Caught unknown exception.");
550 errorDescr = "Caught unknown exception";
552 QThread::usleep(myDelay);
560 serverName = "SALOME_Registry_Server is not loaded. ";
563 serverName = "SALOMEDS_Server is not loaded. ";
566 serverName = "SALOME_ModuleCatalog_Server is not loaded. ";
569 serverName = "SALOME_Session_Server is not loaded. ";
572 serverName = "SALOME_Container FactoryServer is not loaded. ";
575 serverName = "SALOME_ContainerPy.py FactoryServerPy is not loaded. ";
578 serverName = "SALOME_Container SuperVisionContainer is not loaded. ";
581 errMessage = serverName + errorDescr;