]> SALOME platform Git repositories - modules/gui.git/blob - src/Session/InquireServersQThread.cxx
Salome HOME
Join modifications from branch OCC_debug_for_3_2_0b1
[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 #include "InquireServersQThread.h"
11
12 #include <qapplication.h>
13 #include <qpushbutton.h>
14 #include <qabstractlayout.h> 
15 #include <qlayout.h>
16 #include <qevent.h> 
17 #include <qfont.h> 
18 #include <qmessagebox.h> 
19 #include <qdir.h>
20 #include <qfileinfo.h>
21 #include <qstringlist.h>
22 #include <qlabel.h> 
23 #include <qprogressbar.h> 
24
25 //VRV: porting on Qt 3.0.5
26 #if QT_VERSION >= 0x030005
27 #include <qdesktopwidget.h> 
28 #endif
29 //VRV: porting on Qt 3.0.5
30
31 #include <qsize.h> 
32
33 #include <SALOMEconfig.h>
34
35 #include "Utils_ORB_INIT.hxx"
36 #include "Utils_SINGLETON.hxx"
37 #include "SALOME_NamingService.hxx"
38 #include "utilities.h"
39 #include "OpUtil.hxx"
40
41 using namespace std;
42
43 #include CORBA_CLIENT_HEADER(SALOME_Session)
44 #include CORBA_CLIENT_HEADER(SALOME_Registry)
45 #include CORBA_CLIENT_HEADER(SALOMEDS)
46 #include CORBA_CLIENT_HEADER(SALOME_ModuleCatalog)
47 #include CORBA_CLIENT_HEADER(SALOME_Component)
48
49 #define MARGIN_SIZE  5
50 #define SPACING_SIZE 3
51
52 /*!
53   Constructor
54 */
55 InquireServersGUI::InquireServersGUI()
56      : QVBox(0, "SFA splash", Qt::WDestructiveClose | Qt::WStyle_Customize | Qt::WStyle_NoBorder | WType_TopLevel | WStyle_StaysOnTop | WX11BypassWM  )
57 {
58   //  myGUI = false;
59   myThread = new InquireServersQThread( this );
60
61   // 1. Polish the appearance
62   setMargin( MARGIN_SIZE );
63   setSpacing( SPACING_SIZE );
64   setFrameStyle( QFrame::Plain | QFrame::Box );
65   setLineWidth( 2 );
66   setMinimumSize( 200, 150 );
67
68   // 2. Set palette
69   QPalette pal = palette();
70   QColorGroup cg = pal.active();
71   cg.setColor( QColorGroup::Foreground, Qt::darkBlue ); 
72   cg.setColor( QColorGroup::Background, Qt::white );
73   pal.setActive( cg ); pal.setInactive( cg ); pal.setDisabled( cg );
74   setPalette( pal );
75
76   // 2. Splash image
77   mySplashFrame = new QFrame( this );
78   mySplashFrame->setFrameStyle( QFrame::Box | QFrame::Raised );
79   QHBoxLayout* frmLayout = new QHBoxLayout( mySplashFrame );
80   frmLayout->setMargin( MARGIN_SIZE );
81   mySplash = new QLabel( mySplashFrame, "splash" );
82   frmLayout->addWidget( mySplash );
83
84   // setting pixmap
85   //QPixmap pix = SUIT_ResourceMgr( "SalomeApp" ).loadPixmap( "SalomeApp", tr( "ABOUT" ) );
86   //splash->setPixmap( pix  );
87   
88   // 3. Progress bar
89   myPrgBar = new QProgressBar( this, "QProgressBar" );
90   myPrgBar->setFixedWidth( 180 );
91   //Sets the total number of steps . 
92   myPrgBar->setPercentageVisible( false );
93   myPrgBar->setIndicatorFollowsStyle( false );
94   myPrgBar->setFixedHeight( 8 );
95   myPrgBar->setFrameStyle( QFrame::Box | QFrame::Plain );
96   myPrgBar->setMargin( 0 );
97   pal = myPrgBar->palette(); cg = pal.active();
98   cg.setColor( QColorGroup::Highlight, Qt::red );
99   pal.setActive( cg ); pal.setInactive( cg ); pal.setDisabled( cg ); myPrgBar->setPalette( pal );
100   myPrgBar->setTotalSteps ( myThread->getInquiredServers() );
101   myPrgBar->setProgress( 0 );
102
103   // 4. Info label
104   QWidget* aWgt1 = new QWidget( this );
105   QHBoxLayout* aHBoxLayout1 = new QHBoxLayout( aWgt1 );
106   myLabel = new QLabel( tr( "Loading:" ), aWgt1 );
107   myLabel->setFixedWidth( 180 );
108   myLabel->setAlignment( AlignLeft );
109   QFont theFont = myLabel->font();
110   theFont.setBold(true);
111   myLabel->setFont( theFont );
112   aHBoxLayout1->addItem( new QSpacerItem( 0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum ) );
113   aHBoxLayout1->addWidget( myLabel );
114   aHBoxLayout1->addItem( new QSpacerItem( 0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum ) );
115
116   // 5. <Cancel> button
117   QWidget* aWgt = new QWidget( this );
118   QHBoxLayout* aHBoxLayout = new QHBoxLayout( aWgt );
119   QPushButton* myCancelBtn = new QPushButton( tr( "Cancel" ), aWgt );
120   connect( myCancelBtn, SIGNAL( clicked() ), this, SLOT( ClickOnCancel() ) ) ;
121   aHBoxLayout->addItem( new QSpacerItem( 0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum )  );
122   aHBoxLayout->addWidget( myCancelBtn );
123   aHBoxLayout->addItem( new QSpacerItem( 0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum )  );
124
125   //Center widget
126 #if QT_VERSION >= 0x030005
127   QDesktopWidget *d = QApplication::desktop();
128 #else
129   QWidget *d = QApplication::desktop();
130 #endif
131 //VRV: porting on Qt 3.0.5
132
133   int w = d->width();         // returns desktop width
134   int h = d->height();        // returns desktop height
135   QSize mySize = sizeHint (); // returns widget size
136   int Xc = ( w - mySize.width() )  / 2;
137   int Yc = ( h - mySize.height() ) / 2;
138   move( Xc, Yc );
139
140   myThread->start();
141 }
142
143 /*!
144   Sets pixmap of splash screen
145   \param pix - new pixmap
146 */
147 void InquireServersGUI::setPixmap( QPixmap pix )
148 {
149   if ( !pix.isNull() ) 
150   {
151     mySplash->setPixmap( pix );
152     int w = mySplash->sizeHint().width() + MARGIN_SIZE*2;
153     myPrgBar->setFixedWidth( w );
154     myLabel->setFixedWidth( w );
155   }
156 }
157
158 /*!
159   Destructor
160 */
161 InquireServersGUI::~InquireServersGUI()
162 {
163   delete myThread;
164 }
165
166 /*!
167   Gets parameters from qApp
168   \param _argc - variable to return number of arguments
169   \param _argv - variable to return array of arguments
170 */
171 void InquireServersGUI::getArgs( int& _argc, char *** _argv)
172 {
173   _argc = qApp->argc();
174   *_argv = qApp->argv();
175 }
176
177 /*!
178   Cancel loading of SALOME
179 */
180 void InquireServersGUI::ClickOnCancel()
181 {
182   myThread->stop(); //it's necessary to stop asking servers
183   hide();
184   qApp->exit( 1 );
185 }
186
187 /*!
188   Custom event filter
189 */
190 void InquireServersGUI::customEvent( QCustomEvent* pe )
191 {
192   switch( pe->type() )
193     {
194         case InquireEvent::ProgressEvent:
195         {
196             int* value = ( int* )(( InquireEvent*)pe)->data();
197             myPrgBar->setProgress( *value );
198             break;
199         }
200         case InquireEvent::ProgressEventLabel:
201         {
202             QString* myString = ( QString* )(( InquireEvent*)pe)->data();
203             myLabel->setText( *myString );
204             break;
205         }
206         case InquireEvent::ProgressEventError:
207         {
208             QString* myErrDesc = ( QString* )(( InquireEvent*)pe)->data();
209             QString  appName = "SALOME Professional";
210             QString  error = "An internal error occurred.\n"+ *myErrDesc + "\n";
211             QMessageBox myMsgBox(appName,error,QMessageBox::Critical,QMessageBox::Ok,QMessageBox::NoButton,
212                                         QMessageBox::NoButton,0,"MY",TRUE,WStyle_DialogBorder|WStyle_StaysOnTop);
213             myMsgBox.exec();
214             ClickOnCancel();
215             break;
216         }
217       default:
218         {
219           ;
220         }
221     }
222 }
223
224 /*!
225   \return status of thread exit
226 */
227 int InquireServersGUI::getExitStatus()
228 {
229   return myThread->getExitStatus();
230 }
231
232 /*!
233   Constructor
234 */
235 InquireServersQThread::InquireServersQThread( InquireServersGUI* r )
236      : receiver(r),  myExitStatus(0)
237 {
238   char* cenv;
239
240   IsChecking = true;
241   myServersCount = 5;
242   //how many times we should repeat attempts to get response from all needed for launching SALOME servers
243   myRepeat = 30; // default value, user can change it by setting CSF_RepeatServerRequest env.variable
244   cenv = getenv( "CSF_RepeatServerRequest" );
245   if ( cenv ) {
246     int val = atoi( cenv );
247     if ( val > 0 )
248       myRepeat = val;
249   }
250   //define delay time between two attempts
251   myDelay = 1000000; // 1 second
252   QString str = "Loading: ";
253   myMessages[0] = "Checking naming service...";
254   myMessages[1] = str + "SALOME_Registry_Server" + "...";
255   myMessages[2] = str + "SALOMEDS_Server" + "...";
256   myMessages[3] = str + "SALOME_ModuleCatalog_Server" + "...";
257   myMessages[4] = str + "SALOME_Session_Server" + "...";
258   myMessages[5] = "";
259   myMessages[6] = "";
260   myMessages[7] = "";
261
262   r->getArgs( _argc, &_argv);
263
264   // NRI : Temporary solution for SuperVisionContainer
265   for ( int i=1; i<=(_argc-1); i++) {
266     if (strcmp(_argv[i],"CPP")==0) {
267       myMessages[5] = str + "SALOME_Container FactoryServer" + "...";
268       myServersCount++;
269     }
270     if (strcmp(_argv[i],"PY")==0) {
271       myMessages[6] = str + "SALOME_ContainerPy.py FactoryServerPy" + "...";
272       myServersCount++;
273     }
274     if (strcmp(_argv[i],"SUPERV")==0) {
275       myMessages[7] = str + "SALOME_Container SuperVisionContainer" + "...";
276       myServersCount++;
277     }
278 //    if (strcmp(_argv[i],"GUI")==0) {
279 //      r->withGUI(true);
280 //    }
281   }
282 }
283
284 /*!
285   The main loop of this thread
286 */
287 void InquireServersQThread::run()
288 {
289   while ( IsChecking && receiver )
290   {
291     for (int i=1; i<=8; i++)
292     {
293       if ( myMessages[i-1].isEmpty() ) 
294       {
295         if ( i==8 ) 
296         {
297           IsChecking = false;
298           myExitStatus = 0;  //myExitStatus should be 0 because all servers exist and work
299           sleep( 1 ); // sleep( 1 second ) in order to see 100%.  in other case it closes on 85%..
300           break;
301         } 
302         else
303           continue;
304       }
305       QString *message = new QString(myMessages[i-1]);
306       QThread::postEvent( receiver, new InquireEvent( ( QEvent::Type )InquireEvent::ProgressEventLabel, message ) );
307       QThread::usleep(200000);
308       QString *errMsg;
309       bool result = AskServer(i,&errMsg);
310       if (result)
311       {
312         QThread::postEvent( receiver, new InquireEvent( ( QEvent::Type )InquireEvent::ProgressEvent, new int( i ) ) );
313         if ( i==8 )
314         {
315           IsChecking = false;
316           myExitStatus = 0; //myExitStatus should be 0 because all servers exist and work
317           sleep( 1 );  // sleep( 1 second ) in order to see 100%.  in other case it closes on 85%..
318           break;
319         }
320       }
321       else
322       {
323         QThread::postEvent( receiver, new InquireEvent( ( QEvent::Type )InquireEvent::ProgressEventError, errMsg ) );
324         stop();
325         break;
326       }
327     }
328   }
329
330   receiver->hide();
331   qApp->exit( myExitStatus );
332 }
333
334 /*!
335   Stops this thread
336 */
337 void InquireServersQThread::stop()
338 {
339   IsChecking = false;
340   myExitStatus = 1;
341 }
342
343 /*!
344   Destructor
345 */
346 InquireServersQThread::~InquireServersQThread()
347 {
348 }
349
350 bool InquireServersQThread::AskServer(int iteration, QString ** errMessage)
351 {
352   if ( iteration > myServersCount )
353     return true; // we did not launch server with number iteration, so checking for it is not neccessary
354
355   ASSERT(iteration<=myServersCount);
356
357   //will be set true if we get response from server
358   bool IsPassed = false;
359   QString errDescription;
360 #ifdef WNT
361   int i;
362 #endif
363   switch (iteration)
364     {
365     case 1:
366       //First checking - existence of Naming Service
367 #ifndef WNT
368       for (int i = myRepeat; i ; i--)
369 #else
370           for (i = myRepeat; i ; i--)
371 #endif
372         {
373           try
374             {
375               CORBA::ORB_var orb = CORBA::ORB_init(_argc,_argv) ;
376               CORBA::Object_var obj = orb->resolve_initial_references("NameService");
377               CosNaming::NamingContext_var _root_context = CosNaming::NamingContext::_narrow(obj);
378               if (CORBA::is_nil(_root_context))
379                 continue;
380               else
381                 IsPassed = true;
382               break;
383             }
384           catch(CORBA::COMM_FAILURE&)
385             {
386               MESSAGE("CORBA::COMM_FAILURE: unable to contact the naming service");
387             }
388           catch(...)
389             {
390               MESSAGE("Unknown Exception: unable to contact the naming service");
391             }
392           QThread::usleep(myDelay);
393         }
394       if (!IsPassed)
395         *errMessage = new QString("unable to contact the naming service");
396       break;
397     case 2:
398       //checking - existence of SALOME_Registry_Server
399     case 3:
400       //checking - existence of SALOMEDS_Server
401     case 4:
402       //checking - existence of SALOME_ModuleCatalog_Server
403     case 5:
404       //checking - existence of SALOME_Session_Server
405     case 6:
406       //checking - existence of SALOME_Container FactoryServer
407     case 7:
408       //checking - existence of SALOME_ContainerPy.py FactoryServerPy
409     case 8:
410       //checking - existence of SALOME_Container SuperVisionContainer
411
412
413       IsPassed = pingServer(iteration, errDescription);
414       if (!IsPassed)
415         *errMessage = new QString(errDescription);
416       break;
417     }
418 return IsPassed;
419 }
420
421 bool InquireServersQThread::pingServer(int iteration, QString& errMessage)
422 {
423   ASSERT(iteration<=myServersCount);
424   bool result = false;
425   QString errorDescr;
426   for (int i = myRepeat; i ; i--)
427     {
428       try
429         {
430           CORBA::ORB_var orb = CORBA::ORB_init(_argc,_argv) ;
431           SALOME_NamingService &NS = *SINGLETON_<SALOME_NamingService>::Instance() ;
432           ASSERT(SINGLETON_<SALOME_NamingService>::IsAlreadyExisting()) ;
433           NS.init_orb( orb ) ;
434           switch (iteration)
435             {
436             case 2:
437               {
438                 CORBA::Object_var obj = NS.Resolve("/Registry");
439                 Registry::Components_var registry = Registry::Components::_narrow(obj) ;
440                 if (!CORBA::is_nil(registry))
441                   {
442                     MESSAGE("/Registry is found");
443                     registry->ping();
444                     result = true;
445                     MESSAGE("Registry was activated");
446                     return result;
447                   }
448               }
449               break;
450             case 3:
451               {
452                 CORBA::Object_var obj = NS.Resolve("/myStudyManager");
453                 SALOMEDS::StudyManager_var studyManager = SALOMEDS::StudyManager::_narrow(obj) ;
454                 if (!CORBA::is_nil(studyManager))
455
456
457
458
459
460                   {
461                     MESSAGE("/myStudyManager is found");
462                     studyManager->ping();
463                     result = true;
464                     MESSAGE("StudyManager was activated");
465                     return result;
466                   }
467               }
468               break;
469             case 4:
470               {
471                 CORBA::Object_var obj = NS.Resolve("/Kernel/ModulCatalog");
472                 SALOME_ModuleCatalog::ModuleCatalog_var catalog = SALOME_ModuleCatalog::ModuleCatalog::_narrow(obj) ;
473                 if (!CORBA::is_nil(catalog))
474                   {
475                     MESSAGE("/Kernel/ModulCatalog is found");
476                     catalog->ping();
477                     result = true;
478                     MESSAGE("ModuleCatalog was activated");
479                     return result;
480                   }
481               }
482               break;
483             case 5:
484               {
485                 CORBA::Object_var obj = NS.Resolve("/Kernel/Session");
486                 SALOME::Session_var session = SALOME::Session::_narrow(obj) ;
487                 if (!CORBA::is_nil(session))
488                   {
489                     MESSAGE("/Kernel/Session is found");
490                     session->ping();
491                     result = true;
492                     MESSAGE("SALOME_Session was activated");
493                     return result;
494                   }
495               }
496               break;
497             case 6:
498               {
499                 string hostname = GetHostname();
500                 string containerName = "/Containers/";
501                 containerName += hostname;
502                 containerName += "/FactoryServer";
503
504                 CORBA::Object_var obj = NS.Resolve(containerName.c_str());
505                 Engines::Container_var FScontainer = Engines::Container::_narrow(obj) ;
506                 if (!CORBA::is_nil(FScontainer))
507                   {
508                     FScontainer->ping();
509                     result = true;
510                     MESSAGE("FactoryServer container was activated");
511                     return result;
512                   }
513               }
514               break;
515             case 7:
516               {
517                 string hostname = GetHostname();
518                 string containerName = "/Containers/";
519                 containerName += hostname;
520                 containerName += "/FactoryServerPy";
521                 
522                 CORBA::Object_var obj = NS.Resolve(containerName.c_str());
523                 Engines::Container_var FSPcontainer = Engines::Container::_narrow(obj) ;
524                 if (!CORBA::is_nil(FSPcontainer))
525                   {
526                     FSPcontainer->ping();
527                     result = true;
528                     MESSAGE("FactoryServerPy container was activated");
529                     return result;
530                   }
531               }
532               break;
533             case 8:
534               {
535                 string hostname = GetHostname();
536                 string containerName = "/Containers/";
537                 containerName += hostname;
538                 containerName += "/SuperVisionContainer";
539                 
540                 CORBA::Object_var obj = NS.Resolve(containerName.c_str());
541                 Engines::Container_var SVcontainer = Engines::Container::_narrow(obj) ;
542                 if (!CORBA::is_nil(SVcontainer))
543                   {
544                     SVcontainer->ping();
545
546                     result = true;
547                     MESSAGE("SuperVisionContainer container was activated");
548                     return result;
549                   }
550               }
551               break;
552             }
553          }
554       catch (ServiceUnreachable&)
555         {
556           MESSAGE("Caught exception: Naming Service Unreachable");
557           errorDescr = "Caught exception: Naming Service Unreachable";
558         }
559       catch (CORBA::COMM_FAILURE&)
560         {
561           MESSAGE("Caught CORBA::SystemException CommFailure.");
562           errorDescr = "Caught CORBA::SystemException CommFailure";
563         }
564       catch (CORBA::SystemException&)
565         {
566           MESSAGE("Caught CORBA::SystemException.");
567           errorDescr = "Caught CORBA::SystemException";
568         }
569       catch (CORBA::Exception&)
570         {
571           MESSAGE("Caught CORBA::Exception.");
572           errorDescr = "Caught CORBA::Exception";
573         }
574       catch (...)
575         {
576           MESSAGE("Caught unknown exception.");
577           errorDescr = "Caught unknown exception";
578         }
579       QThread::usleep(myDelay);
580     }
581   if (!result)
582     {
583       QString serverName;
584       switch (iteration)
585         {
586         case 2:
587           serverName = "SALOME_Registry_Server is not loaded. ";
588           break;
589         case 3:
590           serverName = "SALOMEDS_Server is not loaded. ";
591           break;
592         case 4:
593           serverName = "SALOME_ModuleCatalog_Server is not loaded. ";
594           break;
595         case 5:
596           serverName = "SALOME_Session_Server is not loaded. ";
597           break;
598         case 6:
599           serverName = "SALOME_Container FactoryServer is not loaded. ";
600           break;
601         case 7:
602           serverName = "SALOME_ContainerPy.py FactoryServerPy is not loaded. ";
603           break;
604         case 8:
605           serverName = "SALOME_Container SuperVisionContainer is not loaded. ";
606           break;
607         }
608       errMessage = serverName + errorDescr;
609     }
610   return result;
611 }
612