You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kvirc/src/kvilib/ext/kvi_config.cpp

1008 lines
28 KiB

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

//==========================================================================================
//
// 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 TQString &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<TQString,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 = TQString::fromUtf8(filename);
m_bDirty = false;
m_szGroup = KVI_CONFIG_DEFAULT_GROUP;
m_bPreserveEmptyGroups = false;
m_bReadOnly = (f == KviConfig::Read);
m_pDict = new KviPointerHashTable<TQString,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<TQString,KviConfigGroup>(17,false);
m_pDict->setAutoDelete(true);
m_bDirty = false;
m_szGroup = KVI_CONFIG_DEFAULT_GROUP;
}
void KviConfig::clearGroup(const TQString & 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 TQString & 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<TQString,KviStrDict> it(*m_pDict);
while(it.current()){
buffer.append(" Section [");
buffer.append(it.currentKey());
buffer.append("]\n");
int sectionKeys = 0;
KviPointerHashTableIterator<TQString,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())
{
TQString szGroup = m_bLocal8Bit ?
TQString::fromLocal8Bit(tmp.ptr(),tmp.len()) :
TQString::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())
{
TQString szKey = m_bLocal8Bit ?
TQString::fromLocal8Bit(tmp.ptr(),tmp.len()) :
TQString::fromUtf8(tmp.ptr(),tmp.len());
z++;
while(*z && ((*z == ' ') || (*z == '\t')))z++;
if(*z)
{
tmp.hexDecode(z);
TQString * pVal = new TQString( m_bLocal8Bit ?
TQString::fromLocal8Bit(tmp.ptr(),tmp.len()) :
TQString::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)
TQString * pVal = new TQString(TQString());
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()
{
TQFile 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())
{
TQString szUtf8 = TQString::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)
TQString *p_data=new TQString(TQString::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);
}
TQString szName = TQString::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
// <09> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20>
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
// <09> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20>
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
// <09> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20>
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
// <09> <20> <20> <20> <20> <20> <20> <20>
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<TQString,KviConfigGroup> it(*m_pDict);
while (it.current())
{
if((it.current()->count() != 0) || (m_bPreserveEmptyGroups))
{
KviStr group(m_bLocal8Bit ? KviTQString::toLocal8Bit(it.currentKey()) : KviTQString::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(TQString * p_str = it2.current())
{
szName = m_bLocal8Bit ? KviTQString::toLocal8Bit(it2.currentKey()) : KviTQString::toUtf8(it2.currentKey());
szValue = m_bLocal8Bit ? KviTQString::toLocal8Bit(*p_str) : KviTQString::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 TQString & szGroup)
{
m_szGroup = szGroup;
if(m_bPreserveEmptyGroups)
{
if(!hasGroup(szGroup))
{
getCurrentGroup(); // we need it to be created.
m_bDirty = true;
}
}
}
bool KviConfig::hasKey(const TQString & szKey)
{
KviConfigGroup * p_group = getCurrentGroup();
return (p_group->find(szKey) != 0);
}
bool KviConfig::hasGroup(const TQString & 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 TQString & szKey,const TQString & szValue)
{
m_bDirty = true;
KviConfigGroup * p_group = getCurrentGroup();
TQString *p_data=new TQString(szValue);
p_group->replace(szKey,p_data);
}
// FIXME: #warning "We have probs here ?"
TQString KviConfig::readEntry(const TQString & szKey,const TQString & szDefault)
{
KviConfigGroup * p_group = getCurrentGroup();
TQString * p_str = p_group->find(szKey);
if(!p_str)
{
m_szStrBuffer = szDefault;
} else {
m_szStrBuffer = *p_str;
}
return m_szStrBuffer;
}
//////////////////////////////////// TQString
/*
TQString KviConfig::readTQStringEntry(const char *szKey,const TQString &szDefault)
{
KviStrDict * p_group = getCurrentGroup();
KviStr * p_str = p_group->find(szKey);
if(!p_str)return szDefault;
return TQString::fromUtf8(p_str->ptr());
}
*/
/*
void KviConfig::writeEntry(const char *szKey,const TQString &szValue)
{
m_bDirty = true;
KviStrDict * p_group = getCurrentGroup();
p_group->replace(szKey,new KviStr(szValue.utf8().data()));
}
*/
////////////////////////////////// TQStringList
static TQString g_szConfigStringListSeparator(",\\[ITEM],");
TQStringList KviConfig::readStringListEntry(const TQString & szKey,const TQStringList &list)
{
KviConfigGroup * p_group = getCurrentGroup();
TQString * p_str = p_group->find(szKey);
if(!p_str)return list;
#ifdef COMPILE_USE_QT4
return p_str->split(g_szConfigStringListSeparator);
#else
return TQStringList::split(g_szConfigStringListSeparator,*p_str);
#endif
}
void KviConfig::writeEntry(const TQString & szKey,const TQStringList &list)
{
m_bDirty = true;
KviConfigGroup * p_group = getCurrentGroup();
TQString *p_data=new TQString(list.join(g_szConfigStringListSeparator));
p_group->replace(szKey,p_data);
}
////////////////////////////////// KviValueList<int>
KviValueList<int> KviConfig::readIntListEntry(const TQString & szKey,const KviValueList<int> &list)
{
KviConfigGroup * p_group = getCurrentGroup();
TQString * 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
TQStringList sl = p_str->split(",");
#else
TQStringList sl = TQStringList::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(TQStringList::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 TQString & 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 TQString(szData.ptr()));
}
////////////////////////////////// KviPixmap
// FIXME: #warning "Spaces in image names ?"
void KviConfig::writeEntry(const TQString & szKey,const KviPixmap &pixmap)
{
m_bDirty = true;
KviConfigGroup * p_group = getCurrentGroup();
TQString *p_data=new TQString();
KviStringConversion::toString(pixmap,*p_data);
p_group->replace(szKey,p_data);
}
KviPixmap KviConfig::readPixmapEntry(const TQString & szKey,const KviPixmap &pixDef)
{
KviConfigGroup * p_group = getCurrentGroup();
TQString * 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 TQString & szKey,const KviMsgType &msg)
{
m_bDirty = true;
KviConfigGroup * p_group = getCurrentGroup();
TQString szData;
KviStringConversion::toString(msg,szData);
p_group->replace(szKey,new TQString(szData));
}
KviMsgType KviConfig::readMsgTypeEntry(const TQString & szKey,const KviMsgType &msgDef)
{
KviConfigGroup * p_group = getCurrentGroup();
TQString * p_str = p_group->find(szKey);
if(!p_str)return msgDef;
KviMsgType ret = msgDef;
KviStringConversion::fromString(*p_str,ret);
return ret;
}
////////////////////////////////// TQColor
void KviConfig::writeEntry(const TQString & szKey,const TQColor &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 TQString(szData.ptr()));
}
TQColor KviConfig::readColorEntry(const TQString & szKey,const TQColor &clr)
{
KviConfigGroup * p_group = getCurrentGroup();
TQColor color(clr);
TQString * 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;
}
////////////////////////////////// TQFont
void KviConfig::getFontProperties(KviStr & buffer,TQFont *fnt)
{
TQString tmp;
KviStringConversion::toString(*fnt,tmp);
buffer = tmp;
}
void KviConfig::writeEntry(const TQString & szKey,TQFont &fnt)
{
m_bDirty = true;
KviConfigGroup * p_group = getCurrentGroup();
TQString *p_data = new TQString();
KviStringConversion::toString(fnt,*p_data);
p_group->replace(szKey,p_data);
}
void KviConfig::setFontProperties(KviStr & str,TQFont *fnt)
{
KviStringConversion::fromString(str.ptr(),*fnt);
}
TQFont KviConfig::readFontEntry(const TQString & szKey,const TQFont &fnt)
{
TQFont font(fnt);
KviConfigGroup * p_group = getCurrentGroup();
TQString * 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 TQString & szKey,bool bTrue)
{
m_bDirty = true;
KviConfigGroup * p_group = getCurrentGroup();
TQString *p_data = new TQString(bTrue ? "true" : "false");
p_group->replace(szKey,p_data);
}
bool KviConfig::readBoolEntry(const TQString & szKey,bool bTrue)
{
KviConfigGroup * p_group = getCurrentGroup();
TQString * p_str = p_group->find(szKey);
if(!p_str)return bTrue;
static TQString szTrue = "true";
return (KviTQString::toLower(*p_str) == szTrue);
}
////////////////////////////////// TQRect
void KviConfig::writeEntry(const TQString & szKey,const TQRect &rct)
{
m_bDirty = true;
KviConfigGroup * p_group = getCurrentGroup();
TQString szBuf;
KviStringConversion::toString(rct,szBuf);
p_group->replace(szKey,new TQString(szBuf));
}
TQRect KviConfig::readRectEntry(const TQString & szKey,const TQRect &rct)
{
KviConfigGroup * p_group = getCurrentGroup();
TQString * str = p_group->find(szKey);
if(!str)return rct;
TQRect ret;
return KviStringConversion::fromString(*str,ret) ? ret : rct;
}
////////////////////////////////// unsigned short
void KviConfig::writeEntry(const TQString & szKey,unsigned short usValue)
{
m_bDirty = true;
KviConfigGroup * p_group = getCurrentGroup();
TQString *p_data = new TQString();
p_data->setNum(usValue);
p_group->replace(szKey,p_data);
}
unsigned short int KviConfig::readUShortEntry(const TQString & szKey,unsigned short int usDefault)
{
KviConfigGroup * p_group = getCurrentGroup();
TQString * 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 TQString & szKey,int iValue)
{
m_bDirty = true;
KviConfigGroup * p_group = getCurrentGroup();
TQString *p_data = new TQString();
p_data->setNum(iValue);
p_group->replace(szKey,p_data);
}
int KviConfig::readIntEntry(const TQString & szKey,int iDefault)
{
KviConfigGroup * p_group = getCurrentGroup();
TQString * 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 TQString & szKey,unsigned int iValue)
{
m_bDirty = true;
KviConfigGroup * p_group = getCurrentGroup();
TQString *p_data = new TQString();
p_data->setNum(iValue);
p_group->replace(szKey,p_data);
}
unsigned int KviConfig::readUIntEntry(const TQString & szKey,unsigned int iDefault)
{
KviConfigGroup * p_group = getCurrentGroup();
TQString * 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 TQString & szKey,char iValue)
{
m_bDirty = true;
KviConfigGroup * p_group = getCurrentGroup();
TQString * p_data = new TQString();
p_data->setNum(iValue);
p_group->replace(szKey,p_data);
}
char KviConfig::readCharEntry(const TQString & szKey,char iDefault)
{
KviConfigGroup * p_group = getCurrentGroup();
TQString * 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 TQString & szKey,unsigned char iValue)
{
m_bDirty = true;
KviConfigGroup * p_group = getCurrentGroup();
TQString *p_data = new TQString();
p_data->setNum(iValue);
p_group->replace(szKey,p_data);
}
unsigned char KviConfig::readUCharEntry(const TQString & szKey,unsigned char iDefault)
{
KviConfigGroup * p_group = getCurrentGroup();
TQString * 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