]> SALOME platform Git repositories - modules/gui.git/commitdiff
Salome HOME
Splash screen was implemented. Changes in packages SUIT and Session are integrated.
authorasv <asv@opencascade.com>
Thu, 23 Jun 2005 11:15:58 +0000 (11:15 +0000)
committerasv <asv@opencascade.com>
Thu, 23 Jun 2005 11:15:58 +0000 (11:15 +0000)
src/SUIT/SUIT_Session.cxx
src/SUIT/SUIT_Session.h
src/Session/InquireServersQThread.cxx [new file with mode: 0755]
src/Session/InquireServersQThread.h [new file with mode: 0755]
src/Session/Makefile.in
src/Session/SALOME_Session_Server.cxx
src/Session/Session_ServerLauncher.cxx
src/Session/Session_Session_i.cxx

index 082d49addffcdc87b3dbc5c4c2dcbc917925ce78..d47b8d3e33ff94fda620db1b0657932aa76a0ecd 100755 (executable)
@@ -23,7 +23,8 @@ SUIT_Session::SUIT_Session()
 : QObject(),
 myResMgr( 0 ),
 myHandler( 0 ),
-myActiveApp( 0 )
+myActiveApp( 0 ),
+myExitStatus( FROM_GUI )
 {
   SUIT_ASSERT( !mySession )
 
@@ -193,19 +194,33 @@ void SUIT_Session::onApplicationClosed( SUIT_Application* theApp )
     myActiveApp = 0;
 
   if ( myAppList.isEmpty() )
-    qApp->quit();
+  {
+    printf( "Calling QApplication::exit() with exit code = %d\n", myExitStatus );
+    qApp->exit( myExitStatus );
+  }
 }
 
 /*!
   Destroys session by closing all applications.
 */
-void SUIT_Session::closeSession()
+void SUIT_Session::closeSession( int mode )
 {
   while ( !myAppList.isEmpty() )
   {
     SUIT_Application* app = myAppList.getFirst();
-    if ( !app->isPossibleToClose() )
+    if ( mode == ASK && !app->isPossibleToClose() )
       return;
+    else if ( mode == SAVE )
+    {
+      SUIT_Study* study = app->activeStudy();
+      if ( study->isModified() && study->isSaved() )
+       study->saveDocument();
+    }
+    else if ( mode == DONT_SAVE )
+    {
+      myExitStatus = FROM_CORBA_SESSION;
+      //....
+    }
 
     app->closeApplication();
   }
index 842ef0ae9da16f2ef766feb55ede2a14031a26a0..7496955f3cddf30634a6664bf74f227986788ee2 100755 (executable)
@@ -37,6 +37,9 @@ class SUIT_EXPORT SUIT_Session: public QObject
 public:
   typedef LIB_HANDLE AppLib;
 
+  enum { ASK = 0, SAVE, DONT_SAVE } CloseMode;
+  enum { FROM_GUI = 0, FROM_CORBA_SESSION } ExitStatus;
+
 public:
   SUIT_Session();
   virtual ~SUIT_Session();
@@ -50,7 +53,7 @@ public:
 
   SUIT_ResourceMgr*            resourceMgr() const;
 
-  void                         closeSession();
+  void                         closeSession( int mode = ASK );
 
   SUIT_ExceptionHandler*       handler() const;
 
@@ -82,6 +85,8 @@ private:
 
   SUIT_ExceptionHandler*       myHandler;
   static SUIT_Session*         mySession;
+
+  int                          myExitStatus;
 };
 
 #endif
diff --git a/src/Session/InquireServersQThread.cxx b/src/Session/InquireServersQThread.cxx
new file mode 100755 (executable)
index 0000000..00bc1da
--- /dev/null
@@ -0,0 +1,556 @@
+//  Copyright (C) 2003  CEA/DEN, EDF R&D
+//
+//
+//
+//  File   : InquireServersQThread.cxx
+//  Author : Vasily RUSYAEV
+//  Module : SALOME
+//  $Header$
+
+using namespace std;
+#include "InquireServersQThread.h"
+
+#include <qlabel.h>
+#include <qpushbutton.h>
+#include <qabstractlayout.h> 
+#include <qlayout.h>
+#include <qevent.h> 
+#include <qfont.h> 
+#include <qmessagebox.h> 
+#include <qdir.h>
+#include <qfileinfo.h>
+#include <qstringlist.h>
+
+//VRV: porting on Qt 3.0.5
+#if QT_VERSION >= 0x030005
+#include <qdesktopwidget.h> 
+#endif
+//VRV: porting on Qt 3.0.5
+
+#include <qsize.h> 
+
+#include <SALOMEconfig.h>
+
+#include "Utils_ORB_INIT.hxx"
+#include "Utils_SINGLETON.hxx"
+#include "SALOME_NamingService.hxx"
+#include "utilities.h"
+#include "OpUtil.hxx"
+
+#include CORBA_CLIENT_HEADER(SALOME_Session)
+#include CORBA_CLIENT_HEADER(SALOME_Registry)
+#include CORBA_CLIENT_HEADER(SALOMEDS)
+#include CORBA_CLIENT_HEADER(SALOME_ModuleCatalog)
+#include CORBA_CLIENT_HEADER(SALOME_Component)
+
+#define MARGIN_SIZE  5
+#define SPACING_SIZE 3
+
+InquireServersGUI::InquireServersGUI()
+     : QVBox(0, "SFA splash", Qt::WDestructiveClose | Qt::WStyle_Customize | Qt::WStyle_NoBorder | WType_TopLevel | WStyle_StaysOnTop | WX11BypassWM  )
+{
+  //  myGUI = false;
+  myThread = new InquireServersQThread( this );
+
+  // 1. Polish the appearance
+  setMargin( MARGIN_SIZE );
+  setSpacing( SPACING_SIZE );
+  setFrameStyle( QFrame::Plain | QFrame::Box );
+  setLineWidth( 2 );
+  setMinimumSize( 200, 150 );
+
+  // 2. Splash image
+  QFrame* frm = new QFrame( this );
+  frm->setFrameStyle( QFrame::Box | QFrame::Raised );
+  QHBoxLayout* frmLayout = new QHBoxLayout( frm );
+  frmLayout->setMargin( MARGIN_SIZE );
+  mySplash = new QLabel( frm, "splash" );
+  frmLayout->addWidget( mySplash );
+
+  // setting pixmap
+  //QPixmap pix = SUIT_ResourceMgr( "SalomeApp" ).loadPixmap( "SalomeApp", tr( "ABOUT" ) );
+  //splash->setPixmap( pix  );
+  
+  // 3. Progress bar
+  myPrgBar = new QProgressBar( this, "QProgressBar" );
+  myPrgBar->setFixedWidth( 180 );
+  //Sets the total number of steps . 
+  myPrgBar->setTotalSteps ( myThread->getInquiredServers() );
+  myPrgBar->setProgress( 0 );
+
+  // 4. Info label
+  QWidget* aWgt1 = new QWidget( this );
+  QHBoxLayout* aHBoxLayout1 = new QHBoxLayout( aWgt1 );
+  myLabel = new QLabel( tr( "Loading:" ), aWgt1 );
+  myLabel->setFixedWidth( 180 );
+  myLabel->setAlignment( AlignLeft );
+  QFont theFont = myLabel->font();
+  theFont.setBold(true);
+  myLabel->setFont( theFont );
+  aHBoxLayout1->addItem( new QSpacerItem( 0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum ) );
+  aHBoxLayout1->addWidget( myLabel );
+  aHBoxLayout1->addItem( new QSpacerItem( 0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum ) );
+
+  // 5. <Cancel> button
+  QWidget* aWgt = new QWidget( this );
+  QHBoxLayout* aHBoxLayout = new QHBoxLayout( aWgt );
+  QPushButton* myCancelBtn = new QPushButton( tr( "Cancel" ), aWgt );
+  connect( myCancelBtn, SIGNAL( clicked() ), this, SLOT( ClickOnCancel() ) ) ;
+  aHBoxLayout->addItem( new QSpacerItem( 0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum )  );
+  aHBoxLayout->addWidget( myCancelBtn );
+  aHBoxLayout->addItem( new QSpacerItem( 0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum )  );
+
+  //Center widget
+#if QT_VERSION >= 0x030005
+  QDesktopWidget *d = QApplication::desktop();
+#else
+  QWidget *d = QApplication::desktop();
+#endif
+//VRV: porting on Qt 3.0.5
+
+  int w = d->width();         // returns desktop width
+  int h = d->height();        // returns desktop height
+  QSize mySize = sizeHint (); // returns widget size
+  int Xc = ( w - mySize.width() )  / 2;
+  int Yc = ( h - mySize.height() ) / 2;
+  move( Xc, Yc );
+
+  myThread->start();
+}
+
+void InquireServersGUI::setPixmap( QPixmap pix )
+{
+  if ( !pix.isNull() ) {
+    mySplash->setPixmap( pix );
+    myPrgBar->setFixedWidth( mySplash->sizeHint().width() );
+    myLabel->setFixedWidth( mySplash->sizeHint().width() );
+  }
+}
+
+InquireServersGUI::~InquireServersGUI()
+{
+  delete myThread;
+}
+
+void InquireServersGUI::getArgs( int& _argc, char *** _argv)
+{
+  _argc = qApp->argc();
+  *_argv = qApp->argv();
+}
+
+//=================================================================================
+// function : ClickOnCancel()
+// purpose  : cancel loading of SALOME
+//=================================================================================
+void InquireServersGUI::ClickOnCancel()
+{
+  //it's necessary to stop asking servers
+  myThread->stop();
+  //  myGUI = false;
+  //Also we should send QCloseEvent in order to close this widget (and remove from screen) 
+  //QThread::postEvent ( this, new QCloseEvent() );
+  qApp->exit(1);
+}
+
+void InquireServersGUI::closeEvent ( QCloseEvent * pe)
+{
+  //default implementation calls e->accept(), which hides this widget. 
+  //See the QCloseEvent documentation for more details.
+  pe->accept();
+  QApplication::flushX ();
+  QApplication::syncX ();
+  qApp->exit();
+}
+
+void InquireServersGUI::customEvent( QCustomEvent* pe )
+{
+  switch( pe->type() )
+    {
+        case InquireEvent::ProgressEvent:
+        {
+            int* value = ( int* )(( InquireEvent*)pe)->data();
+            myPrgBar->setProgress( *value );
+            break;
+        }
+        case InquireEvent::ProgressEventLabel:
+        {
+            QString* myString = ( QString* )(( InquireEvent*)pe)->data();
+            myLabel->setText( *myString );
+            break;
+        }
+        case InquireEvent::ProgressEventError:
+        {
+            QString* myErrDesc = ( QString* )(( InquireEvent*)pe)->data();
+           QString  appName = "SALOME Professional";
+           QString  error = "An internal error occurred.\n"+ *myErrDesc + "\n";
+           QMessageBox myMsgBox(appName,error,QMessageBox::Critical,QMessageBox::Ok,QMessageBox::NoButton,
+                                       QMessageBox::NoButton,0,"MY",TRUE,WStyle_DialogBorder|WStyle_StaysOnTop);
+           myMsgBox.exec();
+           ClickOnCancel();
+            break;
+        }
+      default:
+       {
+         ;
+       }
+    }
+}
+
+int InquireServersGUI::getExitStatus()
+{
+  return myThread->getExitStatus();
+}
+
+InquireServersQThread::InquireServersQThread( InquireServersGUI* r )
+     : receiver(r),  myExitStatus(0)
+{
+  char* cenv;
+
+  IsChecking = true;
+  myServersCount = 5;
+  //how many times we should repeat attempts to get response from all needed for launching SALOME servers
+  myRepeat = 30; // default value, user can change it by setting CSF_RepeatServerRequest env.variable
+  cenv = getenv( "CSF_RepeatServerRequest" );
+  if ( cenv ) {
+    int val = atoi( cenv );
+    if ( val > 0 )
+      myRepeat = val;
+  }
+  //define delay time between two attempts
+  myDelay = 1000000; // 1 second
+  QString str = "Loading: ";
+  myMessages[0] = "Checking naming service...";
+  myMessages[1] = str + "SALOME_Registry_Server" + "...";
+  myMessages[2] = str + "SALOMEDS_Server" + "...";
+  myMessages[3] = str + "SALOME_ModuleCatalog_Server" + "...";
+  myMessages[4] = str + "SALOME_Session_Server" + "...";
+  myMessages[5] = "";
+  myMessages[6] = "";
+  myMessages[7] = "";
+
+  r->getArgs( _argc, &_argv);
+
+  // NRI : Temporary solution for SuperVisionContainer
+  for ( int i=1; i<=(_argc-1); i++) {
+    if (strcmp(_argv[i],"CPP")==0) {
+      myMessages[5] = str + "SALOME_Container FactoryServer" + "...";
+      myServersCount++;
+    }
+    if (strcmp(_argv[i],"PY")==0) {
+      myMessages[6] = str + "SALOME_ContainerPy.py FactoryServerPy" + "...";
+      myServersCount++;
+    }
+    if (strcmp(_argv[i],"SUPERV")==0) {
+      myMessages[7] = str + "SALOME_Container SuperVisionContainer" + "...";
+      myServersCount++;
+    }
+//    if (strcmp(_argv[i],"GUI")==0) {
+//      r->withGUI(true);
+//    }
+  }
+}
+
+void InquireServersQThread::run()
+{
+  while (IsChecking)
+  {
+    if ( !receiver ) 
+    {
+      myExitStatus = 0;
+      return;
+    }
+    for (int i=1; i<=8; i++)
+      {
+       if ( myMessages[i-1].isEmpty() ) {
+         if (i==8) {
+           IsChecking = false;
+           //myExitStatus should be 0 because all servers exist and work
+           myExitStatus = 0;
+           //we should send QCloseEvent in order to close this widget (and remove from screen) 
+           QThread::postEvent ( receiver , new QCloseEvent() );
+         } else
+           continue;
+       }
+       QString *message = new QString(myMessages[i-1]);
+       QThread::postEvent( receiver, new InquireEvent( ( QEvent::Type )InquireEvent::ProgressEventLabel, message ) );
+       QThread::usleep(200000);
+       QString *errMsg;
+       bool result = AskServer(i,&errMsg);
+       if (result)
+         {
+           QThread::postEvent( receiver, new InquireEvent( ( QEvent::Type )InquireEvent::ProgressEvent, new int( i ) ) );
+           if (i==8)
+             {
+               IsChecking = false;
+               //myExitStatus should be 0 because all servers exist and work
+               myExitStatus = 0;
+               //we should send QCloseEvent in order to close this widget (and remove from screen) 
+               QThread::postEvent ( receiver , new QCloseEvent() );
+             }
+         }
+       else
+         {
+           QThread::postEvent( receiver, new InquireEvent( ( QEvent::Type )InquireEvent::ProgressEventError, errMsg ) );
+           //myExitStatus should be 1 because we didn't receive response from server
+           myExitStatus = 1;
+           return;
+         }
+      }
+  }
+}
+
+bool InquireServersQThread::AskServer(int iteration, QString ** errMessage)
+{
+  if ( iteration > myServersCount )
+    return true; // we did not launch server with number iteration, so checking for it is not neccessary
+
+  ASSERT(iteration<=myServersCount);
+
+  //will be set true if we get response from server
+  bool IsPassed = false;
+  QString errDescription;
+  switch (iteration)
+    {
+    case 1:
+      //First checking - existence of Naming Service
+      for (int i = myRepeat; i ; i--)
+       {
+         try
+           {
+             CORBA::ORB_var orb = CORBA::ORB_init(_argc,_argv) ;
+             CORBA::Object_var obj = orb->resolve_initial_references("NameService");
+             CosNaming::NamingContext_var _root_context = CosNaming::NamingContext::_narrow(obj);
+             if (CORBA::is_nil(_root_context))
+               continue;
+             else
+               IsPassed = true;
+             break;
+           }
+         catch(CORBA::COMM_FAILURE&)
+           {
+             MESSAGE("CORBA::COMM_FAILURE: unable to contact the naming service");
+           }
+         catch(...)
+           {
+             MESSAGE("Unknown Exception: unable to contact the naming service");
+           }
+         QThread::usleep(myDelay);
+       }
+      if (!IsPassed)
+       *errMessage = new QString("unable to contact the naming service");
+      break;
+    case 2:
+      //checking - existence of SALOME_Registry_Server
+    case 3:
+      //checking - existence of SALOMEDS_Server
+    case 4:
+      //checking - existence of SALOME_ModuleCatalog_Server
+    case 5:
+      //checking - existence of SALOME_Session_Server
+    case 6:
+      //checking - existence of SALOME_Container FactoryServer
+    case 7:
+      //checking - existence of SALOME_ContainerPy.py FactoryServerPy
+    case 8:
+      //checking - existence of SALOME_Container SuperVisionContainer
+
+
+      IsPassed = pingServer(iteration, errDescription);
+      if (!IsPassed)
+       *errMessage = new QString(errDescription);
+      break;
+    }
+return IsPassed;
+}
+
+bool InquireServersQThread::pingServer(int iteration, QString& errMessage)
+{
+  ASSERT(iteration<=myServersCount);
+  bool result = false;
+  QString errorDescr;
+  for (int i = myRepeat; i ; i--)
+    {
+      try
+       {
+         CORBA::ORB_var orb = CORBA::ORB_init(_argc,_argv) ;
+         SALOME_NamingService &NS = *SINGLETON_<SALOME_NamingService>::Instance() ;
+         ASSERT(SINGLETON_<SALOME_NamingService>::IsAlreadyExisting()) ;
+         NS.init_orb( orb ) ;
+         switch (iteration)
+           {
+           case 2:
+             {
+               CORBA::Object_var obj = NS.Resolve("/Registry");
+               Registry::Components_var registry = Registry::Components::_narrow(obj) ;
+               if (!CORBA::is_nil(registry))
+                 {
+                   MESSAGE("/Registry is found");
+                   registry->ping();
+                   result = true;
+                   MESSAGE("Registry was activated");
+                   return result;
+                 }
+             }
+             break;
+           case 3:
+             {
+               CORBA::Object_var obj = NS.Resolve("/myStudyManager");
+               SALOMEDS::StudyManager_var studyManager = SALOMEDS::StudyManager::_narrow(obj) ;
+               if (!CORBA::is_nil(studyManager))
+
+
+
+
+
+                 {
+                   MESSAGE("/myStudyManager is found");
+                   studyManager->ping();
+                   result = true;
+                   MESSAGE("StudyManager was activated");
+                   return result;
+                 }
+             }
+             break;
+           case 4:
+             {
+               CORBA::Object_var obj = NS.Resolve("/Kernel/ModulCatalog");
+               SALOME_ModuleCatalog::ModuleCatalog_var catalog = SALOME_ModuleCatalog::ModuleCatalog::_narrow(obj) ;
+               if (!CORBA::is_nil(catalog))
+                 {
+                   MESSAGE("/Kernel/ModulCatalog is found");
+                   catalog->ping();
+                   result = true;
+                   MESSAGE("ModuleCatalog was activated");
+                   return result;
+                 }
+             }
+             break;
+           case 5:
+             {
+               CORBA::Object_var obj = NS.Resolve("/Kernel/Session");
+               SALOME::Session_var session = SALOME::Session::_narrow(obj) ;
+               if (!CORBA::is_nil(session))
+                 {
+                   MESSAGE("/Kernel/Session is found");
+                   session->ping();
+                   result = true;
+                   MESSAGE("SALOME_Session was activated");
+                   return result;
+                 }
+             }
+             break;
+           case 6:
+             {
+               string hostname = GetHostname();
+               string containerName = "/Containers/";
+               containerName += hostname;
+               containerName += "/FactoryServer";
+
+               CORBA::Object_var obj = NS.Resolve(containerName.c_str());
+               Engines::Container_var FScontainer = Engines::Container::_narrow(obj) ;
+               if (!CORBA::is_nil(FScontainer))
+                 {
+                   FScontainer->ping();
+                   result = true;
+                   MESSAGE("FactoryServer container was activated");
+                   return result;
+                 }
+             }
+             break;
+           case 7:
+             {
+               string hostname = GetHostname();
+               string containerName = "/Containers/";
+               containerName += hostname;
+               containerName += "/FactoryServerPy";
+               
+               CORBA::Object_var obj = NS.Resolve(containerName.c_str());
+               Engines::Container_var FSPcontainer = Engines::Container::_narrow(obj) ;
+               if (!CORBA::is_nil(FSPcontainer))
+                 {
+                   FSPcontainer->ping();
+                   result = true;
+                   MESSAGE("FactoryServerPy container was activated");
+                   return result;
+                 }
+             }
+             break;
+           case 8:
+             {
+               string hostname = GetHostname();
+               string containerName = "/Containers/";
+               containerName += hostname;
+               containerName += "/SuperVisionContainer";
+               
+               CORBA::Object_var obj = NS.Resolve(containerName.c_str());
+               Engines::Container_var SVcontainer = Engines::Container::_narrow(obj) ;
+               if (!CORBA::is_nil(SVcontainer))
+                 {
+                   SVcontainer->ping();
+
+                   result = true;
+                   MESSAGE("SuperVisionContainer container was activated");
+                   return result;
+                 }
+             }
+             break;
+           }
+        }
+      catch (ServiceUnreachable&)
+       {
+         MESSAGE("Caught exception: Naming Service Unreachable");
+         errorDescr = "Caught exception: Naming Service Unreachable";
+       }
+      catch (CORBA::COMM_FAILURE&)
+       {
+         MESSAGE("Caught CORBA::SystemException CommFailure.");
+         errorDescr = "Caught CORBA::SystemException CommFailure";
+       }
+      catch (CORBA::SystemException&)
+       {
+         MESSAGE("Caught CORBA::SystemException.");
+         errorDescr = "Caught CORBA::SystemException";
+       }
+      catch (CORBA::Exception&)
+       {
+         MESSAGE("Caught CORBA::Exception.");
+         errorDescr = "Caught CORBA::Exception";
+       }
+      catch (...)
+       {
+         MESSAGE("Caught unknown exception.");
+         errorDescr = "Caught unknown exception";
+       }
+      QThread::usleep(myDelay);
+    }
+  if (!result)
+    {
+      QString serverName;
+      switch (iteration)
+       {
+       case 2:
+         serverName = "SALOME_Registry_Server is not loaded. ";
+         break;
+       case 3:
+         serverName = "SALOMEDS_Server is not loaded. ";
+         break;
+       case 4:
+         serverName = "SALOME_ModuleCatalog_Server is not loaded. ";
+         break;
+       case 5:
+         serverName = "SALOME_Session_Server is not loaded. ";
+         break;
+       case 6:
+         serverName = "SALOME_Container FactoryServer is not loaded. ";
+         break;
+       case 7:
+         serverName = "SALOME_ContainerPy.py FactoryServerPy is not loaded. ";
+         break;
+       case 8:
+         serverName = "SALOME_Container SuperVisionContainer is not loaded. ";
+         break;
+       }
+      errMessage = serverName + errorDescr;
+    }
+  return result;
+}
diff --git a/src/Session/InquireServersQThread.h b/src/Session/InquireServersQThread.h
new file mode 100755 (executable)
index 0000000..37b32cd
--- /dev/null
@@ -0,0 +1,118 @@
+//  Copyright (C) 2003  CEA/DEN, EDF R&D
+//
+//
+//
+//  File   : InquireServersQThread.h
+//  Author : Vasily RUSYAEV
+//  Module : SALOME
+//  $Header$
+
+#include <qapplication.h>
+#include <qthread.h> 
+#include <qvbox.h> 
+#include <qprogressbar.h> 
+#include <qlabel.h> 
+
+/**********************************************************
+**  Class:   InquireEvent
+**  Descr:   Contains QCustomEvents for posting to InquireServersQThread
+**  Level:   Private
+***********************************************************/
+
+class InquireEvent : public QCustomEvent
+{
+public:
+
+  enum myCustomEvents{ ProgressEvent = QEvent::User + 10, ProgressEventLabel, ProgressEventError };
+  
+  InquireEvent( QEvent::Type type , void* data = 0 )
+        : QCustomEvent( type, data ) {}
+  ~InquireEvent() 
+      {
+        type() == (QEvent::Type)ProgressEvent ?
+         delete ( int* )data() : delete ( QString* )data();
+      }
+};
+
+class InquireServersGUI;
+
+class InquireServersQThread : public QThread
+{
+public:
+  InquireServersQThread( InquireServersGUI* r );
+
+  //the main loop of this thread
+  virtual void run() ;
+  //stop to ask servers
+  void stop() 
+    {
+      IsChecking = false;
+      myExitStatus = 1;
+    }
+  //return exit status: 0 - OK, >0 - BAD (some servers doesn't exists or user click cancel button) 
+  int getExitStatus() { return myExitStatus;}
+  //return count of inquired servers
+  int getInquiredServers() { return myServersCount; }
+
+private:
+
+//functions:
+
+  bool AskServer(int iteration, QString ** message);
+  bool pingServer(int iteration, QString& errMessage);
+
+//variables:
+
+  InquireServersGUI* receiver;
+  int _argc ;
+  char ** _argv;
+  //this variable is true if we are checking servers
+  bool IsChecking;
+  //count of inquired servers
+  int myServersCount;
+  //how many times we should repeat attempt to get response from all needed for launching SALOME servers
+  int myRepeat;
+  //define delay time between two attempts in microseconds
+  int myDelay;
+  //this strings' array contains messages for each server (e.g. "Loading: SALOMEDS_Server") 
+  QString myMessages[8];
+  //exit status: 0 - OK, >0 - BAD (some servers doesn't exists or user click cancel button) 
+  int myExitStatus;
+
+} ;
+
+class InquireServersGUI : public QVBox
+{
+    Q_OBJECT
+
+public:
+  InquireServersGUI() ;
+  ~InquireServersGUI();
+
+  //returns arguments of QApplication
+  //they are needed for CORBA servers initialization
+  void getArgs(  int& _argc, char *** _argv);
+  //return exit status: 0 - OK, >0 - BAD (some servers doesn't exists or user click cancel button) 
+  int getExitStatus();
+  //launch IAPP
+  //  bool withGUI() { return myGUI; }
+  //  void withGUI(bool gui) { myGUI = gui; }
+
+  void setPixmap( QPixmap );
+
+protected:
+  virtual void customEvent( QCustomEvent* ); 
+  virtual void closeEvent ( QCloseEvent * );
+
+private:
+  InquireServersQThread* myThread;
+  QProgressBar* myPrgBar;
+  //this string contains description of currently asked server
+  QLabel* myLabel;
+  QLabel* mySplash;
+  //  bool myGUI;
+
+private slots:
+
+    void ClickOnCancel();
+} ;
index 69ee385f0fcab9ee0f107e47a4b5af63170ef319..a97a1583b22f7b22111cd9f9351020eca7dffb63 100755 (executable)
@@ -47,7 +47,10 @@ LIB_SRC=Session_Session_i.cxx \
        Session_ServerThread.cxx \
        Session_ServerLauncher.cxx \
        Session_SignalsHandler.cxx \
-       SalomeApp_Engine_i.cxx
+       SalomeApp_Engine_i.cxx \
+       InquireServersQThread.cxx
+
+LIB_MOC = InquireServersQThread.h
 
 # Executables targets
 BIN = SALOME_Session_Server
index 415c5328ac0b8d8feaa9c36d956308a7b2cdc1ac..368b63c8df0c6bdd714010e1e41cc5cfc84c2399 100755 (executable)
@@ -32,6 +32,8 @@
 #include "SALOME_NamingService.hxx"
 #include "SALOMETraceCollector.hxx"
 
+#include "InquireServersQThread.h" // splash
+
 #include <iostream>
 #include <unistd.h>
 
@@ -55,6 +57,7 @@
 #include "SUIT_Session.h"
 #include "SUIT_Application.h"
 #include "SUIT_MessageBox.h"
+#include "SUIT_Tools.h"
 
 
 #include "SUIT_ExceptionHandler.h"
@@ -163,15 +166,38 @@ private:
   SUIT_ExceptionHandler*  myHandler;
 };
 
+// class which calls SALOME::Session::GetInterface() from another thread
+// to avoid mutual lock (if called from the same thread as main()
+class GetInterfaceThread : public QThread
+{
+public: 
+  GetInterfaceThread( SALOME::Session_var s ) : session ( s ) {}
+protected:
+  virtual void run()
+  {
+    if ( !CORBA::is_nil( session ) )
+      session->GetInterface(); 
+    else
+      printf( "\nFATAL ERROR: SALOME::Session object is nil!  Can not display GUI\n\n" );
+  }
+private:
+  SALOME::Session_var session;
+};
+
+// returns true if 'str' is found in argv
+bool isFound( const char* str, int argc, char** argv )
+{
+  for ( int i = 1; i <= (argc-1); i++ )
+    if ( !strcmp( argv[i], str ) )
+      return true;
+  return false;
+}
+
+// ---------------------------- MAIN -----------------------
 int main(int argc, char **argv)
 {
   qInstallMsgHandler( MessageOutput );
 
-  /*
-  char* _argv_0[512];
-  strcpy( (char*)_argv_0, (char*)argv[0] );
-  */
-
   // QApplication should be create before all other operations
   // When uses QApplication::libraryPaths() (example, QFile::encodeName())
   // qApp used for detection of the executable dir path.
@@ -192,17 +218,17 @@ int main(int argc, char **argv)
   char* _argv[] = {""};
   KERNEL_PYTHON::init_python(_argc,_argv);
   PyEval_RestoreThread(KERNEL_PYTHON::_gtstate);
-  if(!KERNEL_PYTHON::salome_shared_modules_module) // import only once
-    {
-      KERNEL_PYTHON::salome_shared_modules_module =
-       PyImport_ImportModule("salome_shared_modules");
-    }
-  if(!KERNEL_PYTHON::salome_shared_modules_module)
-    {
-      INFOS("salome_shared_modules_module == NULL");
-      PyErr_Print();
-      PyErr_Clear();
-    }
+  if ( !KERNEL_PYTHON::salome_shared_modules_module ) // import only once
+  {
+    KERNEL_PYTHON::salome_shared_modules_module =
+      PyImport_ImportModule("salome_shared_modules");
+  }
+  if ( !KERNEL_PYTHON::salome_shared_modules_module )
+  {
+    INFOS("salome_shared_modules_module == NULL");
+    PyErr_Print();
+    PyErr_Clear();
+  }
   PyEval_ReleaseThread(KERNEL_PYTHON::_gtstate);
 
   int result = -1;
@@ -213,167 +239,138 @@ int main(int argc, char **argv)
   int orbArgc = 1;
   CORBA::ORB_var &orb = init( orbArgc , argv ) ;
   SALOMETraceCollector *myThreadTrace = SALOMETraceCollector::instance(orb);
+  GetInterfaceThread* guiThread = 0;
 
   try
+  {
+    SALOME_Event::GetSessionThread();
+
+    CORBA::Object_var obj = orb->resolve_initial_references("RootPOA");
+    PortableServer::POA_var poa = PortableServer::POA::_narrow(obj);
+
+    PortableServer::POAManager_var pman = poa->the_POAManager() ;
+    pman->activate() ;
+    INFOS("pman->activate()");
+
+    SALOME_NamingService *_NS = new SALOME_NamingService(orb);
+
+    // CORBA Servant Launcher
+    QMutex _GUIMutex ;
+    QWaitCondition _ServerLaunch;
+    _GUIMutex.lock();     // to block Launch server thread until wait(mutex)
+    
+    // 2. activate embedded CORBA servers: Registry, SALOMEDS, etc.
+    Session_ServerLauncher* myServerLauncher
+      = new Session_ServerLauncher(argc, argv, orb, poa, &_GUIMutex, &_ServerLaunch);
+    myServerLauncher->start();
+    
+    _ServerLaunch.wait(&_GUIMutex); // to be reseased by Launch server thread when ready:
+    // show splash screen if "SPLASH" parameter was passed (default)
+    if ( isFound( "SPLASH", argc, argv ) ) 
     {
-      SALOME_Event::GetSessionThread();
-
-      CORBA::Object_var obj = orb->resolve_initial_references("RootPOA");
-      PortableServer::POA_var poa = PortableServer::POA::_narrow(obj);
-
-      PortableServer::POAManager_var pman = poa->the_POAManager() ;
-      pman->activate() ;
-      INFOS("pman->activate()");
-
-      SALOME_NamingService *_NS = new SALOME_NamingService(orb);
-
-      // CORBA Servant Launcher
-      QMutex _GUIMutex ;
-      QWaitCondition _ServerLaunch;
-      _GUIMutex.lock();     // to block Launch server thread until wait(mutex)
-
-      // 2. activate embedded CORBA servers: Registry, SALOMEDS, etc.
-      Session_ServerLauncher* myServerLauncher
-       = new Session_ServerLauncher(argc, argv, orb, poa, &_GUIMutex, &_ServerLaunch);
-      myServerLauncher->start();
-
-      // 3. GUI activation
-      // Allow multiple activation/deactivation of GUI
-      //while ( 1 ) {
-       MESSAGE("waiting wakeAll()");
-       _ServerLaunch.wait(&_GUIMutex); // to be reseased by Launch server thread when ready:
-       // atomic operation lock - unlock on mutex
-       // unlock mutex: serverThread runs, calls  _ServerLaunch->wakeAll()
-       // this thread wakes up, and lock mutex
-
-       INFOS("Session activated, Launch IAPP...");
-       /*
-       int qArgc = 1;
-       argv[0] = (char*)_argv_0;
-       SALOME_QApplication* _qappl = new SALOME_QApplication( qArgc, argv );
-
-       QStringList lst = _qappl->libraryPaths();
-       for ( QStringList::const_iterator it = lst.begin(); it != lst.end(); ++it )
-         printf( "=====> Library path: %s\n", (*it).latin1() );
-
-       _qappl->setStyle( "salome" );
-
-       ASSERT ( QObject::connect(_qappl, SIGNAL(lastWindowClosed()), _qappl, SLOT(quit()) ) );
-       */
-       
-       INFOS("creation QApplication");
-       _GUIMutex.unlock();
-
-       // 3.1 SUIT_Session creation    
-       SUIT_Session* aGUISession = new SALOME_Session();
-       INFOS("creation SUIT_Application");
-
-       SCRUTE(_NS);
-
-       // 3.3 run GUI loop
-       // T2.12 - catch exceptions thrown on attempts to modified a locked study
-       while (1) {
-         try 
-         {
-           MESSAGE("run(): starting the main event loop");
-
-           // 3.2 load SalomeApp dynamic library
-            SUIT_Application* aGUIApp = aGUISession->startApplication( "SalomeApp", 0, 0 );
-           if ( aGUIApp ) 
-           {
-             _qappl.setHandler( aGUISession->handler() ); // after loading SalomeApp application
-                                                            // aGUISession contains SalomeApp_ExceptionHandler
-             result = _qappl.exec();
-           }
-           break;
-         }
-         catch (SALOME::SALOME_Exception& e)
-         {
-           INFOS("run(): SALOME_Exception was caught!");
-           QApplication::restoreOverrideCursor();
-           SUIT_MessageBox::warn1 ( 0,
-                                   QObject::tr("WRN_WARNING"), 
-                                   QObject::tr("SALOME_Exception was caught!"),
-                                   QObject::tr("BUT_OK") );
-           //QtCatchCorbaException(e);
-         }
-         catch(SALOMEDS::StudyBuilder::LockProtection&)
-         {
-           INFOS("run(): An attempt to modify a locked study has not been handled by QAD_Operation");
-           QApplication::restoreOverrideCursor();
-           SUIT_MessageBox::warn1 ( 0,
-                                   QObject::tr("WRN_WARNING"), 
-                                   QObject::tr("WRN_STUDY_LOCKED"),
-                                   QObject::tr("BUT_OK") );
-         }
-         catch (const CORBA::Exception& e)
-         {
-           CORBA::Any tmp;
-           tmp<<= e;
-           CORBA::TypeCode_var tc = tmp.type();
-           const char *p = tc->name();
-           INFOS ("run(): CORBA exception of the kind : "<<p<< " is caught");
-
-           QApplication::restoreOverrideCursor();
-           SUIT_MessageBox::error1 ( 0,
-                                    QObject::tr("ERR_ERROR"), 
-                                    QObject::tr("ERR_APP_EXCEPTION")
-                                    + QObject::tr(" CORBA exception ") + QObject::tr(p),
-                                    QObject::tr("BUT_OK") );
-         }
-         catch(exception& e)
-         {
-           INFOS("run(): An exception has been caught");
-           QApplication::restoreOverrideCursor();
-           SUIT_MessageBox::error1 ( 0,
-                                    QObject::tr("ERR_ERROR"), 
-                                    QObject::tr("ERR_APP_EXCEPTION")+ "\n" +QObject::tr(e.what()),
-                                    QObject::tr("BUT_OK") );
-         }
-         catch(...)
-         {
-           INFOS("run(): An exception has been caught");
-           QApplication::restoreOverrideCursor();
-           SUIT_MessageBox::error1 ( 0,
-                                    QObject::tr("ERR_ERROR"), 
-                                    QObject::tr("ERR_APP_EXCEPTION"),
-                                    QObject::tr("BUT_OK") );
-         }
-       }
-//}  end of "outer" while( 1 )
+      // create temporary resource manager just to load splash icon
+      SUIT_ResourceMgr resMgr( "SalomeApp", QString( "%1Config" ) );
+      resMgr.setVersion( salomeVersion() );
+      resMgr.setCurrentFormat( "xml" );
+      resMgr.loadLanguage( "SalomeApp", "en" );
+      // create splash object: widget (splash with progress bar) and "pinging" thread
+      InquireServersGUI splash;
+      splash.setPixmap( resMgr.loadPixmap( "SalomeApp", QObject::tr( "ABOUT" ) ) );
+      SUIT_Tools::centerWidget( &splash, _qappl.desktop() );
+
+      _qappl.setMainWidget( &splash );
+      QObject::connect( &_qappl, SIGNAL( lastWindowClosed() ), &_qappl, SLOT( quit() ) );
+      splash.show(); // display splash with running progress bar 
+      _qappl.exec(); // wait untill splash closes (progress runs till end or Cancel is pressed)
+
+      //int q = 0;
+      //while ( q++ < 10 )
+      //  sleep( 1 );
+    
+      if ( splash.getExitStatus() ) // 1 is error
+       exit( splash.getExitStatus() ); // quit applicaiton
+    }
 
-      // Prepare _GUIMutex for a new GUI activation
-      //_GUIMutex.lock(); 
-       //      }
+    // call Session::GetInterface() if "GUI" parameter was passed (default) 
+    if ( isFound( "GUI", argc, argv ) ) 
+    {
+      CORBA::Object_var obj = _NS->Resolve("/Kernel/Session");
+      SALOME::Session_var session = SALOME::Session::_narrow( obj ) ;
+      ASSERT (! CORBA::is_nil( session ) );
 
-      //orb->shutdown(0);
-      //myServerLauncher->KillAll();
+      INFOS("Session activated, Launch IAPP...");
+      guiThread = new GetInterfaceThread( session );
+      guiThread->start();
     }
-  catch (SALOME_Exception& e)
+
+    // 3. GUI activation
+    // Allow multiple activation/deactivation of GUI
+    while ( 1 ) 
     {
-      INFOS("run(): SALOME::SALOME_Exception is caught: "<<e.what());
+      MESSAGE("waiting wakeAll()");
+      _ServerLaunch.wait(&_GUIMutex); // to be reseased by Launch server thread when ready:
+      // atomic operation lock - unlock on mutex
+      // unlock mutex: serverThread runs, calls  _ServerLaunch->wakeAll()
+      // this thread wakes up, and lock mutex
+            
+      _GUIMutex.unlock();
+
+      // 3.1 SUIT_Session creation     
+      SUIT_Session* aGUISession = new SALOME_Session();
+      INFOS("creation SUIT_Application");
+      
+      SCRUTE(_NS);
+      
+      // 3.3 run GUI loop
+      // T2.12 - catch exceptions thrown on attempts to modified a locked study
+      MESSAGE("run(): starting the main event loop");
+      
+      // 3.2 load SalomeApp dynamic library
+      SUIT_Application* aGUIApp = aGUISession->startApplication( "SalomeApp", 0, 0 );
+      if ( aGUIApp ) 
+      {
+       _qappl.setHandler( aGUISession->handler() ); // after loading SalomeApp application
+                                                    // aGUISession contains SalomeApp_ExceptionHandler
+       result = _qappl.exec();
+
+       if ( result == SUIT_Session::FROM_GUI ) // desktop is closed by user from GUI
+         break;
+      }
+
+      // Prepare _GUIMutex for a new GUI activation
+      _GUIMutex.lock(); 
     }
+
+    //orb->shutdown(0);
+    myServerLauncher->KillAll();  // kill embedded servers
+  }
+  catch (SALOME_Exception& e)
+  {
+    INFOS("run(): SALOME::SALOME_Exception is caught: "<<e.what());
+  }
   catch (CORBA::SystemException& e)
-    {
-      INFOS("Caught CORBA::SystemException.");
-    }
+  {
+    INFOS("Caught CORBA::SystemException.");
+  }
   catch (CORBA::Exception& e)
-    {
-      INFOS("Caught CORBA::Exception.");
-      CORBA::Any tmp;
-      tmp<<= e;
-      CORBA::TypeCode_var tc = tmp.type();
-      const char *p = tc->name();
-      INFOS ("run(): CORBA exception of the kind : "<<p<< " is caught");
-    }
+  {
+    INFOS("Caught CORBA::Exception.");
+    CORBA::Any tmp;
+    tmp<<= e;
+    CORBA::TypeCode_var tc = tmp.type();
+    const char *p = tc->name();
+    INFOS ("run(): CORBA exception of the kind : "<<p<< " is caught");
+  }
   catch(exception& e)
-    {
-      INFOS("run(): An exception has been caught: " <<e.what());
-    }
+  {
+    INFOS("run(): An exception has been caught: " <<e.what());
+  }
   catch (...)
-    {
-      INFOS("Caught unknown exception.");
-    }
+  {
+    INFOS("Caught unknown exception.");
+  }
   delete myThreadTrace;
+  if ( guiThread )
+    delete guiThread;
   return result ;
 }
index 91fb01334e1b5606decc4d43314190aa8c304661..b361fbf9eb66a53918e546678a0aaf6d6d9dbfc0 100755 (executable)
@@ -81,11 +81,11 @@ Session_ServerLauncher::~Session_ServerLauncher()
 
 void Session_ServerLauncher::run()
 {
-  //MESSAGE("Session_ServerLauncher::run");
+  MESSAGE("****>>> Session_ServerLauncher::run");
   _GUIMutex->lock(); // lock released by calling thread when ready: wait(mutex)
-  //MESSAGE("Server Launcher thread free to go...");
+  MESSAGE("****>>> Server Launcher thread free to go...");
    _GUIMutex->unlock();
-
+   _ServerLaunch->wakeAll();
   CheckArgs();
   ActivateAll();
 
@@ -206,6 +206,8 @@ std::cout << "*** activating [" << argc << "] : " << argv[0] << std::endl;
 
   // Always launch Session Server
 
+std::cout << "*** activating [ SESSION ] " << std::endl;
+
   int argc=1;
   char** argv = new char*[argc];
   argv[0] = "Session";
index 0b9fe8ae00cb7bebb4bb8e0bb8ea7f0e5699c246..e383b774f79ade4b2f32b5cb32418a71afc2f0d9 100755 (executable)
@@ -134,6 +134,8 @@ void SALOME_Session_i::NSregister()
 
 void SALOME_Session_i::GetInterface()
 {
+  _GUIMutex->lock();
+  _GUIMutex->unlock();
   if( !SUIT_Session::session() ) {    
     _GUILauncher->wakeAll();
     MESSAGE("SALOME_Session_i::GetInterface() called, starting GUI...")
@@ -149,8 +151,10 @@ class CloseEvent : public SALOME_Event
 {
 public:
   virtual void Execute() {
-//if ( SUIT_Application::getDesktop() )
-//  QAD_Application::getDesktop()->closeDesktop( true );
+    SUIT_Session* session = SUIT_Session::session();
+    session->closeSession( SUIT_Session::DONT_SAVE );
+    //if ( SUIT_Application::getDesktop() )
+    //  QAD_Application::getDesktop()->closeDesktop( true );
   }
 };