1 // Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 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.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 // File: QtxResourceMgr.cxx
24 // Author: Alexander SOLOVYOV, Sergey TELKOV
26 #include "QtxResourceMgr.h"
27 #include "QtxTranslator.h"
34 #include <QTextStream>
35 #include <QApplication>
36 #include <QLibraryInfo>
39 #include <QDomDocument>
40 #include <QDomElement>
47 \class QtxResourceMgr::Resources
49 \brief Represents container for settings read from the resource file.
52 class QtxResourceMgr::Resources
55 Resources( QtxResourceMgr*, const QString& );
59 void setFile( const QString& );
61 QString value( const QString&, const QString&, const bool ) const;
62 void setValue( const QString&, const QString&, const QString& );
64 bool hasSection( const QString& ) const;
65 bool hasValue( const QString&, const QString& ) const;
67 void removeSection( const QString& );
68 void removeValue( const QString&, const QString& );
70 QPixmap loadPixmap( const QString&, const QString&, const QString& ) const;
71 QTranslator* loadTranslator( const QString&, const QString&, const QString& ) const;
73 QString makeSubstitution( const QString&, const QString&, const QString& ) const;
77 QStringList sections() const;
78 QStringList parameters( const QString& ) const;
80 QString path( const QString&, const QString&, const QString& ) const;
83 QtxResourceMgr* resMgr() const;
86 Section section( const QString& );
87 const Section section( const QString& ) const;
89 QString fileName( const QString&, const QString&, const QString& ) const;
92 typedef QMap<QString, Section> SectionMap;
95 QtxResourceMgr* myMgr; //!< resources manager
96 SectionMap mySections; //!< sections map
97 QString myFileName; //!< resources file name
98 QMap<QString,QPixmap> myPixmapCache; //!< pixmaps cache
100 friend class QtxResourceMgr::Format;
105 \param mgr parent resources manager
106 \param fileName resources file name
108 QtxResourceMgr::Resources::Resources( QtxResourceMgr* mgr, const QString& fileName )
110 myFileName( fileName )
117 QtxResourceMgr::Resources::~Resources()
122 \brief Get resources file name.
124 This file is used to load/save operations.
129 QString QtxResourceMgr::Resources::file() const
135 \brief Set resources file name.
139 void QtxResourceMgr::Resources::setFile( const QString& fn )
145 \brief Get string representation of parameter value.
146 \param sect section name
147 \param name parameter name
148 \param subst if \c true, perform variables substitution
149 \return parameter value or null QString if there is no such parameter
150 \sa setValue(), makeSubstitution()
152 QString QtxResourceMgr::Resources::value( const QString& sect, const QString& name, const bool subst ) const
156 if ( hasValue( sect, name ) )
158 val = section( sect )[name];
160 val = makeSubstitution( val, sect, name );
166 \brief Set parameter value.
167 \param sect section name
168 \param name parameter name
169 \param val parameter value
170 \sa value(), makeSubstitution()
172 void QtxResourceMgr::Resources::setValue( const QString& sect, const QString& name, const QString& val )
174 if ( !mySections.contains( sect ) )
175 mySections.insert( sect, Section() );
177 mySections[sect].insert( name, val );
181 \brief Check section existence.
182 \param sect section name
183 \return \c true if section exists
185 bool QtxResourceMgr::Resources::hasSection( const QString& sect ) const
187 return mySections.contains( sect );
191 \brief Check parameter existence.
192 \param sect section name
193 \param name parameter name
194 \return \c true if parameter exists in specified section
196 bool QtxResourceMgr::Resources::hasValue( const QString& sect, const QString& name ) const
198 return hasSection( sect ) && section( sect ).contains( name );
202 \brief Remove resourcs section.
203 \param sect secton name
205 void QtxResourceMgr::Resources::removeSection( const QString& sect )
207 mySections.remove( sect );
211 \brief Remove parameter from the section.
212 \param sect section name
213 \param name parameter name
215 void QtxResourceMgr::Resources::removeValue( const QString& sect, const QString& name )
217 if ( !mySections.contains( sect ) )
220 mySections[sect].remove( name );
222 if ( mySections[sect].isEmpty() )
223 mySections.remove( sect );
227 \brief Remove all sections.
229 void QtxResourceMgr::Resources::clear()
235 \brief Get all sections names.
236 \return list of section names
238 QStringList QtxResourceMgr::Resources::sections() const
240 return mySections.keys();
244 \brief Get all parameters name in specified section.
245 \param sec section name
246 \return list of settings names
248 QStringList QtxResourceMgr::Resources::parameters( const QString& sec ) const
250 if ( !hasSection( sec ) )
251 return QStringList();
253 return section( sec ).keys();
257 \brief Get absolute path to the file which name is defined by the parameter.
259 The file name is defined by \a name argument, while directory name is retrieved
260 from resources parameter \a prefix of section \a sec. Both directory and file name
261 can be relative. If the directory is relative, it is calculated from the initial
262 resources file name (see file()). Directory parameter can contain environment
263 variables, which are substituted automatically.
265 \param sec section name
266 \param prefix parameter containing directory name
267 \param name file name
268 \return absolute file path or null QString if file does not exist
269 \sa fileName(), file(), makeSubstitution()
271 QString QtxResourceMgr::Resources::path( const QString& sec, const QString& prefix, const QString& name ) const
273 QString filePath = fileName( sec, prefix, name );
274 if ( !filePath.isEmpty() )
276 if ( !QFileInfo( filePath ).exists() )
277 filePath = QString();
283 \brief Get resource manager
284 \return resource manager pointer
286 QtxResourceMgr* QtxResourceMgr::Resources::resMgr() const
292 \brief Get resources section by specified name.
294 If section does not exist it is created (empty).
296 \param sn section name
297 \return resources section
299 QtxResourceMgr::Section QtxResourceMgr::Resources::section( const QString& sn )
301 if ( !mySections.contains( sn ) )
302 mySections.insert( sn, Section() );
304 return mySections[sn];
308 \brief Get resources section by specified name.
309 \param sn section name
310 \return resources section
312 const QtxResourceMgr::Section QtxResourceMgr::Resources::section( const QString& sn ) const
314 return mySections[sn];
318 \brief Get file path.
320 The file name is defined by \a name argument, while directory name is retrieved
321 from resources parameter \a prefix of section \a sec. Both directory and file name
322 can be relative. If the directory is relative, it is calculated from the initial
323 resources file name (see file()). Directory parameter can contain environment
324 variables, which are substituted automatically.
325 File existence is not checked.
327 \param sec section name
328 \param prefix parameter containing directory name
329 \param name file name
330 \return absolute file path or null QString if \a prefix parameter
331 does not exist in section \sec
332 \sa path(), file(), makeSubstitution()
334 QString QtxResourceMgr::Resources::fileName( const QString& sect, const QString& prefix, const QString& name ) const
337 if ( hasValue( sect, prefix ) )
339 path = value( sect, prefix, true );
340 if ( !path.isEmpty() )
342 if ( QFileInfo( path ).isRelative() )
343 path = Qtx::addSlash( Qtx::dir( myFileName, true ) ) + path;
345 path = Qtx::addSlash( path ) + name;
348 if( !path.isEmpty() )
350 QString fname = QDir::convertSeparators( path );
351 QFileInfo inf( fname );
352 fname = inf.absoluteFilePath();
359 \brief Load and return pixmap from external file.
361 If QtxResourceMgr::isPixmapCached() is \c true then cached pixmap is returned
362 (if it is already loaded), otherwise it is loaded from file.
363 If the file name is invalid, null pixmap is returned.
365 \param sect section name
366 \param prefix parameter containing resources directory name
367 \param name pixmap file name
368 \return pixmap loaded from file
370 QPixmap QtxResourceMgr::Resources::loadPixmap( const QString& sect, const QString& prefix, const QString& name ) const
372 QString fname = fileName( sect, prefix, name );
373 bool toCache = resMgr() ? resMgr()->isPixmapCached() : false;
375 if( toCache && myPixmapCache.contains( fname ) )
376 p = myPixmapCache[fname];
381 ( ( QMap<QString,QPixmap>& )myPixmapCache ).insert( fname, p );
387 \brief Load translator.
388 \param sect section name
389 \param prefix parameter containing resources directory
390 \param name translation file name
391 \return just created and loaded translator or 0 in case of error
393 QTranslator* QtxResourceMgr::Resources::loadTranslator( const QString& sect, const QString& prefix, const QString& name ) const
395 QTranslator* trans = new QtxTranslator( 0 );
396 QString fname = QDir::convertSeparators( fileName( sect, prefix, name ) );
397 if ( !trans->load( Qtx::file( fname, false ), Qtx::dir( fname ) ) )
406 \brief Substitute variables by their values.
408 Environment variable is substituted by its value. For other variables resource
409 manager tries to find value among defined resources parameters.
411 \param str string to be processed
412 \param sect section, where variables are searched
413 \param name name of variable which must be ignored during substitution
414 \return processed string (with all substitutions made)
416 QString QtxResourceMgr::Resources::makeSubstitution( const QString& str, const QString& sect, const QString& name ) const
420 QMap<QString, int> ignoreMap;
421 ignoreMap.insert( name, 0 );
423 int start( 0 ), len( 0 );
426 QString envName = Qtx::findEnvVar( res, start, len );
427 if ( envName.isNull() )
431 if ( ::getenv( envName.toLatin1() ) )
432 newStr = QString( ::getenv( envName.toLatin1() ) );
434 if ( newStr.isNull() )
436 if ( ignoreMap.contains( envName ) )
442 if ( hasValue( sect, envName ) )
443 newStr = value( sect, envName, false );
444 ignoreMap.insert( envName, 0 );
446 res.replace( start, len, newStr );
449 res.replace( "$$", "$" );
450 res.replace( "%%", "%" );
456 \class QtxResourceMgr::IniFormat
458 \brief Reader/writer for .ini resources files.
461 class QtxResourceMgr::IniFormat : public Format
468 virtual bool load( const QString&, QMap<QString, Section>& );
469 virtual bool save( const QString&, const QMap<QString, Section>& );
472 bool load( const QString&, QMap<QString, Section>&, QSet<QString>& );
478 QtxResourceMgr::IniFormat::IniFormat()
486 QtxResourceMgr::IniFormat::~IniFormat()
491 \brief Load resources from ini-file.
492 \param fname resources file name
493 \param secMap resources map to be filled in
494 \return \c true on success and \c false on error
496 bool QtxResourceMgr::IniFormat::load( const QString& fname, QMap<QString, Section>& secMap )
498 QSet<QString> importHistory;
499 return load( fname, secMap, importHistory );
504 \brief Load resources from xml-file.
505 \param fname resources file name
506 \param secMap resources map to be filled in
507 \param importHistory list of already imported resources files (to prevent import loops)
508 \return \c true on success or \c false on error
510 bool QtxResourceMgr::IniFormat::load( const QString& fname, QMap<QString, Section>& secMap, QSet<QString>& importHistory )
512 QString aFName = fname.trimmed();
513 if ( !QFileInfo( aFName ).exists() )
515 if ( QFileInfo( aFName + ".ini" ).exists() )
517 else if ( QFileInfo( aFName + ".INI" ).exists() )
520 return false; // file does not exist
522 QFileInfo aFinfo( aFName );
523 aFName = aFinfo.canonicalFilePath();
525 if ( !importHistory.contains( aFName ) )
526 importHistory.insert( aFName );
528 return true; // already imported (prevent import loops)
530 QFile file( aFName );
531 if ( !file.open( QFile::ReadOnly ) )
532 return false; // file is not accessible
534 QTextStream ts( &file );
541 QString separator = option( "separator" );
542 if ( separator.isNull() )
543 separator = QString( "=" );
545 QString comment = option( "comment" );
546 if ( comment.isNull() )
547 comment = QString( "#" );
551 data = ts.readLine();
557 data = data.trimmed();
558 if ( data.isEmpty() )
561 if ( data.startsWith( comment ) )
564 QRegExp rx( "^\\[([\\w\\s\\._]*)\\]$" );
565 if ( rx.indexIn( data ) != -1 )
567 section = rx.cap( 1 );
568 if ( section.isEmpty() )
571 qWarning() << "QtxResourceMgr: Empty section in line:" << line;
574 else if ( data.contains( separator ) && !section.isEmpty() )
576 int pos = data.indexOf( separator );
577 QString key = data.left( pos ).trimmed();
578 QString val = data.mid( pos + 1 ).trimmed();
579 secMap[section].insert( key, val );
581 else if ( section == "import" )
583 QString impFile = QDir::convertSeparators( Qtx::makeEnvVarSubst( data, Qtx::Always ) );
584 QFileInfo impFInfo( impFile );
585 if ( impFInfo.isRelative() )
586 impFInfo.setFile( aFinfo.absoluteDir(), impFile );
588 QMap<QString, Section> impMap;
589 if ( !load( impFInfo.absoluteFilePath(), impMap, importHistory ) )
591 qDebug() << "QtxResourceMgr: Error with importing file:" << data;
595 QMap<QString, Section>::const_iterator it = impMap.constBegin();
596 for ( ; it != impMap.constEnd() ; ++it )
598 if ( !secMap.contains( it.key() ) )
600 // insert full section
601 secMap.insert( it.key(), it.value() );
605 // insert all parameters from the section
606 Section::ConstIterator paramIt = it.value().begin();
607 for ( ; paramIt != it.value().end() ; ++paramIt )
609 if ( !secMap[it.key()].contains( paramIt.key() ) )
610 secMap[it.key()].insert( paramIt.key(), paramIt.value() );
619 if ( section.isEmpty() )
620 qWarning() << "QtxResourceMgr: Current section is empty";
622 qWarning() << "QtxResourceMgr: Error in line:" << line;
632 \brief Save resources to the ini-file.
633 \param fname resources file name
634 \param secMap resources map
635 \return \c true on success and \c false on error
637 bool QtxResourceMgr::IniFormat::save( const QString& fname, const QMap<QString, Section>& secMap )
639 if ( !Qtx::mkDir( QFileInfo( fname ).absolutePath() ) )
643 if ( !file.open( QFile::WriteOnly ) )
646 QTextStream ts( &file );
648 ts << "# This file is automatically created by SALOME application." << endl;
649 ts << "# Changes made in this file can be lost!" << endl;
653 for ( QMap<QString, Section>::ConstIterator it = secMap.begin(); it != secMap.end() && res; ++it )
655 QStringList data( QString( "[%1]" ).arg( it.key() ) );
656 for ( Section::ConstIterator iter = it.value().begin(); iter != it.value().end(); ++iter )
657 data.append( iter.key() + " = " + iter.value() );
660 for ( QStringList::ConstIterator itr = data.begin(); itr != data.end(); ++itr )
670 \class QtxResourceMgr::XmlFormat
672 \brief Reader/writer for .xml resources files.
675 class QtxResourceMgr::XmlFormat : public Format
682 virtual bool load( const QString&, QMap<QString, Section>& );
683 virtual bool save( const QString&, const QMap<QString, Section>& );
686 QString docTag() const;
687 QString sectionTag() const;
688 QString parameterTag() const;
689 QString importTag() const;
690 QString nameAttribute() const;
691 QString valueAttribute() const;
693 bool load( const QString&, QMap<QString, Section>&, QSet<QString>& );
699 QtxResourceMgr::XmlFormat::XmlFormat()
707 QtxResourceMgr::XmlFormat::~XmlFormat()
712 \brief Load resources from xml-file.
713 \param fname resources file name
714 \param secMap resources map to be filled in
715 \return \c true on success and \c false on error
717 bool QtxResourceMgr::XmlFormat::load( const QString& fname, QMap<QString, Section>& secMap )
719 QSet<QString> importHistory;
720 return load( fname, secMap, importHistory );
724 \brief Load resources from xml-file.
725 \param fname resources file name
726 \param secMap resources map to be filled in
727 \param importHistory list of already imported resources files (to prevent import loops)
728 \return \c true on success and \c false on error
730 bool QtxResourceMgr::XmlFormat::load( const QString& fname, QMap<QString, Section>& secMap, QSet<QString>& importHistory )
732 QString aFName = fname.trimmed();
733 if ( !QFileInfo( aFName ).exists() )
735 if ( QFileInfo( aFName + ".xml" ).exists() )
737 else if ( QFileInfo( aFName + ".XML" ).exists() )
740 return false; // file does not exist
742 QFileInfo aFinfo( aFName );
743 aFName = aFinfo.canonicalFilePath();
745 if ( !importHistory.contains( aFName ) )
746 importHistory.insert( aFName );
748 return true; // already imported (prevent import loops)
754 QFile file( aFName );
755 if ( !file.open( QFile::ReadOnly ) )
757 qDebug() << "QtxResourceMgr: File is not accessible:" << aFName;
763 res = doc.setContent( &file );
768 qDebug() << "QtxResourceMgr: File is empty:" << aFName;
772 QDomElement root = doc.documentElement();
773 if ( root.isNull() || root.tagName() != docTag() )
775 qDebug() << "QtxResourceMgr: Invalid root in file:" << aFName;
779 QDomNode sectNode = root.firstChild();
780 while ( res && !sectNode.isNull() )
782 res = sectNode.isElement();
785 QDomElement sectElem = sectNode.toElement();
786 if ( sectElem.tagName() == sectionTag() && sectElem.hasAttribute( nameAttribute() ) )
788 QString section = sectElem.attribute( nameAttribute() );
789 QDomNode paramNode = sectNode.firstChild();
790 while ( res && !paramNode.isNull() )
792 res = paramNode.isElement();
795 QDomElement paramElem = paramNode.toElement();
796 if ( paramElem.tagName() == parameterTag() &&
797 paramElem.hasAttribute( nameAttribute() ) && paramElem.hasAttribute( valueAttribute() ) )
799 QString paramName = paramElem.attribute( nameAttribute() );
800 QString paramValue = paramElem.attribute( valueAttribute() );
801 secMap[section].insert( paramName, paramValue );
805 qDebug() << "QtxResourceMgr: Invalid parameter element in file:" << aFName;
811 res = paramNode.isComment();
813 qDebug() << "QtxResourceMgr: Node is neither element nor comment in file:" << aFName;
816 paramNode = paramNode.nextSibling();
819 else if ( sectElem.tagName() == importTag() && sectElem.hasAttribute( nameAttribute() ) )
821 QString impFile = QDir::convertSeparators( Qtx::makeEnvVarSubst( sectElem.attribute( nameAttribute() ), Qtx::Always ) );
822 QFileInfo impFInfo( impFile );
823 if ( impFInfo.isRelative() )
824 impFInfo.setFile( aFinfo.absoluteDir(), impFile );
826 QMap<QString, Section> impMap;
827 if ( !load( impFInfo.absoluteFilePath(), impMap, importHistory ) )
829 qDebug() << "QtxResourceMgr: Error with importing file:" << sectElem.attribute( nameAttribute() );
833 QMap<QString, Section>::const_iterator it = impMap.constBegin();
834 for ( ; it != impMap.constEnd() ; ++it )
836 if ( !secMap.contains( it.key() ) )
838 // insert full section
839 secMap.insert( it.key(), it.value() );
843 // insert all parameters from the section
844 Section::ConstIterator paramIt = it.value().begin();
845 for ( ; paramIt != it.value().end() ; ++paramIt )
847 if ( !secMap[it.key()].contains( paramIt.key() ) )
848 secMap[it.key()].insert( paramIt.key(), paramIt.value() );
856 qDebug() << "QtxResourceMgr: Invalid section in file:" << aFName;
862 res = sectNode.isComment(); // if it's a comment -- let it be, pass it..
864 qDebug() << "QtxResourceMgr: Node is neither element nor comment in file:" << aFName;
867 sectNode = sectNode.nextSibling();
873 qDebug() << "QtxResourceMgr: File" << fname << "is loaded successfully";
878 \brief Save resources to the xml-file.
879 \param fname resources file name
880 \param secMap resources map
881 \return \c true on success and \c false on error
883 bool QtxResourceMgr::XmlFormat::save( const QString& fname, const QMap<QString, Section>& secMap )
889 if ( !Qtx::mkDir( QFileInfo( fname ).absolutePath() ) )
893 if ( !file.open( QFile::WriteOnly ) )
896 QDomDocument doc( docTag() );
897 QDomComment comment = doc.createComment( "\nThis file is automatically created by SALOME application.\nChanges made in this file can be lost!\n" );
898 doc.appendChild( comment );
899 QDomElement root = doc.createElement( docTag() );
900 doc.appendChild( root );
902 for ( QMap<QString, Section>::ConstIterator it = secMap.begin(); it != secMap.end(); ++it )
904 QDomElement sect = doc.createElement( sectionTag() );
905 sect.setAttribute( nameAttribute(), it.key() );
906 root.appendChild( sect );
907 for ( Section::ConstIterator iter = it.value().begin(); iter != it.value().end(); ++iter )
909 QDomElement val = doc.createElement( parameterTag() );
910 val.setAttribute( nameAttribute(), iter.key() );
911 val.setAttribute( valueAttribute(), iter.value() );
912 sect.appendChild( val );
916 QTextStream ts( &file );
917 QStringList docStr = doc.toString().split( "\n" );
918 for ( QStringList::ConstIterator itr = docStr.begin(); itr != docStr.end(); ++itr )
929 \brief Get document tag name
930 \return XML document tag name
932 QString QtxResourceMgr::XmlFormat::docTag() const
934 QString tag = option( "doc_tag" );
936 tag = QString( "document" );
941 \brief Get section tag name
942 \return XML section tag name
944 QString QtxResourceMgr::XmlFormat::sectionTag() const
946 QString tag = option( "section_tag" );
948 tag = QString( "section" );
953 \brief Get parameter tag name
954 \return XML parameter tag name
956 QString QtxResourceMgr::XmlFormat::parameterTag() const
958 QString tag = option( "parameter_tag" );
960 tag = QString( "parameter" );
965 \brief Get import tag name
966 \return XML import tag name
968 QString QtxResourceMgr::XmlFormat::importTag() const
970 QString tag = option( "import_tag" );
972 tag = QString( "import" );
977 \brief Get parameter tag's "name" attribute name
978 \return XML parameter tag's "name" attribute name
980 QString QtxResourceMgr::XmlFormat::nameAttribute() const
982 QString str = option( "name_attribute" );
984 str = QString( "name" );
989 \brief Get parameter tag's "value" attribute name
990 \return XML parameter tag's "value" attribute name
992 QString QtxResourceMgr::XmlFormat::valueAttribute() const
994 QString str = option( "value_attribute" );
996 str = QString( "value" );
1001 \class QtxResourceMgr::Format
1002 \brief Generic resources files reader/writer class.
1007 \param fmt format name (for example, "xml" or "ini")
1009 QtxResourceMgr::Format::Format( const QString& fmt )
1017 QtxResourceMgr::Format::~Format()
1022 \brief Get the format name.
1025 QString QtxResourceMgr::Format::format() const
1031 \brief Get options names.
1032 \return list of the format options
1034 QStringList QtxResourceMgr::Format::options() const
1036 return myOpt.keys();
1040 \brief Get the value of the option with specified name.
1042 If option doesn't exist then null QString is returned.
1044 \param opt option name
1045 \return option value
1047 QString QtxResourceMgr::Format::option( const QString& opt ) const
1050 if ( myOpt.contains( opt ) )
1056 \brief Set the value of the option with specified name.
1057 \param opt option name
1058 \param val option value
1060 void QtxResourceMgr::Format::setOption( const QString& opt, const QString& val )
1062 myOpt.insert( opt, val );
1066 \brief Load resources from the resource file.
1067 \param res resources object
1068 \return \c true on success and \c false on error
1070 bool QtxResourceMgr::Format::load( Resources* res )
1075 QMap<QString, Section> sections;
1076 bool status = load( res->myFileName, sections );
1078 res->mySections = sections;
1080 qDebug() << "QtxResourceMgr: Can't load resource file:" << res->myFileName;
1086 \brief Save resources to the resource file.
1087 \param res resources object
1088 \return \c true on success and \c false on error
1090 bool QtxResourceMgr::Format::save( Resources* res )
1095 Qtx::mkDir( Qtx::dir( res->myFileName ) );
1097 QtxResourceMgr* mgr = res->resMgr();
1098 QString name = mgr ? mgr->userFileName( mgr->appName(), false ) : res->myFileName;
1099 return save( name, res->mySections );
1103 \fn virtual bool QtxResourceMgr::Format::load( const QString& fname,
1104 QMap<QString, Section>& secMap )
1105 \brief Load resources from the specified resources file.
1107 Should be implemented in the successors.
1109 \param fname resources file name
1110 \param secMap resources map to be filled in
1111 \return \c true on success and \c false on error
1115 \fn virtual bool QtxResourceMgr::Format::save( const QString& fname,
1116 const QMap<QString, Section>& secMap )
1118 \brief Save resources to the specified resources file.
1120 Should be implemented in the successors.
1122 \param fname resources file name
1123 \param secMap resources map
1124 \return \c true on success and \c false on error
1128 \class QtxResourceMgr
1129 \brief Application resources manager.
1131 This class can be used to define settings, save/load settings and
1132 application preferences to the resource file(s), load translation files
1133 (internationalization mechanism), load pixmaps and other resources from
1134 external files, etc.
1136 Currently it supports .ini and .xml resources file formats. To implement
1137 own resources file format, inherit from the Format class and implement virtual
1138 Format::load() and Format::save() methods.
1140 Resources manager is initialized by the (symbolic) name of the application.
1141 The parameter \a resVarTemplate specifies the template for the environment
1142 variable which should point to the resource directory or list of directories.
1143 Environment variable name is calculated by substitution of "%1" substring in
1144 the \a resVarTemplate parameter (if it contains such substring) by the
1145 application name (\a appName).
1146 By default, \a resVarTemplate is set to "%1Resources". For example, if the application name
1147 is "MyApp", the environment variable "MyAppResources" will be inspected in this case.
1149 Resource manager can handle several global application configuration files and
1150 one user configuration file. Location of global configuration files is defined
1151 by the environment variable (see above) and these files are always read-only.
1152 The name of the global configuration files is retrieved by calling virtual method
1153 globalFileName() which can be redefined in the QtxResourceMgr class successors.
1154 User configuration file always situated in the user's home directory. It's name
1155 is defined by calling virtual method userFileName() which can be also redefined
1156 in the QtxResourceMgr class successors. This is the only file which the preferences
1157 changed by the user during the application session are written to (usually
1158 when the application closes).
1160 Resources environment variable should contain one or several resource directories
1161 (separated by ";" symbol on Windows and ":" or ";" on Linux). Each resource directory
1162 can contain application global configuration file. The user configuration file has
1163 the highest priority, for the global configuration files the priority is decreasing from
1164 left to right, i.e. the first directory in the directoris list, defined by the
1165 resources environment variable has higher priority. Priority has the meaning when
1166 searching requested resources (application preference, pixmap file name, translation
1169 When retrieving preferences, it is sometimes helpful to ignore values coming from the
1170 user preference file and take into account only global preferences.
1171 To do this, use setWorkingMode() method passing QtxResourceMgr::IgnoreUserValues enumerator
1174 Resources manager operates with such terms like options, sections and parameters.
1175 Parametets are named application resources, for example, application preferences like
1176 integer, double, boolean or string values, pictures, font and color definitions, etc.
1177 Parameters are organized inside the resources files into the named groups - sections.
1178 Options are special kind of resoures which allow customizing resource files interpreting.
1179 For example, by default language settings are defined in the resource file in the
1180 section "language". It is possible to change this section name by setting "language"
1181 option to another value (see setOption()).
1183 Retrieving preferences values can be done by using one of value() methods, each returns
1184 \c true if the corresponding preference is found. Another way is to use integerValue(),
1185 doubleValue(), etc methods, which allow specifying default value which is used if the
1186 specified preference is not found. Removing of preferences or sections can be done using
1187 remove(const QString& sect) or remove(const QString& sect, const QString& name) methods.
1188 To add the preference or to change exiting preference value use setValue() methods family.
1189 Methods hasSection() and hasValue() can be used to check existence of section or
1190 preference (in the specified section). List of all sections can be retrieved with the
1191 sections() method, and list of all settings names in some specified section can be
1192 obtained with parameters() method.
1194 Pixmaps can be loaded with the loadPixmap() methods. If the specified pixmap is not found,
1195 the default one is returned. Default pixmap can be set by setDefaultPixmap().
1197 One of the key feature of the resources manager is support of application
1198 internationalization mechanism. Translation files for the specified language can be loaded
1199 with loadLanguage() method.
1203 \brief Constructs the resource manager.
1204 \param appName application name
1205 \param resVarTemplate resource environment variable pattern
1207 QtxResourceMgr::QtxResourceMgr( const QString& appName, const QString& resVarTemplate )
1208 : myAppName( appName ),
1209 myCheckExist( true ),
1211 myIsPixmapCached( true ),
1212 myHasUserValues( true ),
1213 myWorkingMode( AllowUserValues )
1215 QString envVar = !resVarTemplate.isEmpty() ? resVarTemplate : QString( "%1Resources" );
1216 if ( envVar.contains( "%1" ) )
1217 envVar = envVar.arg( appName );
1220 if ( ::getenv( envVar.toLatin1() ) )
1221 dirs = ::getenv( envVar.toLatin1() );
1223 QString dirsep = ";"; // for Windows: ";" is used as directories separator
1225 QString dirsep = "[:|;]"; // for Linux: both ":" and ";" can be used
1227 setDirList( dirs.split( QRegExp( dirsep ), QString::SkipEmptyParts ) );
1229 installFormat( new XmlFormat() );
1230 installFormat( new IniFormat() );
1232 setOption( "translators", QString( "%P_msg_%L.qm|%P_images.qm" ) );
1238 Destroy the resource manager and free allocated memory.
1240 QtxResourceMgr::~QtxResourceMgr()
1242 QStringList prefList = myTranslator.keys();
1243 for ( QStringList::ConstIterator it = prefList.begin(); it != prefList.end(); ++it )
1244 removeTranslators( *it );
1246 qDeleteAll( myResources );
1247 qDeleteAll( myFormats );
1249 delete myDefaultPix;
1253 \brief Get the application name.
1254 \return application name
1256 QString QtxResourceMgr::appName() const
1262 \brief Get the "check existance" flag
1264 If this flag is \c true then preference can be set (with setValue() method)
1265 only if it doesn't exist or if the value is changed.
1267 \return \c true if "check existance" flag is set
1269 bool QtxResourceMgr::checkExisting() const
1271 return myCheckExist;
1275 \brief Set the "check existance" flag.
1276 \param on new flag value
1278 void QtxResourceMgr::setCheckExisting( const bool on )
1284 \brief Get the resource directories list.
1286 Home user directory (where the user application configuration file is situated)
1287 is not included. This is that directories list defined by the application
1288 resources environment variable.
1290 \return list of directories names
1292 QStringList QtxResourceMgr::dirList() const
1298 \brief Initialise resources manager.
1300 Prepare the resources containers and load resources (if \a autoLoad is \c true).
1302 \param autoLoad if \c true (default) then all resources are loaded
1304 void QtxResourceMgr::initialize( const bool autoLoad ) const
1306 if ( !myResources.isEmpty() )
1309 QtxResourceMgr* that = (QtxResourceMgr*)this;
1311 if ( !userFileName( appName() ).isEmpty() )
1312 that->myResources.append( new Resources( that, userFileName( appName() ) ) );
1314 that->myHasUserValues = myResources.count() > 0;
1316 for ( QStringList::ConstIterator it = myDirList.begin(); it != myDirList.end(); ++it )
1318 QString path = Qtx::addSlash( *it ) + globalFileName( appName() );
1319 that->myResources.append( new Resources( that, path ) );
1327 \brief Get "cached pixmaps" option value.
1329 Resources manager allows possibility to cache loaded pixmaps that allow to
1330 improve application performance. This feature is turned on by default - all
1331 loaded pixmaps are stored in the internal map. Switching of this feature on/off
1332 can be done by setIsPixmapCached() method.
1334 \return \c true if pixmap cache is turned on
1335 \sa setIsPixmapCached()
1337 bool QtxResourceMgr::isPixmapCached() const
1339 return myIsPixmapCached;
1343 \brief Switch "cached pixmaps" option on/off.
1344 \param on enable pixmap cache if \c true and disable it if \c false
1345 \sa isPixmapCached()
1347 void QtxResourceMgr::setIsPixmapCached( const bool on )
1349 myIsPixmapCached = on;
1353 \brief Remove all resources from the resources manager.
1355 void QtxResourceMgr::clear()
1357 for ( ResList::Iterator it = myResources.begin(); it != myResources.end(); ++it )
1362 \brief Get current working mode.
1364 \return current working mode
1365 \sa setWorkingMode(), value(), hasValue(), hasSection(), setValue()
1367 QtxResourceMgr::WorkingMode QtxResourceMgr::workingMode() const
1369 return myWorkingMode;
1373 \brief Set resource manager's working mode.
1375 The resource manager can operate in the following working modes:
1376 * AllowUserValues : methods values(), hasValue(), hasSection() take into account user values (default)
1377 * IgnoreUserValues : methods values(), hasValue(), hasSection() do not take into account user values
1379 Note, that setValue() method always put the value to the user settings file.
1381 \param mode new working mode
1382 \sa workingMode(), value(), hasValue(), hasSection(), setValue()
1384 void QtxResourceMgr::setWorkingMode( WorkingMode mode )
1386 myWorkingMode = mode;
1390 \brief Get interger parameter value.
1391 \param sect section name
1392 \param name parameter name
1393 \param iVal parameter to return resulting integer value
1394 \return \c true if parameter is found and \c false if parameter is not found
1395 (in this case \a iVal value is undefined)
1397 bool QtxResourceMgr::value( const QString& sect, const QString& name, int& iVal ) const
1400 if ( !value( sect, name, val, true ) )
1404 iVal = val.toInt( &ok );
1410 \brief Get double parameter value.
1411 \param sect section name
1412 \param name parameter name
1413 \param dVal parameter to return resulting double value
1414 \return \c true if parameter is found and \c false if parameter is not found
1415 (in this case \a dVal value is undefined)
1417 bool QtxResourceMgr::value( const QString& sect, const QString& name, double& dVal ) const
1420 if ( !value( sect, name, val, true ) )
1424 dVal = val.toDouble( &ok );
1430 \brief Get boolean parameter value.
1431 \param sect section name
1432 \param name parameter name
1433 \param bVal parameter to return resulting boolean value
1434 \return \c true if parameter is found and \c false if parameter is not found
1435 (in this case \a bVal value is undefined)
1437 bool QtxResourceMgr::value( const QString& sect, const QString& name, bool& bVal ) const
1440 if ( !value( sect, name, val, true ) )
1443 static QMap<QString, bool> boolMap;
1444 if ( boolMap.isEmpty() )
1446 boolMap["true"] = boolMap["yes"] = boolMap["on"] = true;
1447 boolMap["false"] = boolMap["no"] = boolMap["off"] = false;
1450 val = val.toLower();
1451 bool res = boolMap.contains( val );
1453 bVal = boolMap[val];
1456 double num = val.toDouble( &res );
1465 \brief Get color parameter value.
1466 \param sect section name
1467 \param name parameter name
1468 \param cVal parameter to return resulting color value
1469 \return \c true if parameter is found and \c false if parameter is not found
1470 (in this case \a cVal value is undefined)
1472 bool QtxResourceMgr::value( const QString& sect, const QString& name, QColor& cVal ) const
1475 if ( !value( sect, name, val, true ) )
1478 return Qtx::stringToColor( val, cVal );
1482 \brief Get font parameter value.
1483 \param sect section name
1484 \param name parameter name
1485 \param fVal parameter to return resulting font value
1486 \return \c true if parameter is found and \c false if parameter is not found
1487 (in this case \a fVal value is undefined)
1489 bool QtxResourceMgr::value( const QString& sect, const QString& name, QFont& fVal ) const
1492 if ( !value( sect, name, val, true ) )
1495 QStringList fontDescr = val.split( ",", QString::SkipEmptyParts );
1497 if ( fontDescr.count() < 2 )
1500 QString family = fontDescr[0];
1501 if ( family.isEmpty() )
1504 fVal = QFont( family );
1506 for ( int i = 1; i < (int)fontDescr.count(); i++ )
1508 QString curval = fontDescr[i].trimmed().toLower();
1509 if ( curval == QString( "bold" ) )
1510 fVal.setBold( true );
1511 else if ( curval == QString( "italic" ) )
1512 fVal.setItalic( true );
1513 else if ( curval == QString( "underline" ) )
1514 fVal.setUnderline( true );
1515 else if ( curval == QString( "shadow" ) || curval == QString( "overline" ) )
1516 fVal.setOverline( true );
1520 int ps = curval.toInt( &isOk );
1522 fVal.setPointSize( ps );
1530 \brief Get byte array parameter value.
1531 \param sect section name
1532 \param name parameter name
1533 \param baVal parameter to return resulting byte array value
1534 \return \c true if parameter is found and \c false if parameter is not found
1535 (in this case \a baVal value is undefined)
1537 bool QtxResourceMgr::value( const QString& sect, const QString& name, QByteArray& baVal ) const
1540 if ( !value( sect, name, val, true ) )
1544 QStringList lst = val.split( QRegExp( "[\\s|,]" ), QString::SkipEmptyParts );
1545 for ( QStringList::ConstIterator it = lst.begin(); it != lst.end(); ++it )
1549 if ( str.startsWith( "#" ) )
1555 int num = str.toInt( &ok, base );
1556 if ( !ok || num < 0 || num > 255 )
1559 baVal.append( (char)num );
1561 return !baVal.isEmpty();
1565 \brief Get linear gradient parameter value.
1566 \param sect section name
1567 \param name parameter name
1568 \param gVal parameter to return resulting linear gradient value
1569 \return \c true if parameter is found and \c false if parameter is not found
1570 (in this case \a gVal value is undefined)
1572 bool QtxResourceMgr::value( const QString& sect, const QString& name, QLinearGradient& gVal ) const
1575 if ( !value( sect, name, val, true ) )
1578 return Qtx::stringToLinearGradient( val, gVal );
1582 \brief Get radial gradient parameter value.
1583 \param sect section name
1584 \param name parameter name
1585 \param gVal parameter to return resulting radial gradient value
1586 \return \c true if parameter is found and \c false if parameter is not found
1587 (in this case \a gVal value is undefined)
1589 bool QtxResourceMgr::value( const QString& sect, const QString& name, QRadialGradient& gVal ) const
1592 if ( !value( sect, name, val, true ) )
1595 return Qtx::stringToRadialGradient( val, gVal );
1599 \brief Get conical gradient parameter value.
1600 \param sect section name
1601 \param name parameter name
1602 \param gVal parameter to return resulting conical gradient value
1603 \return \c true if parameter is found and \c false if parameter is not found
1604 (in this case \a gVal value is undefined)
1606 bool QtxResourceMgr::value( const QString& sect, const QString& name, QConicalGradient& gVal ) const
1609 if ( !value( sect, name, val, true ) )
1612 return Qtx::stringToConicalGradient( val, gVal );
1616 \brief Get background parameter value.
1617 \param sect section name
1618 \param name parameter name
1619 \param bgVal parameter to return resulting background value
1620 \return \c true if parameter is found and \c false if parameter is not found
1621 (in this case \a bgVal value is undefined)
1623 bool QtxResourceMgr::value( const QString& sect, const QString& name, Qtx::BackgroundData& bgVal ) const
1626 if ( !value( sect, name, val, true ) )
1629 bgVal = Qtx::stringToBackground( val );
1630 return bgVal.isValid();
1634 \brief Get string parameter value (native format).
1635 \param sect section name
1636 \param name parameter name
1637 \param val parameter to return resulting byte array value
1638 \param subst if \c true perform environment variables substitution
1639 \return \c true if parameter is found and \c false if parameter is not found
1640 (in this case \a val value is undefined)
1642 bool QtxResourceMgr::value( const QString& sect, const QString& name, QString& val, const bool subst ) const
1648 ResList::ConstIterator it = myResources.begin();
1649 if ( myHasUserValues && workingMode() == IgnoreUserValues )
1652 for ( ; it != myResources.end() && !ok; ++it )
1654 ok = (*it)->hasValue( sect, name );
1656 val = (*it)->value( sect, name, subst );
1663 \brief Get interger parameter value.
1665 If the specified parameter is not found or can not be converted to the integer value,
1666 the specified default value is returned instead.
1668 \param sect section name
1669 \param name parameter name
1670 \param def default value
1671 \return parameter value (or default value if parameter is not found)
1673 int QtxResourceMgr::integerValue( const QString& sect, const QString& name, const int def ) const
1676 if ( !value( sect, name, val ) )
1682 \brief Get double parameter value.
1684 If the specified parameter is not found or can not be converted to the double value,
1685 the specified default value is returned instead.
1687 \param sect section name
1688 \param name parameter name
1689 \param def default value
1690 \return parameter value (or default value if parameter is not found)
1692 double QtxResourceMgr::doubleValue( const QString& sect, const QString& name, const double def ) const
1695 if ( !value( sect, name, val ) )
1701 \brief Get boolean parameter value.
1703 If the specified parameter is not found or can not be converted to the boolean value,
1704 the specified default value is returned instead.
1706 \param sect section name
1707 \param name parameter name
1708 \param def default value
1709 \return parameter value (or default value if parameter is not found)
1711 bool QtxResourceMgr::booleanValue( const QString& sect, const QString& name, const bool def ) const
1714 if ( !value( sect, name, val ) )
1720 \brief Get font parameter value.
1722 If the specified parameter is not found or can not be converted to the font value,
1723 the specified default value is returned instead.
1725 \param sect section name
1726 \param name parameter name
1727 \param def default value
1728 \return parameter value (or default value if parameter is not found)
1730 QFont QtxResourceMgr::fontValue( const QString& sect, const QString& name, const QFont& def ) const
1733 if( !value( sect, name, font ) )
1739 \brief Get color parameter value.
1741 If the specified parameter is not found or can not be converted to the color value,
1742 the specified default value is returned instead.
1744 \param sect section name
1745 \param name parameter name
1746 \param def default value
1747 \return parameter value (or default value if parameter is not found)
1749 QColor QtxResourceMgr::colorValue( const QString& sect, const QString& name, const QColor& def ) const
1752 if ( !value( sect, name, val ) )
1758 \brief Get string parameter value.
1760 If the specified parameter is not found, the specified default value is returned instead.
1762 \param sect section name
1763 \param name parameter name
1764 \param def default value
1765 \return parameter value (or default value if parameter is not found)
1767 QString QtxResourceMgr::stringValue( const QString& sect, const QString& name, const QString& def ) const
1770 if ( !value( sect, name, val ) )
1776 \brief Get byte array parameter value.
1778 If the specified parameter is not found, the specified default value is returned instead.
1780 \param sect section name
1781 \param name parameter name
1782 \param def default value
1783 \return parameter value (or default value if parameter is not found)
1785 QByteArray QtxResourceMgr::byteArrayValue( const QString& sect, const QString& name, const QByteArray& def ) const
1788 if ( !value( sect, name, val ) )
1794 \brief Get linear gradient parameter value.
1796 If the specified parameter is not found, the specified default value is returned instead.
1798 \param sect section name
1799 \param name parameter name
1800 \param def default value
1801 \return parameter value (or default value if parameter is not found)
1803 QLinearGradient QtxResourceMgr::linearGradientValue( const QString& sect, const QString& name, const QLinearGradient& def ) const
1805 QLinearGradient val;
1806 if ( !value( sect, name, val ) )
1812 \brief Get radial gradient parameter value.
1814 If the specified parameter is not found, the specified default value is returned instead.
1816 \param sect section name
1817 \param name parameter name
1818 \param def default value
1819 \return parameter value (or default value if parameter is not found)
1821 QRadialGradient QtxResourceMgr::radialGradientValue( const QString& sect, const QString& name, const QRadialGradient& def ) const
1823 QRadialGradient val;
1824 if ( !value( sect, name, val ) )
1830 \brief Get conical gradient parameter value.
1832 If the specified parameter is not found, the specified default value is returned instead.
1834 \param sect section name
1835 \param name parameter name
1836 \param def default value
1837 \return parameter value (or default value if parameter is not found)
1839 QConicalGradient QtxResourceMgr::conicalGradientValue( const QString& sect, const QString& name, const QConicalGradient& def ) const
1841 QConicalGradient val;
1842 if ( !value( sect, name, val ) )
1848 \brief Get background parameter value.
1850 If the specified parameter is not found, the specified default value is returned instead.
1852 \param sect section name
1853 \param name parameter name
1854 \param def default value
1855 \return parameter value (or default value if parameter is not found)
1857 Qtx::BackgroundData QtxResourceMgr::backgroundValue( const QString& sect, const QString& name, const Qtx::BackgroundData& def ) const
1859 Qtx::BackgroundData val;
1860 if ( !value( sect, name, val ) )
1866 \brief Check parameter existence.
1867 \param sect section name
1868 \param name parameter name
1869 \return \c true if parameter exists in specified section
1871 bool QtxResourceMgr::hasValue( const QString& sect, const QString& name ) const
1877 ResList::ConstIterator it = myResources.begin();
1878 if ( myHasUserValues && workingMode() == IgnoreUserValues )
1881 for ( ; it != myResources.end() && !ok; ++it )
1882 ok = (*it)->hasValue( sect, name );
1888 \brief Check section existence.
1889 \param sect section name
1890 \return \c true if section exists
1892 bool QtxResourceMgr::hasSection( const QString& sect ) const
1898 ResList::ConstIterator it = myResources.begin();
1899 if ( myHasUserValues && workingMode() == IgnoreUserValues )
1902 for ( ; it != myResources.end() && !ok; ++it )
1903 ok = (*it)->hasSection( sect );
1909 \brief Set integer parameter value.
1910 \param sect section name
1911 \param name parameter name
1912 \param val parameter value
1914 void QtxResourceMgr::setValue( const QString& sect, const QString& name, int val )
1917 if ( checkExisting() && value( sect, name, res ) && res == val )
1920 setResource( sect, name, QString::number( val ) );
1924 \brief Set double parameter value.
1925 \param sect section name
1926 \param name parameter name
1927 \param val parameter value
1929 void QtxResourceMgr::setValue( const QString& sect, const QString& name, double val )
1932 if ( checkExisting() && value( sect, name, res ) && res == val )
1935 setResource( sect, name, QString::number( val, 'g', 12 ) );
1939 \brief Set boolean parameter value.
1940 \param sect section name
1941 \param name parameter name
1942 \param val parameter value
1944 void QtxResourceMgr::setValue( const QString& sect, const QString& name, bool val )
1947 if ( checkExisting() && value( sect, name, res ) && res == val )
1950 setResource( sect, name, QString( val ? "true" : "false" ) );
1954 \brief Set color parameter value.
1955 \param sect section name
1956 \param name parameter name
1957 \param val parameter value
1959 void QtxResourceMgr::setValue( const QString& sect, const QString& name, const QColor& val )
1962 if ( checkExisting() && value( sect, name, res ) && res == val )
1965 setResource( sect, name, Qtx::colorToString( val ) );
1969 \brief Set font parameter value.
1970 \param sect section name
1971 \param name parameter name
1972 \param val parameter value
1974 void QtxResourceMgr::setValue( const QString& sect, const QString& name, const QFont& val )
1977 if ( checkExisting() && value( sect, name, res ) && res == val )
1980 QStringList fontDescr;
1981 fontDescr.append( val.family() );
1983 fontDescr.append( "Bold" );
1985 fontDescr.append( "Italic" );
1986 if ( val.underline() )
1987 fontDescr.append( "Underline" );
1988 if ( val.overline() )
1989 fontDescr.append( "Overline" );
1990 fontDescr.append( QString( "%1" ).arg( val.pointSize() ) );
1992 setResource( sect, name, fontDescr.join( "," ) );
1996 \brief Set string parameter value.
1997 \param sect section name
1998 \param name parameter name
1999 \param val parameter value
2001 void QtxResourceMgr::setValue( const QString& sect, const QString& name, const QString& val )
2004 if ( checkExisting() && value( sect, name, res ) && res == val )
2007 setResource( sect, name, val );
2011 \brief Set byte array parameter value.
2012 \param sect section name
2013 \param name parameter name
2014 \param val parameter value
2016 void QtxResourceMgr::setValue( const QString& sect, const QString& name, const QByteArray& val )
2019 if ( checkExisting() && value( sect, name, res ) && res == val )
2024 for ( int i = 0; i < val.size(); i++ )
2026 ::sprintf( buf, "#%02X", (unsigned char)val.at( i ) );
2027 lst.append( QString( buf ) );
2029 setResource( sect, name, lst.join( " " ) );
2033 \brief Set linear gradient parameter value.
2034 \param sect section name
2035 \param name parameter name
2036 \param val parameter value
2038 void QtxResourceMgr::setValue( const QString& sect, const QString& name, const QLinearGradient& val )
2040 QLinearGradient res;
2041 if ( checkExisting() && value( sect, name, res ) && res == val )
2044 setResource( sect, name, Qtx::gradientToString( val ) );
2048 \brief Set radial gradient parameter value.
2049 \param sect section name
2050 \param name parameter name
2051 \param val parameter value
2053 void QtxResourceMgr::setValue( const QString& sect, const QString& name, const QRadialGradient& val )
2055 QRadialGradient res;
2056 if ( checkExisting() && value( sect, name, res ) && res == val )
2059 setResource( sect, name, Qtx::gradientToString( val ) );
2063 \brief Set conical gradient parameter value.
2064 \param sect section name
2065 \param name parameter name
2066 \param val parameter value
2068 void QtxResourceMgr::setValue( const QString& sect, const QString& name, const QConicalGradient& val )
2070 QConicalGradient res;
2071 if ( checkExisting() && value( sect, name, res ) && res == val )
2074 setResource( sect, name, Qtx::gradientToString( val ) );
2078 \brief Set background parameter value.
2079 \param sect section name
2080 \param name parameter name
2081 \param val parameter value
2083 void QtxResourceMgr::setValue( const QString& sect, const QString& name, const Qtx::BackgroundData& val )
2085 Qtx::BackgroundData res;
2086 if ( checkExisting() && value( sect, name, res ) && res == val )
2089 setResource( sect, name, Qtx::backgroundToString( val ) );
2093 \brief Remove resources section.
2094 \param sect section name
2096 void QtxResourceMgr::remove( const QString& sect )
2100 for ( ResList::Iterator it = myResources.begin(); it != myResources.end(); ++it )
2101 (*it)->removeSection( sect );
2105 \brief Remove the specified parameter.
2106 \param sect section name
2107 \param name parameter name
2109 void QtxResourceMgr::remove( const QString& sect, const QString& name )
2113 for ( ResList::Iterator it = myResources.begin(); it != myResources.end(); ++it )
2114 (*it)->removeValue( sect, name );
2118 \brief Get current configuration files format.
2119 \return configuration files format name
2121 QString QtxResourceMgr::currentFormat() const
2124 if ( !myFormats.isEmpty() )
2125 fmt = myFormats[0]->format();
2130 \brief Set current configuration files format.
2131 \param fmt configuration files format name
2133 void QtxResourceMgr::setCurrentFormat( const QString& fmt )
2135 Format* form = format( fmt );
2139 myFormats.removeAll( form );
2140 myFormats.prepend( form );
2142 if ( myResources.isEmpty() )
2145 ResList::Iterator resIt = myResources.begin();
2146 if ( myResources.count() > myDirList.count() && resIt != myResources.end() )
2148 (*resIt)->setFile( userFileName( appName() ) );
2152 for ( QStringList::ConstIterator it = myDirList.begin(); it != myDirList.end() && resIt != myResources.end(); ++it, ++resIt )
2153 (*resIt)->setFile( Qtx::addSlash( *it ) + globalFileName( appName() ) );
2157 \brief Get configuration files format by specified format name.
2158 \param fmt configuration files format name
2159 \return format object or 0 if format is not defined
2161 QtxResourceMgr::Format* QtxResourceMgr::format( const QString& fmt ) const
2164 for ( FormatList::ConstIterator it = myFormats.begin(); it != myFormats.end() && !form; ++it )
2166 if ( (*it)->format() == fmt )
2174 \brief Install configuration files format.
2176 Added format becomes current.
2178 \param form format object to be installed
2180 void QtxResourceMgr::installFormat( QtxResourceMgr::Format* form )
2182 if ( !myFormats.contains( form ) )
2183 myFormats.prepend( form );
2187 \brief Remove configuration files format.
2188 \param form format object to be uninstalled
2190 void QtxResourceMgr::removeFormat( QtxResourceMgr::Format* form )
2192 myFormats.removeAll( form );
2196 \brief Get resource format options names.
2197 \return list of options names
2199 QStringList QtxResourceMgr::options() const
2201 return myOptions.keys();
2205 \brief Get the string value of the specified resources format option.
2207 If option does not exist, null QString is returned.
2209 \param opt option name
2210 \return option value
2211 \sa setOption(), options()
2213 QString QtxResourceMgr::option( const QString& opt ) const
2216 if ( myOptions.contains( opt ) )
2217 val = myOptions[opt];
2222 \brief Set the string value of the specified resources format option.
2223 \param opt option name
2224 \param val option value
2225 \sa option(), options()
2227 void QtxResourceMgr::setOption( const QString& opt, const QString& val )
2229 myOptions.insert( opt, val );
2233 \brief Load all resources from all resource files (global and user).
2234 \return \c true on success and \c false on error
2237 bool QtxResourceMgr::load()
2239 initialize( false );
2241 Format* fmt = format( currentFormat() );
2246 for ( ResList::Iterator it = myResources.begin(); it != myResources.end(); ++it )
2247 res = fmt->load( *it ) && res;
2253 \brief Import resources from specified resource file.
2254 \param fname resources file name
2255 \return \c true on success and \c false on error
2257 bool QtxResourceMgr::import( const QString& fname )
2259 Format* fmt = format( currentFormat() );
2263 if ( myResources.isEmpty() || !myHasUserValues )
2266 Resources* r = myResources[0];
2270 QString old = r->file();
2271 r->setFile( fname );
2272 bool res = fmt->load( r );
2278 \brief Save all resources to the user resource files.
2279 \return \c true on success and \c false on error
2281 bool QtxResourceMgr::save()
2283 initialize( false );
2285 Format* fmt = format( currentFormat() );
2289 if ( myResources.isEmpty() || !myHasUserValues )
2292 return fmt->save( myResources[0] );
2296 \brief Get all sections names.
2297 \return list of section names
2299 QStringList QtxResourceMgr::sections() const
2303 QMap<QString, int> map;
2305 ResList::ConstIterator it = myResources.begin();
2306 if ( myHasUserValues && workingMode() == IgnoreUserValues )
2309 for ( ; it != myResources.end(); ++it )
2311 QStringList lst = (*it)->sections();
2312 for ( QStringList::ConstIterator itr = lst.begin(); itr != lst.end(); ++itr )
2313 map.insert( *itr, 0 );
2320 \brief Get all sections names matching specified regular expression.
2321 \param re searched regular expression
2322 \return list of sections names
2324 QStringList QtxResourceMgr::sections(const QRegExp& re) const
2326 return sections().filter( re );
2330 \brief Get all sections names with the prefix specified by passed
2331 list of parent sections names.
2333 Sub-sections are separated inside the section name by the sections
2334 separator token, for example "splash:color:label".
2336 \param names parent sub-sections names
2337 \return list of sections names
2339 QStringList QtxResourceMgr::sections(const QStringList& names) const
2341 QStringList nm = names;
2343 QRegExp re( QString( "^%1$" ).arg( nm.join( sectionsToken() ) ) );
2344 return sections( re );
2348 \brief Get list of sub-sections names for the specified parent section name.
2350 Sub-sections are separated inside the section name by the sections
2351 separator token, for example "splash:color:label".
2353 \param section parent sub-section name
2354 \param full if \c true return full names of child sub-sections, if \c false,
2355 return only top-level sub-sections names
2356 \return list of sub-sections names
2358 QStringList QtxResourceMgr::subSections(const QString& section, const bool full) const
2360 QStringList names = sections( QStringList() << section );
2361 QMutableListIterator<QString> it( names );
2362 while ( it.hasNext() ) {
2363 QString name = it.next().mid( section.size() + 1 ).trimmed();
2364 if ( name.isEmpty() ) {
2368 if ( !full ) name = name.split( sectionsToken() ).first();
2369 it.setValue( name );
2371 names.removeDuplicates();
2377 \brief Get all parameters name in specified section.
2378 \param sec section name
2379 \return list of settings names
2381 QStringList QtxResourceMgr::parameters( const QString& sec ) const
2385 #if defined(QTX_NO_INDEXED_MAP)
2386 typedef QMap<QString, int> PMap;
2388 typedef IMap<QString, int> PMap;
2392 Resources* ur = !myResources.isEmpty() && workingMode() == IgnoreUserValues ? myResources[0] : 0;
2394 QListIterator<Resources*> it( myResources );
2396 while ( it.hasPrevious() )
2398 Resources* r = it.previous();
2399 if ( r == ur ) break;
2400 QStringList lst = r->parameters( sec );
2401 for ( QStringList::ConstIterator itr = lst.begin(); itr != lst.end(); ++itr )
2402 #if defined(QTX_NO_INDEXED_MAP)
2403 if ( !pmap.contains( *itr ) ) pmap.insert( *itr, 0 );
2405 pmap.insert( *itr, 0, false );
2413 \brief Get all parameters name in specified
2414 list of sub-sections names.
2416 Sub-sections are separated inside the section name by the sections
2417 separator token, for example "splash:color:label".
2419 \param names parent sub-sections names
2420 \return list of settings names
2422 QStringList QtxResourceMgr::parameters( const QStringList& names ) const
2424 return parameters( names.join( sectionsToken() ) );
2428 \brief Get absolute path to the file which name is defined by the parameter.
2430 The file name is defined by \a name argument, while directory name is retrieved
2431 from resources parameter \a prefix of section \a sec. Both directory and file name
2432 can be relative. If the directory is relative, it is calculated from the initial
2433 resources file name. Directory parameter can contain environment
2434 variables, which are substituted automatically.
2436 \param sec section name
2437 \param prefix parameter containing directory name
2438 \param name file name
2439 \return absolute file path or null QString if file does not exist
2441 QString QtxResourceMgr::path( const QString& sect, const QString& prefix, const QString& name ) const
2445 ResList::ConstIterator it = myResources.begin();
2446 if ( myHasUserValues && workingMode() == IgnoreUserValues )
2449 for ( ; it != myResources.end() && res.isEmpty(); ++it )
2450 res = (*it)->path( sect, prefix, name );
2455 \brief Get application resources section name.
2457 By default, application resources section name is "resources" but
2458 it can be changed by setting the "res_section_name" resources manager option.
2460 \return section corresponding to the resources directories
2461 \sa option(), setOption()
2463 QString QtxResourceMgr::resSection() const
2465 QString res = option( "res_section_name" );
2466 if ( res.isEmpty() )
2467 res = QString( "resources" );
2472 \brief Get application language section name.
2474 By default, application language section name is "language" but
2475 it can be changed by setting the "lang_section_name" resources manager option.
2477 \return section corresponding to the application language settings
2478 \sa option(), setOption()
2480 QString QtxResourceMgr::langSection() const
2482 QString res = option( "lang_section_name" );
2483 if ( res.isEmpty() )
2484 res = QString( "language" );
2489 \brief Get sections separator token.
2491 By default, sections separator token is colon symbol ":" but
2492 it can be changed by setting the "section_token" resources manager option.
2494 \return string corresponding to the current section separator token
2495 \sa option(), setOption()
2497 QString QtxResourceMgr::sectionsToken() const
2499 QString res = option( "section_token" );
2500 if ( res.isEmpty() )
2501 res = QString( ":" );
2506 \brief Get default pixmap.
2508 Default pixmap is used when requested pixmap resource is not found.
2510 \return default pixmap
2511 \sa setDefaultPixmap(), loadPixmap()
2513 QPixmap QtxResourceMgr::defaultPixmap() const
2516 if ( myDefaultPix && !myDefaultPix->isNull() )
2517 res = *myDefaultPix;
2522 \brief Set default pixmap.
2524 Default pixmap is used when requested pixmap resource is not found.
2526 \param pix default pixmap
2527 \sa defaultPixmap(), loadPixmap()
2529 void QtxResourceMgr::setDefaultPixmap( const QPixmap& pix )
2531 delete myDefaultPix;
2535 myDefaultPix = new QPixmap( pix );
2539 \brief Load pixmap resource.
2540 \param prefix parameter which refers to the resources directory (directories)
2541 \param name pixmap file name
2542 \return pixmap loaded from the file
2543 \sa defaultPixmap(), setDefaultPixmap()
2545 QPixmap QtxResourceMgr::loadPixmap( const QString& prefix, const QString& name ) const
2547 return loadPixmap( prefix, name, true );
2551 \brief Load pixmap resource.
2553 \param prefix parameter which refers to the resources directory (directories)
2554 \param name pixmap file name
2555 \param useDef if \c false, default pixmap is not returned if resource is not found,
2556 in this case null pixmap is returned instead
2557 \return pixmap loaded from the file
2558 \sa defaultPixmap(), setDefaultPixmap()
2560 QPixmap QtxResourceMgr::loadPixmap( const QString& prefix, const QString& name, const bool useDef ) const
2562 return loadPixmap( prefix, name, useDef ? defaultPixmap() : QPixmap() );
2566 \brief Load pixmap resource.
2568 \param prefix parameter which refers to the resources directory (directories)
2569 \param name pixmap file name
2570 \param defPix default which should be used if the resource file doesn't exist
2571 \return pixmap loaded from the file
2572 \sa defaultPixmap(), setDefaultPixmap()
2574 QPixmap QtxResourceMgr::loadPixmap( const QString& prefix, const QString& name, const QPixmap& defPix ) const
2580 ResList::ConstIterator it = myResources.begin();
2581 if ( myHasUserValues && workingMode() == IgnoreUserValues )
2584 for ( ; it != myResources.end() && pix.isNull(); ++it )
2585 pix = (*it)->loadPixmap( resSection(), prefix, name );
2592 \brief Load translation files according to the specified language.
2594 Names of the translation files are calculated according to the pattern specified
2595 by the "translators" option (this option is read from the section "language" of resources files).
2596 By default, "%P_msg_%L.qm" pattern is used.
2597 Keywords \%A, \%P, \%L in the pattern are substituted by the application name, prefix and language name
2599 For example, for prefix "SUIT" and language "en", all translation files "SUIT_msg_en.qm" are searched and
2602 If prefix is empty or null string, all translation files specified in the "resources" section of resources
2603 files are loaded (actually, the section is retrieved from resSection() method).
2604 If language is not specified, it is retrieved from the langSection() method, and if the latest is also empty,
2605 by default "en" (English) language is used.
2606 By default, settings from the user preferences file are also loaded (if user resource file is valid,
2607 see userFileName()). To avoid loading user settings, pass \c false as first parameter.
2609 \param pref parameter which defines translation context (for example, package name)
2610 \param l language name
2612 \sa resSection(), langSection(), loadTranslators()
2614 void QtxResourceMgr::loadLanguage( const QString& pref, const QString& l )
2618 QMap<QChar, QString> substMap;
2619 substMap.insert( 'A', appName() );
2622 if ( lang.isEmpty() )
2623 value( langSection(), "language", lang );
2625 if ( lang.isEmpty() )
2627 lang = QString( "en" );
2628 qWarning() << "QtxResourceMgr: Language not specified. Assumed:" << lang;
2631 substMap.insert( 'L', lang );
2634 if ( value( langSection(), "translators", trs, false ) && !trs.isEmpty() )
2636 QStringList translators = option( "translators" ).split( "|", QString::SkipEmptyParts );
2637 QStringList newTranslators = trs.split( "|", QString::SkipEmptyParts );
2638 for ( int i = 0; i < (int)newTranslators.count(); i++ )
2640 if ( translators.indexOf( newTranslators[i] ) < 0 )
2641 translators += newTranslators[i];
2643 setOption( "translators", translators.join( "|" ) );
2646 QStringList trList = option( "translators" ).split( "|", QString::SkipEmptyParts );
2647 if ( trList.isEmpty() )
2649 trList.append( "%P_msg_%L.qm" );
2650 qWarning() << "QtxResourceMgr: Translators not defined. Assumed:" << trList[0];
2653 QStringList prefixList;
2654 if ( !pref.isEmpty() )
2655 prefixList.append( pref );
2657 prefixList = parameters( resSection() );
2659 if ( pref.isEmpty() && lang != "en" ) {
2660 // load Qt resources
2661 QString qt_translations = QLibraryInfo::location( QLibraryInfo::TranslationsPath );
2662 QString qt_dir_trpath;
2663 if ( ::getenv( "QTDIR" ) )
2664 qt_dir_trpath = QString( ::getenv( "QTDIR" ) );
2665 if ( !qt_dir_trpath.isEmpty() )
2666 qt_dir_trpath = QDir( qt_dir_trpath ).absoluteFilePath( "translations" );
2668 QTranslator* trans = new QtxTranslator( 0 );
2669 if ( trans->load( QString("qt_%1").arg( lang ), qt_translations ) || trans->load( QString("qt_%1").arg( lang ), qt_dir_trpath ) )
2670 QApplication::instance()->installTranslator( trans );
2673 for ( QStringList::ConstIterator iter = prefixList.begin(); iter != prefixList.end(); ++iter )
2675 QString prefix = *iter;
2676 substMap.insert( 'P', prefix );
2679 for ( QStringList::ConstIterator it = trList.begin(); it != trList.end(); ++it )
2680 trs.append( substMacro( *it, substMap ).trimmed() );
2682 loadTranslators( prefix, trs );
2687 \brief Load translation files for the specified translation context.
2688 \param prefix parameter which defines translation context (for example, package name)
2689 \param translators list of translation files
2692 void QtxResourceMgr::loadTranslators( const QString& prefix, const QStringList& translators )
2698 ResList::ConstIterator iter = myResources.begin();
2699 if ( myHasUserValues && workingMode() == IgnoreUserValues )
2702 for ( ; iter != myResources.end(); ++iter )
2703 lst.prepend( *iter );
2705 QTranslator* trans = 0;
2707 for ( ResList::Iterator it = lst.begin(); it != lst.end(); ++it )
2709 for ( QStringList::ConstIterator itr = translators.begin(); itr != translators.end(); ++itr )
2711 trans = (*it)->loadTranslator( resSection(), prefix, *itr );
2714 if ( !myTranslator[prefix].contains( trans ) )
2715 myTranslator[prefix].append( trans );
2716 QApplication::instance()->installTranslator( trans );
2723 \brief Load translation file.
2724 \param prefix parameter which defines translation context (for example, package name)
2725 \param name translator file name
2726 \sa loadLanguage(), loadTranslators()
2728 void QtxResourceMgr::loadTranslator( const QString& prefix, const QString& name )
2732 QTranslator* trans = 0;
2734 Resources* ur = !myResources.isEmpty() && workingMode() == IgnoreUserValues ? myResources[0] : 0;
2736 QListIterator<Resources*> it( myResources );
2738 while ( it.hasPrevious() )
2740 Resources* r = it.previous();
2741 if ( r == ur ) break;
2743 trans = r->loadTranslator( resSection(), prefix, name );
2746 if ( !myTranslator[prefix].contains( trans ) )
2747 myTranslator[prefix].append( trans );
2748 QApplication::instance()->installTranslator( trans );
2754 \brief Remove all translators corresponding to the specified translation context.
2755 \param prefix parameter which defines translation context (for example, package name)
2757 void QtxResourceMgr::removeTranslators( const QString& prefix )
2759 if ( !myTranslator.contains( prefix ) )
2762 for ( TransList::Iterator it = myTranslator[prefix].begin(); it != myTranslator[prefix].end(); ++it )
2764 QApplication::instance()->removeTranslator( *it );
2768 myTranslator.remove( prefix );
2772 \brief Move all translators corresponding to the specified translation context
2773 to the top of translators stack (increase their priority).
2774 \param prefix parameter which defines translation context (for example, package name)
2776 void QtxResourceMgr::raiseTranslators( const QString& prefix )
2778 if ( !myTranslator.contains( prefix ) )
2781 for ( TransList::Iterator it = myTranslator[prefix].begin(); it != myTranslator[prefix].end(); ++it )
2783 QApplication::instance()->removeTranslator( *it );
2784 QApplication::instance()->installTranslator( *it );
2789 \brief Copy all parameters to the user resources in order to
2790 saved them lately in the user home folder.
2792 void QtxResourceMgr::refresh()
2794 QStringList sl = sections();
2795 for ( QStringList::ConstIterator it = sl.begin(); it != sl.end(); ++it )
2797 QStringList pl = parameters( *it );
2798 for ( QStringList::ConstIterator itr = pl.begin(); itr != pl.end(); ++itr )
2799 setResource( *it, *itr, stringValue( *it, *itr ) );
2804 \brief Set the resource directories (where global confguration files are searched).
2806 This function also clears all currently set resources.
2808 \param dl directories list
2810 void QtxResourceMgr::setDirList( const QStringList& dl )
2813 for ( ResList::Iterator it = myResources.begin(); it != myResources.end(); ++it )
2816 myResources.clear();
2820 \brief Set parameter value.
2821 \param sect section name
2822 \param name parameter name
2823 \param val parameter value
2825 void QtxResourceMgr::setResource( const QString& sect, const QString& name, const QString& val )
2829 if ( !myResources.isEmpty() && myHasUserValues )
2830 myResources.first()->setValue( sect, name, val );
2834 \brief Get user configuration file name.
2836 This method can be redefined in the successor class to customize the user configuration file name.
2837 User configuration file is always situated in the user's home directory. By default .<appName>rc
2838 file is used on Linux (e.g. .MyApprc) and <appName>.<format> under Windows (e.g. MyApp.xml).
2840 Parameter \a for_load (not used in default implementation) specifies the usage mode, i.e. if
2841 user configuration file is opened for reading or writing. This allows customizing a way of application
2842 resources initializing (for example, if the user configuraion file includes version number and there is
2843 no file corresponding to this version in the user's home directory, it could be good idea to try
2844 the configuration file from the previous versions of the application).
2846 \param appName application name
2847 \param for_load boolean flag indicating that file is opened for loading or saving (not used in default implementation)
2848 \return user configuration file name
2849 \sa globalFileName()
2851 QString QtxResourceMgr::userFileName( const QString& appName, const bool /*for_load*/ ) const
2854 QString pathName = QDir::homePath();
2856 QString cfgAppName = QApplication::applicationName();
2857 if ( !cfgAppName.isEmpty() )
2858 pathName = Qtx::addSlash( Qtx::addSlash( pathName ) + QString( ".config" ) ) + cfgAppName;
2861 fileName = QString( "%1.%2" ).arg( appName ).arg( currentFormat() );
2863 fileName = QString( "%1rc" ).arg( appName );
2864 // VSR 24/09/2012: issue 0021781: do not prepend filename with "."
2865 // when user file is stored in ~/.config/<appname> directory
2866 if ( cfgAppName.isEmpty() )
2867 fileName.prepend( "." );
2870 if ( !fileName.isEmpty() )
2871 pathName = Qtx::addSlash( pathName ) + fileName;
2877 \brief Get global configuration file name.
2879 This method can be redefined in the successor class to customize the global configuration file name.
2880 Global configuration files are searched in the directories specified by the application resources
2881 environment variable (e.g. MyAppResources). By default <appName>.<format> file name is used
2884 \param appName application name
2885 \return global configuration file name
2888 QString QtxResourceMgr::globalFileName( const QString& appName ) const
2890 return QString( "%1.%2" ).arg( appName ).arg( currentFormat() );
2894 \brief Perform substitution of the patterns like \%A, \%B, etc by values from the map.
2896 Used by loadLanguage().
2898 \param src sring to be processed
2899 \param substMap map of values for replacing
2900 \return processed string
2902 QString QtxResourceMgr::substMacro( const QString& src, const QMap<QChar, QString>& substMap ) const
2906 QRegExp rx( "%[A-Za-z%]" );
2909 while ( ( idx = rx.indexIn( trg, idx ) ) >= 0 )
2911 QChar spec = trg.at( idx + 1 );
2915 else if ( substMap.contains( spec ) )
2916 subst = substMap[spec];
2918 if ( !subst.isEmpty() )
2920 trg.replace( idx, rx.matchedLength(), subst );
2921 idx += subst.length();
2924 idx += rx.matchedLength();