Salome HOME
Revamped Python interpreter logic in GUI.
[modules/gui.git] / src / SUITApp / SUITApp.cxx
1 // Copyright (C) 2007-2013  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 //#if defined WIN32
24 //#ifdef SUIT_ENABLE_PYTHON
25 //#undef SUIT_ENABLE_PYTHON
26 //#endif
27 //#else //#if defined WIN32
28 //#ifndef SUIT_ENABLE_PYTHON
29 // NOTE: DO NOT DELETE THIS DEFINITION ON LINUX
30 // or make sure Python is initialized in main() in any case
31 // Otherwise, application based on light SALOME and using Python 
32 // are unlikely to work properly.
33 //#define SUIT_ENABLE_PYTHON
34 //#include <Python.h>
35 //#endif
36 //
37 #ifdef SUIT_ENABLE_PYTHON
38 #include "SUITApp_init_python.hxx"
39 #endif
40
41 //#endif //#if defined WIN32
42
43 #include "GUI_version.h"
44 #include "SUITApp_Application.h"
45 #include "SUIT_Desktop.h"
46 #include "SUIT_LicenseDlg.h"
47 #include "SUIT_ResourceMgr.h"
48 #include "SUIT_Session.h"
49 #include "Style_Salome.h"
50 #include "QtxSplash.h"
51
52 #include <QDir>
53 #include <QFile>
54 #include <QRegExp>
55 #include <QString>
56 #include <QStringList>
57
58 #include <stdlib.h>
59
60 #ifdef WIN32
61 #include <UserEnv.h>
62 #endif
63
64 static QString salomeVersion()
65 {
66   return GUI_VERSION_STR;
67 }
68
69 static QString getAppName( const QString& libName )
70 {
71   QString appName = QFileInfo( libName ).baseName();
72   if ( appName.startsWith( "lib" ) ) appName = appName.mid( 3 );
73   return appName;
74 }
75
76 // static void MessageOutput( QtMsgType type, const char* msg )
77 // {
78 //   switch ( type )
79 //   {
80 //   case QtDebugMsg:
81 // #ifdef _DEBUG_
82 //     printf( "Debug: %s\n", msg );
83 // #endif
84 //     break;
85 //   case QtWarningMsg:
86 // #ifdef _DEBUG_
87 //     printf( "Warning: %s\n", msg );
88 // #endif
89 //     break;
90 //   case QtFatalMsg:
91 // #ifdef _DEBUG_
92 //     printf( "Fatal: %s\n", msg );
93 // #endif
94 //     break;
95 //   default:
96 //     break;
97 //   }
98 // }
99
100 /* XPM */
101 static const char* pixmap_not_found_xpm[] = {
102 "16 16 3 1",
103 "       c None",
104 ".      c #000000",
105 "+      c #A80000",
106 "                ",
107 "                ",
108 "    .     .     ",
109 "   .+.   .+.    ",
110 "  .+++. .+++.   ",
111 "   .+++.+++.    ",
112 "    .+++++.     ",
113 "     .+++.      ",
114 "    .+++++.     ",
115 "   .+++.+++.    ",
116 "  .+++. .+++.   ",
117 "   .+.   .+.    ",
118 "    .     .     ",
119 "                ",
120 "                ",
121 "                "};
122
123 class SUITApp_Session: public SUIT_Session
124 {
125 public:
126   SUITApp_Session( bool theIniFormat ) : SUIT_Session(), myIniFormat ( theIniFormat ) {}
127   virtual ~SUITApp_Session() {}
128
129   virtual SUIT_ResourceMgr* createResourceMgr( const QString& appName ) const
130   {
131     SUIT_ResourceMgr* resMgr = 0;
132     if ( myIniFormat )
133     {
134       resMgr = new SUIT_ResourceMgr( appName, QString( "%1Config" ) );
135       resMgr->setCurrentFormat( "ini" );
136     }
137     else
138     {
139       resMgr = new SUIT_ResourceMgr( appName, QString( "%1Config" ) );
140       resMgr->setVersion( salomeVersion() );
141       resMgr->setCurrentFormat( "xml" );
142     }
143
144     if ( resMgr )
145     {
146       static QPixmap defaultPixmap( pixmap_not_found_xpm );
147       resMgr->setDefaultPixmap( defaultPixmap );
148       resMgr->setOption( "translators", QString( "%P_msg_%L.qm|%P_icons.qm|%P_images.qm" ) );
149     }
150     return resMgr;
151   }
152
153 private:
154   bool  myIniFormat;
155 };
156
157 int main( int argc, char* argv[] )
158 {
159   //#ifdef SUIT_ENABLE_PYTHON
160   //  // First of all initialize Python, as in complex multi-component applications
161   //  // someone else might initialize it some way unsuitable for light SALOME!
162   //  Py_SetProgramName( argv[0] );
163   //  Py_Initialize(); // Initialize the interpreter
164   //  PySys_SetArgv( argc,  argv );
165   //  PyEval_InitThreads(); // Create (and acquire) the interpreter lock
166   //  PyEval_ReleaseLock(); // Let the others use Python API until we need it again
167   //#endif
168
169   //qInstallMsgHandler( MessageOutput );
170
171   QStringList argList;
172   bool noExceptHandling = false;
173   bool iniFormat        = false;
174   bool noSplash         = false;
175   bool useLicense       = false;
176   for ( int i = 1; i < argc; i++ )
177   {
178     if ( !strcmp( argv[i], "--noexcepthandling" ) )
179       noExceptHandling = true;
180     else if ( !strcmp( argv[i], "--format=ini") )
181       iniFormat = true;
182     else if ( !strcmp( argv[i], "--nosplash") )
183       noSplash = true;
184     else if ( !strcmp( argv[i], "--uselicense" ) )
185       useLicense = true;
186     else
187       argList.append( QString( argv[i] ) );
188   }
189
190   // add $QTDIR/plugins to the pluins search path for image plugins
191   QString qtdir( ::getenv( "QTDIR" ) );
192   if ( !qtdir.isEmpty() )
193     QApplication::addLibraryPath( QDir( qtdir ).absoluteFilePath( "plugins" ) );
194
195   //Set a "native" graphic system in case if application runs on the remote host
196   QString remote(::getenv("REMOTEHOST"));
197   QString client(::getenv("SSH_CLIENT"));
198   if(remote.length() > 0 || client.length() > 0 ) {
199     QApplication::setGraphicsSystem(QLatin1String("native"));
200   }
201   
202   SUITApp_Application app( argc, argv );
203   QString cfgAppName = getAppName( argList.isEmpty() ? QString() : argList.first() );
204   // hard-coding for LightApp :( no other way to this for the moment
205   if ( cfgAppName == "LightApp" ) {
206     app.setOrganizationName( "salome" );
207     app.setApplicationName( "salome" );
208     app.setApplicationVersion( salomeVersion() );
209   }
210
211   int result = -1;
212
213   if ( useLicense ) {
214     QString env;
215
216 #ifdef WIN32
217     DWORD aLen=1024;
218     char aStr[1024];
219     HANDLE aToken=0;
220     HANDLE hProcess = GetCurrentProcess();
221     OpenProcessToken(hProcess,TOKEN_QUERY,&aToken);
222     if( GetUserProfileDirectory( aToken, aStr, &aLen ) )
223       env = aStr;
224
225 #else
226     if ( ::getenv( "HOME" ) )
227       env = ::getenv( "HOME" );
228 #endif
229  
230     QFile file( env + "/ReadLicense.log" ); // Read the text from a file    
231     if( !file.exists() ) {
232       SUIT_LicenseDlg aLicense;
233       if ( aLicense.exec() != QDialog::Accepted ) 
234         return result;
235     }
236   }
237
238   if ( !argList.isEmpty() )
239   {
240     SUITApp_Session* aSession = new SUITApp_Session( iniFormat );
241     QtxSplash* splash = 0;
242     SUIT_ResourceMgr* resMgr = aSession->createResourceMgr( argList.first() );
243     if ( !noSplash ) 
244     {
245       if ( resMgr )
246       {
247         resMgr->loadLanguage();
248
249         splash = QtxSplash::splash( QPixmap() );
250         splash->readSettings( resMgr );
251         if ( splash->pixmap().isNull() ) {
252           delete splash;
253           splash = 0;
254         }
255         else {
256           QString appName    = QObject::tr( "APP_NAME" ).trimmed();
257           QString appVersion = QObject::tr( "APP_VERSION" ).trimmed();
258           if ( appVersion == "APP_VERSION" )
259           {
260             if ( appName == "APP_NAME" || appName.toLower() == "salome" )
261               appVersion = salomeVersion();
262             else
263               appVersion = "";
264           }
265           splash->setOption( "%A", appName );
266           splash->setOption( "%V", QObject::tr( "ABOUT_VERSION" ).arg( appVersion ) );
267           splash->setOption( "%L", QObject::tr( "ABOUT_LICENSE" ) );
268           splash->setOption( "%C", QObject::tr( "ABOUT_COPYRIGHT" ) );
269           splash->show();
270           QApplication::instance()->processEvents();
271         }
272       }
273     }
274
275 #ifdef SUIT_ENABLE_PYTHON
276     //...Initialize python 
277     int   _argc   = 1;
278     char* _argv[] = {(char*)""};
279     SUIT_PYTHON::init_python(_argc,_argv);
280     PyEval_ReleaseLock();
281 #endif
282
283     SUIT_Application* theApp = aSession->startApplication( argList.first() );
284     if ( theApp )
285     {
286       Style_Salome::initialize( theApp->resourceMgr() );
287       if ( theApp->resourceMgr()->booleanValue( "Style", "use_salome_style", true ) )
288         Style_Salome::apply();
289
290       if ( !noExceptHandling )
291         app.setHandler( aSession->handler() );
292
293       if ( splash )
294         splash->finish( theApp->desktop() );
295
296       result = app.exec();
297     }
298     delete aSession;
299   }
300
301   return result;
302 }