]> SALOME platform Git repositories - modules/gui.git/blob - src/Session/InquireServersQThread.cxx
Salome HOME
try () catch () mechanism modified.
[modules/gui.git] / src / Session / InquireServersQThread.cxx
1 //  Copyright (C) 2003  CEA/DEN, EDF R&D
2 //
3 //
4 //
5 //  File   : InquireServersQThread.cxx
6 //  Author : Vasily RUSYAEV
7 //  Module : SALOME
8 //  $Header$
9
10 using namespace std;
11 #include "InquireServersQThread.h"
12
13 #include <qapplication.h>
14 #include <qpushbutton.h>
15 #include <qabstractlayout.h> 
16 #include <qlayout.h>
17 #include <qevent.h> 
18 #include <qfont.h> 
19 #include <qmessagebox.h> 
20 #include <qdir.h>
21 #include <qfileinfo.h>
22 #include <qstringlist.h>
23
24 //VRV: porting on Qt 3.0.5
25 #if QT_VERSION >= 0x030005
26 #include <qdesktopwidget.h> 
27 #endif
28 //VRV: porting on Qt 3.0.5
29
30 #include <qsize.h> 
31
32 #include <SALOMEconfig.h>
33
34 #include "Utils_ORB_INIT.hxx"
35 #include "Utils_SINGLETON.hxx"
36 #include "SALOME_NamingService.hxx"
37 #include "utilities.h"
38 #include "OpUtil.hxx"
39
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)
45
46 #define MARGIN_SIZE  5
47 #define SPACING_SIZE 3
48
49 InquireServersGUI::InquireServersGUI()
50      : QVBox(0, "SFA splash", Qt::WDestructiveClose | Qt::WStyle_Customize | Qt::WStyle_NoBorder | WType_TopLevel | WStyle_StaysOnTop | WX11BypassWM  )
51 {
52   //  myGUI = false;
53   myThread = new InquireServersQThread( this );
54
55   // 1. Polish the appearance
56   setMargin( MARGIN_SIZE );
57   setSpacing( SPACING_SIZE );
58   setFrameStyle( QFrame::Plain | QFrame::Box );
59   setLineWidth( 2 );
60   setMinimumSize( 200, 150 );
61
62   // 2. Splash image
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 );
69
70   // setting pixmap
71   //QPixmap pix = SUIT_ResourceMgr( "SalomeApp" ).loadPixmap( "SalomeApp", tr( "ABOUT" ) );
72   //splash->setPixmap( pix  );
73   
74   // 3. Progress bar
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 );
80
81   // 4. Info label
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 ) );
93
94   // 5. <Cancel> button
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 )  );
102
103   //Center widget
104 #if QT_VERSION >= 0x030005
105   QDesktopWidget *d = QApplication::desktop();
106 #else
107   QWidget *d = QApplication::desktop();
108 #endif
109 //VRV: porting on Qt 3.0.5
110
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;
116   move( Xc, Yc );
117
118   myThread->start();
119 }
120
121 void InquireServersGUI::setPixmap( QPixmap pix )
122 {
123   if ( !pix.isNull() ) {
124     mySplash->setPixmap( pix );
125     myPrgBar->setFixedWidth( mySplash->sizeHint().width() );
126     myLabel->setFixedWidth( mySplash->sizeHint().width() );
127   }
128 }
129
130 InquireServersGUI::~InquireServersGUI()
131 {
132   // Thread deletes itself in the end of run() function
133   delete myThread;
134 }
135
136 void InquireServersGUI::getArgs( int& _argc, char *** _argv)
137 {
138   _argc = qApp->argc();
139   *_argv = qApp->argv();
140 }
141
142 //=================================================================================
143 // function : ClickOnCancel()
144 // purpose  : cancel loading of SALOME
145 //=================================================================================
146 void InquireServersGUI::ClickOnCancel()
147 {
148   //it's necessary to stop asking servers
149   myThread->stop();
150   //  myGUI = false;
151   //Also we should send QCloseEvent in order to close this widget (and remove from screen) 
152   //QThread::postEvent ( this, new QCloseEvent() );
153   qApp->exit(1);
154 }
155
156 void InquireServersGUI::closeEvent ( QCloseEvent * pe)
157 {
158   //default implementation calls e->accept(), which hides this widget. 
159   //See the QCloseEvent documentation for more details.
160   pe->accept();
161   QApplication::flushX ();
162   QApplication::syncX ();
163   qApp->exit();
164 }
165
166 void InquireServersGUI::customEvent( QCustomEvent* pe )
167 {
168   switch( pe->type() )
169     {
170         case InquireEvent::ProgressEvent:
171         {
172             int* value = ( int* )(( InquireEvent*)pe)->data();
173             myPrgBar->setProgress( *value );
174             break;
175         }
176         case InquireEvent::ProgressEventLabel:
177         {
178             QString* myString = ( QString* )(( InquireEvent*)pe)->data();
179             myLabel->setText( *myString );
180             break;
181         }
182         case InquireEvent::ProgressEventError:
183         {
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);
189             myMsgBox.exec();
190             ClickOnCancel();
191             break;
192         }
193       default:
194         {
195           ;
196         }
197     }
198 }
199
200 int InquireServersGUI::getExitStatus()
201 {
202   return myThread->getExitStatus();
203 }
204
205 InquireServersQThread::InquireServersQThread( InquireServersGUI* r )
206      : receiver(r),  myExitStatus(0)
207 {
208   char* cenv;
209
210   IsChecking = true;
211   myServersCount = 5;
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" );
215   if ( cenv ) {
216     int val = atoi( cenv );
217     if ( val > 0 )
218       myRepeat = val;
219   }
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" + "...";
228   myMessages[5] = "";
229   myMessages[6] = "";
230   myMessages[7] = "";
231
232   r->getArgs( _argc, &_argv);
233
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" + "...";
238       myServersCount++;
239     }
240     if (strcmp(_argv[i],"PY")==0) {
241       myMessages[6] = str + "SALOME_ContainerPy.py FactoryServerPy" + "...";
242       myServersCount++;
243     }
244     if (strcmp(_argv[i],"SUPERV")==0) {
245       myMessages[7] = str + "SALOME_Container SuperVisionContainer" + "...";
246       myServersCount++;
247     }
248 //    if (strcmp(_argv[i],"GUI")==0) {
249 //      r->withGUI(true);
250 //    }
251   }
252 }
253
254 void InquireServersQThread::run()
255 {
256   while ( IsChecking && receiver )
257   {
258     for (int i=1; i<=8; i++)
259       {
260         if ( myMessages[i-1].isEmpty() ) {
261           if ( i==8 ) {
262             IsChecking = false;
263             //myExitStatus should be 0 because all servers exist and work
264             myExitStatus = 0;
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() );
269             break;
270           } else
271             continue;
272         }
273         QString *message = new QString(myMessages[i-1]);
274         QThread::postEvent( receiver, new InquireEvent( ( QEvent::Type )InquireEvent::ProgressEventLabel, message ) );
275         QThread::usleep(200000);
276         QString *errMsg;
277         bool result = AskServer(i,&errMsg);
278         if (result)
279           {
280             QThread::postEvent( receiver, new InquireEvent( ( QEvent::Type )InquireEvent::ProgressEvent, new int( i ) ) );
281             if ( i==8 )
282               {
283                 IsChecking = false;
284                 //myExitStatus should be 0 because all servers exist and work
285                 myExitStatus = 0;
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() );
290                 break;
291               }
292           }
293         else
294           {
295             QThread::postEvent( receiver, new InquireEvent( ( QEvent::Type )InquireEvent::ProgressEventError, errMsg ) );
296             //myExitStatus should be 1 because we didn't receive response from server
297             myExitStatus = 1;
298             return;
299           }
300       }
301   }
302
303   // this outputs WARNING: QThread object is deleted while still running -- it's OK in our case!
304   //delete this;
305 }
306
307 InquireServersQThread::~InquireServersQThread()
308 {
309 }
310
311 bool InquireServersQThread::AskServer(int iteration, QString ** errMessage)
312 {
313   if ( iteration > myServersCount )
314     return true; // we did not launch server with number iteration, so checking for it is not neccessary
315
316   ASSERT(iteration<=myServersCount);
317
318   //will be set true if we get response from server
319   bool IsPassed = false;
320   QString errDescription;
321   switch (iteration)
322     {
323     case 1:
324       //First checking - existence of Naming Service
325       for (int i = myRepeat; i ; i--)
326         {
327           try
328             {
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))
333                 continue;
334               else
335                 IsPassed = true;
336               break;
337             }
338           catch(CORBA::COMM_FAILURE&)
339             {
340               MESSAGE("CORBA::COMM_FAILURE: unable to contact the naming service");
341             }
342           catch(...)
343             {
344               MESSAGE("Unknown Exception: unable to contact the naming service");
345             }
346           QThread::usleep(myDelay);
347         }
348       if (!IsPassed)
349         *errMessage = new QString("unable to contact the naming service");
350       break;
351     case 2:
352       //checking - existence of SALOME_Registry_Server
353     case 3:
354       //checking - existence of SALOMEDS_Server
355     case 4:
356       //checking - existence of SALOME_ModuleCatalog_Server
357     case 5:
358       //checking - existence of SALOME_Session_Server
359     case 6:
360       //checking - existence of SALOME_Container FactoryServer
361     case 7:
362       //checking - existence of SALOME_ContainerPy.py FactoryServerPy
363     case 8:
364       //checking - existence of SALOME_Container SuperVisionContainer
365
366
367       IsPassed = pingServer(iteration, errDescription);
368       if (!IsPassed)
369         *errMessage = new QString(errDescription);
370       break;
371     }
372 return IsPassed;
373 }
374
375 bool InquireServersQThread::pingServer(int iteration, QString& errMessage)
376 {
377   ASSERT(iteration<=myServersCount);
378   bool result = false;
379   QString errorDescr;
380   for (int i = myRepeat; i ; i--)
381     {
382       try
383         {
384           CORBA::ORB_var orb = CORBA::ORB_init(_argc,_argv) ;
385           SALOME_NamingService &NS = *SINGLETON_<SALOME_NamingService>::Instance() ;
386           ASSERT(SINGLETON_<SALOME_NamingService>::IsAlreadyExisting()) ;
387           NS.init_orb( orb ) ;
388           switch (iteration)
389             {
390             case 2:
391               {
392                 CORBA::Object_var obj = NS.Resolve("/Registry");
393                 Registry::Components_var registry = Registry::Components::_narrow(obj) ;
394                 if (!CORBA::is_nil(registry))
395                   {
396                     MESSAGE("/Registry is found");
397                     registry->ping();
398                     result = true;
399                     MESSAGE("Registry was activated");
400                     return result;
401                   }
402               }
403               break;
404             case 3:
405               {
406                 CORBA::Object_var obj = NS.Resolve("/myStudyManager");
407                 SALOMEDS::StudyManager_var studyManager = SALOMEDS::StudyManager::_narrow(obj) ;
408                 if (!CORBA::is_nil(studyManager))
409
410
411
412
413
414                   {
415                     MESSAGE("/myStudyManager is found");
416                     studyManager->ping();
417                     result = true;
418                     MESSAGE("StudyManager was activated");
419                     return result;
420                   }
421               }
422               break;
423             case 4:
424               {
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))
428                   {
429                     MESSAGE("/Kernel/ModulCatalog is found");
430                     catalog->ping();
431                     result = true;
432                     MESSAGE("ModuleCatalog was activated");
433                     return result;
434                   }
435               }
436               break;
437             case 5:
438               {
439                 CORBA::Object_var obj = NS.Resolve("/Kernel/Session");
440                 SALOME::Session_var session = SALOME::Session::_narrow(obj) ;
441                 if (!CORBA::is_nil(session))
442                   {
443                     MESSAGE("/Kernel/Session is found");
444                     session->ping();
445                     result = true;
446                     MESSAGE("SALOME_Session was activated");
447                     return result;
448                   }
449               }
450               break;
451             case 6:
452               {
453                 string hostname = GetHostname();
454                 string containerName = "/Containers/";
455                 containerName += hostname;
456                 containerName += "/FactoryServer";
457
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))
461                   {
462                     FScontainer->ping();
463                     result = true;
464                     MESSAGE("FactoryServer container was activated");
465                     return result;
466                   }
467               }
468               break;
469             case 7:
470               {
471                 string hostname = GetHostname();
472                 string containerName = "/Containers/";
473                 containerName += hostname;
474                 containerName += "/FactoryServerPy";
475                 
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))
479                   {
480                     FSPcontainer->ping();
481                     result = true;
482                     MESSAGE("FactoryServerPy container was activated");
483                     return result;
484                   }
485               }
486               break;
487             case 8:
488               {
489                 string hostname = GetHostname();
490                 string containerName = "/Containers/";
491                 containerName += hostname;
492                 containerName += "/SuperVisionContainer";
493                 
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))
497                   {
498                     SVcontainer->ping();
499
500                     result = true;
501                     MESSAGE("SuperVisionContainer container was activated");
502                     return result;
503                   }
504               }
505               break;
506             }
507          }
508       catch (ServiceUnreachable&)
509         {
510           MESSAGE("Caught exception: Naming Service Unreachable");
511           errorDescr = "Caught exception: Naming Service Unreachable";
512         }
513       catch (CORBA::COMM_FAILURE&)
514         {
515           MESSAGE("Caught CORBA::SystemException CommFailure.");
516           errorDescr = "Caught CORBA::SystemException CommFailure";
517         }
518       catch (CORBA::SystemException&)
519         {
520           MESSAGE("Caught CORBA::SystemException.");
521           errorDescr = "Caught CORBA::SystemException";
522         }
523       catch (CORBA::Exception&)
524         {
525           MESSAGE("Caught CORBA::Exception.");
526           errorDescr = "Caught CORBA::Exception";
527         }
528       catch (...)
529         {
530           MESSAGE("Caught unknown exception.");
531           errorDescr = "Caught unknown exception";
532         }
533       QThread::usleep(myDelay);
534     }
535   if (!result)
536     {
537       QString serverName;
538       switch (iteration)
539         {
540         case 2:
541           serverName = "SALOME_Registry_Server is not loaded. ";
542           break;
543         case 3:
544           serverName = "SALOMEDS_Server is not loaded. ";
545           break;
546         case 4:
547           serverName = "SALOME_ModuleCatalog_Server is not loaded. ";
548           break;
549         case 5:
550           serverName = "SALOME_Session_Server is not loaded. ";
551           break;
552         case 6:
553           serverName = "SALOME_Container FactoryServer is not loaded. ";
554           break;
555         case 7:
556           serverName = "SALOME_ContainerPy.py FactoryServerPy is not loaded. ";
557           break;
558         case 8:
559           serverName = "SALOME_Container SuperVisionContainer is not loaded. ";
560           break;
561         }
562       errMessage = serverName + errorDescr;
563     }
564   return result;
565 }