summaryrefslogtreecommitdiff
path: root/library/config.cpp
Unidiff
Diffstat (limited to 'library/config.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--library/config.cpp2
1 files changed, 0 insertions, 2 deletions
diff --git a/library/config.cpp b/library/config.cpp
index b28c771..8b60f60 100644
--- a/library/config.cpp
+++ b/library/config.cpp
@@ -1,407 +1,405 @@
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>
23#include <qfileinfo.h>
24#include <qmessagebox.h> 22#include <qmessagebox.h>
25#if QT_VERSION <= 230 && defined(QT_NO_CODECS) 23#if QT_VERSION <= 230 && defined(QT_NO_CODECS)
26#include <qtextcodec.h> 24#include <qtextcodec.h>
27#endif 25#endif
28#include <qtextstream.h> 26#include <qtextstream.h>
29 27
30#include <sys/stat.h> 28#include <sys/stat.h>
31#include <sys/types.h> 29#include <sys/types.h>
32#include <fcntl.h> 30#include <fcntl.h>
33#include <stdlib.h> 31#include <stdlib.h>
34#include <unistd.h> 32#include <unistd.h>
35 33
36#define QTOPIA_INTERNAL_LANGLIST 34#define QTOPIA_INTERNAL_LANGLIST
37#include "config.h" 35#include "config.h"
38#include "global.h" 36#include "global.h"
39 37
40 38
41/*! 39/*!
42 \internal 40 \internal
43*/ 41*/
44QString Config::configFilename(const QString& name, Domain d) 42QString Config::configFilename(const QString& name, Domain d)
45{ 43{
46 switch (d) { 44 switch (d) {
47 case File: 45 case File:
48 return name; 46 return name;
49 case User: { 47 case User: {
50 QDir dir = (QString(getenv("HOME")) + "/Settings"); 48 QDir dir = (QString(getenv("HOME")) + "/Settings");
51 if ( !dir.exists() ) 49 if ( !dir.exists() )
52 mkdir(dir.path().local8Bit(),0700); 50 mkdir(dir.path().local8Bit(),0700);
53 return dir.path() + "/" + name + ".conf"; 51 return dir.path() + "/" + name + ".conf";
54 } 52 }
55 } 53 }
56 return name; 54 return name;
57} 55}
58 56
59/*! 57/*!
60 \class Config config.h 58 \class Config config.h
61 \brief The Config class provides for saving application cofniguration state. 59 \brief The Config class provides for saving application cofniguration state.
62 60
63 You should keep a Config in existence only while you do not want others 61 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 62 to be able to change the state. There is no locking currently, but there
65 may be in the future. 63 may be in the future.
66*/ 64*/
67 65
68/*! 66/*!
69 \enum Config::ConfigGroup 67 \enum Config::ConfigGroup
70 \internal 68 \internal
71*/ 69*/
72 70
73/*! 71/*!
74 \enum Config::Domain 72 \enum Config::Domain
75 73
76 \value File 74 \value File
77 \value User 75 \value User
78 76
79 See Config for details. 77 See Config for details.
80*/ 78*/
81 79
82/*! 80/*!
83 Constructs a config that will load or create a configuration with the 81 Constructs a config that will load or create a configuration with the
84 given \a name in the given \a domain. 82 given \a name in the given \a domain.
85 83
86 You must call setGroup() before doing much else with the Config. 84 You must call setGroup() before doing much else with the Config.
87 85
88 In the default Domain, \e User, 86 In the default Domain, \e User,
89 the configuration is user-specific. \a name should not contain "/" in 87 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 88 this case, and in general should be the name of the C++ class that is
91 primarily responsible for maintaining the configuration. 89 primarily responsible for maintaining the configuration.
92 90
93 In the File Domain, \a name is an absolute filename. 91 In the File Domain, \a name is an absolute filename.
94*/ 92*/
95Config::Config( const QString &name, Domain domain ) 93Config::Config( const QString &name, Domain domain )
96 : filename( configFilename(name,domain) ) 94 : filename( configFilename(name,domain) )
97{ 95{
98 git = groups.end(); 96 git = groups.end();
99 read(); 97 read();
100 QStringList l = Global::languageList(); 98 QStringList l = Global::languageList();
101 lang = l[0]; 99 lang = l[0];
102 glang = l[1]; 100 glang = l[1];
103} 101}
104 102
105 103
106// Sharp ROM compatibility 104// Sharp ROM compatibility
107Config::Config ( const QString &name, bool what ) 105Config::Config ( const QString &name, bool what )
108 : filename( configFilename(name,what ? User : File) ) 106 : filename( configFilename(name,what ? User : File) )
109{ 107{
110 git = groups.end(); 108 git = groups.end();
111 read(); 109 read();
112 QStringList l = Global::languageList(); 110 QStringList l = Global::languageList();
113 lang = l[0]; 111 lang = l[0];
114 glang = l[1]; 112 glang = l[1];
115} 113}
116 114
117/*! 115/*!
118 Writes any changes to disk and destroys the in-memory object. 116 Writes any changes to disk and destroys the in-memory object.
119*/ 117*/
120Config::~Config() 118Config::~Config()
121{ 119{
122 if ( changed ) 120 if ( changed )
123 write(); 121 write();
124} 122}
125 123
126/*! 124/*!
127 Returns whether the current group has an entry called \a key. 125 Returns whether the current group has an entry called \a key.
128*/ 126*/
129bool Config::hasKey( const QString &key ) const 127bool Config::hasKey( const QString &key ) const
130{ 128{
131 if ( groups.end() == git ) 129 if ( groups.end() == git )
132 return FALSE; 130 return FALSE;
133 ConfigGroup::ConstIterator it = ( *git ).find( key ); 131 ConfigGroup::ConstIterator it = ( *git ).find( key );
134 return it != ( *git ).end(); 132 return it != ( *git ).end();
135} 133}
136 134
137/*! 135/*!
138 Sets the current group for subsequent reading and writing of 136 Sets the current group for subsequent reading and writing of
139 entries to \a gname. Grouping allows the application to partition the namespace. 137 entries to \a gname. Grouping allows the application to partition the namespace.
140 138
141 This function must be called prior to any reading or writing 139 This function must be called prior to any reading or writing
142 of entries. 140 of entries.
143 141
144 The \a gname must not be empty. 142 The \a gname must not be empty.
145*/ 143*/
146void Config::setGroup( const QString &gname ) 144void Config::setGroup( const QString &gname )
147{ 145{
148 QMap< QString, ConfigGroup>::Iterator it = groups.find( gname ); 146 QMap< QString, ConfigGroup>::Iterator it = groups.find( gname );
149 if ( it == groups.end() ) { 147 if ( it == groups.end() ) {
150 git = groups.insert( gname, ConfigGroup() ); 148 git = groups.insert( gname, ConfigGroup() );
151 changed = TRUE; 149 changed = TRUE;
152 return; 150 return;
153 } 151 }
154 git = it; 152 git = it;
155} 153}
156 154
157/*! 155/*!
158 Writes a (\a key, \a value) entry to the current group. 156 Writes a (\a key, \a value) entry to the current group.
159 157
160 \sa readEntry() 158 \sa readEntry()
161*/ 159*/
162void Config::writeEntry( const QString &key, const char* value ) 160void Config::writeEntry( const QString &key, const char* value )
163{ 161{
164 writeEntry(key,QString(value)); 162 writeEntry(key,QString(value));
165} 163}
166 164
167/*! 165/*!
168 Writes a (\a key, \a value) entry to the current group. 166 Writes a (\a key, \a value) entry to the current group.
169 167
170 \sa readEntry() 168 \sa readEntry()
171*/ 169*/
172void Config::writeEntry( const QString &key, const QString &value ) 170void Config::writeEntry( const QString &key, const QString &value )
173{ 171{
174 if ( git == groups.end() ) { 172 if ( git == groups.end() ) {
175 qWarning( "no group set" ); 173 qWarning( "no group set" );
176 return; 174 return;
177 } 175 }
178 if ( (*git)[key] != value ) { 176 if ( (*git)[key] != value ) {
179 ( *git ).insert( key, value ); 177 ( *git ).insert( key, value );
180 changed = TRUE; 178 changed = TRUE;
181 } 179 }
182} 180}
183 181
184/* 182/*
185 Note that the degree of protection offered by the encryption here is 183 Note that the degree of protection offered by the encryption here is
186 only sufficient to avoid the most casual observation of the configuration 184 only sufficient to avoid the most casual observation of the configuration
187 files. People with access to the files can write down the contents and 185 files. People with access to the files can write down the contents and
188 decrypt it using this source code. 186 decrypt it using this source code.
189 187
190 Conceivably, and at some burden to the user, this encryption could 188 Conceivably, and at some burden to the user, this encryption could
191 be improved. 189 be improved.
192*/ 190*/
193static QString encipher(const QString& plain) 191static QString encipher(const QString& plain)
194{ 192{
195 // mainly, we make it long 193 // mainly, we make it long
196 QString cipher; 194 QString cipher;
197 int mix=28730492; 195 int mix=28730492;
198 for (int i=0; i<(int)plain.length(); i++) { 196 for (int i=0; i<(int)plain.length(); i++) {
199 int u = plain[i].unicode(); 197 int u = plain[i].unicode();
200 int c = u ^ mix; 198 int c = u ^ mix;
201 QString x = QString::number(c,36); 199 QString x = QString::number(c,36);
202 cipher.append(QChar('a'+x.length())); 200 cipher.append(QChar('a'+x.length()));
203 cipher.append(x); 201 cipher.append(x);
204 mix *= u; 202 mix *= u;
205 } 203 }
206 return cipher; 204 return cipher;
207} 205}
208 206
209static QString decipher(const QString& cipher) 207static QString decipher(const QString& cipher)
210{ 208{
211 QString plain; 209 QString plain;
212 int mix=28730492; 210 int mix=28730492;
213 for (int i=0; i<(int)cipher.length();) { 211 for (int i=0; i<(int)cipher.length();) {
214 int l = cipher[i].unicode()-'a'; 212 int l = cipher[i].unicode()-'a';
215 QString x = cipher.mid(i+1,l); i+=l+1; 213 QString x = cipher.mid(i+1,l); i+=l+1;
216 int u = x.toInt(0,36) ^ mix; 214 int u = x.toInt(0,36) ^ mix;
217 plain.append(QChar(u)); 215 plain.append(QChar(u));
218 mix *= u; 216 mix *= u;
219 } 217 }
220 return plain; 218 return plain;
221} 219}
222 220
223/*! 221/*!
224 Writes an encrypted (\a key, \a value) entry to the current group. 222 Writes an encrypted (\a key, \a value) entry to the current group.
225 223
226 Note that the degree of protection offered by the encryption is 224 Note that the degree of protection offered by the encryption is
227 only sufficient to avoid the most casual observation of the configuration 225 only sufficient to avoid the most casual observation of the configuration
228 files. 226 files.
229 227
230 \sa readEntry() 228 \sa readEntry()
231*/ 229*/
232void Config::writeEntryCrypt( const QString &key, const QString &value ) 230void Config::writeEntryCrypt( const QString &key, const QString &value )
233{ 231{
234 if ( git == groups.end() ) { 232 if ( git == groups.end() ) {
235 qWarning( "no group set" ); 233 qWarning( "no group set" );
236 return; 234 return;
237 } 235 }
238 QString evalue = encipher(value); 236 QString evalue = encipher(value);
239 if ( (*git)[key] != evalue ) { 237 if ( (*git)[key] != evalue ) {
240 ( *git ).insert( key, evalue ); 238 ( *git ).insert( key, evalue );
241 changed = TRUE; 239 changed = TRUE;
242 } 240 }
243} 241}
244 242
245/*! 243/*!
246 Writes a (\a key, \a num) entry to the current group. 244 Writes a (\a key, \a num) entry to the current group.
247 245
248 \sa readNumEntry() 246 \sa readNumEntry()
249*/ 247*/
250void Config::writeEntry( const QString &key, int num ) 248void Config::writeEntry( const QString &key, int num )
251{ 249{
252 QString s; 250 QString s;
253 s.setNum( num ); 251 s.setNum( num );
254 writeEntry( key, s ); 252 writeEntry( key, s );
255} 253}
256 254
257#ifdef Q_HAS_BOOL_TYPE 255#ifdef Q_HAS_BOOL_TYPE
258/*! 256/*!
259 Writes a (\a key, \a b) entry to the current group. This is equivalent 257 Writes a (\a key, \a b) entry to the current group. This is equivalent
260 to writing a 0 or 1 as an integer entry. 258 to writing a 0 or 1 as an integer entry.
261 259
262 \sa readBoolEntry() 260 \sa readBoolEntry()
263*/ 261*/
264void Config::writeEntry( const QString &key, bool b ) 262void Config::writeEntry( const QString &key, bool b )
265{ 263{
266 QString s; 264 QString s;
267 s.setNum( ( int )b ); 265 s.setNum( ( int )b );
268 writeEntry( key, s ); 266 writeEntry( key, s );
269} 267}
270#endif 268#endif
271 269
272/*! 270/*!
273 Writes a (\a key, \a lst) entry to the current group. The list 271 Writes a (\a key, \a lst) entry to the current group. The list
274 is separated by \a sep, so the strings must not contain that character. 272 is separated by \a sep, so the strings must not contain that character.
275 273
276 \sa readListEntry() 274 \sa readListEntry()
277*/ 275*/
278void Config::writeEntry( const QString &key, const QStringList &lst, const QChar &sep ) 276void Config::writeEntry( const QString &key, const QStringList &lst, const QChar &sep )
279{ 277{
280 QString s; 278 QString s;
281 QStringList::ConstIterator it = lst.begin(); 279 QStringList::ConstIterator it = lst.begin();
282 for ( ; it != lst.end(); ++it ) 280 for ( ; it != lst.end(); ++it )
283 s += *it + sep; 281 s += *it + sep;
284 writeEntry( key, s ); 282 writeEntry( key, s );
285} 283}
286 284
287/*! 285/*!
288 Removes the \a key entry from the current group. Does nothing if 286 Removes the \a key entry from the current group. Does nothing if
289 there is no such entry. 287 there is no such entry.
290*/ 288*/
291 289
292void Config::removeEntry( const QString &key ) 290void Config::removeEntry( const QString &key )
293{ 291{
294 if ( git == groups.end() ) { 292 if ( git == groups.end() ) {
295 qWarning( "no group set" ); 293 qWarning( "no group set" );
296 return; 294 return;
297 } 295 }
298 ( *git ).remove( key ); 296 ( *git ).remove( key );
299 changed = TRUE; 297 changed = TRUE;
300} 298}
301 299
302/*! 300/*!
303 \fn bool Config::operator == ( const Config & other ) const 301 \fn bool Config::operator == ( const Config & other ) const
304 302
305 Tests for equality with \a other. Config objects are equal if they refer to the same filename. 303 Tests for equality with \a other. Config objects are equal if they refer to the same filename.
306*/ 304*/
307 305
308/*! 306/*!
309 \fn bool Config::operator != ( const Config & other ) const 307 \fn bool Config::operator != ( const Config & other ) const
310 308
311 Tests for inequality with \a other. Config objects are equal if they refer to the same filename. 309 Tests for inequality with \a other. Config objects are equal if they refer to the same filename.
312*/ 310*/
313 311
314/*! 312/*!
315 \fn QString Config::readEntry( const QString &key, const QString &deflt ) const 313 \fn QString Config::readEntry( const QString &key, const QString &deflt ) const
316 314
317 Reads a string entry stored with \a key, defaulting to \a deflt if there is no entry. 315 Reads a string entry stored with \a key, defaulting to \a deflt if there is no entry.
318*/ 316*/
319 317
320/*! 318/*!
321 \internal 319 \internal
322 For compatibility, non-const version. 320 For compatibility, non-const version.
323*/ 321*/
324QString Config::readEntry( const QString &key, const QString &deflt ) 322QString Config::readEntry( const QString &key, const QString &deflt )
325{ 323{
326 QString res = readEntryDirect( key+"["+lang+"]" ); 324 QString res = readEntryDirect( key+"["+lang+"]" );
327 if ( !res.isNull() ) 325 if ( !res.isNull() )
328 return res; 326 return res;
329 if ( !glang.isEmpty() ) { 327 if ( !glang.isEmpty() ) {
330 res = readEntryDirect( key+"["+glang+"]" ); 328 res = readEntryDirect( key+"["+glang+"]" );
331 if ( !res.isNull() ) 329 if ( !res.isNull() )
332 return res; 330 return res;
333 } 331 }
334 return readEntryDirect( key, deflt ); 332 return readEntryDirect( key, deflt );
335} 333}
336 334
337/*! 335/*!
338 \fn QString Config::readEntryCrypt( const QString &key, const QString &deflt ) const 336 \fn QString Config::readEntryCrypt( const QString &key, const QString &deflt ) const
339 337
340 Reads an encrypted string entry stored with \a key, defaulting to \a deflt if there is no entry. 338 Reads an encrypted string entry stored with \a key, defaulting to \a deflt if there is no entry.
341*/ 339*/
342 340
343/*! 341/*!
344 \internal 342 \internal
345 For compatibility, non-const version. 343 For compatibility, non-const version.
346*/ 344*/
347QString Config::readEntryCrypt( const QString &key, const QString &deflt ) 345QString Config::readEntryCrypt( const QString &key, const QString &deflt )
348{ 346{
349 QString res = readEntryDirect( key+"["+lang+"]" ); 347 QString res = readEntryDirect( key+"["+lang+"]" );
350 if ( res.isNull() && glang.isEmpty() ) 348 if ( res.isNull() && glang.isEmpty() )
351 res = readEntryDirect( key+"["+glang+"]" ); 349 res = readEntryDirect( key+"["+glang+"]" );
352 if ( res.isNull() ) 350 if ( res.isNull() )
353 res = readEntryDirect( key, QString::null ); 351 res = readEntryDirect( key, QString::null );
354 if ( res.isNull() ) 352 if ( res.isNull() )
355 return deflt; 353 return deflt;
356 return decipher(res); 354 return decipher(res);
357} 355}
358 356
359/*! 357/*!
360 \fn QString Config::readEntryDirect( const QString &key, const QString &deflt ) const 358 \fn QString Config::readEntryDirect( const QString &key, const QString &deflt ) const
361 \internal 359 \internal
362*/ 360*/
363 361
364/*! 362/*!
365 \internal 363 \internal
366 For compatibility, non-const version. 364 For compatibility, non-const version.
367*/ 365*/
368QString Config::readEntryDirect( const QString &key, const QString &deflt ) 366QString Config::readEntryDirect( const QString &key, const QString &deflt )
369{ 367{
370 if ( git == groups.end() ) { 368 if ( git == groups.end() ) {
371 //qWarning( "no group set" ); 369 //qWarning( "no group set" );
372 return deflt; 370 return deflt;
373 } 371 }
374 ConfigGroup::ConstIterator it = ( *git ).find( key ); 372 ConfigGroup::ConstIterator it = ( *git ).find( key );
375 if ( it != ( *git ).end() ) 373 if ( it != ( *git ).end() )
376 return *it; 374 return *it;
377 else 375 else
378 return deflt; 376 return deflt;
379} 377}
380 378
381/*! 379/*!
382 \fn int Config::readNumEntry( const QString &key, int deflt ) const 380 \fn int Config::readNumEntry( const QString &key, int deflt ) const
383 Reads a numeric entry stored with \a key, defaulting to \a deflt if there is no entry. 381 Reads a numeric entry stored with \a key, defaulting to \a deflt if there is no entry.
384*/ 382*/
385 383
386/*! 384/*!
387 \internal 385 \internal
388 For compatibility, non-const version. 386 For compatibility, non-const version.
389*/ 387*/
390int Config::readNumEntry( const QString &key, int deflt ) 388int Config::readNumEntry( const QString &key, int deflt )
391{ 389{
392 QString s = readEntry( key ); 390 QString s = readEntry( key );
393 if ( s.isEmpty() ) 391 if ( s.isEmpty() )
394 return deflt; 392 return deflt;
395 else 393 else
396 return s.toInt(); 394 return s.toInt();
397} 395}
398 396
399/*! 397/*!
400 \fn bool Config::readBoolEntry( const QString &key, bool deflt ) const 398 \fn bool Config::readBoolEntry( const QString &key, bool deflt ) const
401 Reads a bool entry stored with \a key, defaulting to \a deflt if there is no entry. 399 Reads a bool entry stored with \a key, defaulting to \a deflt if there is no entry.
402*/ 400*/
403 401
404/*! 402/*!
405 \internal 403 \internal
406 For compatibility, non-const version. 404 For compatibility, non-const version.
407*/ 405*/