summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--library/config.cpp231
-rw-r--r--library/config.h6
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
@@ -34,8 +34,36 @@
34#define QTOPIA_INTERNAL_LANGLIST 34#define QTOPIA_INTERNAL_LANGLIST
35#include "config.h" 35#include "config.h"
36#include "global.h" 36#include "global.h"
37#include "qpeapplication.h"
37 38
38 39
40/*
41 * Internal Class
42 */
43class ConfigPrivate {
44public:
45 ConfigPrivate() : multilang(FALSE) {}
46 ConfigPrivate(const ConfigPrivate& o) :
47 trfile(o.trfile),
48 trcontext(o.trcontext),
49 multilang(o.multilang)
50 {}
51 ConfigPrivate& operator=(const ConfigPrivate& o)
52 {
53 trfile = o.trfile;
54 trcontext = o.trcontext;
55 multilang = o.multilang;
56 return *this;
57 }
58
59 QString trfile;
60 QCString trcontext;
61 bool multilang;
62};
63
64/////////////////////////////////////////////////////////////////
65/////////////////////////////////////////////////////////////////
66
39/*! 67/*!
40 \internal 68 \internal
41*/ 69*/
@@ -54,6 +82,26 @@ QString Config::configFilename(const QString& name, Domain d)
54 return name; 82 return name;
55} 83}
56 84
85/* This cannot be made public because of binary compat issues */
86void Config::read( QTextStream &s )
87{
88#if QT_VERSION <= 230 && defined(QT_NO_CODECS)
89 // The below should work, but doesn't in Qt 2.3.0
90 s.setCodec( QTextCodec::codecForMib( 106 ) );
91#else
92 s.setEncoding( QTextStream::UnicodeUTF8 );
93#endif
94
95 QStringList list = QStringList::split('\n', s.read() );
96
97 for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) {
98 if ( !parse( *it ) ) {
99 git = groups.end();
100 return;
101 }
102 }
103}
104
57/*! 105/*!
58 \class Config config.h 106 \class Config config.h
59 \brief The Config class provides for saving application cofniguration state. 107 \brief The Config class provides for saving application cofniguration state.
@@ -94,10 +142,8 @@ Config::Config( const QString &name, Domain domain )
94 : filename( configFilename(name,domain) ) 142 : filename( configFilename(name,domain) )
95{ 143{
96 git = groups.end(); 144 git = groups.end();
145 d = 0;
97 read(); 146 read();
98 QStringList l = Global::languageList();
99 lang = l[0];
100 glang = l[1];
101} 147}
102 148
103 149
@@ -106,10 +152,8 @@ Config::Config ( const QString &name, bool what )
106 : filename( configFilename(name,what ? User : File) ) 152 : filename( configFilename(name,what ? User : File) )
107{ 153{
108 git = groups.end(); 154 git = groups.end();
155 d = 0;
109 read(); 156 read();
110 QStringList l = Global::languageList();
111 lang = l[0];
112 glang = l[1];
113} 157}
114 158
115/*! 159/*!
@@ -118,7 +162,9 @@ Config::Config ( const QString &name, bool what )
118Config::~Config() 162Config::~Config()
119{ 163{
120 if ( changed ) 164 if ( changed )
121 write(); 165 write();
166
167 delete d;
122} 168}
123 169
124/*! 170/*!
@@ -129,6 +175,15 @@ bool Config::hasKey( const QString &key ) const
129 if ( groups.end() == git ) 175 if ( groups.end() == git )
130 return FALSE; 176 return FALSE;
131 ConfigGroup::ConstIterator it = ( *git ).find( key ); 177 ConfigGroup::ConstIterator it = ( *git ).find( key );
178 if ( it == ( *git ).end() ) {
179 if ( d && !d->trcontext.isNull() ) {
180 it = ( *git ).find( key + "[]" );
181 } else if ( d && d->multilang ) {
182 it = ( *git ).find( key + "["+lang+"]" );
183 if ( it == ( *git ).end() && !glang.isEmpty() )
184 it = ( *git ).find( key + "["+glang+"]" );
185 }
186 }
132 return it != ( *git ).end(); 187 return it != ( *git ).end();
133} 188}
134 189
@@ -309,27 +364,48 @@ void Config::removeEntry( const QString &key )
309 Tests for inequality with \a other. Config objects are equal if they refer to the same filename. 364 Tests for inequality with \a other. Config objects are equal if they refer to the same filename.
310*/ 365*/
311 366
367
312/*! 368/*!
313 \fn QString Config::readEntry( const QString &key, const QString &deflt ) const 369 \fn QString Config::readEntry( const QString &key, const QString &deflt ) const
314 370
315 Reads a string entry stored with \a key, defaulting to \a deflt if there is no entry. 371 Reads a string entry stored with \a key, defaulting to \a deflt if there is no entry.
316*/ 372*/
317 373
374/*
375 * ### !LocalTranslator::translate was kept out!
376 *
377 */
378
318/*! 379/*!
319 \internal 380 \internal
320 For compatibility, non-const version. 381 For compatibility, non-const version.
321*/ 382*/
322QString Config::readEntry( const QString &key, const QString &deflt ) 383QString Config::readEntry( const QString &key, const QString &deflt )
323{ 384{
324 QString res = readEntryDirect( key+"["+lang+"]" ); 385 QString r;
325 if ( !res.isNull() ) 386 if ( d && !d->trcontext.isNull() ) {
326 return res; 387 // Still try untranslated first, becuase:
327 if ( !glang.isEmpty() ) { 388 // 1. It's the common case
328 res = readEntryDirect( key+"["+glang+"]" ); 389 // 2. That way the value can be WRITTEN (becoming untranslated)
329 if ( !res.isNull() ) 390 r = readEntryDirect( key );
330 return res; 391 if ( !r.isNull() )
392 return r;
393 r = readEntryDirect( key + "[]" );
394 if ( !r.isNull() )
395 return qApp->translate(d->trfile,d->trcontext,r);
396 } else if ( d && d->multilang ) {
397 // For compatibilitity
398 r = readEntryDirect( key + "["+lang+"]" );
399 if ( !r.isNull() )
400 return r;
401 if ( !glang.isEmpty() ) {
402 r = readEntryDirect( key + "["+glang+"]" );
403 if ( !r.isNull() )
404 return r;
405 }
331 } 406 }
332 return readEntryDirect( key, deflt ); 407 r = readEntryDirect( key, deflt );
408 return r;
333} 409}
334 410
335/*! 411/*!
@@ -344,13 +420,9 @@ QString Config::readEntry( const QString &key, const QString &deflt )
344*/ 420*/
345QString Config::readEntryCrypt( const QString &key, const QString &deflt ) 421QString Config::readEntryCrypt( const QString &key, const QString &deflt )
346{ 422{
347 QString res = readEntryDirect( key+"["+lang+"]" ); 423 QString res = readEntry( key );
348 if ( res.isNull() && glang.isEmpty() )
349 res = readEntryDirect( key+"["+glang+"]" );
350 if ( res.isNull() )
351 res = readEntryDirect( key, QString::null );
352 if ( res.isNull() ) 424 if ( res.isNull() )
353 return deflt; 425 return deflt;
354 return decipher(res); 426 return decipher(res);
355} 427}
356 428
@@ -489,8 +561,11 @@ void Config::write( const QString &fn )
489 if ( rename( strNewFile, filename ) < 0 ) { 561 if ( rename( strNewFile, filename ) < 0 ) {
490 qWarning( "problem renaming the file %s to %s", strNewFile.latin1(), 562 qWarning( "problem renaming the file %s to %s", strNewFile.latin1(),
491 filename.latin1() ); 563 filename.latin1() );
492 QFile::remove( strNewFile ); 564 QFile::remove( strNewFile );
565 return;
493 } 566 }
567
568 changed = FALSE;
494} 569}
495 570
496/*! 571/*!
@@ -508,46 +583,42 @@ void Config::read()
508{ 583{
509 changed = FALSE; 584 changed = FALSE;
510 585
511 if ( !QFileInfo( filename ).exists() ) { 586 QString readFilename(filename);
512 git = groups.end(); 587
513 return; 588 if ( !QFile::exists(filename) ) {
589 bool failed = TRUE;
590 QFileInfo fi(filename);
591 QString settingsDir = QDir::homeDirPath() + "/Settings";
592 if (fi.dirPath(TRUE) == settingsDir) {
593 // User setting - see if there is a default in $OPIEDIR/etc/default/
594 QString dftlFile = QPEApplication::qpeDir() + "etc/default/" + fi.fileName();
595 if (QFile::exists(dftlFile)) {
596 readFilename = dftlFile;
597 failed = FALSE;
598 }
599 }
600 if (failed) {
601 git = groups.end();
602 return;
603 }
514 } 604 }
515 605
516 QFile f( filename ); 606
607 QFile f( readFilename );
517 if ( !f.open( IO_ReadOnly ) ) { 608 if ( !f.open( IO_ReadOnly ) ) {
518 git = groups.end(); 609 git = groups.end();
519 return; 610 return;
520 } 611 }
521 612
522 613 if (f.getch()!='[') {
523 // hack to avoid problems if big files are passed to test
524 // if they are valid configs ( like passing a mp3 ... )
525 // I just hope that there are no conf files > 100000 byte
526 // not the best solution, find something else later
527 if ( f.getch()!='[' ||f.size() > 100000 ) {
528 git = groups.end(); 614 git = groups.end();
529 return; 615 return;
530 } 616 }
531 f.ungetch('['); 617 f.ungetch('[');
532 618
533
534 QTextStream s( &f ); 619 QTextStream s( &f );
535#if QT_VERSION <= 230 && defined(QT_NO_CODECS) 620 read( s );
536 // The below should work, but doesn't in Qt 2.3.0
537 s.setCodec( QTextCodec::codecForMib( 106 ) );
538#else
539 s.setEncoding( QTextStream::UnicodeUTF8 );
540#endif
541
542 QStringList list = QStringList::split('\n', s.read() );
543 f.close(); 621 f.close();
544
545 for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) {
546 if ( !parse( *it ) ) {
547 git = groups.end();
548 return;
549 }
550 }
551} 622}
552 623
553/*! 624/*!
@@ -556,25 +627,51 @@ void Config::read()
556bool Config::parse( const QString &l ) 627bool Config::parse( const QString &l )
557{ 628{
558 QString line = l.stripWhiteSpace(); 629 QString line = l.stripWhiteSpace();
559
560 if ( line [0] == QChar ( '#' ))
561 return true; // ignore comments
562
563 if ( line[ 0 ] == QChar( '[' ) ) { 630 if ( line[ 0 ] == QChar( '[' ) ) {
564 QString gname = line; 631 QString gname = line;
565 gname = gname.remove( 0, 1 ); 632 gname = gname.remove( 0, 1 );
566 if ( gname[ (int)gname.length() - 1 ] == QChar( ']' ) ) 633 if ( gname[ (int)gname.length() - 1 ] == QChar( ']' ) )
567 gname = gname.remove( gname.length() - 1, 1 ); 634 gname = gname.remove( gname.length() - 1, 1 );
568 git = groups.insert( gname, ConfigGroup() ); 635 git = groups.insert( gname, ConfigGroup() );
569 } else if ( !line.isEmpty() ) { 636 } else if ( !line.isEmpty() ) {
570 if ( git == groups.end() ) 637 if ( git == groups.end() )
571 return FALSE; 638 return FALSE;
572 int eq = line.find( '=' ); 639 int eq = line.find( '=' );
573 if ( eq == -1 ) 640 if ( eq == -1 )
574 return FALSE; 641 return FALSE;
575 QString key = line.left(eq).stripWhiteSpace(); 642 QString key = line.left(eq).stripWhiteSpace();
576 QString value = line.mid(eq+1).stripWhiteSpace(); 643 QString value = line.mid(eq+1).stripWhiteSpace();
577 ( *git ).insert( key, value ); 644
645 if ( git.key() == "Translation" ) {
646 if ( key == "File" ) {
647 if ( !d )
648 d = new ConfigPrivate;
649 d->trfile = value;
650 } else if ( key == "Context" ) {
651 if ( !d )
652 d = new ConfigPrivate;
653 d->trcontext = value.latin1();
654 } else if ( key.startsWith("Comment") ) {
655 return TRUE; // ignore comment for ts file
656 } else {
657 return FALSE; // Unrecognized
658 }
659 }
660
661 int kl = key.length();
662 if ( kl > 1 && key[kl-1] == ']' && key[kl-2] != '[' ) {
663 // Old-style translation (inefficient)
664 if ( !d )
665 d = new ConfigPrivate;
666 if ( !d->multilang ) {
667 QStringList l = Global::languageList();
668 lang = l[0];
669 glang = l[1];
670 d->multilang = TRUE;
671 }
672 }
673
674 ( *git ).insert( key, value );
578 } 675 }
579 return TRUE; 676 return TRUE;
580} 677}
diff --git a/library/config.h b/library/config.h
index 29ba0d6..f8d3bf7 100644
--- a/library/config.h
+++ b/library/config.h
@@ -31,6 +31,7 @@
31typedef QMap< QString, QString > ConfigGroup; 31typedef QMap< QString, QString > ConfigGroup;
32typedef QMap< QString, ConfigGroup> ConfigGroupMap; 32typedef QMap< QString, ConfigGroup> ConfigGroupMap;
33 33
34class QTextStream;
34class ConfigPrivate; 35class ConfigPrivate;
35class Config 36class Config
36{ 37{
@@ -92,8 +93,8 @@ protected:
92 void read(); 93 void read();
93 bool parse( const QString &line ); 94 bool parse( const QString &line );
94 95
95 QMap< QString, ConfigGroup > groups; 96 ConfigGroupMap groups;
96 QMap< QString, ConfigGroup >::Iterator git; 97 ConfigGroupMap::Iterator git;
97 QString filename; 98 QString filename;
98 QString lang; 99 QString lang;
99 QString glang; 100 QString glang;
@@ -103,6 +104,7 @@ protected:
103 104
104private: // Sharp ROM compatibility 105private: // Sharp ROM compatibility
105 Config( const QString &name, bool what ); 106 Config( const QString &name, bool what );
107 void read( QTextStream &s);
106}; 108};
107 109
108#endif 110#endif