summaryrefslogtreecommitdiff
path: root/library
Unidiff
Diffstat (limited to 'library') (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
@@ -5,159 +5,214 @@
5** 5**
6** This file may be distributed and/or modified under the terms of the 6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software 7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the 8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file. 9** packaging of this file.
10** 10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13** 13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information. 14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15** 15**
16** Contact info@trolltech.com if any conditions of this licensing are 16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you. 17** not clear to you.
18** 18**
19**********************************************************************/ 19**********************************************************************/
20 20
21#include <qdir.h> 21#include <qdir.h>
22#include <qmessagebox.h> 22#include <qmessagebox.h>
23#if QT_VERSION <= 230 && defined(QT_NO_CODECS) 23#if QT_VERSION <= 230 && defined(QT_NO_CODECS)
24#include <qtextcodec.h> 24#include <qtextcodec.h>
25#endif 25#endif
26#include <qtextstream.h> 26#include <qtextstream.h>
27 27
28#include <sys/stat.h> 28#include <sys/stat.h>
29#include <sys/types.h> 29#include <sys/types.h>
30#include <fcntl.h> 30#include <fcntl.h>
31#include <stdlib.h> 31#include <stdlib.h>
32#include <unistd.h> 32#include <unistd.h>
33 33
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*/
42QString Config::configFilename(const QString& name, Domain d) 70QString Config::configFilename(const QString& name, Domain d)
43{ 71{
44 switch (d) { 72 switch (d) {
45 case File: 73 case File:
46 return name; 74 return name;
47 case User: { 75 case User: {
48 QDir dir = (QString(getenv("HOME")) + "/Settings"); 76 QDir dir = (QString(getenv("HOME")) + "/Settings");
49 if ( !dir.exists() ) 77 if ( !dir.exists() )
50 mkdir(dir.path().local8Bit(),0700); 78 mkdir(dir.path().local8Bit(),0700);
51 return dir.path() + "/" + name + ".conf"; 79 return dir.path() + "/" + name + ".conf";
52 } 80 }
53 } 81 }
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.
60 108
61 You should keep a Config in existence only while you do not want others 109 You should keep a Config in existence only while you do not want others
62 to be able to change the state. There is no locking currently, but there 110 to be able to change the state. There is no locking currently, but there
63 may be in the future. 111 may be in the future.
64*/ 112*/
65 113
66/*! 114/*!
67 \enum Config::ConfigGroup 115 \enum Config::ConfigGroup
68 \internal 116 \internal
69*/ 117*/
70 118
71/*! 119/*!
72 \enum Config::Domain 120 \enum Config::Domain
73 121
74 \value File 122 \value File
75 \value User 123 \value User
76 124
77 See Config for details. 125 See Config for details.
78*/ 126*/
79 127
80/*! 128/*!
81 Constructs a config that will load or create a configuration with the 129 Constructs a config that will load or create a configuration with the
82 given \a name in the given \a domain. 130 given \a name in the given \a domain.
83 131
84 You must call setGroup() before doing much else with the Config. 132 You must call setGroup() before doing much else with the Config.
85 133
86 In the default Domain, \e User, 134 In the default Domain, \e User,
87 the configuration is user-specific. \a name should not contain "/" in 135 the configuration is user-specific. \a name should not contain "/" in
88 this case, and in general should be the name of the C++ class that is 136 this case, and in general should be the name of the C++ class that is
89 primarily responsible for maintaining the configuration. 137 primarily responsible for maintaining the configuration.
90 138
91 In the File Domain, \a name is an absolute filename. 139 In the File Domain, \a name is an absolute filename.
92*/ 140*/
93Config::Config( const QString &name, Domain domain ) 141Config::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
104// Sharp ROM compatibility 150// Sharp ROM compatibility
105Config::Config ( const QString &name, bool what ) 151Config::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/*!
116 Writes any changes to disk and destroys the in-memory object. 160 Writes any changes to disk and destroys the in-memory object.
117*/ 161*/
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/*!
125 Returns whether the current group has an entry called \a key. 171 Returns whether the current group has an entry called \a key.
126*/ 172*/
127bool Config::hasKey( const QString &key ) const 173bool Config::hasKey( const QString &key ) const
128{ 174{
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
135/*! 190/*!
136 Sets the current group for subsequent reading and writing of 191 Sets the current group for subsequent reading and writing of
137 entries to \a gname. Grouping allows the application to partition the namespace. 192 entries to \a gname. Grouping allows the application to partition the namespace.
138 193
139 This function must be called prior to any reading or writing 194 This function must be called prior to any reading or writing
140 of entries. 195 of entries.
141 196
142 The \a gname must not be empty. 197 The \a gname must not be empty.
143*/ 198*/
144void Config::setGroup( const QString &gname ) 199void Config::setGroup( const QString &gname )
145{ 200{
146 QMap< QString, ConfigGroup>::Iterator it = groups.find( gname ); 201 QMap< QString, ConfigGroup>::Iterator it = groups.find( gname );
147 if ( it == groups.end() ) { 202 if ( it == groups.end() ) {
148 git = groups.insert( gname, ConfigGroup() ); 203 git = groups.insert( gname, ConfigGroup() );
149 changed = TRUE; 204 changed = TRUE;
150 return; 205 return;
151 } 206 }
152 git = it; 207 git = it;
153} 208}
154 209
155/*! 210/*!
156 Writes a (\a key, \a value) entry to the current group. 211 Writes a (\a key, \a value) entry to the current group.
157 212
158 \sa readEntry() 213 \sa readEntry()
159*/ 214*/
160void Config::writeEntry( const QString &key, const char* value ) 215void Config::writeEntry( const QString &key, const char* value )
161{ 216{
162 writeEntry(key,QString(value)); 217 writeEntry(key,QString(value));
163} 218}
@@ -280,106 +335,123 @@ void Config::writeEntry( const QString &key, const QStringList &lst, const QChar
280 for ( ; it != lst.end(); ++it ) 335 for ( ; it != lst.end(); ++it )
281 s += *it + sep; 336 s += *it + sep;
282 writeEntry( key, s ); 337 writeEntry( key, s );
283} 338}
284 339
285/*! 340/*!
286 Removes the \a key entry from the current group. Does nothing if 341 Removes the \a key entry from the current group. Does nothing if
287 there is no such entry. 342 there is no such entry.
288*/ 343*/
289 344
290void Config::removeEntry( const QString &key ) 345void Config::removeEntry( const QString &key )
291{ 346{
292 if ( git == groups.end() ) { 347 if ( git == groups.end() ) {
293 qWarning( "no group set" ); 348 qWarning( "no group set" );
294 return; 349 return;
295 } 350 }
296 ( *git ).remove( key ); 351 ( *git ).remove( key );
297 changed = TRUE; 352 changed = TRUE;
298} 353}
299 354
300/*! 355/*!
301 \fn bool Config::operator == ( const Config & other ) const 356 \fn bool Config::operator == ( const Config & other ) const
302 357
303 Tests for equality with \a other. Config objects are equal if they refer to the same filename. 358 Tests for equality with \a other. Config objects are equal if they refer to the same filename.
304*/ 359*/
305 360
306/*! 361/*!
307 \fn bool Config::operator != ( const Config & other ) const 362 \fn bool Config::operator != ( const Config & other ) const
308 363
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/*!
336 \fn QString Config::readEntryCrypt( const QString &key, const QString &deflt ) const 412 \fn QString Config::readEntryCrypt( const QString &key, const QString &deflt ) const
337 413
338 Reads an encrypted string entry stored with \a key, defaulting to \a deflt if there is no entry. 414 Reads an encrypted string entry stored with \a key, defaulting to \a deflt if there is no entry.
339*/ 415*/
340 416
341/*! 417/*!
342 \internal 418 \internal
343 For compatibility, non-const version. 419 For compatibility, non-const version.
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
357/*! 429/*!
358 \fn QString Config::readEntryDirect( const QString &key, const QString &deflt ) const 430 \fn QString Config::readEntryDirect( const QString &key, const QString &deflt ) const
359 \internal 431 \internal
360*/ 432*/
361 433
362/*! 434/*!
363 \internal 435 \internal
364 For compatibility, non-const version. 436 For compatibility, non-const version.
365*/ 437*/
366QString Config::readEntryDirect( const QString &key, const QString &deflt ) 438QString Config::readEntryDirect( const QString &key, const QString &deflt )
367{ 439{
368 if ( git == groups.end() ) { 440 if ( git == groups.end() ) {
369 //qWarning( "no group set" ); 441 //qWarning( "no group set" );
370 return deflt; 442 return deflt;
371 } 443 }
372 ConfigGroup::ConstIterator it = ( *git ).find( key ); 444 ConfigGroup::ConstIterator it = ( *git ).find( key );
373 if ( it != ( *git ).end() ) 445 if ( it != ( *git ).end() )
374 return *it; 446 return *it;
375 else 447 else
376 return deflt; 448 return deflt;
377} 449}
378 450
379/*! 451/*!
380 \fn int Config::readNumEntry( const QString &key, int deflt ) const 452 \fn int Config::readNumEntry( const QString &key, int deflt ) const
381 Reads a numeric entry stored with \a key, defaulting to \a deflt if there is no entry. 453 Reads a numeric entry stored with \a key, defaulting to \a deflt if there is no entry.
382*/ 454*/
383 455
384/*! 456/*!
385 \internal 457 \internal
@@ -460,150 +532,175 @@ void Config::write( const QString &fn )
460 qWarning( "could not open for writing `%s'", strNewFile.latin1() ); 532 qWarning( "could not open for writing `%s'", strNewFile.latin1() );
461 git = groups.end(); 533 git = groups.end();
462 return; 534 return;
463 } 535 }
464 536
465 QString str; 537 QString str;
466 QCString cstr; 538 QCString cstr;
467 QMap< QString, ConfigGroup >::Iterator g_it = groups.begin(); 539 QMap< QString, ConfigGroup >::Iterator g_it = groups.begin();
468 540
469 for ( ; g_it != groups.end(); ++g_it ) { 541 for ( ; g_it != groups.end(); ++g_it ) {
470 str += "[" + g_it.key() + "]\n"; 542 str += "[" + g_it.key() + "]\n";
471 ConfigGroup::Iterator e_it = ( *g_it ).begin(); 543 ConfigGroup::Iterator e_it = ( *g_it ).begin();
472 for ( ; e_it != ( *g_it ).end(); ++e_it ) 544 for ( ; e_it != ( *g_it ).end(); ++e_it )
473 str += e_it.key() + " = " + *e_it + "\n"; 545 str += e_it.key() + " = " + *e_it + "\n";
474 } 546 }
475 cstr = str.utf8(); 547 cstr = str.utf8();
476 548
477 int total_length; 549 int total_length;
478 total_length = f.writeBlock( cstr.data(), cstr.length() ); 550 total_length = f.writeBlock( cstr.data(), cstr.length() );
479 if ( total_length != int(cstr.length()) ) { 551 if ( total_length != int(cstr.length()) ) {
480 QMessageBox::critical( 0, QObject::tr("Out of Space"), 552 QMessageBox::critical( 0, QObject::tr("Out of Space"),
481 QObject::tr("There was a problem creating\nConfiguration Information \nfor this program.\n\nPlease free up some space and\ntry again.") ); 553 QObject::tr("There was a problem creating\nConfiguration Information \nfor this program.\n\nPlease free up some space and\ntry again.") );
482 f.close(); 554 f.close();
483 QFile::remove( strNewFile ); 555 QFile::remove( strNewFile );
484 return; 556 return;
485 } 557 }
486 558
487 f.close(); 559 f.close();
488 // now rename the file... 560 // now rename the file...
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/*!
497 Returns whether the Config is in a valid state. 572 Returns whether the Config is in a valid state.
498*/ 573*/
499bool Config::isValid() const 574bool Config::isValid() const
500{ 575{
501 return groups.end() != git; 576 return groups.end() != git;
502} 577}
503 578
504/*! 579/*!
505 \internal 580 \internal
506*/ 581*/
507void Config::read() 582void 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/*!
554 \internal 625 \internal
555*/ 626*/
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}
581 678
582 679
583 680
584bool Config::hasGroup( const QString& name )const { 681bool Config::hasGroup( const QString& name )const {
585 return ( groups. find ( name ) != groups. end ( )); 682 return ( groups. find ( name ) != groups. end ( ));
586}; 683};
587 684
588QStringList Config::groupList()const { 685QStringList Config::groupList()const {
589 QStringList sl; 686 QStringList sl;
590 for ( ConfigGroupMap::ConstIterator it = groups. begin ( ); it != groups. end ( ); ++it ) 687 for ( ConfigGroupMap::ConstIterator it = groups. begin ( ); it != groups. end ( ); ++it )
591 sl << it.key(); 688 sl << it.key();
592 689
593 return sl; 690 return sl;
594}; 691};
595 692
596///////////// 693/////////////
597// Qtopia 2.1 Functions 694// Qtopia 2.1 Functions
598// 695//
599//////////// 696////////////
600 697
601QStringList Config::allGroups()const { 698QStringList Config::allGroups()const {
602 return groupList(); 699 return groupList();
603} 700}
604 701
605/*! 702/*!
606 Returns the time stamp for the config identified by \a name. The 703 Returns the time stamp for the config identified by \a name. The
607 time stamp represents the time the config was last committed to storage. 704 time stamp represents the time the config was last committed to storage.
608 Returns 0 if there is no time stamp available for the config. 705 Returns 0 if there is no time stamp available for the config.
609 706
diff --git a/library/config.h b/library/config.h
index 29ba0d6..f8d3bf7 100644
--- a/library/config.h
+++ b/library/config.h
@@ -2,107 +2,109 @@
2** Copyright (C) 2000, 2004 Trolltech AS. All rights reserved. 2** Copyright (C) 2000, 2004 Trolltech AS. All rights reserved.
3** 3**
4** This file is part of Qtopia Environment. 4** This file is part of Qtopia Environment.
5** 5**
6** This file may be distributed and/or modified under the terms of the 6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software 7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the 8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file. 9** packaging of this file.
10** 10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13** 13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information. 14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15** 15**
16** Contact info@trolltech.com if any conditions of this licensing are 16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you. 17** not clear to you.
18** 18**
19**********************************************************************/ 19**********************************************************************/
20 20
21#ifndef CONFIG_H 21#ifndef CONFIG_H
22#define CONFIG_H 22#define CONFIG_H
23 23
24// ##### could use QSettings with Qt 3.0 24// ##### could use QSettings with Qt 3.0
25 25
26#include <qpe/qpeglobal.h> 26#include <qpe/qpeglobal.h>
27 27
28#include <qmap.h> 28#include <qmap.h>
29#include <qstringlist.h> 29#include <qstringlist.h>
30 30
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{
37public: 38public:
38 39
39 enum Domain { File, User }; 40 enum Domain { File, User };
40 Config( const QString &name, Domain domain=User ); 41 Config( const QString &name, Domain domain=User );
41 ~Config(); 42 ~Config();
42 43
43 QTOPIA_MERGED_METHOD(static long timeStamp( const QString &name, Domain domain=User ), "2.1"); 44 QTOPIA_MERGED_METHOD(static long timeStamp( const QString &name, Domain domain=User ), "2.1");
44 45
45 bool operator == ( const Config & other ) const { return (filename == other.filename); } 46 bool operator == ( const Config & other ) const { return (filename == other.filename); }
46 bool operator != ( const Config & other ) const { return (filename != other.filename); } 47 bool operator != ( const Config & other ) const { return (filename != other.filename); }
47 48
48 bool isValid() const; 49 bool isValid() const;
49 bool hasKey( const QString &key ) const; 50 bool hasKey( const QString &key ) const;
50 51
51 // inline for better SharpROM BC 52 // inline for better SharpROM BC
52 NOT_IN_QPE(bool hasGroup ( const QString &gname ) const); 53 NOT_IN_QPE(bool hasGroup ( const QString &gname ) const);
53 NOT_IN_QPE(QStringList groupList ( ) const); 54 NOT_IN_QPE(QStringList groupList ( ) const);
54 55
55 void setGroup( const QString &gname ); 56 void setGroup( const QString &gname );
56 void writeEntry( const QString &key, const char* value ); 57 void writeEntry( const QString &key, const char* value );
57 void writeEntry( const QString &key, const QString &value ); 58 void writeEntry( const QString &key, const QString &value );
58 void writeEntryCrypt( const QString &key, const QString &value ); 59 void writeEntryCrypt( const QString &key, const QString &value );
59 void writeEntry( const QString &key, int num ); 60 void writeEntry( const QString &key, int num );
60#ifdef Q_HAS_BOOL_TYPE 61#ifdef Q_HAS_BOOL_TYPE
61 void writeEntry( const QString &key, bool b ); 62 void writeEntry( const QString &key, bool b );
62#endif 63#endif
63 void writeEntry( const QString &key, const QStringList &lst, const QChar &sep ); 64 void writeEntry( const QString &key, const QStringList &lst, const QChar &sep );
64 QTOPIA_MERGED_METHOD(void writeEntry( const QString &key, const QStringList &lst ), "2.1.0"); 65 QTOPIA_MERGED_METHOD(void writeEntry( const QString &key, const QStringList &lst ), "2.1.0");
65 66
66 void removeEntry( const QString &key ); 67 void removeEntry( const QString &key );
67 68
68 QString readEntry( const QString &key, const QString &deflt = QString::null ) const; 69 QString readEntry( const QString &key, const QString &deflt = QString::null ) const;
69 QString readEntryCrypt( const QString &key, const QString &deflt = QString::null ) const; 70 QString readEntryCrypt( const QString &key, const QString &deflt = QString::null ) const;
70 QString readEntryDirect( const QString &key, const QString &deflt = QString::null ) const; 71 QString readEntryDirect( const QString &key, const QString &deflt = QString::null ) const;
71 int readNumEntry( const QString &key, int deflt = -1 ) const; 72 int readNumEntry( const QString &key, int deflt = -1 ) const;
72 bool readBoolEntry( const QString &key, bool deflt = FALSE ) const; 73 bool readBoolEntry( const QString &key, bool deflt = FALSE ) const;
73 QStringList readListEntry( const QString &key, const QChar &sep ) const; 74 QStringList readListEntry( const QString &key, const QChar &sep ) const;
74 QTOPIA_MERGED_METHOD(QStringList readListEntry( const QString &key ) const, "2.1.0"); 75 QTOPIA_MERGED_METHOD(QStringList readListEntry( const QString &key ) const, "2.1.0");
75 76
76 // For compatibility, non-const versions. 77 // For compatibility, non-const versions.
77 QString readEntry( const QString &key, const QString &deflt ); 78 QString readEntry( const QString &key, const QString &deflt );
78 QString readEntryCrypt( const QString &key, const QString &deflt ); 79 QString readEntryCrypt( const QString &key, const QString &deflt );
79 QString readEntryDirect( const QString &key, const QString &deflt ); 80 QString readEntryDirect( const QString &key, const QString &deflt );
80 int readNumEntry( const QString &key, int deflt ); 81 int readNumEntry( const QString &key, int deflt );
81 bool readBoolEntry( const QString &key, bool deflt ); 82 bool readBoolEntry( const QString &key, bool deflt );
82 QStringList readListEntry( const QString &key, const QChar &sep ); 83 QStringList readListEntry( const QString &key, const QChar &sep );
83 84
84 void clearGroup(); 85 void clearGroup();
85 QTOPIA_MERGED_METHOD(void removeGroup(), "2.1.0"); 86 QTOPIA_MERGED_METHOD(void removeGroup(), "2.1.0");
86 QTOPIA_MERGED_METHOD(void removeGroup(const QString&), "2.1.0"); 87 QTOPIA_MERGED_METHOD(void removeGroup(const QString&), "2.1.0");
87 QTOPIA_MERGED_METHOD(QStringList allGroups() const, "2.1.0"); 88 QTOPIA_MERGED_METHOD(QStringList allGroups() const, "2.1.0");
88 89
89 void write( const QString &fn = QString::null ); 90 void write( const QString &fn = QString::null );
90 91
91protected: 92protected:
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;
100 bool changed; 101 bool changed;
101 ConfigPrivate *d; 102 ConfigPrivate *d;
102 static QString configFilename(const QString& name, Domain); 103 static QString configFilename(const QString& name, Domain);
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