1 // Copyright (C) 2007-2014 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, or (at your option) any later version.
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>
46 /* XPM for the default pixmap */
47 static const char* pixmap_not_found_xpm[] = {
70 \class QtxResourceMgr::Resources
72 \brief Represents container for settings read from the resource file.
75 class QtxResourceMgr::Resources
78 Resources( QtxResourceMgr*, const QString& );
82 void setFile( const QString& );
84 QString value( const QString&, const QString&, const bool ) const;
85 void setValue( const QString&, const QString&, const QString& );
87 bool hasSection( const QString& ) const;
88 bool hasValue( const QString&, const QString& ) const;
90 void removeSection( const QString& );
91 void removeValue( const QString&, const QString& );
93 QPixmap loadPixmap( const QString&, const QString&, const QString& ) const;
94 QTranslator* loadTranslator( const QString&, const QString&, const QString& ) const;
96 QString makeSubstitution( const QString&, const QString&, const QString& ) const;
100 QStringList sections() const;
101 QStringList parameters( const QString& ) const;
103 QString path( const QString&, const QString&, const QString& ) const;
106 QtxResourceMgr* resMgr() const;
109 Section section( const QString& );
110 const Section section( const QString& ) const;
112 QString fileName( const QString&, const QString&, const QString& ) const;
115 typedef QMap<QString, Section> SectionMap;
118 QtxResourceMgr* myMgr; //!< resources manager
119 SectionMap mySections; //!< sections map
120 QString myFileName; //!< resources file name
121 QMap<QString,QPixmap> myPixmapCache; //!< pixmaps cache
123 friend class QtxResourceMgr::Format;
128 \param mgr parent resources manager
129 \param fileName resources file name
131 QtxResourceMgr::Resources::Resources( QtxResourceMgr* mgr, const QString& fileName )
133 myFileName( fileName )
140 QtxResourceMgr::Resources::~Resources()
145 \brief Get resources file name.
147 This file is used to load/save operations.
152 QString QtxResourceMgr::Resources::file() const
158 \brief Set resources file name.
162 void QtxResourceMgr::Resources::setFile( const QString& fn )
168 \brief Get string representation of parameter value.
169 \param sect section name
170 \param name parameter name
171 \param subst if \c true, perform variables substitution
172 \return parameter value or null QString if there is no such parameter
173 \sa setValue(), makeSubstitution()
175 QString QtxResourceMgr::Resources::value( const QString& sect, const QString& name, const bool subst ) const
179 if ( hasValue( sect, name ) )
181 val = section( sect )[name];
183 val = makeSubstitution( val, sect, name );
189 \brief Set parameter value.
190 \param sect section name
191 \param name parameter name
192 \param val parameter value
193 \sa value(), makeSubstitution()
195 void QtxResourceMgr::Resources::setValue( const QString& sect, const QString& name, const QString& val )
197 if ( !mySections.contains( sect ) )
198 mySections.insert( sect, Section() );
200 mySections[sect].insert( name, val );
204 \brief Check section existence.
205 \param sect section name
206 \return \c true if section exists
208 bool QtxResourceMgr::Resources::hasSection( const QString& sect ) const
210 return mySections.contains( sect );
214 \brief Check parameter existence.
215 \param sect section name
216 \param name parameter name
217 \return \c true if parameter exists in specified section
219 bool QtxResourceMgr::Resources::hasValue( const QString& sect, const QString& name ) const
221 return hasSection( sect ) && section( sect ).contains( name );
225 \brief Remove resourcs section.
226 \param sect secton name
228 void QtxResourceMgr::Resources::removeSection( const QString& sect )
230 mySections.remove( sect );
234 \brief Remove parameter from the section.
235 \param sect section name
236 \param name parameter name
238 void QtxResourceMgr::Resources::removeValue( const QString& sect, const QString& name )
240 if ( !mySections.contains( sect ) )
243 mySections[sect].remove( name );
245 if ( mySections[sect].isEmpty() )
246 mySections.remove( sect );
250 \brief Remove all sections.
252 void QtxResourceMgr::Resources::clear()
258 \brief Get all sections names.
259 \return list of section names
261 QStringList QtxResourceMgr::Resources::sections() const
263 return mySections.keys();
267 \brief Get all parameters name in specified section.
268 \param sec section name
269 \return list of settings names
271 QStringList QtxResourceMgr::Resources::parameters( const QString& sec ) const
273 if ( !hasSection( sec ) )
274 return QStringList();
276 return section( sec ).keys();
280 \brief Get absolute path to the file which name is defined by the parameter.
282 The file name is defined by \a name argument, while directory name is retrieved
283 from resources parameter \a prefix of section \a sec. Both directory and file name
284 can be relative. If the directory is relative, it is calculated from the initial
285 resources file name (see file()). Directory parameter can contain environment
286 variables, which are substituted automatically.
288 \param sec section name
289 \param prefix parameter containing directory name
290 \param name file name
291 \return absolute file path or null QString if file does not exist
292 \sa fileName(), file(), makeSubstitution()
294 QString QtxResourceMgr::Resources::path( const QString& sec, const QString& prefix, const QString& name ) const
296 QString filePath = fileName( sec, prefix, name );
297 if ( !filePath.isEmpty() )
299 if ( !QFileInfo( filePath ).exists() )
300 filePath = QString();
306 \brief Get resource manager
307 \return resource manager pointer
309 QtxResourceMgr* QtxResourceMgr::Resources::resMgr() const
315 \brief Get resources section by specified name.
317 If section does not exist it is created (empty).
319 \param sn section name
320 \return resources section
322 QtxResourceMgr::Section QtxResourceMgr::Resources::section( const QString& sn )
324 if ( !mySections.contains( sn ) )
325 mySections.insert( sn, Section() );
327 return mySections[sn];
331 \brief Get resources section by specified name.
332 \param sn section name
333 \return resources section
335 const QtxResourceMgr::Section QtxResourceMgr::Resources::section( const QString& sn ) const
337 return mySections[sn];
341 \brief Get file path.
343 The file name is defined by \a name argument, while directory name is retrieved
344 from resources parameter \a prefix of section \a sec. Both directory and file name
345 can be relative. If the directory is relative, it is calculated from the initial
346 resources file name (see file()). Directory parameter can contain environment
347 variables, which are substituted automatically.
348 File existence is not checked.
350 \param sec section name
351 \param prefix parameter containing directory name
352 \param name file name
353 \return absolute file path or null QString if \a prefix parameter
354 does not exist in section \sec
355 \sa path(), file(), makeSubstitution()
357 QString QtxResourceMgr::Resources::fileName( const QString& sect, const QString& prefix, const QString& name ) const
360 if ( !QFileInfo( name ).isRelative() )
366 if ( hasValue( sect, prefix ) )
368 path = value( sect, prefix, true );
369 if ( !path.isEmpty() )
371 if ( QFileInfo( path ).isRelative() )
372 path = Qtx::addSlash( Qtx::dir( myFileName, true ) ) + path;
374 path = Qtx::addSlash( path ) + name;
378 if( !path.isEmpty() )
380 QString fname = QDir::convertSeparators( path );
381 QFileInfo inf( fname );
382 fname = inf.absoluteFilePath();
389 \brief Load and return pixmap from external file.
391 If QtxResourceMgr::isPixmapCached() is \c true then cached pixmap is returned
392 (if it is already loaded), otherwise it is loaded from file.
393 If the file name is invalid, null pixmap is returned.
395 \param sect section name
396 \param prefix parameter containing resources directory name
397 \param name pixmap file name
398 \return pixmap loaded from file
400 QPixmap QtxResourceMgr::Resources::loadPixmap( const QString& sect, const QString& prefix, const QString& name ) const
402 QString fname = fileName( sect, prefix, name );
403 bool toCache = resMgr() ? resMgr()->isPixmapCached() : false;
405 if( toCache && myPixmapCache.contains( fname ) )
406 p = myPixmapCache[fname];
411 ( ( QMap<QString,QPixmap>& )myPixmapCache ).insert( fname, p );
417 \brief Load translator.
418 \param sect section name
419 \param prefix parameter containing resources directory
420 \param name translation file name
421 \return just created and loaded translator or 0 in case of error
423 QTranslator* QtxResourceMgr::Resources::loadTranslator( const QString& sect, const QString& prefix, const QString& name ) const
425 QTranslator* trans = new QtxTranslator( 0 );
426 QString fname = QDir::convertSeparators( fileName( sect, prefix, name ) );
427 if ( !trans->load( Qtx::file( fname, false ), Qtx::dir( fname ) ) )
436 \brief Substitute variables by their values.
438 Environment variable is substituted by its value. For other variables resource
439 manager tries to find value among defined resources parameters.
441 \param str string to be processed
442 \param sect section, where variables are searched
443 \param name name of variable which must be ignored during substitution
444 \return processed string (with all substitutions made)
446 QString QtxResourceMgr::Resources::makeSubstitution( const QString& str, const QString& sect, const QString& name ) const
450 QMap<QString, int> ignoreMap;
451 ignoreMap.insert( name, 0 );
453 int start( 0 ), len( 0 );
456 QString envName = Qtx::findEnvVar( res, start, len );
457 if ( envName.isNull() )
461 if ( ::getenv( envName.toLatin1() ) )
462 newStr = QString( ::getenv( envName.toLatin1() ) );
464 if ( newStr.isNull() )
466 if ( ignoreMap.contains( envName ) )
472 if ( hasValue( sect, envName ) )
473 newStr = value( sect, envName, false );
474 ignoreMap.insert( envName, 0 );
476 res.replace( start, len, newStr );
479 res.replace( "$$", "$" );
480 res.replace( "%%", "%" );
486 \class QtxResourceMgr::IniFormat
488 \brief Reader/writer for .ini resources files.
491 class QtxResourceMgr::IniFormat : public Format
498 virtual bool load( const QString&, QMap<QString, Section>& );
499 virtual bool save( const QString&, const QMap<QString, Section>& );
502 bool load( const QString&, QMap<QString, Section>&, QSet<QString>& );
508 QtxResourceMgr::IniFormat::IniFormat()
516 QtxResourceMgr::IniFormat::~IniFormat()
521 \brief Load resources from ini-file.
522 \param fname resources file name
523 \param secMap resources map to be filled in
524 \return \c true on success and \c false on error
526 bool QtxResourceMgr::IniFormat::load( const QString& fname, QMap<QString, Section>& secMap )
528 QSet<QString> importHistory;
529 return load( fname, secMap, importHistory );
534 \brief Load resources from xml-file.
535 \param fname resources file name
536 \param secMap resources map to be filled in
537 \param importHistory list of already imported resources files (to prevent import loops)
538 \return \c true on success or \c false on error
540 bool QtxResourceMgr::IniFormat::load( const QString& fname, QMap<QString, Section>& secMap, QSet<QString>& importHistory )
542 QString aFName = fname.trimmed();
543 if ( !QFileInfo( aFName ).exists() )
545 if ( QFileInfo( aFName + ".ini" ).exists() )
547 else if ( QFileInfo( aFName + ".INI" ).exists() )
550 return false; // file does not exist
552 QFileInfo aFinfo( aFName );
553 aFName = aFinfo.canonicalFilePath();
555 if ( !importHistory.contains( aFName ) )
556 importHistory.insert( aFName );
558 return true; // already imported (prevent import loops)
560 QFile file( aFName );
561 if ( !file.open( QFile::ReadOnly ) )
562 return false; // file is not accessible
564 QTextStream ts( &file );
571 QString separator = option( "separator" );
572 if ( separator.isNull() )
573 separator = QString( "=" );
575 QString comment = option( "comment" );
576 if ( comment.isNull() )
577 comment = QString( "#" );
581 data = ts.readLine();
587 data = data.trimmed();
588 if ( data.isEmpty() )
591 if ( data.startsWith( comment ) )
594 QRegExp rx( "^\\[([\\w\\s\\._]*)\\]$" );
595 if ( rx.indexIn( data ) != -1 )
597 section = rx.cap( 1 );
598 if ( section.isEmpty() )
601 qWarning() << "QtxResourceMgr: Empty section in line:" << line;
604 else if ( data.contains( separator ) && !section.isEmpty() )
606 int pos = data.indexOf( separator );
607 QString key = data.left( pos ).trimmed();
608 QString val = data.mid( pos + 1 ).trimmed();
609 secMap[section].insert( key, val );
611 else if ( section == "import" )
613 QString impFile = QDir::convertSeparators( Qtx::makeEnvVarSubst( data, Qtx::Always ) );
614 QFileInfo impFInfo( impFile );
615 if ( impFInfo.isRelative() )
616 impFInfo.setFile( aFinfo.absoluteDir(), impFile );
618 QMap<QString, Section> impMap;
619 if ( !load( impFInfo.absoluteFilePath(), impMap, importHistory ) )
621 qDebug() << "QtxResourceMgr: Error with importing file:" << data;
625 QMap<QString, Section>::const_iterator it = impMap.constBegin();
626 for ( ; it != impMap.constEnd() ; ++it )
628 if ( !secMap.contains( it.key() ) )
630 // insert full section
631 secMap.insert( it.key(), it.value() );
635 // insert all parameters from the section
636 Section::ConstIterator paramIt = it.value().begin();
637 for ( ; paramIt != it.value().end() ; ++paramIt )
639 if ( !secMap[it.key()].contains( paramIt.key() ) )
640 secMap[it.key()].insert( paramIt.key(), paramIt.value() );
649 if ( section.isEmpty() )
650 qWarning() << "QtxResourceMgr: Current section is empty";
652 qWarning() << "QtxResourceMgr: Error in line:" << line;
662 \brief Save resources to the ini-file.
663 \param fname resources file name
664 \param secMap resources map
665 \return \c true on success and \c false on error
667 bool QtxResourceMgr::IniFormat::save( const QString& fname, const QMap<QString, Section>& secMap )
669 if ( !Qtx::mkDir( QFileInfo( fname ).absolutePath() ) )
673 if ( !file.open( QFile::WriteOnly ) )
676 QTextStream ts( &file );
678 ts << "# This file is automatically created by SALOME application." << endl;
679 ts << "# Changes made in this file can be lost!" << endl;
683 for ( QMap<QString, Section>::ConstIterator it = secMap.begin(); it != secMap.end() && res; ++it )
685 QStringList data( QString( "[%1]" ).arg( it.key() ) );
686 for ( Section::ConstIterator iter = it.value().begin(); iter != it.value().end(); ++iter )
687 data.append( iter.key() + " = " + iter.value() );
690 for ( QStringList::ConstIterator itr = data.begin(); itr != data.end(); ++itr )
700 \class QtxResourceMgr::XmlFormat
702 \brief Reader/writer for .xml resources files.
705 class QtxResourceMgr::XmlFormat : public Format
712 virtual bool load( const QString&, QMap<QString, Section>& );
713 virtual bool save( const QString&, const QMap<QString, Section>& );
716 QString docTag() const;
717 QString sectionTag() const;
718 QString parameterTag() const;
719 QString importTag() const;
720 QString nameAttribute() const;
721 QString valueAttribute() const;
723 bool load( const QString&, QMap<QString, Section>&, QSet<QString>& );
729 QtxResourceMgr::XmlFormat::XmlFormat()
737 QtxResourceMgr::XmlFormat::~XmlFormat()
742 \brief Load resources from xml-file.
743 \param fname resources file name
744 \param secMap resources map to be filled in
745 \return \c true on success and \c false on error
747 bool QtxResourceMgr::XmlFormat::load( const QString& fname, QMap<QString, Section>& secMap )
749 QSet<QString> importHistory;
750 return load( fname, secMap, importHistory );
754 \brief Load resources from xml-file.
755 \param fname resources file name
756 \param secMap resources map to be filled in
757 \param importHistory list of already imported resources files (to prevent import loops)
758 \return \c true on success and \c false on error
760 bool QtxResourceMgr::XmlFormat::load( const QString& fname, QMap<QString, Section>& secMap, QSet<QString>& importHistory )
762 QString aFName = fname.trimmed();
763 if ( !QFileInfo( aFName ).exists() )
765 if ( QFileInfo( aFName + ".xml" ).exists() )
767 else if ( QFileInfo( aFName + ".XML" ).exists() )
770 return false; // file does not exist
772 QFileInfo aFinfo( aFName );
773 aFName = aFinfo.canonicalFilePath();
775 if ( !importHistory.contains( aFName ) )
776 importHistory.insert( aFName );
778 return true; // already imported (prevent import loops)
784 QFile file( aFName );
785 if ( !file.open( QFile::ReadOnly ) )
787 qDebug() << "QtxResourceMgr: File is not accessible:" << aFName;
793 res = doc.setContent( &file );
798 qDebug() << "QtxResourceMgr: File is empty:" << aFName;
802 QDomElement root = doc.documentElement();
803 if ( root.isNull() || root.tagName() != docTag() )
805 qDebug() << "QtxResourceMgr: Invalid root in file:" << aFName;
809 QDomNode sectNode = root.firstChild();
810 while ( res && !sectNode.isNull() )
812 res = sectNode.isElement();
815 QDomElement sectElem = sectNode.toElement();
816 if ( sectElem.tagName() == sectionTag() && sectElem.hasAttribute( nameAttribute() ) )
818 QString section = sectElem.attribute( nameAttribute() );
819 QDomNode paramNode = sectNode.firstChild();
820 while ( res && !paramNode.isNull() )
822 res = paramNode.isElement();
825 QDomElement paramElem = paramNode.toElement();
826 if ( paramElem.tagName() == parameterTag() &&
827 paramElem.hasAttribute( nameAttribute() ) && paramElem.hasAttribute( valueAttribute() ) )
829 QString paramName = paramElem.attribute( nameAttribute() );
830 QString paramValue = paramElem.attribute( valueAttribute() );
831 secMap[section].insert( paramName, paramValue );
835 qDebug() << "QtxResourceMgr: Invalid parameter element in file:" << aFName;
841 res = paramNode.isComment();
843 qDebug() << "QtxResourceMgr: Node is neither element nor comment in file:" << aFName;
846 paramNode = paramNode.nextSibling();
849 else if ( sectElem.tagName() == importTag() && sectElem.hasAttribute( nameAttribute() ) )
851 QString impFile = QDir::convertSeparators( Qtx::makeEnvVarSubst( sectElem.attribute( nameAttribute() ), Qtx::Always ) );
852 QFileInfo impFInfo( impFile );
853 if ( impFInfo.isRelative() )
854 impFInfo.setFile( aFinfo.absoluteDir(), impFile );
856 QMap<QString, Section> impMap;
857 if ( !load( impFInfo.absoluteFilePath(), impMap, importHistory ) )
859 qDebug() << "QtxResourceMgr: Error with importing file:" << sectElem.attribute( nameAttribute() );
863 QMap<QString, Section>::const_iterator it = impMap.constBegin();
864 for ( ; it != impMap.constEnd() ; ++it )
866 if ( !secMap.contains( it.key() ) )
868 // insert full section
869 secMap.insert( it.key(), it.value() );
873 // insert all parameters from the section
874 Section::ConstIterator paramIt = it.value().begin();
875 for ( ; paramIt != it.value().end() ; ++paramIt )
877 if ( !secMap[it.key()].contains( paramIt.key() ) )
878 secMap[it.key()].insert( paramIt.key(), paramIt.value() );
886 qDebug() << "QtxResourceMgr: Invalid section in file:" << aFName;
892 res = sectNode.isComment(); // if it's a comment -- let it be, pass it..
894 qDebug() << "QtxResourceMgr: Node is neither element nor comment in file:" << aFName;
897 sectNode = sectNode.nextSibling();
903 qDebug() << "QtxResourceMgr: File" << fname << "is loaded successfully";
908 \brief Save resources to the xml-file.
909 \param fname resources file name
910 \param secMap resources map
911 \return \c true on success and \c false on error
913 bool QtxResourceMgr::XmlFormat::save( const QString& fname, const QMap<QString, Section>& secMap )
919 if ( !Qtx::mkDir( QFileInfo( fname ).absolutePath() ) )
923 if ( !file.open( QFile::WriteOnly ) )
926 QDomDocument doc( docTag() );
927 QDomComment comment = doc.createComment( "\nThis file is automatically created by SALOME application.\nChanges made in this file can be lost!\n" );
928 doc.appendChild( comment );
929 QDomElement root = doc.createElement( docTag() );
930 doc.appendChild( root );
932 for ( QMap<QString, Section>::ConstIterator it = secMap.begin(); it != secMap.end(); ++it )
934 QDomElement sect = doc.createElement( sectionTag() );
935 sect.setAttribute( nameAttribute(), it.key() );
936 root.appendChild( sect );
937 for ( Section::ConstIterator iter = it.value().begin(); iter != it.value().end(); ++iter )
939 QDomElement val = doc.createElement( parameterTag() );
940 val.setAttribute( nameAttribute(), iter.key() );
941 val.setAttribute( valueAttribute(), iter.value() );
942 sect.appendChild( val );
946 QTextStream ts( &file );
947 QStringList docStr = doc.toString().split( "\n" );
948 for ( QStringList::ConstIterator itr = docStr.begin(); itr != docStr.end(); ++itr )
959 \brief Get document tag name
960 \return XML document tag name
962 QString QtxResourceMgr::XmlFormat::docTag() const
964 QString tag = option( "doc_tag" );
966 tag = QString( "document" );
971 \brief Get section tag name
972 \return XML section tag name
974 QString QtxResourceMgr::XmlFormat::sectionTag() const
976 QString tag = option( "section_tag" );
978 tag = QString( "section" );
983 \brief Get parameter tag name
984 \return XML parameter tag name
986 QString QtxResourceMgr::XmlFormat::parameterTag() const
988 QString tag = option( "parameter_tag" );
990 tag = QString( "parameter" );
995 \brief Get import tag name
996 \return XML import tag name
998 QString QtxResourceMgr::XmlFormat::importTag() const
1000 QString tag = option( "import_tag" );
1001 if ( tag.isEmpty() )
1002 tag = QString( "import" );
1007 \brief Get parameter tag's "name" attribute name
1008 \return XML parameter tag's "name" attribute name
1010 QString QtxResourceMgr::XmlFormat::nameAttribute() const
1012 QString str = option( "name_attribute" );
1013 if ( str.isEmpty() )
1014 str = QString( "name" );
1019 \brief Get parameter tag's "value" attribute name
1020 \return XML parameter tag's "value" attribute name
1022 QString QtxResourceMgr::XmlFormat::valueAttribute() const
1024 QString str = option( "value_attribute" );
1025 if ( str.isEmpty() )
1026 str = QString( "value" );
1031 \class QtxResourceMgr::Format
1032 \brief Generic resources files reader/writer class.
1037 \param fmt format name (for example, "xml" or "ini")
1039 QtxResourceMgr::Format::Format( const QString& fmt )
1047 QtxResourceMgr::Format::~Format()
1052 \brief Get the format name.
1055 QString QtxResourceMgr::Format::format() const
1061 \brief Get options names.
1062 \return list of the format options
1064 QStringList QtxResourceMgr::Format::options() const
1066 return myOpt.keys();
1070 \brief Get the value of the option with specified name.
1072 If option doesn't exist then null QString is returned.
1074 \param opt option name
1075 \return option value
1077 QString QtxResourceMgr::Format::option( const QString& opt ) const
1080 if ( myOpt.contains( opt ) )
1086 \brief Set the value of the option with specified name.
1087 \param opt option name
1088 \param val option value
1090 void QtxResourceMgr::Format::setOption( const QString& opt, const QString& val )
1092 myOpt.insert( opt, val );
1096 \brief Load resources from the resource file.
1097 \param res resources object
1098 \return \c true on success and \c false on error
1100 bool QtxResourceMgr::Format::load( Resources* res )
1105 QMap<QString, Section> sections;
1106 bool status = load( res->myFileName, sections );
1108 res->mySections = sections;
1110 qDebug() << "QtxResourceMgr: Can't load resource file:" << res->myFileName;
1116 \brief Save resources to the resource file.
1117 \param res resources object
1118 \return \c true on success and \c false on error
1120 bool QtxResourceMgr::Format::save( Resources* res )
1125 Qtx::mkDir( Qtx::dir( res->myFileName ) );
1127 QtxResourceMgr* mgr = res->resMgr();
1128 QString name = mgr ? mgr->userFileName( mgr->appName(), false ) : res->myFileName;
1129 return save( name, res->mySections );
1133 \fn virtual bool QtxResourceMgr::Format::load( const QString& fname,
1134 QMap<QString, Section>& secMap )
1135 \brief Load resources from the specified resources file.
1137 Should be implemented in the successors.
1139 \param fname resources file name
1140 \param secMap resources map to be filled in
1141 \return \c true on success and \c false on error
1145 \fn virtual bool QtxResourceMgr::Format::save( const QString& fname,
1146 const QMap<QString, Section>& secMap )
1148 \brief Save resources to the specified resources file.
1150 Should be implemented in the successors.
1152 \param fname resources file name
1153 \param secMap resources map
1154 \return \c true on success and \c false on error
1158 \class QtxResourceMgr
1159 \brief Application resources manager.
1161 This class can be used to define settings, save/load settings and
1162 application preferences to the resource file(s), load translation files
1163 (internationalization mechanism), load pixmaps and other resources from
1164 external files, etc.
1166 Currently it supports .ini and .xml resources file formats. To implement
1167 own resources file format, inherit from the Format class and implement virtual
1168 Format::load() and Format::save() methods.
1170 Resources manager is initialized by the (symbolic) name of the application.
1171 The parameter \a resVarTemplate specifies the template for the environment
1172 variable which should point to the resource directory or list of directories.
1173 Environment variable name is calculated by substitution of "%1" substring in
1174 the \a resVarTemplate parameter (if it contains such substring) by the
1175 application name (\a appName).
1176 By default, \a resVarTemplate is set to "%1Resources". For example, if the application name
1177 is "MyApp", the environment variable "MyAppResources" will be inspected in this case.
1179 Resource manager can handle several global application configuration files and
1180 one user configuration file. Location of global configuration files is defined
1181 by the environment variable (see above) and these files are always read-only.
1182 The name of the global configuration files is retrieved by calling virtual method
1183 globalFileName() which can be redefined in the QtxResourceMgr class successors.
1184 User configuration file always situated in the user's home directory. It's name
1185 is defined by calling virtual method userFileName() which can be also redefined
1186 in the QtxResourceMgr class successors. This is the only file which the preferences
1187 changed by the user during the application session are written to (usually
1188 when the application closes).
1190 Resources environment variable should contain one or several resource directories
1191 (separated by ";" symbol on Windows and ":" or ";" on Linux). Each resource directory
1192 can contain application global configuration file. The user configuration file has
1193 the highest priority, for the global configuration files the priority is decreasing from
1194 left to right, i.e. the first directory in the directoris list, defined by the
1195 resources environment variable has higher priority. Priority has the meaning when
1196 searching requested resources (application preference, pixmap file name, translation
1199 When retrieving preferences, it is sometimes helpful to ignore values coming from the
1200 user preference file and take into account only global preferences.
1201 To do this, use setWorkingMode() method passing QtxResourceMgr::IgnoreUserValues enumerator
1204 Resources manager operates with such terms like options, sections and parameters.
1205 Parametets are named application resources, for example, application preferences like
1206 integer, double, boolean or string values, pictures, font and color definitions, etc.
1207 Parameters are organized inside the resources files into the named groups - sections.
1208 Options are special kind of resoures which allow customizing resource files interpreting.
1209 For example, by default language settings are defined in the resource file in the
1210 section "language". It is possible to change this section name by setting "language"
1211 option to another value (see setOption()).
1213 Retrieving preferences values can be done by using one of value() methods, each returns
1214 \c true if the corresponding preference is found. Another way is to use integerValue(),
1215 doubleValue(), etc methods, which allow specifying default value which is used if the
1216 specified preference is not found. Removing of preferences or sections can be done using
1217 remove(const QString& sect) or remove(const QString& sect, const QString& name) methods.
1218 To add the preference or to change exiting preference value use setValue() methods family.
1219 Methods hasSection() and hasValue() can be used to check existence of section or
1220 preference (in the specified section). List of all sections can be retrieved with the
1221 sections() method, and list of all settings names in some specified section can be
1222 obtained with parameters() method.
1224 Pixmaps can be loaded with the loadPixmap() methods. If the specified pixmap is not found,
1225 the default one is returned. Default pixmap can be set by setDefaultPixmap().
1227 One of the key feature of the resources manager is support of application
1228 internationalization mechanism. Translation files for the specified language can be loaded
1229 with loadLanguage() method.
1233 \brief Constructs the resource manager.
1234 \param appName application name
1235 \param resVarTemplate resource environment variable pattern
1237 QtxResourceMgr::QtxResourceMgr( const QString& appName, const QString& resVarTemplate )
1238 : myAppName( appName ),
1239 myCheckExist( true ),
1241 myIsPixmapCached( true ),
1242 myHasUserValues( true ),
1243 myWorkingMode( AllowUserValues )
1245 QString envVar = !resVarTemplate.isEmpty() ? resVarTemplate : QString( "%1Resources" );
1246 if ( envVar.contains( "%1" ) )
1247 envVar = envVar.arg( appName );
1250 if ( ::getenv( envVar.toLatin1() ) )
1251 dirs = ::getenv( envVar.toLatin1() );
1253 QString dirsep = ";"; // for Windows: ";" is used as directories separator
1255 QString dirsep = "[:|;]"; // for Linux: both ":" and ";" can be used
1257 setDirList( dirs.split( QRegExp( dirsep ), QString::SkipEmptyParts ) );
1259 installFormat( new XmlFormat() );
1260 installFormat( new IniFormat() );
1262 setOption( "translators", QString( "%P_msg_%L.qm|%P_images.qm" ) );
1268 Destroy the resource manager and free allocated memory.
1270 QtxResourceMgr::~QtxResourceMgr()
1272 QStringList prefList = myTranslator.keys();
1273 for ( QStringList::ConstIterator it = prefList.begin(); it != prefList.end(); ++it )
1274 removeTranslators( *it );
1276 qDeleteAll( myResources );
1277 qDeleteAll( myFormats );
1279 delete myDefaultPix;
1283 \brief Get the application name.
1284 \return application name
1286 QString QtxResourceMgr::appName() const
1292 \brief Get the "check existance" flag
1294 If this flag is \c true then preference can be set (with setValue() method)
1295 only if it doesn't exist or if the value is changed.
1297 \return \c true if "check existance" flag is set
1299 bool QtxResourceMgr::checkExisting() const
1301 return myCheckExist;
1305 \brief Set the "check existance" flag.
1306 \param on new flag value
1308 void QtxResourceMgr::setCheckExisting( const bool on )
1314 \brief Get the resource directories list.
1316 Home user directory (where the user application configuration file is situated)
1317 is not included. This is that directories list defined by the application
1318 resources environment variable.
1320 \return list of directories names
1322 QStringList QtxResourceMgr::dirList() const
1328 \brief Initialise resources manager.
1330 Prepare the resources containers and load resources (if \a autoLoad is \c true).
1332 \param autoLoad if \c true (default) then all resources are loaded
1334 void QtxResourceMgr::initialize( const bool autoLoad ) const
1336 if ( !myResources.isEmpty() )
1339 QtxResourceMgr* that = (QtxResourceMgr*)this;
1341 if ( !userFileName( appName() ).isEmpty() )
1342 that->myResources.append( new Resources( that, userFileName( appName() ) ) );
1344 that->myHasUserValues = myResources.count() > 0;
1346 for ( QStringList::ConstIterator it = myDirList.begin(); it != myDirList.end(); ++it )
1348 QString path = Qtx::addSlash( *it ) + globalFileName( appName() );
1349 that->myResources.append( new Resources( that, path ) );
1357 \brief Get "cached pixmaps" option value.
1359 Resources manager allows possibility to cache loaded pixmaps that allow to
1360 improve application performance. This feature is turned on by default - all
1361 loaded pixmaps are stored in the internal map. Switching of this feature on/off
1362 can be done by setIsPixmapCached() method.
1364 \return \c true if pixmap cache is turned on
1365 \sa setIsPixmapCached()
1367 bool QtxResourceMgr::isPixmapCached() const
1369 return myIsPixmapCached;
1373 \brief Switch "cached pixmaps" option on/off.
1374 \param on enable pixmap cache if \c true and disable it if \c false
1375 \sa isPixmapCached()
1377 void QtxResourceMgr::setIsPixmapCached( const bool on )
1379 myIsPixmapCached = on;
1383 \brief Remove all resources from the resources manager.
1385 void QtxResourceMgr::clear()
1387 for ( ResList::Iterator it = myResources.begin(); it != myResources.end(); ++it )
1392 \brief Get current working mode.
1394 \return current working mode
1395 \sa setWorkingMode(), value(), hasValue(), hasSection(), setValue()
1397 QtxResourceMgr::WorkingMode QtxResourceMgr::workingMode() const
1399 return myWorkingMode;
1403 \brief Set resource manager's working mode.
1405 The resource manager can operate in the following working modes:
1406 * AllowUserValues : methods values(), hasValue(), hasSection() take into account user values (default)
1407 * IgnoreUserValues : methods values(), hasValue(), hasSection() do not take into account user values
1409 Note, that setValue() method always put the value to the user settings file.
1411 \param mode new working mode
1412 \sa workingMode(), value(), hasValue(), hasSection(), setValue()
1414 void QtxResourceMgr::setWorkingMode( WorkingMode mode )
1416 myWorkingMode = mode;
1420 \brief Get interger parameter value.
1421 \param sect section name
1422 \param name parameter name
1423 \param iVal parameter to return resulting integer value
1424 \return \c true if parameter is found and \c false if parameter is not found
1425 (in this case \a iVal value is undefined)
1427 bool QtxResourceMgr::value( const QString& sect, const QString& name, int& iVal ) const
1430 if ( !value( sect, name, val, true ) )
1434 iVal = val.toInt( &ok );
1440 \brief Get double parameter value.
1441 \param sect section name
1442 \param name parameter name
1443 \param dVal parameter to return resulting double value
1444 \return \c true if parameter is found and \c false if parameter is not found
1445 (in this case \a dVal value is undefined)
1447 bool QtxResourceMgr::value( const QString& sect, const QString& name, double& dVal ) const
1450 if ( !value( sect, name, val, true ) )
1454 dVal = val.toDouble( &ok );
1460 \brief Get boolean parameter value.
1461 \param sect section name
1462 \param name parameter name
1463 \param bVal parameter to return resulting boolean value
1464 \return \c true if parameter is found and \c false if parameter is not found
1465 (in this case \a bVal value is undefined)
1467 bool QtxResourceMgr::value( const QString& sect, const QString& name, bool& bVal ) const
1470 if ( !value( sect, name, val, true ) )
1473 static QMap<QString, bool> boolMap;
1474 if ( boolMap.isEmpty() )
1476 boolMap["true"] = boolMap["yes"] = boolMap["on"] = true;
1477 boolMap["false"] = boolMap["no"] = boolMap["off"] = false;
1480 val = val.toLower();
1481 bool res = boolMap.contains( val );
1483 bVal = boolMap[val];
1486 double num = val.toDouble( &res );
1495 \brief Get color parameter value.
1496 \param sect section name
1497 \param name parameter name
1498 \param cVal parameter to return resulting color value
1499 \return \c true if parameter is found and \c false if parameter is not found
1500 (in this case \a cVal value is undefined)
1502 bool QtxResourceMgr::value( const QString& sect, const QString& name, QColor& cVal ) const
1505 if ( !value( sect, name, val, true ) )
1508 return Qtx::stringToColor( val, cVal );
1512 \brief Get font parameter value.
1513 \param sect section name
1514 \param name parameter name
1515 \param fVal parameter to return resulting font value
1516 \return \c true if parameter is found and \c false if parameter is not found
1517 (in this case \a fVal value is undefined)
1519 bool QtxResourceMgr::value( const QString& sect, const QString& name, QFont& fVal ) const
1522 if ( !value( sect, name, val, true ) )
1525 QStringList fontDescr = val.split( ",", QString::SkipEmptyParts );
1527 if ( fontDescr.count() < 2 )
1530 QString family = fontDescr[0];
1531 if ( family.isEmpty() )
1534 fVal = QFont( family );
1536 for ( int i = 1; i < (int)fontDescr.count(); i++ )
1538 QString curval = fontDescr[i].trimmed().toLower();
1539 if ( curval == QString( "bold" ) )
1540 fVal.setBold( true );
1541 else if ( curval == QString( "italic" ) )
1542 fVal.setItalic( true );
1543 else if ( curval == QString( "underline" ) )
1544 fVal.setUnderline( true );
1545 else if ( curval == QString( "shadow" ) || curval == QString( "overline" ) )
1546 fVal.setOverline( true );
1550 int ps = curval.toInt( &isOk );
1552 fVal.setPointSize( ps );
1560 \brief Get byte array parameter value.
1561 \param sect section name
1562 \param name parameter name
1563 \param baVal parameter to return resulting byte array value
1564 \return \c true if parameter is found and \c false if parameter is not found
1565 (in this case \a baVal value is undefined)
1567 bool QtxResourceMgr::value( const QString& sect, const QString& name, QByteArray& baVal ) const
1570 if ( !value( sect, name, val, true ) )
1574 QStringList lst = val.split( QRegExp( "[\\s|,]" ), QString::SkipEmptyParts );
1575 for ( QStringList::ConstIterator it = lst.begin(); it != lst.end(); ++it )
1579 if ( str.startsWith( "#" ) )
1585 int num = str.toInt( &ok, base );
1586 if ( !ok || num < 0 || num > 255 )
1589 baVal.append( (char)num );
1591 return !baVal.isEmpty();
1595 \brief Get linear gradient parameter value.
1596 \param sect section name
1597 \param name parameter name
1598 \param gVal parameter to return resulting linear gradient value
1599 \return \c true if parameter is found and \c false if parameter is not found
1600 (in this case \a gVal value is undefined)
1602 bool QtxResourceMgr::value( const QString& sect, const QString& name, QLinearGradient& gVal ) const
1605 if ( !value( sect, name, val, true ) )
1608 return Qtx::stringToLinearGradient( val, gVal );
1612 \brief Get radial gradient parameter value.
1613 \param sect section name
1614 \param name parameter name
1615 \param gVal parameter to return resulting radial gradient value
1616 \return \c true if parameter is found and \c false if parameter is not found
1617 (in this case \a gVal value is undefined)
1619 bool QtxResourceMgr::value( const QString& sect, const QString& name, QRadialGradient& gVal ) const
1622 if ( !value( sect, name, val, true ) )
1625 return Qtx::stringToRadialGradient( val, gVal );
1629 \brief Get conical gradient parameter value.
1630 \param sect section name
1631 \param name parameter name
1632 \param gVal parameter to return resulting conical gradient value
1633 \return \c true if parameter is found and \c false if parameter is not found
1634 (in this case \a gVal value is undefined)
1636 bool QtxResourceMgr::value( const QString& sect, const QString& name, QConicalGradient& gVal ) const
1639 if ( !value( sect, name, val, true ) )
1642 return Qtx::stringToConicalGradient( val, gVal );
1646 \brief Get background parameter value.
1647 \param sect section name
1648 \param name parameter name
1649 \param bgVal parameter to return resulting background value
1650 \return \c true if parameter is found and \c false if parameter is not found
1651 (in this case \a bgVal value is undefined)
1653 bool QtxResourceMgr::value( const QString& sect, const QString& name, Qtx::BackgroundData& bgVal ) const
1656 if ( !value( sect, name, val, true ) )
1659 bgVal = Qtx::stringToBackground( val );
1660 return bgVal.isValid();
1664 \brief Get string parameter value (native format).
1665 \param sect section name
1666 \param name parameter name
1667 \param val parameter to return resulting byte array value
1668 \param subst if \c true perform environment variables substitution
1669 \return \c true if parameter is found and \c false if parameter is not found
1670 (in this case \a val value is undefined)
1672 bool QtxResourceMgr::value( const QString& sect, const QString& name, QString& val, const bool subst ) const
1678 ResList::ConstIterator it = myResources.begin();
1679 if ( myHasUserValues && workingMode() == IgnoreUserValues )
1682 for ( ; it != myResources.end() && !ok; ++it )
1684 ok = (*it)->hasValue( sect, name );
1686 val = (*it)->value( sect, name, subst );
1693 \brief Get interger parameter value.
1695 If the specified parameter is not found or can not be converted to the integer value,
1696 the specified default value is returned instead.
1698 \param sect section name
1699 \param name parameter name
1700 \param def default value
1701 \return parameter value (or default value if parameter is not found)
1703 int QtxResourceMgr::integerValue( const QString& sect, const QString& name, const int def ) const
1706 if ( !value( sect, name, val ) )
1712 \brief Get double parameter value.
1714 If the specified parameter is not found or can not be converted to the double value,
1715 the specified default value is returned instead.
1717 \param sect section name
1718 \param name parameter name
1719 \param def default value
1720 \return parameter value (or default value if parameter is not found)
1722 double QtxResourceMgr::doubleValue( const QString& sect, const QString& name, const double def ) const
1725 if ( !value( sect, name, val ) )
1731 \brief Get boolean parameter value.
1733 If the specified parameter is not found or can not be converted to the boolean value,
1734 the specified default value is returned instead.
1736 \param sect section name
1737 \param name parameter name
1738 \param def default value
1739 \return parameter value (or default value if parameter is not found)
1741 bool QtxResourceMgr::booleanValue( const QString& sect, const QString& name, const bool def ) const
1744 if ( !value( sect, name, val ) )
1750 \brief Get font parameter value.
1752 If the specified parameter is not found or can not be converted to the font value,
1753 the specified default value is returned instead.
1755 \param sect section name
1756 \param name parameter name
1757 \param def default value
1758 \return parameter value (or default value if parameter is not found)
1760 QFont QtxResourceMgr::fontValue( const QString& sect, const QString& name, const QFont& def ) const
1763 if( !value( sect, name, font ) )
1769 \brief Get color parameter value.
1771 If the specified parameter is not found or can not be converted to the color value,
1772 the specified default value is returned instead.
1774 \param sect section name
1775 \param name parameter name
1776 \param def default value
1777 \return parameter value (or default value if parameter is not found)
1779 QColor QtxResourceMgr::colorValue( const QString& sect, const QString& name, const QColor& def ) const
1782 if ( !value( sect, name, val ) )
1788 \brief Get string parameter value.
1790 If the specified parameter is not found, the specified default value is returned instead.
1792 \param sect section name
1793 \param name parameter name
1794 \param def default value
1795 \return parameter value (or default value if parameter is not found)
1797 QString QtxResourceMgr::stringValue( const QString& sect, const QString& name, const QString& def ) const
1800 if ( !value( sect, name, val ) )
1806 \brief Get byte array parameter value.
1808 If the specified parameter is not found, the specified default value is returned instead.
1810 \param sect section name
1811 \param name parameter name
1812 \param def default value
1813 \return parameter value (or default value if parameter is not found)
1815 QByteArray QtxResourceMgr::byteArrayValue( const QString& sect, const QString& name, const QByteArray& def ) const
1818 if ( !value( sect, name, val ) )
1824 \brief Get linear gradient parameter value.
1826 If the specified parameter is not found, the specified default value is returned instead.
1828 \param sect section name
1829 \param name parameter name
1830 \param def default value
1831 \return parameter value (or default value if parameter is not found)
1833 QLinearGradient QtxResourceMgr::linearGradientValue( const QString& sect, const QString& name, const QLinearGradient& def ) const
1835 QLinearGradient val;
1836 if ( !value( sect, name, val ) )
1842 \brief Get radial gradient parameter value.
1844 If the specified parameter is not found, the specified default value is returned instead.
1846 \param sect section name
1847 \param name parameter name
1848 \param def default value
1849 \return parameter value (or default value if parameter is not found)
1851 QRadialGradient QtxResourceMgr::radialGradientValue( const QString& sect, const QString& name, const QRadialGradient& def ) const
1853 QRadialGradient val;
1854 if ( !value( sect, name, val ) )
1860 \brief Get conical gradient parameter value.
1862 If the specified parameter is not found, the specified default value is returned instead.
1864 \param sect section name
1865 \param name parameter name
1866 \param def default value
1867 \return parameter value (or default value if parameter is not found)
1869 QConicalGradient QtxResourceMgr::conicalGradientValue( const QString& sect, const QString& name, const QConicalGradient& def ) const
1871 QConicalGradient val;
1872 if ( !value( sect, name, val ) )
1878 \brief Get background parameter value.
1880 If the specified parameter is not found, the specified default value is returned instead.
1882 \param sect section name
1883 \param name parameter name
1884 \param def default value
1885 \return parameter value (or default value if parameter is not found)
1887 Qtx::BackgroundData QtxResourceMgr::backgroundValue( const QString& sect, const QString& name, const Qtx::BackgroundData& def ) const
1889 Qtx::BackgroundData val;
1890 if ( !value( sect, name, val ) )
1896 \brief Check parameter existence.
1897 \param sect section name
1898 \param name parameter name
1899 \return \c true if parameter exists in specified section
1901 bool QtxResourceMgr::hasValue( const QString& sect, const QString& name ) const
1907 ResList::ConstIterator it = myResources.begin();
1908 if ( myHasUserValues && workingMode() == IgnoreUserValues )
1911 for ( ; it != myResources.end() && !ok; ++it )
1912 ok = (*it)->hasValue( sect, name );
1918 \brief Check section existence.
1919 \param sect section name
1920 \return \c true if section exists
1922 bool QtxResourceMgr::hasSection( const QString& sect ) const
1928 ResList::ConstIterator it = myResources.begin();
1929 if ( myHasUserValues && workingMode() == IgnoreUserValues )
1932 for ( ; it != myResources.end() && !ok; ++it )
1933 ok = (*it)->hasSection( sect );
1939 \brief Set integer 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, int val )
1947 if ( checkExisting() && value( sect, name, res ) && res == val )
1950 setResource( sect, name, QString::number( val ) );
1954 \brief Set double 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, double val )
1962 if ( checkExisting() && value( sect, name, res ) && res == val )
1965 setResource( sect, name, QString::number( val, 'g', 12 ) );
1969 \brief Set boolean 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, bool val )
1977 if ( checkExisting() && value( sect, name, res ) && res == val )
1980 setResource( sect, name, QString( val ? "true" : "false" ) );
1984 \brief Set color parameter value.
1985 \param sect section name
1986 \param name parameter name
1987 \param val parameter value
1989 void QtxResourceMgr::setValue( const QString& sect, const QString& name, const QColor& val )
1992 if ( checkExisting() && value( sect, name, res ) && res == val )
1995 setResource( sect, name, Qtx::colorToString( val ) );
1999 \brief Set font parameter value.
2000 \param sect section name
2001 \param name parameter name
2002 \param val parameter value
2004 void QtxResourceMgr::setValue( const QString& sect, const QString& name, const QFont& val )
2007 if ( checkExisting() && value( sect, name, res ) && res == val )
2010 QStringList fontDescr;
2011 fontDescr.append( val.family() );
2013 fontDescr.append( "Bold" );
2015 fontDescr.append( "Italic" );
2016 if ( val.underline() )
2017 fontDescr.append( "Underline" );
2018 if ( val.overline() )
2019 fontDescr.append( "Overline" );
2020 fontDescr.append( QString( "%1" ).arg( val.pointSize() ) );
2022 setResource( sect, name, fontDescr.join( "," ) );
2026 \brief Set string parameter value.
2027 \param sect section name
2028 \param name parameter name
2029 \param val parameter value
2031 void QtxResourceMgr::setValue( const QString& sect, const QString& name, const QString& val )
2034 if ( checkExisting() && value( sect, name, res ) && res == val )
2037 setResource( sect, name, val );
2041 \brief Set byte array parameter value.
2042 \param sect section name
2043 \param name parameter name
2044 \param val parameter value
2046 void QtxResourceMgr::setValue( const QString& sect, const QString& name, const QByteArray& val )
2049 if ( checkExisting() && value( sect, name, res ) && res == val )
2054 for ( int i = 0; i < val.size(); i++ )
2056 ::sprintf( buf, "#%02X", (unsigned char)val.at( i ) );
2057 lst.append( QString( buf ) );
2059 setResource( sect, name, lst.join( " " ) );
2063 \brief Set linear 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 QLinearGradient& val )
2070 QLinearGradient res;
2071 if ( checkExisting() && value( sect, name, res ) && res == val )
2074 setResource( sect, name, Qtx::gradientToString( val ) );
2078 \brief Set radial gradient 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 QRadialGradient& val )
2085 QRadialGradient res;
2086 if ( checkExisting() && value( sect, name, res ) && res == val )
2089 setResource( sect, name, Qtx::gradientToString( val ) );
2093 \brief Set conical gradient parameter value.
2094 \param sect section name
2095 \param name parameter name
2096 \param val parameter value
2098 void QtxResourceMgr::setValue( const QString& sect, const QString& name, const QConicalGradient& val )
2100 QConicalGradient res;
2101 if ( checkExisting() && value( sect, name, res ) && res == val )
2104 setResource( sect, name, Qtx::gradientToString( val ) );
2108 \brief Set background parameter value.
2109 \param sect section name
2110 \param name parameter name
2111 \param val parameter value
2113 void QtxResourceMgr::setValue( const QString& sect, const QString& name, const Qtx::BackgroundData& val )
2115 Qtx::BackgroundData res;
2116 if ( checkExisting() && value( sect, name, res ) && res == val )
2119 setResource( sect, name, Qtx::backgroundToString( val ) );
2123 \brief Remove resources section.
2124 \param sect section name
2126 void QtxResourceMgr::remove( const QString& sect )
2130 for ( ResList::Iterator it = myResources.begin(); it != myResources.end(); ++it )
2131 (*it)->removeSection( sect );
2135 \brief Remove the specified parameter.
2136 \param sect section name
2137 \param name parameter name
2139 void QtxResourceMgr::remove( const QString& sect, const QString& name )
2143 for ( ResList::Iterator it = myResources.begin(); it != myResources.end(); ++it )
2144 (*it)->removeValue( sect, name );
2148 \brief Get current configuration files format.
2149 \return configuration files format name
2151 QString QtxResourceMgr::currentFormat() const
2154 if ( !myFormats.isEmpty() )
2155 fmt = myFormats[0]->format();
2160 \brief Set current configuration files format.
2161 \param fmt configuration files format name
2163 void QtxResourceMgr::setCurrentFormat( const QString& fmt )
2165 Format* form = format( fmt );
2169 myFormats.removeAll( form );
2170 myFormats.prepend( form );
2172 if ( myResources.isEmpty() )
2175 ResList::Iterator resIt = myResources.begin();
2176 if ( myResources.count() > myDirList.count() && resIt != myResources.end() )
2178 (*resIt)->setFile( userFileName( appName() ) );
2182 for ( QStringList::ConstIterator it = myDirList.begin(); it != myDirList.end() && resIt != myResources.end(); ++it, ++resIt )
2183 (*resIt)->setFile( Qtx::addSlash( *it ) + globalFileName( appName() ) );
2187 \brief Get configuration files format by specified format name.
2188 \param fmt configuration files format name
2189 \return format object or 0 if format is not defined
2191 QtxResourceMgr::Format* QtxResourceMgr::format( const QString& fmt ) const
2194 for ( FormatList::ConstIterator it = myFormats.begin(); it != myFormats.end() && !form; ++it )
2196 if ( (*it)->format() == fmt )
2204 \brief Install configuration files format.
2206 Added format becomes current.
2208 \param form format object to be installed
2210 void QtxResourceMgr::installFormat( QtxResourceMgr::Format* form )
2212 if ( !myFormats.contains( form ) )
2213 myFormats.prepend( form );
2217 \brief Remove configuration files format.
2218 \param form format object to be uninstalled
2220 void QtxResourceMgr::removeFormat( QtxResourceMgr::Format* form )
2222 myFormats.removeAll( form );
2226 \brief Get resource format options names.
2227 \return list of options names
2229 QStringList QtxResourceMgr::options() const
2231 return myOptions.keys();
2235 \brief Get the string value of the specified resources format option.
2237 If option does not exist, null QString is returned.
2239 \param opt option name
2240 \return option value
2241 \sa setOption(), options()
2243 QString QtxResourceMgr::option( const QString& opt ) const
2246 if ( myOptions.contains( opt ) )
2247 val = myOptions[opt];
2252 \brief Set the string value of the specified resources format option.
2253 \param opt option name
2254 \param val option value
2255 \sa option(), options()
2257 void QtxResourceMgr::setOption( const QString& opt, const QString& val )
2259 myOptions.insert( opt, val );
2263 \brief Load all resources from all resource files (global and user).
2264 \return \c true on success and \c false on error
2267 bool QtxResourceMgr::load()
2269 initialize( false );
2271 Format* fmt = format( currentFormat() );
2276 for ( ResList::Iterator it = myResources.begin(); it != myResources.end(); ++it )
2277 res = fmt->load( *it ) && res;
2283 \brief Import resources from specified resource file.
2284 \param fname resources file name
2285 \return \c true on success and \c false on error
2287 bool QtxResourceMgr::import( const QString& fname )
2289 Format* fmt = format( currentFormat() );
2293 if ( myResources.isEmpty() || !myHasUserValues )
2296 Resources* r = myResources[0];
2300 QString old = r->file();
2301 r->setFile( fname );
2302 bool res = fmt->load( r );
2308 \brief Save all resources to the user resource files.
2309 \return \c true on success and \c false on error
2311 bool QtxResourceMgr::save()
2313 initialize( false );
2315 Format* fmt = format( currentFormat() );
2319 if ( myResources.isEmpty() || !myHasUserValues )
2322 bool result = fmt->save( myResources[0] );
2330 \brief Get all sections names.
2331 \return list of section names
2333 QStringList QtxResourceMgr::sections() const
2337 QMap<QString, int> map;
2339 ResList::ConstIterator it = myResources.begin();
2340 if ( myHasUserValues && workingMode() == IgnoreUserValues )
2343 for ( ; it != myResources.end(); ++it )
2345 QStringList lst = (*it)->sections();
2346 for ( QStringList::ConstIterator itr = lst.begin(); itr != lst.end(); ++itr )
2347 map.insert( *itr, 0 );
2354 \brief Get all sections names matching specified regular expression.
2355 \param re searched regular expression
2356 \return list of sections names
2358 QStringList QtxResourceMgr::sections(const QRegExp& re) const
2360 return sections().filter( re );
2364 \brief Get all sections names with the prefix specified by passed
2365 list of parent sections names.
2367 Sub-sections are separated inside the section name by the sections
2368 separator token, for example "splash:color:label".
2370 \param names parent sub-sections names
2371 \return list of sections names
2373 QStringList QtxResourceMgr::sections(const QStringList& names) const
2375 QStringList nm = names;
2377 QRegExp re( QString( "^%1$" ).arg( nm.join( sectionsToken() ) ) );
2378 return sections( re );
2382 \brief Get list of sub-sections names for the specified parent section name.
2384 Sub-sections are separated inside the section name by the sections
2385 separator token, for example "splash:color:label".
2387 \param section parent sub-section name
2388 \param full if \c true return full names of child sub-sections, if \c false,
2389 return only top-level sub-sections names
2390 \return list of sub-sections names
2392 QStringList QtxResourceMgr::subSections(const QString& section, const bool full) const
2394 QStringList names = sections( QStringList() << section );
2395 QMutableListIterator<QString> it( names );
2396 while ( it.hasNext() ) {
2397 QString name = it.next().mid( section.size() + 1 ).trimmed();
2398 if ( name.isEmpty() ) {
2402 if ( !full ) name = name.split( sectionsToken() ).first();
2403 it.setValue( name );
2405 names.removeDuplicates();
2411 \brief Get all parameters name in specified section.
2412 \param sec section name
2413 \return list of settings names
2415 QStringList QtxResourceMgr::parameters( const QString& sec ) const
2419 #if defined(QTX_NO_INDEXED_MAP)
2420 typedef QMap<QString, int> PMap;
2422 typedef IMap<QString, int> PMap;
2426 Resources* ur = !myResources.isEmpty() && workingMode() == IgnoreUserValues ? myResources[0] : 0;
2428 QListIterator<Resources*> it( myResources );
2430 while ( it.hasPrevious() )
2432 Resources* r = it.previous();
2433 if ( r == ur ) break;
2434 QStringList lst = r->parameters( sec );
2435 for ( QStringList::ConstIterator itr = lst.begin(); itr != lst.end(); ++itr )
2436 #if defined(QTX_NO_INDEXED_MAP)
2437 if ( !pmap.contains( *itr ) ) pmap.insert( *itr, 0 );
2439 pmap.insert( *itr, 0, false );
2447 \brief Get all parameters name in specified
2448 list of sub-sections names.
2450 Sub-sections are separated inside the section name by the sections
2451 separator token, for example "splash:color:label".
2453 \param names parent sub-sections names
2454 \return list of settings names
2456 QStringList QtxResourceMgr::parameters( const QStringList& names ) const
2458 return parameters( names.join( sectionsToken() ) );
2462 \brief Get absolute path to the file which name is defined by the parameter.
2464 The file name is defined by \a name argument, while directory name is retrieved
2465 from resources parameter \a prefix of section \a sec. Both directory and file name
2466 can be relative. If the directory is relative, it is calculated from the initial
2467 resources file name. Directory parameter can contain environment
2468 variables, which are substituted automatically.
2470 \param sec section name
2471 \param prefix parameter containing directory name
2472 \param name file name
2473 \return absolute file path or null QString if file does not exist
2475 QString QtxResourceMgr::path( const QString& sect, const QString& prefix, const QString& name ) const
2479 ResList::ConstIterator it = myResources.begin();
2480 if ( myHasUserValues && workingMode() == IgnoreUserValues )
2483 for ( ; it != myResources.end() && res.isEmpty(); ++it )
2484 res = (*it)->path( sect, prefix, name );
2489 \brief Get application resources section name.
2491 By default, application resources section name is "resources" but
2492 it can be changed by setting the "res_section_name" resources manager option.
2494 \return section corresponding to the resources directories
2495 \sa option(), setOption()
2497 QString QtxResourceMgr::resSection() const
2499 QString res = option( "res_section_name" );
2500 if ( res.isEmpty() )
2501 res = QString( "resources" );
2506 \brief Get application language section name.
2508 By default, application language section name is "language" but
2509 it can be changed by setting the "lang_section_name" resources manager option.
2511 \return section corresponding to the application language settings
2512 \sa option(), setOption()
2514 QString QtxResourceMgr::langSection() const
2516 QString res = option( "lang_section_name" );
2517 if ( res.isEmpty() )
2518 res = QString( "language" );
2523 \brief Get sections separator token.
2525 By default, sections separator token is colon symbol ":" but
2526 it can be changed by setting the "section_token" resources manager option.
2528 \return string corresponding to the current section separator token
2529 \sa option(), setOption()
2531 QString QtxResourceMgr::sectionsToken() const
2533 QString res = option( "section_token" );
2534 if ( res.isEmpty() )
2535 res = QString( ":" );
2540 \brief Get default pixmap.
2542 Default pixmap is used when requested pixmap resource is not found.
2544 \return default pixmap
2545 \sa setDefaultPixmap(), loadPixmap()
2547 QPixmap QtxResourceMgr::defaultPixmap() const
2549 static QPixmap* defpx = 0;
2551 defpx = new QPixmap( pixmap_not_found_xpm );
2553 return myDefaultPix ? *myDefaultPix : *defpx;
2557 \brief Set default pixmap.
2559 Default pixmap is used when requested pixmap resource is not found.
2561 \param pix default pixmap
2562 \sa defaultPixmap(), loadPixmap()
2564 void QtxResourceMgr::setDefaultPixmap( const QPixmap& pix )
2566 delete myDefaultPix;
2570 myDefaultPix = new QPixmap( pix );
2574 \brief Load pixmap resource.
2575 \param prefix parameter which refers to the resources directory (directories)
2576 \param name pixmap file name
2577 \return pixmap loaded from the file
2578 \sa defaultPixmap(), setDefaultPixmap()
2580 QPixmap QtxResourceMgr::loadPixmap( const QString& prefix, const QString& name ) const
2582 return loadPixmap( prefix, name, true );
2586 \brief Load pixmap resource.
2588 \param prefix parameter which refers to the resources directory (directories)
2589 \param name pixmap file name
2590 \param useDef if \c false, default pixmap is not returned if resource is not found,
2591 in this case null pixmap is returned instead
2592 \return pixmap loaded from the file
2593 \sa defaultPixmap(), setDefaultPixmap()
2595 QPixmap QtxResourceMgr::loadPixmap( const QString& prefix, const QString& name, const bool useDef ) const
2597 return loadPixmap( prefix, name, useDef ? defaultPixmap() : QPixmap() );
2601 \brief Load pixmap resource.
2603 \param prefix parameter which refers to the resources directory (directories)
2604 \param name pixmap file name
2605 \param defPix default which should be used if the resource file doesn't exist
2606 \return pixmap loaded from the file
2607 \sa defaultPixmap(), setDefaultPixmap()
2609 QPixmap QtxResourceMgr::loadPixmap( const QString& prefix, const QString& name, const QPixmap& defPix ) const
2615 ResList::ConstIterator it = myResources.begin();
2616 if ( myHasUserValues && workingMode() == IgnoreUserValues )
2619 for ( ; it != myResources.end() && pix.isNull(); ++it )
2620 pix = (*it)->loadPixmap( resSection(), prefix, name );
2627 \brief Load translation files according to the specified language.
2629 Names of the translation files are calculated according to the pattern specified
2630 by the "translators" option (this option is read from the section "language" of resources files).
2631 By default, "%P_msg_%L.qm" pattern is used.
2632 Keywords \%A, \%P, \%L in the pattern are substituted by the application name, prefix and language name
2634 For example, for prefix "SUIT" and language "en", all translation files "SUIT_msg_en.qm" are searched and
2637 If prefix is empty or null string, all translation files specified in the "resources" section of resources
2638 files are loaded (actually, the section is retrieved from resSection() method).
2639 If language is not specified, it is retrieved from the langSection() method, and if the latest is also empty,
2640 by default "en" (English) language is used.
2641 By default, settings from the user preferences file are also loaded (if user resource file is valid,
2642 see userFileName()). To avoid loading user settings, pass \c false as first parameter.
2644 \param pref parameter which defines translation context (for example, package name)
2645 \param l language name
2647 \sa resSection(), langSection(), loadTranslators()
2649 void QtxResourceMgr::loadLanguage( const QString& pref, const QString& l )
2653 QMap<QChar, QString> substMap;
2654 substMap.insert( 'A', appName() );
2657 if ( lang.isEmpty() )
2658 value( langSection(), "language", lang );
2660 if ( lang.isEmpty() )
2662 lang = QString( "en" );
2663 qWarning() << "QtxResourceMgr: Language not specified. Assumed:" << lang;
2666 substMap.insert( 'L', lang );
2669 if ( value( langSection(), "translators", trs, false ) && !trs.isEmpty() )
2671 QStringList translators = option( "translators" ).split( "|", QString::SkipEmptyParts );
2672 QStringList newTranslators = trs.split( "|", QString::SkipEmptyParts );
2673 for ( int i = 0; i < (int)newTranslators.count(); i++ )
2675 if ( translators.indexOf( newTranslators[i] ) < 0 )
2676 translators += newTranslators[i];
2678 setOption( "translators", translators.join( "|" ) );
2681 QStringList trList = option( "translators" ).split( "|", QString::SkipEmptyParts );
2682 if ( trList.isEmpty() )
2684 trList.append( "%P_msg_%L.qm" );
2685 qWarning() << "QtxResourceMgr: Translators not defined. Assumed:" << trList[0];
2688 QStringList prefixList;
2689 if ( !pref.isEmpty() )
2690 prefixList.append( pref );
2692 prefixList = parameters( resSection() );
2694 if ( pref.isEmpty() && lang != "en" ) {
2695 // load Qt resources
2696 QString qt_translations = QLibraryInfo::location( QLibraryInfo::TranslationsPath );
2697 QString qt_dir_trpath;
2698 if ( ::getenv( "QTDIR" ) )
2699 qt_dir_trpath = QString( ::getenv( "QTDIR" ) );
2700 if ( !qt_dir_trpath.isEmpty() )
2701 qt_dir_trpath = QDir( qt_dir_trpath ).absoluteFilePath( "translations" );
2703 QTranslator* trans = new QtxTranslator( 0 );
2704 if ( trans->load( QString("qt_%1").arg( lang ), qt_translations ) || trans->load( QString("qt_%1").arg( lang ), qt_dir_trpath ) )
2705 QApplication::instance()->installTranslator( trans );
2708 for ( QStringList::ConstIterator iter = prefixList.begin(); iter != prefixList.end(); ++iter )
2710 QString prefix = *iter;
2711 substMap.insert( 'P', prefix );
2714 for ( QStringList::ConstIterator it = trList.begin(); it != trList.end(); ++it )
2715 trs.append( substMacro( *it, substMap ).trimmed() );
2717 loadTranslators( prefix, trs );
2722 \brief Load translation files for the specified translation context.
2723 \param prefix parameter which defines translation context (for example, package name)
2724 \param translators list of translation files
2727 void QtxResourceMgr::loadTranslators( const QString& prefix, const QStringList& translators )
2733 ResList::ConstIterator iter = myResources.begin();
2734 if ( myHasUserValues && workingMode() == IgnoreUserValues )
2737 for ( ; iter != myResources.end(); ++iter )
2738 lst.prepend( *iter );
2740 QTranslator* trans = 0;
2742 for ( ResList::Iterator it = lst.begin(); it != lst.end(); ++it )
2744 for ( QStringList::ConstIterator itr = translators.begin(); itr != translators.end(); ++itr )
2746 trans = (*it)->loadTranslator( resSection(), prefix, *itr );
2749 if ( !myTranslator[prefix].contains( trans ) )
2750 myTranslator[prefix].append( trans );
2751 QApplication::instance()->installTranslator( trans );
2758 \brief Load translation file.
2759 \param prefix parameter which defines translation context (for example, package name)
2760 \param name translator file name
2761 \sa loadLanguage(), loadTranslators()
2763 void QtxResourceMgr::loadTranslator( const QString& prefix, const QString& name )
2767 QTranslator* trans = 0;
2769 Resources* ur = !myResources.isEmpty() && workingMode() == IgnoreUserValues ? myResources[0] : 0;
2771 QListIterator<Resources*> it( myResources );
2773 while ( it.hasPrevious() )
2775 Resources* r = it.previous();
2776 if ( r == ur ) break;
2778 trans = r->loadTranslator( resSection(), prefix, name );
2781 if ( !myTranslator[prefix].contains( trans ) )
2782 myTranslator[prefix].append( trans );
2783 QApplication::instance()->installTranslator( trans );
2789 \brief Remove all translators corresponding to the specified translation context.
2790 \param prefix parameter which defines translation context (for example, package name)
2792 void QtxResourceMgr::removeTranslators( const QString& prefix )
2794 if ( !myTranslator.contains( prefix ) )
2797 for ( TransList::Iterator it = myTranslator[prefix].begin(); it != myTranslator[prefix].end(); ++it )
2799 QApplication::instance()->removeTranslator( *it );
2803 myTranslator.remove( prefix );
2807 \brief Move all translators corresponding to the specified translation context
2808 to the top of translators stack (increase their priority).
2809 \param prefix parameter which defines translation context (for example, package name)
2811 void QtxResourceMgr::raiseTranslators( const QString& prefix )
2813 if ( !myTranslator.contains( prefix ) )
2816 for ( TransList::Iterator it = myTranslator[prefix].begin(); it != myTranslator[prefix].end(); ++it )
2818 QApplication::instance()->removeTranslator( *it );
2819 QApplication::instance()->installTranslator( *it );
2824 \brief Copy all parameters to the user resources in order to
2825 saved them lately in the user home folder.
2827 void QtxResourceMgr::refresh()
2829 QStringList sl = sections();
2830 for ( QStringList::ConstIterator it = sl.begin(); it != sl.end(); ++it )
2832 QStringList pl = parameters( *it );
2833 for ( QStringList::ConstIterator itr = pl.begin(); itr != pl.end(); ++itr )
2834 setResource( *it, *itr, stringValue( *it, *itr ) );
2839 \brief Set the resource directories (where global confguration files are searched).
2841 This function also clears all currently set resources.
2843 \param dl directories list
2845 void QtxResourceMgr::setDirList( const QStringList& dl )
2848 for ( ResList::Iterator it = myResources.begin(); it != myResources.end(); ++it )
2851 myResources.clear();
2855 \brief Set parameter value.
2856 \param sect section name
2857 \param name parameter name
2858 \param val parameter value
2860 void QtxResourceMgr::setResource( const QString& sect, const QString& name, const QString& val )
2864 if ( !myResources.isEmpty() && myHasUserValues )
2865 myResources.first()->setValue( sect, name, val );
2869 \brief Get user configuration file name.
2871 This method can be redefined in the successor class to customize the user configuration file name.
2872 User configuration file is always situated in the user's home directory. By default .<appName>rc
2873 file is used on Linux (e.g. .MyApprc) and <appName>.<format> under Windows (e.g. MyApp.xml).
2875 Parameter \a for_load (not used in default implementation) specifies the usage mode, i.e. if
2876 user configuration file is opened for reading or writing. This allows customizing a way of application
2877 resources initializing (for example, if the user configuraion file includes version number and there is
2878 no file corresponding to this version in the user's home directory, it could be good idea to try
2879 the configuration file from the previous versions of the application).
2881 \param appName application name
2882 \param for_load boolean flag indicating that file is opened for loading or saving (not used in default implementation)
2883 \return user configuration file name
2884 \sa globalFileName()
2886 QString QtxResourceMgr::userFileName( const QString& appName, const bool /*for_load*/ ) const
2889 QString pathName = QDir::homePath();
2890 QString cfgAppName = QApplication::applicationName();
2891 if ( !cfgAppName.isEmpty() )
2892 pathName = Qtx::addSlash( Qtx::addSlash( pathName ) + QString( ".config" ) ) + cfgAppName;
2895 fileName = QString( "%1.%2" ).arg( appName ).arg( currentFormat() );
2897 fileName = QString( "%1rc" ).arg( appName );
2898 // VSR 24/09/2012: issue 0021781: do not prepend filename with "."
2899 // when user file is stored in ~/.config/<appname> directory
2900 if ( cfgAppName.isEmpty() )
2901 fileName.prepend( "." );
2904 if ( !fileName.isEmpty() )
2905 pathName = Qtx::addSlash( pathName ) + fileName;
2911 \brief Get global configuration file name.
2913 This method can be redefined in the successor class to customize the global configuration file name.
2914 Global configuration files are searched in the directories specified by the application resources
2915 environment variable (e.g. MyAppResources). By default <appName>.<format> file name is used
2918 \param appName application name
2919 \return global configuration file name
2922 QString QtxResourceMgr::globalFileName( const QString& appName ) const
2924 return QString( "%1.%2" ).arg( appName ).arg( currentFormat() );
2928 \brief This function is called after user configuration file is saved.
2929 Can be redefined in the successor classes, default implementation does nothing.
2931 void QtxResourceMgr::saved()
2936 \brief Perform substitution of the patterns like \%A, \%B, etc by values from the map.
2938 Used by loadLanguage().
2940 \param src sring to be processed
2941 \param substMap map of values for replacing
2942 \return processed string
2944 QString QtxResourceMgr::substMacro( const QString& src, const QMap<QChar, QString>& substMap ) const
2948 QRegExp rx( "%[A-Za-z%]" );
2951 while ( ( idx = rx.indexIn( trg, idx ) ) >= 0 )
2953 QChar spec = trg.at( idx + 1 );
2957 else if ( substMap.contains( spec ) )
2958 subst = substMap[spec];
2960 if ( !subst.isEmpty() )
2962 trg.replace( idx, rx.matchedLength(), subst );
2963 idx += subst.length();
2966 idx += rx.matchedLength();