summaryrefslogtreecommitdiff
path: root/library/config.cpp
Unidiff
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,360 +1,372 @@
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;