-rw-r--r-- | library/config.cpp | 231 | ||||
-rw-r--r-- | library/config.h | 6 |
2 files changed, 168 insertions, 69 deletions
diff --git a/library/config.cpp b/library/config.cpp index 61ff089..bdfcb3f 100644 --- a/library/config.cpp +++ b/library/config.cpp @@ -36,4 +36,32 @@ #include "global.h" +#include "qpeapplication.h" +/* + * Internal Class + */ +class ConfigPrivate { +public: + ConfigPrivate() : multilang(FALSE) {} + ConfigPrivate(const ConfigPrivate& o) : + trfile(o.trfile), + trcontext(o.trcontext), + multilang(o.multilang) + {} + ConfigPrivate& operator=(const ConfigPrivate& o) + { + trfile = o.trfile; + trcontext = o.trcontext; + multilang = o.multilang; + return *this; + } + + QString trfile; + QCString trcontext; + bool multilang; +}; + +///////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////// + /*! @@ -56,2 +84,22 @@ QString Config::configFilename(const QString& name, Domain d) +/* This cannot be made public because of binary compat issues */ +void Config::read( QTextStream &s ) +{ +#if QT_VERSION <= 230 && defined(QT_NO_CODECS) + // The below should work, but doesn't in Qt 2.3.0 + s.setCodec( QTextCodec::codecForMib( 106 ) ); +#else + s.setEncoding( QTextStream::UnicodeUTF8 ); +#endif + + QStringList list = QStringList::split('\n', s.read() ); + + for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) { + if ( !parse( *it ) ) { + git = groups.end(); + return; + } + } +} + /*! @@ -96,6 +144,4 @@ Config::Config( const QString &name, Domain domain ) git = groups.end(); + d = 0; read(); - QStringList l = Global::languageList(); - lang = l[0]; - glang = l[1]; } @@ -108,6 +154,4 @@ Config::Config ( const QString &name, bool what ) git = groups.end(); + d = 0; read(); - QStringList l = Global::languageList(); - lang = l[0]; - glang = l[1]; } @@ -120,3 +164,5 @@ Config::~Config() if ( changed ) - write(); + write(); + + delete d; } @@ -131,2 +177,11 @@ bool Config::hasKey( const QString &key ) const ConfigGroup::ConstIterator it = ( *git ).find( key ); + if ( it == ( *git ).end() ) { + if ( d && !d->trcontext.isNull() ) { + it = ( *git ).find( key + "[]" ); + } else if ( d && d->multilang ) { + it = ( *git ).find( key + "["+lang+"]" ); + if ( it == ( *git ).end() && !glang.isEmpty() ) + it = ( *git ).find( key + "["+glang+"]" ); + } + } return it != ( *git ).end(); @@ -311,2 +366,3 @@ void Config::removeEntry( const QString &key ) + /*! @@ -317,2 +373,7 @@ void Config::removeEntry( const QString &key ) +/* + * ### !LocalTranslator::translate was kept out! + * + */ + /*! @@ -323,11 +384,26 @@ QString Config::readEntry( const QString &key, const QString &deflt ) { - QString res = readEntryDirect( key+"["+lang+"]" ); - if ( !res.isNull() ) - return res; - if ( !glang.isEmpty() ) { - res = readEntryDirect( key+"["+glang+"]" ); - if ( !res.isNull() ) - return res; + QString r; + if ( d && !d->trcontext.isNull() ) { + // Still try untranslated first, becuase: + // 1. It's the common case + // 2. That way the value can be WRITTEN (becoming untranslated) + r = readEntryDirect( key ); + if ( !r.isNull() ) + return r; + r = readEntryDirect( key + "[]" ); + if ( !r.isNull() ) + return qApp->translate(d->trfile,d->trcontext,r); + } else if ( d && d->multilang ) { + // For compatibilitity + r = readEntryDirect( key + "["+lang+"]" ); + if ( !r.isNull() ) + return r; + if ( !glang.isEmpty() ) { + r = readEntryDirect( key + "["+glang+"]" ); + if ( !r.isNull() ) + return r; + } } - return readEntryDirect( key, deflt ); + r = readEntryDirect( key, deflt ); + return r; } @@ -346,9 +422,5 @@ QString Config::readEntryCrypt( const QString &key, const QString &deflt ) { - QString res = readEntryDirect( key+"["+lang+"]" ); - if ( res.isNull() && glang.isEmpty() ) - res = readEntryDirect( key+"["+glang+"]" ); - if ( res.isNull() ) - res = readEntryDirect( key, QString::null ); + QString res = readEntry( key ); if ( res.isNull() ) - return deflt; + return deflt; return decipher(res); @@ -491,4 +563,7 @@ void Config::write( const QString &fn ) filename.latin1() ); - QFile::remove( strNewFile ); + QFile::remove( strNewFile ); + return; } + + changed = FALSE; } @@ -510,19 +585,30 @@ void Config::read() - if ( !QFileInfo( filename ).exists() ) { - git = groups.end(); - return; + QString readFilename(filename); + + if ( !QFile::exists(filename) ) { + bool failed = TRUE; + QFileInfo fi(filename); + QString settingsDir = QDir::homeDirPath() + "/Settings"; + if (fi.dirPath(TRUE) == settingsDir) { + // User setting - see if there is a default in $OPIEDIR/etc/default/ + QString dftlFile = QPEApplication::qpeDir() + "etc/default/" + fi.fileName(); + if (QFile::exists(dftlFile)) { + readFilename = dftlFile; + failed = FALSE; + } + } + if (failed) { + git = groups.end(); + return; + } } - QFile f( filename ); + + QFile f( readFilename ); if ( !f.open( IO_ReadOnly ) ) { - git = groups.end(); - return; + git = groups.end(); + return; } - - // hack to avoid problems if big files are passed to test - // if they are valid configs ( like passing a mp3 ... ) - // I just hope that there are no conf files > 100000 byte - // not the best solution, find something else later - if ( f.getch()!='[' ||f.size() > 100000 ) { + if (f.getch()!='[') { git = groups.end(); @@ -532,20 +618,5 @@ void Config::read() - QTextStream s( &f ); -#if QT_VERSION <= 230 && defined(QT_NO_CODECS) - // The below should work, but doesn't in Qt 2.3.0 - s.setCodec( QTextCodec::codecForMib( 106 ) ); -#else - s.setEncoding( QTextStream::UnicodeUTF8 ); -#endif - - QStringList list = QStringList::split('\n', s.read() ); + read( s ); f.close(); - - for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) { - if ( !parse( *it ) ) { - git = groups.end(); - return; - } - } } @@ -558,21 +629,47 @@ bool Config::parse( const QString &l ) QString line = l.stripWhiteSpace(); - - if ( line [0] == QChar ( '#' )) - return true; // ignore comments - if ( line[ 0 ] == QChar( '[' ) ) { - QString gname = line; - gname = gname.remove( 0, 1 ); - if ( gname[ (int)gname.length() - 1 ] == QChar( ']' ) ) - gname = gname.remove( gname.length() - 1, 1 ); - git = groups.insert( gname, ConfigGroup() ); + QString gname = line; + gname = gname.remove( 0, 1 ); + if ( gname[ (int)gname.length() - 1 ] == QChar( ']' ) ) + gname = gname.remove( gname.length() - 1, 1 ); + git = groups.insert( gname, ConfigGroup() ); } else if ( !line.isEmpty() ) { - if ( git == groups.end() ) - return FALSE; - int eq = line.find( '=' ); - if ( eq == -1 ) - return FALSE; - QString key = line.left(eq).stripWhiteSpace(); - QString value = line.mid(eq+1).stripWhiteSpace(); - ( *git ).insert( key, value ); + if ( git == groups.end() ) + return FALSE; + int eq = line.find( '=' ); + if ( eq == -1 ) + return FALSE; + QString key = line.left(eq).stripWhiteSpace(); + QString value = line.mid(eq+1).stripWhiteSpace(); + + if ( git.key() == "Translation" ) { + if ( key == "File" ) { + if ( !d ) + d = new ConfigPrivate; + d->trfile = value; + } else if ( key == "Context" ) { + if ( !d ) + d = new ConfigPrivate; + d->trcontext = value.latin1(); + } else if ( key.startsWith("Comment") ) { + return TRUE; // ignore comment for ts file + } else { + return FALSE; // Unrecognized + } + } + + int kl = key.length(); + if ( kl > 1 && key[kl-1] == ']' && key[kl-2] != '[' ) { + // Old-style translation (inefficient) + if ( !d ) + d = new ConfigPrivate; + if ( !d->multilang ) { + QStringList l = Global::languageList(); + lang = l[0]; + glang = l[1]; + d->multilang = TRUE; + } + } + + ( *git ).insert( key, value ); } diff --git a/library/config.h b/library/config.h index 29ba0d6..f8d3bf7 100644 --- a/library/config.h +++ b/library/config.h @@ -33,2 +33,3 @@ typedef QMap< QString, ConfigGroup> ConfigGroupMap; +class QTextStream; class ConfigPrivate; @@ -94,4 +95,4 @@ protected: - QMap< QString, ConfigGroup > groups; - QMap< QString, ConfigGroup >::Iterator git; + ConfigGroupMap groups; + ConfigGroupMap::Iterator git; QString filename; @@ -105,2 +106,3 @@ private: // Sharp ROM compatibility Config( const QString &name, bool what ); + void read( QTextStream &s); }; |