+// Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// File: QtxResourceMgr.cxx
+// Author: Alexander SOLOVYOV, Sergey TELKOV
+//
#include "QtxResourceMgr.h"
-
-#include <qdir.h>
-#include <qfile.h>
-#include <qregexp.h>
-#include <qpixmap.h>
-#include <qtranslator.h>
-#include <qapplication.h>
-
+#include "QtxTranslator.h"
+
+#include <QSet>
+#include <QDir>
+#include <QFile>
+#include <QFileInfo>
+#include <QRegExp>
+#include <QTextStream>
+#include <QApplication>
+#include <QLibraryInfo>
+#include <QtDebug>
#ifndef QT_NO_DOM
-#include <qdom.h>
+#include <QDomDocument>
+#include <QDomElement>
+#include <QDomNode>
#endif
#include <stdlib.h>
+/* XPM for the default pixmap */
+static const char* pixmap_not_found_xpm[] = {
+"16 16 3 1",
+" c None",
+". c #000000",
+"+ c #A80000",
+" ",
+" ",
+" . . ",
+" .+. .+. ",
+" .+++. .+++. ",
+" .+++.+++. ",
+" .+++++. ",
+" .+++. ",
+" .+++++. ",
+" .+++.+++. ",
+" .+++. .+++. ",
+" .+. .+. ",
+" . . ",
+" ",
+" ",
+" "};
+
/*!
- Class: QtxResourceMgr::Resources
- Level: Internal
+ \class QtxResourceMgr::Resources
+ \internal
+ \brief Represents container for settings read from the resource file.
*/
-QtxResourceMgr::Resources::Resources( const QString& fileName )
-: myFileName( fileName )
+class QtxResourceMgr::Resources
+{
+public:
+ Resources( QtxResourceMgr*, const QString& );
+ virtual ~Resources();
+
+ QString file() const;
+ void setFile( const QString& );
+
+ QString value( const QString&, const QString&, const bool ) const;
+ void setValue( const QString&, const QString&, const QString& );
+
+ bool hasSection( const QString& ) const;
+ bool hasValue( const QString&, const QString& ) const;
+
+ void removeSection( const QString& );
+ void removeValue( const QString&, const QString& );
+
+ QPixmap loadPixmap( const QString&, const QString&, const QString& ) const;
+ QTranslator* loadTranslator( const QString&, const QString&, const QString& ) const;
+
+ QString makeSubstitution( const QString&, const QString&, const QString& ) const;
+
+ void clear();
+
+ QStringList sections() const;
+ QStringList parameters( const QString& ) const;
+
+ QString path( const QString&, const QString&, const QString& ) const;
+
+protected:
+ QtxResourceMgr* resMgr() const;
+
+private:
+ Section section( const QString& );
+ const Section section( const QString& ) const;
+
+ QString fileName( const QString&, const QString&, const QString& ) const;
+
+private:
+ typedef QMap<QString, Section> SectionMap;
+
+private:
+ QtxResourceMgr* myMgr; //!< resources manager
+ SectionMap mySections; //!< sections map
+ QString myFileName; //!< resources file name
+ QMap<QString,QPixmap> myPixmapCache; //!< pixmaps cache
+
+ friend class QtxResourceMgr::Format;
+};
+
+/*!
+ \brief Constructor.
+ \param mgr parent resources manager
+ \param fileName resources file name
+*/
+QtxResourceMgr::Resources::Resources( QtxResourceMgr* mgr, const QString& fileName )
+: myMgr( mgr ),
+ myFileName( fileName )
{
}
+/*!
+ \brief Destructor.
+*/
QtxResourceMgr::Resources::~Resources()
{
}
+/*!
+ \brief Get resources file name.
+
+ This file is used to load/save operations.
+
+ \return file name
+ \sa setFile()
+*/
QString QtxResourceMgr::Resources::file() const
{
return myFileName;
}
+/*!
+ \brief Set resources file name.
+ \param fn file name
+ \sa file()
+*/
void QtxResourceMgr::Resources::setFile( const QString& fn )
{
myFileName = fn;
}
+/*!
+ \brief Get string representation of parameter value.
+ \param sect section name
+ \param name parameter name
+ \param subst if \c true, perform variables substitution
+ \return parameter value or null QString if there is no such parameter
+ \sa setValue(), makeSubstitution()
+*/
QString QtxResourceMgr::Resources::value( const QString& sect, const QString& name, const bool subst ) const
{
QString val;
return val;
}
+/*!
+ \brief Set parameter value.
+ \param sect section name
+ \param name parameter name
+ \param val parameter value
+ \sa value(), makeSubstitution()
+*/
void QtxResourceMgr::Resources::setValue( const QString& sect, const QString& name, const QString& val )
{
- Section& s = section( sect );
- s.insert( name, val );
+ if ( !mySections.contains( sect ) )
+ mySections.insert( sect, Section() );
+
+ mySections[sect].insert( name, val );
}
+/*!
+ \brief Check section existence.
+ \param sect section name
+ \return \c true if section exists
+*/
bool QtxResourceMgr::Resources::hasSection( const QString& sect ) const
{
return mySections.contains( sect );
}
+/*!
+ \brief Check parameter existence.
+ \param sect section name
+ \param name parameter name
+ \return \c true if parameter exists in specified section
+*/
bool QtxResourceMgr::Resources::hasValue( const QString& sect, const QString& name ) const
{
return hasSection( sect ) && section( sect ).contains( name );
}
+/*!
+ \brief Remove resourcs section.
+ \param sect secton name
+*/
void QtxResourceMgr::Resources::removeSection( const QString& sect )
{
mySections.remove( sect );
}
+/*!
+ \brief Remove parameter from the section.
+ \param sect section name
+ \param name parameter name
+*/
void QtxResourceMgr::Resources::removeValue( const QString& sect, const QString& name )
{
- if ( !hasSection( sect ) )
+ if ( !mySections.contains( sect ) )
return;
- Section& s = section( sect );
- s.remove( name );
+ mySections[sect].remove( name );
- if ( s.isEmpty() )
+ if ( mySections[sect].isEmpty() )
mySections.remove( sect );
}
+/*!
+ \brief Remove all sections.
+*/
void QtxResourceMgr::Resources::clear()
{
mySections.clear();
}
+/*!
+ \brief Get all sections names.
+ \return list of section names
+*/
QStringList QtxResourceMgr::Resources::sections() const
{
return mySections.keys();
}
+/*!
+ \brief Get all parameters name in specified section.
+ \param sec section name
+ \return list of settings names
+*/
QStringList QtxResourceMgr::Resources::parameters( const QString& sec ) const
{
if ( !hasSection( sec ) )
return section( sec ).keys();
}
+/*!
+ \brief Get absolute path to the file which name is defined by the parameter.
+
+ The file name is defined by \a name argument, while directory name is retrieved
+ from resources parameter \a prefix of section \a sec. Both directory and file name
+ can be relative. If the directory is relative, it is calculated from the initial
+ resources file name (see file()). Directory parameter can contain environment
+ variables, which are substituted automatically.
+
+ \param sec section name
+ \param prefix parameter containing directory name
+ \param name file name
+ \return absolute file path or null QString if file does not exist
+ \sa fileName(), file(), makeSubstitution()
+*/
QString QtxResourceMgr::Resources::path( const QString& sec, const QString& prefix, const QString& name ) const
{
QString filePath = fileName( sec, prefix, name );
if ( !filePath.isEmpty() )
{
if ( !QFileInfo( filePath ).exists() )
- filePath = QString::null;
+ filePath = QString();
}
return filePath;
}
-QtxResourceMgr::Section& QtxResourceMgr::Resources::section( const QString& sn )
+/*!
+ \brief Get resource manager
+ \return resource manager pointer
+*/
+QtxResourceMgr* QtxResourceMgr::Resources::resMgr() const
+{
+ return myMgr;
+}
+
+/*!
+ \brief Get resources section by specified name.
+
+ If section does not exist it is created (empty).
+
+ \param sn section name
+ \return resources section
+*/
+QtxResourceMgr::Section QtxResourceMgr::Resources::section( const QString& sn )
{
if ( !mySections.contains( sn ) )
mySections.insert( sn, Section() );
return mySections[sn];
}
-const QtxResourceMgr::Section& QtxResourceMgr::Resources::section( const QString& sn ) const
+/*!
+ \brief Get resources section by specified name.
+ \param sn section name
+ \return resources section
+*/
+const QtxResourceMgr::Section QtxResourceMgr::Resources::section( const QString& sn ) const
{
return mySections[sn];
}
+/*!
+ \brief Get file path.
+
+ The file name is defined by \a name argument, while directory name is retrieved
+ from resources parameter \a prefix of section \a sec. Both directory and file name
+ can be relative. If the directory is relative, it is calculated from the initial
+ resources file name (see file()). Directory parameter can contain environment
+ variables, which are substituted automatically.
+ File existence is not checked.
+
+ \param sec section name
+ \param prefix parameter containing directory name
+ \param name file name
+ \return absolute file path or null QString if \a prefix parameter
+ does not exist in section \sec
+ \sa path(), file(), makeSubstitution()
+*/
QString QtxResourceMgr::Resources::fileName( const QString& sect, const QString& prefix, const QString& name ) const
{
QString path;
- if ( hasValue( sect, prefix ) )
+ if ( !QFileInfo( name ).isRelative() )
+ {
+ path = name;
+ }
+ else
{
- path = value( sect, prefix, true );
- if ( !path.isEmpty() )
+ if ( hasValue( sect, prefix ) )
{
- if ( QFileInfo( path ).isRelative() )
- path = Qtx::addSlash( QFileInfo( myFileName ).dirPath( true ) ) + path;
-
- path = Qtx::addSlash( path ) + name;
+ path = value( sect, prefix, true );
+ if ( !path.isEmpty() )
+ {
+ if ( QFileInfo( path ).isRelative() )
+ path = Qtx::addSlash( Qtx::dir( myFileName, true ) ) + path;
+
+ path = Qtx::addSlash( path ) + name;
+ }
}
}
- return QDir::convertSeparators( path );
+ if( !path.isEmpty() )
+ {
+ QString fname = QDir::convertSeparators( path );
+ QFileInfo inf( fname );
+ fname = inf.absoluteFilePath();
+ return fname;
+ }
+ return QString();
}
+/*!
+ \brief Load and return pixmap from external file.
+
+ If QtxResourceMgr::isPixmapCached() is \c true then cached pixmap is returned
+ (if it is already loaded), otherwise it is loaded from file.
+ If the file name is invalid, null pixmap is returned.
+
+ \param sect section name
+ \param prefix parameter containing resources directory name
+ \param name pixmap file name
+ \return pixmap loaded from file
+*/
QPixmap QtxResourceMgr::Resources::loadPixmap( const QString& sect, const QString& prefix, const QString& name ) const
{
- return QPixmap( fileName( sect, prefix, name ) );
+ QString fname = fileName( sect, prefix, name );
+ bool toCache = resMgr() ? resMgr()->isPixmapCached() : false;
+ QPixmap p;
+ if( toCache && myPixmapCache.contains( fname ) )
+ p = myPixmapCache[fname];
+ else
+ {
+ p.load( fname );
+ if( toCache )
+ ( ( QMap<QString,QPixmap>& )myPixmapCache ).insert( fname, p );
+ }
+ return p;
}
+/*!
+ \brief Load translator.
+ \param sect section name
+ \param prefix parameter containing resources directory
+ \param name translation file name
+ \return just created and loaded translator or 0 in case of error
+*/
QTranslator* QtxResourceMgr::Resources::loadTranslator( const QString& sect, const QString& prefix, const QString& name ) const
{
- QTranslator* trans = new QTranslator( 0 );
- if ( !trans->load( fileName( sect, prefix, name ) ) )
+ QTranslator* trans = new QtxTranslator( 0 );
+ QString fname = QDir::convertSeparators( fileName( sect, prefix, name ) );
+ if ( !trans->load( Qtx::file( fname, false ), Qtx::dir( fname ) ) )
{
delete trans;
trans = 0;
return trans;
}
-QString QtxResourceMgr::Resources::environmentVariable( const QString& str, int& start, int& len ) const
-{
- QString varName = QString::null;
- len = 0;
-
- QRegExp rx( "\\$\\{([a-zA-Z]+[a-zA-Z0-9_]*)\\}|\\$\\(([a-zA-Z]+[a-zA-Z0-9_]*)\\)|\\$([a-zA-Z]+[a-zA-Z0-9_]*)|\\%([a-zA-Z]+[a-zA-Z0-9_]*)\\%" );
+/*!
+ \brief Substitute variables by their values.
- int pos = rx.search( str, start );
- if ( pos != -1 )
- {
- start = pos;
- len = rx.matchedLength();
- QStringList caps = rx.capturedTexts();
- for ( uint i = 1; i <= caps.count() && varName.isEmpty(); i++ )
- varName = *caps.at( i );
- }
- return varName;
-}
+ Environment variable is substituted by its value. For other variables resource
+ manager tries to find value among defined resources parameters.
+ \param str string to be processed
+ \param sect section, where variables are searched
+ \param name name of variable which must be ignored during substitution
+ \return processed string (with all substitutions made)
+*/
QString QtxResourceMgr::Resources::makeSubstitution( const QString& str, const QString& sect, const QString& name ) const
{
QString res = str;
int start( 0 ), len( 0 );
while ( true )
{
- QString envName = environmentVariable( res, start, len );
+ QString envName = Qtx::findEnvVar( res, start, len );
if ( envName.isNull() )
break;
- QString newStr = QString::null;
- if ( ::getenv( envName ) )
- newStr = QString( ::getenv( envName ) );
+ QString newStr;
+ if ( ::getenv( envName.toLatin1() ) )
+ newStr = QString( ::getenv( envName.toLatin1() ) );
if ( newStr.isNull() )
{
res.replace( start, len, newStr );
}
+ res.replace( "$$", "$" );
+ res.replace( "%%", "%" );
+
return res;
}
/*!
- Class: QtxResourceMgr::IniFormat
- Level: Internal
+ \class QtxResourceMgr::IniFormat
+ \internal
+ \brief Reader/writer for .ini resources files.
*/
class QtxResourceMgr::IniFormat : public Format
protected:
virtual bool load( const QString&, QMap<QString, Section>& );
virtual bool save( const QString&, const QMap<QString, Section>& );
+
+private:
+ bool load( const QString&, QMap<QString, Section>&, QSet<QString>& );
};
+/*!
+ \brief Constructor.
+*/
QtxResourceMgr::IniFormat::IniFormat()
: Format( "ini" )
{
}
+/*!
+ \brief Destructor.
+*/
QtxResourceMgr::IniFormat::~IniFormat()
{
}
+/*!
+ \brief Load resources from ini-file.
+ \param fname resources file name
+ \param secMap resources map to be filled in
+ \return \c true on success and \c false on error
+*/
bool QtxResourceMgr::IniFormat::load( const QString& fname, QMap<QString, Section>& secMap )
{
- QFile file( fname );
- if ( !file.open( IO_ReadOnly ) )
- return false;
+ QSet<QString> importHistory;
+ return load( fname, secMap, importHistory );
+}
+
+
+/*!
+ \brief Load resources from xml-file.
+ \param fname resources file name
+ \param secMap resources map to be filled in
+ \param importHistory list of already imported resources files (to prevent import loops)
+ \return \c true on success or \c false on error
+*/
+bool QtxResourceMgr::IniFormat::load( const QString& fname, QMap<QString, Section>& secMap, QSet<QString>& importHistory )
+{
+ QString aFName = fname.trimmed();
+ if ( !QFileInfo( aFName ).exists() )
+ {
+ if ( QFileInfo( aFName + ".ini" ).exists() )
+ aFName += ".ini";
+ else if ( QFileInfo( aFName + ".INI" ).exists() )
+ aFName += ".INI";
+ else
+ return false; // file does not exist
+ }
+ QFileInfo aFinfo( aFName );
+ aFName = aFinfo.canonicalFilePath();
+
+ if ( !importHistory.contains( aFName ) )
+ importHistory.insert( aFName );
+ else
+ return true; // already imported (prevent import loops)
+
+ QFile file( aFName );
+ if ( !file.open( QFile::ReadOnly ) )
+ return false; // file is not accessible
QTextStream ts( &file );
if ( data.isNull() )
break;
- data = data.stripWhiteSpace();
+ data = data.trimmed();
if ( data.isEmpty() )
continue;
continue;
QRegExp rx( "^\\[([\\w\\s\\._]*)\\]$" );
- if ( rx.search( data ) != -1 )
+ if ( rx.indexIn( data ) != -1 )
{
section = rx.cap( 1 );
if ( section.isEmpty() )
{
res = false;
- qWarning( QString( "Empty section in line %1" ).arg( line ) );
+ qWarning() << "QtxResourceMgr: Empty section in line:" << line;
}
}
- else if ( data.contains( "=" ) && !section.isEmpty() )
+ else if ( data.contains( separator ) && !section.isEmpty() )
{
- int pos = data.find( separator );
- QString key = data.left( pos ).stripWhiteSpace();
- QString val = data.mid( pos + 1 ).stripWhiteSpace();
+ int pos = data.indexOf( separator );
+ QString key = data.left( pos ).trimmed();
+ QString val = data.mid( pos + 1 ).trimmed();
secMap[section].insert( key, val );
}
+ else if ( section == "import" )
+ {
+ QString impFile = QDir::convertSeparators( Qtx::makeEnvVarSubst( data, Qtx::Always ) );
+ QFileInfo impFInfo( impFile );
+ if ( impFInfo.isRelative() )
+ impFInfo.setFile( aFinfo.absoluteDir(), impFile );
+
+ QMap<QString, Section> impMap;
+ if ( !load( impFInfo.absoluteFilePath(), impMap, importHistory ) )
+ {
+ qDebug() << "QtxResourceMgr: Error with importing file:" << data;
+ }
+ else
+ {
+ QMap<QString, Section>::const_iterator it = impMap.constBegin();
+ for ( ; it != impMap.constEnd() ; ++it )
+ {
+ if ( !secMap.contains( it.key() ) )
+ {
+ // insert full section
+ secMap.insert( it.key(), it.value() );
+ }
+ else
+ {
+ // insert all parameters from the section
+ Section::ConstIterator paramIt = it.value().begin();
+ for ( ; paramIt != it.value().end() ; ++paramIt )
+ {
+ if ( !secMap[it.key()].contains( paramIt.key() ) )
+ secMap[it.key()].insert( paramIt.key(), paramIt.value() );
+ }
+ }
+ }
+ }
+ }
else
{
res = false;
- section.isEmpty() ? qWarning( "Current section is empty" ) :
- qWarning( QString( "Error in line: %1" ).arg( line ) );
+ if ( section.isEmpty() )
+ qWarning() << "QtxResourceMgr: Current section is empty";
+ else
+ qWarning() << "QtxResourceMgr: Error in line:" << line;
}
}
file.close();
- return res;
+ return res;
}
+/*!
+ \brief Save resources to the ini-file.
+ \param fname resources file name
+ \param secMap resources map
+ \return \c true on success and \c false on error
+*/
bool QtxResourceMgr::IniFormat::save( const QString& fname, const QMap<QString, Section>& secMap )
{
+ if ( !Qtx::mkDir( QFileInfo( fname ).absolutePath() ) )
+ return false;
+
QFile file( fname );
- if ( !file.open( IO_WriteOnly ) )
+ if ( !file.open( QFile::WriteOnly ) )
return false;
+ QTextStream ts( &file );
+
+ ts << "# This file is automatically created by SALOME application." << endl;
+ ts << "# Changes made in this file can be lost!" << endl;
+ ts << endl;
+
bool res = true;
for ( QMap<QString, Section>::ConstIterator it = secMap.begin(); it != secMap.end() && res; ++it )
{
- QString data = QString( "[%1]\n" ).arg( it.key() );
- for ( Section::ConstIterator iter = it.data().begin(); iter != it.data().end(); ++iter )
- data += iter.key() + " = " + iter.data() + "\n";
- data += "\n";
+ QStringList data( QString( "[%1]" ).arg( it.key() ) );
+ for ( Section::ConstIterator iter = it.value().begin(); iter != it.value().end(); ++iter )
+ data.append( iter.key() + " = " + iter.value() );
+ data.append( "" );
- res = file.writeBlock( data.latin1(), data.length() ) == (int)data.length();
+ for ( QStringList::ConstIterator itr = data.begin(); itr != data.end(); ++itr )
+ ts << *itr << endl;
}
file.close();
}
/*!
- Class: QtxResourceMgr::XmlFormat
- Level: Internal
+ \class QtxResourceMgr::XmlFormat
+ \internal
+ \brief Reader/writer for .xml resources files.
*/
class QtxResourceMgr::XmlFormat : public Format
QString docTag() const;
QString sectionTag() const;
QString parameterTag() const;
+ QString importTag() const;
QString nameAttribute() const;
QString valueAttribute() const;
+
+ bool load( const QString&, QMap<QString, Section>&, QSet<QString>& );
};
+/*!
+ \brief Constructor.
+*/
QtxResourceMgr::XmlFormat::XmlFormat()
: Format( "xml" )
{
}
+/*!
+ \brief Destructor.
+*/
QtxResourceMgr::XmlFormat::~XmlFormat()
{
}
+/*!
+ \brief Load resources from xml-file.
+ \param fname resources file name
+ \param secMap resources map to be filled in
+ \return \c true on success and \c false on error
+*/
bool QtxResourceMgr::XmlFormat::load( const QString& fname, QMap<QString, Section>& secMap )
{
+ QSet<QString> importHistory;
+ return load( fname, secMap, importHistory );
+}
+
+/*!
+ \brief Load resources from xml-file.
+ \param fname resources file name
+ \param secMap resources map to be filled in
+ \param importHistory list of already imported resources files (to prevent import loops)
+ \return \c true on success and \c false on error
+*/
+bool QtxResourceMgr::XmlFormat::load( const QString& fname, QMap<QString, Section>& secMap, QSet<QString>& importHistory )
+{
+ QString aFName = fname.trimmed();
+ if ( !QFileInfo( aFName ).exists() )
+ {
+ if ( QFileInfo( aFName + ".xml" ).exists() )
+ aFName += ".xml";
+ else if ( QFileInfo( aFName + ".XML" ).exists() )
+ aFName += ".XML";
+ else
+ return false; // file does not exist
+ }
+ QFileInfo aFinfo( aFName );
+ aFName = aFinfo.canonicalFilePath();
+
+ if ( !importHistory.contains( aFName ) )
+ importHistory.insert( aFName );
+ else
+ return true; // already imported (prevent import loops)
+
bool res = false;
#ifndef QT_NO_DOM
- QFile file( fname );
- if ( !file.open( IO_ReadOnly ) )
+ QFile file( aFName );
+ if ( !file.open( QFile::ReadOnly ) )
+ {
+ qDebug() << "QtxResourceMgr: File is not accessible:" << aFName;
return false;
+ }
QDomDocument doc;
file.close();
if ( !res )
+ {
+ qDebug() << "QtxResourceMgr: File is empty:" << aFName;
return false;
+ }
QDomElement root = doc.documentElement();
if ( root.isNull() || root.tagName() != docTag() )
+ {
+ qDebug() << "QtxResourceMgr: Invalid root in file:" << aFName;
return false;
+ }
QDomNode sectNode = root.firstChild();
while ( res && !sectNode.isNull() )
{
QString paramName = paramElem.attribute( nameAttribute() );
QString paramValue = paramElem.attribute( valueAttribute() );
-
secMap[section].insert( paramName, paramValue );
}
else
+ {
+ qDebug() << "QtxResourceMgr: Invalid parameter element in file:" << aFName;
res = false;
+ }
+ }
+ else
+ {
+ res = paramNode.isComment();
+ if ( !res )
+ qDebug() << "QtxResourceMgr: Node is neither element nor comment in file:" << aFName;
}
- else
- res = paramNode.isComment();
paramNode = paramNode.nextSibling();
}
}
+ else if ( sectElem.tagName() == importTag() && sectElem.hasAttribute( nameAttribute() ) )
+ {
+ QString impFile = QDir::convertSeparators( Qtx::makeEnvVarSubst( sectElem.attribute( nameAttribute() ), Qtx::Always ) );
+ QFileInfo impFInfo( impFile );
+ if ( impFInfo.isRelative() )
+ impFInfo.setFile( aFinfo.absoluteDir(), impFile );
+
+ QMap<QString, Section> impMap;
+ if ( !load( impFInfo.absoluteFilePath(), impMap, importHistory ) )
+ {
+ qDebug() << "QtxResourceMgr: Error with importing file:" << sectElem.attribute( nameAttribute() );
+ }
+ else
+ {
+ QMap<QString, Section>::const_iterator it = impMap.constBegin();
+ for ( ; it != impMap.constEnd() ; ++it )
+ {
+ if ( !secMap.contains( it.key() ) )
+ {
+ // insert full section
+ secMap.insert( it.key(), it.value() );
+ }
+ else
+ {
+ // insert all parameters from the section
+ Section::ConstIterator paramIt = it.value().begin();
+ for ( ; paramIt != it.value().end() ; ++paramIt )
+ {
+ if ( !secMap[it.key()].contains( paramIt.key() ) )
+ secMap[it.key()].insert( paramIt.key(), paramIt.value() );
+ }
+ }
+ }
+ }
+ }
else
- res = false;
+ {
+ qDebug() << "QtxResourceMgr: Invalid section in file:" << aFName;
+ res = false;
+ }
}
else
+ {
res = sectNode.isComment(); // if it's a comment -- let it be, pass it..
+ if ( !res )
+ qDebug() << "QtxResourceMgr: Node is neither element nor comment in file:" << aFName;
+ }
sectNode = sectNode.nextSibling();
}
#endif
-
+
+ if ( res )
+ qDebug() << "QtxResourceMgr: File" << fname << "is loaded successfully";
return res;
}
+/*!
+ \brief Save resources to the xml-file.
+ \param fname resources file name
+ \param secMap resources map
+ \return \c true on success and \c false on error
+*/
bool QtxResourceMgr::XmlFormat::save( const QString& fname, const QMap<QString, Section>& secMap )
{
bool res = false;
#ifndef QT_NO_DOM
+ if ( !Qtx::mkDir( QFileInfo( fname ).absolutePath() ) )
+ return false;
+
QFile file( fname );
- if ( !file.open( IO_WriteOnly ) )
+ if ( !file.open( QFile::WriteOnly ) )
return false;
QDomDocument doc( docTag() );
+ QDomComment comment = doc.createComment( "\nThis file is automatically created by SALOME application.\nChanges made in this file can be lost!\n" );
+ doc.appendChild( comment );
QDomElement root = doc.createElement( docTag() );
doc.appendChild( root );
QDomElement sect = doc.createElement( sectionTag() );
sect.setAttribute( nameAttribute(), it.key() );
root.appendChild( sect );
- for ( QMap<QString, QString>::ConstIterator iter = it.data().begin(); iter != it.data().end(); ++iter )
+ for ( Section::ConstIterator iter = it.value().begin(); iter != it.value().end(); ++iter )
{
QDomElement val = doc.createElement( parameterTag() );
val.setAttribute( nameAttribute(), iter.key() );
- val.setAttribute( valueAttribute(), iter.data() );
+ val.setAttribute( valueAttribute(), iter.value() );
sect.appendChild( val );
}
}
- QString docStr = doc.toString();
- res = file.writeBlock( docStr.latin1(), docStr.length() ) == (int)docStr.length();
+ QTextStream ts( &file );
+ QStringList docStr = doc.toString().split( "\n" );
+ for ( QStringList::ConstIterator itr = docStr.begin(); itr != docStr.end(); ++itr )
+ ts << *itr << endl;
+
file.close();
#endif
return res;
}
+/*!
+ \brief Get document tag name
+ \return XML document tag name
+*/
QString QtxResourceMgr::XmlFormat::docTag() const
{
QString tag = option( "doc_tag" );
return tag;
}
+/*!
+ \brief Get section tag name
+ \return XML section tag name
+*/
QString QtxResourceMgr::XmlFormat::sectionTag() const
{
QString tag = option( "section_tag" );
return tag;
}
+/*!
+ \brief Get parameter tag name
+ \return XML parameter tag name
+*/
QString QtxResourceMgr::XmlFormat::parameterTag() const
{
QString tag = option( "parameter_tag" );
return tag;
}
+/*!
+ \brief Get import tag name
+ \return XML import tag name
+*/
+QString QtxResourceMgr::XmlFormat::importTag() const
+{
+ QString tag = option( "import_tag" );
+ if ( tag.isEmpty() )
+ tag = QString( "import" );
+ return tag;
+}
+
+/*!
+ \brief Get parameter tag's "name" attribute name
+ \return XML parameter tag's "name" attribute name
+*/
QString QtxResourceMgr::XmlFormat::nameAttribute() const
{
QString str = option( "name_attribute" );
return str;
}
+/*!
+ \brief Get parameter tag's "value" attribute name
+ \return XML parameter tag's "value" attribute name
+*/
QString QtxResourceMgr::XmlFormat::valueAttribute() const
{
QString str = option( "value_attribute" );
}
/*!
- Class: QtxResourceMgr::Format
- Level: Public
+ \class QtxResourceMgr::Format
+ \brief Generic resources files reader/writer class.
*/
/*!
- \brief Constructs the format object with specified name.
- \param fmt - name of the format
+ \brief Constructor.
+ \param fmt format name (for example, "xml" or "ini")
*/
QtxResourceMgr::Format::Format( const QString& fmt )
: myFmt( fmt )
}
/*!
- \brief Destructs the format object.
+ \brief Destructor
*/
QtxResourceMgr::Format::~Format()
{
}
/*!
- \brief Returns the format name.
+ \brief Get the format name.
+ \return format name
*/
QString QtxResourceMgr::Format::format() const
{
}
/*!
- \brief Returns the string list of the format options.
+ \brief Get options names.
+ \return list of the format options
*/
QStringList QtxResourceMgr::Format::options() const
{
}
/*!
- \brief Returns the value of the option with specified name.
- If option doesn't exist then empty string returned.
- \param opt - name of the option
+ \brief Get the value of the option with specified name.
+
+ If option doesn't exist then null QString is returned.
+
+ \param opt option name
+ \return option value
*/
QString QtxResourceMgr::Format::option( const QString& opt ) const
{
}
/*!
- \brief Sets the value of the option with specified name.
- \param opt - name of the option
- \param opt - value of the option
+ \brief Set the value of the option with specified name.
+ \param opt option name
+ \param val option value
*/
void QtxResourceMgr::Format::setOption( const QString& opt, const QString& val )
{
}
/*!
- \brief Perform the loading of the resources from resource file.
- \param res - resources object which will be loaded
+ \brief Load resources from the resource file.
+ \param res resources object
+ \return \c true on success and \c false on error
*/
bool QtxResourceMgr::Format::load( Resources* res )
{
if ( status )
res->mySections = sections;
else
- qDebug( "QtxResourceMgr: Could not load resource file \"%s\"", res->myFileName.latin1() );
+ qDebug() << "QtxResourceMgr: Can't load resource file:" << res->myFileName;
return status;
}
/*!
- \brief Perform the saving of the resources into resource file.
- \param res - resources object which will be saved
+ \brief Save resources to the resource file.
+ \param res resources object
+ \return \c true on success and \c false on error
*/
bool QtxResourceMgr::Format::save( Resources* res )
{
Qtx::mkDir( Qtx::dir( res->myFileName ) );
- return save( res->myFileName, res->mySections );
+ QtxResourceMgr* mgr = res->resMgr();
+ QString name = mgr ? mgr->userFileName( mgr->appName(), false ) : res->myFileName;
+ return save( name, res->mySections );
}
/*!
- Class: QtxResourceMgr
- Level: Public
+ \fn virtual bool QtxResourceMgr::Format::load( const QString& fname,
+ QMap<QString, Section>& secMap )
+ \brief Load resources from the specified resources file.
+
+ Should be implemented in the successors.
+
+ \param fname resources file name
+ \param secMap resources map to be filled in
+ \return \c true on success and \c false on error
+*/
+
+/*!
+ \fn virtual bool QtxResourceMgr::Format::save( const QString& fname,
+ const QMap<QString, Section>& secMap )
+
+ \brief Save resources to the specified resources file.
+
+ Should be implemented in the successors.
+
+ \param fname resources file name
+ \param secMap resources map
+ \return \c true on success and \c false on error
+*/
+
+/*!
+ \class QtxResourceMgr
+ \brief Application resources manager.
+
+ This class can be used to define settings, save/load settings and
+ application preferences to the resource file(s), load translation files
+ (internationalization mechanism), load pixmaps and other resources from
+ external files, etc.
+
+ Currently it supports .ini and .xml resources file formats. To implement
+ own resources file format, inherit from the Format class and implement virtual
+ Format::load() and Format::save() methods.
+
+ Resources manager is initialized by the (symbolic) name of the application.
+ The parameter \a resVarTemplate specifies the template for the environment
+ variable which should point to the resource directory or list of directories.
+ Environment variable name is calculated by substitution of "%1" substring in
+ the \a resVarTemplate parameter (if it contains such substring) by the
+ application name (\a appName).
+ By default, \a resVarTemplate is set to "%1Resources". For example, if the application name
+ is "MyApp", the environment variable "MyAppResources" will be inspected in this case.
+
+ Resource manager can handle several global application configuration files and
+ one user configuration file. Location of global configuration files is defined
+ by the environment variable (see above) and these files are always read-only.
+ The name of the global configuration files is retrieved by calling virtual method
+ globalFileName() which can be redefined in the QtxResourceMgr class successors.
+ User configuration file always situated in the user's home directory. It's name
+ is defined by calling virtual method userFileName() which can be also redefined
+ in the QtxResourceMgr class successors. This is the only file which the preferences
+ changed by the user during the application session are written to (usually
+ when the application closes).
+
+ Resources environment variable should contain one or several resource directories
+ (separated by ";" symbol on Windows and ":" or ";" on Linux). Each resource directory
+ can contain application global configuration file. The user configuration file has
+ the highest priority, for the global configuration files the priority is decreasing from
+ left to right, i.e. the first directory in the directoris list, defined by the
+ resources environment variable has higher priority. Priority has the meaning when
+ searching requested resources (application preference, pixmap file name, translation
+ file, etc).
+
+ When retrieving preferences, it is sometimes helpful to ignore values coming from the
+ user preference file and take into account only global preferences.
+ To do this, use setWorkingMode() method passing QtxResourceMgr::IgnoreUserValues enumerator
+ as parameter.
+
+ Resources manager operates with such terms like options, sections and parameters.
+ Parametets are named application resources, for example, application preferences like
+ integer, double, boolean or string values, pictures, font and color definitions, etc.
+ Parameters are organized inside the resources files into the named groups - sections.
+ Options are special kind of resoures which allow customizing resource files interpreting.
+ For example, by default language settings are defined in the resource file in the
+ section "language". It is possible to change this section name by setting "language"
+ option to another value (see setOption()).
+
+ Retrieving preferences values can be done by using one of value() methods, each returns
+ \c true if the corresponding preference is found. Another way is to use integerValue(),
+ doubleValue(), etc methods, which allow specifying default value which is used if the
+ specified preference is not found. Removing of preferences or sections can be done using
+ remove(const QString& sect) or remove(const QString& sect, const QString& name) methods.
+ To add the preference or to change exiting preference value use setValue() methods family.
+ Methods hasSection() and hasValue() can be used to check existence of section or
+ preference (in the specified section). List of all sections can be retrieved with the
+ sections() method, and list of all settings names in some specified section can be
+ obtained with parameters() method.
+
+ Pixmaps can be loaded with the loadPixmap() methods. If the specified pixmap is not found,
+ the default one is returned. Default pixmap can be set by setDefaultPixmap().
+
+ One of the key feature of the resources manager is support of application
+ internationalization mechanism. Translation files for the specified language can be loaded
+ with loadLanguage() method.
*/
/*!
- \brief Constructs the resource manager object for application.
- \param appName - name of the application which resources will be used.
- \param resVarTemplate - template for the resource environment variable name which
- should point to the resource directory list.
- Default value is "%1Resources". Its mean that for application
- with name "MyApp" environment variable "MyAppResources" will
- be used. Template may not have the parameter '%1' substituted
- by application name. In this case this string will be used as
- is without substitution.
- Resource environment variable should contains one or several resource directories
- separated by symbol ';'. Resource directories list transfered into the setDirList().
- These directories and the user home directory used for the loading application resources.
- Each of the resource directories can contains resource file. The name of this file defined
- by the function globalFileName(). Resource file name in the user home defined by the
- function userFileName(). Any resource looking firstly in the user home resources then
- resource directories used in the specified order. All setted resources always stored into
- the resource file at the user home. Only user home resource file is saved.
+ \brief Constructs the resource manager.
+ \param appName application name
+ \param resVarTemplate resource environment variable pattern
*/
QtxResourceMgr::QtxResourceMgr( const QString& appName, const QString& resVarTemplate )
: myAppName( appName ),
-myCheckExist( true )
+ myCheckExist( true ),
+ myDefaultPix( 0 ),
+ myIsPixmapCached( true ),
+ myHasUserValues( true ),
+ myWorkingMode( AllowUserValues )
{
QString envVar = !resVarTemplate.isEmpty() ? resVarTemplate : QString( "%1Resources" );
if ( envVar.contains( "%1" ) )
envVar = envVar.arg( appName );
QString dirs;
- if ( ::getenv( envVar ) )
- dirs = ::getenv( envVar );
-
- setDirList( QStringList::split( ";", dirs ) );
+ if ( ::getenv( envVar.toLatin1() ) )
+ dirs = ::getenv( envVar.toLatin1() );
+#ifdef WIN32
+ QString dirsep = ";"; // for Windows: ";" is used as directories separator
+#else
+ QString dirsep = "[:|;]"; // for Linux: both ":" and ";" can be used
+#endif
+ setDirList( dirs.split( QRegExp( dirsep ), QString::SkipEmptyParts ) );
installFormat( new XmlFormat() );
installFormat( new IniFormat() );
}
/*!
- \brief Destructs the resource manager object and free allocated memory.
+ \brief Destructor.
+
+ Destroy the resource manager and free allocated memory.
*/
QtxResourceMgr::~QtxResourceMgr()
{
QStringList prefList = myTranslator.keys();
- for ( QStringList::const_iterator it = prefList.begin(); it != prefList.end(); ++it )
+ for ( QStringList::ConstIterator it = prefList.begin(); it != prefList.end(); ++it )
removeTranslators( *it );
+
+ qDeleteAll( myResources );
+ qDeleteAll( myFormats );
+
+ delete myDefaultPix;
}
/*!
- \brief Returns the application name.
+ \brief Get the application name.
+ \return application name
*/
QString QtxResourceMgr::appName() const
{
}
/*!
- \brief Returns the checking of the existance flag. If its 'true' then resource
- will be setted into the manager only if it doesn't exist or has different
- value that existing value.
+ \brief Get the "check existance" flag
+
+ If this flag is \c true then preference can be set (with setValue() method)
+ only if it doesn't exist or if the value is changed.
+
+ \return \c true if "check existance" flag is set
*/
bool QtxResourceMgr::checkExisting() const
{
}
/*!
- \brief Sets the checking of the existance flag.
- \param on - boolean value of the flag.
+ \brief Set the "check existance" flag.
+ \param on new flag value
*/
void QtxResourceMgr::setCheckExisting( const bool on )
{
}
/*!
- \brief Returns the resource directories list except user home directory.
+ \brief Get the resource directories list.
+
+ Home user directory (where the user application configuration file is situated)
+ is not included. This is that directories list defined by the application
+ resources environment variable.
+
+ \return list of directories names
*/
QStringList QtxResourceMgr::dirList() const
{
}
/*!
- \brief Initialise the manager. Prepare the resource containers and load resources.
- \param autoLoad - if 'true' then all resources will be loaded.
+ \brief Initialise resources manager.
+
+ Prepare the resources containers and load resources (if \a autoLoad is \c true).
+
+ \param autoLoad if \c true (default) then all resources are loaded
*/
void QtxResourceMgr::initialize( const bool autoLoad ) const
{
QtxResourceMgr* that = (QtxResourceMgr*)this;
- that->myResources.append( new Resources( userFileName( appName() ) ) );
- for ( QStringList::const_iterator it = myDirList.begin(); it != myDirList.end(); ++it )
+ if ( !userFileName( appName() ).isEmpty() )
+ that->myResources.append( new Resources( that, userFileName( appName() ) ) );
+
+ that->myHasUserValues = myResources.count() > 0;
+
+ for ( QStringList::ConstIterator it = myDirList.begin(); it != myDirList.end(); ++it )
{
QString path = Qtx::addSlash( *it ) + globalFileName( appName() );
- that->myResources.append( new Resources( path ) );
+ that->myResources.append( new Resources( that, path ) );
}
if ( autoLoad )
}
/*!
- \brief Removes all resources from the manager.
+ \brief Get "cached pixmaps" option value.
+
+ Resources manager allows possibility to cache loaded pixmaps that allow to
+ improve application performance. This feature is turned on by default - all
+ loaded pixmaps are stored in the internal map. Switching of this feature on/off
+ can be done by setIsPixmapCached() method.
+
+ \return \c true if pixmap cache is turned on
+ \sa setIsPixmapCached()
+*/
+bool QtxResourceMgr::isPixmapCached() const
+{
+ return myIsPixmapCached;
+}
+
+/*!
+ \brief Switch "cached pixmaps" option on/off.
+ \param on enable pixmap cache if \c true and disable it if \c false
+ \sa isPixmapCached()
+*/
+void QtxResourceMgr::setIsPixmapCached( const bool on )
+{
+ myIsPixmapCached = on;
+}
+
+/*!
+ \brief Remove all resources from the resources manager.
*/
void QtxResourceMgr::clear()
{
- for ( ResListIterator it( myResources ); it.current(); ++it )
- it.current()->clear();
+ for ( ResList::Iterator it = myResources.begin(); it != myResources.end(); ++it )
+ (*it)->clear();
+}
+
+/*!
+ \brief Get current working mode.
+
+ \return current working mode
+ \sa setWorkingMode(), value(), hasValue(), hasSection(), setValue()
+*/
+QtxResourceMgr::WorkingMode QtxResourceMgr::workingMode() const
+{
+ return myWorkingMode;
+}
+
+/*!
+ \brief Set resource manager's working mode.
+
+ The resource manager can operate in the following working modes:
+ * AllowUserValues : methods values(), hasValue(), hasSection() take into account user values (default)
+ * IgnoreUserValues : methods values(), hasValue(), hasSection() do not take into account user values
+
+ Note, that setValue() method always put the value to the user settings file.
+
+ \param mode new working mode
+ \return previous working mode
+ \sa workingMode(), value(), hasValue(), hasSection(), setValue()
+*/
+QtxResourceMgr::WorkingMode QtxResourceMgr::setWorkingMode( WorkingMode mode )
+{
+ WorkingMode m = myWorkingMode;
+ myWorkingMode = mode;
+ return m;
}
/*!
- \brief Get the resource value as integer. Returns 'true' if it successfull otherwise
- returns 'false'.
- \param sect - Resource section name which contains resource.
- \param name - Name of the resource.
- \param iVal - Reference on the variable which should contains the resource output.
+ \brief Get interger parameter value.
+ \param sect section name
+ \param name parameter name
+ \param iVal parameter to return resulting integer value
+ \return \c true if parameter is found and \c false if parameter is not found
+ (in this case \a iVal value is undefined)
*/
bool QtxResourceMgr::value( const QString& sect, const QString& name, int& iVal ) const
{
}
/*!
- \brief Get the resource value as double. Returns 'true' if it successfull otherwise
- returns 'false'.
- \param sect - Resource section name which contains resource.
- \param name - Name of the resource.
- \param dVal - Reference on the variable which should contains the resource output.
+ \brief Get double parameter value.
+ \param sect section name
+ \param name parameter name
+ \param dVal parameter to return resulting double value
+ \return \c true if parameter is found and \c false if parameter is not found
+ (in this case \a dVal value is undefined)
*/
bool QtxResourceMgr::value( const QString& sect, const QString& name, double& dVal ) const
{
}
/*!
- \brief Get the resource value as boolean. Returns 'true' if it successfull otherwise
- returns 'false'.
- \param sect - Resource section name which contains resource.
- \param name - Name of the resource.
- \param bVal - Reference on the variable which should contains the resource output.
+ \brief Get boolean parameter value.
+ \param sect section name
+ \param name parameter name
+ \param bVal parameter to return resulting boolean value
+ \return \c true if parameter is found and \c false if parameter is not found
+ (in this case \a bVal value is undefined)
*/
bool QtxResourceMgr::value( const QString& sect, const QString& name, bool& bVal ) const
{
boolMap["false"] = boolMap["no"] = boolMap["off"] = false;
}
- val = val.lower();
+ val = val.toLower();
bool res = boolMap.contains( val );
if ( res )
bVal = boolMap[val];
}
/*!
- \brief Get the resource value as color. Returns 'true' if it successfull otherwise
- returns 'false'.
- \param sect - Resource section name which contains resource.
- \param name - Name of the resource.
- \param cVal - Reference on the variable which should contains the resource output.
+ \brief Get color parameter value.
+ \param sect section name
+ \param name parameter name
+ \param cVal parameter to return resulting color value
+ \return \c true if parameter is found and \c false if parameter is not found
+ (in this case \a cVal value is undefined)
*/
bool QtxResourceMgr::value( const QString& sect, const QString& name, QColor& cVal ) const
{
if ( !value( sect, name, val, true ) )
return false;
- bool res = true;
- QStringList vals = QStringList::split( ",", val, true );
-
- QIntList nums;
- for ( QStringList::const_iterator it = vals.begin(); it != vals.end() && res; ++it )
- nums.append( (*it).toInt( &res ) );
-
- if ( res && nums.count() >= 3 )
- cVal.setRgb( nums[0], nums[1], nums[2] );
- else
- {
- int pack = val.toInt( &res );
- if ( res )
- Qtx::rgbSet( pack, cVal );
- }
-
- return res;
+ return Qtx::stringToColor( val, cVal );
}
/*!
- \brief Get the resource value as font. Returns 'true' if it successfull otherwise
- returns 'false'.
- \param sect - Resource section name which contains resource.
- \param name - Name of the resource.
- \param fVal - Reference on the variable which should contains the resource output.
+ \brief Get font parameter value.
+ \param sect section name
+ \param name parameter name
+ \param fVal parameter to return resulting font value
+ \return \c true if parameter is found and \c false if parameter is not found
+ (in this case \a fVal value is undefined)
*/
bool QtxResourceMgr::value( const QString& sect, const QString& name, QFont& fVal ) const
{
if ( !value( sect, name, val, true ) )
return false;
- QStringList fontDescr = QStringList::split( ",", val );
+ QStringList fontDescr = val.split( ",", QString::SkipEmptyParts );
if ( fontDescr.count() < 2 )
return false;
for ( int i = 1; i < (int)fontDescr.count(); i++ )
{
- QString curval = fontDescr[i].stripWhiteSpace().lower();
+ QString curval = fontDescr[i].trimmed().toLower();
if ( curval == QString( "bold" ) )
fVal.setBold( true );
else if ( curval == QString( "italic" ) )
fVal.setItalic( true );
else if ( curval == QString( "underline" ) )
fVal.setUnderline( true );
+ else if ( curval == QString( "shadow" ) || curval == QString( "overline" ) )
+ fVal.setOverline( true );
else
{
bool isOk = false;
}
/*!
- \brief Get the resource value as string (native format). Returns 'true' if it
- successfull otherwise returns 'false'.
- \param sect - Resource section name which contains resource.
- \param name - Name of the resource.
- \param val - Reference on the variable which should contains the resource output.
- \param subst - If 'true' then manager substitute reference on environment variables
- and other resources by thier values. Default value of this parameter
- is 'true'
+ \brief Get byte array parameter value.
+ \param sect section name
+ \param name parameter name
+ \param baVal parameter to return resulting byte array value
+ \return \c true if parameter is found and \c false if parameter is not found
+ (in this case \a baVal value is undefined)
*/
-bool QtxResourceMgr::value( const QString& sect, const QString& name, QString& val, const bool subst ) const
+bool QtxResourceMgr::value( const QString& sect, const QString& name, QByteArray& baVal ) const
{
- initialize();
-
- bool ok = false;
- for ( ResListIterator it( myResources ); it.current() && !ok; ++it )
+ QString val;
+ if ( !value( sect, name, val, true ) )
+ return false;
+
+ baVal.clear();
+ QStringList lst = val.split( QRegExp( "[\\s|,]" ), QString::SkipEmptyParts );
+ for ( QStringList::ConstIterator it = lst.begin(); it != lst.end(); ++it )
{
- ok = it.current()->hasValue( sect, name );
+ int base = 10;
+ QString str = *it;
+ if ( str.startsWith( "#" ) )
+ {
+ base = 16;
+ str = str.mid( 1 );
+ }
+ bool ok = false;
+ int num = str.toInt( &ok, base );
+ if ( !ok || num < 0 || num > 255 )
+ continue;
+
+ baVal.append( (char)num );
+ }
+ return !baVal.isEmpty();
+}
+
+/*!
+ \brief Get linear gradient parameter value.
+ \param sect section name
+ \param name parameter name
+ \param gVal parameter to return resulting linear gradient value
+ \return \c true if parameter is found and \c false if parameter is not found
+ (in this case \a gVal value is undefined)
+*/
+bool QtxResourceMgr::value( const QString& sect, const QString& name, QLinearGradient& gVal ) const
+{
+ QString val;
+ if ( !value( sect, name, val, true ) )
+ return false;
+
+ return Qtx::stringToLinearGradient( val, gVal );
+}
+
+/*!
+ \brief Get radial gradient parameter value.
+ \param sect section name
+ \param name parameter name
+ \param gVal parameter to return resulting radial gradient value
+ \return \c true if parameter is found and \c false if parameter is not found
+ (in this case \a gVal value is undefined)
+*/
+bool QtxResourceMgr::value( const QString& sect, const QString& name, QRadialGradient& gVal ) const
+{
+ QString val;
+ if ( !value( sect, name, val, true ) )
+ return false;
+
+ return Qtx::stringToRadialGradient( val, gVal );
+}
+
+/*!
+ \brief Get conical gradient parameter value.
+ \param sect section name
+ \param name parameter name
+ \param gVal parameter to return resulting conical gradient value
+ \return \c true if parameter is found and \c false if parameter is not found
+ (in this case \a gVal value is undefined)
+*/
+bool QtxResourceMgr::value( const QString& sect, const QString& name, QConicalGradient& gVal ) const
+{
+ QString val;
+ if ( !value( sect, name, val, true ) )
+ return false;
+
+ return Qtx::stringToConicalGradient( val, gVal );
+}
+
+/*!
+ \brief Get background parameter value.
+ \param sect section name
+ \param name parameter name
+ \param bgVal parameter to return resulting background value
+ \return \c true if parameter is found and \c false if parameter is not found
+ (in this case \a bgVal value is undefined)
+*/
+bool QtxResourceMgr::value( const QString& sect, const QString& name, Qtx::BackgroundData& bgVal ) const
+{
+ QString val;
+ if ( !value( sect, name, val, true ) )
+ return false;
+
+ bgVal = Qtx::stringToBackground( val );
+ return bgVal.isValid();
+}
+
+/*!
+ \brief Get string parameter value (native format).
+ \param sect section name
+ \param name parameter name
+ \param val parameter to return resulting byte array value
+ \param subst if \c true perform environment variables substitution
+ \return \c true if parameter is found and \c false if parameter is not found
+ (in this case \a val value is undefined)
+*/
+bool QtxResourceMgr::value( const QString& sect, const QString& name, QString& val, const bool subst ) const
+{
+ initialize();
+
+ bool ok = false;
+
+ ResList::ConstIterator it = myResources.begin();
+ if ( myHasUserValues && workingMode() == IgnoreUserValues )
+ ++it;
+
+ for ( ; it != myResources.end() && !ok; ++it )
+ {
+ ok = (*it)->hasValue( sect, name );
if ( ok )
- val = it.current()->value( sect, name, subst );
+ val = (*it)->value( sect, name, subst );
}
return ok;
}
/*!
- \brief Returns the integer resource value. If resource can not be found or converted
- then specified default value will be returned.
- \param sect - Resource section name which contains resource.
- \param name - Name of the resource.
- \param def - Default resource value which will be used when resource not found.
+ \brief Get interger parameter value.
+
+ If the specified parameter is not found or can not be converted to the integer value,
+ the specified default value is returned instead.
+
+ \param sect section name
+ \param name parameter name
+ \param def default value
+ \return parameter value (or default value if parameter is not found)
*/
int QtxResourceMgr::integerValue( const QString& sect, const QString& name, const int def ) const
{
}
/*!
- \brief Returns the double resource value. If resource can not be found or converted
- then specified default value will be returned.
- \param sect - Resource section name which contains resource.
- \param name - Name of the resource.
- \param def - Default resource value which will be used when resource not found.
+ \brief Get double parameter value.
+
+ If the specified parameter is not found or can not be converted to the double value,
+ the specified default value is returned instead.
+
+ \param sect section name
+ \param name parameter name
+ \param def default value
+ \return parameter value (or default value if parameter is not found)
*/
double QtxResourceMgr::doubleValue( const QString& sect, const QString& name, const double def ) const
{
}
/*!
- \brief Returns the boolean resource value. If resource can not be found or converted
- then specified default value will be returned.
- \param sect - Resource section name which contains resource.
- \param name - Name of the resource.
- \param def - Default resource value which will be used when resource not found.
+ \brief Get boolean parameter value.
+
+ If the specified parameter is not found or can not be converted to the boolean value,
+ the specified default value is returned instead.
+
+ \param sect section name
+ \param name parameter name
+ \param def default value
+ \return parameter value (or default value if parameter is not found)
*/
bool QtxResourceMgr::booleanValue( const QString& sect, const QString& name, const bool def ) const
{
}
/*!
- \brief Returns the font resource value. If resource can not be found or converted
- then specified default value will be returned.
- \param sect - Resource section name which contains resource.
- \param name - Name of the resource.
- \param def - Default resource value which will be used when resource not found.
+ \brief Get font parameter value.
+
+ If the specified parameter is not found or can not be converted to the font value,
+ the specified default value is returned instead.
+
+ \param sect section name
+ \param name parameter name
+ \param def default value
+ \return parameter value (or default value if parameter is not found)
*/
QFont QtxResourceMgr::fontValue( const QString& sect, const QString& name, const QFont& def ) const
{
}
/*!
- \brief Returns the color resource value. If resource can not be found or converted
- then specified default value will be returned.
- \param sect - Resource section name which contains resource.
- \param name - Name of the resource.
- \param def - Default resource value which will be used when resource not found.
+ \brief Get color parameter value.
+
+ If the specified parameter is not found or can not be converted to the color value,
+ the specified default value is returned instead.
+
+ \param sect section name
+ \param name parameter name
+ \param def default value
+ \return parameter value (or default value if parameter is not found)
*/
QColor QtxResourceMgr::colorValue( const QString& sect, const QString& name, const QColor& def ) const
{
}
/*!
- \brief Returns the string resource value. If resource can not be found or converted
- then specified default value will be returned.
- \param sect - Resource section name which contains resource.
- \param name - Name of the resource.
- \param def - Default resource value which will be used when resource not found.
+ \brief Get string parameter value.
+
+ If the specified parameter is not found, the specified default value is returned instead.
+
+ \param sect section name
+ \param name parameter name
+ \param def default value
+ \return parameter value (or default value if parameter is not found)
*/
QString QtxResourceMgr::stringValue( const QString& sect, const QString& name, const QString& def ) const
{
}
/*!
- \brief Checks existance of the specified resource.
- \param sect - Resource section name which contains resource.
- \param name - Name of the resource.
+ \brief Get byte array parameter value.
+
+ If the specified parameter is not found, the specified default value is returned instead.
+
+ \param sect section name
+ \param name parameter name
+ \param def default value
+ \return parameter value (or default value if parameter is not found)
+*/
+QByteArray QtxResourceMgr::byteArrayValue( const QString& sect, const QString& name, const QByteArray& def ) const
+{
+ QByteArray val;
+ if ( !value( sect, name, val ) )
+ val = def;
+ return val;
+}
+
+/*!
+ \brief Get linear gradient parameter value.
+
+ If the specified parameter is not found, the specified default value is returned instead.
+
+ \param sect section name
+ \param name parameter name
+ \param def default value
+ \return parameter value (or default value if parameter is not found)
+*/
+QLinearGradient QtxResourceMgr::linearGradientValue( const QString& sect, const QString& name, const QLinearGradient& def ) const
+{
+ QLinearGradient val;
+ if ( !value( sect, name, val ) )
+ val = def;
+ return val;
+}
+
+/*!
+ \brief Get radial gradient parameter value.
+
+ If the specified parameter is not found, the specified default value is returned instead.
+
+ \param sect section name
+ \param name parameter name
+ \param def default value
+ \return parameter value (or default value if parameter is not found)
+*/
+QRadialGradient QtxResourceMgr::radialGradientValue( const QString& sect, const QString& name, const QRadialGradient& def ) const
+{
+ QRadialGradient val;
+ if ( !value( sect, name, val ) )
+ val = def;
+ return val;
+}
+
+/*!
+ \brief Get conical gradient parameter value.
+
+ If the specified parameter is not found, the specified default value is returned instead.
+
+ \param sect section name
+ \param name parameter name
+ \param def default value
+ \return parameter value (or default value if parameter is not found)
+*/
+QConicalGradient QtxResourceMgr::conicalGradientValue( const QString& sect, const QString& name, const QConicalGradient& def ) const
+{
+ QConicalGradient val;
+ if ( !value( sect, name, val ) )
+ val = def;
+ return val;
+}
+
+/*!
+ \brief Get background parameter value.
+
+ If the specified parameter is not found, the specified default value is returned instead.
+
+ \param sect section name
+ \param name parameter name
+ \param def default value
+ \return parameter value (or default value if parameter is not found)
+*/
+Qtx::BackgroundData QtxResourceMgr::backgroundValue( const QString& sect, const QString& name, const Qtx::BackgroundData& def ) const
+{
+ Qtx::BackgroundData val;
+ if ( !value( sect, name, val ) )
+ val = def;
+ return val;
+}
+
+/*!
+ \brief Check parameter existence.
+ \param sect section name
+ \param name parameter name
+ \return \c true if parameter exists in specified section
*/
bool QtxResourceMgr::hasValue( const QString& sect, const QString& name ) const
{
initialize();
bool ok = false;
- for ( ResListIterator it( myResources ); it.current() && !ok; ++it )
- ok = it.current()->hasValue( sect, name );
+
+ ResList::ConstIterator it = myResources.begin();
+ if ( myHasUserValues && workingMode() == IgnoreUserValues )
+ ++it;
+
+ for ( ; it != myResources.end() && !ok; ++it )
+ ok = (*it)->hasValue( sect, name );
return ok;
}
/*!
- \brief Checks existance of the specified resource section.
- \param sect - Resource section name which contains resource.
+ \brief Check section existence.
+ \param sect section name
+ \return \c true if section exists
*/
bool QtxResourceMgr::hasSection( const QString& sect ) const
{
initialize();
bool ok = false;
- for ( ResListIterator it( myResources ); it.current() && !ok; ++it )
- ok = it.current()->hasSection( sect );
+
+ ResList::ConstIterator it = myResources.begin();
+ if ( myHasUserValues && workingMode() == IgnoreUserValues )
+ ++it;
+
+ for ( ; it != myResources.end() && !ok; ++it )
+ ok = (*it)->hasSection( sect );
return ok;
}
/*!
- \brief Sets the integer resource value.
- \param sect - Resource section name.
- \param name - Name of the resource.
- \param val - Resource value.
+ \brief Set integer parameter value.
+ \param sect section name
+ \param name parameter name
+ \param val parameter value
*/
void QtxResourceMgr::setValue( const QString& sect, const QString& name, int val )
{
}
/*!
- \brief Sets the double resource value.
- \param sect - Resource section name.
- \param name - Name of the resource.
- \param val - Resource value.
+ \brief Set double parameter value.
+ \param sect section name
+ \param name parameter name
+ \param val parameter value
*/
void QtxResourceMgr::setValue( const QString& sect, const QString& name, double val )
{
}
/*!
- \brief Sets the boolean resource value.
- \param sect - Resource section name.
- \param name - Name of the resource.
- \param val - Resource value.
+ \brief Set boolean parameter value.
+ \param sect section name
+ \param name parameter name
+ \param val parameter value
*/
void QtxResourceMgr::setValue( const QString& sect, const QString& name, bool val )
{
}
/*!
- \brief Sets the color resource value.
- \param sect - Resource section name.
- \param name - Name of the resource.
- \param val - Resource value.
+ \brief Set color parameter value.
+ \param sect section name
+ \param name parameter name
+ \param val parameter value
*/
void QtxResourceMgr::setValue( const QString& sect, const QString& name, const QColor& val )
{
if ( checkExisting() && value( sect, name, res ) && res == val )
return;
- setResource( sect, name, QString( "%1, %2, %3" ).arg( val.red() ).arg( val.green() ).arg( val.blue() ) );
+ setResource( sect, name, Qtx::colorToString( val ) );
}
/*!
- \brief Sets the font resource value.
- \param sect - Resource section name.
- \param name - Name of the resource.
- \param val - Resource value.
+ \brief Set font parameter value.
+ \param sect section name
+ \param name parameter name
+ \param val parameter value
*/
void QtxResourceMgr::setValue( const QString& sect, const QString& name, const QFont& val )
{
fontDescr.append( "Italic" );
if ( val.underline() )
fontDescr.append( "Underline" );
+ if ( val.overline() )
+ fontDescr.append( "Overline" );
fontDescr.append( QString( "%1" ).arg( val.pointSize() ) );
setResource( sect, name, fontDescr.join( "," ) );
}
/*!
- \brief Sets the string resource value.
- \param sect - Resource section name.
- \param name - Name of the resource.
- \param val - Resource value.
+ \brief Set string parameter value.
+ \param sect section name
+ \param name parameter name
+ \param val parameter value
*/
void QtxResourceMgr::setValue( const QString& sect, const QString& name, const QString& val )
{
}
/*!
- \brief Remove the all specified resource section.
- \param sect - Resource section name.
+ \brief Set byte array parameter value.
+ \param sect section name
+ \param name parameter name
+ \param val parameter value
+*/
+void QtxResourceMgr::setValue( const QString& sect, const QString& name, const QByteArray& val )
+{
+ QByteArray res;
+ if ( checkExisting() && value( sect, name, res ) && res == val )
+ return;
+
+ char buf[8];
+ QStringList lst;
+ for ( int i = 0; i < val.size(); i++ )
+ {
+ ::sprintf( buf, "#%02X", (unsigned char)val.at( i ) );
+ lst.append( QString( buf ) );
+ }
+ setResource( sect, name, lst.join( " " ) );
+}
+
+/*!
+ \brief Set linear gradient parameter value.
+ \param sect section name
+ \param name parameter name
+ \param val parameter value
+*/
+void QtxResourceMgr::setValue( const QString& sect, const QString& name, const QLinearGradient& val )
+{
+ QLinearGradient res;
+ if ( checkExisting() && value( sect, name, res ) && res == val )
+ return;
+
+ setResource( sect, name, Qtx::gradientToString( val ) );
+}
+
+/*!
+ \brief Set radial gradient parameter value.
+ \param sect section name
+ \param name parameter name
+ \param val parameter value
+*/
+void QtxResourceMgr::setValue( const QString& sect, const QString& name, const QRadialGradient& val )
+{
+ QRadialGradient res;
+ if ( checkExisting() && value( sect, name, res ) && res == val )
+ return;
+
+ setResource( sect, name, Qtx::gradientToString( val ) );
+}
+
+/*!
+ \brief Set conical gradient parameter value.
+ \param sect section name
+ \param name parameter name
+ \param val parameter value
+*/
+void QtxResourceMgr::setValue( const QString& sect, const QString& name, const QConicalGradient& val )
+{
+ QConicalGradient res;
+ if ( checkExisting() && value( sect, name, res ) && res == val )
+ return;
+
+ setResource( sect, name, Qtx::gradientToString( val ) );
+}
+
+/*!
+ \brief Set background parameter value.
+ \param sect section name
+ \param name parameter name
+ \param val parameter value
+*/
+void QtxResourceMgr::setValue( const QString& sect, const QString& name, const Qtx::BackgroundData& val )
+{
+ Qtx::BackgroundData res;
+ if ( checkExisting() && value( sect, name, res ) && res == val )
+ return;
+
+ setResource( sect, name, Qtx::backgroundToString( val ) );
+}
+
+/*!
+ \brief Remove resources section.
+ \param sect section name
*/
void QtxResourceMgr::remove( const QString& sect )
{
initialize();
- for ( ResListIterator it( myResources ); it.current(); ++it )
- it.current()->removeSection( sect );
+ for ( ResList::Iterator it = myResources.begin(); it != myResources.end(); ++it )
+ (*it)->removeSection( sect );
}
/*!
- \brief Remove the specified resource.
- \param sect - Resource section name.
- \param name - Name of the resource.
+ \brief Remove the specified parameter.
+ \param sect section name
+ \param name parameter name
*/
void QtxResourceMgr::remove( const QString& sect, const QString& name )
{
initialize();
- for ( ResListIterator it( myResources ); it.current(); ++it )
- it.current()->removeValue( sect, name );
+ for ( ResList::Iterator it = myResources.begin(); it != myResources.end(); ++it )
+ (*it)->removeValue( sect, name );
}
/*!
- \brief Returns the current format which operates with resource files.
+ \brief Get current configuration files format.
+ \return configuration files format name
*/
QString QtxResourceMgr::currentFormat() const
{
QString fmt;
if ( !myFormats.isEmpty() )
- fmt = myFormats.getFirst()->format();
+ fmt = myFormats[0]->format();
return fmt;
}
/*!
- \brief Sets the current format which operates with resource files.
- \param fmt - Resource format name.
+ \brief Set current configuration files format.
+ \param fmt configuration files format name
*/
void QtxResourceMgr::setCurrentFormat( const QString& fmt )
{
if ( !form )
return;
- myFormats.remove( form );
+ myFormats.removeAll( form );
myFormats.prepend( form );
if ( myResources.isEmpty() )
return;
- ResListIterator resIt( myResources );
- if ( resIt.current() )
- resIt.current()->setFile( userFileName( appName() ) );
- ++resIt;
+ ResList::Iterator resIt = myResources.begin();
+ if ( myResources.count() > myDirList.count() && resIt != myResources.end() )
+ {
+ (*resIt)->setFile( userFileName( appName() ) );
+ ++resIt;
+ }
- for ( QStringList::const_iterator it = myDirList.begin(); it != myDirList.end() && resIt.current(); ++it, ++resIt )
- resIt.current()->setFile( Qtx::addSlash( *it ) + globalFileName( appName() ) );
+ for ( QStringList::ConstIterator it = myDirList.begin(); it != myDirList.end() && resIt != myResources.end(); ++it, ++resIt )
+ (*resIt)->setFile( Qtx::addSlash( *it ) + globalFileName( appName() ) );
}
/*!
- \brief Returns the resource format object by it name.
- \param fmt - Resource format name.
+ \brief Get configuration files format by specified format name.
+ \param fmt configuration files format name
+ \return format object or 0 if format is not defined
*/
QtxResourceMgr::Format* QtxResourceMgr::format( const QString& fmt ) const
{
Format* form = 0;
- for ( FormatListIterator it( myFormats ); it.current() && !form; ++it )
+ for ( FormatList::ConstIterator it = myFormats.begin(); it != myFormats.end() && !form; ++it )
{
- if ( it.current()->format() == fmt )
- form = it.current();
+ if ( (*it)->format() == fmt )
+ form = *it;
}
return form;
}
/*!
- \brief Add the resource format to the manager. Newly added become current.
- \param form - Resource format object.
+ \brief Install configuration files format.
+
+ Added format becomes current.
+
+ \param form format object to be installed
*/
void QtxResourceMgr::installFormat( QtxResourceMgr::Format* form )
{
}
/*!
- \brief Remove the resource format from the manager.
- \param form - Resource format object.
+ \brief Remove configuration files format.
+ \param form format object to be uninstalled
*/
void QtxResourceMgr::removeFormat( QtxResourceMgr::Format* form )
{
- myFormats.remove( form );
+ myFormats.removeAll( form );
}
/*!
- \brief Returns the string list of the resource format options names.
+ \brief Get resource format options names.
+ \return list of options names
*/
QStringList QtxResourceMgr::options() const
{
}
/*!
- \brief Returns the string value for the specified option. If option doesn't exist
- then empty string will be returned.
- \param opt - Option name.
+ \brief Get the string value of the specified resources format option.
+
+ If option does not exist, null QString is returned.
+
+ \param opt option name
+ \return option value
+ \sa setOption(), options()
*/
QString QtxResourceMgr::option( const QString& opt ) const
{
}
/*!
- \brief Sets the string value for the specified option.
- \param opt - Option name.
- \param val - Option value.
+ \brief Set the string value of the specified resources format option.
+ \param opt option name
+ \param val option value
+ \sa option(), options()
*/
void QtxResourceMgr::setOption( const QString& opt, const QString& val )
{
}
/*!
- \brief Load the all resources from the resource files.
+ \brief Load all resources from all resource files (global and user).
+ \return \c true on success and \c false on error
+ \sa save()
*/
bool QtxResourceMgr::load()
{
return false;
bool res = true;
- for ( ResListIterator it( myResources ); it.current(); ++it )
- res = fmt->load( it.current() ) && res;
+ for ( ResList::Iterator it = myResources.begin(); it != myResources.end(); ++it )
+ res = fmt->load( *it ) && res;
+
+ return res;
+}
+
+/*!
+ \brief Import resources from specified resource file.
+ \param fname resources file name
+ \return \c true on success and \c false on error
+*/
+bool QtxResourceMgr::import( const QString& fname )
+{
+ Format* fmt = format( currentFormat() );
+ if ( !fmt )
+ return false;
+
+ if ( myResources.isEmpty() || !myHasUserValues )
+ return false;
+
+ Resources* r = myResources[0];
+ if ( !r )
+ return false;
+ QString old = r->file();
+ r->setFile( fname );
+ bool res = fmt->load( r );
+ r->setFile( old );
return res;
}
/*!
- \brief Save the changed resources in to the user resource file.
+ \brief Save all resources to the user resource files.
+ \return \c true on success and \c false on error
*/
bool QtxResourceMgr::save()
{
if ( !fmt )
return false;
- if ( myResources.isEmpty() )
+ if ( myResources.isEmpty() || !myHasUserValues )
return true;
- return fmt->save( myResources.getFirst() );
+ bool result = fmt->save( myResources[0] );
+
+ saved();
+
+ return result;
}
/*!
- \brief Returns the string list of the existing section names..
+ \brief Get all sections names.
+ \return list of section names
*/
QStringList QtxResourceMgr::sections() const
{
initialize();
QMap<QString, int> map;
- for ( ResListIterator it( myResources ); it.current(); ++it )
+
+ ResList::ConstIterator it = myResources.begin();
+ if ( myHasUserValues && workingMode() == IgnoreUserValues )
+ ++it;
+
+ for ( ; it != myResources.end(); ++it )
{
- QStringList lst = it.current()->sections();
- for ( QStringList::const_iterator itr = lst.begin(); itr != lst.end(); ++itr )
+ QStringList lst = (*it)->sections();
+ for ( QStringList::ConstIterator itr = lst.begin(); itr != lst.end(); ++itr )
map.insert( *itr, 0 );
}
- QStringList res;
- for ( QMap<QString, int>::ConstIterator iter = map.begin(); iter != map.end(); ++iter )
- res.append( iter.key() );
+ return map.keys();
+}
- return res;
+/*!
+ \brief Get all sections names matching specified regular expression.
+ \param re searched regular expression
+ \return list of sections names
+*/
+QStringList QtxResourceMgr::sections(const QRegExp& re) const
+{
+ return sections().filter( re );
}
/*!
- \brief Returns the string list of the existing resource names in the specified section.
- \param sec - Resource section name.
+ \brief Get all sections names with the prefix specified by passed
+ list of parent sections names.
+
+ Sub-sections are separated inside the section name by the sections
+ separator token, for example "splash:color:label".
+
+ \param names parent sub-sections names
+ \return list of sections names
+*/
+QStringList QtxResourceMgr::sections(const QStringList& names) const
+{
+ QStringList nm = names;
+ nm << ".+";
+ QRegExp re( QString( "^%1$" ).arg( nm.join( sectionsToken() ) ) );
+ return sections( re );
+}
+
+/*!
+ \brief Get list of sub-sections names for the specified parent section name.
+
+ Sub-sections are separated inside the section name by the sections
+ separator token, for example "splash:color:label".
+
+ \param section parent sub-section name
+ \param full if \c true return full names of child sub-sections, if \c false,
+ return only top-level sub-sections names
+ \return list of sub-sections names
+*/
+QStringList QtxResourceMgr::subSections(const QString& section, const bool full) const
+{
+ QStringList names = sections( QStringList() << section );
+ QMutableListIterator<QString> it( names );
+ while ( it.hasNext() ) {
+ QString name = it.next().mid( section.size() + 1 ).trimmed();
+ if ( name.isEmpty() ) {
+ it.remove();
+ continue;
+ }
+ if ( !full ) name = name.split( sectionsToken() ).first();
+ it.setValue( name );
+ }
+ names.removeDuplicates();
+ names.sort();
+ return names;
+}
+
+/*!
+ \brief Get all parameters name in specified section.
+ \param sec section name
+ \return list of settings names
*/
QStringList QtxResourceMgr::parameters( const QString& sec ) const
{
initialize();
- QMap<QString, int> map;
- for ( ResListIterator it( myResources ); it.current(); ++it )
+#if defined(QTX_NO_INDEXED_MAP)
+ typedef QMap<QString, int> PMap;
+#else
+ typedef IMap<QString, int> PMap;
+#endif
+ PMap pmap;
+
+ Resources* ur = !myResources.isEmpty() && workingMode() == IgnoreUserValues ? myResources[0] : 0;
+
+ QListIterator<Resources*> it( myResources );
+ it.toBack();
+ while ( it.hasPrevious() )
{
- QStringList lst = it.current()->parameters( sec );
- for ( QStringList::const_iterator itr = lst.begin(); itr != lst.end(); ++itr )
- map.insert( *itr, 0 );
+ Resources* r = it.previous();
+ if ( r == ur ) break;
+ QStringList lst = r->parameters( sec );
+ for ( QStringList::ConstIterator itr = lst.begin(); itr != lst.end(); ++itr )
+#if defined(QTX_NO_INDEXED_MAP)
+ if ( !pmap.contains( *itr ) ) pmap.insert( *itr, 0 );
+#else
+ pmap.insert( *itr, 0, false );
+#endif
}
- QStringList res;
- for ( QMap<QString, int>::ConstIterator iter = map.begin(); iter != map.end(); ++iter )
- res.append( iter.key() );
+ return pmap.keys();
+}
- return res;
+/*!
+ \brief Get all parameters name in specified
+ list of sub-sections names.
+
+ Sub-sections are separated inside the section name by the sections
+ separator token, for example "splash:color:label".
+
+ \param names parent sub-sections names
+ \return list of settings names
+*/
+QStringList QtxResourceMgr::parameters( const QStringList& names ) const
+{
+ return parameters( names.join( sectionsToken() ) );
}
+/*!
+ \brief Get absolute path to the file which name is defined by the parameter.
+
+ The file name is defined by \a name argument, while directory name is retrieved
+ from resources parameter \a prefix of section \a sec. Both directory and file name
+ can be relative. If the directory is relative, it is calculated from the initial
+ resources file name. Directory parameter can contain environment
+ variables, which are substituted automatically.
+
+ \param sec section name
+ \param prefix parameter containing directory name
+ \param name file name
+ \return absolute file path or null QString if file does not exist
+*/
QString QtxResourceMgr::path( const QString& sect, const QString& prefix, const QString& name ) const
{
QString res;
- for ( ResListIterator it( myResources ); it.current() && res.isEmpty(); ++it )
- res = it.current()->path( sect, prefix, name );
+
+ ResList::ConstIterator it = myResources.begin();
+ if ( myHasUserValues && workingMode() == IgnoreUserValues )
+ ++it;
+
+ for ( ; it != myResources.end() && res.isEmpty(); ++it )
+ res = (*it)->path( sect, prefix, name );
return res;
}
+/*!
+ \brief Get application resources section name.
+
+ By default, application resources section name is "resources" but
+ it can be changed by setting the "res_section_name" resources manager option.
+
+ \return section corresponding to the resources directories
+ \sa option(), setOption()
+*/
QString QtxResourceMgr::resSection() const
{
QString res = option( "res_section_name" );
return res;
}
+/*!
+ \brief Get application language section name.
+
+ By default, application language section name is "language" but
+ it can be changed by setting the "lang_section_name" resources manager option.
+
+ \return section corresponding to the application language settings
+ \sa option(), setOption()
+*/
QString QtxResourceMgr::langSection() const
{
QString res = option( "lang_section_name" );
return res;
}
+/*!
+ \brief Get sections separator token.
+
+ By default, sections separator token is colon symbol ":" but
+ it can be changed by setting the "section_token" resources manager option.
+
+ \return string corresponding to the current section separator token
+ \sa option(), setOption()
+*/
+QString QtxResourceMgr::sectionsToken() const
+{
+ QString res = option( "section_token" );
+ if ( res.isEmpty() )
+ res = QString( ":" );
+ return res;
+}
+
+/*!
+ \brief Get default pixmap.
+
+ Default pixmap is used when requested pixmap resource is not found.
+
+ \return default pixmap
+ \sa setDefaultPixmap(), loadPixmap()
+*/
QPixmap QtxResourceMgr::defaultPixmap() const
{
- return myDefaultPix;
+ static QPixmap* defpx = 0;
+ if ( !defpx )
+ defpx = new QPixmap( pixmap_not_found_xpm );
+
+ return myDefaultPix ? *myDefaultPix : *defpx;
}
+/*!
+ \brief Set default pixmap.
+
+ Default pixmap is used when requested pixmap resource is not found.
+
+ \param pix default pixmap
+ \sa defaultPixmap(), loadPixmap()
+*/
void QtxResourceMgr::setDefaultPixmap( const QPixmap& pix )
{
- myDefaultPix = pix;
+ delete myDefaultPix;
+ if ( pix.isNull() )
+ myDefaultPix = 0;
+ else
+ myDefaultPix = new QPixmap( pix );
}
+/*!
+ \brief Load pixmap resource.
+ \param prefix parameter which refers to the resources directory (directories)
+ \param name pixmap file name
+ \return pixmap loaded from the file
+ \sa defaultPixmap(), setDefaultPixmap()
+*/
QPixmap QtxResourceMgr::loadPixmap( const QString& prefix, const QString& name ) const
{
return loadPixmap( prefix, name, true );
}
+/*!
+ \brief Load pixmap resource.
+ \overload
+ \param prefix parameter which refers to the resources directory (directories)
+ \param name pixmap file name
+ \param useDef if \c false, default pixmap is not returned if resource is not found,
+ in this case null pixmap is returned instead
+ \return pixmap loaded from the file
+ \sa defaultPixmap(), setDefaultPixmap()
+*/
QPixmap QtxResourceMgr::loadPixmap( const QString& prefix, const QString& name, const bool useDef ) const
{
return loadPixmap( prefix, name, useDef ? defaultPixmap() : QPixmap() );
}
+/*!
+ \brief Load pixmap resource.
+ \overload
+ \param prefix parameter which refers to the resources directory (directories)
+ \param name pixmap file name
+ \param defPix default which should be used if the resource file doesn't exist
+ \return pixmap loaded from the file
+ \sa defaultPixmap(), setDefaultPixmap()
+*/
QPixmap QtxResourceMgr::loadPixmap( const QString& prefix, const QString& name, const QPixmap& defPix ) const
{
initialize();
QPixmap pix;
- for ( ResListIterator it( myResources ); it.current() && pix.isNull(); ++it )
- pix = it.current()->loadPixmap( resSection(), prefix, name );
+
+ ResList::ConstIterator it = myResources.begin();
+ if ( myHasUserValues && workingMode() == IgnoreUserValues )
+ ++it;
+
+ for ( ; it != myResources.end() && pix.isNull(); ++it )
+ pix = (*it)->loadPixmap( resSection(), prefix, name );
if ( pix.isNull() )
pix = defPix;
return pix;
}
+/*!
+ \brief Load translation files according to the specified language.
+
+ Names of the translation files are calculated according to the pattern specified
+ by the "translators" option (this option is read from the section "language" of resources files).
+ By default, "%P_msg_%L.qm" pattern is used.
+ Keywords \%A, \%P, \%L in the pattern are substituted by the application name, prefix and language name
+ correspondingly.
+ For example, for prefix "SUIT" and language "en", all translation files "SUIT_msg_en.qm" are searched and
+ loaded.
+
+ If prefix is empty or null string, all translation files specified in the "resources" section of resources
+ files are loaded (actually, the section is retrieved from resSection() method).
+ If language is not specified, it is retrieved from the langSection() method, and if the latest is also empty,
+ by default "en" (English) language is used.
+ By default, settings from the user preferences file are also loaded (if user resource file is valid,
+ see userFileName()). To avoid loading user settings, pass \c false as first parameter.
+
+ \param pref parameter which defines translation context (for example, package name)
+ \param l language name
+
+ \sa resSection(), langSection(), loadTranslators()
+*/
void QtxResourceMgr::loadLanguage( const QString& pref, const QString& l )
{
- initialize();
+ initialize( true );
QMap<QChar, QString> substMap;
substMap.insert( 'A', appName() );
if ( lang.isEmpty() )
{
lang = QString( "en" );
- qWarning( QString( "Language not specified. Assumed: %1" ).arg( lang ) );
+ qWarning() << "QtxResourceMgr: Language not specified. Assumed:" << lang;
}
substMap.insert( 'L', lang );
QString trs;
if ( value( langSection(), "translators", trs, false ) && !trs.isEmpty() )
{
- QStringList translators = QStringList::split( "|", option( "translators" ) );
- QStringList newTranslators = QStringList::split( "|", trs );
- for ( uint i = 0; i < newTranslators.count(); i++ )
- if ( translators.find( newTranslators[i] ) == translators.end() )
+ QStringList translators = option( "translators" ).split( "|", QString::SkipEmptyParts );
+ QStringList newTranslators = trs.split( "|", QString::SkipEmptyParts );
+ for ( int i = 0; i < (int)newTranslators.count(); i++ )
+ {
+ if ( translators.indexOf( newTranslators[i] ) < 0 )
translators += newTranslators[i];
+ }
setOption( "translators", translators.join( "|" ) );
}
- QStringList trList = QStringList::split( "|", option( "translators" ) );
+ QStringList trList = option( "translators" ).split( "|", QString::SkipEmptyParts );
if ( trList.isEmpty() )
{
trList.append( "%P_msg_%L.qm" );
- qWarning( QString( "Translators not defined. Assumed: %1" ).arg( trList.first() ) );
+ qWarning() << "QtxResourceMgr: Translators not defined. Assumed:" << trList[0];
}
QStringList prefixList;
else
prefixList = parameters( resSection() );
- for ( QStringList::const_iterator iter = prefixList.begin(); iter != prefixList.end(); ++iter )
+ if ( pref.isEmpty() && lang != "en" ) {
+ // load Qt resources
+ QString qt_translations = QLibraryInfo::location( QLibraryInfo::TranslationsPath );
+ QString qt_dir_trpath = qgetenv( "QT_ROOT_DIR" );
+ if ( qt_dir_trpath.isEmpty() )
+ qt_dir_trpath = qgetenv( "QTDIR" );
+ if ( !qt_dir_trpath.isEmpty() )
+ qt_dir_trpath = QDir( qt_dir_trpath ).absoluteFilePath( "translations" );
+
+ QTranslator* trans = new QtxTranslator( 0 );
+ if ( trans->load( QString("qt_%1").arg( lang ), qt_translations ) || trans->load( QString("qt_%1").arg( lang ), qt_dir_trpath ) ) {
+ if ( QApplication::instance() ) QApplication::instance()->installTranslator( trans );
+ }
+ }
+
+ for ( QStringList::ConstIterator iter = prefixList.begin(); iter != prefixList.end(); ++iter )
{
QString prefix = *iter;
substMap.insert( 'P', prefix );
QStringList trs;
- for ( QStringList::const_iterator it = trList.begin(); it != trList.end(); ++it )
- trs.append( substMacro( *it, substMap ).stripWhiteSpace() );
+ for ( QStringList::ConstIterator it = trList.begin(); it != trList.end(); ++it )
+ trs.append( substMacro( *it, substMap ).trimmed() );
+
+ loadTranslators( prefix, trs );
+ }
+}
+
+/*!
+ \brief Load translation files for the specified translation context.
+ \param prefix parameter which defines translation context (for example, package name)
+ \param translators list of translation files
+ \sa loadLanguage()
+*/
+void QtxResourceMgr::loadTranslators( const QString& prefix, const QStringList& translators )
+{
+ initialize();
+
+ ResList lst;
+
+ ResList::ConstIterator iter = myResources.begin();
+ if ( myHasUserValues && workingMode() == IgnoreUserValues )
+ ++iter;
+
+ for ( ; iter != myResources.end(); ++iter )
+ lst.prepend( *iter );
- for ( QStringList::const_iterator itr = trs.begin(); itr != trs.end(); ++itr )
- loadTranslator( prefix, *itr );
+ QTranslator* trans = 0;
+
+ for ( ResList::Iterator it = lst.begin(); it != lst.end(); ++it )
+ {
+ for ( QStringList::ConstIterator itr = translators.begin(); itr != translators.end(); ++itr )
+ {
+ trans = (*it)->loadTranslator( resSection(), prefix, *itr );
+ if ( trans )
+ {
+ if ( !myTranslator[prefix].contains( trans ) )
+ myTranslator[prefix].append( trans );
+ if ( QApplication::instance() ) QApplication::instance()->installTranslator( trans );
+ }
+ }
}
}
+/*!
+ \brief Load translation file.
+ \param prefix parameter which defines translation context (for example, package name)
+ \param name translator file name
+ \sa loadLanguage(), loadTranslators()
+*/
void QtxResourceMgr::loadTranslator( const QString& prefix, const QString& name )
{
initialize();
QTranslator* trans = 0;
- for ( ResListIterator it( myResources ); it.current() && !trans; ++it )
- trans = it.current()->loadTranslator( resSection(), prefix, name );
- if ( !trans )
- return;
+ Resources* ur = !myResources.isEmpty() && workingMode() == IgnoreUserValues ? myResources[0] : 0;
+
+ QListIterator<Resources*> it( myResources );
+ it.toBack();
+ while ( it.hasPrevious() )
+ {
+ Resources* r = it.previous();
+ if ( r == ur ) break;
- if ( !myTranslator[prefix].contains( trans ) )
- myTranslator[prefix].append( trans );
- qApp->installTranslator( trans );
+ trans = r->loadTranslator( resSection(), prefix, name );
+ if ( trans )
+ {
+ if ( !myTranslator[prefix].contains( trans ) )
+ myTranslator[prefix].append( trans );
+ if ( QApplication::instance() ) QApplication::instance()->installTranslator( trans );
+ }
+ }
}
+/*!
+ \brief Remove all translators corresponding to the specified translation context.
+ \param prefix parameter which defines translation context (for example, package name)
+*/
void QtxResourceMgr::removeTranslators( const QString& prefix )
{
if ( !myTranslator.contains( prefix ) )
return;
- for ( TransListIterator it( myTranslator[prefix] ); it.current(); ++it )
+ for ( TransList::Iterator it = myTranslator[prefix].begin(); it != myTranslator[prefix].end(); ++it )
{
- qApp->removeTranslator( it.current() );
- delete it.current();
+ if ( QApplication::instance() ) QApplication::instance()->removeTranslator( *it );
+ delete *it;
}
myTranslator.remove( prefix );
}
+/*!
+ \brief Move all translators corresponding to the specified translation context
+ to the top of translators stack (increase their priority).
+ \param prefix parameter which defines translation context (for example, package name)
+*/
void QtxResourceMgr::raiseTranslators( const QString& prefix )
{
if ( !myTranslator.contains( prefix ) )
return;
- for ( TransListIterator it( myTranslator[prefix] ); it.current(); ++it )
+ for ( TransList::Iterator it = myTranslator[prefix].begin(); it != myTranslator[prefix].end(); ++it )
{
- qApp->removeTranslator( it.current() );
- qApp->installTranslator( it.current() );
+ if ( QApplication::instance() ) {
+ QApplication::instance()->removeTranslator( *it );
+ QApplication::instance()->installTranslator( *it );
+ }
}
}
+/*!
+ \brief Copy all parameters to the user resources in order to
+ saved them lately in the user home folder.
+*/
void QtxResourceMgr::refresh()
{
QStringList sl = sections();
- for ( QStringList::const_iterator it = sl.begin(); it != sl.end(); ++it )
+ for ( QStringList::ConstIterator it = sl.begin(); it != sl.end(); ++it )
{
QStringList pl = parameters( *it );
- for ( QStringList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr )
+ for ( QStringList::ConstIterator itr = pl.begin(); itr != pl.end(); ++itr )
setResource( *it, *itr, stringValue( *it, *itr ) );
}
}
+/*!
+ \brief Set the resource directories (where global confguration files are searched).
+
+ This function also clears all currently set resources.
+
+ \param dl directories list
+*/
void QtxResourceMgr::setDirList( const QStringList& dl )
{
myDirList = dl;
- for ( ResListIterator it( myResources ); it.current(); ++it )
- delete it.current();
+ for ( ResList::Iterator it = myResources.begin(); it != myResources.end(); ++it )
+ delete *it;
myResources.clear();
}
+/*!
+ \brief Set parameter value.
+ \param sect section name
+ \param name parameter name
+ \param val parameter value
+*/
void QtxResourceMgr::setResource( const QString& sect, const QString& name, const QString& val )
{
initialize();
- if ( !myResources.isEmpty() )
+ if ( !myResources.isEmpty() && myHasUserValues )
myResources.first()->setValue( sect, name, val );
}
-QString QtxResourceMgr::userFileName( const QString& appName ) const
+/*!
+ \brief Get user configuration file name.
+
+ This method can be redefined in the successor class to customize the user configuration file name.
+ User configuration file is always situated in the user's home directory. By default .<appName>rc
+ file is used on Linux (e.g. .MyApprc) and <appName>.<format> under Windows (e.g. MyApp.xml).
+
+ Parameter \a for_load (not used in default implementation) specifies the usage mode, i.e. if
+ user configuration file is opened for reading or writing. This allows customizing a way of application
+ resources initializing (for example, if the user configuraion file includes version number and there is
+ no file corresponding to this version in the user's home directory, it could be good idea to try
+ the configuration file from the previous versions of the application).
+
+ \param appName application name
+ \param for_load boolean flag indicating that file is opened for loading or saving (not used in default implementation)
+ \return user configuration file name
+ \sa globalFileName()
+*/
+QString QtxResourceMgr::userFileName( const QString& appName, const bool /*for_load*/ ) const
{
QString fileName;
- QString pathName = QDir::homeDirPath();
+ QString pathName = QDir::homePath();
+ QString cfgAppName = QApplication::applicationName();
+ if ( !cfgAppName.isEmpty() )
+ pathName = Qtx::addSlash( Qtx::addSlash( pathName ) + QString( ".config" ) ) + cfgAppName;
#ifdef WIN32
fileName = QString( "%1.%2" ).arg( appName ).arg( currentFormat() );
#else
- fileName = QString( ".%1rc" ).arg( appName );
+ fileName = QString( "%1rc" ).arg( appName );
+ // VSR 24/09/2012: issue 0021781: do not prepend filename with "."
+ // when user file is stored in ~/.config/<appname> directory
+ if ( cfgAppName.isEmpty() )
+ fileName.prepend( "." );
#endif
if ( !fileName.isEmpty() )
return pathName;
}
+/*!
+ \brief Get global configuration file name.
+
+ This method can be redefined in the successor class to customize the global configuration file name.
+ Global configuration files are searched in the directories specified by the application resources
+ environment variable (e.g. MyAppResources). By default <appName>.<format> file name is used
+ (e.g. MyApp.xml).
+
+ \param appName application name
+ \return global configuration file name
+ \sa userFileName()
+*/
QString QtxResourceMgr::globalFileName( const QString& appName ) const
{
return QString( "%1.%2" ).arg( appName ).arg( currentFormat() );
}
+/*!
+ \brief This function is called after user configuration file is saved.
+ Can be redefined in the successor classes, default implementation does nothing.
+*/
+void QtxResourceMgr::saved()
+{
+}
+
+/*!
+ \brief Perform substitution of the patterns like \%A, \%B, etc by values from the map.
+
+ Used by loadLanguage().
+
+ \param src sring to be processed
+ \param substMap map of values for replacing
+ \return processed string
+*/
QString QtxResourceMgr::substMacro( const QString& src, const QMap<QChar, QString>& substMap ) const
{
QString trg = src;
QRegExp rx( "%[A-Za-z%]" );
int idx = 0;
- while ( ( idx = rx.search( trg, idx ) ) >= 0 )
+ while ( ( idx = rx.indexIn( trg, idx ) ) >= 0 )
{
QChar spec = trg.at( idx + 1 );
QString subst;