2 // File : QAD_ResourceMgr.cxx
3 // Created : UI team, 22.10.00
4 // Descr : ResourceMgr QAD-based application
8 // Copyright : Open CASCADE
12 \class QAD_ResourceMgr QAD_ResourceMgr.h
13 \brief ResourceMgr QAD-based application.
17 #include "QAD_Tools.h"
18 #include "QAD_MessageBox.h"
19 #include "QAD_ResourceMgr.h"
21 #include "utilities.h"
25 #include <qtranslator.h>
26 #include <qapplication.h>
27 #include <qfileinfo.h>
29 #include <Standard.hxx>
31 /* configuration file */
32 static const char* CONFIG_FILE = "config";
35 static const char* RES_DIR = "res";
36 static const char* RES_DOCS = "docs";
37 static const char* RES_PIXMAPS = "icons";
38 static const char* RES_STRINGS = "strings";
39 static const char* RES_LANGUAGE = "language";
41 static const char* SEPARATOR = ":";
46 QAD_ResourceMgr::QAD_ResourceMgr() :
49 myRes.setAutoDelete( true );
55 QAD_ResourceMgr::~QAD_ResourceMgr()
61 Removes icons and messages from 'prefix'_msg_'lang'
62 and 'prefix'_icons' files. Returns 'true' if OK.
63 Each application which has its own resources must
64 have a unique 'prefix' ( prefix "QAD" is reserved )
66 bool QAD_ResourceMgr::removeResources( const char* prefix )
68 return myRes.remove(prefix);
72 Loads icons and messages from 'prefix'_msg_'lang'
73 and 'prefix'_icons' files. Returns 'true' if OK.
74 Each application which has its own resources must
75 have a unique 'prefix' ( prefix "QAD" is reserved )
77 bool QAD_ResourceMgr::loadResources( const char* prefix, QString &msg )
79 bool allLoaded = true;
80 if ( !myRes[ prefix ] ) {
83 /* We read the settings once and keep them.
84 The resources are loaded consequently from the end of directory list
85 which ( see collectDirs() method description ). This allows to override
86 resources when it is necessary.
89 ResourceSettings* settings = new ResourceSettings();
90 StringDict& conf = settings->config();
91 myRes.insert( prefix, settings );
93 // settings->config().insert( RES_DIR, new QString( resDir ) );
95 /* we search language definition : we read it in config file
96 If not found, we use default : English
98 conf.insert( RES_LANGUAGE, new QString( "en" ) );
100 /* Read configuration file */
102 /* WE MUST HAVE ONE CONFIGURATION FILE FOR ALL SALOME !!!
103 I DON'T KNOW WHERE READ IT AND SAVE ITS CONTENTS FOR ALL GUI
104 ALL GUI HAS SAME LANGUAGE AND HAVE DEFAULT (en) IF SPECIFIED
107 QString resDirs = collectDirs( prefix );
108 conf.insert( RES_DIR, new QString( resDirs ) );
109 QString fileConfig = path( CONFIG_FILE, prefix, 0 ) ;
110 //MESSAGE("QAD_ResourceMgr::loadresources : config : "<<fileConfig);
111 if ( !fileConfig.isEmpty() ) {
112 QFile configFile( fileConfig );
113 if ( !configFile.exists() || !configFile.open( IO_ReadOnly ) ) {
115 warnMsg.sprintf( "Cannot open configuration file: %s\nDefault settings will be used.",
116 configFile.name().latin1() );
118 // removeResources( prefix );
122 /* read 'config' file */
123 const int MAX_LINE = 512;
124 while ( !configFile.atEnd() ) {
126 if ( configFile.readLine( line, MAX_LINE ) > 0 ) {
128 if ( ( index = line.find( "=" ) ) > 0 ) {
129 QString key = line.left(index).stripWhiteSpace();
130 QString value = line.mid( index+1 ).stripWhiteSpace();
131 conf.replace( key, new QString( value ) );
139 /* Load the resources */
140 QString stFile( prefix );
141 stFile = stFile + "_msg_" + *( conf[ RES_LANGUAGE ] ) + ".qm" ;
142 QString imagesFile( prefix );
143 imagesFile = imagesFile + "_" + RES_PIXMAPS + ".qm";
144 if ( conf[ RES_STRINGS ] && !conf[ RES_STRINGS ]->isEmpty() )
145 stFile = QAD_Tools::addSlash( *conf[ RES_STRINGS ] ) + stFile;
146 if ( conf[ RES_PIXMAPS ] && !conf[ RES_PIXMAPS ]->isEmpty() )
147 imagesFile = QAD_Tools::addSlash( *conf[ RES_PIXMAPS ] ) + imagesFile;
149 bool bLoadString = false;
150 bool bLoadImages = false;
152 QStringList dirList = QStringList::split( SEPARATOR, resDirs, false ); // skip empty entries
153 for ( int i = dirList.count()-1; i >= 0; i-- ) {
154 QString dir = dirList[ i ];
155 QString fileString = QAD_Tools::addSlash( dir ) + stFile;
156 QString fileImage = QAD_Tools::addSlash( dir ) + imagesFile;
158 if ( settings->load( fileString ) ) {
161 if ( settings->load( fileImage ) ) {
166 if ( !bLoadString ) {
168 warnMsg.sprintf( "String resources for module %s not found.\n"
169 "Please, check your settings.",
172 // removeResources( prefix );
175 if ( !bLoadImages ) {
177 warnMsg.sprintf( "Icons resources for module %s not found.\n"
178 "Please, check your settings.",
181 // removeResources( prefix );
184 allLoaded = bLoadString && bLoadImages;
190 Returns language setting for the module 'prefix' ( e.g. "en" )
192 QString QAD_ResourceMgr::language( const char* prefix ) const
195 ResourceSettings* rs = myRes[ prefix ];
198 StringDict& conf = rs->config();
199 ret = *(conf[RES_LANGUAGE]);
205 Returns list of directories where resources can be located
206 See collectDirs() method description for more detail
208 QString QAD_ResourceMgr::resources( const char* prefix ) const
211 ResourceSettings* rs = myRes[ prefix ];
214 StringDict& conf = rs->config();
215 ret = *(conf[RES_DIR]);
221 Collects list of directories, separated by ';' where resources for module 'prefix'
223 The order is following :
224 - CSF_<prefix>Resources env.var directory ( or directory list )
225 - CSF_ResourcesDefaults env.var directory ( or directory list )
226 - ${HOME}/.salome/resources directory
227 - ${SALOME_SITE_DIR}/share/salome/resources directory
228 - ${SALOME_ROOT_DIR}/share/salome/resources directory
230 QString QAD_ResourceMgr::collectDirs( const QString& prefix ) const
233 QCString envVar( "CSF_" );
237 if ( !prefix.isEmpty() ) {
238 envVar = prefix.latin1() + QCString( "_ROOT_DIR" );
239 cenv = getenv( ( const char* ) envVar );
241 dir.sprintf( "%s", cenv );
242 if ( !dir.isEmpty() ) {
243 dir = QAD_Tools::addSlash(dir) ;
244 dir = dir + "share" ;
245 dir = QAD_Tools::addSlash(dir) ;
246 dir = dir + "salome" ;
247 dir = QAD_Tools::addSlash(dir) ;
248 dir = dir + "resources" ;
249 dir = QAD_Tools::addSlash(dir) ;
250 dirList.append( dirList.isEmpty() ? dir : ( QString( SEPARATOR ) + dir ) );
255 // Try CSF_<prefix>Resources env.var directory ( or directory list )
256 if ( !prefix.isEmpty() ) {
257 envVar = QCString( "CSF_" ) + prefix.latin1() + QCString( "Resources" );
258 cenv = getenv( ( const char* ) envVar );
260 dir.sprintf( "%s", cenv );
261 if ( !dir.isEmpty() )
262 dirList.append( dirList.isEmpty() ? dir : ( QString( SEPARATOR ) + dir ) );
265 // Try CSF_ResourcesDefaults env.var directory ( or directory list )
266 cenv = getenv( "CSF_ResourcesDefaults" );
268 dir.sprintf( "%s", cenv );
269 if ( !dir.isEmpty() )
270 dirList.append( dirList.isEmpty() ? dir : ( QString( SEPARATOR ) + dir ) );
272 // Try ${HOME}/.salome/resources directory
273 cenv = getenv( "HOME" );
275 dir.sprintf( "%s", cenv );
276 if ( !dir.isEmpty() ) {
277 dir = QAD_Tools::addSlash(dir) ;
278 dir = dir + ".salome" ;
279 dir = QAD_Tools::addSlash(dir) ;
280 dir = dir + "resources" ;
281 dir = QAD_Tools::addSlash(dir) ;
282 dirList.append( dirList.isEmpty() ? dir : ( QString( SEPARATOR ) + dir ) );
285 // Try ${SALOME_SITE_DIR}/share/salome/resources directory
286 cenv = getenv( "SALOME_SITE_DIR" );
288 dir.sprintf( "%s", cenv );
289 if ( !dir.isEmpty() ) {
290 dir = QAD_Tools::addSlash(dir) ;
291 dir = dir + "share" ;
292 dir = QAD_Tools::addSlash(dir) ;
293 dir = dir + "salome" ;
294 dir = QAD_Tools::addSlash(dir) ;
295 dir = dir + "resources" ;
296 dir = QAD_Tools::addSlash(dir) ;
297 dirList.append( dirList.isEmpty() ? dir : ( QString( SEPARATOR ) + dir ) );
300 // Try ${SALOME_ROOT_DIR}/share/salome/resources directory
301 cenv = getenv( "SALOME_ROOT_DIR" );
303 dir.sprintf( "%s", cenv );
304 if ( !dir.isEmpty() ) {
305 dir = QAD_Tools::addSlash(dir) ;
306 dir = dir + "share" ;
307 dir = QAD_Tools::addSlash(dir) ;
308 dir = dir + "salome" ;
309 dir = QAD_Tools::addSlash(dir) ;
310 dir = dir + "resources" ;
311 dir = QAD_Tools::addSlash(dir) ;
312 dirList.append( dirList.isEmpty() ? dir : ( QString( SEPARATOR ) + dir ) );
316 // Try ${KERNEL_ROOT_DIR}/share/salome/resources directory
317 cenv = getenv( "KERNEL_ROOT_DIR" );
319 dir.sprintf( "%s", cenv );
320 if ( !dir.isEmpty() ) {
321 dir = QAD_Tools::addSlash(dir) ;
322 dir = dir + "share" ;
323 dir = QAD_Tools::addSlash(dir) ;
324 dir = dir + "salome" ;
325 dir = QAD_Tools::addSlash(dir) ;
326 dir = dir + "resources" ;
327 dir = QAD_Tools::addSlash(dir) ;
328 dirList.append( dirList.isEmpty() ? dir : ( QString( SEPARATOR ) + dir ) );
331 //MESSAGE("QAD_ResourceMgr::collectDirs : "<<dirList.latin1()) ;
336 Returns a directory where 'filename' is located (filename is relative
337 of the application identified by 'prefix' or empty string if file not found
338 Search is processed in different location : see collectDirs() method description
340 QString QAD_ResourceMgr::getFile( const QString& filename, const char* prefix ) const
342 QFileInfo fi( path( filename, prefix, 0 ) );
343 if ( fi.isFile() && fi.exists() )
349 Returns a directory where 'filename' is located (filename is relative
350 of the application identified by 'prefix' or empty string if file not found
351 Search is processed in different location : see collectDirs() method description
352 The difference from above method that this function is used when resources
353 is not yet actually loaded by application.
355 QString QAD_ResourceMgr::findFile( const QString& filename, const char* prefix ) const
357 QString resDirs = collectDirs( prefix );
358 QStringList dirList = QStringList::split( SEPARATOR, resDirs, false ); // skip empty entries
359 for ( int i = 0; i < dirList.count(); i++ ) {
360 QString dir = dirList[ i ];
361 QFileInfo fi( QAD_Tools::addSlash( dir ) + filename );
362 if ( fi.isFile() && fi.exists() )
369 Returns a path to file 'filename' (filename is relative
370 of the application identified by 'prefix' and subdirectory identified by 'key'
371 or empty string if file not found.
372 Search is processed in different location : see collectDirs() method description
374 Returns a directory 'key' resource of the application
375 identified by 'prefix'
377 QString QAD_ResourceMgr::path( const QString& filename, const char* prefix, const char* key ) const
381 ResourceSettings* rs = myRes[ prefix ];
383 StringDict& conf = rs->config();
384 QString resDirs = QString( *( conf[ RES_DIR ] ) );
385 if ( !resDirs.isEmpty() ) {
386 //MESSAGE("QAD_ResourceMgr::resDirs : <"<<resDirs<<">") ;
387 QStringList dirList = QStringList::split( SEPARATOR, resDirs, false ); // skip empty entries
388 for ( int i = 0; i < dirList.count(); i++ ) {
389 QString dir = dirList[ i ];
390 dir = QAD_Tools::addSlash( dir );
392 QString* where = conf[ key ];
394 dir = dir + QAD_Tools::addSlash( *where );
396 dir = dir + filename;
397 QFileInfo fileInfo( dir );
398 if ( fileInfo.isFile() && fileInfo.exists() ) {
399 filePath = fileInfo.filePath();
405 //MESSAGE("QAD_ResourceMgr::path : <"<<filename.latin1()<<"> : "<<filePath.latin1()) ;
410 Loads a pixmap from 'resname' resources
411 and indetified by 'id'
413 QPixmap QAD_ResourceMgr::loadPixmap( const char* resname,
414 const QString& id ) const
416 return QPixmap( path( id, resname, RES_PIXMAPS ) );
420 Loads a doc page from 'resname' resources
421 and indetified by 'id'
423 bool QAD_ResourceMgr::loadDoc( const char* resname,
424 const QString& id ) const
426 QString docPath = path( id, resname, RES_DOCS );
430 /************************************************************************
432 ** Class QAD_ResourceMgr::ResourceSettings ( internal )
434 *************************************************************************/
437 Loads a resource 'file'.
438 Returns 'false' if 'file' can't be loaded( not found etc. ),
439 'true' if loaded or reloaded OK.
441 bool QAD_ResourceMgr::ResourceSettings::load( const QString& file )
443 #if QT_VERSION >= 0x030000 // VSR: workaround - crash on qt3.0.5 ==========
444 static const int magic_length = 16; // length of *.qm file header (qtranslator.cpp)
445 static const uchar magic[magic_length] = { // magic number for the file
446 0x3c, 0xb8, 0x64, 0x18, 0xca, 0xef, 0x9c, 0x95,
447 0xcd, 0x21, 0x1c, 0xbf, 0x60, 0xa1, 0xbd, 0xdd };
449 if ( !f.exists() || f.size() < magic_length)
451 char buf[magic_length];
452 if ( !f.open(IO_ReadOnly) )
454 bool bOk = ( f.readBlock(buf, magic_length) == magic_length );
458 if ( memcmp( (const void *)buf, magic, magic_length ) )
460 if ( f.size() == magic_length)
462 #endif // VSR =============================================================
463 QTranslator* strTbl = new QTranslator( 0 );
465 if ( !strTbl->load( file, "" ) ) {
473 QAD_ASSERT_DEBUG_ONLY( qApp );
474 qApp->installTranslator( strTbl );