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 - <prefix>_ROOT_DIR/share/salome/resources directory
244 - CSF_<prefix>Resources env.var directory ( or directory list )
245 - ${HOME}/.salome/resources directory
246 - KERNEL_ROOT_DIR/share/salome/resources directory
248 QString QAD_ResourceMgr::collectDirs( const QString& prefix ) const
251 QCString envVar( "CSF_" );
255 if ( !prefix.isEmpty() ) {
256 envVar = prefix.latin1() + QCString( "_ROOT_DIR" );
257 cenv = getenv( ( const char* ) envVar );
259 dir.sprintf( "%s", cenv );
260 if ( !dir.isEmpty() ) {
261 dir = QAD_Tools::addSlash(dir) ;
262 dir = dir + "share" ;
263 dir = QAD_Tools::addSlash(dir) ;
264 dir = dir + "salome" ;
265 dir = QAD_Tools::addSlash(dir) ;
266 dir = dir + "resources" ;
267 dir = QAD_Tools::addSlash(dir) ;
268 dirList.append( dirList.isEmpty() ? dir : ( QString( SEPARATOR ) + dir ) );
273 // Try CSF_<prefix>Resources env.var directory ( or directory list )
274 if ( !prefix.isEmpty() ) {
275 envVar = QCString( "CSF_" ) + prefix.latin1() + QCString( "Resources" );
276 cenv = getenv( ( const char* ) envVar );
278 dir.sprintf( "%s", cenv );
279 if ( !dir.isEmpty() )
280 dirList.append( dirList.isEmpty() ? dir : ( QString( SEPARATOR ) + dir ) );
283 // Try ${HOME}/.salome/resources directory
284 cenv = getenv( "HOME" );
286 dir.sprintf( "%s", cenv );
287 if ( !dir.isEmpty() ) {
288 dir = QAD_Tools::addSlash(dir) ;
289 dir = dir + ".salome" ;
290 dir = QAD_Tools::addSlash(dir) ;
291 dir = dir + "resources" ;
292 dir = QAD_Tools::addSlash(dir) ;
293 dirList.append( dirList.isEmpty() ? dir : ( QString( SEPARATOR ) + dir ) );
297 // Try ${KERNEL_ROOT_DIR}/share/salome/resources directory
298 cenv = getenv( "KERNEL_ROOT_DIR" );
300 dir.sprintf( "%s", cenv );
301 if ( !dir.isEmpty() ) {
302 dir = QAD_Tools::addSlash(dir) ;
303 dir = dir + "share" ;
304 dir = QAD_Tools::addSlash(dir) ;
305 dir = dir + "salome" ;
306 dir = QAD_Tools::addSlash(dir) ;
307 dir = dir + "resources" ;
308 dir = QAD_Tools::addSlash(dir) ;
309 dirList.append( dirList.isEmpty() ? dir : ( QString( SEPARATOR ) + dir ) );
312 //MESSAGE("QAD_ResourceMgr::collectDirs : "<<dirList.latin1()) ;
317 Returns a directory where 'filename' is located (filename is relative
318 of the application identified by 'prefix' or empty string if file not found
319 Search is processed in different location : see collectDirs() method description
321 QString QAD_ResourceMgr::getFile( const QString& filename, const char* prefix ) const
323 QFileInfo fi( path( filename, prefix, 0 ) );
324 if ( fi.isFile() && fi.exists() )
330 Returns a directory where 'filename' is located (filename is relative
331 of the application identified by 'prefix' or empty string if file not found
332 Search is processed in different location : see collectDirs() method description
333 The difference from above method that this function is used when resources
334 is not yet actually loaded by application.
336 QString QAD_ResourceMgr::findFile( const QString& filename, const char* prefix ) const
338 QString resDirs = collectDirs( prefix );
339 QStringList dirList = QStringList::split( SEPARATOR, resDirs, false ); // skip empty entries
340 for ( int i = 0; i < dirList.count(); i++ ) {
341 QString dir = dirList[ i ];
342 QFileInfo fi( QAD_Tools::addSlash( dir ) + filename );
343 if ( fi.isFile() && fi.exists() )
350 Returns a path to file 'filename' (filename is relative
351 of the application identified by 'prefix' and subdirectory identified by 'key'
352 or empty string if file not found.
353 Search is processed in different location : see collectDirs() method description
355 Returns a directory 'key' resource of the application
356 identified by 'prefix'
358 QString QAD_ResourceMgr::path( const QString& filename, const char* prefix, const char* key ) const
362 ResourceSettings* rs = myRes[ prefix ];
364 StringDict& conf = rs->config();
365 QString resDirs = QString( *( conf[ RES_DIR ] ) );
366 if ( !resDirs.isEmpty() ) {
367 //MESSAGE("QAD_ResourceMgr::resDirs : <"<<resDirs<<">") ;
368 QStringList dirList = QStringList::split( SEPARATOR, resDirs, false ); // skip empty entries
369 for ( int i = 0; i < dirList.count(); i++ ) {
370 QString dir = dirList[ i ];
371 dir = QAD_Tools::addSlash( dir );
373 QString* where = conf[ key ];
375 dir = dir + QAD_Tools::addSlash( *where );
377 dir = dir + filename;
378 QFileInfo fileInfo( dir );
379 if ( fileInfo.isFile() && fileInfo.exists() ) {
380 filePath = fileInfo.filePath();
386 //MESSAGE("QAD_ResourceMgr::path : <"<<filename.latin1()<<"> : "<<filePath.latin1()) ;
391 Loads a pixmap from 'resname' resources
392 and indetified by 'id'
394 QPixmap QAD_ResourceMgr::loadPixmap( const char* resname,
395 const QString& id ) const
397 return QPixmap( path( id, resname, RES_PIXMAPS ) );
401 Loads a doc page from 'resname' resources
402 and indetified by 'id'
404 bool QAD_ResourceMgr::loadDoc( const char* resname,
405 const QString& id ) const
407 QString docPath = path( id, resname, RES_DOCS );
411 /************************************************************************
413 ** Class QAD_ResourceMgr::ResourceSettings ( internal )
415 *************************************************************************/
418 Loads a resource 'file'.
419 Returns 'false' if 'file' can't be loaded( not found etc. ),
420 'true' if loaded or reloaded OK.
422 bool QAD_ResourceMgr::ResourceSettings::load( const QString& file )
424 #if QT_VERSION >= 0x030000 // VSR: workaround - crash on qt3.0.5 ==========
425 static const int magic_length = 16; // length of *.qm file header (qtranslator.cpp)
426 static const uchar magic[magic_length] = { // magic number for the file
427 0x3c, 0xb8, 0x64, 0x18, 0xca, 0xef, 0x9c, 0x95,
428 0xcd, 0x21, 0x1c, 0xbf, 0x60, 0xa1, 0xbd, 0xdd };
430 if ( !f.exists() || f.size() < magic_length)
432 char buf[magic_length];
433 if ( !f.open(IO_ReadOnly) )
435 bool bOk = ( f.readBlock(buf, magic_length) == magic_length );
439 if ( memcmp( (const void *)buf, magic, magic_length ) )
441 if ( f.size() == magic_length)
443 #endif // VSR =============================================================
444 QTranslator* strTbl = new QTranslator( 0 );
446 if ( !strTbl->load( file, "" ) ) {
454 QAD_ASSERT_DEBUG_ONLY( qApp );
455 qApp->installTranslator( strTbl );