summaryrefslogtreecommitdiff
Unidiff
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,342 +1,341 @@
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