1 // SALOME SALOMEGUI : implementation of desktop and GUI kernel
3 // Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
20 // See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
24 // File : QAD_ResourceMgr.cxx
31 \class QAD_ResourceMgr QAD_ResourceMgr.h
32 \brief ResourceMgr QAD-based application.
36 #include "QAD_Tools.h"
37 #include "QAD_MessageBox.h"
38 #include "QAD_ResourceMgr.h"
40 #include "utilities.h"
44 #include <qtranslator.h>
45 #include <qapplication.h>
46 #include <qfileinfo.h>
48 #include <Standard.hxx>
50 /* configuration file */
51 static const char* CONFIG_FILE = "config";
54 static const char* RES_DIR = "res";
55 static const char* RES_DOCS = "docs";
56 static const char* RES_PIXMAPS = "icons";
57 static const char* RES_STRINGS = "strings";
58 static const char* RES_LANGUAGE = "language";
60 static const char* SEPARATOR = ":";
65 QAD_ResourceMgr::QAD_ResourceMgr() :
68 myRes.setAutoDelete( true );
74 QAD_ResourceMgr::~QAD_ResourceMgr()
80 Removes icons and messages from 'prefix'_msg_'lang'
81 and 'prefix'_icons' files. Returns 'true' if OK.
82 Each application which has its own resources must
83 have a unique 'prefix' ( prefix "QAD" is reserved )
85 bool QAD_ResourceMgr::removeResources( const char* prefix )
87 return myRes.remove(prefix);
91 Loads icons and messages from 'prefix'_msg_'lang'
92 and 'prefix'_icons' files. Returns 'true' if OK.
93 Each application which has its own resources must
94 have a unique 'prefix' ( prefix "QAD" is reserved )
96 bool QAD_ResourceMgr::loadResources( const char* prefix, QString &msg )
98 bool allLoaded = true;
99 if ( !myRes[ prefix ] ) {
102 /* We read the settings once and keep them.
103 The resources are loaded consequently from the end of directory list
104 which ( see collectDirs() method description ). This allows to override
105 resources when it is necessary.
108 ResourceSettings* settings = new ResourceSettings();
109 StringDict& conf = settings->config();
110 myRes.insert( prefix, settings );
112 // settings->config().insert( RES_DIR, new QString( resDir ) );
114 /* we search language definition : we read it in config file
115 If not found, we use default : English
117 conf.insert( RES_LANGUAGE, new QString( "en" ) );
119 /* Read configuration file */
121 /* WE MUST HAVE ONE CONFIGURATION FILE FOR ALL SALOME !!!
122 I DON'T KNOW WHERE READ IT AND SAVE ITS CONTENTS FOR ALL GUI
123 ALL GUI HAS SAME LANGUAGE AND HAVE DEFAULT (en) IF SPECIFIED
126 QString resDirs = collectDirs( prefix );
127 conf.insert( RES_DIR, new QString( resDirs ) );
128 QString fileConfig = path( CONFIG_FILE, prefix, 0 ) ;
129 //MESSAGE("QAD_ResourceMgr::loadresources : config : "<<fileConfig);
130 if ( !fileConfig.isEmpty() ) {
131 QFile configFile( fileConfig );
132 if ( !configFile.exists() || !configFile.open( IO_ReadOnly ) ) {
134 warnMsg.sprintf( "Cannot open configuration file: %s\nDefault settings will be used.",
135 configFile.name().latin1() );
137 // removeResources( prefix );
141 /* read 'config' file */
142 const int MAX_LINE = 512;
143 while ( !configFile.atEnd() ) {
145 if ( configFile.readLine( line, MAX_LINE ) > 0 ) {
147 if ( ( index = line.find( "=" ) ) > 0 ) {
148 QString key = line.left(index).stripWhiteSpace();
149 QString value = line.mid( index+1 ).stripWhiteSpace();
150 conf.replace( key, new QString( value ) );
158 /* Load the resources */
159 QString stFile( prefix );
160 stFile = stFile + "_msg_" + *( conf[ RES_LANGUAGE ] ) + ".qm" ;
161 QString imagesFile( prefix );
162 imagesFile = imagesFile + "_" + RES_PIXMAPS + ".qm";
163 if ( conf[ RES_STRINGS ] && !conf[ RES_STRINGS ]->isEmpty() )
164 stFile = QAD_Tools::addSlash( *conf[ RES_STRINGS ] ) + stFile;
165 if ( conf[ RES_PIXMAPS ] && !conf[ RES_PIXMAPS ]->isEmpty() )
166 imagesFile = QAD_Tools::addSlash( *conf[ RES_PIXMAPS ] ) + imagesFile;
168 bool bLoadString = false;
169 bool bLoadImages = false;
171 QStringList dirList = QStringList::split( SEPARATOR, resDirs, false ); // skip empty entries
172 for ( int i = dirList.count()-1; i >= 0; i-- ) {
173 QString dir = dirList[ i ];
174 QString fileString = QAD_Tools::addSlash( dir ) + stFile;
175 QString fileImage = QAD_Tools::addSlash( dir ) + imagesFile;
177 if ( settings->load( fileString ) ) {
180 if ( settings->load( fileImage ) ) {
185 if ( !bLoadString ) {
187 warnMsg.sprintf( "String resources for module %s not found.\n"
188 "Please, check your settings.",
191 // removeResources( prefix );
194 if ( !bLoadImages ) {
196 warnMsg.sprintf( "Icons resources for module %s not found.\n"
197 "Please, check your settings.",
200 // removeResources( prefix );
203 allLoaded = bLoadString && bLoadImages;
209 Returns language setting for the module 'prefix' ( e.g. "en" )
211 QString QAD_ResourceMgr::language( const char* prefix ) const
214 ResourceSettings* rs = myRes[ prefix ];
217 StringDict& conf = rs->config();
218 ret = *(conf[RES_LANGUAGE]);
224 Returns list of directories where resources can be located
225 See collectDirs() method description for more detail
227 QString QAD_ResourceMgr::resources( const char* prefix ) const
230 ResourceSettings* rs = myRes[ prefix ];
233 StringDict& conf = rs->config();
234 ret = *(conf[RES_DIR]);
240 Collects list of directories, separated by ';' where resources for module 'prefix'
242 The order is following :
243 - CSF_<prefix>Resources env.var directory ( or directory list )
244 - CSF_ResourcesDefaults env.var directory ( or directory list )
245 - ${HOME}/.salome/resources directory
246 - ${SALOME_SITE_DIR}/share/salome/resources directory
247 - ${SALOME_ROOT_DIR}/share/salome/resources directory
249 QString QAD_ResourceMgr::collectDirs( const QString& prefix ) const
252 QCString envVar( "CSF_" );
256 // Try CSF_<prefix>Resources env.var directory ( or directory list )
257 if ( !prefix.isEmpty() ) {
258 envVar = QCString( "CSF_" ) + prefix.latin1() + QCString( "Resources" );
259 cenv = getenv( ( const char* ) envVar );
261 dir.sprintf( "%s", cenv );
262 if ( !dir.isEmpty() )
263 dirList.append( dirList.isEmpty() ? dir : ( QString( SEPARATOR ) + dir ) );
266 // Try CSF_ResourcesDefaults env.var directory ( or directory list )
267 cenv = getenv( "CSF_ResourcesDefaults" );
269 dir.sprintf( "%s", cenv );
270 if ( !dir.isEmpty() )
271 dirList.append( dirList.isEmpty() ? dir : ( QString( SEPARATOR ) + dir ) );
273 // Try ${HOME}/.salome/resources directory
274 cenv = getenv( "HOME" );
276 dir.sprintf( "%s", cenv );
277 if ( !dir.isEmpty() ) {
278 dir = QAD_Tools::addSlash(dir) ;
279 dir = dir + ".salome" ;
280 dir = QAD_Tools::addSlash(dir) ;
281 dir = dir + "resources" ;
282 dir = QAD_Tools::addSlash(dir) ;
283 dirList.append( dirList.isEmpty() ? dir : ( QString( SEPARATOR ) + dir ) );
286 // Try ${SALOME_SITE_DIR}/share/salome/resources directory
287 cenv = getenv( "SALOME_SITE_DIR" );
289 dir.sprintf( "%s", cenv );
290 if ( !dir.isEmpty() ) {
291 dir = QAD_Tools::addSlash(dir) ;
292 dir = dir + "share" ;
293 dir = QAD_Tools::addSlash(dir) ;
294 dir = dir + "salome" ;
295 dir = QAD_Tools::addSlash(dir) ;
296 dir = dir + "resources" ;
297 dir = QAD_Tools::addSlash(dir) ;
298 dirList.append( dirList.isEmpty() ? dir : ( QString( SEPARATOR ) + dir ) );
301 // Try ${SALOME_ROOT_DIR}/share/salome/resources directory
302 cenv = getenv( "SALOME_ROOT_DIR" );
304 dir.sprintf( "%s", cenv );
305 if ( !dir.isEmpty() ) {
306 dir = QAD_Tools::addSlash(dir) ;
307 dir = dir + "share" ;
308 dir = QAD_Tools::addSlash(dir) ;
309 dir = dir + "salome" ;
310 dir = QAD_Tools::addSlash(dir) ;
311 dir = dir + "resources" ;
312 dir = QAD_Tools::addSlash(dir) ;
313 dirList.append( dirList.isEmpty() ? dir : ( QString( SEPARATOR ) + dir ) );
316 //MESSAGE("QAD_ResourceMgr::collectDirs : "<<dirList.latin1()) ;
321 Returns a directory where 'filename' is located (filename is relative
322 of the application identified by 'prefix' or empty string if file not found
323 Search is processed in different location : see collectDirs() method description
325 QString QAD_ResourceMgr::getFile( const QString& filename, const char* prefix ) const
327 QFileInfo fi( path( filename, prefix, 0 ) );
328 if ( fi.isFile() && fi.exists() )
334 Returns a directory where 'filename' is located (filename is relative
335 of the application identified by 'prefix' or empty string if file not found
336 Search is processed in different location : see collectDirs() method description
337 The difference from above method that this function is used when resources
338 is not yet actually loaded by application.
340 QString QAD_ResourceMgr::findFile( const QString& filename, const char* prefix ) const
342 QString resDirs = collectDirs( prefix );
343 QStringList dirList = QStringList::split( SEPARATOR, resDirs, false ); // skip empty entries
344 for ( int i = 0; i < dirList.count(); i++ ) {
345 QString dir = dirList[ i ];
346 QFileInfo fi( QAD_Tools::addSlash( dir ) + filename );
347 if ( fi.isFile() && fi.exists() )
354 Returns a path to file 'filename' (filename is relative
355 of the application identified by 'prefix' and subdirectory identified by 'key'
356 or empty string if file not found.
357 Search is processed in different location : see collectDirs() method description
359 Returns a directory 'key' resource of the application
360 identified by 'prefix'
362 QString QAD_ResourceMgr::path( const QString& filename, const char* prefix, const char* key ) const
366 ResourceSettings* rs = myRes[ prefix ];
368 StringDict& conf = rs->config();
369 QString resDirs = QString( *( conf[ RES_DIR ] ) );
370 if ( !resDirs.isEmpty() ) {
371 //MESSAGE("QAD_ResourceMgr::resDirs : <"<<resDirs<<">") ;
372 QStringList dirList = QStringList::split( SEPARATOR, resDirs, false ); // skip empty entries
373 for ( int i = 0; i < dirList.count(); i++ ) {
374 QString dir = dirList[ i ];
375 dir = QAD_Tools::addSlash( dir );
377 QString* where = conf[ key ];
379 dir = dir + QAD_Tools::addSlash( *where );
381 dir = dir + filename;
382 QFileInfo fileInfo( dir );
383 if ( fileInfo.isFile() && fileInfo.exists() ) {
384 filePath = fileInfo.filePath();
390 //MESSAGE("QAD_ResourceMgr::path : <"<<filename.latin1()<<"> : "<<filePath.latin1()) ;
395 Loads a pixmap from 'resname' resources
396 and indetified by 'id'
398 QPixmap QAD_ResourceMgr::loadPixmap( const char* resname,
399 const QString& id ) const
401 return QPixmap( path( id, resname, RES_PIXMAPS ) );
405 Loads a doc page from 'resname' resources
406 and indetified by 'id'
408 bool QAD_ResourceMgr::loadDoc( const char* resname,
409 const QString& id ) const
411 QString docPath = path( id, resname, RES_DOCS );
415 /************************************************************************
417 ** Class QAD_ResourceMgr::ResourceSettings ( internal )
419 *************************************************************************/
422 Loads a resource 'file'.
423 Returns 'false' if 'file' can't be loaded( not found etc. ),
424 'true' if loaded or reloaded OK.
426 bool QAD_ResourceMgr::ResourceSettings::load( const QString& file )
428 #if QT_VERSION >= 0x030000 // VSR: workaround - crash on qt3.0.5 ==========
429 static const int magic_length = 16; // length of *.qm file header (qtranslator.cpp)
430 static const uchar magic[magic_length] = { // magic number for the file
431 0x3c, 0xb8, 0x64, 0x18, 0xca, 0xef, 0x9c, 0x95,
432 0xcd, 0x21, 0x1c, 0xbf, 0x60, 0xa1, 0xbd, 0xdd };
434 if ( !f.exists() || f.size() < magic_length)
436 char buf[magic_length];
437 if ( !f.open(IO_ReadOnly) )
439 bool bOk = ( f.readBlock(buf, magic_length) == magic_length );
443 if ( memcmp( (const void *)buf, magic, magic_length ) )
445 if ( f.size() == magic_length)
447 #endif // VSR =============================================================
448 QTranslator* strTbl = new QTranslator( 0 );
450 if ( !strTbl->load( file, "" ) ) {
458 QAD_ASSERT_DEBUG_ONLY( qApp );
459 qApp->installTranslator( strTbl );