ktimezones.cpp
/*
This file is part of the KDE libraries
Copyright (c) 2005 S.R.Haque <srhaque@iee.org>.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License version 2 as published by the Free Software Foundation.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include <config.h>
#include <ktimezones.h>
#include <kdebug.h>
#include <kmdcodec.h>
#include <kprocess.h>
#include <kstringhandler.h>
#include <ktempfile.h>
#include <qdatetime.h>
#include <qfile.h>
#include <qregexp.h>
#include <qstringlist.h>
#include <qtextstream.h>
#include <cerrno>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <ctime>
#define UTC_ZONE "UTC"
class AbbreviationsMatch :
public KTimezoneDetails
{
public:
AbbreviationsMatch(const QString &stdZone, const QString &dstZone = "")
{
m_stdZone = stdZone;
m_dstZone = dstZone;
}
void parseStarted()
{
m_foundStd = false;
m_foundDst = m_dstZone.isEmpty();
}
bool test()
{
return (m_foundStd && m_foundDst);
}
private:
bool m_foundStd;
bool m_foundDst;
QString m_stdZone;
QString m_dstZone;
virtual void gotAbbreviation(int /*index*/, const QString &value)
{
if (m_stdZone == value)
{
m_foundStd = true;
}
if (m_dstZone == value)
{
m_foundDst = true;
}
}
};
class DummySource :
public KTimezoneSource
{
public:
DummySource() :
KTimezoneSource("")
{
}
virtual bool parse(const QString &/*zone*/, KTimezoneDetails &/*dataReceiver*/) const
{
return true;
}
};
class OffsetFind :
public KTimezoneDetails
{
public:
OffsetFind(unsigned dateTime)
{
m_dateTime = dateTime;
}
void parseStarted()
{
m_transitionTimeIndex = 0;
m_localTimeIndex = -1;
m_abbrIndex = -1;
m_offset = 0;
m_isDst = false;
m_abbr = UTC_ZONE;
}
int offset()
{
return m_offset;
}
bool isDst()
{
return m_isDst;
}
QString abbreviation()
{
return m_abbr;
}
private:
unsigned m_dateTime;
int m_transitionTimeIndex;
int m_localTimeIndex;
int m_abbrIndex;
int m_offset;
bool m_isDst;
QString m_abbr;
virtual void gotTransitionTime(int index, unsigned transitionTime)
{
if (transitionTime <= m_dateTime)
{
// Remember the index of the transition time that relates to dateTime.
m_transitionTimeIndex = index;
}
}
virtual void gotLocalTimeIndex(int index, unsigned localTimeIndex)
{
if (index == m_transitionTimeIndex)
{
// Remember the index of the local time that relates to dateTime.
m_localTimeIndex = localTimeIndex;
}
}
virtual void gotLocalTime(int index, int gmtOff, bool isDst, unsigned abbrInd)
{
if (index == m_localTimeIndex)
{
// Remember the results that relate to gmtOffset.
m_offset = gmtOff;
m_isDst = isDst;
m_abbrIndex = abbrInd;
}
}
virtual void gotAbbreviation(int index, const QString &value)
{
if (index == m_abbrIndex)
{
m_abbr = value;
}
}
};
const float KTimezone::UNKNOWN = 1000.0;
bool KTimezone::isValidLatitude(float latitude)
{
return (latitude >= -90.0) && (latitude <= 90.0);
}
bool KTimezone::isValidLongitude(float longitude)
{
return (longitude >= -180.0) && (longitude <= 180.0);
}
KTimezone::KTimezone(
KSharedPtr<KTimezoneSource> db, const QString& name,
const QString &countryCode, float latitude, float longitude,
const QString &comment) :
m_db(db),
m_name(name),
m_countryCode(countryCode),
m_latitude(latitude),
m_longitude(longitude),
m_comment(comment),
d(0)
{
// Detect duff values.
if (m_latitude * m_latitude > 90 * 90)
m_latitude = UNKNOWN;
if (m_longitude * m_longitude > 180 * 180)
m_longitude = UNKNOWN;
}
KTimezone::~KTimezone()
{
// FIXME when needed:
// delete d;
}
QString KTimezone::comment() const
{
return m_comment;
}
QDateTime KTimezone::convert(const KTimezone *newZone, const QDateTime &dateTime) const
{
char *originalZone = ::getenv("TZ");
// Convert the given localtime to UTC.
::setenv("TZ", m_name.utf8(), 1);
tzset();
unsigned utc = dateTime.toTime_t();
// Set the timezone and convert UTC to localtime.
::setenv("TZ", newZone->name().utf8(), 1);
tzset();
QDateTime remoteTime;
remoteTime.setTime_t(utc, Qt::LocalTime);
// Now restore things
if (!originalZone)
{
::unsetenv("TZ");
}
else
{
::setenv("TZ", originalZone, 1);
}
tzset();
return remoteTime;
}
QString KTimezone::countryCode() const
{
return m_countryCode;
}
float KTimezone::latitude() const
{
return m_latitude;
}
float KTimezone::longitude() const
{
return m_longitude;
}
QString KTimezone::name() const
{
return m_name;
}
int KTimezone::offset(Qt::TimeSpec basisSpec) const
{
char *originalZone = ::getenv("TZ");
// Get the time in the current timezone.
QDateTime basisTime = QDateTime::currentDateTime(basisSpec);
// Set the timezone and find out what time it is there compared to the basis.
::setenv("TZ", m_name.utf8(), 1);
tzset();
QDateTime remoteTime = QDateTime::currentDateTime(Qt::LocalTime);
int offset = remoteTime.secsTo(basisTime);
// Now restore things
if (!originalZone)
{
::unsetenv("TZ");
}
else
{
::setenv("TZ", originalZone, 1);
}
tzset();
return offset;
}
int KTimezone::offset(const QDateTime &dateTime) const
{
OffsetFind finder(dateTime.toTime_t());
int result = 0;
if (parse(finder))
{
result = finder.offset();
}
return result;
}
bool KTimezone::parse(KTimezoneDetails &dataReceiver) const
{
dataReceiver.parseStarted();
bool result = m_db->parse(m_name, dataReceiver);
dataReceiver.parseEnded();
return result;
}
KTimezones::KTimezones() :
m_zoneinfoDir(),
m_zones(0),
d(0)
{
// Create the database (and resolve m_zoneinfoDir!).
allZones();
m_UTC = new KTimezone(new DummySource(), UTC_ZONE);
add(m_UTC);
}
KTimezones::~KTimezones()
{
// FIXME when needed:
// delete d;
// Autodelete behavior.
if (m_zones)
{
for (ZoneMap::ConstIterator it = m_zones->begin(); it != m_zones->end(); ++it)
{
delete it.data();
}
}
delete m_zones;
}
void KTimezones::add(KTimezone *zone)
{
m_zones->insert(zone->name(), zone);
}
const KTimezones::ZoneMap KTimezones::allZones()
{
// Have we already done all the hard work? If not, create the cache.
if (m_zones)
return *m_zones;
m_zones = new ZoneMap();
// Go read the database.
//
// On Windows, HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones
// is the place to look. The TZI binary value is the TIME_ZONE_INFORMATION structure.
//
// For Unix its all easy except knowing where to look. Try the LSB location first.
QFile f;
m_zoneinfoDir = "/usr/share/zoneinfo";
f.setName(m_zoneinfoDir + "/zone.tab");
if (!f.open(IO_ReadOnly))
{
kdDebug() << "Can't open " << f.name() << endl;
m_zoneinfoDir = "/usr/lib/zoneinfo";
f.setName(m_zoneinfoDir + "/zone.tab");
if (!f.open(IO_ReadOnly))
{
kdDebug() << "Can't open " << f.name() << endl;
m_zoneinfoDir = ::getenv("TZDIR");
f.setName(m_zoneinfoDir + "/zone.tab");
if (m_zoneinfoDir.isEmpty() || !f.open(IO_ReadOnly))
{
kdDebug() << "Can't open " << f.name() << endl;
// Solaris support. Synthesise something that looks like a zone.tab.
//
// /bin/grep -h ^Zone /usr/share/lib/zoneinfo/src/* | /bin/awk '{print "??\t+9999+99999\t" $2}'
//
// where the country code is set to "??" and the lattitude/longitude
// values are dummies.
m_zoneinfoDir = "/usr/share/lib/zoneinfo";
KTempFile temp;
KShellProcess reader;
reader << "/bin/grep" << "-h" << "^Zone" << m_zoneinfoDir << "/src/*" << temp.name() << "|" <<
"/bin/awk" << "'{print \"??\\t+9999+99999\\t\" $2}'";
// Note the use of blocking here...it is a trivial amount of data!
temp.close();
reader.start(KProcess::Block);
f.setName(temp.name());
if (!temp.status() || !f.open(IO_ReadOnly))
{
kdDebug() << "Can't open " << f.name() << endl;
return *m_zones;
}
}
}
}
// Parse the zone.tab.
QTextStream str(&f);
QRegExp lineSeparator("[ \t]");
QRegExp ordinateSeparator("[+-]");
KSharedPtr<KTimezoneSource> db(new KTimezoneSource(m_zoneinfoDir));
while (!str.atEnd())
{
QString line = str.readLine();
if (line.isEmpty() || '#' == line[0])
continue;
QStringList tokens = KStringHandler::perlSplit(lineSeparator, line, 4);
if (tokens.count() < 3)
{
kdError() << "invalid record: " << line << endl;
continue;
}
// Got three tokens. Now check for two ordinates plus first one is "".
QStringList ordinates = KStringHandler::perlSplit(ordinateSeparator, tokens[1], 2);
if (ordinates.count() < 2)
{
kdError() << "invalid coordinates: " << tokens[1] << endl;
continue;
}
float latitude = convertCoordinate(ordinates[1]);
float longitude = convertCoordinate(ordinates[2]);
// Add entry to list.
if (tokens[0] == "??")
tokens[0] = "";
KTimezone *timezone = new KTimezone(db, tokens[2], tokens[0], latitude, longitude, tokens[3]);
add(timezone);
}
f.close();
return *m_zones;
}
float KTimezones::convertCoordinate(const QString &coordinate)
{
int value = coordinate.toInt();
int degrees = 0;
int minutes = 0;
int seconds = 0;
if (coordinate.length() > 11)
{
degrees = value / 10000;
value -= degrees * 10000;
minutes = value / 100;
value -= minutes * 100;
seconds = value;
}
else
{
degrees = value / 100;
value -= degrees * 100;
minutes = value;
}
value = degrees * 3600 + minutes * 60 + seconds;
return value / 3600.0;
}
const KTimezone *KTimezones::local()
{
const KTimezone *local = 0;
// First try the simplest solution of checking for well-formed TZ setting.
char *envZone = ::getenv("TZ");
if (envZone)
{
if (envZone[0] == '\0')
{
return m_UTC;
}
else
if (envZone[0] == ':')
{
envZone++;
}
local = zone(envZone);
}
if (local)
return local;
// Try to match /etc/localtime against the list of zoneinfo files.
QFile f;
f.setName("/etc/localtime");
if (f.open(IO_ReadOnly))
{
// Compute the MD5 sum of /etc/localtime.
KMD5 context("");
context.reset();
context.update(f);
QIODevice::Offset referenceSize = f.size();
QString referenceMd5Sum = context.hexDigest();
f.close();
if (!m_zoneinfoDir.isEmpty())
{
// Compare it with each zoneinfo file.
for (ZoneMap::Iterator it = m_zones->begin(); it != m_zones->end(); ++it)
{
KTimezone *zone = it.data();
f.setName(m_zoneinfoDir + '/' + zone->name());
if (f.open(IO_ReadOnly))
{
QIODevice::Offset candidateSize = f.size();
QString candidateMd5Sum;
if (candidateSize == referenceSize)
{
// Only do the heavy lifting for file sizes which match.
context.reset();
context.update(f);
candidateMd5Sum = context.hexDigest();
}
f.close();
if (candidateMd5Sum == referenceMd5Sum)
{
// kdError() << "local=" << zone->name() << endl;
local = zone;
break;
}
}
}
}
}
if (local)
return local;
// BSD support.
QString fileZone;
f.setName("/etc/timezone");
if (!f.open(IO_ReadOnly))
{
kdDebug() << "Can't open " << f.name() << endl;
// Solaris support using /etc/default/init.
f.setName("/etc/default/init");
if (!f.open(IO_ReadOnly))
{
kdDebug() << "Can't open " << f.name() << endl;
}
else
{
QTextStream ts(&f);
ts.setEncoding(QTextStream::Latin1);
// Read the last line starting "TZ=".
while (!ts.atEnd())
{
fileZone = ts.readLine();
if (fileZone.startsWith("TZ="))
{
fileZone = fileZone.mid(3);
// kdError() << "local=" << fileZone << endl;
local = zone(fileZone);
}
}
f.close();
}
}
else
{
QTextStream ts(&f);
ts.setEncoding(QTextStream::Latin1);
// Read the first line.
if (!ts.atEnd())
{
fileZone = ts.readLine();
// kdError() << "local=" << fileZone << endl;
local = zone(fileZone);
}
f.close();
}
if (local)
return local;
// None of the deterministic stuff above has worked: try a heuristic. We
// try to find a pair of matching timezone abbreviations...that way, we'll
// likely return a value in the user's own country.
if (!m_zoneinfoDir.isEmpty())
{
tzset();
AbbreviationsMatch matcher(tzname[0], tzname[1]);
int bestOffset = INT_MAX;
for (ZoneMap::Iterator it = m_zones->begin(); it != m_zones->end(); ++it)
{
KTimezone *zone = it.data();
int candidateOffset = QABS(zone->offset(Qt::LocalTime));
if (zone->parse(matcher) && matcher.test() && (candidateOffset < bestOffset))
{
// kdError() << "local=" << zone->name() << endl;
bestOffset = candidateOffset;
local = zone;
}
}
}
if (local)
return local;
return m_UTC;
}
const KTimezone *KTimezones::zone(const QString &name)
{
if (name.isEmpty())
return m_UTC;
ZoneMap::ConstIterator it = m_zones->find(name);
if (it != m_zones->end())
return it.data();
// Error.
return 0;
}
KTimezoneDetails::KTimezoneDetails()
{
}
KTimezoneDetails::~KTimezoneDetails()
{
}
void KTimezoneDetails::gotAbbreviation(int /*index*/, const QString &)
{}
void KTimezoneDetails::gotHeader(
unsigned, unsigned, unsigned,
unsigned, unsigned, unsigned)
{}
void KTimezoneDetails::gotLeapAdjustment(int /*index*/, unsigned, unsigned)
{}
void KTimezoneDetails::gotLocalTime(int /*index*/, int, bool, unsigned)
{}
void KTimezoneDetails::gotLocalTimeIndex(int /*index*/, unsigned)
{}
void KTimezoneDetails::gotIsStandard(int /*index*/, bool)
{}
void KTimezoneDetails::gotTransitionTime(int /*index*/, unsigned)
{}
void KTimezoneDetails::gotIsUTC(int /*index*/, bool)
{}
void KTimezoneDetails::parseEnded()
{}
void KTimezoneDetails::parseStarted()
{}
KTimezoneSource::KTimezoneSource(const QString &db) :
m_db(db)
{
}
KTimezoneSource::~KTimezoneSource()
{
}
QString KTimezoneSource::db()
{
return m_db;
}
bool KTimezoneSource::parse(const QString &zone, KTimezoneDetails &dataReceiver) const
{
QFile f(m_db + '/' + zone);
if (!f.open(IO_ReadOnly))
{
kdError() << "Cannot open " << f.name() << endl;
return false;
}
// Structures that represent the zoneinfo file.
Q_UINT8 T, z, i_, f_;
struct
{
Q_UINT32 ttisgmtcnt;
Q_UINT32 ttisstdcnt;
Q_UINT32 leapcnt;
Q_UINT32 timecnt;
Q_UINT32 typecnt;
Q_UINT32 charcnt;
} tzh;
Q_UINT32 transitionTime;
Q_UINT8 localTimeIndex;
struct
{
Q_INT32 gmtoff;
Q_INT8 isdst;
Q_UINT8 abbrind;
} tt;
Q_UINT32 leapTime;
Q_UINT32 leapSeconds;
Q_UINT8 isStandard;
Q_UINT8 isUTC;
QDataStream str(&f);
str >> T >> z >> i_ >> f_;
// kdError() << "signature: " << QChar(T) << QChar(z) << QChar(i_) << QChar(f_) << endl;
unsigned i;
for (i = 0; i < 4; i++)
str >> tzh.ttisgmtcnt;
str >> tzh.ttisgmtcnt >> tzh.ttisstdcnt >> tzh.leapcnt >> tzh.timecnt >> tzh.typecnt >> tzh.charcnt;
// kdError() << "header: " << tzh.ttisgmtcnt << ", " << tzh.ttisstdcnt << ", " << tzh.leapcnt << ", " <<
// tzh.timecnt << ", " << tzh.typecnt << ", " << tzh.charcnt << endl;
dataReceiver.gotHeader(tzh.ttisgmtcnt, tzh.ttisstdcnt, tzh.leapcnt, tzh.timecnt, tzh.typecnt, tzh.charcnt);
for (i = 0; i < tzh.timecnt; i++)
{
str >> transitionTime;
dataReceiver.gotTransitionTime(i, transitionTime);
}
for (i = 0; i < tzh.timecnt; i++)
{
// NB: these appear to be 1-based, not zero-based!
str >> localTimeIndex;
dataReceiver.gotLocalTimeIndex(i, localTimeIndex);
}
for (i = 0; i < tzh.typecnt; i++)
{
str >> tt.gmtoff >> tt.isdst >> tt.abbrind;
// kdError() << "local type: " << tt.gmtoff << ", " << tt.isdst << ", " << tt.abbrind << endl;
dataReceiver.gotLocalTime(i, tt.gmtoff, (tt.isdst != 0), tt.abbrind);
}
// Make sure we don't run foul of maliciously coded timezone abbreviations.
if (tzh.charcnt > 64)
{
kdError() << "excessive length for timezone abbreviations: " << tzh.charcnt << endl;
return false;
}
QByteArray array(tzh.charcnt);
str.readRawBytes(array.data(), array.size());
char *abbrs = array.data();
if (abbrs[tzh.charcnt - 1] != 0)
{
// These abbrevations are corrupt!
kdError() << "timezone abbreviations not terminated: " << abbrs[tzh.charcnt - 1] << endl;
return false;
}
char *abbr = abbrs;
while (abbr < abbrs + tzh.charcnt)
{
// kdError() << "abbr: " << abbr << endl;
dataReceiver.gotAbbreviation((abbr - abbrs), abbr);
abbr += strlen(abbr) + 1;
}
for (i = 0; i < tzh.leapcnt; i++)
{
str >> leapTime >> leapSeconds;
// kdError() << "leap entry: " << leapTime << ", " << leapSeconds << endl;
dataReceiver.gotLeapAdjustment(i, leapTime, leapSeconds);
}
for (i = 0; i < tzh.ttisstdcnt; i++)
{
str >> isStandard;
// kdError() << "standard: " << isStandard << endl;
dataReceiver.gotIsStandard(i, (isStandard != 0));
}
for (i = 0; i < tzh.ttisgmtcnt; i++)
{
str >> isUTC;
// kdError() << "UTC: " << isUTC << endl;
dataReceiver.gotIsUTC(i, (isUTC != 0));
}
return true;
}
KSharedPtr< KTimezoneSource >
KTimezoneDetails::gotLocalTimeIndex
virtual void gotLocalTimeIndex(int index, unsigned localTimeIndex)
Called when a local time index is seen.
Definition: ktimezones.cpp:656
KTimezoneDetails::parseStarted
virtual void parseStarted()
Always called before any other callback.
Definition: ktimezones.cpp:671
KTimezone::isValidLongitude
static bool isValidLongitude(float longitude)
A test for a valid longitude.
Definition: ktimezones.cpp:200
KShellProcess
A class derived from KProcess to start child processes through a shell.
Definition: kprocess.h:899
KTimezoneDetails::gotIsStandard
virtual void gotIsStandard(int index, bool isStandard)
Called when a standard/wall time indicator is seen.
Definition: ktimezones.cpp:659
KTimezone
The KTimezone class contains core functions related to a timezone.
Definition: ktimezones.h:85
KTimezone::isValidLatitude
static bool isValidLatitude(float latitude)
A test for a valid latitude.
Definition: ktimezones.cpp:195
KTimezoneDetails::parseEnded
virtual void parseEnded()
Always called after all other callbacks.
Definition: ktimezones.cpp:668
KTimezone::name
QString name() const
Returns the name of the timezone.
Definition: ktimezones.cpp:278
KTimezone::KTimezone
KTimezone(KSharedPtr< KTimezoneSource > db, const QString &name, const QString &countryCode=QString(), float latitude=UNKNOWN, float longitude=UNKNOWN, const QString &comment=QString())
Create a timezone.
Definition: ktimezones.cpp:205
KTimezoneSource
The KTimezoneSource class contains information source-dependent functions related to a timezone...
Definition: ktimezones.h:51
KTimezoneSource::parse
virtual bool parse(const QString &zone, KTimezoneDetails &dataReceiver) const
Extract timezone detail information.
Definition: ktimezones.cpp:688
KTimezoneDetails::gotIsUTC
virtual void gotIsUTC(int index, bool isUTC)
Called when a UTC/local time indicator is seen.
Definition: ktimezones.cpp:665
KTimezone::convert
QDateTime convert(const KTimezone *newZone, const QDateTime &dateTime) const
Convert a date/time (which is interpreted as being localtime in this timezone) into localtime in the ...
Definition: ktimezones.cpp:235
KTimezoneDetails::gotLeapAdjustment
virtual void gotLeapAdjustment(int index, unsigned leapTime, unsigned leapSeconds)
Called when a leap second adjustment is seen.
Definition: ktimezones.cpp:650
KTimezones::local
const KTimezone * local()
Returns the local timezone.
Definition: ktimezones.cpp:480
KMD5::hexDigest
QCString hexDigest()
Returns the value of the calculated message digest in a hexadecimal representation.
Definition: kmdcodec.cpp:902
KMD5::update
void update(const char *in, int len=-1)
Updates the message to be digested.
Definition: kmdcodec.h:442
KTimezoneDetails::gotLocalTime
virtual void gotLocalTime(int index, int gmtOff, bool isDst, unsigned abbrIndex)
Called when a local time is seen.
Definition: ktimezones.cpp:653
KTimezone::latitude
float latitude() const
Returns the latitude of the timezone.
Definition: ktimezones.cpp:268
KTimezones::allZones
const ZoneMap allZones()
Return timezone database.
Definition: ktimezones.cpp:360
KShellProcess::start
virtual bool start(RunMode runmode=NotifyOnExit, Communication comm=NoCommunication)
Starts the process.
Definition: kprocess.cpp:1129
KTimezone::UNKNOWN
static const float UNKNOWN
A representation for unknown locations; this is a float that does not represent a real latitude or lo...
Definition: ktimezones.h:92
KTempFile
The KTempFile class creates and opens a unique file for temporary use.
Definition: ktempfile.h:55
KTimezone::longitude
float longitude() const
Returns the latitude of the timezone.
Definition: ktimezones.cpp:273
KMD5
An adapted C++ implementation of RSA Data Securities MD5 algorithm.
Definition: kmdcodec.h:402
KTimezone::countryCode
QString countryCode() const
Returns the two-letter country code of the timezone.
Definition: ktimezones.cpp:263
KTimezone::offset
int offset(Qt::TimeSpec basisSpec=Qt::UTC) const
Returns the current offset of this timezone to UTC or the local timezone in seconds.
Definition: ktimezones.cpp:283
KTimezoneDetails::gotHeader
virtual void gotHeader(unsigned ttIsGmtCnt, unsigned ttIsStdCnt, unsigned leapCnt, unsigned timeCnt, unsigned typeCnt, unsigned charCnt)
Called when the header is seen.
Definition: ktimezones.cpp:645
KTimezone::comment
QString comment() const
Returns any comment for the timezone.
Definition: ktimezones.cpp:230
KTimezone::parse
bool parse(KTimezoneDetails &dataReceiver) const
Extract timezone detail information.
Definition: ktimezones.cpp:320
KProcess::Block
The application is suspended until the started process is finished.
Definition: kprocess.h:177
KTimezoneSource::db
virtual QString db()
Location of system timezone information.
Definition: ktimezones.cpp:683
KTempFile::close
bool close()
Closes the file.
Definition: ktempfile.cpp:253
KTempFile::status
int status() const
Returns the status of the file based on errno.
Definition: ktempfile.cpp:137
KMD5::reset
void reset()
Calling this function will reset the calculated message digest.
Definition: kmdcodec.cpp:941
KTimezoneDetails::gotAbbreviation
virtual void gotAbbreviation(int index, const QString &abbr)
Called when a timezone abbreviation is seen.
Definition: ktimezones.cpp:642
endl
kndbgstream & endl(kndbgstream &s)
Does nothing.
Definition: kdebug.h:583
KTimezones::zone
const KTimezone * zone(const QString &name)
Returns the given timezone.
Definition: ktimezones.cpp:622
KTempFile::name
QString name() const
Returns the full path and name of the file.
Definition: ktempfile.cpp:143
KTimezoneDetails
The KTimezoneDetails class contains extended functions related to a timezone.
Definition: ktimezones.h:225
KTimezoneDetails::gotTransitionTime
virtual void gotTransitionTime(int index, unsigned transitionTime)
Called when a transition time is seen.
Definition: ktimezones.cpp:662
KTimezones::add
void add(KTimezone *zone)
Add user-defined timezone to database.
Definition: ktimezones.cpp:355
KStringHandler::perlSplit
static QStringList perlSplit(const QString &sep, const QString &s, uint max=0)
Split a QString into a QStringList in a similar fashion to the static QStringList function in Qt...
Definition: kstringhandler.cpp:452

KDE Home | KDE Accessibility Home | Description of Access Keys