: QObject(),
myResMgr( 0 ),
myHandler( 0 ),
-myActiveApp( 0 )
+myActiveApp( 0 ),
+myExitStatus( FROM_GUI )
{
SUIT_ASSERT( !mySession )
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();
}
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();
SUIT_ResourceMgr* resourceMgr() const;
- void closeSession();
+ void closeSession( int mode = ASK );
SUIT_ExceptionHandler* handler() const;
SUIT_ExceptionHandler* myHandler;
static SUIT_Session* mySession;
+
+ int myExitStatus;
};
#endif
--- /dev/null
+// 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;
+}
--- /dev/null
+// 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();
+} ;
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
#include "SALOME_NamingService.hxx"
#include "SALOMETraceCollector.hxx"
+#include "InquireServersQThread.h" // splash
+
#include <iostream>
#include <unistd.h>
#include "SUIT_Session.h"
#include "SUIT_Application.h"
#include "SUIT_MessageBox.h"
+#include "SUIT_Tools.h"
#include "SUIT_ExceptionHandler.h"
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.
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;
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 ;
}
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();
// Always launch Session Server
+std::cout << "*** activating [ SESSION ] " << std::endl;
+
int argc=1;
char** argv = new char*[argc];
argv[0] = "Session";
void SALOME_Session_i::GetInterface()
{
+ _GUIMutex->lock();
+ _GUIMutex->unlock();
if( !SUIT_Session::session() ) {
_GUILauncher->wakeAll();
MESSAGE("SALOME_Session_i::GetInterface() called, starting GUI...")
{
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 );
}
};