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 if ( !prefix.isEmpty() ) {
257 envVar = prefix.latin1() + QCString( "_ROOT_DIR" );
258 cenv = getenv( ( const char* ) envVar );
260 dir.sprintf( "%s", cenv );
261 if ( !dir.isEmpty() ) {
262 dir = QAD_Tools::addSlash(dir) ;
263 dir = dir + "share" ;
264 dir = QAD_Tools::addSlash(dir) ;
265 dir = dir + "salome" ;
266 dir = QAD_Tools::addSlash(dir) ;
267 dir = dir + "resources" ;
268 dir = QAD_Tools::addSlash(dir) ;
269 dirList.append( dirList.isEmpty() ? dir : ( QString( SEPARATOR ) + dir ) );
274 // Try CSF_<prefix>Resources env.var directory ( or directory list )
275 if ( !prefix.isEmpty() ) {
276 envVar = QCString( "CSF_" ) + prefix.latin1() + QCString( "Resources" );
277 cenv = getenv( ( const char* ) envVar );
279 dir.sprintf( "%s", cenv );
280 if ( !dir.isEmpty() )
281 dirList.append( dirList.isEmpty() ? dir : ( QString( SEPARATOR ) + dir ) );
284 // Try CSF_ResourcesDefaults env.var directory ( or directory list )
285 cenv = getenv( "CSF_ResourcesDefaults" );
287 dir.sprintf( "%s", cenv );
288 if ( !dir.isEmpty() )
289 dirList.append( dirList.isEmpty() ? dir : ( QString( SEPARATOR ) + dir ) );
291 // Try ${HOME}/.salome/resources directory
292 cenv = getenv( "HOME" );
294 dir.sprintf( "%s", cenv );
295 if ( !dir.isEmpty() ) {
296 dir = QAD_Tools::addSlash(dir) ;
297 dir = dir + ".salome" ;
298 dir = QAD_Tools::addSlash(dir) ;
299 dir = dir + "resources" ;
300 dir = QAD_Tools::addSlash(dir) ;
301 dirList.append( dirList.isEmpty() ? dir : ( QString( SEPARATOR ) + dir ) );
304 // Try ${SALOME_SITE_DIR}/share/salome/resources directory
305 cenv = getenv( "SALOME_SITE_DIR" );
307 dir.sprintf( "%s", cenv );
308 if ( !dir.isEmpty() ) {
309 dir = QAD_Tools::addSlash(dir) ;
310 dir = dir + "share" ;
311 dir = QAD_Tools::addSlash(dir) ;
312 dir = dir + "salome" ;
313 dir = QAD_Tools::addSlash(dir) ;
314 dir = dir + "resources" ;
315 dir = QAD_Tools::addSlash(dir) ;
316 dirList.append( dirList.isEmpty() ? dir : ( QString( SEPARATOR ) + dir ) );
319 // Try ${SALOME_ROOT_DIR}/share/salome/resources directory
320 cenv = getenv( "SALOME_ROOT_DIR" );
322 dir.sprintf( "%s", cenv );
323 if ( !dir.isEmpty() ) {
324 dir = QAD_Tools::addSlash(dir) ;
325 dir = dir + "share" ;
326 dir = QAD_Tools::addSlash(dir) ;
327 dir = dir + "salome" ;
328 dir = QAD_Tools::addSlash(dir) ;
329 dir = dir + "resources" ;
330 dir = QAD_Tools::addSlash(dir) ;
331 dirList.append( dirList.isEmpty() ? dir : ( QString( SEPARATOR ) + dir ) );
335 // Try ${KERNEL_ROOT_DIR}/share/salome/resources directory
336 cenv = getenv( "KERNEL_ROOT_DIR" );
338 dir.sprintf( "%s", cenv );
339 if ( !dir.isEmpty() ) {
340 dir = QAD_Tools::addSlash(dir) ;
341 dir = dir + "share" ;
342 dir = QAD_Tools::addSlash(dir) ;
343 dir = dir + "salome" ;
344 dir = QAD_Tools::addSlash(dir) ;
345 dir = dir + "resources" ;
346 dir = QAD_Tools::addSlash(dir) ;
347 dirList.append( dirList.isEmpty() ? dir : ( QString( SEPARATOR ) + dir ) );
350 //MESSAGE("QAD_ResourceMgr::collectDirs : "<<dirList.latin1()) ;
355 Returns a directory where 'filename' is located (filename is relative
356 of the application identified by 'prefix' or empty string if file not found
357 Search is processed in different location : see collectDirs() method description
359 QString QAD_ResourceMgr::getFile( const QString& filename, const char* prefix ) const
361 QFileInfo fi( path( filename, prefix, 0 ) );
362 if ( fi.isFile() && fi.exists() )
368 Returns a directory where 'filename' is located (filename is relative
369 of the application identified by 'prefix' or empty string if file not found
370 Search is processed in different location : see collectDirs() method description
371 The difference from above method that this function is used when resources
372 is not yet actually loaded by application.
374 QString QAD_ResourceMgr::findFile( const QString& filename, const char* prefix ) const
376 QString resDirs = collectDirs( prefix );
377 QStringList dirList = QStringList::split( SEPARATOR, resDirs, false ); // skip empty entries
378 for ( int i = 0; i < dirList.count(); i++ ) {
379 QString dir = dirList[ i ];
380 QFileInfo fi( QAD_Tools::addSlash( dir ) + filename );
381 if ( fi.isFile() && fi.exists() )
388 Returns a path to file 'filename' (filename is relative
389 of the application identified by 'prefix' and subdirectory identified by 'key'
390 or empty string if file not found.
391 Search is processed in different location : see collectDirs() method description
393 Returns a directory 'key' resource of the application
394 identified by 'prefix'
396 QString QAD_ResourceMgr::path( const QString& filename, const char* prefix, const char* key ) const
400 ResourceSettings* rs = myRes[ prefix ];
402 StringDict& conf = rs->config();
403 QString resDirs = QString( *( conf[ RES_DIR ] ) );
404 if ( !resDirs.isEmpty() ) {
405 //MESSAGE("QAD_ResourceMgr::resDirs : <"<<resDirs<<">") ;
406 QStringList dirList = QStringList::split( SEPARATOR, resDirs, false ); // skip empty entries
407 for ( int i = 0; i < dirList.count(); i++ ) {
408 QString dir = dirList[ i ];
409 dir = QAD_Tools::addSlash( dir );
411 QString* where = conf[ key ];
413 dir = dir + QAD_Tools::addSlash( *where );
415 dir = dir + filename;
416 QFileInfo fileInfo( dir );
417 if ( fileInfo.isFile() && fileInfo.exists() ) {
418 filePath = fileInfo.filePath();
424 //MESSAGE("QAD_ResourceMgr::path : <"<<filename.latin1()<<"> : "<<filePath.latin1()) ;
429 Loads a pixmap from 'resname' resources
430 and indetified by 'id'
432 QPixmap QAD_ResourceMgr::loadPixmap( const char* resname,
433 const QString& id ) const
435 return QPixmap( path( id, resname, RES_PIXMAPS ) );
439 Loads a doc page from 'resname' resources
440 and indetified by 'id'
442 bool QAD_ResourceMgr::loadDoc( const char* resname,
443 const QString& id ) const
445 QString docPath = path( id, resname, RES_DOCS );
449 /************************************************************************
451 ** Class QAD_ResourceMgr::ResourceSettings ( internal )
453 *************************************************************************/
456 Loads a resource 'file'.
457 Returns 'false' if 'file' can't be loaded( not found etc. ),
458 'true' if loaded or reloaded OK.
460 bool QAD_ResourceMgr::ResourceSettings::load( const QString& file )
462 #if QT_VERSION >= 0x030000 // VSR: workaround - crash on qt3.0.5 ==========
463 static const int magic_length = 16; // length of *.qm file header (qtranslator.cpp)
464 static const uchar magic[magic_length] = { // magic number for the file
465 0x3c, 0xb8, 0x64, 0x18, 0xca, 0xef, 0x9c, 0x95,
466 0xcd, 0x21, 0x1c, 0xbf, 0x60, 0xa1, 0xbd, 0xdd };
468 if ( !f.exists() || f.size() < magic_length)
470 char buf[magic_length];
471 if ( !f.open(IO_ReadOnly) )
473 bool bOk = ( f.readBlock(buf, magic_length) == magic_length );
477 if ( memcmp( (const void *)buf, magic, magic_length ) )
479 if ( f.size() == magic_length)
481 #endif // VSR =============================================================
482 QTranslator* strTbl = new QTranslator( 0 );
484 if ( !strTbl->load( file, "" ) ) {
492 QAD_ASSERT_DEBUG_ONLY( qApp );
493 qApp->installTranslator( strTbl );