summaryrefslogtreecommitdiff
path: root/library/config.cpp
authorsandman <sandman>2002-11-26 23:34:04 (UTC)
committer sandman <sandman>2002-11-26 23:34:04 (UTC)
commite52158d2f9e1fdc9766d991dc672729648d5a020 (patch) (unidiff)
tree2e87e8d9a24cdb336b2d7ca654a5ffa2f80c5f8c /library/config.cpp
parentac4f32931212847803534a72eb5e951bd01e6ff5 (diff)
downloadopie-e52158d2f9e1fdc9766d991dc672729648d5a020.zip
opie-e52158d2f9e1fdc9766d991dc672729648d5a020.tar.gz
opie-e52158d2f9e1fdc9766d991dc672729648d5a020.tar.bz2
Sharp ROM compatibilty upgrade:
All these functions are needed to get qtmail (from the Sharp ROM) running on Opie - I have even tested qtmail on an iPAQ and it seems to work ..
Diffstat (limited to 'library/config.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--library/config.cpp12
1 files changed, 12 insertions, 0 deletions
diff --git a/library/config.cpp b/library/config.cpp
index 1121cd4..b47c620 100644
--- a/library/config.cpp
+++ b/library/config.cpp
@@ -1,558 +1,570 @@
1/********************************************************************** 1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved. 2** Copyright (C) 2000 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 <qfile.h> 22#include <qfile.h>
23#include <qfileinfo.h> 23#include <qfileinfo.h>
24#include <qmessagebox.h> 24#include <qmessagebox.h>
25#if QT_VERSION <= 230 && defined(QT_NO_CODECS) 25#if QT_VERSION <= 230 && defined(QT_NO_CODECS)
26#include <qtextcodec.h> 26#include <qtextcodec.h>
27#endif 27#endif
28#include <qtextstream.h> 28#include <qtextstream.h>
29 29
30#include <sys/stat.h> 30#include <sys/stat.h>
31#include <sys/types.h> 31#include <sys/types.h>
32#include <fcntl.h> 32#include <fcntl.h>
33#include <stdlib.h> 33#include <stdlib.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 39
40 40
41/*! 41/*!
42 \internal 42 \internal
43*/ 43*/
44QString Config::configFilename(const QString& name, Domain d) 44QString Config::configFilename(const QString& name, Domain d)
45{ 45{
46 switch (d) { 46 switch (d) {
47 case File: 47 case File:
48 return name; 48 return name;
49 case User: { 49 case User: {
50 QDir dir = (QString(getenv("HOME")) + "/Settings"); 50 QDir dir = (QString(getenv("HOME")) + "/Settings");
51 if ( !dir.exists() ) 51 if ( !dir.exists() )
52 mkdir(dir.path().local8Bit(),0700); 52 mkdir(dir.path().local8Bit(),0700);
53 return dir.path() + "/" + name + ".conf"; 53 return dir.path() + "/" + name + ".conf";
54 } 54 }
55 } 55 }
56 return name; 56 return name;
57} 57}
58 58
59/*! 59/*!
60 \class Config config.h 60 \class Config config.h
61 \brief The Config class provides for saving application cofniguration state. 61 \brief The Config class provides for saving application cofniguration state.
62 62
63 You should keep a Config in existence only while you do not want others 63 You should keep a Config in existence only while you do not want others
64 to be able to change the state. There is no locking currently, but there 64 to be able to change the state. There is no locking currently, but there
65 may be in the future. 65 may be in the future.
66*/ 66*/
67 67
68/*! 68/*!
69 \enum Config::ConfigGroup 69 \enum Config::ConfigGroup
70 \internal 70 \internal
71*/ 71*/
72 72
73/*! 73/*!
74 \enum Config::Domain 74 \enum Config::Domain
75 75
76 \value File 76 \value File
77 \value User 77 \value User
78 78
79 See Config for details. 79 See Config for details.
80*/ 80*/
81 81
82/*! 82/*!
83 Constructs a config that will load or create a configuration with the 83 Constructs a config that will load or create a configuration with the
84 given \a name in the given \a domain. 84 given \a name in the given \a domain.
85 85
86 You must call setGroup() before doing much else with the Config. 86 You must call setGroup() before doing much else with the Config.
87 87
88 In the default Domain, \e User, 88 In the default Domain, \e User,
89 the configuration is user-specific. \a name should not contain "/" in 89 the configuration is user-specific. \a name should not contain "/" in
90 this case, and in general should be the name of the C++ class that is 90 this case, and in general should be the name of the C++ class that is
91 primarily responsible for maintaining the configuration. 91 primarily responsible for maintaining the configuration.
92 92
93 In the File Domain, \a name is an absolute filename. 93 In the File Domain, \a name is an absolute filename.
94*/ 94*/
95Config::Config( const QString &name, Domain domain ) 95Config::Config( const QString &name, Domain domain )
96 : filename( configFilename(name,domain) ) 96 : filename( configFilename(name,domain) )
97{ 97{
98 git = groups.end(); 98 git = groups.end();
99 read(); 99 read();
100 QStringList l = Global::languageList(); 100 QStringList l = Global::languageList();
101 lang = l[0]; 101 lang = l[0];
102 glang = l[1]; 102 glang = l[1];
103} 103}
104 104
105
106// Sharp ROM compatibility
107Config::Config ( const QString &name, bool what )
108 : filename( configFilename(name,what ? User : File) )
109{
110 git = groups.end();
111 read();
112 QStringList l = Global::languageList();
113 lang = l[0];
114 glang = l[1];
115}
116
105/*! 117/*!
106 Writes any changes to disk and destroys the in-memory object. 118 Writes any changes to disk and destroys the in-memory object.
107*/ 119*/
108Config::~Config() 120Config::~Config()
109{ 121{
110 if ( changed ) 122 if ( changed )
111 write(); 123 write();
112} 124}
113 125
114/*! 126/*!
115 Returns whether the current group has an entry called \a key. 127 Returns whether the current group has an entry called \a key.
116*/ 128*/
117bool Config::hasKey( const QString &key ) const 129bool Config::hasKey( const QString &key ) const
118{ 130{
119 if ( groups.end() == git ) 131 if ( groups.end() == git )
120 return FALSE; 132 return FALSE;
121 ConfigGroup::ConstIterator it = ( *git ).find( key ); 133 ConfigGroup::ConstIterator it = ( *git ).find( key );
122 return it != ( *git ).end(); 134 return it != ( *git ).end();
123} 135}
124 136
125/*! 137/*!
126 Sets the current group for subsequent reading and writing of 138 Sets the current group for subsequent reading and writing of
127 entries to \a gname. Grouping allows the application to partition the namespace. 139 entries to \a gname. Grouping allows the application to partition the namespace.
128 140
129 This function must be called prior to any reading or writing 141 This function must be called prior to any reading or writing
130 of entries. 142 of entries.
131 143
132 The \a gname must not be empty. 144 The \a gname must not be empty.
133*/ 145*/
134void Config::setGroup( const QString &gname ) 146void Config::setGroup( const QString &gname )
135{ 147{
136 QMap< QString, ConfigGroup>::Iterator it = groups.find( gname ); 148 QMap< QString, ConfigGroup>::Iterator it = groups.find( gname );
137 if ( it == groups.end() ) { 149 if ( it == groups.end() ) {
138 git = groups.insert( gname, ConfigGroup() ); 150 git = groups.insert( gname, ConfigGroup() );
139 changed = TRUE; 151 changed = TRUE;
140 return; 152 return;
141 } 153 }
142 git = it; 154 git = it;
143} 155}
144 156
145/*! 157/*!
146 Writes a (\a key, \a value) entry to the current group. 158 Writes a (\a key, \a value) entry to the current group.
147 159
148 \sa readEntry() 160 \sa readEntry()
149*/ 161*/
150void Config::writeEntry( const QString &key, const char* value ) 162void Config::writeEntry( const QString &key, const char* value )
151{ 163{
152 writeEntry(key,QString(value)); 164 writeEntry(key,QString(value));
153} 165}
154 166
155/*! 167/*!
156 Writes a (\a key, \a value) entry to the current group. 168 Writes a (\a key, \a value) entry to the current group.
157 169
158 \sa readEntry() 170 \sa readEntry()
159*/ 171*/
160void Config::writeEntry( const QString &key, const QString &value ) 172void Config::writeEntry( const QString &key, const QString &value )
161{ 173{
162 if ( git == groups.end() ) { 174 if ( git == groups.end() ) {
163 qWarning( "no group set" ); 175 qWarning( "no group set" );
164 return; 176 return;
165 } 177 }
166 if ( (*git)[key] != value ) { 178 if ( (*git)[key] != value ) {
167 ( *git ).insert( key, value ); 179 ( *git ).insert( key, value );
168 changed = TRUE; 180 changed = TRUE;
169 } 181 }
170} 182}
171 183
172/* 184/*
173 Note that the degree of protection offered by the encryption here is 185 Note that the degree of protection offered by the encryption here is
174 only sufficient to avoid the most casual observation of the configuration 186 only sufficient to avoid the most casual observation of the configuration
175 files. People with access to the files can write down the contents and 187 files. People with access to the files can write down the contents and
176 decrypt it using this source code. 188 decrypt it using this source code.
177 189
178 Conceivably, and at some burden to the user, this encryption could 190 Conceivably, and at some burden to the user, this encryption could
179 be improved. 191 be improved.
180*/ 192*/
181static QString encipher(const QString& plain) 193static QString encipher(const QString& plain)
182{ 194{
183 // mainly, we make it long 195 // mainly, we make it long
184 QString cipher; 196 QString cipher;
185 int mix=28730492; 197 int mix=28730492;
186 for (int i=0; i<(int)plain.length(); i++) { 198 for (int i=0; i<(int)plain.length(); i++) {
187 int u = plain[i].unicode(); 199 int u = plain[i].unicode();
188 int c = u ^ mix; 200 int c = u ^ mix;
189 QString x = QString::number(c,36); 201 QString x = QString::number(c,36);
190 cipher.append(QChar('a'+x.length())); 202 cipher.append(QChar('a'+x.length()));
191 cipher.append(x); 203 cipher.append(x);
192 mix *= u; 204 mix *= u;
193 } 205 }
194 return cipher; 206 return cipher;
195} 207}
196 208
197static QString decipher(const QString& cipher) 209static QString decipher(const QString& cipher)
198{ 210{
199 QString plain; 211 QString plain;
200 int mix=28730492; 212 int mix=28730492;
201 for (int i=0; i<(int)cipher.length();) { 213 for (int i=0; i<(int)cipher.length();) {
202 int l = cipher[i].unicode()-'a'; 214 int l = cipher[i].unicode()-'a';
203 QString x = cipher.mid(i+1,l); i+=l+1; 215 QString x = cipher.mid(i+1,l); i+=l+1;
204 int u = x.toInt(0,36) ^ mix; 216 int u = x.toInt(0,36) ^ mix;
205 plain.append(QChar(u)); 217 plain.append(QChar(u));
206 mix *= u; 218 mix *= u;
207 } 219 }
208 return plain; 220 return plain;
209} 221}
210 222
211/*! 223/*!
212 Writes an encrypted (\a key, \a value) entry to the current group. 224 Writes an encrypted (\a key, \a value) entry to the current group.
213 225
214 Note that the degree of protection offered by the encryption is 226 Note that the degree of protection offered by the encryption is
215 only sufficient to avoid the most casual observation of the configuration 227 only sufficient to avoid the most casual observation of the configuration
216 files. 228 files.
217 229
218 \sa readEntry() 230 \sa readEntry()
219*/ 231*/
220void Config::writeEntryCrypt( const QString &key, const QString &value ) 232void Config::writeEntryCrypt( const QString &key, const QString &value )
221{ 233{
222 if ( git == groups.end() ) { 234 if ( git == groups.end() ) {
223 qWarning( "no group set" ); 235 qWarning( "no group set" );
224 return; 236 return;
225 } 237 }
226 QString evalue = encipher(value); 238 QString evalue = encipher(value);
227 if ( (*git)[key] != evalue ) { 239 if ( (*git)[key] != evalue ) {
228 ( *git ).insert( key, evalue ); 240 ( *git ).insert( key, evalue );
229 changed = TRUE; 241 changed = TRUE;
230 } 242 }
231} 243}
232 244
233/*! 245/*!
234 Writes a (\a key, \a num) entry to the current group. 246 Writes a (\a key, \a num) entry to the current group.
235 247
236 \sa readNumEntry() 248 \sa readNumEntry()
237*/ 249*/
238void Config::writeEntry( const QString &key, int num ) 250void Config::writeEntry( const QString &key, int num )
239{ 251{
240 QString s; 252 QString s;
241 s.setNum( num ); 253 s.setNum( num );
242 writeEntry( key, s ); 254 writeEntry( key, s );
243} 255}
244 256
245#ifdef Q_HAS_BOOL_TYPE 257#ifdef Q_HAS_BOOL_TYPE
246/*! 258/*!
247 Writes a (\a key, \a b) entry to the current group. This is equivalent 259 Writes a (\a key, \a b) entry to the current group. This is equivalent
248 to writing a 0 or 1 as an integer entry. 260 to writing a 0 or 1 as an integer entry.
249 261
250 \sa readBoolEntry() 262 \sa readBoolEntry()
251*/ 263*/
252void Config::writeEntry( const QString &key, bool b ) 264void Config::writeEntry( const QString &key, bool b )
253{ 265{
254 QString s; 266 QString s;
255 s.setNum( ( int )b ); 267 s.setNum( ( int )b );
256 writeEntry( key, s ); 268 writeEntry( key, s );
257} 269}
258#endif 270#endif
259 271
260/*! 272/*!
261 Writes a (\a key, \a lst) entry to the current group. The list 273 Writes a (\a key, \a lst) entry to the current group. The list
262 is separated by \a sep, so the strings must not contain that character. 274 is separated by \a sep, so the strings must not contain that character.
263 275
264 \sa readListEntry() 276 \sa readListEntry()
265*/ 277*/
266void Config::writeEntry( const QString &key, const QStringList &lst, const QChar &sep ) 278void Config::writeEntry( const QString &key, const QStringList &lst, const QChar &sep )
267{ 279{
268 QString s; 280 QString s;
269 QStringList::ConstIterator it = lst.begin(); 281 QStringList::ConstIterator it = lst.begin();
270 for ( ; it != lst.end(); ++it ) 282 for ( ; it != lst.end(); ++it )
271 s += *it + sep; 283 s += *it + sep;
272 writeEntry( key, s ); 284 writeEntry( key, s );
273} 285}
274 286
275/*! 287/*!
276 Removes the \a key entry from the current group. Does nothing if 288 Removes the \a key entry from the current group. Does nothing if
277 there is no such entry. 289 there is no such entry.
278*/ 290*/
279 291
280void Config::removeEntry( const QString &key ) 292void Config::removeEntry( const QString &key )
281{ 293{
282 if ( git == groups.end() ) { 294 if ( git == groups.end() ) {
283 qWarning( "no group set" ); 295 qWarning( "no group set" );
284 return; 296 return;
285 } 297 }
286 ( *git ).remove( key ); 298 ( *git ).remove( key );
287 changed = TRUE; 299 changed = TRUE;
288} 300}
289 301
290/*! 302/*!
291 \fn bool Config::operator == ( const Config & other ) const 303 \fn bool Config::operator == ( const Config & other ) const
292 304
293 Tests for equality with \a other. Config objects are equal if they refer to the same filename. 305 Tests for equality with \a other. Config objects are equal if they refer to the same filename.
294*/ 306*/
295 307
296/*! 308/*!
297 \fn bool Config::operator != ( const Config & other ) const 309 \fn bool Config::operator != ( const Config & other ) const
298 310
299 Tests for inequality with \a other. Config objects are equal if they refer to the same filename. 311 Tests for inequality with \a other. Config objects are equal if they refer to the same filename.
300*/ 312*/
301 313
302/*! 314/*!
303 \fn QString Config::readEntry( const QString &key, const QString &deflt ) const 315 \fn QString Config::readEntry( const QString &key, const QString &deflt ) const
304 316
305 Reads a string entry stored with \a key, defaulting to \a deflt if there is no entry. 317 Reads a string entry stored with \a key, defaulting to \a deflt if there is no entry.
306*/ 318*/
307 319
308/*! 320/*!
309 \internal 321 \internal
310 For compatibility, non-const version. 322 For compatibility, non-const version.
311*/ 323*/
312QString Config::readEntry( const QString &key, const QString &deflt ) 324QString Config::readEntry( const QString &key, const QString &deflt )
313{ 325{
314 QString res = readEntryDirect( key+"["+lang+"]" ); 326 QString res = readEntryDirect( key+"["+lang+"]" );
315 if ( !res.isNull() ) 327 if ( !res.isNull() )
316 return res; 328 return res;
317 if ( !glang.isEmpty() ) { 329 if ( !glang.isEmpty() ) {
318 res = readEntryDirect( key+"["+glang+"]" ); 330 res = readEntryDirect( key+"["+glang+"]" );
319 if ( !res.isNull() ) 331 if ( !res.isNull() )
320 return res; 332 return res;
321 } 333 }
322 return readEntryDirect( key, deflt ); 334 return readEntryDirect( key, deflt );
323} 335}
324 336
325/*! 337/*!
326 \fn QString Config::readEntryCrypt( const QString &key, const QString &deflt ) const 338 \fn QString Config::readEntryCrypt( const QString &key, const QString &deflt ) const
327 339
328 Reads an encrypted string entry stored with \a key, defaulting to \a deflt if there is no entry. 340 Reads an encrypted string entry stored with \a key, defaulting to \a deflt if there is no entry.
329*/ 341*/
330 342
331/*! 343/*!
332 \internal 344 \internal
333 For compatibility, non-const version. 345 For compatibility, non-const version.
334*/ 346*/
335QString Config::readEntryCrypt( const QString &key, const QString &deflt ) 347QString Config::readEntryCrypt( const QString &key, const QString &deflt )
336{ 348{
337 QString res = readEntryDirect( key+"["+lang+"]" ); 349 QString res = readEntryDirect( key+"["+lang+"]" );
338 if ( res.isNull() && glang.isEmpty() ) 350 if ( res.isNull() && glang.isEmpty() )
339 res = readEntryDirect( key+"["+glang+"]" ); 351 res = readEntryDirect( key+"["+glang+"]" );
340 if ( res.isNull() ) 352 if ( res.isNull() )
341 res = readEntryDirect( key, QString::null ); 353 res = readEntryDirect( key, QString::null );
342 if ( res.isNull() ) 354 if ( res.isNull() )
343 return deflt; 355 return deflt;
344 return decipher(res); 356 return decipher(res);
345} 357}
346 358
347/*! 359/*!
348 \fn QString Config::readEntryDirect( const QString &key, const QString &deflt ) const 360 \fn QString Config::readEntryDirect( const QString &key, const QString &deflt ) const
349 \internal 361 \internal
350*/ 362*/
351 363
352/*! 364/*!
353 \internal 365 \internal
354 For compatibility, non-const version. 366 For compatibility, non-const version.
355*/ 367*/
356QString Config::readEntryDirect( const QString &key, const QString &deflt ) 368QString Config::readEntryDirect( const QString &key, const QString &deflt )
357{ 369{
358 if ( git == groups.end() ) { 370 if ( git == groups.end() ) {
359 //qWarning( "no group set" ); 371 //qWarning( "no group set" );
360 return deflt; 372 return deflt;
361 } 373 }
362 ConfigGroup::ConstIterator it = ( *git ).find( key ); 374 ConfigGroup::ConstIterator it = ( *git ).find( key );
363 if ( it != ( *git ).end() ) 375 if ( it != ( *git ).end() )
364 return *it; 376 return *it;
365 else 377 else
366 return deflt; 378 return deflt;
367} 379}
368 380
369/*! 381/*!
370 \fn int Config::readNumEntry( const QString &key, int deflt ) const 382 \fn int Config::readNumEntry( const QString &key, int deflt ) const
371 Reads a numeric entry stored with \a key, defaulting to \a deflt if there is no entry. 383 Reads a numeric entry stored with \a key, defaulting to \a deflt if there is no entry.
372*/ 384*/
373 385
374/*! 386/*!
375 \internal 387 \internal
376 For compatibility, non-const version. 388 For compatibility, non-const version.
377*/ 389*/
378int Config::readNumEntry( const QString &key, int deflt ) 390int Config::readNumEntry( const QString &key, int deflt )
379{ 391{
380 QString s = readEntry( key ); 392 QString s = readEntry( key );
381 if ( s.isEmpty() ) 393 if ( s.isEmpty() )
382 return deflt; 394 return deflt;
383 else 395 else
384 return s.toInt(); 396 return s.toInt();
385} 397}
386 398
387/*! 399/*!
388 \fn bool Config::readBoolEntry( const QString &key, bool deflt ) const 400 \fn bool Config::readBoolEntry( const QString &key, bool deflt ) const
389 Reads a bool entry stored with \a key, defaulting to \a deflt if there is no entry. 401 Reads a bool entry stored with \a key, defaulting to \a deflt if there is no entry.
390*/ 402*/
391 403
392/*! 404/*!
393 \internal 405 \internal
394 For compatibility, non-const version. 406 For compatibility, non-const version.
395*/ 407*/
396bool Config::readBoolEntry( const QString &key, bool deflt ) 408bool Config::readBoolEntry( const QString &key, bool deflt )
397{ 409{
398 QString s = readEntry( key ); 410 QString s = readEntry( key );
399 if ( s.isEmpty() ) 411 if ( s.isEmpty() )
400 return deflt; 412 return deflt;
401 else 413 else
402 return (bool)s.toInt(); 414 return (bool)s.toInt();
403} 415}
404 416
405/*! 417/*!
406 \fn QStringList Config::readListEntry( const QString &key, const QChar &sep ) const 418 \fn QStringList Config::readListEntry( const QString &key, const QChar &sep ) const
407 Reads a string list entry stored with \a key, and with \a sep as the separator. 419 Reads a string list entry stored with \a key, and with \a sep as the separator.
408*/ 420*/
409 421
410/*! 422/*!
411 \internal 423 \internal
412 For compatibility, non-const version. 424 For compatibility, non-const version.
413*/ 425*/
414QStringList Config::readListEntry( const QString &key, const QChar &sep ) 426QStringList Config::readListEntry( const QString &key, const QChar &sep )
415{ 427{
416 QString s = readEntry( key ); 428 QString s = readEntry( key );
417 if ( s.isEmpty() ) 429 if ( s.isEmpty() )
418 return QStringList(); 430 return QStringList();
419 else 431 else
420 return QStringList::split( sep, s ); 432 return QStringList::split( sep, s );
421} 433}
422 434
423/*! 435/*!
424 Removes all entries from the current group. 436 Removes all entries from the current group.
425*/ 437*/
426void Config::clearGroup() 438void Config::clearGroup()
427{ 439{
428 if ( git == groups.end() ) { 440 if ( git == groups.end() ) {
429 qWarning( "no group set" ); 441 qWarning( "no group set" );
430 return; 442 return;
431 } 443 }
432 if ( !(*git).isEmpty() ) { 444 if ( !(*git).isEmpty() ) {
433 ( *git ).clear(); 445 ( *git ).clear();
434 changed = TRUE; 446 changed = TRUE;
435 } 447 }
436} 448}
437 449
438/*! 450/*!
439 \internal 451 \internal
440*/ 452*/
441void Config::write( const QString &fn ) 453void Config::write( const QString &fn )
442{ 454{
443 QString strNewFile; 455 QString strNewFile;
444 if ( !fn.isEmpty() ) 456 if ( !fn.isEmpty() )
445 filename = fn; 457 filename = fn;
446 strNewFile = filename + ".new"; 458 strNewFile = filename + ".new";
447 459
448 QFile f( strNewFile ); 460 QFile f( strNewFile );
449 if ( !f.open( IO_WriteOnly|IO_Raw ) ) { 461 if ( !f.open( IO_WriteOnly|IO_Raw ) ) {
450 qWarning( "could not open for writing `%s'", strNewFile.latin1() ); 462 qWarning( "could not open for writing `%s'", strNewFile.latin1() );
451 git = groups.end(); 463 git = groups.end();
452 return; 464 return;
453 } 465 }
454 466
455 QString str; 467 QString str;
456 QCString cstr; 468 QCString cstr;
457 QMap< QString, ConfigGroup >::Iterator g_it = groups.begin(); 469 QMap< QString, ConfigGroup >::Iterator g_it = groups.begin();
458 470
459 for ( ; g_it != groups.end(); ++g_it ) { 471 for ( ; g_it != groups.end(); ++g_it ) {
460 str += "[" + g_it.key() + "]\n"; 472 str += "[" + g_it.key() + "]\n";
461 ConfigGroup::Iterator e_it = ( *g_it ).begin(); 473 ConfigGroup::Iterator e_it = ( *g_it ).begin();
462 for ( ; e_it != ( *g_it ).end(); ++e_it ) 474 for ( ; e_it != ( *g_it ).end(); ++e_it )
463 str += e_it.key() + " = " + *e_it + "\n"; 475 str += e_it.key() + " = " + *e_it + "\n";
464 } 476 }
465 cstr = str.utf8(); 477 cstr = str.utf8();
466 478
467 int total_length; 479 int total_length;
468 total_length = f.writeBlock( cstr.data(), cstr.length() ); 480 total_length = f.writeBlock( cstr.data(), cstr.length() );
469 if ( total_length != int(cstr.length()) ) { 481 if ( total_length != int(cstr.length()) ) {
470 QMessageBox::critical( 0, QObject::tr("Out of Space"), 482 QMessageBox::critical( 0, QObject::tr("Out of Space"),
471 QObject::tr("There was a problem creating\nConfiguration Information \nfor this program.\n\nPlease free up some space and\ntry again.") ); 483 QObject::tr("There was a problem creating\nConfiguration Information \nfor this program.\n\nPlease free up some space and\ntry again.") );
472 f.close(); 484 f.close();
473 QFile::remove( strNewFile ); 485 QFile::remove( strNewFile );
474 return; 486 return;
475 } 487 }
476 488
477 f.close(); 489 f.close();
478 // now rename the file... 490 // now rename the file...
479 if ( rename( strNewFile, filename ) < 0 ) { 491 if ( rename( strNewFile, filename ) < 0 ) {
480 qWarning( "problem renaming the file %s to %s", strNewFile.latin1(), 492 qWarning( "problem renaming the file %s to %s", strNewFile.latin1(),
481 filename.latin1() ); 493 filename.latin1() );
482 QFile::remove( strNewFile ); 494 QFile::remove( strNewFile );
483 } 495 }
484} 496}
485 497
486/*! 498/*!
487 Returns whether the Config is in a valid state. 499 Returns whether the Config is in a valid state.
488*/ 500*/
489bool Config::isValid() const 501bool Config::isValid() const
490{ 502{
491 return groups.end() != git; 503 return groups.end() != git;
492} 504}
493 505
494/*! 506/*!
495 \internal 507 \internal
496*/ 508*/
497void Config::read() 509void Config::read()
498{ 510{
499 changed = FALSE; 511 changed = FALSE;
500 512
501 if ( !QFileInfo( filename ).exists() ) { 513 if ( !QFileInfo( filename ).exists() ) {
502 git = groups.end(); 514 git = groups.end();
503 return; 515 return;
504 } 516 }
505 517
506 QFile f( filename ); 518 QFile f( filename );
507 if ( !f.open( IO_ReadOnly ) ) { 519 if ( !f.open( IO_ReadOnly ) ) {
508 git = groups.end(); 520 git = groups.end();
509 return; 521 return;
510 } 522 }
511 523
512 QTextStream s( &f ); 524 QTextStream s( &f );
513#if QT_VERSION <= 230 && defined(QT_NO_CODECS) 525#if QT_VERSION <= 230 && defined(QT_NO_CODECS)
514 // The below should work, but doesn't in Qt 2.3.0 526 // The below should work, but doesn't in Qt 2.3.0
515 s.setCodec( QTextCodec::codecForMib( 106 ) ); 527 s.setCodec( QTextCodec::codecForMib( 106 ) );
516#else 528#else
517 s.setEncoding( QTextStream::UnicodeUTF8 ); 529 s.setEncoding( QTextStream::UnicodeUTF8 );
518#endif 530#endif
519 531
520 QStringList list = QStringList::split('\n', s.read() ); 532 QStringList list = QStringList::split('\n', s.read() );
521 f.close(); 533 f.close();
522 534
523 for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) { 535 for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) {
524 if ( !parse( *it ) ) { 536 if ( !parse( *it ) ) {
525 git = groups.end(); 537 git = groups.end();
526 return; 538 return;
527 } 539 }
528 } 540 }
529} 541}
530 542
531/*! 543/*!
532 \internal 544 \internal
533*/ 545*/
534bool Config::parse( const QString &l ) 546bool Config::parse( const QString &l )
535{ 547{
536 QString line = l.stripWhiteSpace(); 548 QString line = l.stripWhiteSpace();
537 549
538 if ( line [0] == QChar ( '#' )) 550 if ( line [0] == QChar ( '#' ))
539 return true; // ignore comments 551 return true; // ignore comments
540 552
541 if ( line[ 0 ] == QChar( '[' ) ) { 553 if ( line[ 0 ] == QChar( '[' ) ) {
542 QString gname = line; 554 QString gname = line;
543 gname = gname.remove( 0, 1 ); 555 gname = gname.remove( 0, 1 );
544 if ( gname[ (int)gname.length() - 1 ] == QChar( ']' ) ) 556 if ( gname[ (int)gname.length() - 1 ] == QChar( ']' ) )
545 gname = gname.remove( gname.length() - 1, 1 ); 557 gname = gname.remove( gname.length() - 1, 1 );
546 git = groups.insert( gname, ConfigGroup() ); 558 git = groups.insert( gname, ConfigGroup() );
547 } else if ( !line.isEmpty() ) { 559 } else if ( !line.isEmpty() ) {
548 if ( git == groups.end() ) 560 if ( git == groups.end() )
549 return FALSE; 561 return FALSE;
550 int eq = line.find( '=' ); 562 int eq = line.find( '=' );
551 if ( eq == -1 ) 563 if ( eq == -1 )
552 return FALSE; 564 return FALSE;
553 QString key = line.left(eq).stripWhiteSpace(); 565 QString key = line.left(eq).stripWhiteSpace();
554 QString value = line.mid(eq+1).stripWhiteSpace(); 566 QString value = line.mid(eq+1).stripWhiteSpace();
555 ( *git ).insert( key, value ); 567 ( *git ).insert( key, value );
556 } 568 }
557 return TRUE; 569 return TRUE;
558} 570}