1 // Copyright (C) 2007-2022 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"
33 #include <QJsonDocument>
34 #include <QJsonObject>
36 #include <QTextStream>
37 #include <QApplication>
38 #include <QLibraryInfo>
41 #include <QDomDocument>
42 #include <QDomElement>
48 /* XPM for the default pixmap */
49 static const char* pixmap_not_found_xpm[] = {
72 \class QtxResourceMgr::Resources
74 \brief Represents container for settings read from the resource file.
77 class QtxResourceMgr::Resources
80 typedef QMap<QString, Section> SectionMap;
81 typedef QMap<QString, QString> OptionsMap;
84 Resources( QtxResourceMgr*, const QString& );
88 void setFile( const QString& );
90 QString value( const QString&, const QString&, const bool, const OptionsMap& ) const;
91 void setValue( const QString&, const QString&, const QString& );
93 bool hasSection( const QString& ) const;
94 bool hasValue( const QString&, const QString& ) const;
96 void removeSection( const QString& );
97 void removeValue( const QString&, const QString& );
99 QPixmap loadPixmap( const QString&, const QString&, const QString&, const OptionsMap& ) const;
100 QTranslator* loadTranslator( const QString&, const QString&, const QString&, const OptionsMap& ) const;
104 QStringList sections() const;
105 QStringList parameters( const QString& ) const;
107 QString path( const QString&, const QString&, const QString&, const OptionsMap& ) const;
110 QtxResourceMgr* resMgr() const;
113 Section section( const QString& );
114 const Section section( const QString& ) const;
116 QString makeSubstitution( const QString&, const QString&, const QString&, const OptionsMap& ) const;
118 QString fileName( const QString&, const QString&, const QString&, const OptionsMap& ) const;
121 QtxResourceMgr* myMgr; //!< resources manager
122 SectionMap mySections; //!< sections map
123 QString myFileName; //!< resources file name
124 QMap<QString,QPixmap> myPixmapCache; //!< pixmaps cache
126 friend class QtxResourceMgr::Format;
131 \param mgr parent resources manager
132 \param fileName resources file name
134 QtxResourceMgr::Resources::Resources( QtxResourceMgr* mgr, const QString& fileName )
136 myFileName( fileName )
143 QtxResourceMgr::Resources::~Resources()
148 \brief Get resources file name.
150 This file is used to load/save operations.
155 QString QtxResourceMgr::Resources::file() const
161 \brief Set resources file name.
165 void QtxResourceMgr::Resources::setFile( const QString& fn )
171 \brief Get string representation of parameter value.
172 \param sect section name
173 \param name parameter name
174 \param subst if \c true, perform variables substitution
175 \return parameter value or null QString if there is no such parameter
176 \sa setValue(), makeSubstitution()
178 QString QtxResourceMgr::Resources::value( const QString& sect, const QString& name, const bool subst, const OptionsMap& constants ) const
182 if ( hasValue( sect, name ) )
184 val = section( sect )[name];
186 val = makeSubstitution( val, sect, name, constants );
192 \brief Set parameter value.
193 \param sect section name
194 \param name parameter name
195 \param val parameter value
196 \sa value(), makeSubstitution()
198 void QtxResourceMgr::Resources::setValue( const QString& sect, const QString& name, const QString& val )
200 if ( !mySections.contains( sect ) )
201 mySections.insert( sect, Section() );
203 mySections[sect].insert( name, val );
207 \brief Check section existence.
208 \param sect section name
209 \return \c true if section exists
211 bool QtxResourceMgr::Resources::hasSection( const QString& sect ) const
213 return mySections.contains( sect );
217 \brief Check parameter existence.
218 \param sect section name
219 \param name parameter name
220 \return \c true if parameter exists in specified section
222 bool QtxResourceMgr::Resources::hasValue( const QString& sect, const QString& name ) const
224 return hasSection( sect ) && section( sect ).contains( name );
228 \brief Remove resourcs section.
229 \param sect secton name
231 void QtxResourceMgr::Resources::removeSection( const QString& sect )
233 mySections.remove( sect );
237 \brief Remove parameter from the section.
238 \param sect section name
239 \param name parameter name
241 void QtxResourceMgr::Resources::removeValue( const QString& sect, const QString& name )
243 if ( !mySections.contains( sect ) )
246 mySections[sect].remove( name );
248 if ( mySections[sect].isEmpty() )
249 mySections.remove( sect );
253 \brief Remove all sections.
255 void QtxResourceMgr::Resources::clear()
261 \brief Get all sections names.
262 \return list of section names
264 QStringList QtxResourceMgr::Resources::sections() const
266 return mySections.keys();
270 \brief Get all parameters name in specified section.
271 \param sec section name
272 \return list of settings names
274 QStringList QtxResourceMgr::Resources::parameters( const QString& sec ) const
276 if ( !hasSection( sec ) )
277 return QStringList();
279 return section( sec ).keys();
283 \brief Get absolute path to the file which name is defined by the parameter.
285 The file name is defined by \a name argument, while directory name is retrieved
286 from resources parameter \a prefix of section \a sec. Both directory and file name
287 can be relative. If the directory is relative, it is calculated from the initial
288 resources file name (see file()). Directory parameter can contain environment
289 variables, which are substituted automatically.
291 \param sec section name
292 \param prefix parameter containing directory name
293 \param name file name
294 \return absolute file path or null QString if file does not exist
295 \sa fileName(), file(), makeSubstitution()
297 QString QtxResourceMgr::Resources::path( const QString& sec, const QString& prefix, const QString& name, const OptionsMap& constants ) const
299 QString filePath = fileName( sec, prefix, name, constants );
300 if ( !filePath.isEmpty() )
302 if ( !QFileInfo( filePath ).exists() )
303 filePath = QString();
309 \brief Get resource manager
310 \return resource manager pointer
312 QtxResourceMgr* QtxResourceMgr::Resources::resMgr() const
318 \brief Get resources section by specified name.
320 If section does not exist it is created (empty).
322 \param sn section name
323 \return resources section
325 QtxResourceMgr::Section QtxResourceMgr::Resources::section( const QString& sn )
327 if ( !mySections.contains( sn ) )
328 mySections.insert( sn, Section() );
330 return mySections[sn];
334 \brief Get resources section by specified name.
335 \param sn section name
336 \return resources section
338 const QtxResourceMgr::Section QtxResourceMgr::Resources::section( const QString& sn ) const
340 return mySections[sn];
344 \brief Get file path.
346 The file name is defined by \a name argument, while directory name is retrieved
347 from resources parameter \a prefix of section \a sec. Both directory and file name
348 can be relative. If the directory is relative, it is calculated from the initial
349 resources file name (see file()). Directory parameter can contain environment
350 variables, which are substituted automatically.
351 File existence is not checked.
353 \param sec section name
354 \param prefix parameter containing directory name
355 \param name file name
356 \return absolute file path or null QString if \a prefix parameter
357 does not exist in section \sec
358 \sa path(), file(), makeSubstitution()
360 QString QtxResourceMgr::Resources::fileName( const QString& sect, const QString& prefix, const QString& name, const OptionsMap& constants ) const
363 if ( !QFileInfo( name ).isRelative() )
369 if ( hasValue( sect, prefix ) )
371 path = value( sect, prefix, true, constants );
372 if ( !path.isEmpty() )
374 if ( QFileInfo( path ).isRelative() )
375 path = Qtx::addSlash( Qtx::dir( myFileName, true ) ) + path;
377 path = Qtx::addSlash( path ) + name;
381 if( !path.isEmpty() )
383 QString fname = QDir::toNativeSeparators( path );
384 QFileInfo inf( fname );
385 fname = inf.absoluteFilePath();
392 \brief Load and return pixmap from external file.
394 If QtxResourceMgr::isPixmapCached() is \c true then cached pixmap is returned
395 (if it is already loaded), otherwise it is loaded from file.
396 If the file name is invalid, null pixmap is returned.
398 \param sect section name
399 \param prefix parameter containing resources directory name
400 \param name pixmap file name
401 \return pixmap loaded from file
403 QPixmap QtxResourceMgr::Resources::loadPixmap( const QString& sect, const QString& prefix, const QString& name, const OptionsMap& constants ) const
405 QString fname = fileName( sect, prefix, name, constants );
406 bool toCache = resMgr() ? resMgr()->isPixmapCached() : false;
408 if( toCache && myPixmapCache.contains( fname ) )
409 p = myPixmapCache[fname];
414 ( ( QMap<QString,QPixmap>& )myPixmapCache ).insert( fname, p );
420 \brief Load translator.
421 \param sect section name
422 \param prefix parameter containing resources directory
423 \param name translation file name
424 \return just created and loaded translator or 0 in case of error
426 QTranslator* QtxResourceMgr::Resources::loadTranslator( const QString& sect, const QString& prefix, const QString& name, const OptionsMap& constants ) const
428 QTranslator* trans = new QtxTranslator( 0 );
429 QString fname = QDir::toNativeSeparators( fileName( sect, prefix, name, constants ) );
430 if ( !trans->load( Qtx::file( fname, false ), Qtx::dir( fname ) ) )
439 \brief Substitute variables by their values.
441 Environment variable is substituted by its value. For other variables resource
442 manager tries to find value among defined resources parameters.
444 \param str string to be processed
445 \param sect section, where variables are searched
446 \param name name of variable which must be ignored during substitution
447 \return processed string (with all substitutions made)
449 QString QtxResourceMgr::Resources::makeSubstitution( const QString& str, const QString& sect, const QString& name, const OptionsMap& constants ) const
453 QMap<QString, int> ignoreMap;
454 ignoreMap.insert( name, 0 );
456 int start( 0 ), len( 0 );
459 QString envName = Qtx::findEnvVar( res, start, len );
460 if ( envName.isNull() )
463 // First we look in the constants map
464 QString newStr = constants.value( envName, QString() );
466 // Then we check for environment variable
467 QString tmpValue = Qtx::getenv( envName );
468 if ( newStr.isEmpty() && !tmpValue.isEmpty() )
471 if ( newStr.isEmpty() )
473 if ( ignoreMap.contains( envName ) )
479 if ( hasValue( sect, envName ) )
480 newStr = value( sect, envName, false, constants );
481 ignoreMap.insert( envName, 0 );
483 res.replace( start, len, newStr );
486 res.replace( "$$", "$" );
487 res.replace( "%%", "%" );
493 \class QtxResourceMgr::IniFormat
495 \brief Reader/writer for .ini resources files.
498 class QtxResourceMgr::IniFormat : public Format
505 virtual bool load( const QString&, QMap<QString, Section>& );
506 virtual bool save( const QString&, const QMap<QString, Section>& );
509 bool load( const QString&, QMap<QString, Section>&, QSet<QString>& );
515 QtxResourceMgr::IniFormat::IniFormat()
523 QtxResourceMgr::IniFormat::~IniFormat()
528 \brief Load resources from ini-file.
529 \param fname resources file name
530 \param secMap resources map to be filled in
531 \return \c true on success and \c false on error
533 bool QtxResourceMgr::IniFormat::load( const QString& fname, QMap<QString, Section>& secMap )
535 QSet<QString> importHistory;
536 return load( fname, secMap, importHistory );
541 \brief Load resources from ini-file.
542 \param fname resources file name
543 \param secMap resources map to be filled in
544 \param importHistory list of already imported resources files (to prevent import loops)
545 \return \c true on success or \c false on error
547 bool QtxResourceMgr::IniFormat::load( const QString& fname, QMap<QString, Section>& secMap, QSet<QString>& importHistory )
549 QString aFName = fname.trimmed();
550 if ( !QFileInfo( aFName ).exists() )
552 if ( QFileInfo( aFName + ".ini" ).exists() )
554 else if ( QFileInfo( aFName + ".INI" ).exists() )
557 return false; // file does not exist
559 QFileInfo aFinfo( aFName );
560 aFName = aFinfo.canonicalFilePath();
562 if ( !importHistory.contains( aFName ) )
563 importHistory.insert( aFName );
565 return true; // already imported (prevent import loops)
567 QFile file( aFName );
568 if ( !file.open( QFile::ReadOnly ) )
569 return false; // file is not accessible
571 QTextStream ts( &file );
578 QString separator = option( "separator" );
579 if ( separator.isNull() )
580 separator = QString( "=" );
582 QString comment = option( "comment" );
583 if ( comment.isNull() )
584 comment = QString( "#" );
588 data = ts.readLine();
594 data = data.trimmed();
595 if ( data.isEmpty() )
598 if ( data.startsWith( comment ) )
601 QRegExp rx( "^\\[([\\w\\s\\._]*)\\]$" );
602 if ( rx.indexIn( data ) != -1 )
604 section = rx.cap( 1 );
605 if ( section.isEmpty() )
608 qWarning() << "QtxResourceMgr: Empty section in line:" << line;
611 else if ( data.contains( separator ) && !section.isEmpty() )
613 int pos = data.indexOf( separator );
614 QString key = data.left( pos ).trimmed();
615 QString val = data.mid( pos + 1 ).trimmed();
616 secMap[section].insert( key, val );
618 else if ( section == "import" )
620 QString impFile = QDir::toNativeSeparators( Qtx::makeEnvVarSubst( data, Qtx::Always ) );
621 QFileInfo impFInfo( impFile );
622 if ( impFInfo.isRelative() )
623 impFInfo.setFile( aFinfo.absoluteDir(), impFile );
625 QMap<QString, Section> impMap;
626 if ( !load( impFInfo.absoluteFilePath(), impMap, importHistory ) )
628 qDebug() << "QtxResourceMgr: Error with importing file:" << data;
632 QMap<QString, Section>::const_iterator it = impMap.constBegin();
633 for ( ; it != impMap.constEnd() ; ++it )
635 if ( !secMap.contains( it.key() ) )
637 // insert full section
638 secMap.insert( it.key(), it.value() );
642 // insert all parameters from the section
643 Section::ConstIterator paramIt = it.value().begin();
644 for ( ; paramIt != it.value().end() ; ++paramIt )
646 if ( !secMap[it.key()].contains( paramIt.key() ) )
647 secMap[it.key()].insert( paramIt.key(), paramIt.value() );
656 if ( section.isEmpty() )
657 qWarning() << "QtxResourceMgr: Current section is empty";
659 qWarning() << "QtxResourceMgr: Error in line:" << line;
669 \brief Save resources to the ini-file.
670 \param fname resources file name
671 \param secMap resources map
672 \return \c true on success and \c false on error
674 bool QtxResourceMgr::IniFormat::save( const QString& fname, const QMap<QString, Section>& secMap )
676 if ( !Qtx::mkDir( QFileInfo( fname ).absolutePath() ) )
680 if ( !file.open( QFile::WriteOnly ) )
683 QTextStream ts( &file );
685 ts << "# This file is automatically created by SALOME application." << endl;
686 ts << "# Changes made in this file can be lost!" << endl;
690 for ( QMap<QString, Section>::ConstIterator it = secMap.begin(); it != secMap.end() && res; ++it )
692 QStringList data( QString( "[%1]" ).arg( it.key() ) );
693 for ( Section::ConstIterator iter = it.value().begin(); iter != it.value().end(); ++iter )
694 data.append( iter.key() + " = " + iter.value() );
697 for ( QStringList::ConstIterator itr = data.begin(); itr != data.end(); ++itr )
707 \class QtxResourceMgr::XmlFormat
709 \brief Reader/writer for .xml resources files.
712 class QtxResourceMgr::XmlFormat : public Format
719 virtual bool load( const QString&, QMap<QString, Section>& );
720 virtual bool save( const QString&, const QMap<QString, Section>& );
723 QString docTag() const;
724 QString sectionTag() const;
725 QString parameterTag() const;
726 QString importTag() const;
727 QString nameAttribute() const;
728 QString valueAttribute() const;
730 bool load( const QString&, QMap<QString, Section>&, QSet<QString>& );
736 QtxResourceMgr::XmlFormat::XmlFormat()
744 QtxResourceMgr::XmlFormat::~XmlFormat()
749 \brief Load resources from xml-file.
750 \param fname resources file name
751 \param secMap resources map to be filled in
752 \return \c true on success and \c false on error
754 bool QtxResourceMgr::XmlFormat::load( const QString& fname, QMap<QString, Section>& secMap )
756 QSet<QString> importHistory;
757 return load( fname, secMap, importHistory );
761 \brief Load resources from xml-file.
762 \param fname resources file name
763 \param secMap resources map to be filled in
764 \param importHistory list of already imported resources files (to prevent import loops)
765 \return \c true on success and \c false on error
767 bool QtxResourceMgr::XmlFormat::load( const QString& fname, QMap<QString, Section>& secMap, QSet<QString>& importHistory )
769 QString aFName = fname.trimmed();
770 if ( !QFileInfo( aFName ).exists() )
772 if ( QFileInfo( aFName + ".xml" ).exists() )
774 else if ( QFileInfo( aFName + ".XML" ).exists() )
777 return false; // file does not exist
779 QFileInfo aFinfo( aFName );
780 aFName = aFinfo.canonicalFilePath();
782 if ( !importHistory.contains( aFName ) )
783 importHistory.insert( aFName );
785 return true; // already imported (prevent import loops)
791 QFile file( aFName );
792 if ( !file.open( QFile::ReadOnly ) )
794 qDebug() << "QtxResourceMgr: File is not accessible:" << aFName;
800 res = doc.setContent( &file );
805 qDebug() << "QtxResourceMgr: File is empty:" << aFName;
809 QDomElement root = doc.documentElement();
810 if ( root.isNull() || root.tagName() != docTag() )
812 qDebug() << "QtxResourceMgr: Invalid root in file:" << aFName;
816 QDomNode sectNode = root.firstChild();
817 while ( res && !sectNode.isNull() )
819 res = sectNode.isElement();
822 QDomElement sectElem = sectNode.toElement();
823 if ( sectElem.tagName() == sectionTag() && sectElem.hasAttribute( nameAttribute() ) )
825 QString section = sectElem.attribute( nameAttribute() );
826 QDomNode paramNode = sectNode.firstChild();
827 while ( res && !paramNode.isNull() )
829 res = paramNode.isElement();
832 QDomElement paramElem = paramNode.toElement();
833 if ( paramElem.tagName() == parameterTag() &&
834 paramElem.hasAttribute( nameAttribute() ) && paramElem.hasAttribute( valueAttribute() ) )
836 QString paramName = paramElem.attribute( nameAttribute() );
837 QString paramValue = paramElem.attribute( valueAttribute() );
838 secMap[section].insert( paramName, paramValue );
842 qDebug() << "QtxResourceMgr: Invalid parameter element in file:" << aFName;
848 res = paramNode.isComment();
850 qDebug() << "QtxResourceMgr: Node is neither element nor comment in file:" << aFName;
853 paramNode = paramNode.nextSibling();
856 else if ( sectElem.tagName() == importTag() && sectElem.hasAttribute( nameAttribute() ) )
858 QString impFile = QDir::toNativeSeparators( Qtx::makeEnvVarSubst( sectElem.attribute( nameAttribute() ), Qtx::Always ) );
859 QFileInfo impFInfo( impFile );
860 if ( impFInfo.isRelative() )
861 impFInfo.setFile( aFinfo.absoluteDir(), impFile );
863 QMap<QString, Section> impMap;
864 if ( !load( impFInfo.absoluteFilePath(), impMap, importHistory ) )
866 qDebug() << "QtxResourceMgr: Error with importing file:" << sectElem.attribute( nameAttribute() );
870 QMap<QString, Section>::const_iterator it = impMap.constBegin();
871 for ( ; it != impMap.constEnd() ; ++it )
873 if ( !secMap.contains( it.key() ) )
875 // insert full section
876 secMap.insert( it.key(), it.value() );
880 // insert all parameters from the section
881 Section::ConstIterator paramIt = it.value().begin();
882 for ( ; paramIt != it.value().end() ; ++paramIt )
884 if ( !secMap[it.key()].contains( paramIt.key() ) )
885 secMap[it.key()].insert( paramIt.key(), paramIt.value() );
893 qDebug() << "QtxResourceMgr: Invalid section in file:" << aFName;
899 res = sectNode.isComment(); // if it's a comment -- let it be, pass it..
901 qDebug() << "QtxResourceMgr: Node is neither element nor comment in file:" << aFName;
904 sectNode = sectNode.nextSibling();
910 qDebug() << "QtxResourceMgr: File" << fname << "is loaded successfully";
915 \brief Save resources to the xml-file.
916 \param fname resources file name
917 \param secMap resources map
918 \return \c true on success and \c false on error
920 bool QtxResourceMgr::XmlFormat::save( const QString& fname, const QMap<QString, Section>& secMap )
926 if ( !Qtx::mkDir( QFileInfo( fname ).absolutePath() ) )
930 if ( !file.open( QFile::WriteOnly ) )
933 QDomDocument doc( docTag() );
934 QDomComment comment = doc.createComment( "\nThis file is automatically created by SALOME application.\nChanges made in this file can be lost!\n" );
935 doc.appendChild( comment );
936 QDomElement root = doc.createElement( docTag() );
937 doc.appendChild( root );
939 for ( QMap<QString, Section>::ConstIterator it = secMap.begin(); it != secMap.end(); ++it )
941 QDomElement sect = doc.createElement( sectionTag() );
942 sect.setAttribute( nameAttribute(), it.key() );
943 root.appendChild( sect );
944 for ( Section::ConstIterator iter = it.value().begin(); iter != it.value().end(); ++iter )
946 QDomElement val = doc.createElement( parameterTag() );
947 val.setAttribute( nameAttribute(), iter.key() );
948 val.setAttribute( valueAttribute(), iter.value() );
949 sect.appendChild( val );
953 QTextStream ts( &file );
954 QStringList docStr = doc.toString().split( "\n" );
955 for ( QStringList::ConstIterator itr = docStr.begin(); itr != docStr.end(); ++itr )
966 \brief Get document tag name
967 \return XML document tag name
969 QString QtxResourceMgr::XmlFormat::docTag() const
971 QString tag = option( "doc_tag" );
973 tag = QString( "document" );
978 \brief Get section tag name
979 \return XML section tag name
981 QString QtxResourceMgr::XmlFormat::sectionTag() const
983 QString tag = option( "section_tag" );
985 tag = QString( "section" );
990 \brief Get parameter tag name
991 \return XML parameter tag name
993 QString QtxResourceMgr::XmlFormat::parameterTag() const
995 QString tag = option( "parameter_tag" );
997 tag = QString( "parameter" );
1002 \brief Get import tag name
1003 \return XML import tag name
1005 QString QtxResourceMgr::XmlFormat::importTag() const
1007 QString tag = option( "import_tag" );
1008 if ( tag.isEmpty() )
1009 tag = QString( "import" );
1014 \brief Get parameter tag's "name" attribute name
1015 \return XML parameter tag's "name" attribute name
1017 QString QtxResourceMgr::XmlFormat::nameAttribute() const
1019 QString str = option( "name_attribute" );
1020 if ( str.isEmpty() )
1021 str = QString( "name" );
1026 \brief Get parameter tag's "value" attribute name
1027 \return XML parameter tag's "value" attribute name
1029 QString QtxResourceMgr::XmlFormat::valueAttribute() const
1031 QString str = option( "value_attribute" );
1032 if ( str.isEmpty() )
1033 str = QString( "value" );
1038 \class QtxResourceMgr::JsonFormat
1040 \brief Reader/writer for .json resources files.
1043 class QtxResourceMgr::JsonFormat : public Format
1050 JsonFormat( const QString& );
1051 virtual bool load( const QString&, QMap<QString, Section>& );
1052 virtual bool save( const QString&, const QMap<QString, Section>& );
1055 bool load( const QString&, QMap<QString, Section>&, QSet<QString>& );
1061 QtxResourceMgr::JsonFormat::JsonFormat()
1062 : QtxResourceMgr::JsonFormat( "json" )
1069 QtxResourceMgr::JsonFormat::JsonFormat( const QString& fmt )
1077 QtxResourceMgr::JsonFormat::~JsonFormat()
1082 \brief Load resources from json-file.
1083 \param fname resources file name
1084 \param secMap resources map to be filled in
1085 \return \c true on success and \c false on error
1087 bool QtxResourceMgr::JsonFormat::load( const QString& fname, QMap<QString, Section>& secMap )
1089 QSet<QString> importHistory;
1090 return load( fname, secMap, importHistory );
1094 \brief Load resources from json-file.
1095 \param fname resources file name
1096 \param secMap resources map to be filled in
1097 \param importHistory list of already imported resources files (to prevent import loops)
1098 \return \c true on success or \c false on error
1100 bool QtxResourceMgr::JsonFormat::load( const QString& fname, QMap<QString, Section>& secMap, QSet<QString>& importHistory )
1102 QString aFName = fname.trimmed();
1103 if ( !QFileInfo( aFName ).exists() )
1105 if ( QFileInfo( aFName + ".json" ).exists() )
1107 else if ( QFileInfo( aFName + ".JSON" ).exists() )
1110 return false; // file does not exist
1112 QFileInfo aFinfo( aFName );
1113 aFName = aFinfo.canonicalFilePath();
1115 if ( !importHistory.contains( aFName ) )
1116 importHistory.insert( aFName );
1118 return true; // already imported (prevent import loops)
1120 QFile file( aFName );
1121 if ( !file.open( QFile::ReadOnly ) )
1122 return false; // file is not accessible
1124 QJsonDocument document = QJsonDocument::fromJson( file.readAll() );
1125 if ( document.isNull() )
1126 return false; // invalid json file
1128 QJsonObject root = document.object();
1129 foreach ( QString sectionName, root.keys() )
1131 if ( sectionName == "import" )
1133 QString impFile = root.value( sectionName ).toString();
1134 if ( impFile.isEmpty() )
1136 QString impPath = QDir::toNativeSeparators( Qtx::makeEnvVarSubst( impFile, Qtx::Always ) );
1137 QFileInfo impFInfo( impPath );
1138 if ( impFInfo.isRelative() )
1139 impFInfo.setFile( aFinfo.absoluteDir(), impPath );
1140 QMap<QString, Section> impMap;
1141 if ( !load( impFInfo.absoluteFilePath(), impMap, importHistory ) )
1143 qDebug() << "QtxResourceMgr: Error with importing file:" << impPath;
1147 QMap<QString, Section>::const_iterator it = impMap.constBegin();
1148 for ( ; it != impMap.constEnd() ; ++it )
1150 if ( !secMap.contains( it.key() ) )
1152 // insert full section
1153 secMap.insert( it.key(), it.value() );
1157 // insert all parameters from the section
1158 Section::ConstIterator paramIt = it.value().begin();
1159 for ( ; paramIt != it.value().end() ; ++paramIt )
1161 if ( !secMap[it.key()].contains( paramIt.key() ) )
1162 secMap[it.key()].insert( paramIt.key(), paramIt.value() );
1170 QJsonObject section = root.value( sectionName ).toObject();
1171 if ( !section.isEmpty() )
1173 // case when a top-level item is a section
1174 foreach ( QString parameterName, section.keys() )
1176 // each value must be a string, number, or boolean
1177 QJsonValue parameter = section.value( parameterName );
1178 if ( parameter.isDouble() )
1179 secMap[sectionName].insert( parameterName, QString::number( parameter.toDouble() ) );
1180 else if ( parameter.isBool() )
1181 secMap[sectionName].insert( parameterName, QString( parameter.toBool() ? "true" : "false" ) );
1182 else if ( parameter.isString() )
1183 secMap[sectionName].insert( parameterName, parameter.toString() );
1188 QString parameterName = sectionName;
1189 sectionName = "General"; // default section name for top-level items
1190 // each value must be a string, number, or boolean
1191 QJsonValue parameter = root.value( parameterName );
1192 if ( parameter.isDouble() )
1193 secMap[sectionName].insert( parameterName, QString::number( parameter.toDouble() ) );
1194 else if ( parameter.isBool() )
1195 secMap[sectionName].insert( parameterName, QString( parameter.toBool() ? "true" : "false" ) );
1196 else if ( parameter.isString() )
1197 secMap[sectionName].insert( parameterName, parameter.toString() );
1202 if ( !secMap.isEmpty() )
1203 qDebug() << "QtxResourceMgr: File" << fname << "is loaded successfully";
1208 \brief Save resources to the json-file.
1209 \param fname resources file name
1210 \param secMap resources map
1211 \return \c true on success and \c false on error
1213 bool QtxResourceMgr::JsonFormat::save( const QString& fname, const QMap<QString, Section>& secMap )
1215 if ( !Qtx::mkDir( QFileInfo( fname ).absolutePath() ) )
1218 QFile file( fname );
1219 if ( !file.open( QFile::WriteOnly ) )
1223 for ( QMap<QString, Section>::ConstIterator it = secMap.begin(); it != secMap.end(); ++it )
1225 // note: we write all values as string, as it's enough to store resources as strings
1226 // anyway resource manager converts values to strings when reading JSON file
1227 QJsonObject section;
1228 for ( Section::ConstIterator iter = it.value().begin(); iter != it.value().end(); ++iter )
1229 section.insert( iter.key(), iter.value() );
1230 root.insert( it.key(), section );
1233 QJsonDocument document;
1234 document.setObject( root );
1235 file.write( document.toJson() );
1241 \class QtxResourceMgr::SalomexFormat
1243 \brief Reader/writer for .salomex resources files. This is an alias for JSON format.
1246 class QtxResourceMgr::SalomexFormat : public JsonFormat
1249 SalomexFormat() : JsonFormat( "salomex" ) {}
1254 \class QtxResourceMgr::Format
1255 \brief Generic resources files reader/writer class.
1260 \param fmt format name (for example, "xml" or "ini")
1262 QtxResourceMgr::Format::Format( const QString& fmt )
1270 QtxResourceMgr::Format::~Format()
1275 \brief Get the format name.
1278 QString QtxResourceMgr::Format::format() const
1284 \brief Get options names.
1285 \return list of the format options
1287 QStringList QtxResourceMgr::Format::options() const
1289 return myOpt.keys();
1293 \brief Get the value of the option with specified name.
1295 If option doesn't exist then null QString is returned.
1297 \param opt option name
1298 \return option value
1300 QString QtxResourceMgr::Format::option( const QString& opt ) const
1303 if ( myOpt.contains( opt ) )
1309 \brief Set the value of the option with specified name.
1310 \param opt option name
1311 \param val option value
1313 void QtxResourceMgr::Format::setOption( const QString& opt, const QString& val )
1315 myOpt.insert( opt, val );
1319 \brief Load resources from the resource file.
1320 \param res resources object
1321 \return \c true on success and \c false on error
1323 bool QtxResourceMgr::Format::load( Resources* res )
1328 QMap<QString, Section> sections;
1329 bool status = load( res->myFileName, sections );
1331 res->mySections = sections;
1333 qDebug() << "QtxResourceMgr: Can't load resource file:" << res->myFileName;
1339 \brief Save resources to the resource file.
1340 \param res resources object
1341 \return \c true on success and \c false on error
1343 bool QtxResourceMgr::Format::save( Resources* res )
1348 QtxResourceMgr* mgr = res->resMgr();
1350 if ( mgr->appName().isEmpty() )
1353 Qtx::mkDir( Qtx::dir( res->myFileName ) );
1355 QString name = mgr ? mgr->userFileName( mgr->appName(), false ) : res->myFileName;
1356 return save( name, res->mySections );
1360 \fn virtual bool QtxResourceMgr::Format::load( const QString& fname,
1361 QMap<QString, Section>& secMap )
1362 \brief Load resources from the specified resources file.
1364 Should be implemented in the successors.
1366 \param fname resources file name
1367 \param secMap resources map to be filled in
1368 \return \c true on success and \c false on error
1372 \fn virtual bool QtxResourceMgr::Format::save( const QString& fname,
1373 const QMap<QString, Section>& secMap )
1375 \brief Save resources to the specified resources file.
1377 Should be implemented in the successors.
1379 \param fname resources file name
1380 \param secMap resources map
1381 \return \c true on success and \c false on error
1385 \class QtxResourceMgr
1386 \brief Application resources manager.
1388 This class can be used to define settings, save/load settings and
1389 application preferences to the resource file(s), load translation files
1390 (internationalization mechanism), load pixmaps and other resources from
1391 external files, etc.
1393 Currently it supports .ini, .xml, and .json resources file formats. To implement
1394 own resources file format, inherit from the Format class and implement virtual
1395 Format::load() and Format::save() methods.
1397 Resources manager is initialized by the (symbolic) name of the application.
1398 The parameter \a resVarTemplate specifies the template for the environment
1399 variable which should point to the resource directory or list of directories.
1400 Environment variable name is calculated by substitution of "%1" substring in
1401 the \a resVarTemplate parameter (if it contains such substring) by the
1402 application name (\a appName).
1403 By default, \a resVarTemplate is set to "%1Resources". For example, if the application name
1404 is "MyApp", the environment variable "MyAppResources" will be inspected in this case.
1406 Resource manager can handle several global application configuration files and
1407 one user configuration file. Location of global configuration files is defined
1408 by the environment variable (see above) and these files are always read-only.
1409 The name of the global configuration files is retrieved by calling virtual method
1410 globalFileName() which can be redefined in the QtxResourceMgr class successors.
1411 User configuration file always situated in the user's home directory. It's name
1412 is defined by calling virtual method userFileName() which can be also redefined
1413 in the QtxResourceMgr class successors. This is the only file which the preferences
1414 changed by the user during the application session are written to (usually
1415 when the application closes).
1417 Resources environment variable should contain one or several resource directories
1418 (separated by ";" symbol on Windows and ":" or ";" on Linux). Each resource directory
1419 can contain application global configuration file. The user configuration file has
1420 the highest priority, for the global configuration files the priority is decreasing from
1421 left to right, i.e. the first directory in the directoris list, defined by the
1422 resources environment variable has higher priority. Priority has the meaning when
1423 searching requested resources (application preference, pixmap file name, translation
1426 When retrieving preferences, it is sometimes helpful to ignore values coming from the
1427 user preference file and take into account only global preferences.
1428 To do this, use setWorkingMode() method passing QtxResourceMgr::IgnoreUserValues enumerator
1431 Resources manager operates with such terms like options, sections and parameters.
1432 Parametets are named application resources, for example, application preferences like
1433 integer, double, boolean or string values, pictures, font and color definitions, etc.
1434 Parameters are organized inside the resources files into the named groups - sections.
1435 Options are special kind of resoures which allow customizing resource files interpreting.
1436 For example, by default language settings are defined in the resource file in the
1437 section "language". It is possible to change this section name by setting "language"
1438 option to another value (see setOption()).
1440 Retrieving preferences values can be done by using one of value() methods, each returns
1441 \c true if the corresponding preference is found. Another way is to use integerValue(),
1442 doubleValue(), etc methods, which allow specifying default value which is used if the
1443 specified preference is not found. Removing of preferences or sections can be done using
1444 remove(const QString& sect) or remove(const QString& sect, const QString& name) methods.
1445 To add the preference or to change exiting preference value use setValue() methods family.
1446 Methods hasSection() and hasValue() can be used to check existence of section or
1447 preference (in the specified section). List of all sections can be retrieved with the
1448 sections() method, and list of all settings names in some specified section can be
1449 obtained with parameters() method.
1451 Pixmaps can be loaded with the loadPixmap() methods. If the specified pixmap is not found,
1452 the default one is returned. Default pixmap can be set by setDefaultPixmap().
1454 One of the key feature of the resources manager is support of application
1455 internationalization mechanism. Translation files for the specified language can be loaded
1456 with loadLanguage() method.
1460 \brief Constructs the resource manager.
1461 \param appName application name
1462 \param resVarTemplate resource environment variable pattern
1464 QtxResourceMgr::QtxResourceMgr( const QString& appName, const QString& resVarTemplate )
1465 : myAppName( appName ),
1466 myCheckExist( true ),
1468 myIsPixmapCached( true ),
1469 myHasUserValues( true ),
1470 myWorkingMode( AllowUserValues )
1472 QString envVar = !resVarTemplate.isEmpty() ? resVarTemplate : QString( "%1Resources" );
1473 if ( envVar.contains( "%1" ) )
1474 envVar = envVar.arg( appName );
1477 QString tmpValue = Qtx::getenv( envVar );
1478 if ( !tmpValue.isEmpty() )
1481 QString dirsep = ";"; // for Windows: ";" is used as directories separator
1483 QString dirsep = "[:|;]"; // for Linux: both ":" and ";" can be used
1485 setDirList( dirs.split( QRegExp( dirsep ), QString::SkipEmptyParts ) );
1487 installFormat( new XmlFormat() );
1488 installFormat( new IniFormat() );
1489 installFormat( new JsonFormat() );
1490 installFormat( new SalomexFormat() );
1492 setOption( "translators", QString( "%P_msg_%L.qm|%P_images.qm" ) );
1496 \brief Default constructor
1498 QtxResourceMgr::QtxResourceMgr()
1499 : myCheckExist( true ),
1501 myIsPixmapCached( true ),
1502 myHasUserValues( false ),
1503 myWorkingMode( IgnoreUserValues )
1505 installFormat( new XmlFormat() );
1506 installFormat( new IniFormat() );
1507 installFormat( new JsonFormat() );
1508 installFormat( new SalomexFormat() );
1510 setOption( "translators", QString( "%P_msg_%L.qm|%P_images.qm" ) );
1516 Destroy the resource manager and free allocated memory.
1518 QtxResourceMgr::~QtxResourceMgr()
1520 QStringList prefList = myTranslator.keys();
1521 for ( QStringList::ConstIterator it = prefList.begin(); it != prefList.end(); ++it )
1522 removeTranslators( *it );
1524 qDeleteAll( myResources );
1525 qDeleteAll( myFormats );
1527 delete myDefaultPix;
1531 \brief Get the application name.
1532 \return application name
1534 QString QtxResourceMgr::appName() const
1540 \brief Get the "check existance" flag
1542 If this flag is \c true then preference can be set (with setValue() method)
1543 only if it doesn't exist or if the value is changed.
1545 \return \c true if "check existance" flag is set
1547 bool QtxResourceMgr::checkExisting() const
1549 return myCheckExist;
1553 \brief Set the "check existance" flag.
1554 \param on new flag value
1556 void QtxResourceMgr::setCheckExisting( const bool on )
1562 \brief Get the resource directories list.
1564 Home user directory (where the user application configuration file is situated)
1565 is not included. This is that directories list defined by the application
1566 resources environment variable.
1568 \return list of directories names
1570 QStringList QtxResourceMgr::dirList() const
1576 \brief Initialise resources manager.
1578 Prepare the resources containers and load resources (if \a autoLoad is \c true).
1580 \param autoLoad if \c true (default) then all resources are loaded
1582 void QtxResourceMgr::initialize( const bool autoLoad ) const
1584 if ( !myResources.isEmpty() || appName().isEmpty() )
1587 QtxResourceMgr* that = (QtxResourceMgr*)this;
1589 QString userFile = userFileName( appName() );
1590 if ( !userFile.isEmpty() )
1591 that->myResources.append( new Resources( that, userFile ) );
1593 that->myHasUserValues = myResources.count() > 0;
1595 for ( QStringList::ConstIterator it = myDirList.begin(); it != myDirList.end(); ++it )
1597 QString path = Qtx::addSlash( *it ) + globalFileName( appName() );
1598 that->myResources.append( new Resources( that, path ) );
1606 \brief Get "cached pixmaps" option value.
1608 Resources manager allows possibility to cache loaded pixmaps that allow to
1609 improve application performance. This feature is turned on by default - all
1610 loaded pixmaps are stored in the internal map. Switching of this feature on/off
1611 can be done by setIsPixmapCached() method.
1613 \return \c true if pixmap cache is turned on
1614 \sa setIsPixmapCached()
1616 bool QtxResourceMgr::isPixmapCached() const
1618 return myIsPixmapCached;
1622 \brief Switch "cached pixmaps" option on/off.
1623 \param on enable pixmap cache if \c true and disable it if \c false
1624 \sa isPixmapCached()
1626 void QtxResourceMgr::setIsPixmapCached( const bool on )
1628 myIsPixmapCached = on;
1632 \brief Remove all resources from the resources manager.
1634 void QtxResourceMgr::clear()
1636 for ( ResList::Iterator it = myResources.begin(); it != myResources.end(); ++it )
1641 \brief Get current working mode.
1643 \return current working mode
1644 \sa setWorkingMode(), value(), hasValue(), hasSection(), setValue()
1646 QtxResourceMgr::WorkingMode QtxResourceMgr::workingMode() const
1648 return myWorkingMode;
1652 \brief Set resource manager's working mode.
1654 The resource manager can operate in the following working modes:
1655 * AllowUserValues : methods values(), hasValue(), hasSection() take into account user values (default)
1656 * IgnoreUserValues : methods values(), hasValue(), hasSection() do not take into account user values
1658 Note, that setValue() method always put the value to the user settings file.
1660 \param mode new working mode
1661 \return previous working mode
1662 \sa workingMode(), value(), hasValue(), hasSection(), setValue()
1664 QtxResourceMgr::WorkingMode QtxResourceMgr::setWorkingMode( WorkingMode mode )
1666 WorkingMode m = myWorkingMode;
1667 myWorkingMode = mode;
1672 \brief Get interger parameter value.
1673 \param sect section name
1674 \param name parameter name
1675 \param iVal parameter to return resulting integer value
1676 \return \c true if parameter is found and \c false if parameter is not found
1677 (in this case \a iVal value is undefined)
1679 bool QtxResourceMgr::value( const QString& sect, const QString& name, int& iVal ) const
1682 if ( !value( sect, name, val, true ) )
1686 iVal = val.toInt( &ok );
1692 \brief Get double parameter value.
1693 \param sect section name
1694 \param name parameter name
1695 \param dVal parameter to return resulting double value
1696 \return \c true if parameter is found and \c false if parameter is not found
1697 (in this case \a dVal value is undefined)
1699 bool QtxResourceMgr::value( const QString& sect, const QString& name, double& dVal ) const
1702 if ( !value( sect, name, val, true ) )
1706 dVal = val.toDouble( &ok );
1712 \brief Get boolean parameter value.
1713 \param sect section name
1714 \param name parameter name
1715 \param bVal parameter to return resulting boolean value
1716 \return \c true if parameter is found and \c false if parameter is not found
1717 (in this case \a bVal value is undefined)
1719 bool QtxResourceMgr::value( const QString& sect, const QString& name, bool& bVal ) const
1722 if ( !value( sect, name, val, true ) )
1725 static QMap<QString, bool> boolMap;
1726 if ( boolMap.isEmpty() )
1728 boolMap["true"] = boolMap["yes"] = boolMap["on"] = true;
1729 boolMap["false"] = boolMap["no"] = boolMap["off"] = false;
1732 val = val.toLower();
1733 bool res = boolMap.contains( val );
1735 bVal = boolMap[val];
1738 double num = val.toDouble( &res );
1747 \brief Get color parameter value.
1748 \param sect section name
1749 \param name parameter name
1750 \param cVal parameter to return resulting color value
1751 \return \c true if parameter is found and \c false if parameter is not found
1752 (in this case \a cVal value is undefined)
1754 bool QtxResourceMgr::value( const QString& sect, const QString& name, QColor& cVal ) const
1757 if ( !value( sect, name, val, true ) )
1760 return Qtx::stringToColor( val, cVal );
1764 \brief Get font parameter value.
1765 \param sect section name
1766 \param name parameter name
1767 \param fVal parameter to return resulting font value
1768 \return \c true if parameter is found and \c false if parameter is not found
1769 (in this case \a fVal value is undefined)
1771 bool QtxResourceMgr::value( const QString& sect, const QString& name, QFont& fVal ) const
1774 if ( !value( sect, name, val, true ) )
1777 QStringList fontDescr = val.split( ",", QString::SkipEmptyParts );
1779 if ( fontDescr.count() < 2 )
1782 QString family = fontDescr[0];
1783 if ( family.isEmpty() )
1786 fVal = QFont( family );
1788 for ( int i = 1; i < (int)fontDescr.count(); i++ )
1790 QString curval = fontDescr[i].trimmed().toLower();
1791 if ( curval == QString( "bold" ) )
1792 fVal.setBold( true );
1793 else if ( curval == QString( "italic" ) )
1794 fVal.setItalic( true );
1795 else if ( curval == QString( "underline" ) )
1796 fVal.setUnderline( true );
1797 else if ( curval == QString( "shadow" ) || curval == QString( "overline" ) )
1798 fVal.setOverline( true );
1802 int ps = curval.toInt( &isOk );
1804 fVal.setPointSize( ps );
1812 \brief Get byte array parameter value.
1813 \param sect section name
1814 \param name parameter name
1815 \param baVal parameter to return resulting byte array value
1816 \return \c true if parameter is found and \c false if parameter is not found
1817 (in this case \a baVal value is undefined)
1819 bool QtxResourceMgr::value( const QString& sect, const QString& name, QByteArray& baVal ) const
1822 if ( !value( sect, name, val, true ) )
1825 if ( val.startsWith( "@ByteArray(" ) && val.endsWith( ')' ) ) {
1826 baVal = QByteArray( val.midRef( 11, val.size() - 12 ).toLatin1() );
1829 if ( val.startsWith( "@ByteArray[" ) && val.endsWith( ']' ) ) {
1830 val = val.mid( 11, val.size() - 12 );
1833 QStringList lst = val.split( QRegExp( "[\\s|,]" ), QString::SkipEmptyParts );
1834 for ( QStringList::ConstIterator it = lst.begin(); it != lst.end(); ++it )
1838 if ( str.startsWith( "#" ) )
1844 int num = str.toInt( &ok, base );
1845 if ( !ok || num < 0 || num > 255 )
1848 baVal.append( (char)num );
1851 return !baVal.isEmpty();
1855 \brief Get linear gradient parameter value.
1856 \param sect section name
1857 \param name parameter name
1858 \param gVal parameter to return resulting linear gradient value
1859 \return \c true if parameter is found and \c false if parameter is not found
1860 (in this case \a gVal value is undefined)
1862 bool QtxResourceMgr::value( const QString& sect, const QString& name, QLinearGradient& gVal ) const
1865 if ( !value( sect, name, val, true ) )
1868 return Qtx::stringToLinearGradient( val, gVal );
1872 \brief Get radial gradient parameter value.
1873 \param sect section name
1874 \param name parameter name
1875 \param gVal parameter to return resulting radial gradient value
1876 \return \c true if parameter is found and \c false if parameter is not found
1877 (in this case \a gVal value is undefined)
1879 bool QtxResourceMgr::value( const QString& sect, const QString& name, QRadialGradient& gVal ) const
1882 if ( !value( sect, name, val, true ) )
1885 return Qtx::stringToRadialGradient( val, gVal );
1889 \brief Get conical gradient parameter value.
1890 \param sect section name
1891 \param name parameter name
1892 \param gVal parameter to return resulting conical gradient value
1893 \return \c true if parameter is found and \c false if parameter is not found
1894 (in this case \a gVal value is undefined)
1896 bool QtxResourceMgr::value( const QString& sect, const QString& name, QConicalGradient& gVal ) const
1899 if ( !value( sect, name, val, true ) )
1902 return Qtx::stringToConicalGradient( val, gVal );
1906 \brief Get background parameter value.
1907 \param sect section name
1908 \param name parameter name
1909 \param bgVal parameter to return resulting background value
1910 \return \c true if parameter is found and \c false if parameter is not found
1911 (in this case \a bgVal value is undefined)
1913 bool QtxResourceMgr::value( const QString& sect, const QString& name, Qtx::BackgroundData& bgVal ) const
1916 if ( !value( sect, name, val, true ) )
1919 bgVal = Qtx::stringToBackground( val );
1920 return bgVal.isValid();
1924 \brief Get string parameter value (native format).
1925 \param sect section name
1926 \param name parameter name
1927 \param val parameter to return resulting byte array value
1928 \param subst if \c true perform environment variables substitution
1929 \return \c true if parameter is found and \c false if parameter is not found
1930 (in this case \a val value is undefined)
1932 bool QtxResourceMgr::value( const QString& sect, const QString& name, QString& val, const bool subst ) const
1938 ResList::ConstIterator it = myResources.begin();
1939 if ( myHasUserValues && workingMode() == IgnoreUserValues )
1942 for ( ; it != myResources.end() && !ok; ++it )
1944 ok = (*it)->hasValue( sect, name );
1946 val = (*it)->value( sect, name, subst, myConstants );
1953 \brief Get interger parameter value.
1955 If the specified parameter is not found or can not be converted to the integer value,
1956 the specified default value is returned instead.
1958 \param sect section name
1959 \param name parameter name
1960 \param def default value
1961 \return parameter value (or default value if parameter is not found)
1963 int QtxResourceMgr::integerValue( const QString& sect, const QString& name, const int def ) const
1966 if ( !value( sect, name, val ) )
1972 \brief Get double parameter value.
1974 If the specified parameter is not found or can not be converted to the double value,
1975 the specified default value is returned instead.
1977 \param sect section name
1978 \param name parameter name
1979 \param def default value
1980 \return parameter value (or default value if parameter is not found)
1982 double QtxResourceMgr::doubleValue( const QString& sect, const QString& name, const double def ) const
1985 if ( !value( sect, name, val ) )
1991 \brief Get boolean parameter value.
1993 If the specified parameter is not found or can not be converted to the boolean value,
1994 the specified default value is returned instead.
1996 \param sect section name
1997 \param name parameter name
1998 \param def default value
1999 \return parameter value (or default value if parameter is not found)
2001 bool QtxResourceMgr::booleanValue( const QString& sect, const QString& name, const bool def ) const
2004 if ( !value( sect, name, val ) )
2010 \brief Get font parameter value.
2012 If the specified parameter is not found or can not be converted to the font value,
2013 the specified default value is returned instead.
2015 \param sect section name
2016 \param name parameter name
2017 \param def default value
2018 \return parameter value (or default value if parameter is not found)
2020 QFont QtxResourceMgr::fontValue( const QString& sect, const QString& name, const QFont& def ) const
2023 if( !value( sect, name, font ) )
2029 \brief Get color parameter value.
2031 If the specified parameter is not found or can not be converted to the color value,
2032 the specified default value is returned instead.
2034 \param sect section name
2035 \param name parameter name
2036 \param def default value
2037 \return parameter value (or default value if parameter is not found)
2039 QColor QtxResourceMgr::colorValue( const QString& sect, const QString& name, const QColor& def ) const
2042 if ( !value( sect, name, val ) )
2048 \brief Get string parameter value.
2050 If the specified parameter is not found, the specified default value is returned instead.
2052 \param sect section name
2053 \param name parameter name
2054 \param def default value
2055 \return parameter value (or default value if parameter is not found)
2057 QString QtxResourceMgr::stringValue( const QString& sect, const QString& name, const QString& def, const bool subst ) const
2060 if ( !value( sect, name, val, subst ) )
2066 \brief Get byte array parameter value.
2068 If the specified parameter is not found, the specified default value is returned instead.
2070 \param sect section name
2071 \param name parameter name
2072 \param def default value
2073 \return parameter value (or default value if parameter is not found)
2075 QByteArray QtxResourceMgr::byteArrayValue( const QString& sect, const QString& name, const QByteArray& def ) const
2078 if ( !value( sect, name, val ) )
2084 \brief Get linear gradient parameter value.
2086 If the specified parameter is not found, the specified default value is returned instead.
2088 \param sect section name
2089 \param name parameter name
2090 \param def default value
2091 \return parameter value (or default value if parameter is not found)
2093 QLinearGradient QtxResourceMgr::linearGradientValue( const QString& sect, const QString& name, const QLinearGradient& def ) const
2095 QLinearGradient val;
2096 if ( !value( sect, name, val ) )
2102 \brief Get radial gradient parameter value.
2104 If the specified parameter is not found, the specified default value is returned instead.
2106 \param sect section name
2107 \param name parameter name
2108 \param def default value
2109 \return parameter value (or default value if parameter is not found)
2111 QRadialGradient QtxResourceMgr::radialGradientValue( const QString& sect, const QString& name, const QRadialGradient& def ) const
2113 QRadialGradient val;
2114 if ( !value( sect, name, val ) )
2120 \brief Get conical gradient parameter value.
2122 If the specified parameter is not found, the specified default value is returned instead.
2124 \param sect section name
2125 \param name parameter name
2126 \param def default value
2127 \return parameter value (or default value if parameter is not found)
2129 QConicalGradient QtxResourceMgr::conicalGradientValue( const QString& sect, const QString& name, const QConicalGradient& def ) const
2131 QConicalGradient val;
2132 if ( !value( sect, name, val ) )
2138 \brief Get background parameter value.
2140 If the specified parameter is not found, the specified default value is returned instead.
2142 \param sect section name
2143 \param name parameter name
2144 \param def default value
2145 \return parameter value (or default value if parameter is not found)
2147 Qtx::BackgroundData QtxResourceMgr::backgroundValue( const QString& sect, const QString& name, const Qtx::BackgroundData& def ) const
2149 Qtx::BackgroundData val;
2150 if ( !value( sect, name, val ) )
2156 \brief Check parameter existence.
2157 \param sect section name
2158 \param name parameter name
2159 \return \c true if parameter exists in specified section
2161 bool QtxResourceMgr::hasValue( const QString& sect, const QString& name ) const
2167 ResList::ConstIterator it = myResources.begin();
2168 if ( myHasUserValues && workingMode() == IgnoreUserValues )
2171 for ( ; it != myResources.end() && !ok; ++it )
2172 ok = (*it)->hasValue( sect, name );
2178 \brief Check section existence.
2179 \param sect section name
2180 \return \c true if section exists
2182 bool QtxResourceMgr::hasSection( const QString& sect ) const
2188 ResList::ConstIterator it = myResources.begin();
2189 if ( myHasUserValues && workingMode() == IgnoreUserValues )
2192 for ( ; it != myResources.end() && !ok; ++it )
2193 ok = (*it)->hasSection( sect );
2199 \brief Set integer parameter value.
2200 \param sect section name
2201 \param name parameter name
2202 \param val parameter value
2204 void QtxResourceMgr::setValue( const QString& sect, const QString& name, int val )
2207 if ( checkExisting() && value( sect, name, res ) && res == val )
2210 setResource( sect, name, QString::number( val ) );
2214 \brief Set double parameter value.
2215 \param sect section name
2216 \param name parameter name
2217 \param val parameter value
2219 void QtxResourceMgr::setValue( const QString& sect, const QString& name, double val )
2222 if ( checkExisting() && value( sect, name, res ) && res == val )
2225 setResource( sect, name, QString::number( val, 'g', 12 ) );
2229 \brief Set boolean parameter value.
2230 \param sect section name
2231 \param name parameter name
2232 \param val parameter value
2234 void QtxResourceMgr::setValue( const QString& sect, const QString& name, bool val )
2237 if ( checkExisting() && value( sect, name, res ) && res == val )
2240 setResource( sect, name, QString( val ? "true" : "false" ) );
2244 \brief Set color parameter value.
2245 \param sect section name
2246 \param name parameter name
2247 \param val parameter value
2249 void QtxResourceMgr::setValue( const QString& sect, const QString& name, const QColor& val )
2252 if ( checkExisting() && value( sect, name, res ) && res == val )
2255 setResource( sect, name, Qtx::colorToString( val ) );
2259 \brief Set font parameter value.
2260 \param sect section name
2261 \param name parameter name
2262 \param val parameter value
2264 void QtxResourceMgr::setValue( const QString& sect, const QString& name, const QFont& val )
2267 if ( checkExisting() && value( sect, name, res ) && res == val )
2270 QStringList fontDescr;
2271 fontDescr.append( val.family() );
2273 fontDescr.append( "Bold" );
2275 fontDescr.append( "Italic" );
2276 if ( val.underline() )
2277 fontDescr.append( "Underline" );
2278 if ( val.overline() )
2279 fontDescr.append( "Overline" );
2280 fontDescr.append( QString( "%1" ).arg( val.pointSize() ) );
2282 setResource( sect, name, fontDescr.join( "," ) );
2286 \brief Set string parameter value.
2287 \param sect section name
2288 \param name parameter name
2289 \param val parameter value
2291 void QtxResourceMgr::setValue( const QString& sect, const QString& name, const QString& val )
2294 if ( checkExisting() && value( sect, name, res ) && res == val )
2297 setResource( sect, name, val );
2301 \brief Set byte array parameter value.
2302 \param sect section name
2303 \param name parameter name
2304 \param val parameter value
2306 void QtxResourceMgr::setValue( const QString& sect, const QString& name, const QByteArray& val )
2309 if ( checkExisting() && value( sect, name, res ) && res == val )
2314 for ( int i = 0; i < val.size(); i++ )
2316 ::sprintf( buf, "#%02X", (unsigned char)val.at( i ) );
2317 lst.append( QString( buf ) );
2320 QString result = QString( "@ByteArray[%1]" ).arg( lst.join( " " ) );
2321 setResource( sect, name, result );
2325 \brief Set linear gradient parameter value.
2326 \param sect section name
2327 \param name parameter name
2328 \param val parameter value
2330 void QtxResourceMgr::setValue( const QString& sect, const QString& name, const QLinearGradient& val )
2332 QLinearGradient res;
2333 if ( checkExisting() && value( sect, name, res ) && res == val )
2336 setResource( sect, name, Qtx::gradientToString( val ) );
2340 \brief Set radial gradient parameter value.
2341 \param sect section name
2342 \param name parameter name
2343 \param val parameter value
2345 void QtxResourceMgr::setValue( const QString& sect, const QString& name, const QRadialGradient& val )
2347 QRadialGradient res;
2348 if ( checkExisting() && value( sect, name, res ) && res == val )
2351 setResource( sect, name, Qtx::gradientToString( val ) );
2355 \brief Set conical gradient parameter value.
2356 \param sect section name
2357 \param name parameter name
2358 \param val parameter value
2360 void QtxResourceMgr::setValue( const QString& sect, const QString& name, const QConicalGradient& val )
2362 QConicalGradient res;
2363 if ( checkExisting() && value( sect, name, res ) && res == val )
2366 setResource( sect, name, Qtx::gradientToString( val ) );
2370 \brief Set background parameter value.
2371 \param sect section name
2372 \param name parameter name
2373 \param val parameter value
2375 void QtxResourceMgr::setValue( const QString& sect, const QString& name, const Qtx::BackgroundData& val )
2377 Qtx::BackgroundData res;
2378 if ( checkExisting() && value( sect, name, res ) && res == val )
2381 setResource( sect, name, Qtx::backgroundToString( val ) );
2385 \brief Remove resources section.
2386 \param sect section name
2388 void QtxResourceMgr::remove( const QString& sect )
2392 for ( ResList::Iterator it = myResources.begin(); it != myResources.end(); ++it )
2393 (*it)->removeSection( sect );
2397 \brief Remove the specified parameter.
2398 \param sect section name
2399 \param name parameter name
2401 void QtxResourceMgr::remove( const QString& sect, const QString& name )
2405 for ( ResList::Iterator it = myResources.begin(); it != myResources.end(); ++it )
2406 (*it)->removeValue( sect, name );
2410 \brief Get current configuration files format.
2411 \return configuration files format name
2413 QString QtxResourceMgr::currentFormat() const
2416 if ( !myFormats.isEmpty() )
2417 fmt = myFormats[0]->format();
2422 \brief Set current configuration files format.
2423 \param fmt configuration files format name
2425 void QtxResourceMgr::setCurrentFormat( const QString& fmt )
2427 Format* form = format( fmt );
2431 myFormats.removeAll( form );
2432 myFormats.prepend( form );
2434 if ( myResources.isEmpty() || appName().isEmpty() )
2437 ResList::Iterator resIt = myResources.begin();
2438 if ( myResources.count() > myDirList.count() && resIt != myResources.end() )
2440 (*resIt)->setFile( userFileName( appName() ) );
2444 for ( QStringList::ConstIterator it = myDirList.begin(); it != myDirList.end() && resIt != myResources.end(); ++it, ++resIt )
2445 (*resIt)->setFile( Qtx::addSlash( *it ) + globalFileName( appName() ) );
2449 \brief Get configuration files format by specified format name.
2450 \param fmt configuration files format name
2451 \return format object or 0 if format is not defined
2453 QtxResourceMgr::Format* QtxResourceMgr::format( const QString& fmt ) const
2456 for ( FormatList::ConstIterator it = myFormats.begin(); it != myFormats.end() && !form; ++it )
2458 if ( (*it)->format() == fmt )
2466 \brief Install configuration files format.
2468 Added format becomes current.
2470 \param form format object to be installed
2472 void QtxResourceMgr::installFormat( QtxResourceMgr::Format* form )
2474 if ( !myFormats.contains( form ) )
2475 myFormats.prepend( form );
2479 \brief Remove configuration files format.
2480 \param form format object to be uninstalled
2482 void QtxResourceMgr::removeFormat( QtxResourceMgr::Format* form )
2484 myFormats.removeAll( form );
2488 \brief Get resource format options names.
2489 \return list of options names
2491 QStringList QtxResourceMgr::options() const
2493 return myOptions.keys();
2497 \brief Get the string value of the specified resources format option.
2499 If option does not exist, null QString is returned.
2501 \param opt option name
2502 \return option value
2503 \sa setOption(), options()
2505 QString QtxResourceMgr::option( const QString& opt ) const
2508 if ( myOptions.contains( opt ) )
2509 val = myOptions[opt];
2514 \brief Set the string value of the specified resources format option.
2515 \param opt option name
2516 \param val option value
2517 \sa option(), options()
2519 void QtxResourceMgr::setOption( const QString& opt, const QString& val )
2521 myOptions.insert( opt, val );
2525 \brief Get names of all known constants.
2526 \return list of constants names
2527 \sa constant(), setConstant
2529 QStringList QtxResourceMgr::constants() const
2531 return myConstants.keys();
2535 \brief Get the value of the known constant.
2537 If constant is not set, null QString is returned.
2539 \param name constant name
2540 \return constant value
2541 \sa setConstant(), constants()
2543 QString QtxResourceMgr::constant( const QString& name ) const
2545 return myConstants.value( name, QString() );
2549 \brief Set the value of the constant.
2550 \param name constant name
2551 \param value constant value
2552 \sa constants(), constants()
2554 void QtxResourceMgr::setConstant( const QString& name, const QString& value )
2556 if ( !name.isEmpty() )
2557 myConstants.insert( name, value );
2561 \brief Load all resources from all resource files (global and user).
2562 \return \c true on success and \c false on error
2565 bool QtxResourceMgr::load()
2567 initialize( false );
2569 Format* fmt = format( currentFormat() );
2574 for ( ResList::Iterator it = myResources.begin(); it != myResources.end(); ++it )
2575 res = fmt->load( *it ) && res;
2581 \brief Import resources from specified resource file.
2582 \param fname resources file name
2583 \return \c true on success and \c false on error
2585 bool QtxResourceMgr::import( const QString& fname )
2587 Format* fmt = format( currentFormat() );
2591 if ( myResources.isEmpty() || !myHasUserValues )
2594 Resources* r = myResources[0];
2598 QString old = r->file();
2599 r->setFile( fname );
2600 bool res = fmt->load( r );
2606 \brief Save all resources to the user resource files.
2607 \return \c true on success and \c false on error
2609 bool QtxResourceMgr::save()
2611 initialize( false );
2613 Format* fmt = format( currentFormat() );
2617 if ( myResources.isEmpty() || !myHasUserValues )
2620 bool result = fmt->save( myResources[0] );
2628 \brief Load resource from given file.
2630 bool QtxResourceMgr::addResource( const QString& fname )
2632 if ( fname.isEmpty() )
2635 QFileInfo fi( fname );
2637 if ( fi.exists() && fi.isDir() && !appName().isEmpty() )
2638 fi.setFile( QDir( fname ).filePath( globalFileName( appName() ) ) );
2643 QString dirName = fi.absolutePath();
2644 if ( myDirList.contains( dirName ) )
2645 return true; // file already loaded
2647 Format* fmt = format( fi.suffix() );
2651 Resources* resource = new Resources( this, fi.absoluteFilePath() );
2652 if ( !fmt->load( resource ) )
2658 myDirList << dirName;
2659 myResources << resource;
2664 \brief Get all sections names.
2665 \return list of section names
2667 QStringList QtxResourceMgr::sections() const
2671 QMap<QString, int> map;
2673 ResList::ConstIterator it = myResources.begin();
2674 if ( myHasUserValues && workingMode() == IgnoreUserValues )
2677 for ( ; it != myResources.end(); ++it )
2679 QStringList lst = (*it)->sections();
2680 for ( QStringList::ConstIterator itr = lst.begin(); itr != lst.end(); ++itr )
2681 map.insert( *itr, 0 );
2688 \brief Get all sections names matching specified regular expression.
2689 \param re searched regular expression
2690 \return list of sections names
2692 QStringList QtxResourceMgr::sections(const QRegExp& re) const
2694 return sections().filter( re );
2698 \brief Get all sections names with the prefix specified by passed
2699 list of parent sections names.
2701 Sub-sections are separated inside the section name by the sections
2702 separator token, for example "splash:color:label".
2704 \param names parent sub-sections names
2705 \return list of sections names
2707 QStringList QtxResourceMgr::sections(const QStringList& names) const
2709 QStringList nm = names;
2711 QRegExp re( QString( "^%1$" ).arg( nm.join( sectionsToken() ) ) );
2712 return sections( re );
2716 \brief Get list of sub-sections names for the specified parent section name.
2718 Sub-sections are separated inside the section name by the sections
2719 separator token, for example "splash:color:label".
2721 \param section parent sub-section name
2722 \param full if \c true return full names of child sub-sections, if \c false,
2723 return only top-level sub-sections names
2724 \return list of sub-sections names
2726 QStringList QtxResourceMgr::subSections(const QString& section, const bool full) const
2728 QStringList names = sections( QStringList() << section );
2729 QMutableListIterator<QString> it( names );
2730 while ( it.hasNext() ) {
2731 QString name = it.next().mid( section.size() + 1 ).trimmed();
2732 if ( name.isEmpty() ) {
2736 if ( !full ) name = name.split( sectionsToken() ).first();
2737 it.setValue( name );
2739 names.removeDuplicates();
2745 \brief Get all parameters name in specified section.
2746 \param sec section name
2747 \return list of settings names
2749 QStringList QtxResourceMgr::parameters( const QString& sec ) const
2753 #if defined(QTX_NO_INDEXED_MAP)
2754 typedef QMap<QString, int> PMap;
2756 typedef IMap<QString, int> PMap;
2760 Resources* ur = !myResources.isEmpty() && workingMode() == IgnoreUserValues ? myResources[0] : 0;
2762 QListIterator<Resources*> it( myResources );
2764 while ( it.hasPrevious() )
2766 Resources* r = it.previous();
2767 if ( r == ur ) break;
2768 QStringList lst = r->parameters( sec );
2769 for ( QStringList::ConstIterator itr = lst.begin(); itr != lst.end(); ++itr )
2770 #if defined(QTX_NO_INDEXED_MAP)
2771 if ( !pmap.contains( *itr ) ) pmap.insert( *itr, 0 );
2773 pmap.insert( *itr, 0, false );
2781 \brief Get all parameters name in specified
2782 list of sub-sections names.
2784 Sub-sections are separated inside the section name by the sections
2785 separator token, for example "splash:color:label".
2787 \param names parent sub-sections names
2788 \return list of settings names
2790 QStringList QtxResourceMgr::parameters( const QStringList& names ) const
2792 return parameters( names.join( sectionsToken() ) );
2796 \brief Get absolute path to the file which name is defined by the parameter.
2798 The file name is defined by \a name argument, while directory name is retrieved
2799 from resources parameter \a prefix of section \a sec. Both directory and file name
2800 can be relative. If the directory is relative, it is calculated from the initial
2801 resources file name. Directory parameter can contain environment
2802 variables, which are substituted automatically.
2804 \param sec section name
2805 \param prefix parameter containing directory name
2806 \param name file name
2807 \return absolute file path or null QString if file does not exist
2809 QString QtxResourceMgr::path( const QString& sect, const QString& prefix, const QString& name ) const
2813 ResList::ConstIterator it = myResources.begin();
2814 if ( myHasUserValues && workingMode() == IgnoreUserValues )
2817 for ( ; it != myResources.end() && res.isEmpty(); ++it )
2818 res = (*it)->path( sect, prefix, name, myConstants );
2823 \brief Get application resources section name.
2825 By default, application resources section name is "resources" but
2826 it can be changed by setting the "res_section_name" resources manager option.
2828 \return section corresponding to the resources directories
2829 \sa option(), setOption()
2831 QString QtxResourceMgr::resSection() const
2833 QString res = option( "res_section_name" );
2834 if ( res.isEmpty() )
2835 res = QString( "resources" );
2840 \brief Get application language section name.
2842 By default, application language section name is "language" but
2843 it can be changed by setting the "lang_section_name" resources manager option.
2845 \return section corresponding to the application language settings
2846 \sa option(), setOption()
2848 QString QtxResourceMgr::langSection() const
2850 QString res = option( "lang_section_name" );
2851 if ( res.isEmpty() )
2852 res = QString( "language" );
2857 \brief Get sections separator token.
2859 By default, sections separator token is colon symbol ":" but
2860 it can be changed by setting the "section_token" resources manager option.
2862 \return string corresponding to the current section separator token
2863 \sa option(), setOption()
2865 QString QtxResourceMgr::sectionsToken() const
2867 QString res = option( "section_token" );
2868 if ( res.isEmpty() )
2869 res = QString( ":" );
2874 \brief Get default pixmap.
2876 Default pixmap is used when requested pixmap resource is not found.
2878 \return default pixmap
2879 \sa setDefaultPixmap(), loadPixmap()
2881 QPixmap QtxResourceMgr::defaultPixmap() const
2883 static QPixmap* defpx = 0;
2885 defpx = new QPixmap( pixmap_not_found_xpm );
2887 return myDefaultPix ? *myDefaultPix : *defpx;
2891 \brief Set default pixmap.
2893 Default pixmap is used when requested pixmap resource is not found.
2895 \param pix default pixmap
2896 \sa defaultPixmap(), loadPixmap()
2898 void QtxResourceMgr::setDefaultPixmap( const QPixmap& pix )
2900 delete myDefaultPix;
2904 myDefaultPix = new QPixmap( pix );
2908 \brief Load pixmap resource.
2909 \param prefix parameter which refers to the resources directory (directories)
2910 \param name pixmap file name
2911 \return pixmap loaded from the file
2912 \sa defaultPixmap(), setDefaultPixmap()
2914 QPixmap QtxResourceMgr::loadPixmap( const QString& prefix, const QString& name ) const
2916 return loadPixmap( prefix, name, true );
2920 \brief Load pixmap resource.
2922 \param prefix parameter which refers to the resources directory (directories)
2923 \param name pixmap file name
2924 \param useDef if \c false, default pixmap is not returned if resource is not found,
2925 in this case null pixmap is returned instead
2926 \return pixmap loaded from the file
2927 \sa defaultPixmap(), setDefaultPixmap()
2929 QPixmap QtxResourceMgr::loadPixmap( const QString& prefix, const QString& name, const bool useDef ) const
2931 return loadPixmap( prefix, name, useDef ? defaultPixmap() : QPixmap() );
2935 \brief Load pixmap resource.
2937 \param prefix parameter which refers to the resources directory (directories)
2938 \param name pixmap file name
2939 \param defPix default which should be used if the resource file doesn't exist
2940 \return pixmap loaded from the file
2941 \sa defaultPixmap(), setDefaultPixmap()
2943 QPixmap QtxResourceMgr::loadPixmap( const QString& prefix, const QString& name, const QPixmap& defPix ) const
2949 ResList::ConstIterator it = myResources.begin();
2950 if ( myHasUserValues && workingMode() == IgnoreUserValues )
2953 for ( ; it != myResources.end() && pix.isNull(); ++it )
2954 pix = (*it)->loadPixmap( resSection(), prefix, name, myConstants );
2961 \brief Specify default language for the application.
2963 QString QtxResourceMgr::defaultLanguage() const
2970 \brief Select language to be used.
2971 \param preferableLanguage preferable language name (if empty, default language is used)
2973 QString QtxResourceMgr::language( const QString& preferableLanguage ) const
2975 // first try to select preferable language probably specified via the parameter
2976 QString lang = preferableLanguage;
2978 // then try default language; selection of default language can be redefined in successors
2979 if ( lang.isEmpty() )
2980 lang = defaultLanguage();
2982 // then try language as defined in the preferences files
2983 if ( lang.isEmpty() )
2984 value( langSection(), "language", lang );
2986 // finally try strongly hardcoded Ennglish
2987 if ( lang.isEmpty() )
2989 lang = QString( "en" );
2990 qWarning() << "QtxResourceMgr: Language not specified. Assumed:" << lang;
2998 \brief Load translation files according to the specified language.
3000 Names of the translation files are calculated according to the pattern specified
3001 by the "translators" option (this option is read from the section "language" of resources files).
3002 By default, "%P_msg_%L.qm" pattern is used.
3003 Keywords \%A, \%P, \%L in the pattern are substituted by the application name, prefix and language name
3005 For example, for prefix "SUIT" and language "en", all translation files "SUIT_msg_en.qm" are searched and
3008 If prefix is empty or null string, all translation files specified in the "resources" section of resources
3009 files are loaded (actually, the section is retrieved from resSection() method).
3010 If language is not specified, it is retrieved from the langSection() method, and if the latest is also empty,
3011 by default "en" (English) language is used.
3012 By default, settings from the user preferences file are also loaded (if user resource file is valid,
3013 see userFileName()). To avoid loading user settings, pass \c false as first parameter.
3015 \param pref parameter which defines translation context (for example, package name)
3016 \param preferableLanguage language name
3018 \sa resSection(), langSection(), loadTranslators()
3020 void QtxResourceMgr::loadLanguage( const QString& pref, const QString& preferableLanguage )
3024 QMap<QChar, QString> substMap;
3025 if ( !appName().isEmpty() )
3026 substMap.insert( 'A', appName() );
3028 QString lang = language( preferableLanguage );
3030 substMap.insert( 'L', lang );
3033 if ( value( langSection(), "translators", trs, false ) && !trs.isEmpty() )
3035 QStringList translators = option( "translators" ).split( "|", QString::SkipEmptyParts );
3036 QStringList newTranslators = trs.split( "|", QString::SkipEmptyParts );
3037 for ( int i = 0; i < (int)newTranslators.count(); i++ )
3039 if ( translators.indexOf( newTranslators[i] ) < 0 )
3040 translators += newTranslators[i];
3042 setOption( "translators", translators.join( "|" ) );
3045 QStringList trList = option( "translators" ).split( "|", QString::SkipEmptyParts );
3046 if ( trList.isEmpty() )
3048 trList.append( "%P_msg_%L.qm" );
3049 qWarning() << "QtxResourceMgr: Translators not defined. Assumed:" << trList[0];
3052 QStringList prefixList;
3053 if ( !pref.isEmpty() )
3054 prefixList.append( pref );
3056 prefixList = parameters( resSection() );
3058 if ( pref.isEmpty() && lang != "en" ) {
3059 // load Qt resources
3060 QString qt_translations = QLibraryInfo::location( QLibraryInfo::TranslationsPath );
3061 QString qt_dir_trpath = Qtx::qtDir( "translations" );
3062 QTranslator* trans = new QtxTranslator( 0 );
3063 if ( trans->load( QString("qt_%1").arg( lang ), qt_translations ) || trans->load( QString("qt_%1").arg( lang ), qt_dir_trpath ) ) {
3064 if ( QApplication::instance() ) QApplication::instance()->installTranslator( trans );
3068 for ( QStringList::ConstIterator iter = prefixList.begin(); iter != prefixList.end(); ++iter )
3070 QString prefix = *iter;
3071 substMap.insert( 'P', prefix );
3074 for ( QStringList::ConstIterator it = trList.begin(); it != trList.end(); ++it )
3075 trs.append( substMacro( *it, substMap ).trimmed() );
3077 loadTranslators( prefix, trs );
3082 \brief Load translation files for the specified translation context.
3083 \param prefix parameter which defines translation context (for example, package name)
3084 \param translators list of translation files
3087 void QtxResourceMgr::loadTranslators( const QString& prefix, const QStringList& translators )
3093 ResList::ConstIterator iter = myResources.begin();
3094 if ( myHasUserValues && workingMode() == IgnoreUserValues )
3097 for ( ; iter != myResources.end(); ++iter )
3098 lst.prepend( *iter );
3100 QTranslator* trans = 0;
3102 for ( ResList::Iterator it = lst.begin(); it != lst.end(); ++it )
3104 for ( QStringList::ConstIterator itr = translators.begin(); itr != translators.end(); ++itr )
3106 trans = (*it)->loadTranslator( resSection(), prefix, *itr, myConstants );
3109 if ( !myTranslator[prefix].contains( trans ) )
3110 myTranslator[prefix].append( trans );
3111 if ( QApplication::instance() ) QApplication::instance()->installTranslator( trans );
3118 \brief Load translation file.
3119 \param prefix parameter which defines translation context (for example, package name)
3120 \param name translator file name
3121 \sa loadLanguage(), loadTranslators()
3123 void QtxResourceMgr::loadTranslator( const QString& prefix, const QString& name )
3127 QTranslator* trans = 0;
3129 Resources* ur = !myResources.isEmpty() && workingMode() == IgnoreUserValues ? myResources[0] : 0;
3131 QListIterator<Resources*> it( myResources );
3133 while ( it.hasPrevious() )
3135 Resources* r = it.previous();
3136 if ( r == ur ) break;
3138 trans = r->loadTranslator( resSection(), prefix, name, myConstants );
3141 if ( !myTranslator[prefix].contains( trans ) )
3142 myTranslator[prefix].append( trans );
3143 if ( QApplication::instance() ) QApplication::instance()->installTranslator( trans );
3149 \brief Add custom translator.
3150 \param prefix parameter which defines translation context (for example, package name)
3151 \param translator translator being installed
3152 \sa loadLanguage(), loadTranslators()
3154 void QtxResourceMgr::addTranslator( const QString& prefix, QTranslator* translator )
3158 if ( !myTranslator[prefix].contains( translator ) ) {
3159 myTranslator[prefix].append( translator );
3160 if ( QApplication::instance() )
3161 QApplication::instance()->installTranslator( translator );
3167 \brief Remove all translators corresponding to the specified translation context.
3168 \param prefix parameter which defines translation context (for example, package name)
3170 void QtxResourceMgr::removeTranslators( const QString& prefix )
3172 if ( !myTranslator.contains( prefix ) )
3175 for ( TransList::Iterator it = myTranslator[prefix].begin(); it != myTranslator[prefix].end(); ++it )
3177 if ( QApplication::instance() ) QApplication::instance()->removeTranslator( *it );
3181 myTranslator.remove( prefix );
3185 \brief Move all translators corresponding to the specified translation context
3186 to the top of translators stack (increase their priority).
3187 \param prefix parameter which defines translation context (for example, package name)
3189 void QtxResourceMgr::raiseTranslators( const QString& prefix )
3191 if ( !myTranslator.contains( prefix ) )
3194 for ( TransList::Iterator it = myTranslator[prefix].begin(); it != myTranslator[prefix].end(); ++it )
3196 if ( QApplication::instance() ) {
3197 QApplication::instance()->removeTranslator( *it );
3198 QApplication::instance()->installTranslator( *it );
3204 \brief Copy all parameters to the user resources in order to
3205 saved them lately in the user home folder.
3207 void QtxResourceMgr::refresh()
3209 QStringList sl = sections();
3210 for ( QStringList::ConstIterator it = sl.begin(); it != sl.end(); ++it )
3212 QStringList pl = parameters( *it );
3213 for ( QStringList::ConstIterator itr = pl.begin(); itr != pl.end(); ++itr )
3214 setResource( *it, *itr, stringValue( *it, *itr ) );
3219 \brief Set the resource directories (where global confguration files are searched).
3221 This function also clears all currently set resources.
3223 \param dl directories list
3225 void QtxResourceMgr::setDirList( const QStringList& dl )
3228 for ( ResList::Iterator it = myResources.begin(); it != myResources.end(); ++it )
3231 myResources.clear();
3235 \brief Set parameter value.
3236 \param sect section name
3237 \param name parameter name
3238 \param val parameter value
3240 void QtxResourceMgr::setResource( const QString& sect, const QString& name, const QString& val )
3244 if ( !myResources.isEmpty() && myHasUserValues )
3245 myResources.first()->setValue( sect, name, val );
3249 \brief Get user configuration file name.
3251 This method can be redefined in the successor class to customize the user configuration file name.
3252 User configuration file is always situated in the user's home directory. By default .<appName>rc
3253 file is used on Linux (e.g. .MyApprc) and <appName>.<format> under Windows (e.g. MyApp.xml).
3255 Parameter \a for_load (not used in default implementation) specifies the usage mode, i.e. if
3256 user configuration file is opened for reading or writing. This allows customizing a way of application
3257 resources initializing (for example, if the user configuraion file includes version number and there is
3258 no file corresponding to this version in the user's home directory, it could be good idea to try
3259 the configuration file from the previous versions of the application).
3261 \param appName application name
3262 \param for_load boolean flag indicating that file is opened for loading or saving (not used in default implementation)
3263 \return user configuration file name
3264 \sa globalFileName()
3266 QString QtxResourceMgr::userFileName( const QString& appName, const bool /*for_load*/ ) const
3269 QString pathName = QDir::homePath();
3270 QString cfgAppName = QApplication::organizationName();
3271 if ( !cfgAppName.isEmpty() )
3272 pathName = Qtx::addSlash( Qtx::addSlash( pathName ) + QString( ".config" ) ) + cfgAppName;
3275 fileName = QString( "%1.%2" ).arg( appName ).arg( currentFormat() );
3277 fileName = QString( "%1rc" ).arg( appName );
3278 // VSR 24/09/2012: issue 0021781: do not prepend filename with "."
3279 // when user file is stored in ~/.config/<appname> directory
3280 if ( cfgAppName.isEmpty() )
3281 fileName.prepend( "." );
3284 if ( !fileName.isEmpty() )
3285 pathName = Qtx::addSlash( pathName ) + fileName;
3291 \brief Get global configuration file name.
3293 This method can be redefined in the successor class to customize the global configuration file name.
3294 Global configuration files are searched in the directories specified by the application resources
3295 environment variable (e.g. MyAppResources). By default <appName>.<format> file name is used
3298 \param appName application name
3299 \return global configuration file name
3302 QString QtxResourceMgr::globalFileName( const QString& appName ) const
3304 return QString( "%1.%2" ).arg( appName ).arg( currentFormat() );
3308 \brief This function is called after user configuration file is saved.
3309 Can be redefined in the successor classes, default implementation does nothing.
3311 void QtxResourceMgr::saved()
3316 \brief Perform substitution of the patterns like \%A, \%B, etc by values from the map.
3318 Used by loadLanguage().
3320 \param src sring to be processed
3321 \param substMap map of values for replacing
3322 \return processed string
3324 QString QtxResourceMgr::substMacro( const QString& src, const QMap<QChar, QString>& substMap ) const
3328 QRegExp rx( "%[A-Za-z%]" );
3331 while ( ( idx = rx.indexIn( trg, idx ) ) >= 0 )
3333 QChar spec = trg.at( idx + 1 );
3337 else if ( substMap.contains( spec ) )
3338 subst = substMap[spec];
3340 if ( !subst.isEmpty() )
3342 trg.replace( idx, rx.matchedLength(), subst );
3343 idx += subst.length();
3346 idx += rx.matchedLength();