summaryrefslogtreecommitdiff
authorzecke <zecke>2005-02-08 23:00:37 (UTC)
committer zecke <zecke>2005-02-08 23:00:37 (UTC)
commit80144c63f04e798b10a966402f235d236e3e540f (patch) (unidiff)
treef3d986c4f58a8730b4a30008aadf97b70ef4c9ce
parentf24d8318de30b47ec8f877293fd175deaa0b914c (diff)
downloadopie-80144c63f04e798b10a966402f235d236e3e540f.zip
opie-80144c63f04e798b10a966402f235d236e3e540f.tar.gz
opie-80144c63f04e798b10a966402f235d236e3e540f.tar.bz2
Remove the debug output of the ConfigCache
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--library/config.cpp1
1 files changed, 0 insertions, 1 deletions
diff --git a/library/config.cpp b/library/config.cpp
index e9cae4c..72bd4d2 100644
--- a/library/config.cpp
+++ b/library/config.cpp
@@ -1,1014 +1,1013 @@
1/********************************************************************** 1/**********************************************************************
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#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 <sys/time.h> 30#include <sys/time.h>
31#include <fcntl.h> 31#include <fcntl.h>
32#include <stdlib.h> 32#include <stdlib.h>
33#include <time.h> 33#include <time.h>
34#include <unistd.h> 34#include <unistd.h>
35 35
36#define QTOPIA_INTERNAL_LANGLIST 36#define QTOPIA_INTERNAL_LANGLIST
37#include "config.h" 37#include "config.h"
38#include "global.h" 38#include "global.h"
39#include "qpeapplication.h" 39#include "qpeapplication.h"
40 40
41 41
42/* 42/*
43 * Internal Class 43 * Internal Class
44 */ 44 */
45class ConfigPrivate { 45class ConfigPrivate {
46public: 46public:
47 ConfigPrivate() : multilang(FALSE) {} 47 ConfigPrivate() : multilang(FALSE) {}
48 ConfigPrivate(const ConfigPrivate& o) : 48 ConfigPrivate(const ConfigPrivate& o) :
49 trfile(o.trfile), 49 trfile(o.trfile),
50 trcontext(o.trcontext), 50 trcontext(o.trcontext),
51 multilang(o.multilang) 51 multilang(o.multilang)
52 {} 52 {}
53 ConfigPrivate& operator=(const ConfigPrivate& o) 53 ConfigPrivate& operator=(const ConfigPrivate& o)
54 { 54 {
55 trfile = o.trfile; 55 trfile = o.trfile;
56 trcontext = o.trcontext; 56 trcontext = o.trcontext;
57 multilang = o.multilang; 57 multilang = o.multilang;
58 return *this; 58 return *this;
59 } 59 }
60 60
61 QString trfile; 61 QString trfile;
62 QCString trcontext; 62 QCString trcontext;
63 bool multilang; 63 bool multilang;
64}; 64};
65 65
66///////////////////////////////////////////////////////////////// 66/////////////////////////////////////////////////////////////////
67///////////////////////////////////////////////////////////////// 67/////////////////////////////////////////////////////////////////
68 68
69#ifndef Q_OS_WIN32 69#ifndef Q_OS_WIN32
70 70
71//#define DEBUG_CONFIG_CACHE 71//#define DEBUG_CONFIG_CACHE
72class ConfigData 72class ConfigData
73{ 73{
74public: 74public:
75 ConfigData() {} 75 ConfigData() {}
76 ConfigData( const ConfigGroupMap& cf, const ConfigPrivate& pri, 76 ConfigData( const ConfigGroupMap& cf, const ConfigPrivate& pri,
77 struct stat sbuf ) 77 struct stat sbuf )
78 : cfg( cf ), priv( pri ), mtime( sbuf.st_mtime ), 78 : cfg( cf ), priv( pri ), mtime( sbuf.st_mtime ),
79 size( sbuf.st_size ) 79 size( sbuf.st_size )
80 { 80 {
81 gettimeofday(&used, 0 ); 81 gettimeofday(&used, 0 );
82 } 82 }
83 83
84 ConfigGroupMap cfg; 84 ConfigGroupMap cfg;
85 ConfigPrivate priv; // Owned by this object 85 ConfigPrivate priv; // Owned by this object
86 time_t mtime; 86 time_t mtime;
87 unsigned int size; 87 unsigned int size;
88 struct timeval used; 88 struct timeval used;
89}; 89};
90 90
91 91
92class ConfigCache : public QObject { 92class ConfigCache : public QObject {
93public: 93public:
94 static ConfigCache* instance(); 94 static ConfigCache* instance();
95 95
96 void insert( const QString& fileName, const ConfigGroupMap& cfg, 96 void insert( const QString& fileName, const ConfigGroupMap& cfg,
97 const ConfigPrivate *priv ); 97 const ConfigPrivate *priv );
98 bool find(const QString& fileName, ConfigGroupMap& cfg, 98 bool find(const QString& fileName, ConfigGroupMap& cfg,
99 ConfigPrivate** priv ); 99 ConfigPrivate** priv );
100protected: 100protected:
101 void timerEvent( QTimerEvent* ); 101 void timerEvent( QTimerEvent* );
102 102
103private: 103private:
104 ConfigCache(); 104 ConfigCache();
105 void remove( const QString& fileName ); 105 void remove( const QString& fileName );
106 void removeLru(); 106 void removeLru();
107 107
108private: 108private:
109 QMap<QString, ConfigData> m_cached; 109 QMap<QString, ConfigData> m_cached;
110 unsigned int m_totalSize; 110 unsigned int m_totalSize;
111 int m_tid; 111 int m_tid;
112private: 112private:
113 static ConfigCache* m_inst; 113 static ConfigCache* m_inst;
114 static const unsigned int CONFIG_CACHE_SIZE = 8192; 114 static const unsigned int CONFIG_CACHE_SIZE = 8192;
115 static const unsigned int CONFIG_CACHE_TIMEOUT = 1000; 115 static const unsigned int CONFIG_CACHE_TIMEOUT = 1000;
116}; 116};
117 117
118ConfigCache* ConfigCache::m_inst = 0; 118ConfigCache* ConfigCache::m_inst = 0;
119/* 119/*
120 * get destroyed when qApp gets destroyed 120 * get destroyed when qApp gets destroyed
121 */ 121 */
122ConfigCache::ConfigCache() : QObject( qApp ), m_totalSize( 0 ), m_tid( 0 ) {} 122ConfigCache::ConfigCache() : QObject( qApp ), m_totalSize( 0 ), m_tid( 0 ) {}
123ConfigCache* ConfigCache::instance() { 123ConfigCache* ConfigCache::instance() {
124 if ( !m_inst ) 124 if ( !m_inst )
125 m_inst = new ConfigCache(); 125 m_inst = new ConfigCache();
126 126
127 return m_inst; 127 return m_inst;
128} 128}
129 129
130void ConfigCache::remove( const QString& fileName ) { 130void ConfigCache::remove( const QString& fileName ) {
131 QMap<QString, ConfigData>::Iterator it = m_cached.find( fileName ); 131 QMap<QString, ConfigData>::Iterator it = m_cached.find( fileName );
132 132
133 if ( it == m_cached.end() ) 133 if ( it == m_cached.end() )
134 return; 134 return;
135 135
136 m_totalSize -= (*it).size; 136 m_totalSize -= (*it).size;
137 m_cached.remove( it ); 137 m_cached.remove( it );
138} 138}
139 139
140void ConfigCache::removeLru() { 140void ConfigCache::removeLru() {
141 QMap<QString, ConfigData>::Iterator it = m_cached.begin(); 141 QMap<QString, ConfigData>::Iterator it = m_cached.begin();
142 QMap<QString, ConfigData>::Iterator lru = it; 142 QMap<QString, ConfigData>::Iterator lru = it;
143 ++it; 143 ++it;
144 for (; it != m_cached.end(); ++it) 144 for (; it != m_cached.end(); ++it)
145 if ((*it).used.tv_sec < (*lru).used.tv_sec || 145 if ((*it).used.tv_sec < (*lru).used.tv_sec ||
146 ((*it).used.tv_sec == (*lru).used.tv_sec && 146 ((*it).used.tv_sec == (*lru).used.tv_sec &&
147 (*it).used.tv_usec < (*lru).used.tv_usec)) 147 (*it).used.tv_usec < (*lru).used.tv_usec))
148 lru = it; 148 lru = it;
149 149
150 qWarning( "Removing item" );
151 m_totalSize -= (*lru).size; 150 m_totalSize -= (*lru).size;
152 m_cached.remove(lru); 151 m_cached.remove(lru);
153} 152}
154 153
155void ConfigCache::timerEvent( QTimerEvent* ) { 154void ConfigCache::timerEvent( QTimerEvent* ) {
156 while ( m_totalSize > CONFIG_CACHE_SIZE ) 155 while ( m_totalSize > CONFIG_CACHE_SIZE )
157 removeLru(); 156 removeLru();
158 157
159 killTimer(m_tid); 158 killTimer(m_tid);
160 m_tid = 0; 159 m_tid = 0;
161} 160}
162 161
163void ConfigCache::insert( const QString& fileName, const ConfigGroupMap& cfg, 162void ConfigCache::insert( const QString& fileName, const ConfigGroupMap& cfg,
164 const ConfigPrivate* _priv ) { 163 const ConfigPrivate* _priv ) {
165 164
166 165
167 struct stat sbuf; 166 struct stat sbuf;
168 ::stat( QFile::encodeName(fileName), &sbuf ); 167 ::stat( QFile::encodeName(fileName), &sbuf );
169 if ( static_cast<unsigned int>(sbuf.st_size) >= CONFIG_CACHE_SIZE>>1) 168 if ( static_cast<unsigned int>(sbuf.st_size) >= CONFIG_CACHE_SIZE>>1)
170 return; 169 return;
171 170
172 /* 171 /*
173 * remove the old version and use the new one 172 * remove the old version and use the new one
174 */ 173 */
175 ConfigPrivate priv = _priv ? *_priv : ConfigPrivate(); 174 ConfigPrivate priv = _priv ? *_priv : ConfigPrivate();
176 ConfigData data( cfg, priv, sbuf ); 175 ConfigData data( cfg, priv, sbuf );
177 m_totalSize += data.size; 176 m_totalSize += data.size;
178 177
179 remove( fileName ); 178 remove( fileName );
180 m_cached.insert( fileName, data ); 179 m_cached.insert( fileName, data );
181 180
182 /* 181 /*
183 * we've overcommited allocation, let us clean up 182 * we've overcommited allocation, let us clean up
184 * soon 183 * soon
185 */ 184 */
186 if ( m_totalSize >= CONFIG_CACHE_SIZE ) 185 if ( m_totalSize >= CONFIG_CACHE_SIZE )
187 if ( !m_tid ) 186 if ( !m_tid )
188 m_tid = startTimer(CONFIG_CACHE_TIMEOUT); 187 m_tid = startTimer(CONFIG_CACHE_TIMEOUT);
189} 188}
190 189
191bool ConfigCache::find( const QString& fileName, ConfigGroupMap& cfg, 190bool ConfigCache::find( const QString& fileName, ConfigGroupMap& cfg,
192 ConfigPrivate **ppriv ) { 191 ConfigPrivate **ppriv ) {
193 QMap<QString, ConfigData>::Iterator it = m_cached.find(fileName); 192 QMap<QString, ConfigData>::Iterator it = m_cached.find(fileName);
194 if (it != m_cached.end()) { 193 if (it != m_cached.end()) {
195 ConfigData &data = *it; 194 ConfigData &data = *it;
196 struct stat sbuf; 195 struct stat sbuf;
197 ::stat(QFile::encodeName( fileName ), &sbuf); 196 ::stat(QFile::encodeName( fileName ), &sbuf);
198 197
199 if (data.mtime == sbuf.st_mtime && (int)data.size == sbuf.st_size) { 198 if (data.mtime == sbuf.st_mtime && (int)data.size == sbuf.st_size) {
200 cfg = data.cfg; 199 cfg = data.cfg;
201 200
202 /* 201 /*
203 * null pointer 202 * null pointer
204 */ 203 */
205 if ( *ppriv == 0 ) 204 if ( *ppriv == 0 )
206 *ppriv = new ConfigPrivate( data.priv ); 205 *ppriv = new ConfigPrivate( data.priv );
207 **ppriv = data.priv; 206 **ppriv = data.priv;
208 gettimeofday(&data.used, 0); 207 gettimeofday(&data.used, 0);
209 208
210 return true; 209 return true;
211 } 210 }
212 } 211 }
213 212
214 return false; 213 return false;
215} 214}
216 215
217#endif 216#endif
218 217
219 218
220/*! 219/*!
221 \internal 220 \internal
222*/ 221*/
223QString Config::configFilename(const QString& name, Domain d) 222QString Config::configFilename(const QString& name, Domain d)
224{ 223{
225 switch (d) { 224 switch (d) {
226 case File: 225 case File:
227 return name; 226 return name;
228 case User: { 227 case User: {
229 QDir dir = (QString(getenv("HOME")) + "/Settings"); 228 QDir dir = (QString(getenv("HOME")) + "/Settings");
230 if ( !dir.exists() ) 229 if ( !dir.exists() )
231 mkdir(dir.path().local8Bit(),0700); 230 mkdir(dir.path().local8Bit(),0700);
232 return dir.path() + "/" + name + ".conf"; 231 return dir.path() + "/" + name + ".conf";
233 } 232 }
234 } 233 }
235 return name; 234 return name;
236} 235}
237 236
238/* This cannot be made public because of binary compat issues */ 237/* This cannot be made public because of binary compat issues */
239void Config::read( QTextStream &s ) 238void Config::read( QTextStream &s )
240{ 239{
241#if QT_VERSION <= 230 && defined(QT_NO_CODECS) 240#if QT_VERSION <= 230 && defined(QT_NO_CODECS)
242 // The below should work, but doesn't in Qt 2.3.0 241 // The below should work, but doesn't in Qt 2.3.0
243 s.setCodec( QTextCodec::codecForMib( 106 ) ); 242 s.setCodec( QTextCodec::codecForMib( 106 ) );
244#else 243#else
245 s.setEncoding( QTextStream::UnicodeUTF8 ); 244 s.setEncoding( QTextStream::UnicodeUTF8 );
246#endif 245#endif
247 246
248 QStringList list = QStringList::split('\n', s.read() ); 247 QStringList list = QStringList::split('\n', s.read() );
249 248
250 for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) { 249 for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) {
251 if ( !parse( *it ) ) { 250 if ( !parse( *it ) ) {
252 git = groups.end(); 251 git = groups.end();
253 return; 252 return;
254 } 253 }
255 } 254 }
256} 255}
257 256
258/*! 257/*!
259 \class Config config.h 258 \class Config config.h
260 \brief The Config class provides for saving application cofniguration state. 259 \brief The Config class provides for saving application cofniguration state.
261 260
262 You should keep a Config in existence only while you do not want others 261 You should keep a Config in existence only while you do not want others
263 to be able to change the state. There is no locking currently, but there 262 to be able to change the state. There is no locking currently, but there
264 may be in the future. 263 may be in the future.
265*/ 264*/
266 265
267/*! 266/*!
268 \enum Config::ConfigGroup 267 \enum Config::ConfigGroup
269 \internal 268 \internal
270*/ 269*/
271 270
272/*! 271/*!
273 \enum Config::Domain 272 \enum Config::Domain
274 273
275 \value File 274 \value File
276 \value User 275 \value User
277 276
278 See Config for details. 277 See Config for details.
279*/ 278*/
280 279
281/*! 280/*!
282 Constructs a config that will load or create a configuration with the 281 Constructs a config that will load or create a configuration with the
283 given \a name in the given \a domain. 282 given \a name in the given \a domain.
284 283
285 You must call setGroup() before doing much else with the Config. 284 You must call setGroup() before doing much else with the Config.
286 285
287 In the default Domain, \e User, 286 In the default Domain, \e User,
288 the configuration is user-specific. \a name should not contain "/" in 287 the configuration is user-specific. \a name should not contain "/" in
289 this case, and in general should be the name of the C++ class that is 288 this case, and in general should be the name of the C++ class that is
290 primarily responsible for maintaining the configuration. 289 primarily responsible for maintaining the configuration.
291 290
292 In the File Domain, \a name is an absolute filename. 291 In the File Domain, \a name is an absolute filename.
293*/ 292*/
294Config::Config( const QString &name, Domain domain ) 293Config::Config( const QString &name, Domain domain )
295 : filename( configFilename(name,domain) ) 294 : filename( configFilename(name,domain) )
296{ 295{
297 git = groups.end(); 296 git = groups.end();
298 d = 0; 297 d = 0;
299 read(); 298 read();
300} 299}
301 300
302 301
303// Sharp ROM compatibility 302// Sharp ROM compatibility
304Config::Config ( const QString &name, bool what ) 303Config::Config ( const QString &name, bool what )
305 : filename( configFilename(name,what ? User : File) ) 304 : filename( configFilename(name,what ? User : File) )
306{ 305{
307 git = groups.end(); 306 git = groups.end();
308 d = 0; 307 d = 0;
309 read(); 308 read();
310} 309}
311 310
312/*! 311/*!
313 Writes any changes to disk and destroys the in-memory object. 312 Writes any changes to disk and destroys the in-memory object.
314*/ 313*/
315Config::~Config() 314Config::~Config()
316{ 315{
317 if ( changed ) 316 if ( changed )
318 write(); 317 write();
319 318
320 delete d; 319 delete d;
321} 320}
322 321
323/*! 322/*!
324 Returns whether the current group has an entry called \a key. 323 Returns whether the current group has an entry called \a key.
325*/ 324*/
326bool Config::hasKey( const QString &key ) const 325bool Config::hasKey( const QString &key ) const
327{ 326{
328 if ( groups.end() == git ) 327 if ( groups.end() == git )
329 return FALSE; 328 return FALSE;
330 ConfigGroup::ConstIterator it = ( *git ).find( key ); 329 ConfigGroup::ConstIterator it = ( *git ).find( key );
331 if ( it == ( *git ).end() ) { 330 if ( it == ( *git ).end() ) {
332 if ( d && !d->trcontext.isNull() ) { 331 if ( d && !d->trcontext.isNull() ) {
333 it = ( *git ).find( key + "[]" ); 332 it = ( *git ).find( key + "[]" );
334 } else if ( d && d->multilang ) { 333 } else if ( d && d->multilang ) {
335 it = ( *git ).find( key + "["+lang+"]" ); 334 it = ( *git ).find( key + "["+lang+"]" );
336 if ( it == ( *git ).end() && !glang.isEmpty() ) 335 if ( it == ( *git ).end() && !glang.isEmpty() )
337 it = ( *git ).find( key + "["+glang+"]" ); 336 it = ( *git ).find( key + "["+glang+"]" );
338 } 337 }
339 } 338 }
340 return it != ( *git ).end(); 339 return it != ( *git ).end();
341} 340}
342 341
343/*! 342/*!
344 Sets the current group for subsequent reading and writing of 343 Sets the current group for subsequent reading and writing of
345 entries to \a gname. Grouping allows the application to partition the namespace. 344 entries to \a gname. Grouping allows the application to partition the namespace.
346 345
347 This function must be called prior to any reading or writing 346 This function must be called prior to any reading or writing
348 of entries. 347 of entries.
349 348
350 The \a gname must not be empty. 349 The \a gname must not be empty.
351*/ 350*/
352void Config::setGroup( const QString &gname ) 351void Config::setGroup( const QString &gname )
353{ 352{
354 QMap< QString, ConfigGroup>::Iterator it = groups.find( gname ); 353 QMap< QString, ConfigGroup>::Iterator it = groups.find( gname );
355 if ( it == groups.end() ) { 354 if ( it == groups.end() ) {
356 git = groups.insert( gname, ConfigGroup() ); 355 git = groups.insert( gname, ConfigGroup() );
357 changed = TRUE; 356 changed = TRUE;
358 return; 357 return;
359 } 358 }
360 git = it; 359 git = it;
361} 360}
362 361
363/*! 362/*!
364 Writes a (\a key, \a value) entry to the current group. 363 Writes a (\a key, \a value) entry to the current group.
365 364
366 \sa readEntry() 365 \sa readEntry()
367*/ 366*/
368void Config::writeEntry( const QString &key, const char* value ) 367void Config::writeEntry( const QString &key, const char* value )
369{ 368{
370 writeEntry(key,QString(value)); 369 writeEntry(key,QString(value));
371} 370}
372 371
373/*! 372/*!
374 Writes a (\a key, \a value) entry to the current group. 373 Writes a (\a key, \a value) entry to the current group.
375 374
376 \sa readEntry() 375 \sa readEntry()
377*/ 376*/
378void Config::writeEntry( const QString &key, const QString &value ) 377void Config::writeEntry( const QString &key, const QString &value )
379{ 378{
380 if ( git == groups.end() ) { 379 if ( git == groups.end() ) {
381 qWarning( "no group set" ); 380 qWarning( "no group set" );
382 return; 381 return;
383 } 382 }
384 if ( (*git)[key] != value ) { 383 if ( (*git)[key] != value ) {
385 ( *git ).insert( key, value ); 384 ( *git ).insert( key, value );
386 changed = TRUE; 385 changed = TRUE;
387 } 386 }
388} 387}
389 388
390/* 389/*
391 Note that the degree of protection offered by the encryption here is 390 Note that the degree of protection offered by the encryption here is
392 only sufficient to avoid the most casual observation of the configuration 391 only sufficient to avoid the most casual observation of the configuration
393 files. People with access to the files can write down the contents and 392 files. People with access to the files can write down the contents and
394 decrypt it using this source code. 393 decrypt it using this source code.
395 394
396 Conceivably, and at some burden to the user, this encryption could 395 Conceivably, and at some burden to the user, this encryption could
397 be improved. 396 be improved.
398*/ 397*/
399static QString encipher(const QString& plain) 398static QString encipher(const QString& plain)
400{ 399{
401 // mainly, we make it long 400 // mainly, we make it long
402 QString cipher; 401 QString cipher;
403 int mix=28730492; 402 int mix=28730492;
404 for (int i=0; i<(int)plain.length(); i++) { 403 for (int i=0; i<(int)plain.length(); i++) {
405 int u = plain[i].unicode(); 404 int u = plain[i].unicode();
406 int c = u ^ mix; 405 int c = u ^ mix;
407 QString x = QString::number(c,36); 406 QString x = QString::number(c,36);
408 cipher.append(QChar('a'+x.length())); 407 cipher.append(QChar('a'+x.length()));
409 cipher.append(x); 408 cipher.append(x);
410 mix *= u; 409 mix *= u;
411 } 410 }
412 return cipher; 411 return cipher;
413} 412}
414 413
415static QString decipher(const QString& cipher) 414static QString decipher(const QString& cipher)
416{ 415{
417 QString plain; 416 QString plain;
418 int mix=28730492; 417 int mix=28730492;
419 for (int i=0; i<(int)cipher.length();) { 418 for (int i=0; i<(int)cipher.length();) {
420 int l = cipher[i].unicode()-'a'; 419 int l = cipher[i].unicode()-'a';
421 QString x = cipher.mid(i+1,l); i+=l+1; 420 QString x = cipher.mid(i+1,l); i+=l+1;
422 int u = x.toInt(0,36) ^ mix; 421 int u = x.toInt(0,36) ^ mix;
423 plain.append(QChar(u)); 422 plain.append(QChar(u));
424 mix *= u; 423 mix *= u;
425 } 424 }
426 return plain; 425 return plain;
427} 426}
428 427
429/*! 428/*!
430 Writes an encrypted (\a key, \a value) entry to the current group. 429 Writes an encrypted (\a key, \a value) entry to the current group.
431 430
432 Note that the degree of protection offered by the encryption is 431 Note that the degree of protection offered by the encryption is
433 only sufficient to avoid the most casual observation of the configuration 432 only sufficient to avoid the most casual observation of the configuration
434 files. 433 files.
435 434
436 \sa readEntry() 435 \sa readEntry()
437*/ 436*/
438void Config::writeEntryCrypt( const QString &key, const QString &value ) 437void Config::writeEntryCrypt( const QString &key, const QString &value )
439{ 438{
440 if ( git == groups.end() ) { 439 if ( git == groups.end() ) {
441 qWarning( "no group set" ); 440 qWarning( "no group set" );
442 return; 441 return;
443 } 442 }
444 QString evalue = encipher(value); 443 QString evalue = encipher(value);
445 if ( (*git)[key] != evalue ) { 444 if ( (*git)[key] != evalue ) {
446 ( *git ).insert( key, evalue ); 445 ( *git ).insert( key, evalue );
447 changed = TRUE; 446 changed = TRUE;
448 } 447 }
449} 448}
450 449
451/*! 450/*!
452 Writes a (\a key, \a num) entry to the current group. 451 Writes a (\a key, \a num) entry to the current group.
453 452
454 \sa readNumEntry() 453 \sa readNumEntry()
455*/ 454*/
456void Config::writeEntry( const QString &key, int num ) 455void Config::writeEntry( const QString &key, int num )
457{ 456{
458 QString s; 457 QString s;
459 s.setNum( num ); 458 s.setNum( num );
460 writeEntry( key, s ); 459 writeEntry( key, s );
461} 460}
462 461
463#ifdef Q_HAS_BOOL_TYPE 462#ifdef Q_HAS_BOOL_TYPE
464/*! 463/*!
465 Writes a (\a key, \a b) entry to the current group. This is equivalent 464 Writes a (\a key, \a b) entry to the current group. This is equivalent
466 to writing a 0 or 1 as an integer entry. 465 to writing a 0 or 1 as an integer entry.
467 466
468 \sa readBoolEntry() 467 \sa readBoolEntry()
469*/ 468*/
470void Config::writeEntry( const QString &key, bool b ) 469void Config::writeEntry( const QString &key, bool b )
471{ 470{
472 QString s; 471 QString s;
473 s.setNum( ( int )b ); 472 s.setNum( ( int )b );
474 writeEntry( key, s ); 473 writeEntry( key, s );
475} 474}
476#endif 475#endif
477 476
478/*! 477/*!
479 Writes a (\a key, \a lst) entry to the current group. The list 478 Writes a (\a key, \a lst) entry to the current group. The list
480 is separated by \a sep, so the strings must not contain that character. 479 is separated by \a sep, so the strings must not contain that character.
481 480
482 \sa readListEntry() 481 \sa readListEntry()
483*/ 482*/
484void Config::writeEntry( const QString &key, const QStringList &lst, const QChar &sep ) 483void Config::writeEntry( const QString &key, const QStringList &lst, const QChar &sep )
485{ 484{
486 QString s; 485 QString s;
487 QStringList::ConstIterator it = lst.begin(); 486 QStringList::ConstIterator it = lst.begin();
488 for ( ; it != lst.end(); ++it ) 487 for ( ; it != lst.end(); ++it )
489 s += *it + sep; 488 s += *it + sep;
490 writeEntry( key, s ); 489 writeEntry( key, s );
491} 490}
492 491
493/*! 492/*!
494 Removes the \a key entry from the current group. Does nothing if 493 Removes the \a key entry from the current group. Does nothing if
495 there is no such entry. 494 there is no such entry.
496*/ 495*/
497 496
498void Config::removeEntry( const QString &key ) 497void Config::removeEntry( const QString &key )
499{ 498{
500 if ( git == groups.end() ) { 499 if ( git == groups.end() ) {
501 qWarning( "no group set" ); 500 qWarning( "no group set" );
502 return; 501 return;
503 } 502 }
504 ( *git ).remove( key ); 503 ( *git ).remove( key );
505 changed = TRUE; 504 changed = TRUE;
506} 505}
507 506
508/*! 507/*!
509 \fn bool Config::operator == ( const Config & other ) const 508 \fn bool Config::operator == ( const Config & other ) const
510 509
511 Tests for equality with \a other. Config objects are equal if they refer to the same filename. 510 Tests for equality with \a other. Config objects are equal if they refer to the same filename.
512*/ 511*/
513 512
514/*! 513/*!
515 \fn bool Config::operator != ( const Config & other ) const 514 \fn bool Config::operator != ( const Config & other ) const
516 515
517 Tests for inequality with \a other. Config objects are equal if they refer to the same filename. 516 Tests for inequality with \a other. Config objects are equal if they refer to the same filename.
518*/ 517*/
519 518
520 519
521/*! 520/*!
522 \fn QString Config::readEntry( const QString &key, const QString &deflt ) const 521 \fn QString Config::readEntry( const QString &key, const QString &deflt ) const
523 522
524 Reads a string entry stored with \a key, defaulting to \a deflt if there is no entry. 523 Reads a string entry stored with \a key, defaulting to \a deflt if there is no entry.
525*/ 524*/
526 525
527/* 526/*
528 * ### !LocalTranslator::translate was kept out! 527 * ### !LocalTranslator::translate was kept out!
529 * 528 *
530 */ 529 */
531 530
532/*! 531/*!
533 \internal 532 \internal
534 For compatibility, non-const version. 533 For compatibility, non-const version.
535*/ 534*/
536QString Config::readEntry( const QString &key, const QString &deflt ) 535QString Config::readEntry( const QString &key, const QString &deflt )
537{ 536{
538 QString r; 537 QString r;
539 if ( d && !d->trcontext.isNull() ) { 538 if ( d && !d->trcontext.isNull() ) {
540 // Still try untranslated first, becuase: 539 // Still try untranslated first, becuase:
541 // 1. It's the common case 540 // 1. It's the common case
542 // 2. That way the value can be WRITTEN (becoming untranslated) 541 // 2. That way the value can be WRITTEN (becoming untranslated)
543 r = readEntryDirect( key ); 542 r = readEntryDirect( key );
544 if ( !r.isNull() ) 543 if ( !r.isNull() )
545 return r; 544 return r;
546 r = readEntryDirect( key + "[]" ); 545 r = readEntryDirect( key + "[]" );
547 if ( !r.isNull() ) 546 if ( !r.isNull() )
548 return qApp->translate(d->trfile,d->trcontext,r); 547 return qApp->translate(d->trfile,d->trcontext,r);
549 } else if ( d && d->multilang ) { 548 } else if ( d && d->multilang ) {
550 // For compatibilitity 549 // For compatibilitity
551 r = readEntryDirect( key + "["+lang+"]" ); 550 r = readEntryDirect( key + "["+lang+"]" );
552 if ( !r.isNull() ) 551 if ( !r.isNull() )
553 return r; 552 return r;
554 if ( !glang.isEmpty() ) { 553 if ( !glang.isEmpty() ) {
555 r = readEntryDirect( key + "["+glang+"]" ); 554 r = readEntryDirect( key + "["+glang+"]" );
556 if ( !r.isNull() ) 555 if ( !r.isNull() )
557 return r; 556 return r;
558 } 557 }
559 } 558 }
560 r = readEntryDirect( key, deflt ); 559 r = readEntryDirect( key, deflt );
561 return r; 560 return r;
562} 561}
563 562
564/*! 563/*!
565 \fn QString Config::readEntryCrypt( const QString &key, const QString &deflt ) const 564 \fn QString Config::readEntryCrypt( const QString &key, const QString &deflt ) const
566 565
567 Reads an encrypted string entry stored with \a key, defaulting to \a deflt if there is no entry. 566 Reads an encrypted string entry stored with \a key, defaulting to \a deflt if there is no entry.
568*/ 567*/
569 568
570/*! 569/*!
571 \internal 570 \internal
572 For compatibility, non-const version. 571 For compatibility, non-const version.
573*/ 572*/
574QString Config::readEntryCrypt( const QString &key, const QString &deflt ) 573QString Config::readEntryCrypt( const QString &key, const QString &deflt )
575{ 574{
576 QString res = readEntry( key ); 575 QString res = readEntry( key );
577 if ( res.isNull() ) 576 if ( res.isNull() )
578 return deflt; 577 return deflt;
579 return decipher(res); 578 return decipher(res);
580} 579}
581 580
582/*! 581/*!
583 \fn QString Config::readEntryDirect( const QString &key, const QString &deflt ) const 582 \fn QString Config::readEntryDirect( const QString &key, const QString &deflt ) const
584 \internal 583 \internal
585*/ 584*/
586 585
587/*! 586/*!
588 \internal 587 \internal
589 For compatibility, non-const version. 588 For compatibility, non-const version.
590*/ 589*/
591QString Config::readEntryDirect( const QString &key, const QString &deflt ) 590QString Config::readEntryDirect( const QString &key, const QString &deflt )
592{ 591{
593 if ( git == groups.end() ) { 592 if ( git == groups.end() ) {
594 //qWarning( "no group set" ); 593 //qWarning( "no group set" );
595 return deflt; 594 return deflt;
596 } 595 }
597 ConfigGroup::ConstIterator it = ( *git ).find( key ); 596 ConfigGroup::ConstIterator it = ( *git ).find( key );
598 if ( it != ( *git ).end() ) 597 if ( it != ( *git ).end() )
599 return *it; 598 return *it;
600 else 599 else
601 return deflt; 600 return deflt;
602} 601}
603 602
604/*! 603/*!
605 \fn int Config::readNumEntry( const QString &key, int deflt ) const 604 \fn int Config::readNumEntry( const QString &key, int deflt ) const
606 Reads a numeric entry stored with \a key, defaulting to \a deflt if there is no entry. 605 Reads a numeric entry stored with \a key, defaulting to \a deflt if there is no entry.
607*/ 606*/
608 607
609/*! 608/*!
610 \internal 609 \internal
611 For compatibility, non-const version. 610 For compatibility, non-const version.
612*/ 611*/
613int Config::readNumEntry( const QString &key, int deflt ) 612int Config::readNumEntry( const QString &key, int deflt )
614{ 613{
615 QString s = readEntry( key ); 614 QString s = readEntry( key );
616 if ( s.isEmpty() ) 615 if ( s.isEmpty() )
617 return deflt; 616 return deflt;
618 else 617 else
619 return s.toInt(); 618 return s.toInt();
620} 619}
621 620
622/*! 621/*!
623 \fn bool Config::readBoolEntry( const QString &key, bool deflt ) const 622 \fn bool Config::readBoolEntry( const QString &key, bool deflt ) const
624 Reads a bool entry stored with \a key, defaulting to \a deflt if there is no entry. 623 Reads a bool entry stored with \a key, defaulting to \a deflt if there is no entry.
625*/ 624*/
626 625
627/*! 626/*!
628 \internal 627 \internal
629 For compatibility, non-const version. 628 For compatibility, non-const version.
630*/ 629*/
631bool Config::readBoolEntry( const QString &key, bool deflt ) 630bool Config::readBoolEntry( const QString &key, bool deflt )
632{ 631{
633 QString s = readEntry( key ); 632 QString s = readEntry( key );
634 if ( s.isEmpty() ) 633 if ( s.isEmpty() )
635 return deflt; 634 return deflt;
636 else 635 else
637 return (bool)s.toInt(); 636 return (bool)s.toInt();
638} 637}
639 638
640/*! 639/*!
641 \fn QStringList Config::readListEntry( const QString &key, const QChar &sep ) const 640 \fn QStringList Config::readListEntry( const QString &key, const QChar &sep ) const
642 Reads a string list entry stored with \a key, and with \a sep as the separator. 641 Reads a string list entry stored with \a key, and with \a sep as the separator.
643*/ 642*/
644 643
645/*! 644/*!
646 \internal 645 \internal
647 For compatibility, non-const version. 646 For compatibility, non-const version.
648*/ 647*/
649QStringList Config::readListEntry( const QString &key, const QChar &sep ) 648QStringList Config::readListEntry( const QString &key, const QChar &sep )
650{ 649{
651 QString s = readEntry( key ); 650 QString s = readEntry( key );
652 if ( s.isEmpty() ) 651 if ( s.isEmpty() )
653 return QStringList(); 652 return QStringList();
654 else 653 else
655 return QStringList::split( sep, s ); 654 return QStringList::split( sep, s );
656} 655}
657 656
658/*! 657/*!
659 Removes all entries from the current group. 658 Removes all entries from the current group.
660*/ 659*/
661void Config::clearGroup() 660void Config::clearGroup()
662{ 661{
663 if ( git == groups.end() ) { 662 if ( git == groups.end() ) {
664 qWarning( "no group set" ); 663 qWarning( "no group set" );
665 return; 664 return;
666 } 665 }
667 if ( !(*git).isEmpty() ) { 666 if ( !(*git).isEmpty() ) {
668 ( *git ).clear(); 667 ( *git ).clear();
669 changed = TRUE; 668 changed = TRUE;
670 } 669 }
671} 670}
672 671
673/*! 672/*!
674 \internal 673 \internal
675*/ 674*/
676void Config::write( const QString &fn ) 675void Config::write( const QString &fn )
677{ 676{
678 QString oldGroup = git.key(); 677 QString oldGroup = git.key();
679 678
680 QString strNewFile; 679 QString strNewFile;
681 if ( !fn.isEmpty() ) 680 if ( !fn.isEmpty() )
682 filename = fn; 681 filename = fn;
683 strNewFile = filename + ".new"; 682 strNewFile = filename + ".new";
684 683
685 QFile f( strNewFile ); 684 QFile f( strNewFile );
686 if ( !f.open( IO_WriteOnly|IO_Raw ) ) { 685 if ( !f.open( IO_WriteOnly|IO_Raw ) ) {
687 qWarning( "could not open for writing `%s'", strNewFile.latin1() ); 686 qWarning( "could not open for writing `%s'", strNewFile.latin1() );
688 git = groups.end(); 687 git = groups.end();
689 return; 688 return;
690 } 689 }
691 690
692 QString str; 691 QString str;
693 QCString cstr; 692 QCString cstr;
694 QMap< QString, ConfigGroup >::Iterator g_it = groups.begin(); 693 QMap< QString, ConfigGroup >::Iterator g_it = groups.begin();
695 694
696 for ( ; g_it != groups.end(); ++g_it ) { 695 for ( ; g_it != groups.end(); ++g_it ) {
697 str += "[" + g_it.key() + "]\n"; 696 str += "[" + g_it.key() + "]\n";
698 ConfigGroup::Iterator e_it = ( *g_it ).begin(); 697 ConfigGroup::Iterator e_it = ( *g_it ).begin();
699 for ( ; e_it != ( *g_it ).end(); ++e_it ) 698 for ( ; e_it != ( *g_it ).end(); ++e_it )
700 str += e_it.key() + " = " + *e_it + "\n"; 699 str += e_it.key() + " = " + *e_it + "\n";
701 } 700 }
702 cstr = str.utf8(); 701 cstr = str.utf8();
703 702
704 int total_length; 703 int total_length;
705 total_length = f.writeBlock( cstr.data(), cstr.length() ); 704 total_length = f.writeBlock( cstr.data(), cstr.length() );
706 if ( total_length != int(cstr.length()) ) { 705 if ( total_length != int(cstr.length()) ) {
707 QMessageBox::critical( 0, QObject::tr("Out of Space"), 706 QMessageBox::critical( 0, QObject::tr("Out of Space"),
708 QObject::tr("There was a problem creating\nConfiguration Information \nfor this program.\n\nPlease free up some space and\ntry again.") ); 707 QObject::tr("There was a problem creating\nConfiguration Information \nfor this program.\n\nPlease free up some space and\ntry again.") );
709 f.close(); 708 f.close();
710 QFile::remove( strNewFile ); 709 QFile::remove( strNewFile );
711 return; 710 return;
712 } 711 }
713 712
714 f.close(); 713 f.close();
715 // now rename the file... 714 // now rename the file...
716 if ( rename( strNewFile, filename ) < 0 ) { 715 if ( rename( strNewFile, filename ) < 0 ) {
717 qWarning( "problem renaming the file %s to %s", strNewFile.latin1(), 716 qWarning( "problem renaming the file %s to %s", strNewFile.latin1(),
718 filename.latin1() ); 717 filename.latin1() );
719 QFile::remove( strNewFile ); 718 QFile::remove( strNewFile );
720 return; 719 return;
721 } 720 }
722 721
723#ifndef Q_OS_WIN32 722#ifndef Q_OS_WIN32
724 ConfigCache::instance()->insert( filename, groups, d ); 723 ConfigCache::instance()->insert( filename, groups, d );
725 setGroup( oldGroup ); 724 setGroup( oldGroup );
726#endif 725#endif
727 changed = FALSE; 726 changed = FALSE;
728} 727}
729 728
730/*! 729/*!
731 Returns whether the Config is in a valid state. 730 Returns whether the Config is in a valid state.
732*/ 731*/
733bool Config::isValid() const 732bool Config::isValid() const
734{ 733{
735 return groups.end() != git; 734 return groups.end() != git;
736} 735}
737 736
738/*! 737/*!
739 \internal 738 \internal
740*/ 739*/
741void Config::read() 740void Config::read()
742{ 741{
743 changed = FALSE; 742 changed = FALSE;
744 743
745 QString readFilename(filename); 744 QString readFilename(filename);
746 745
747 if ( !QFile::exists(filename) ) { 746 if ( !QFile::exists(filename) ) {
748 bool failed = TRUE; 747 bool failed = TRUE;
749 QFileInfo fi(filename); 748 QFileInfo fi(filename);
750 QString settingsDir = QDir::homeDirPath() + "/Settings"; 749 QString settingsDir = QDir::homeDirPath() + "/Settings";
751 if (fi.dirPath(TRUE) == settingsDir) { 750 if (fi.dirPath(TRUE) == settingsDir) {
752 // User setting - see if there is a default in $OPIEDIR/etc/default/ 751 // User setting - see if there is a default in $OPIEDIR/etc/default/
753 QString dftlFile = QPEApplication::qpeDir() + "etc/default/" + fi.fileName(); 752 QString dftlFile = QPEApplication::qpeDir() + "etc/default/" + fi.fileName();
754 if (QFile::exists(dftlFile)) { 753 if (QFile::exists(dftlFile)) {
755 readFilename = dftlFile; 754 readFilename = dftlFile;
756 failed = FALSE; 755 failed = FALSE;
757 } 756 }
758 } 757 }
759 if (failed) { 758 if (failed) {
760 git = groups.end(); 759 git = groups.end();
761 return; 760 return;
762 } 761 }
763 } 762 }
764 763
765#ifndef Q_OS_WIN32 764#ifndef Q_OS_WIN32
766 765
767 if (ConfigCache::instance()->find(readFilename, groups, &d)) { 766 if (ConfigCache::instance()->find(readFilename, groups, &d)) {
768 if ( d && d->multilang ) { 767 if ( d && d->multilang ) {
769 QStringList l = Global::languageList(); 768 QStringList l = Global::languageList();
770 lang = l[0]; 769 lang = l[0];
771 glang = l[1]; 770 glang = l[1];
772 } 771 }
773 git = groups.begin(); 772 git = groups.begin();
774 return; 773 return;
775 } 774 }
776#endif 775#endif
777 776
778 QFile f( readFilename ); 777 QFile f( readFilename );
779 if ( !f.open( IO_ReadOnly ) ) { 778 if ( !f.open( IO_ReadOnly ) ) {
780 git = groups.end(); 779 git = groups.end();
781 return; 780 return;
782 } 781 }
783 782
784 if (f.getch()!='[') { 783 if (f.getch()!='[') {
785 git = groups.end(); 784 git = groups.end();
786 return; 785 return;
787 } 786 }
788 f.ungetch('['); 787 f.ungetch('[');
789 788
790 QTextStream s( &f ); 789 QTextStream s( &f );
791 read( s ); 790 read( s );
792 f.close(); 791 f.close();
793 792
794#ifndef Q_OS_WIN32 793#ifndef Q_OS_WIN32
795 ConfigCache::instance()->insert(readFilename, groups, d); 794 ConfigCache::instance()->insert(readFilename, groups, d);
796#endif 795#endif
797} 796}
798 797
799/*! 798/*!
800 \internal 799 \internal
801*/ 800*/
802bool Config::parse( const QString &l ) 801bool Config::parse( const QString &l )
803{ 802{
804 QString line = l.stripWhiteSpace(); 803 QString line = l.stripWhiteSpace();
805 if ( line[ 0 ] == QChar( '[' ) ) { 804 if ( line[ 0 ] == QChar( '[' ) ) {
806 QString gname = line; 805 QString gname = line;
807 gname = gname.remove( 0, 1 ); 806 gname = gname.remove( 0, 1 );
808 if ( gname[ (int)gname.length() - 1 ] == QChar( ']' ) ) 807 if ( gname[ (int)gname.length() - 1 ] == QChar( ']' ) )
809 gname = gname.remove( gname.length() - 1, 1 ); 808 gname = gname.remove( gname.length() - 1, 1 );
810 git = groups.insert( gname, ConfigGroup() ); 809 git = groups.insert( gname, ConfigGroup() );
811 } else if ( !line.isEmpty() ) { 810 } else if ( !line.isEmpty() ) {
812 if ( git == groups.end() ) 811 if ( git == groups.end() )
813 return FALSE; 812 return FALSE;
814 int eq = line.find( '=' ); 813 int eq = line.find( '=' );
815 if ( eq == -1 ) 814 if ( eq == -1 )
816 return FALSE; 815 return FALSE;
817 QString key = line.left(eq).stripWhiteSpace(); 816 QString key = line.left(eq).stripWhiteSpace();
818 QString value = line.mid(eq+1).stripWhiteSpace(); 817 QString value = line.mid(eq+1).stripWhiteSpace();
819 818
820 if ( git.key() == "Translation" ) { 819 if ( git.key() == "Translation" ) {
821 if ( key == "File" ) { 820 if ( key == "File" ) {
822 if ( !d ) 821 if ( !d )
823 d = new ConfigPrivate; 822 d = new ConfigPrivate;
824 d->trfile = value; 823 d->trfile = value;
825 } else if ( key == "Context" ) { 824 } else if ( key == "Context" ) {
826 if ( !d ) 825 if ( !d )
827 d = new ConfigPrivate; 826 d = new ConfigPrivate;
828 d->trcontext = value.latin1(); 827 d->trcontext = value.latin1();
829 } else if ( key.startsWith("Comment") ) { 828 } else if ( key.startsWith("Comment") ) {
830 return TRUE; // ignore comment for ts file 829 return TRUE; // ignore comment for ts file
831 } else { 830 } else {
832 return FALSE; // Unrecognized 831 return FALSE; // Unrecognized
833 } 832 }
834 } 833 }
835 834
836 int kl = key.length(); 835 int kl = key.length();
837 if ( kl > 1 && key[kl-1] == ']' && key[kl-2] != '[' ) { 836 if ( kl > 1 && key[kl-1] == ']' && key[kl-2] != '[' ) {
838 // Old-style translation (inefficient) 837 // Old-style translation (inefficient)
839 if ( !d ) 838 if ( !d )
840 d = new ConfigPrivate; 839 d = new ConfigPrivate;
841 if ( !d->multilang ) { 840 if ( !d->multilang ) {
842 QStringList l = Global::languageList(); 841 QStringList l = Global::languageList();
843 lang = l[0]; 842 lang = l[0];
844 glang = l[1]; 843 glang = l[1];
845 d->multilang = TRUE; 844 d->multilang = TRUE;
846 } 845 }
847 } 846 }
848 847
849 ( *git ).insert( key, value ); 848 ( *git ).insert( key, value );
850 } 849 }
851 return TRUE; 850 return TRUE;
852} 851}
853 852
854 853
855 854
856bool Config::hasGroup( const QString& name )const { 855bool Config::hasGroup( const QString& name )const {
857 return ( groups. find ( name ) != groups. end ( )); 856 return ( groups. find ( name ) != groups. end ( ));
858}; 857};
859 858
860QStringList Config::groupList()const { 859QStringList Config::groupList()const {
861 QStringList sl; 860 QStringList sl;
862 for ( ConfigGroupMap::ConstIterator it = groups. begin ( ); it != groups. end ( ); ++it ) 861 for ( ConfigGroupMap::ConstIterator it = groups. begin ( ); it != groups. end ( ); ++it )
863 sl << it.key(); 862 sl << it.key();
864 863
865 return sl; 864 return sl;
866}; 865};
867 866
868///////////// 867/////////////
869// Qtopia 2.1 Functions 868// Qtopia 2.1 Functions
870// 869//
871//////////// 870////////////
872 871
873QStringList Config::allGroups()const { 872QStringList Config::allGroups()const {
874 return groupList(); 873 return groupList();
875} 874}
876 875
877/*! 876/*!
878 Returns the time stamp for the config identified by \a name. The 877 Returns the time stamp for the config identified by \a name. The
879 time stamp represents the time the config was last committed to storage. 878 time stamp represents the time the config was last committed to storage.
880 Returns 0 if there is no time stamp available for the config. 879 Returns 0 if there is no time stamp available for the config.
881 880
882 A \a domain can optionally be specified and defaults to User. 881 A \a domain can optionally be specified and defaults to User.
883 See \l{Config()} for details. 882 See \l{Config()} for details.
884 883
885 First availability: Qtopia 2.0 884 First availability: Qtopia 2.0
886*/ 885*/
887long Config::timeStamp(const QString& name, Domain domain) 886long Config::timeStamp(const QString& name, Domain domain)
888{ 887{
889#ifdef Q_WS_WIN 888#ifdef Q_WS_WIN
890 // Too slow (many conversions too and from time_t and QDataTime) 889 // Too slow (many conversions too and from time_t and QDataTime)
891 QDateTime epoch; 890 QDateTime epoch;
892 epoch.setTime_t(0); 891 epoch.setTime_t(0);
893 return epoch.secsTo(QFileInfo(Config::configFilename(name,domain)).lastModified()); 892 return epoch.secsTo(QFileInfo(Config::configFilename(name,domain)).lastModified());
894#else 893#else
895 QString fn = Config::configFilename(name,domain); 894 QString fn = Config::configFilename(name,domain);
896 struct stat b; 895 struct stat b;
897 if (lstat( QFile::encodeName(fn).data(), &b ) == 0) 896 if (lstat( QFile::encodeName(fn).data(), &b ) == 0)
898 return b.st_mtime; 897 return b.st_mtime;
899 else 898 else
900 return 0; 899 return 0;
901#endif 900#endif
902} 901}
903 902
904 903
905/*! 904/*!
906 Removes the current group (and all its entries). 905 Removes the current group (and all its entries).
907 906
908 The current group becomes unset. 907 The current group becomes unset.
909 908
910 First availability: Qtopia 2.0 909 First availability: Qtopia 2.0
911*/ 910*/
912void Config::removeGroup() 911void Config::removeGroup()
913{ 912{
914 if ( git == groups.end() ) { 913 if ( git == groups.end() ) {
915 qWarning( "no group set" ); 914 qWarning( "no group set" );
916 return; 915 return;
917 } 916 }
918 917
919 groups.remove(git.key()); 918 groups.remove(git.key());
920 git = groups.end(); 919 git = groups.end();
921 changed = TRUE; 920 changed = TRUE;
922} 921}
923 922
924/*! 923/*!
925 Removes the current group (and all its entries). 924 Removes the current group (and all its entries).
926 925
927 The current group becomes unset. 926 The current group becomes unset.
928 927
929 First availability: Qtopia 2.0 928 First availability: Qtopia 2.0
930*/ 929*/
931void Config::removeGroup(const QString& g) 930void Config::removeGroup(const QString& g)
932{ 931{
933 groups.remove(g); 932 groups.remove(g);
934 git = groups.end(); 933 git = groups.end();
935} 934}
936 935
937 936
938 937
939/*! 938/*!
940 Writes a (\a key, \a lst) entry to the current group. 939 Writes a (\a key, \a lst) entry to the current group.
941 940
942 The list is 941 The list is
943 separated by the two characters "^e", and "^" withing the strings 942 separated by the two characters "^e", and "^" withing the strings
944 is replaced by "^^", such that the strings may contain any character, 943 is replaced by "^^", such that the strings may contain any character,
945 including "^". 944 including "^".
946 945
947 Null strings are also allowed, and are recorded as "^0" in the string. 946 Null strings are also allowed, and are recorded as "^0" in the string.
948 947
949 First availability: Qtopia 2.0 948 First availability: Qtopia 2.0
950 949
951 \sa readListEntry() 950 \sa readListEntry()
952*/ 951*/
953void Config::writeEntry( const QString &key, const QStringList &lst ) 952void Config::writeEntry( const QString &key, const QStringList &lst )
954{ 953{
955 QString s; 954 QString s;
956 for (QStringList::ConstIterator it=lst.begin(); it!=lst.end(); ++it) { 955 for (QStringList::ConstIterator it=lst.begin(); it!=lst.end(); ++it) {
957 QString el = *it; 956 QString el = *it;
958 if ( el.isNull() ) { 957 if ( el.isNull() ) {
959 el = "^0"; 958 el = "^0";
960 } else { 959 } else {
961 el.replace(QRegExp("\\^"), "^^"); 960 el.replace(QRegExp("\\^"), "^^");
962 } 961 }
963 s+=el; 962 s+=el;
964 s+="^e"; // end of element 963 s+="^e"; // end of element
965 } 964 }
966 writeEntry(key, s); 965 writeEntry(key, s);
967} 966}
968 967
969/*! 968/*!
970 Returns the string list entry stored using \a key and with 969 Returns the string list entry stored using \a key and with
971 the escaped seperator convention described in writeListEntry(). 970 the escaped seperator convention described in writeListEntry().
972 971
973 First availability: Qtopia 2.0 972 First availability: Qtopia 2.0
974*/ 973*/
975QStringList Config::readListEntry( const QString &key ) const 974QStringList Config::readListEntry( const QString &key ) const
976{ 975{
977 QString value = readEntry( key, QString::null ); 976 QString value = readEntry( key, QString::null );
978 QStringList l; 977 QStringList l;
979 QString s; 978 QString s;
980 bool esc=FALSE; 979 bool esc=FALSE;
981 for (int i=0; i<(int)value.length(); i++) { 980 for (int i=0; i<(int)value.length(); i++) {
982 if ( esc ) { 981 if ( esc ) {
983 if ( value[i] == 'e' ) { // end-of-string 982 if ( value[i] == 'e' ) { // end-of-string
984 l.append(s); 983 l.append(s);
985 s=""; 984 s="";
986 } else if ( value[i] == '0' ) { // null string 985 } else if ( value[i] == '0' ) { // null string
987 s=QString::null; 986 s=QString::null;
988 } else { 987 } else {
989 s.append(value[i]); 988 s.append(value[i]);
990 } 989 }
991 esc = FALSE; 990 esc = FALSE;
992 } else if ( value[i] == '^' ) { 991 } else if ( value[i] == '^' ) {
993 esc = TRUE; 992 esc = TRUE;
994 } else { 993 } else {
995 s.append(value[i]); 994 s.append(value[i]);
996 if ( i == (int)value.length()-1 ) 995 if ( i == (int)value.length()-1 )
997 l.append(s); 996 l.append(s);
998 } 997 }
999 } 998 }
1000 return l; 999 return l;
1001} 1000}
1002 1001
1003QString Config::readEntry( const QString &key, const QString &deflt ) const 1002QString Config::readEntry( const QString &key, const QString &deflt ) const
1004{ return ((Config*)this)->readEntry(key,deflt); } 1003{ return ((Config*)this)->readEntry(key,deflt); }
1005QString Config::readEntryCrypt( const QString &key, const QString &deflt ) const 1004QString Config::readEntryCrypt( const QString &key, const QString &deflt ) const
1006{ return ((Config*)this)->readEntryCrypt(key,deflt); } 1005{ return ((Config*)this)->readEntryCrypt(key,deflt); }
1007QString Config::readEntryDirect( const QString &key, const QString &deflt ) const 1006QString Config::readEntryDirect( const QString &key, const QString &deflt ) const
1008{ return ((Config*)this)->readEntryDirect(key,deflt); } 1007{ return ((Config*)this)->readEntryDirect(key,deflt); }
1009int Config::readNumEntry( const QString &key, int deflt ) const 1008int Config::readNumEntry( const QString &key, int deflt ) const
1010{ return ((Config*)this)->readNumEntry(key,deflt); } 1009{ return ((Config*)this)->readNumEntry(key,deflt); }
1011bool Config::readBoolEntry( const QString &key, bool deflt ) const 1010bool Config::readBoolEntry( const QString &key, bool deflt ) const
1012{ return ((Config*)this)->readBoolEntry(key,deflt); } 1011{ return ((Config*)this)->readBoolEntry(key,deflt); }
1013QStringList Config::readListEntry( const QString &key, const QChar &sep ) const 1012QStringList Config::readListEntry( const QString &key, const QChar &sep ) const
1014{ return ((Config*)this)->readListEntry(key,sep); } 1013{ return ((Config*)this)->readListEntry(key,sep); }