Salome HOME
d5376b7e067c2a1d173452961afcbaaa33e9d2b0
[modules/gui.git] / src / Qtx / QtxResourceMgr.cxx
1 // Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
2 // 
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either 
6 // version 2.1 of the License.
7 // 
8 // This library is distributed in the hope that it will be useful 
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public  
14 // License along with this library; if not, write to the Free Software 
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/
18 //
19 #include "QtxResourceMgr.h"
20
21 #include <qdir.h>
22 #include <qfile.h>
23 #include <qregexp.h>
24 #include <qpixmap.h>
25 #include <qtranslator.h>
26 #include <qapplication.h>
27
28 #ifndef QT_NO_DOM
29 #include <qdom.h>
30 #endif
31
32 #include <stdlib.h>
33
34 /*!
35   Class: QtxResourceMgr::Resources
36   Level: Internal
37 */
38
39 QtxResourceMgr::Resources::Resources( const QtxResourceMgr* mgr, const QString& fileName )
40 : myFileName( fileName ),
41   myMgr( const_cast<QtxResourceMgr*>( mgr ) )
42 {
43 }
44
45 QtxResourceMgr::Resources::~Resources()
46 {
47 }
48
49 QString QtxResourceMgr::Resources::file() const
50 {
51   return myFileName;
52 }
53
54 void QtxResourceMgr::Resources::setFile( const QString& fn )
55 {
56   myFileName = fn;
57 }
58
59 QString QtxResourceMgr::Resources::value( const QString& sect, const QString& name, const bool subst ) const
60 {
61   QString val;
62
63   if ( hasValue( sect, name ) )
64   {
65     val = section( sect )[name];
66     if ( subst )
67       val = makeSubstitution( val, sect, name );
68   }
69   return val;
70 }
71
72 void QtxResourceMgr::Resources::setValue( const QString& sect, const QString& name, const QString& val )
73 {
74   Section& s = section( sect );
75   s.insert( name, val );
76 }
77
78 bool QtxResourceMgr::Resources::hasSection( const QString& sect ) const
79 {
80   return mySections.contains( sect );
81 }
82
83 bool QtxResourceMgr::Resources::hasValue( const QString& sect, const QString& name ) const
84 {
85   return hasSection( sect ) && section( sect ).contains( name );
86 }
87
88 void QtxResourceMgr::Resources::removeSection( const QString& sect )
89 {
90   mySections.remove( sect );
91 }
92
93 void QtxResourceMgr::Resources::removeValue( const QString& sect, const QString& name )
94 {
95   if ( !hasSection( sect ) )
96     return;
97
98   Section& s = section( sect );
99   s.remove( name );
100
101   if ( s.isEmpty() )
102     mySections.remove( sect );
103 }
104
105 void QtxResourceMgr::Resources::clear()
106 {
107   mySections.clear();
108 }
109
110 QStringList QtxResourceMgr::Resources::sections() const
111 {
112   return mySections.keys();
113 }
114
115 QStringList QtxResourceMgr::Resources::parameters( const QString& sec ) const
116 {
117   if ( !hasSection( sec ) )
118     return QStringList();
119
120   return section( sec ).keys();
121 }
122
123 QString QtxResourceMgr::Resources::path( const QString& sec, const QString& prefix, const QString& name ) const
124 {
125   QString filePath = fileName( sec, prefix, name );
126   if ( !filePath.isEmpty() )
127   {
128     if ( !QFileInfo( filePath ).exists() )
129       filePath = QString::null;
130   }
131   return filePath;
132 }
133
134 QtxResourceMgr* QtxResourceMgr::Resources::resMgr() const
135 {
136   return myMgr;
137 }
138
139 QtxResourceMgr::Section& QtxResourceMgr::Resources::section( const QString& sn )
140 {
141   if ( !mySections.contains( sn ) )
142     mySections.insert( sn, Section() );
143
144   return mySections[sn];
145 }
146
147 const QtxResourceMgr::Section& QtxResourceMgr::Resources::section( const QString& sn ) const
148 {
149   return mySections[sn];
150 }
151
152 QString QtxResourceMgr::Resources::fileName( const QString& sect, const QString& prefix, const QString& name ) const
153 {
154   QString path;
155   if ( hasValue( sect, prefix ) )
156   {
157     path = value( sect, prefix, true );
158     if ( !path.isEmpty() )
159     {
160       if ( QFileInfo( path ).isRelative() )
161         path = Qtx::addSlash( QFileInfo( myFileName ).dirPath( true ) ) + path;
162
163       path = Qtx::addSlash( path ) + name;
164     }
165   }
166   if( !path.isEmpty() )
167   {
168     QString fname = QDir::convertSeparators( path );
169     QFileInfo inf( fname );
170     fname = inf.absFilePath();
171     return fname;
172   }
173   return QString();
174 }
175
176 QPixmap QtxResourceMgr::Resources::loadPixmap( const QString& sect, const QString& prefix, const QString& name ) const
177 {
178   QString fname = fileName( sect, prefix, name );
179   bool toCache = resMgr() ? resMgr()->isPixmapCached() : false;
180   QPixmap p;
181   if( toCache && myPixmapCache.contains( fname ) )
182     p = myPixmapCache[fname];
183   else
184   {
185     p.load( fname );
186     if( toCache )
187       ( ( QMap<QString,QPixmap>& )myPixmapCache ).insert( fname, p );
188   }
189   return p;
190 }
191
192 QTranslator* QtxResourceMgr::Resources::loadTranslator( const QString& sect, const QString& prefix, const QString& name ) const
193 {
194   QTranslator* trans = new QTranslator( 0 );
195   if ( !trans->load( fileName( sect, prefix, name ) ) )
196   {
197     delete trans;
198     trans = 0;
199   }
200   return trans;
201 }
202
203 QString QtxResourceMgr::Resources::environmentVariable( const QString& str, int& start, int& len ) const
204 {
205   QString varName = QString::null;
206   len = 0;
207
208   QRegExp rx( "\\$\\{([a-zA-Z]+[a-zA-Z0-9_]*)\\}|\\$\\(([a-zA-Z]+[a-zA-Z0-9_]*)\\)|\\$([a-zA-Z]+[a-zA-Z0-9_]*)|\\%([a-zA-Z]+[a-zA-Z0-9_]*)\\%" );
209
210   int pos = rx.search( str, start );
211   if ( pos != -1 )
212   {
213     start = pos;
214     len = rx.matchedLength();
215     QStringList caps = rx.capturedTexts();
216     for ( uint i = 1; i <= caps.count() && varName.isEmpty(); i++ )
217       varName = *caps.at( i );
218   }
219   return varName;
220 }
221
222 QString QtxResourceMgr::Resources::makeSubstitution( const QString& str, const QString& sect, const QString& name ) const
223 {
224   QString res = str;
225
226   QMap<QString, int> ignoreMap;
227   ignoreMap.insert( name, 0 );
228
229   int start( 0 ), len( 0 );
230   while ( true )
231   {
232     QString envName = environmentVariable( res, start, len );
233     if ( envName.isNull() )
234       break;
235
236     QString newStr = QString::null;
237     if ( ::getenv( envName ) )
238       newStr = QString( ::getenv( envName ) );
239
240     if ( newStr.isNull() )
241     {
242       if ( ignoreMap.contains( envName ) )
243       {
244         start += len;
245         continue;
246       }
247
248       if ( hasValue( sect, envName ) )
249         newStr = value( sect, envName, false );
250       ignoreMap.insert( envName, 0 );
251     }
252     res.replace( start, len, newStr );
253   }
254
255   return res;
256 }
257
258 /*!
259         Class: QtxResourceMgr::IniFormat
260         Level: Internal
261 */
262
263 class QtxResourceMgr::IniFormat : public Format
264 {
265 public:
266   IniFormat();
267   ~IniFormat();
268
269 protected:
270   virtual bool load( const QString&, QMap<QString, Section>& );
271   virtual bool save( const QString&, const QMap<QString, Section>& );
272 };
273
274 QtxResourceMgr::IniFormat::IniFormat()
275 : Format( "ini" )
276 {
277 }
278
279 QtxResourceMgr::IniFormat::~IniFormat()
280 {
281 }
282
283 bool QtxResourceMgr::IniFormat::load( const QString& fname, QMap<QString, Section>& secMap )
284 {
285   QFile file( fname );
286   if ( !file.open( IO_ReadOnly ) )
287     return false;
288
289   QTextStream ts( &file );
290
291   QString data;
292   int line = 0;
293   bool res = true;
294   QString section;
295
296   QString separator = option( "separator" );
297   if ( separator.isNull() )
298     separator = QString( "=" );
299
300   QString comment = option( "comment" );
301   if ( comment.isNull() )
302     comment = QString( "#" );
303
304   while ( true )
305   {
306     data = ts.readLine();
307     line++;
308
309     if ( data.isNull() )
310       break;
311
312     data = data.stripWhiteSpace();
313     if ( data.isEmpty() )
314       continue;
315
316     if ( data.startsWith( comment ) )
317       continue;
318
319     QRegExp rx( "^\\[([\\w\\s\\._]*)\\]$" );
320     if ( rx.search( data ) != -1 )
321     {
322       section = rx.cap( 1 );
323       if ( section.isEmpty() )
324       {
325         res = false;
326         qWarning( QString( "Empty section in line %1" ).arg( line ) );
327       }
328     }
329     else if ( data.contains( "=" ) && !section.isEmpty() )
330     {
331       int pos = data.find( separator );
332       QString key = data.left( pos ).stripWhiteSpace();
333       QString val = data.mid( pos + 1 ).stripWhiteSpace();
334       secMap[section].insert( key, val );
335     }
336     else
337     {
338       res = false;
339       section.isEmpty() ? qWarning( "Current section is empty" ) :
340                           qWarning( QString( "Error in line: %1" ).arg( line ) );
341     }
342   }
343
344   file.close();
345
346   return res;
347 }
348
349 bool QtxResourceMgr::IniFormat::save( const QString& fname, const QMap<QString, Section>& secMap )
350 {
351   QFile file( fname );
352   if ( !file.open( IO_WriteOnly ) )
353     return false;
354
355   bool res = true;
356   for ( QMap<QString, Section>::ConstIterator it = secMap.begin(); it != secMap.end() && res; ++it )
357   {
358     QString data = QString( "[%1]\n" ).arg( it.key() );
359     for ( Section::ConstIterator iter = it.data().begin(); iter != it.data().end(); ++iter )
360       data += iter.key() + " = " + iter.data() + "\n";
361     data += "\n";
362
363     res = file.writeBlock( data.latin1(), data.length() ) == (int)data.length();
364   }
365
366   file.close();
367
368   return res;
369 }
370
371 /*!
372         Class: QtxResourceMgr::XmlFormat
373         Level: Internal
374 */
375
376 class QtxResourceMgr::XmlFormat : public Format
377 {
378 public:
379   XmlFormat();
380   ~XmlFormat();
381
382 protected:
383   virtual bool load( const QString&, QMap<QString, Section>& );
384   virtual bool save( const QString&, const QMap<QString, Section>& );
385
386 private:
387   QString      docTag() const;
388   QString      sectionTag() const;
389   QString      parameterTag() const;
390   QString      nameAttribute() const;
391   QString      valueAttribute() const;
392 };
393
394 QtxResourceMgr::XmlFormat::XmlFormat()
395 : Format( "xml" )
396 {
397 }
398
399 QtxResourceMgr::XmlFormat::~XmlFormat()
400 {
401 }
402
403 bool QtxResourceMgr::XmlFormat::load( const QString& fname, QMap<QString, Section>& secMap )
404 {
405   bool res = false;
406
407 #ifndef QT_NO_DOM
408
409   QFile file( fname );
410   if ( !file.open( IO_ReadOnly ) )
411     return false;
412
413   QDomDocument doc;
414
415   res = doc.setContent( &file );
416   file.close();
417
418   if ( !res )
419     return false;
420
421   QDomElement root = doc.documentElement();
422   if ( root.isNull() || root.tagName() != docTag() )
423     return false;
424
425   QDomNode sectNode = root.firstChild();
426   while ( res && !sectNode.isNull() )
427   {
428     res = sectNode.isElement();
429     if ( res )
430     {
431       QDomElement sectElem = sectNode.toElement();
432       if ( sectElem.tagName() == sectionTag() && sectElem.hasAttribute( nameAttribute() ) )
433       {
434         QString section = sectElem.attribute( nameAttribute() );
435         QDomNode paramNode = sectNode.firstChild();
436         while ( res && !paramNode.isNull() )
437         {
438           res = paramNode.isElement();
439           if ( res )
440           {
441             QDomElement paramElem = paramNode.toElement();
442             if ( paramElem.tagName() == parameterTag() &&
443                  paramElem.hasAttribute( nameAttribute() ) && paramElem.hasAttribute( valueAttribute() ) )
444             {
445               QString paramName = paramElem.attribute( nameAttribute() );
446               QString paramValue = paramElem.attribute( valueAttribute() );
447
448               secMap[section].insert( paramName, paramValue );
449             }
450             else
451               res = false;
452           }
453           else
454             res = paramNode.isComment();
455
456           paramNode = paramNode.nextSibling();
457         }
458       }
459       else
460         res = false;
461     }
462     else
463       res = sectNode.isComment(); // if it's a comment -- let it be, pass it..
464
465     sectNode = sectNode.nextSibling();
466   }
467
468 #endif
469
470   return res;
471 }
472
473 bool QtxResourceMgr::XmlFormat::save( const QString& fname, const QMap<QString, Section>& secMap )
474 {
475   bool res = false;
476
477 #ifndef QT_NO_DOM
478
479   QFile file( fname );
480   if ( !file.open( IO_WriteOnly ) )
481     return false;
482
483   QDomDocument doc( docTag() );
484   QDomElement root = doc.createElement( docTag() );
485   doc.appendChild( root );
486
487   for ( QMap<QString, Section>::ConstIterator it = secMap.begin(); it != secMap.end(); ++it )
488   {
489     QDomElement sect = doc.createElement( sectionTag() );
490     sect.setAttribute( nameAttribute(), it.key() );
491     root.appendChild( sect );
492     for ( Section::ConstIterator iter = it.data().begin(); iter != it.data().end(); ++iter )
493     {
494       QDomElement val = doc.createElement( parameterTag() );
495       val.setAttribute( nameAttribute(), iter.key() );
496       val.setAttribute( valueAttribute(), iter.data() );
497       sect.appendChild( val );
498     }
499   }
500
501   QString docStr = doc.toString();
502   res = file.writeBlock( docStr.latin1(), docStr.length() ) == (int)docStr.length();
503   file.close();
504
505 #endif
506
507   return res;
508 }
509
510 QString QtxResourceMgr::XmlFormat::docTag() const
511 {
512   QString tag = option( "doc_tag" );
513   if ( tag.isEmpty() )
514     tag = QString( "document" );
515   return tag;
516 }
517
518 QString QtxResourceMgr::XmlFormat::sectionTag() const
519 {
520   QString tag = option( "section_tag" );
521   if ( tag.isEmpty() )
522     tag = QString( "section" );
523   return tag;
524 }
525
526 QString QtxResourceMgr::XmlFormat::parameterTag() const
527 {
528   QString tag = option( "parameter_tag" );
529   if ( tag.isEmpty() )
530     tag = QString( "parameter" );
531   return tag;
532 }
533
534 QString QtxResourceMgr::XmlFormat::nameAttribute() const
535 {
536   QString str = option( "name_attribute" );
537   if ( str.isEmpty() )
538     str = QString( "name" );
539   return str;
540 }
541
542 QString QtxResourceMgr::XmlFormat::valueAttribute() const
543 {
544   QString str = option( "value_attribute" );
545   if ( str.isEmpty() )
546     str = QString( "value" );
547   return str;
548 }
549
550 /*!
551         Class: QtxResourceMgr::Format
552         Level: Public
553 */
554
555 /*!
556   \brief Constructs the format object with specified name.
557   \param fmt - name of the format
558 */
559 QtxResourceMgr::Format::Format( const QString& fmt )
560 : myFmt( fmt )
561 {
562 }
563
564 /*!
565   \brief Destructs the format object.
566 */
567 QtxResourceMgr::Format::~Format()
568 {
569 }
570
571 /*!
572   \brief Returns the format name.
573 */
574 QString QtxResourceMgr::Format::format() const
575 {
576   return myFmt;
577 }
578
579 /*!
580   \brief Returns the string list of the format options.
581 */
582 QStringList QtxResourceMgr::Format::options() const
583 {
584   return myOpt.keys();
585 }
586
587 /*!
588   \brief Returns the value of the option with specified name.
589          If option doesn't exist then empty string returned.
590   \param opt - name of the option
591 */
592 QString QtxResourceMgr::Format::option( const QString& opt ) const
593 {
594   QString val;
595   if ( myOpt.contains( opt ) )
596     val = myOpt[opt];
597   return val;
598 }
599
600 /*!
601   \brief Sets the value of the option with specified name.
602   \param opt - name of the option
603   \param opt - value of the option
604 */
605 void QtxResourceMgr::Format::setOption( const QString& opt, const QString& val )
606 {
607   myOpt.insert( opt, val );
608 }
609
610 /*!
611   \brief Perform the loading of the resources from resource file.
612   \param res - resources object which will be loaded
613 */
614 bool QtxResourceMgr::Format::load( Resources* res )
615 {
616   if ( !res )
617     return false;
618
619   QMap<QString, Section> sections;
620   bool status = load( res->myFileName, sections );
621   if ( status )
622     res->mySections = sections;
623   else
624     qDebug( "QtxResourceMgr: Could not load resource file \"%s\"", res->myFileName.latin1() );
625
626   return status;
627 }
628
629 /*!
630   \brief Perform the saving of the resources into resource file.
631   \param res - resources object which will be saved
632 */
633 bool QtxResourceMgr::Format::save( Resources* res )
634 {
635   if ( !res )
636     return false;
637
638   Qtx::mkDir( Qtx::dir( res->myFileName ) );
639
640   return save( res->myFileName, res->mySections );
641 }
642
643 /*!
644         Class: QtxResourceMgr
645         Level: Public
646 */
647
648 /*!
649   \brief Constructs the resource manager object for application.
650   \param appName - name of the application which resources will be used.
651   \param resVarTemplate - template for the resource environment variable name which
652                           should point to the resource directory list.
653                           Default value is "%1Resources". Its mean that for application
654                           with name "MyApp" environment variable "MyAppResources" will
655                           be used. Template may not have the parameter '%1' substituted
656                           by application name. In this case this string will be used as
657                           is without substitution.
658   Resource environment variable should contains one or several resource directories
659   separated by symbol ';'. Resource directories list transfered into the setDirList().
660   These directories and the user home directory used for the loading application resources.
661   Each of the resource directories can contains resource file. The name of this file defined
662   by the function globalFileName(). Resource file name in the user home defined by the
663   function userFileName(). Any resource looking firstly in the user home resources then
664   resource directories used in the specified order. All setted resources always stored into
665   the resource file at the user home. Only user home resource file is saved.
666   If you want to ignore of loading of Local User Preferences, you needs setup setIngoreUserValues()
667   as true.
668 */
669 QtxResourceMgr::QtxResourceMgr( const QString& appName, const QString& resVarTemplate )
670 : myAppName( appName ),
671   myCheckExist( true ),
672   myIsPixmapCached( true ),
673   myIsIgnoreUserValues( false )
674 {
675   QString envVar = !resVarTemplate.isEmpty() ? resVarTemplate : QString( "%1Resources" );
676   if ( envVar.contains( "%1" ) )
677     envVar = envVar.arg( appName );
678
679   QString dirs;
680   if ( ::getenv( envVar ) )
681     dirs = ::getenv( envVar );
682 #ifdef WNT
683   QString dirsep = ";";      // for Windows: ";" is used as directories separator
684 #else
685   QString dirsep = "[:|;]";  // for Linux: both ":" and ";" can be used
686 #endif
687   setDirList( QStringList::split( QRegExp(dirsep), dirs ) );
688
689   installFormat( new XmlFormat() );
690   installFormat( new IniFormat() );
691
692   setOption( "translators", QString( "%P_msg_%L.qm|%P_images.qm" ) );
693 }
694
695 /*!
696   \brief Destructs the resource manager object and free allocated memory.
697 */
698 QtxResourceMgr::~QtxResourceMgr()
699 {
700   QStringList prefList = myTranslator.keys();
701   for ( QStringList::const_iterator it = prefList.begin(); it != prefList.end(); ++it )
702     removeTranslators( *it );
703 }
704
705 /*!
706   \brief Returns the application name.
707 */
708 QString QtxResourceMgr::appName() const
709 {
710   return myAppName;
711 }
712
713 /*!
714   \brief Returns the checking of the existance flag. If its 'true' then resource
715          will be setted into the manager only if it doesn't exist or has different
716          value that existing value.
717 */
718 bool QtxResourceMgr::checkExisting() const
719 {
720   return myCheckExist;
721 }
722
723 /*!
724   \brief Sets the checking of the existance flag.
725   \param on - boolean value of the flag.
726 */
727 void QtxResourceMgr::setCheckExisting( const bool on )
728 {
729   myCheckExist = on;
730 }
731
732 /*!
733   \brief Returns the resource directories list except user home directory.
734 */
735 QStringList QtxResourceMgr::dirList() const
736 {
737   return myDirList;
738 }
739
740 /*!
741   \brief Initialise the manager. Prepare the resource containers and load resources.
742   \param autoLoad - if 'true' then all resources will be loaded.
743 */
744 void QtxResourceMgr::initialize( const bool autoLoad ) const
745 {
746   if ( !myResources.isEmpty() )
747     return;
748
749   QtxResourceMgr* that = (QtxResourceMgr*)this;
750
751   if ( !userFileName( appName() ).isEmpty() )
752     that->myResources.append( new Resources( this, userFileName( appName() ) ) );
753
754   for ( QStringList::const_iterator it = myDirList.begin(); it != myDirList.end(); ++it )
755   {
756     QString path = Qtx::addSlash( *it ) + globalFileName( appName() );
757     that->myResources.append( new Resources( this, path ) );
758   }
759
760   if ( autoLoad )
761     that->load();
762 }
763
764 /*!
765   \brief Return true if all loaded pixmaps are stored in internal map; by default: true
766 */
767 bool QtxResourceMgr::isPixmapCached() const
768 {
769   return myIsPixmapCached;
770 }
771
772 /*!
773   \brief Set true, if it is necessary to store all loaded pixmap in internal map
774   (it accelerates following calls of loadPixmap)
775 */
776 void QtxResourceMgr::setIsPixmapCached( const bool on )
777 {
778   myIsPixmapCached = on;
779 }
780
781 /*!
782   \brief Removes all resources from the manager.
783 */
784 void QtxResourceMgr::clear()
785 {
786   for ( ResListIterator it( myResources ); it.current(); ++it )
787     it.current()->clear();
788 }
789
790 void QtxResourceMgr::setIgnoreUserValues( const bool val )
791 {
792   myIsIgnoreUserValues = val;
793 }
794
795 bool QtxResourceMgr::ignoreUserValues() const
796 {
797   return myIsIgnoreUserValues;
798 }
799
800 /*!
801   \brief Get the resource value as integer. Returns 'true' if it successfull otherwise
802          returns 'false'.
803   \param sect - Resource section name which contains resource.
804   \param name - Name of the resource.
805   \param iVal - Reference on the variable which should contains the resource output.
806 */
807 bool QtxResourceMgr::value( const QString& sect, const QString& name, int& iVal ) const
808 {
809   QString val;
810   if ( !value( sect, name, val, true ) )
811     return false;
812
813   bool ok;
814   iVal = val.toInt( &ok );
815
816   return ok;
817 }
818
819 /*!
820   \brief Get the resource value as double. Returns 'true' if it successfull otherwise
821          returns 'false'.
822   \param sect - Resource section name which contains resource.
823   \param name - Name of the resource.
824   \param dVal - Reference on the variable which should contains the resource output.
825 */
826 bool QtxResourceMgr::value( const QString& sect, const QString& name, double& dVal ) const
827 {
828   QString val;
829   if ( !value( sect, name, val, true ) )
830     return false;
831
832   bool ok;
833   dVal = val.toDouble( &ok );
834
835   return ok;
836 }
837
838 /*!
839   \brief Get the resource value as boolean. Returns 'true' if it successfull otherwise
840          returns 'false'.
841   \param sect - Resource section name which contains resource.
842   \param name - Name of the resource.
843   \param bVal - Reference on the variable which should contains the resource output.
844 */
845 bool QtxResourceMgr::value( const QString& sect, const QString& name, bool& bVal ) const
846 {
847   QString val;
848   if ( !value( sect, name, val, true ) )
849     return false;
850
851   static QMap<QString, bool> boolMap;
852   if ( boolMap.isEmpty() )
853   {
854     boolMap["true"]  = boolMap["yes"] = boolMap["on"]  = true;
855     boolMap["false"] = boolMap["no"]  = boolMap["off"] = false;
856   }
857
858   val = val.lower();
859   bool res = boolMap.contains( val );
860   if ( res )
861     bVal = boolMap[val];
862   else
863   {
864     double num = val.toDouble( &res );
865     if ( res )
866       bVal = num != 0;
867   }
868
869   return res;
870 }
871
872 /*!
873   \brief Get the resource value as color. Returns 'true' if it successfull otherwise
874          returns 'false'.
875   \param sect - Resource section name which contains resource.
876   \param name - Name of the resource.
877   \param cVal - Reference on the variable which should contains the resource output.
878 */
879 bool QtxResourceMgr::value( const QString& sect, const QString& name, QColor& cVal ) const
880 {
881   QString val;
882   if ( !value( sect, name, val, true ) )
883     return false;
884
885   bool res = true;
886   QStringList vals = QStringList::split( ",", val, true );
887
888   QIntList nums;
889   for ( QStringList::const_iterator it = vals.begin(); it != vals.end() && res; ++it )
890     nums.append( (*it).toInt( &res ) );
891
892   if ( res && nums.count() >= 3 )
893     cVal.setRgb( nums[0], nums[1], nums[2] );
894   else
895   {
896     int pack = val.toInt( &res );
897     if ( res )
898       Qtx::rgbSet( pack, cVal );
899   }
900
901   return res;
902 }
903
904 /*!
905   \brief Get the resource value as font. Returns 'true' if it successfull otherwise
906          returns 'false'.
907   \param sect - Resource section name which contains resource.
908   \param name - Name of the resource.
909   \param fVal - Reference on the variable which should contains the resource output.
910 */
911 bool QtxResourceMgr::value( const QString& sect, const QString& name, QFont& fVal ) const
912 {
913   QString val;
914   if ( !value( sect, name, val, true ) )
915     return false;
916
917   QStringList fontDescr = QStringList::split( ",", val );
918
919   if ( fontDescr.count() < 2 )
920     return false;
921
922   QString family = fontDescr[0];
923   if ( family.isEmpty() )
924     return false;
925
926   fVal = QFont( family );
927
928   for ( int i = 1; i < (int)fontDescr.count(); i++ )
929   {
930     QString curval = fontDescr[i].stripWhiteSpace().lower();
931     if ( curval == QString( "bold" ) )
932       fVal.setBold( true );
933     else if ( curval == QString( "italic" ) )
934       fVal.setItalic( true );
935     else if ( curval == QString( "underline" ) )
936       fVal.setUnderline( true );
937     else
938     {
939       bool isOk = false;
940       int ps = curval.toInt( &isOk );
941       if ( isOk )
942         fVal.setPointSize( ps );
943     }
944   }
945
946   return true;
947 }
948
949 /*!
950   \brief Get the resource value as string (native format). Returns 'true' if it
951          successfull otherwise returns 'false'.
952   \param sect  - Resource section name which contains resource.
953   \param name  - Name of the resource.
954   \param val   - Reference on the variable which should contains the resource output.
955   \param subst - If 'true' then manager substitute reference on environment variables
956                  and other resources by thier values. Default value of this parameter
957                  is 'true'
958 */
959 bool QtxResourceMgr::value( const QString& sect, const QString& name, QString& val, const bool subst ) const
960 {
961   initialize();
962
963   bool ok = false;
964  
965   ResListIterator it( myResources );
966   if ( ignoreUserValues() )
967     ++it;
968
969   for ( ; it.current() && !ok; ++it )
970   {
971     ok = it.current()->hasValue( sect, name );
972     if ( ok )
973       val = it.current()->value( sect, name, subst );
974   }
975
976   return ok;
977 }
978
979 /*!
980   \brief Returns the integer resource value. If resource can not be found or converted
981          then specified default value will be returned.
982   \param sect  - Resource section name which contains resource.
983   \param name  - Name of the resource.
984   \param def   - Default resource value which will be used when resource not found.
985 */
986 int QtxResourceMgr::integerValue( const QString& sect, const QString& name, const int def ) const
987 {
988   int val;
989   if ( !value( sect, name, val ) )
990     val = def;
991   return val;
992 }
993
994 /*!
995   \brief Returns the double resource value. If resource can not be found or converted
996          then specified default value will be returned.
997   \param sect  - Resource section name which contains resource.
998   \param name  - Name of the resource.
999   \param def   - Default resource value which will be used when resource not found.
1000 */
1001 double QtxResourceMgr::doubleValue( const QString& sect, const QString& name, const double def ) const
1002 {
1003   double val;
1004   if ( !value( sect, name, val ) )
1005     val = def;
1006   return val;
1007 }
1008
1009 /*!
1010   \brief Returns the boolean resource value. If resource can not be found or converted
1011          then specified default value will be returned.
1012   \param sect  - Resource section name which contains resource.
1013   \param name  - Name of the resource.
1014   \param def   - Default resource value which will be used when resource not found.
1015 */
1016 bool QtxResourceMgr::booleanValue( const QString& sect, const QString& name, const bool def ) const
1017 {
1018   bool val;
1019   if ( !value( sect, name, val ) )
1020     val = def;
1021   return val;
1022 }
1023
1024 /*!
1025   \brief Returns the font resource value. If resource can not be found or converted
1026          then specified default value will be returned.
1027   \param sect  - Resource section name which contains resource.
1028   \param name  - Name of the resource.
1029   \param def   - Default resource value which will be used when resource not found.
1030 */
1031 QFont QtxResourceMgr::fontValue( const QString& sect, const QString& name, const QFont& def ) const
1032 {
1033   QFont font;
1034   if( !value( sect, name, font ) )
1035     font = def;
1036   return font;
1037 }
1038
1039 /*!
1040   \brief Returns the color resource value. If resource can not be found or converted
1041          then specified default value will be returned.
1042   \param sect  - Resource section name which contains resource.
1043   \param name  - Name of the resource.
1044   \param def   - Default resource value which will be used when resource not found.
1045 */
1046 QColor QtxResourceMgr::colorValue( const QString& sect, const QString& name, const QColor& def ) const
1047 {
1048   QColor val;
1049   if ( !value( sect, name, val ) )
1050     val = def;
1051   return val;
1052 }
1053
1054 /*!
1055   \brief Returns the string resource value. If resource can not be found or converted
1056          then specified default value will be returned.
1057   \param sect  - Resource section name which contains resource.
1058   \param name  - Name of the resource.
1059   \param def   - Default resource value which will be used when resource not found.
1060 */
1061 QString QtxResourceMgr::stringValue( const QString& sect, const QString& name, const QString& def ) const
1062 {
1063   QString val;
1064   if ( !value( sect, name, val ) )
1065     val = def;
1066   return val;
1067 }
1068
1069 /*!
1070   \brief Checks existance of the specified resource.
1071   \param sect  - Resource section name which contains resource.
1072   \param name  - Name of the resource.
1073 */
1074 bool QtxResourceMgr::hasValue( const QString& sect, const QString& name ) const
1075 {
1076   initialize();
1077
1078   bool ok = false;
1079   for ( ResListIterator it( myResources ); it.current() && !ok; ++it )
1080     ok = it.current()->hasValue( sect, name );
1081
1082   return ok;
1083 }
1084
1085 /*!
1086   \brief Checks existance of the specified resource section.
1087   \param sect  - Resource section name which contains resource.
1088 */
1089 bool QtxResourceMgr::hasSection( const QString& sect ) const
1090 {
1091   initialize();
1092
1093   bool ok = false;
1094   for ( ResListIterator it( myResources ); it.current() && !ok; ++it )
1095     ok = it.current()->hasSection( sect );
1096
1097   return ok;
1098 }
1099
1100 /*!
1101   \brief Sets the integer resource value.
1102   \param sect  - Resource section name.
1103   \param name  - Name of the resource.
1104   \param val   - Resource value.
1105 */
1106 void QtxResourceMgr::setValue( const QString& sect, const QString& name, int val )
1107 {
1108   int res;
1109   if ( checkExisting() && value( sect, name, res ) && res == val )
1110     return;
1111
1112   setResource( sect, name, QString::number( val ) );
1113 }
1114
1115 /*!
1116   \brief Sets the double resource value.
1117   \param sect  - Resource section name.
1118   \param name  - Name of the resource.
1119   \param val   - Resource value.
1120 */
1121 void QtxResourceMgr::setValue( const QString& sect, const QString& name, double val )
1122 {
1123   double res;
1124   if ( checkExisting() && value( sect, name, res ) && res == val )
1125     return;
1126
1127   setResource( sect, name, QString::number( val, 'g', 12 ) );
1128 }
1129
1130 /*!
1131   \brief Sets the boolean resource value.
1132   \param sect  - Resource section name.
1133   \param name  - Name of the resource.
1134   \param val   - Resource value.
1135 */
1136 void QtxResourceMgr::setValue( const QString& sect, const QString& name, bool val )
1137 {
1138   bool res;
1139   if ( checkExisting() && value( sect, name, res ) && res == val )
1140     return;
1141
1142   setResource( sect, name, QString( val ? "true" : "false" ) );
1143 }
1144
1145 /*!
1146   \brief Sets the color resource value.
1147   \param sect  - Resource section name.
1148   \param name  - Name of the resource.
1149   \param val   - Resource value.
1150 */
1151 void QtxResourceMgr::setValue( const QString& sect, const QString& name, const QColor& val )
1152 {
1153   QColor res;
1154   if ( checkExisting() && value( sect, name, res ) && res == val )
1155     return;
1156
1157   setResource( sect, name, QString( "%1, %2, %3" ).arg( val.red() ).arg( val.green() ).arg( val.blue() ) );
1158 }
1159
1160 /*!
1161   \brief Sets the font resource value.
1162   \param sect  - Resource section name.
1163   \param name  - Name of the resource.
1164   \param val   - Resource value.
1165 */
1166 void QtxResourceMgr::setValue( const QString& sect, const QString& name, const QFont& val )
1167 {
1168   QFont res;
1169   if ( checkExisting() && value( sect, name, res ) && res == val )
1170     return;
1171
1172   QStringList fontDescr;
1173   fontDescr.append( val.family() );
1174   if ( val.bold() )
1175     fontDescr.append( "Bold" );
1176   if ( val.italic() )
1177     fontDescr.append( "Italic" );
1178   if ( val.underline() )
1179     fontDescr.append( "Underline" );
1180   fontDescr.append( QString( "%1" ).arg( val.pointSize() ) );
1181
1182   setResource( sect, name, fontDescr.join( "," ) );
1183 }
1184
1185 /*!
1186   \brief Sets the string resource value.
1187   \param sect  - Resource section name.
1188   \param name  - Name of the resource.
1189   \param val   - Resource value.
1190 */
1191 void QtxResourceMgr::setValue( const QString& sect, const QString& name, const QString& val )
1192 {
1193   QString res;
1194   if ( checkExisting() && value( sect, name, res ) && res == val )
1195     return;
1196
1197   setResource( sect, name, val );
1198 }
1199
1200 /*!
1201   \brief Remove the all specified resource section.
1202   \param sect  - Resource section name.
1203 */
1204 void QtxResourceMgr::remove( const QString& sect )
1205 {
1206   initialize();
1207
1208   for ( ResListIterator it( myResources ); it.current(); ++it )
1209     it.current()->removeSection( sect );
1210 }
1211
1212 /*!
1213   \brief Remove the specified resource.
1214   \param sect  - Resource section name.
1215   \param name  - Name of the resource.
1216 */
1217 void QtxResourceMgr::remove( const QString& sect, const QString& name )
1218 {
1219   initialize();
1220
1221   for ( ResListIterator it( myResources ); it.current(); ++it )
1222     it.current()->removeValue( sect, name );
1223 }
1224
1225 /*!
1226   \brief Returns the current format which operates with resource files.
1227 */
1228 QString QtxResourceMgr::currentFormat() const
1229 {
1230   QString fmt;
1231   if ( !myFormats.isEmpty() )
1232     fmt = myFormats.getFirst()->format();
1233   return fmt;
1234 }
1235
1236 /*!
1237   \brief Sets the current format which operates with resource files.
1238   \param fmt - Resource format name.
1239 */
1240 void QtxResourceMgr::setCurrentFormat( const QString& fmt )
1241 {
1242   Format* form = format( fmt );
1243   if ( !form )
1244     return;
1245
1246   myFormats.remove( form );
1247   myFormats.prepend( form );
1248
1249   if ( myResources.isEmpty() )
1250     return;
1251
1252   ResListIterator resIt( myResources );
1253   if ( myResources.count() > myDirList.count() && resIt.current() ) {
1254     resIt.current()->setFile( userFileName( appName() ) );
1255     ++resIt;
1256   }
1257
1258   for ( QStringList::const_iterator it = myDirList.begin(); it != myDirList.end() && resIt.current(); ++it, ++resIt )
1259     resIt.current()->setFile( Qtx::addSlash( *it ) + globalFileName( appName() ) );
1260 }
1261
1262 /*!
1263   \brief Returns the resource format object by it name.
1264   \param fmt - Resource format name.
1265 */
1266 QtxResourceMgr::Format* QtxResourceMgr::format( const QString& fmt ) const
1267 {
1268   Format* form = 0;
1269   for ( FormatListIterator it( myFormats ); it.current() && !form; ++it )
1270   {
1271     if ( it.current()->format() == fmt )
1272       form = it.current();
1273   }
1274
1275   return form;
1276 }
1277
1278 /*!
1279   \brief Add the resource format to the manager. Newly added become current.
1280   \param form - Resource format object.
1281 */
1282 void QtxResourceMgr::installFormat( QtxResourceMgr::Format* form )
1283 {
1284   if ( !myFormats.contains( form ) )
1285     myFormats.prepend( form );
1286 }
1287
1288 /*!
1289   \brief Remove the resource format from the manager.
1290   \param form - Resource format object.
1291 */
1292 void QtxResourceMgr::removeFormat( QtxResourceMgr::Format* form )
1293 {
1294   myFormats.remove( form );
1295 }
1296
1297 /*!
1298   \brief Returns the string list of the resource format options names.
1299 */
1300 QStringList QtxResourceMgr::options() const
1301 {
1302   return myOptions.keys();
1303 }
1304
1305 /*!
1306   \brief Returns the string value for the specified option. If option doesn't exist
1307          then empty string will be returned.
1308   \param opt - Option name.
1309 */
1310 QString QtxResourceMgr::option( const QString& opt ) const
1311 {
1312   QString val;
1313   if ( myOptions.contains( opt ) )
1314     val = myOptions[opt];
1315   return val;
1316 }
1317
1318 /*!
1319   \brief Sets the string value for the specified option.
1320   \param opt - Option name.
1321   \param val - Option value.
1322 */
1323 void QtxResourceMgr::setOption( const QString& opt, const QString& val )
1324 {
1325   myOptions.insert( opt, val );
1326 }
1327
1328 /*!
1329   \brief Load the all resources from the resource files.
1330 */
1331 bool QtxResourceMgr::load()
1332 {
1333   initialize( false );
1334
1335   Format* fmt = format( currentFormat() );
1336   if ( !fmt )
1337     return false;
1338
1339   bool res = true;
1340   for ( ResListIterator it( myResources ); it.current(); ++it )
1341     res = fmt->load( it.current() ) && res;
1342
1343   return res;
1344 }
1345
1346 /*!
1347   \brief Save the changed resources in to the user resource file.
1348 */
1349 bool QtxResourceMgr::save()
1350 {
1351   initialize( false );
1352
1353   Format* fmt = format( currentFormat() );
1354   if ( !fmt )
1355     return false;
1356
1357   if ( myResources.isEmpty() )
1358     return true;
1359
1360   return fmt->save( myResources.getFirst() );
1361 }
1362
1363 /*!
1364   \brief Returns the string list of the existing section names..
1365 */
1366 QStringList QtxResourceMgr::sections() const
1367 {
1368   initialize();
1369
1370   QMap<QString, int> map;
1371   for ( ResListIterator it( myResources ); it.current(); ++it )
1372   {
1373     QStringList lst = it.current()->sections();
1374     for ( QStringList::const_iterator itr = lst.begin(); itr != lst.end(); ++itr )
1375       map.insert( *itr, 0 );
1376   }
1377
1378   QStringList res;
1379   for ( QMap<QString, int>::ConstIterator iter = map.begin(); iter != map.end(); ++iter )
1380     res.append( iter.key() );
1381
1382   return res;
1383 }
1384
1385 /*!
1386   \brief Returns the string list of the existing resource names in the specified section.
1387   \param sec - Resource section name.
1388 */
1389 QStringList QtxResourceMgr::parameters( const QString& sec ) const
1390 {
1391   initialize();
1392
1393 #if defined(QTX_NO_INDEXED_MAP)
1394   typedef QMap<QString, int> PMap;
1395 #else
1396   typedef IMap<QString, int> PMap;
1397 #endif
1398   PMap pmap;
1399   ResListIterator it( myResources );
1400   it.toLast();
1401   for ( ; it.current(); --it ) {
1402     QStringList lst = it.current()->parameters( sec );
1403     for ( QStringList::const_iterator itr = lst.begin(); itr != lst.end(); ++itr )
1404       pmap.insert( *itr, 0, false );
1405   }
1406
1407   QStringList res;
1408   for ( PMap::ConstIterator iter = pmap.begin(); iter != pmap.end(); ++iter )
1409     res.append( iter.key() );
1410
1411   return res;
1412 }
1413
1414 QString QtxResourceMgr::path( const QString& sect, const QString& prefix, const QString& name ) const
1415 {
1416   QString res;
1417   for ( ResListIterator it( myResources ); it.current() && res.isEmpty(); ++it )
1418     res = it.current()->path( sect, prefix, name );
1419   return res;
1420 }
1421
1422 QString QtxResourceMgr::resSection() const
1423 {
1424   QString res = option( "res_section_name" );
1425   if ( res.isEmpty() )
1426     res = QString( "resources" );
1427   return res;
1428 }
1429
1430 QString QtxResourceMgr::langSection() const
1431 {
1432   QString res = option( "lang_section_name" );
1433   if ( res.isEmpty() )
1434     res = QString( "language" );
1435   return res;
1436 }
1437
1438 QPixmap QtxResourceMgr::defaultPixmap() const
1439 {
1440   return myDefaultPix;
1441 }
1442
1443 void QtxResourceMgr::setDefaultPixmap( const QPixmap& pix )
1444 {
1445   myDefaultPix = pix;
1446 }
1447
1448 QPixmap QtxResourceMgr::loadPixmap( const QString& prefix, const QString& name ) const
1449 {
1450   return loadPixmap( prefix, name, true );
1451 }
1452
1453 QPixmap QtxResourceMgr::loadPixmap( const QString& prefix, const QString& name, const bool useDef ) const
1454 {
1455   return loadPixmap( prefix, name, useDef ? defaultPixmap() : QPixmap() );
1456 }
1457
1458 QPixmap QtxResourceMgr::loadPixmap( const QString& prefix, const QString& name, const QPixmap& defPix ) const
1459 {
1460   initialize();
1461
1462   QPixmap pix;
1463   for ( ResListIterator it( myResources ); it.current() && pix.isNull(); ++it )
1464     pix = it.current()->loadPixmap( resSection(), prefix, name );
1465   if ( pix.isNull() )
1466     pix = defPix;
1467   return pix;
1468 }
1469
1470 void QtxResourceMgr::loadLanguage( const QString& pref, const QString& l )
1471 {
1472   initialize();
1473
1474   QMap<QChar, QString> substMap;
1475   substMap.insert( 'A', appName() );
1476
1477   QString lang = l;
1478   if ( lang.isEmpty() )
1479     value( langSection(), "language", lang );
1480
1481   if ( lang.isEmpty() )
1482   {
1483     lang = QString( "en" );
1484     qWarning( QString( "Language not specified. Assumed: %1" ).arg( lang ) );
1485   }
1486
1487   substMap.insert( 'L', lang );
1488
1489   QString trs;
1490   if ( value( langSection(), "translators", trs, false ) && !trs.isEmpty() )
1491   {
1492     QStringList translators    = QStringList::split( "|", option( "translators" ) );
1493     QStringList newTranslators = QStringList::split( "|", trs );
1494     for ( uint i = 0; i < newTranslators.count(); i++ )
1495       if ( translators.find( newTranslators[i] ) == translators.end() )
1496         translators += newTranslators[i];
1497     setOption( "translators", translators.join( "|" ) );
1498   }
1499
1500   QStringList trList = QStringList::split( "|", option( "translators" ) );
1501   if ( trList.isEmpty() )
1502   {
1503     trList.append( "%P_msg_%L.qm" );
1504     qWarning( QString( "Translators not defined. Assumed: %1" ).arg( trList.first() ) );
1505   }
1506
1507   QStringList prefixList;
1508   if ( !pref.isEmpty() )
1509     prefixList.append( pref );
1510   else
1511     prefixList = parameters( resSection() );
1512
1513   for ( QStringList::const_iterator iter = prefixList.begin(); iter != prefixList.end(); ++iter )
1514   {
1515     QString prefix = *iter;
1516     substMap.insert( 'P', prefix );
1517
1518     QStringList trs;
1519     for ( QStringList::const_iterator it = trList.begin(); it != trList.end(); ++it )
1520       trs.append( substMacro( *it, substMap ).stripWhiteSpace() );
1521
1522     loadTranslators( prefix, trs );
1523   }
1524 }
1525
1526 void QtxResourceMgr::loadTranslators( const QString& prefix, const QStringList& translators )
1527 {
1528   initialize();
1529
1530   QTranslator* trans = 0;
1531   ResListIterator it( myResources );
1532   it.toLast();
1533   for ( ; it.current(); --it )
1534   {
1535     for ( QStringList::const_iterator itr = translators.begin(); itr != translators.end(); ++itr )
1536     {
1537       trans = it.current()->loadTranslator( resSection(), prefix, *itr );
1538       if ( trans )
1539       {
1540         if ( !myTranslator[prefix].contains( trans ) )
1541           myTranslator[prefix].append( trans );
1542         qApp->installTranslator( trans );
1543       }
1544     }
1545   }
1546 }
1547
1548 void QtxResourceMgr::loadTranslator( const QString& prefix, const QString& name )
1549 {
1550   initialize();
1551
1552   QTranslator* trans = 0;
1553   ResListIterator it( myResources );
1554   it.toLast();
1555   for ( ; it.current(); --it )
1556   {
1557     trans = it.current()->loadTranslator( resSection(), prefix, name );
1558     if ( trans )
1559     {
1560       if ( !myTranslator[prefix].contains( trans ) )
1561         myTranslator[prefix].append( trans );
1562       qApp->installTranslator( trans );
1563     }
1564   }
1565 }
1566
1567 void QtxResourceMgr::removeTranslators( const QString& prefix )
1568 {
1569   if ( !myTranslator.contains( prefix ) )
1570     return;
1571
1572   for ( TransListIterator it( myTranslator[prefix] ); it.current(); ++it )
1573   {
1574     qApp->removeTranslator( it.current() );
1575     delete it.current();
1576   }
1577
1578   myTranslator.remove( prefix );
1579 }
1580
1581 void QtxResourceMgr::raiseTranslators( const QString& prefix )
1582 {
1583   if ( !myTranslator.contains( prefix ) )
1584     return;
1585
1586   for ( TransListIterator it( myTranslator[prefix] ); it.current(); ++it )
1587   {
1588     qApp->removeTranslator( it.current() );
1589     qApp->installTranslator( it.current() );
1590   }
1591 }
1592
1593 void QtxResourceMgr::refresh()
1594 {
1595   QStringList sl = sections();
1596   for ( QStringList::const_iterator it = sl.begin(); it != sl.end(); ++it )
1597   {
1598     QStringList pl = parameters( *it );
1599     for ( QStringList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr )
1600       setResource( *it, *itr, stringValue( *it, *itr ) );
1601   }
1602 }
1603
1604 void QtxResourceMgr::setDirList( const QStringList& dl )
1605 {
1606   myDirList = dl;
1607   for ( ResListIterator it( myResources ); it.current(); ++it )
1608     delete it.current();
1609
1610   myResources.clear();
1611 }
1612
1613 void QtxResourceMgr::setResource( const QString& sect, const QString& name, const QString& val )
1614 {
1615   initialize();
1616
1617   if ( !myResources.isEmpty() )
1618     myResources.first()->setValue( sect, name, val );
1619 }
1620
1621 QString QtxResourceMgr::userFileName( const QString& appName ) const
1622 {
1623   QString fileName;
1624   QString pathName = QDir::homeDirPath();
1625
1626 #ifdef WIN32
1627   fileName = QString( "%1.%2" ).arg( appName ).arg( currentFormat() );
1628 #else
1629   fileName = QString( ".%1rc" ).arg( appName );
1630 #endif
1631
1632   if ( !fileName.isEmpty() )
1633     pathName = Qtx::addSlash( pathName ) + fileName;
1634
1635   return pathName;
1636 }
1637
1638 QString QtxResourceMgr::globalFileName( const QString& appName ) const
1639 {
1640   return QString( "%1.%2" ).arg( appName ).arg( currentFormat() );
1641 }
1642
1643 QString QtxResourceMgr::substMacro( const QString& src, const QMap<QChar, QString>& substMap ) const
1644 {
1645   QString trg = src;
1646
1647   QRegExp rx( "%[A-Za-z%]" );
1648
1649   int idx = 0;
1650   while ( ( idx = rx.search( trg, idx ) ) >= 0 )
1651   {
1652     QChar spec = trg.at( idx + 1 );
1653     QString subst;
1654     if ( spec == '%' )
1655       subst = "%";
1656     else if ( substMap.contains( spec ) )
1657       subst = substMap[spec];
1658
1659     if ( !subst.isEmpty() )
1660     {
1661       trg.replace( idx, rx.matchedLength(), subst );
1662       idx += subst.length();
1663     }
1664     else
1665       idx += rx.matchedLength();
1666   }
1667
1668   return trg;
1669 }