summaryrefslogtreecommitdiffstats
path: root/src/kvilib/ext/kvi_config.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/kvilib/ext/kvi_config.cpp')
-rw-r--r--src/kvilib/ext/kvi_config.cpp1007
1 files changed, 1007 insertions, 0 deletions
diff --git a/src/kvilib/ext/kvi_config.cpp b/src/kvilib/ext/kvi_config.cpp
new file mode 100644
index 00000000..eb3dc0bc
--- /dev/null
+++ b/src/kvilib/ext/kvi_config.cpp
@@ -0,0 +1,1007 @@
+//==========================================================================================
+//
+// File : kvi_config.cpp
+// Last major modification : Thu Jan 14 1999 18:03:59 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 1999-2007 Szymon Stefanek (pragma at kvirc dot net)
+//
+// This program is FREE software. You can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your opinion) any later version.
+//
+// This program is distributed in the HOPE that it will be USEFUL,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+// See the GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//==========================================================================================
+
+#define __KVILIB__
+
+#include "kvi_config.h"
+#include "kvi_fileutils.h"
+#include "kvi_pixmap.h"
+#include "kvi_msgtype.h"
+#include "kvi_stringconversion.h"
+#include "kvi_memmove.h"
+#include "kvi_malloc.h"
+#include "kvi_file.h"
+
+
+KviConfig::KviConfig(const QString &filename,FileMode f,bool bLocal8Bit)
+{
+ m_bLocal8Bit = bLocal8Bit;
+ m_szFileName = filename;
+ m_bDirty = false;
+ m_szGroup = KVI_CONFIG_DEFAULT_GROUP;
+ m_bPreserveEmptyGroups = false;
+ m_bReadOnly = (f == KviConfig::Read);
+ m_pDict = new KviPointerHashTable<QString,KviConfigGroup>(17,false);
+ m_pDict->setAutoDelete(true);
+ if(f != KviConfig::Write)load();
+}
+
+KviConfig::KviConfig(const char* filename,FileMode f,bool bLocal8Bit)
+{
+ m_bLocal8Bit = bLocal8Bit;
+ m_szFileName = QString::fromUtf8(filename);
+ m_bDirty = false;
+ m_szGroup = KVI_CONFIG_DEFAULT_GROUP;
+ m_bPreserveEmptyGroups = false;
+ m_bReadOnly = (f == KviConfig::Read);
+ m_pDict = new KviPointerHashTable<QString,KviConfigGroup>(17,false);
+ m_pDict->setAutoDelete(true);
+ if(f != KviConfig::Write)load();
+}
+
+
+KviConfig::~KviConfig()
+{
+ if(m_bDirty)save();
+ delete m_pDict;
+}
+
+void KviConfig::clear()
+{
+ delete m_pDict;
+ m_pDict = new KviPointerHashTable<QString,KviConfigGroup>(17,false);
+ m_pDict->setAutoDelete(true);
+ m_bDirty = false;
+ m_szGroup = KVI_CONFIG_DEFAULT_GROUP;
+}
+
+void KviConfig::clearGroup(const QString & szGroup)
+{
+ m_bDirty = true;
+ m_pDict->remove(szGroup);
+ if(!m_pDict->find(m_szGroup))m_szGroup = KVI_CONFIG_DEFAULT_GROUP; //removed the current one
+}
+
+void KviConfig::clearKey(const QString & szKey)
+{
+ m_bDirty = true;
+ KviConfigGroup * p_group = getCurrentGroup();
+ p_group->remove(szKey);
+ if(p_group->count() == 0)clearGroup(m_szGroup);
+}
+
+/*
+void KviConfig::getContentsString(KviStr &buffer)
+{
+ buffer = __tr("Contents of config file ");
+ buffer.append(m_szFileName.ptr());
+ buffer.append('\n');
+ int sections = 0;
+ int keys = 0;
+ KviPointerHashTableIterator<QString,KviStrDict> it(*m_pDict);
+ while(it.current()){
+ buffer.append(" Section [");
+ buffer.append(it.currentKey());
+ buffer.append("]\n");
+ int sectionKeys = 0;
+ KviPointerHashTableIterator<QString,KviStr> it2(*it.current());
+ while(it2.current()){
+ buffer.append(" Key [");
+ buffer.append(it2.currentKey());
+ buffer.append("] : ");
+ buffer.append(it2.current()->ptr());
+ buffer.append('\n');
+ ++it2;
+ ++sectionKeys;
+ ++keys;
+ }
+ KviStr tmp(KviStr::Format,__tr(" Total: %d keys"),sectionKeys);
+ buffer.append(tmp);
+ buffer.append('\n');
+ ++it;
+ ++sections;
+ }
+ KviStr tmp(KviStr::Format,__tr("Total: %d keys in %d sections"),keys,sections);
+ buffer.append(tmp);
+}
+*/
+
+
+
+#define LOAD_BLOCK_SIZE 32768
+
+bool KviConfig::load()
+{
+ // this is really faster than the old version :)
+
+ // open the file
+ KviFile f(m_szFileName);
+ if(!f.openForReading())return false;
+
+ KviStr tmp;
+ KviConfigGroup * p_group = 0;
+
+ int iLoadBlockSize = LOAD_BLOCK_SIZE;
+
+ char * buffer = (char *)kvi_malloc(iLoadBlockSize * sizeof(char));
+
+ int toRead;
+ int readedLen;
+ int remainingLen = 0;
+
+ char * p = buffer; // start writing to the beginning of the buffer
+
+ do {
+ // compute the length to read
+ toRead = iLoadBlockSize - remainingLen;
+ if(toRead < 1)
+ {
+ // ops... a string longer than iLoadBlockSize - 1 chars
+ iLoadBlockSize += LOAD_BLOCK_SIZE;
+ int iOffset = p - buffer;
+ buffer = (char *)kvi_realloc(buffer,iLoadBlockSize * sizeof(char));
+ p = buffer + iOffset;
+ toRead += LOAD_BLOCK_SIZE;
+ }
+
+ // do read
+ readedLen = f.readBlock(p,toRead);
+ if(readedLen < toRead)
+ {
+ // check for errors
+ if(readedLen <= 0)
+ {
+ if(readedLen < 0)
+ {
+ // error at all
+ f.close();
+ kvi_free(buffer);
+ return true; // nothing more to parse anyway
+ } else {
+ // just a zero byte read
+ if(remainingLen == 0)
+ {
+ // there was nothing in the buffer
+ f.close(); // nothing to parse anyway
+ kvi_free(buffer);
+ return true;
+ }
+ // there is something in the buffer but we have readed 0 bytes
+ // this usually means that the last line in the file has no trailing newline
+ // ...we just fake it :)
+ *p = '\n';
+ readedLen = 1;
+ }
+ } else {
+ // just readed something but less than expected
+ // check if the last readed char is a newline
+ // if it isn't , fake it
+ if(*(p + readedLen - 1) != '\n')
+ {
+ *(p + readedLen) = '\n';
+ readedLen++;
+ }
+ }
+ }
+ // compute the end pointer
+ char * endp = p + readedLen;
+
+ p = buffer; // start from beginning of the data buffer at all
+ // begin of the current string
+ char * begin = p;
+
+ // and loop
+ while(p < endp)
+ {
+ // find a newline
+ if(*p != '\n')
+ {
+ p++;
+ continue;
+ }
+ // newline!
+ *p = 0;
+ // now begin points to the string that terminates in p
+ // skip leading whitespace
+ while((*begin == '\t') || (*begin == ' '))begin++;
+
+ if(p == begin)
+ {
+ // empty line
+ p++;
+ begin = p;
+ continue;
+ }
+ // now p > begin
+ // check if there are trailing spaces (include CR so CRLF is trimmed too)
+ char * trail = p - 1;
+
+ p++;
+
+ while(trail >= begin)
+ {
+ if((*trail == '\r') || (*trail == '\t') || (*trail == ' '))*trail = 0;
+ else break;
+ trail--;
+ }
+
+ // yeah, have some data in this line :D
+ switch(*begin)
+ {
+ case 0:
+ // empty line
+ break;
+ case '#':
+ // comment: just skip it
+ break;
+ case '[':
+ // group ?
+ begin++;
+ if(*begin && (*begin != ']'))
+ {
+ char * z = begin;
+#define COMPAT_WITH_OLD_CONFIGS
+#ifdef COMPAT_WITH_OLD_CONFIGS
+ // run to the end of the string
+ while(*z)z++;
+ // run back to the trailing ']'
+ while((z > begin) && (*z != ']'))z--;
+ // if it is not ther just run back to the end of the string
+ if(*z != ']')while(*z)z++;
+#else
+ // new configs have it always encoded properly
+ while(*z && (*z != ']'))z++;
+#endif
+ *z = 0;
+ tmp.hexDecode(begin);
+ tmp.stripRightWhiteSpace(); // no external spaces in group names
+
+ if(!tmp.isEmpty())
+ {
+ QString szGroup = m_bLocal8Bit ?
+ QString::fromLocal8Bit(tmp.ptr(),tmp.len()) :
+ QString::fromUtf8(tmp.ptr(),tmp.len());
+ p_group = m_pDict->find(szGroup);
+ if(!p_group)
+ {
+ p_group = new KviConfigGroup(17,false);
+ p_group->setAutoDelete(true);
+ m_pDict->insert(szGroup,p_group);
+ }
+ }
+ }
+ break;
+ default:
+ {
+ // real data ?
+ char * z = begin;
+ while(*z && (*z != '='))z++;
+ if(*z && (z != begin))
+ {
+ *z = 0;
+ tmp.hexDecode(begin);
+ tmp.stripRightWhiteSpace(); // No external spaces at all in keys
+ if(!tmp.isEmpty())
+ {
+ QString szKey = m_bLocal8Bit ?
+ QString::fromLocal8Bit(tmp.ptr(),tmp.len()) :
+ QString::fromUtf8(tmp.ptr(),tmp.len());
+ z++;
+ while(*z && ((*z == ' ') || (*z == '\t')))z++;
+ if(*z)
+ {
+ tmp.hexDecode(z);
+ QString * pVal = new QString( m_bLocal8Bit ?
+ QString::fromLocal8Bit(tmp.ptr(),tmp.len()) :
+ QString::fromUtf8(tmp.ptr(),tmp.len())
+ );
+ if(!p_group)
+ {
+ // ops...we're missing a group
+ // use the default one
+ p_group = new KviConfigGroup(17,false);
+ p_group->setAutoDelete(true);
+ m_pDict->insert(KVI_CONFIG_DEFAULT_GROUP,p_group);
+ }
+ p_group->replace(szKey,pVal);
+ } else {
+ // we in fact need this (mercy :D)
+ // otherwise the empty options will be treated as non-existing ones
+ // and will get the defaults (which is bad)
+ QString * pVal = new QString(QString::null);
+ p_group->replace(szKey,pVal);
+ }
+ }
+ }
+ }
+ break;
+ }
+ begin = p;
+ }
+ if(begin != endp)
+ {
+ // there is data with no trailing newline in the buffer
+ remainingLen = endp-begin;
+ if(buffer != begin)
+ {
+ kvi_memmove(buffer,begin,remainingLen);
+ p = buffer + remainingLen;
+ } // else p remains where it is
+ } else {
+ p = buffer;
+ }
+ } while(readedLen == toRead);
+
+ f.close();
+ kvi_free(buffer);
+ return true;
+}
+
+/*
+
+bool KviConfig::load()
+{
+ QFile f(m_szFileName);
+ if(!f.open(IO_ReadOnly))return false;
+
+
+ KviConfigGroup * p_group = 0;
+
+ KviStr dataLine;
+ bool bContinue;
+
+ do {
+ bContinue = kvi_readLine(&f,dataLine);
+ dataLine.stripWhiteSpace();
+ if(dataLine.hasData())
+ {
+ switch(*(dataLine.ptr()))
+ {
+ case '#':
+ // just skip it , it is a comment
+ break;
+ case '[':
+ {
+ //set the group
+ dataLine.cutLeft(1);
+ dataLine.cutRight(1);
+ dataLine.hexDecode();
+ if(dataLine.hasData())
+ {
+ QString szUtf8 = QString::fromUtf8(dataLine.ptr());
+ p_group = m_pDict->find(szUtf8);
+
+ if(!p_group)
+ {
+ p_group = new KviConfigGroup(17,false);
+ p_group->setAutoDelete(true);
+ m_pDict->insert(szUtf8,p_group);
+ }
+ }
+ }
+ break;
+ default:
+ {
+ //data entry...split in two...
+ KviStr name=dataLine.getToken('=');
+ name.stripRightWhiteSpace(); // strip any whitespace added externally
+ name.hexDecode();
+ if(name.hasData())
+ {
+ dataLine.stripLeftWhiteSpace(); // strip any whitespace added externally
+ dataLine.hexDecode();
+ //insert (replace items if needed)
+ QString *p_data=new QString(QString::fromUtf8(dataLine.ptr()));
+ if(!p_group)
+ {
+ // ops...we're missing a group
+ // use the default one
+ p_group = new KviConfigGroup(17,false);
+ p_group->setAutoDelete(true);
+ m_pDict->insert(KVI_CONFIG_DEFAULT_GROUP,p_group);
+ }
+ QString szName = QString::fromUtf8(name.ptr());
+ p_group->replace(szName,p_data);
+ }
+ }
+ break;
+ }
+ }
+ } while (bContinue);
+
+ f.close();
+ return true;
+}
+
+*/
+
+bool KviConfig::save()
+{
+ static unsigned char encode_table[256]=
+ {
+ // 000 001 002 003 004 005 006 007 008 009 010 011 012 013 014 015
+ // NUL SOH STX ETX EOT ENQ ACK BEL BS HT LF VT FF CR SO SI
+ 1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,
+ // 016 017 018 019 020 021 022 023 024 025 026 027 028 029 030 031
+ // DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS US
+ 1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,
+ // 032 033 034 035 036 037 038 039 040 041 042 043 044 045 046 047
+ // ! " # $ % & ' ( ) * + , - . /
+ 1 ,0 ,0 ,1 ,0 ,1 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
+ // 048 049 050 051 052 053 054 055 056 057 058 059 060 061 062 063
+ // 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
+ 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,1 ,0 ,0 ,
+ // 064 065 066 067 068 069 070 071 072 073 074 075 076 077 078 079
+ // @ A B C D E F G H I J K L M N O
+ 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
+ // 080 081 082 083 084 085 086 087 088 089 090 091 092 093 094 095
+ // P Q R S T U V W X Y Z [ \ ] ^ _
+ 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,1 ,0 ,1 ,0 ,0 ,
+ // 096 097 098 099 100 101 102 103 104 105 106 107 108 109 110 111
+ // ` a b c d e f g h i j k l m n o
+ 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
+ // 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
+ // p q r s t u v w x y z { | } ~ 
+ 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
+ // 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
+ //
+ 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
+ // 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
+ //
+ 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
+ // 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
+ //
+ 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
+ // 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
+ //
+ 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
+ // 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
+ // � � � � � � � � � � � � � � � �
+ 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
+ // 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223
+ // � � � � � � � � � � � � � � � �
+ 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
+ // 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239
+ // � � � � � � � � � � � � � � � �
+ 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
+ // 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255
+ // � � � � � � � �
+ 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0
+ };
+
+
+ if(m_bReadOnly)return false;
+
+ KviFile f(m_szFileName);
+ if(!f.openForWriting())return false;
+ if(f.writeBlock("# KVIrc configuration file\n",27) != 27)return false;
+
+ KviPointerHashTableIterator<QString,KviConfigGroup> it(*m_pDict);
+ while (it.current())
+ {
+ if((it.current()->count() != 0) || (m_bPreserveEmptyGroups))
+ {
+ KviStr group(m_bLocal8Bit ? KviQString::toLocal8Bit(it.currentKey()) : KviQString::toUtf8(it.currentKey()));
+ group.hexEncodeWithTable(encode_table);
+
+ if(!f.putChar('['))return false;
+ if(f.writeBlock(group.ptr(),group.len()) < (int) group.len())return false;
+ if(f.writeBlock("]\n",2) < 2)return false;
+
+ KviConfigGroup * dict = (KviConfigGroup *)it.current();
+ KviConfigGroupIterator it2(*dict);
+
+ KviStr szName,szValue;
+ while(QString * p_str = it2.current())
+ {
+ szName = m_bLocal8Bit ? KviQString::toLocal8Bit(it2.currentKey()) : KviQString::toUtf8(it2.currentKey());
+ szValue = m_bLocal8Bit ? KviQString::toLocal8Bit(*p_str) : KviQString::toUtf8(*p_str);
+ szName.hexEncodeWithTable(encode_table);
+ szValue.hexEncodeWhiteSpace();
+
+ if(f.writeBlock(szName.ptr(),szName.len()) < (int) szName.len())return false;
+ if(!f.putChar('='))return false;
+ if(f.writeBlock(szValue.ptr(),szValue.len()) < (int) szValue.len())return false;
+ if(!f.putChar('\n'))return false;
+ ++it2;
+ }
+ }
+ ++it;
+ }
+ f.close();
+ m_bDirty = false;
+ return true;
+}
+
+void KviConfig::setGroup(const QString & szGroup)
+{
+ m_szGroup = szGroup;
+ if(m_bPreserveEmptyGroups)
+ {
+ if(!hasGroup(szGroup))
+ {
+ getCurrentGroup(); // we need it to be created.
+ m_bDirty = true;
+ }
+ }
+}
+
+bool KviConfig::hasKey(const QString & szKey)
+{
+ KviConfigGroup * p_group = getCurrentGroup();
+ return (p_group->find(szKey) != 0);
+}
+
+bool KviConfig::hasGroup(const QString & szGroup)
+{
+ return (m_pDict->find(szGroup) != 0);
+}
+
+KviConfigGroup * KviConfig::getCurrentGroup()
+{
+ if(m_szGroup.isEmpty())m_szGroup = KVI_CONFIG_DEFAULT_GROUP;
+ KviConfigGroup * p_group = m_pDict->find(m_szGroup);
+ if(!p_group)
+ {
+ //create the group
+ p_group = new KviConfigGroup(17,false);
+ p_group->setAutoDelete(true);
+ m_pDict->insert(m_szGroup,p_group);
+ }
+ return p_group;
+}
+
+////////////////////////////////// KviStr
+
+void KviConfig::writeEntry(const QString & szKey,const QString & szValue)
+{
+ m_bDirty = true;
+ KviConfigGroup * p_group = getCurrentGroup();
+ QString *p_data=new QString(szValue);
+ p_group->replace(szKey,p_data);
+}
+
+// FIXME: #warning "We have probs here ?"
+
+QString KviConfig::readEntry(const QString & szKey,const QString & szDefault)
+{
+ KviConfigGroup * p_group = getCurrentGroup();
+ QString * p_str = p_group->find(szKey);
+ if(!p_str)
+ {
+ m_szStrBuffer = szDefault;
+ } else {
+ m_szStrBuffer = *p_str;
+ }
+ return m_szStrBuffer;
+}
+
+//////////////////////////////////// QString
+
+/*
+QString KviConfig::readQStringEntry(const char *szKey,const QString &szDefault)
+{
+ KviStrDict * p_group = getCurrentGroup();
+ KviStr * p_str = p_group->find(szKey);
+ if(!p_str)return szDefault;
+ return QString::fromUtf8(p_str->ptr());
+}
+*/
+
+/*
+void KviConfig::writeEntry(const char *szKey,const QString &szValue)
+{
+ m_bDirty = true;
+ KviStrDict * p_group = getCurrentGroup();
+ p_group->replace(szKey,new KviStr(szValue.utf8().data()));
+}
+*/
+
+////////////////////////////////// QStringList
+
+static QString g_szConfigStringListSeparator(",\\[ITEM],");
+
+QStringList KviConfig::readStringListEntry(const QString & szKey,const QStringList &list)
+{
+ KviConfigGroup * p_group = getCurrentGroup();
+ QString * p_str = p_group->find(szKey);
+ if(!p_str)return list;
+#ifdef COMPILE_USE_QT4
+ return p_str->split(g_szConfigStringListSeparator);
+#else
+ return QStringList::split(g_szConfigStringListSeparator,*p_str);
+#endif
+}
+
+void KviConfig::writeEntry(const QString & szKey,const QStringList &list)
+{
+ m_bDirty = true;
+ KviConfigGroup * p_group = getCurrentGroup();
+ QString *p_data=new QString(list.join(g_szConfigStringListSeparator));
+ p_group->replace(szKey,p_data);
+}
+
+////////////////////////////////// KviValueList<int>
+
+KviValueList<int> KviConfig::readIntListEntry(const QString & szKey,const KviValueList<int> &list)
+{
+ KviConfigGroup * p_group = getCurrentGroup();
+ QString * p_str = p_group->find(szKey);
+ if(!p_str)
+ {
+ //debug("Returning default list for group %s and key %s",m_szGroup.latin1(),szKey.latin1());
+ return list;
+ }
+#ifdef COMPILE_USE_QT4
+ QStringList sl = p_str->split(",");
+#else
+ QStringList sl = QStringList::split(",",*p_str);
+#endif
+ KviValueList<int> ret;
+
+ //debug("Got option list for group %s and key %s: %s",m_szGroup.latin1(),szKey.latin1(),p_str->latin1());
+
+ for(QStringList::Iterator it = sl.begin();it != sl.end();++it)
+ {
+ bool bOk;
+ int iTmp = (*it).toInt(&bOk);
+ if(bOk)ret.append(iTmp);
+ }
+
+ return ret;
+}
+
+
+void KviConfig::writeEntry(const QString & szKey,const KviValueList<int> &list)
+{
+ m_bDirty = true;
+ KviConfigGroup * p_group = getCurrentGroup();
+ KviStr szData;
+ for(KviValueList<int>::ConstIterator it = list.begin();it != list.end();++it)
+ {
+ if(szData.hasData())szData.append(',');
+ szData.append(KviStr::Format,"%d",*it);
+ }
+ //debug("Writing option list for group %s and key %s: %s",m_szGroup.latin1(),szKey.latin1(),szData.ptr());
+
+ p_group->replace(szKey,new QString(szData.ptr()));
+}
+
+////////////////////////////////// KviPixmap
+
+// FIXME: #warning "Spaces in image names ?"
+
+void KviConfig::writeEntry(const QString & szKey,const KviPixmap &pixmap)
+{
+ m_bDirty = true;
+ KviConfigGroup * p_group = getCurrentGroup();
+ QString *p_data=new QString();
+ KviStringConversion::toString(pixmap,*p_data);
+ p_group->replace(szKey,p_data);
+}
+
+KviPixmap KviConfig::readPixmapEntry(const QString & szKey,const KviPixmap &pixDef)
+{
+ KviConfigGroup * p_group = getCurrentGroup();
+ QString * p_str = p_group->find(szKey);
+ if(p_str)
+ {
+ KviPixmap ret("");
+ return KviStringConversion::fromString(*p_str,ret) ? ret : pixDef;
+ } else {
+ return pixDef;
+ }
+}
+
+////////////////////////////////// KviMsgType
+
+void KviConfig::writeEntry(const QString & szKey,const KviMsgType &msg)
+{
+ m_bDirty = true;
+ KviConfigGroup * p_group = getCurrentGroup();
+ QString szData;
+ KviStringConversion::toString(msg,szData);
+ p_group->replace(szKey,new QString(szData));
+}
+
+KviMsgType KviConfig::readMsgTypeEntry(const QString & szKey,const KviMsgType &msgDef)
+{
+ KviConfigGroup * p_group = getCurrentGroup();
+ QString * p_str = p_group->find(szKey);
+ if(!p_str)return msgDef;
+ KviMsgType ret = msgDef;
+ KviStringConversion::fromString(*p_str,ret);
+ return ret;
+}
+
+////////////////////////////////// QColor
+
+void KviConfig::writeEntry(const QString & szKey,const QColor &clr)
+{
+ m_bDirty = true;
+ KviConfigGroup * p_group = getCurrentGroup();
+ KviStr szData(KviStr::Format,"%d,%d,%d",clr.red(),clr.green(),clr.blue());
+ p_group->replace(szKey,new QString(szData.ptr()));
+}
+
+QColor KviConfig::readColorEntry(const QString & szKey,const QColor &clr)
+{
+ KviConfigGroup * p_group = getCurrentGroup();
+ QColor color(clr);
+ QString * pointer_that_IS_initialized = p_group->find(szKey);
+
+
+ if(pointer_that_IS_initialized)
+ {
+
+ KviStr str(*pointer_that_IS_initialized);
+ str.stripLeftWhiteSpace();
+
+ KviStr red,green,blue;
+
+ str.getToken(red,',');
+ str.getToken(green,',');
+ str.getToken(blue,',');
+
+ if((red.isUnsignedNum())&&(green.isUnsignedNum())&&(blue.isUnsignedNum())){
+ bool bOk;
+ int r = red.toInt(&bOk) % 256;
+ int g = green.toInt(&bOk) % 256;
+ int b = blue.toInt(&bOk) % 256;
+ if(r < 0)r = -r;
+ if(g < 0)g = -g;
+ if(b < 0)b = -b;
+ color.setRgb(r,g,b);
+ }
+ }
+ return color;
+}
+
+////////////////////////////////// QFont
+
+void KviConfig::getFontProperties(KviStr & buffer,QFont *fnt)
+{
+ QString tmp;
+ KviStringConversion::toString(*fnt,tmp);
+ buffer = tmp;
+}
+
+void KviConfig::writeEntry(const QString & szKey,QFont &fnt)
+{
+ m_bDirty = true;
+ KviConfigGroup * p_group = getCurrentGroup();
+ QString *p_data = new QString();
+ KviStringConversion::toString(fnt,*p_data);
+ p_group->replace(szKey,p_data);
+}
+
+
+void KviConfig::setFontProperties(KviStr & str,QFont *fnt)
+{
+ KviStringConversion::fromString(str.ptr(),*fnt);
+}
+
+QFont KviConfig::readFontEntry(const QString & szKey,const QFont &fnt)
+{
+ QFont font(fnt);
+ KviConfigGroup * p_group = getCurrentGroup();
+ QString * p_str = p_group->find(szKey);
+ if(p_str)
+ {
+ //FontEntry=Arial,12,9,0,100,italic,underline,strikeout,
+ KviStr str(*p_str);
+ str.stripLeftWhiteSpace();
+ setFontProperties(str,&font);
+ }
+ return font;
+}
+
+////////////////////////////////// bool
+
+void KviConfig::writeEntry(const QString & szKey,bool bTrue)
+{
+ m_bDirty = true;
+ KviConfigGroup * p_group = getCurrentGroup();
+ QString *p_data = new QString(bTrue ? "true" : "false");
+ p_group->replace(szKey,p_data);
+}
+
+bool KviConfig::readBoolEntry(const QString & szKey,bool bTrue)
+{
+ KviConfigGroup * p_group = getCurrentGroup();
+ QString * p_str = p_group->find(szKey);
+ if(!p_str)return bTrue;
+ static QString szTrue = "true";
+ return (KviQString::toLower(*p_str) == szTrue);
+}
+
+////////////////////////////////// QRect
+
+void KviConfig::writeEntry(const QString & szKey,const QRect &rct)
+{
+ m_bDirty = true;
+ KviConfigGroup * p_group = getCurrentGroup();
+ QString szBuf;
+ KviStringConversion::toString(rct,szBuf);
+ p_group->replace(szKey,new QString(szBuf));
+}
+
+QRect KviConfig::readRectEntry(const QString & szKey,const QRect &rct)
+{
+ KviConfigGroup * p_group = getCurrentGroup();
+ QString * str = p_group->find(szKey);
+ if(!str)return rct;
+ QRect ret;
+ return KviStringConversion::fromString(*str,ret) ? ret : rct;
+}
+
+////////////////////////////////// unsigned short
+
+void KviConfig::writeEntry(const QString & szKey,unsigned short usValue)
+{
+ m_bDirty = true;
+ KviConfigGroup * p_group = getCurrentGroup();
+ QString *p_data = new QString();
+ p_data->setNum(usValue);
+ p_group->replace(szKey,p_data);
+}
+
+unsigned short int KviConfig::readUShortEntry(const QString & szKey,unsigned short int usDefault)
+{
+ KviConfigGroup * p_group = getCurrentGroup();
+ QString * p_str = p_group->find(szKey);
+ if(!p_str)return usDefault;
+ bool bOk;
+ unsigned short int usVal=p_str->toUShort(&bOk);
+ return bOk ? usVal : usDefault;
+}
+
+/*
+////////////////////////////////// unsigned long
+
+Unused code
+void KviConfig::writeEntry(const char *szKey,unsigned long lValue)
+{
+ m_bDirty = true;
+ KviStrDict * p_group = getCurrentGroup();
+ KviStr *p_data = new KviStr();
+ p_data->setNum(lValue);
+ p_group->replace(szKey,p_data);
+}
+
+unsigned long KviConfig::readULongEntry(const char *szKey,unsigned long lDefault)
+{
+ KviStrDict * p_group = getCurrentGroup();
+ KviStr * p_str = p_group->find(szKey);
+ if(!p_str)return lDefault;
+ bool bOk;
+ unsigned long lVal=p_str->toULong(&bOk);
+ return bOk ? lVal : lDefault;
+}
+*/
+
+////////////////////////////////// int
+
+void KviConfig::writeEntry(const QString & szKey,int iValue)
+{
+ m_bDirty = true;
+ KviConfigGroup * p_group = getCurrentGroup();
+ QString *p_data = new QString();
+ p_data->setNum(iValue);
+ p_group->replace(szKey,p_data);
+}
+
+int KviConfig::readIntEntry(const QString & szKey,int iDefault)
+{
+ KviConfigGroup * p_group = getCurrentGroup();
+ QString * p_str = p_group->find(szKey);
+ if(!p_str)return iDefault;
+ bool bOk;
+ int iVal=p_str->toInt(&bOk);
+ return bOk ? iVal : iDefault;
+}
+
+////////////////////////////////// unsigned int
+
+void KviConfig::writeEntry(const QString & szKey,unsigned int iValue)
+{
+ m_bDirty = true;
+ KviConfigGroup * p_group = getCurrentGroup();
+ QString *p_data = new QString();
+ p_data->setNum(iValue);
+ p_group->replace(szKey,p_data);
+}
+
+unsigned int KviConfig::readUIntEntry(const QString & szKey,unsigned int iDefault)
+{
+ KviConfigGroup * p_group = getCurrentGroup();
+ QString * p_str = p_group->find(szKey);
+ if(!p_str)return iDefault;
+ bool bOk;
+ unsigned int iVal=p_str->toUInt(&bOk);
+ return bOk ? iVal : iDefault;
+}
+
+////////////////////////////////// char
+
+void KviConfig::writeEntry(const QString & szKey,char iValue)
+{
+ m_bDirty = true;
+ KviConfigGroup * p_group = getCurrentGroup();
+ QString * p_data = new QString();
+ p_data->setNum(iValue);
+ p_group->replace(szKey,p_data);
+}
+
+char KviConfig::readCharEntry(const QString & szKey,char iDefault)
+{
+ KviConfigGroup * p_group = getCurrentGroup();
+ QString * p_str = p_group->find(szKey);
+ if(!p_str)return iDefault;
+ bool bOk;
+ char iVal=(char)p_str->toInt(&bOk);
+ return bOk ? iVal : iDefault;
+}
+
+////////////////////////////////// unsigned char
+
+void KviConfig::writeEntry(const QString & szKey,unsigned char iValue)
+{
+ m_bDirty = true;
+ KviConfigGroup * p_group = getCurrentGroup();
+ QString *p_data = new QString();
+ p_data->setNum(iValue);
+ p_group->replace(szKey,p_data);
+}
+
+unsigned char KviConfig::readUCharEntry(const QString & szKey,unsigned char iDefault)
+{
+ KviConfigGroup * p_group = getCurrentGroup();
+ QString * p_str = p_group->find(szKey);
+ if(!p_str)return iDefault;
+ bool bOk;
+ unsigned char iVal=(unsigned char)p_str->toUInt(&bOk);
+ return bOk ? iVal : iDefault;
+}
+
+
+#ifdef COMPILE_ON_WINDOWS
+
+ // On windows we need to override new and delete operators
+ // to ensure that always the right new/delete pair is called for an object instance
+ // This bug is present in all the classes exported by a module that
+ // can be instantiated/destroyed from external modules.
+ // (this is a well known bug described in Q122675 of MSDN)
+
+ void * KviConfig::operator new(size_t tSize)
+ {
+ return kvi_malloc(tSize);
+ }
+
+ void KviConfig::operator delete(void * p)
+ {
+ kvi_free(p);
+ }
+
+#endif