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";
59 static const char* RES_FILES = "resources";
61 static const char* SEPARATOR = ":";
66 QAD_ResourceMgr::QAD_ResourceMgr() :
69 myRes.setAutoDelete( true );
75 QAD_ResourceMgr::~QAD_ResourceMgr()
81 Removes icons and messages from 'prefix'_msg_'lang'
82 and 'prefix'_icons' files. Returns 'true' if OK.
83 Each application which has its own resources must
84 have a unique 'prefix' ( prefix "QAD" is reserved )
86 bool QAD_ResourceMgr::removeResources( const char* prefix )
88 return myRes.remove(prefix);
92 Loads icons and messages from 'prefix'_msg_'lang'
93 and 'prefix'_icons' files. Returns 'true' if OK.
94 Each application which has its own resources must
95 have a unique 'prefix' ( prefix "QAD" is reserved )
97 bool QAD_ResourceMgr::loadResources( const char* prefix, QString &msg )
99 bool allLoaded = true;
100 if ( !myRes[ prefix ] ) {
103 /* We read the settings once and keep them.
104 The resources are loaded consequently from the end of directory list
105 which ( see collectDirs() method description ). This allows to override
106 resources when it is necessary.
109 ResourceSettings* settings = new ResourceSettings();
110 StringDict& conf = settings->config();
111 myRes.insert( prefix, settings );
113 // settings->config().insert( RES_DIR, new QString( resDir ) );
115 /* we search language definition : we read it in config file
116 If not found, we use default : English
118 conf.insert( RES_LANGUAGE, new QString( "en" ) );
120 /* Read configuration file */
122 /* WE MUST HAVE ONE CONFIGURATION FILE FOR ALL SALOME !!!
123 I DON'T KNOW WHERE READ IT AND SAVE ITS CONTENTS FOR ALL GUI
124 ALL GUI HAS SAME LANGUAGE AND HAVE DEFAULT (en) IF SPECIFIED
127 QString resDirs = collectDirs( prefix );
128 conf.insert( RES_DIR, new QString( resDirs ) );
129 QString fileConfig = QString( prefix ) + QString( "." ) + QString( CONFIG_FILE );
130 fileConfig = path( fileConfig, prefix, 0 ) ;
131 //MESSAGE("QAD_ResourceMgr::loadresources : config : "<<fileConfig);
132 if ( fileConfig.isEmpty() )
133 fileConfig = path( CONFIG_FILE, prefix, 0 ) ;
134 if ( !fileConfig.isEmpty() ) {
135 QFile configFile( fileConfig );
136 if ( !configFile.exists() || !configFile.open( IO_ReadOnly ) ) {
138 warnMsg.sprintf( "Cannot open configuration file: %s\nDefault settings will be used.",
139 configFile.name().latin1() );
141 // removeResources( prefix );
145 /* read 'config' file */
146 const int MAX_LINE = 512;
147 while ( !configFile.atEnd() ) {
149 if ( configFile.readLine( line, MAX_LINE ) > 0 ) {
151 if ( ( index = line.find( "=" ) ) > 0 ) {
152 QString key = line.left(index).stripWhiteSpace();
153 QString value = line.mid( index+1 ).stripWhiteSpace();
154 conf.replace( key, new QString( value ) );
162 /* Load the resources */
163 QString stFile( prefix );
164 stFile = stFile + "_msg_" + *( conf[ RES_LANGUAGE ] ) + ".qm" ;
165 QString imagesFile( prefix );
166 imagesFile = imagesFile + "_" + RES_PIXMAPS + ".qm";
167 if ( conf[ RES_STRINGS ] && !conf[ RES_STRINGS ]->isEmpty() )
168 stFile = QAD_Tools::addSlash( *conf[ RES_STRINGS ] ) + stFile;
169 if ( conf[ RES_PIXMAPS ] && !conf[ RES_PIXMAPS ]->isEmpty() )
170 imagesFile = QAD_Tools::addSlash( *conf[ RES_PIXMAPS ] ) + imagesFile;
172 bool bLoadString = false;
173 bool bLoadImages = false;
175 QStringList resFiles = conf[ RES_FILES ] ? QStringList::split( SEPARATOR, *( conf[ RES_FILES ] ), false ) : QStringList();
177 // first load main module's resources
178 QString fileString = path( stFile, prefix, 0 );
179 QString fileImage = path( imagesFile, prefix, 0 );
181 if ( !fileString.isEmpty() && settings->load( fileString ) ) {
184 if ( !fileImage.isEmpty() && settings->load( fileImage ) ) {
188 // then load additional module's resources if any are given
189 for ( int j = 0; j < resFiles.count(); j++ ) {
190 QString stFileAdd = resFiles[j] + "_msg_" + *( conf[ RES_LANGUAGE ] ) + ".qm" ;
191 QString imagesFileAdd = resFiles[j] + "_" + RES_PIXMAPS + ".qm";
192 if ( conf[ RES_STRINGS ] && !conf[ RES_STRINGS ]->isEmpty() )
193 stFileAdd = QAD_Tools::addSlash( *conf[ RES_STRINGS ] ) + stFileAdd;
194 if ( conf[ RES_PIXMAPS ] && !conf[ RES_PIXMAPS ]->isEmpty() )
195 imagesFileAdd = QAD_Tools::addSlash( *conf[ RES_PIXMAPS ] ) + imagesFileAdd;
197 QString fileStringAdd = path( stFileAdd, prefix, 0 );
198 QString fileImageAdd = path( imagesFileAdd, prefix, 0 );
200 if ( !fileStringAdd.isEmpty() )
201 settings->load( fileStringAdd );
202 if ( !fileImageAdd.isEmpty() )
203 settings->load( fileImageAdd );
206 if ( !bLoadString ) {
208 warnMsg.sprintf( "String resources for module %s not found.\n"
209 "Please, check your settings.",
212 // removeResources( prefix );
215 if ( !bLoadImages ) {
217 warnMsg.sprintf( "Icons resources for module %s not found.\n"
218 "Please, check your settings.",
221 // removeResources( prefix );
224 allLoaded = bLoadString && bLoadImages;
230 Returns language setting for the module 'prefix' ( e.g. "en" )
232 QString QAD_ResourceMgr::language( const char* prefix ) const
235 ResourceSettings* rs = myRes[ prefix ];
238 StringDict& conf = rs->config();
239 ret = *(conf[RES_LANGUAGE]);
245 Returns list of directories where resources can be located
246 See collectDirs() method description for more detail
248 QString QAD_ResourceMgr::resources( const char* prefix ) const
251 ResourceSettings* rs = myRes[ prefix ];
254 StringDict& conf = rs->config();
255 ret = *(conf[RES_DIR]);
261 Collects list of directories, separated by ';' where resources for module 'prefix'
263 The order is following :
264 - <prefix>_ROOT_DIR/share/salome/resources directory
265 - SALOME_<prefix>Resources env.var directory ( or directory list )
266 - ${HOME}/.salome/resources directory
267 - KERNEL_ROOT_DIR/share/salome/resources directory
269 QString QAD_ResourceMgr::collectDirs( const QString& prefix ) const
276 if ( !prefix.isEmpty() ) {
277 envVar = prefix.latin1() + QCString( "_ROOT_DIR" );
278 cenv = getenv( ( const char* ) envVar );
280 dir.sprintf( "%s", cenv );
281 if ( !dir.isEmpty() ) {
282 dir = QAD_Tools::addSlash(dir) ;
283 dir = dir + "share" ;
284 dir = QAD_Tools::addSlash(dir) ;
285 dir = dir + "salome" ;
286 dir = QAD_Tools::addSlash(dir) ;
287 dir = dir + "resources" ;
288 dir = QAD_Tools::addSlash(dir) ;
289 dirList.append( dirList.isEmpty() ? dir : ( QString( SEPARATOR ) + dir ) );
294 // Try SALOME_<prefix>Resources env.var directory ( or directory list )
295 if ( !prefix.isEmpty() ) {
296 envVar = QCString( "SALOME_" ) + prefix.latin1() + QCString( "Resources" );
297 cenv = getenv( ( const char* ) envVar );
299 dir.sprintf( "%s", cenv );
300 if ( !dir.isEmpty() )
301 dirList.append( dirList.isEmpty() ? dir : ( QString( SEPARATOR ) + dir ) );
304 // Try ${HOME}/.salome/resources directory
305 cenv = getenv( "HOME" );
307 dir.sprintf( "%s", cenv );
308 if ( !dir.isEmpty() ) {
309 dir = QAD_Tools::addSlash(dir) ;
310 dir = dir + ".salome" ;
311 dir = QAD_Tools::addSlash(dir) ;
312 dir = dir + "resources" ;
313 dir = QAD_Tools::addSlash(dir) ;
314 dirList.append( dirList.isEmpty() ? dir : ( QString( SEPARATOR ) + dir ) );
318 // Try ${KERNEL_ROOT_DIR}/share/salome/resources directory
319 cenv = getenv( "KERNEL_ROOT_DIR" );
321 dir.sprintf( "%s", cenv );
322 if ( !dir.isEmpty() ) {
323 dir = QAD_Tools::addSlash(dir) ;
324 dir = dir + "share" ;
325 dir = QAD_Tools::addSlash(dir) ;
326 dir = dir + "salome" ;
327 dir = QAD_Tools::addSlash(dir) ;
328 dir = dir + "resources" ;
329 dir = QAD_Tools::addSlash(dir) ;
330 dirList.append( dirList.isEmpty() ? dir : ( QString( SEPARATOR ) + dir ) );
333 //MESSAGE("QAD_ResourceMgr::collectDirs : "<<dirList.latin1()) ;
338 Returns a directory where 'filename' is located (filename is relative
339 of the application identified by 'prefix' or empty string if file not found
340 Search is processed in different location : see collectDirs() method description
342 QString QAD_ResourceMgr::getFile( const QString& filename, const char* prefix ) const
344 QFileInfo fi( path( filename, prefix, 0 ) );
345 if ( fi.isFile() && fi.exists() )
351 Returns a directory where 'filename' is located (filename is relative
352 of the application identified by 'prefix' or empty string if file not found
353 Search is processed in different location : see collectDirs() method description
354 The difference from above method that this function is used when resources
355 is not yet actually loaded by application.
357 QString QAD_ResourceMgr::findFile( const QString& filename, const char* prefix ) const
359 QString resDirs = collectDirs( prefix );
360 QStringList dirList = QStringList::split( SEPARATOR, resDirs, false ); // skip empty entries
361 for ( int i = 0; i < dirList.count(); i++ ) {
362 QString dir = dirList[ i ];
363 QFileInfo fi( QAD_Tools::addSlash( dir ) + filename );
364 if ( fi.isFile() && fi.exists() )
371 Returns a path to file 'filename' (filename is relative
372 of the application identified by 'prefix' and subdirectory identified by 'key'
373 or empty string if file not found.
374 Search is processed in different location : see collectDirs() method description
376 Returns a directory 'key' resource of the application
377 identified by 'prefix'
379 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 );
391 if ( key && conf[ key ] ) {
392 dir = dir + QString( *( conf[ key ] ) );
393 dir = QAD_Tools::addSlash( dir );
395 dir = dir + filename;
396 QFileInfo fileInfo( dir );
397 if ( fileInfo.isFile() && fileInfo.exists() ) {
398 return fileInfo.filePath();
403 //MESSAGE("QAD_ResourceMgr::path : <"<<filename.latin1()<<"> : "<<filePath.latin1()) ;
404 return QString::null;
408 Loads a pixmap from 'resname' resources
409 and indetified by 'id'
411 QPixmap QAD_ResourceMgr::loadPixmap( const char* resname,
412 const QString& id ) const
414 return QPixmap( path( id, resname, RES_PIXMAPS ) );
418 Loads a doc page from 'resname' resources
419 and indetified by 'id'
421 bool QAD_ResourceMgr::loadDoc( const char* resname,
422 const QString& id ) const
424 QString docPath = path( id, resname, RES_DOCS );
428 /************************************************************************
430 ** Class QAD_ResourceMgr::ResourceSettings ( internal )
432 *************************************************************************/
435 Loads a resource 'file'.
436 Returns 'false' if 'file' can't be loaded( not found etc. ),
437 'true' if loaded or reloaded OK.
439 bool QAD_ResourceMgr::ResourceSettings::load( const QString& file )
441 #if QT_VERSION >= 0x030000 // VSR: workaround - crash on qt3.0.5 ==========
442 static const int magic_length = 16; // length of *.qm file header (qtranslator.cpp)
443 static const uchar magic[magic_length] = { // magic number for the file
444 0x3c, 0xb8, 0x64, 0x18, 0xca, 0xef, 0x9c, 0x95,
445 0xcd, 0x21, 0x1c, 0xbf, 0x60, 0xa1, 0xbd, 0xdd };
447 if ( !f.exists() || f.size() < magic_length)
449 char buf[magic_length];
450 if ( !f.open(IO_ReadOnly) )
452 bool bOk = ( f.readBlock(buf, magic_length) == magic_length );
456 if ( memcmp( (const void *)buf, magic, magic_length ) )
458 if ( f.size() == magic_length)
460 #endif // VSR =============================================================
461 QTranslator* strTbl = new QTranslator( 0 );
463 if ( !strTbl->load( file, "" ) ) {
471 QAD_ASSERT_DEBUG_ONLY( qApp );
472 qApp->installTranslator( strTbl );