generic: remove ktimezoned and adjust to KSystemTimeZones changes

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
Ivailo Monev 2022-10-01 12:21:35 +03:00
parent 024911099f
commit 4bcf576d6d
11 changed files with 90 additions and 972 deletions

View file

@ -356,7 +356,6 @@ add_subdirectory(konsole)
# Background processes
add_subdirectory(kdontchangethehostname)
add_subdirectory(kglobalaccel)
add_subdirectory(ktimezoned)
# Command-line tools (e.g. for shell scripts)
add_subdirectory(kdeeject)
add_subdirectory(kfile)

View file

@ -33,6 +33,7 @@
#include <kmessagebox.h>
#include <kstandarddirs.h>
#include <kauthorization.h>
#include <ksystemtimezone.h>
#include "moc_main.cpp"
@ -46,76 +47,84 @@ K_EXPORT_PLUGIN(KlockModuleFactory("kcmkclock"))
KclockModule::KclockModule(QWidget *parent, const QVariantList &)
: KCModule(KlockModuleFactory::componentData(), parent/*, name*/)
{
KAboutData *about =
new KAboutData(I18N_NOOP("kcmclock"), 0, ki18n("KDE Clock Control Module"),
0, KLocalizedString(), KAboutData::License_GPL,
ki18n("(c) 1996 - 2001 Luca Montecchiani\n"
"(c) 2014 Ivailo Monev"));
KAboutData *about =
new KAboutData(I18N_NOOP("kcmclock"), 0, ki18n("KDE Clock Control Module"),
0, KLocalizedString(), KAboutData::License_GPL,
ki18n("(c) 1996 - 2001 Luca Montecchiani\n(c) 2014 Ivailo Monev"));
about->addAuthor(ki18n("Luca Montecchiani"), ki18n("Original author"), "m.luca@usa.net");
about->addAuthor(ki18n("Paul Campbell"), ki18n("Past Maintainer"), "paul@taniwha.com");
about->addAuthor(ki18n("Benjamin Meyer"), ki18n("Added NTP support"), "ben+kcmclock@meyerhome.net");
about->addAuthor(ki18n("Ivailo Monev"), ki18n("Current Maintainer"), "xakepa10@gmail.com");
setAboutData( about );
setQuickHelp( i18n("<h1>Date & Time</h1> This control module can be used to set the system date and"
" time. As these settings do not only affect you as a user, but rather the whole system, you"
" can only change these settings when you start the System Settings as root. If you do not have"
" the root password, but feel the system time should be corrected, please contact your system"
" administrator."));
about->addAuthor(ki18n("Luca Montecchiani"), ki18n("Original author"), "m.luca@usa.net");
about->addAuthor(ki18n("Paul Campbell"), ki18n("Past Maintainer"), "paul@taniwha.com");
about->addAuthor(ki18n("Benjamin Meyer"), ki18n("Added NTP support"), "ben+kcmclock@meyerhome.net");
about->addAuthor(ki18n("Ivailo Monev"), ki18n("Current Maintainer"), "xakepa10@gmail.com");
setAboutData( about );
setQuickHelp( i18n("<h1>Date & Time</h1> This control module can be used to set the system date and"
" time. As these settings do not only affect you as a user, but rather the whole system, you"
" can only change these settings when you start the System Settings as root. If you do not have"
" the root password, but feel the system time should be corrected, please contact your system"
" administrator."));
KGlobal::locale()->insertCatalog("timezones4"); // For time zone translations
KGlobal::locale()->insertCatalog("timezones4"); // For time zone translations
QVBoxLayout *layout = new QVBoxLayout(this);
layout->setMargin(0);
layout->setSpacing(KDialog::spacingHint());
QVBoxLayout *layout = new QVBoxLayout(this);
layout->setMargin(0);
layout->setSpacing(KDialog::spacingHint());
dtime = new Dtime(this);
layout->addWidget(dtime);
connect(dtime, SIGNAL(timeChanged(bool)), this, SIGNAL(changed(bool)));
dtime = new Dtime(this);
layout->addWidget(dtime);
connect(dtime, SIGNAL(timeChanged(bool)), this, SIGNAL(changed(bool)));
setButtons(Help|Apply);
setButtons(Help|Apply);
if (!KAuthorization::isAuthorized("org.kde.kcontrol.kcmclock")) {
setUseRootOnlyMessage(true);
setRootOnlyMessage(i18n("You are not allowed to save the configuration"));
}
if (!KAuthorization::isAuthorized("org.kde.kcontrol.kcmclock")) {
setUseRootOnlyMessage(true);
setRootOnlyMessage(i18n("You are not allowed to save the configuration"));
}
m_tz = KSystemTimeZones::local().name();
QTimer::singleShot(3000, this, SLOT(checkTZ()));
}
void KclockModule::save()
{
setDisabled(true);
setDisabled(true);
QVariantMap helperargs;
dtime->save( helperargs );
QVariantMap helperargs;
dtime->save( helperargs );
int reply = KAuthorization::execute(
"org.kde.kcontrol.kcmclock", "save", helperargs
);
int reply = KAuthorization::execute(
"org.kde.kcontrol.kcmclock", "save", helperargs
);
if (reply != KAuthorization::NoError) {
if (reply < KAuthorization::NoError) {
KMessageBox::error(this, i18n("Unable to authenticate/execute the action: %1", KAuthorization::errorString(reply)));
if (reply != KAuthorization::NoError) {
if (reply < KAuthorization::NoError) {
KMessageBox::error(this, i18n("Unable to authenticate/execute the action: %1", KAuthorization::errorString(reply)));
} else {
dtime->processHelperErrors(reply);
}
} else {
dtime->processHelperErrors(reply);
QDBusMessage msg = QDBusMessage::createSignal("/org/kde/kcmshell_clock", "org.kde.kcmshell_clock", "clockUpdated");
QDBusConnection::sessionBus().send(msg);
}
} else {
QDBusMessage msg = QDBusMessage::createSignal("/org/kde/kcmshell_clock", "org.kde.kcmshell_clock", "clockUpdated");
QDBusConnection::sessionBus().send(msg);
}
// NOTE: super nasty hack #1
// Try to work around time mismatch between KSystemTimeZones' update of local
// timezone and reloading of data, so that the new timezone is taken into account.
// The Ultimate solution to this would be if KSTZ emitted a signal when a new
// local timezone was found.
QTimer::singleShot(5000, this, SLOT(load()));
// setDisabled(false) happens in load(), since QTimer::singleShot is non-blocking
// setDisabled(false) happens in load()
}
void KclockModule::load()
{
dtime->load();
setDisabled(false);
dtime->load();
setDisabled(false);
emit changed(false);
}
void KclockModule::checkTZ()
{
const QString localtz = KSystemTimeZones::local().name();
if (localtz != m_tz) {
m_tz = localtz;
load();
}
QTimer::singleShot(1000, this, SLOT(checkTZ()));
}

View file

@ -21,24 +21,27 @@
#ifndef main_included
#define main_included
#include <QTabWidget>
#include <kcmodule.h>
class Dtime;
#include <QTabWidget>
class KclockModule : public KCModule
{
Q_OBJECT
Q_OBJECT
public:
KclockModule(QWidget *parent, const QVariantList &);
KclockModule(QWidget *parent, const QVariantList &);
void save();
void load();
void save();
void load();
protected Q_SLOTS:
void checkTZ();
private:
Dtime *dtime;
Dtime *dtime;
QString m_tz;
};
#endif // main_included

View file

@ -1,16 +0,0 @@
set(kded_ktimezoned_SRCS ktimezoned.cpp)
kde4_add_plugin(kded_ktimezoned ${kded_ktimezoned_SRCS})
#qt4_add_dbus_adaptor(kded_ktimezoned_SRCS org.kde.KTimeZoned ktimezonedbus.h DBusHandler)
target_link_libraries(kded_ktimezoned ${KDE4_KIO_LIBS})
install(TARGETS kded_ktimezoned DESTINATION ${KDE4_PLUGIN_INSTALL_DIR})
########### install files ###############
install( FILES ktimezoned.desktop DESTINATION ${KDE4_SERVICES_INSTALL_DIR}/kded )
install( FILES org.kde.KTimeZoned.xml DESTINATION ${KDE4_DBUS_INTERFACES_INSTALL_DIR} )

View file

@ -1,572 +0,0 @@
/*
This file is part of the KDE libraries
Copyright (c) 2005-2010 David Jarvie <djarvie@kde.org>
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 as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
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 "moc_ktimezoned.cpp"
#include "moc_ktimezonedbase.cpp"
#include <climits>
#include <cstdlib>
#include <QFile>
#include <QFileInfo>
#include <QDir>
#include <QRegExp>
#include <QStringList>
#include <QtDBus/QtDBus>
#include <kglobal.h>
#include <klocale.h>
#include <kstandarddirs.h>
#include <kstringhandler.h>
#include <ktemporaryfile.h>
#include <kdebug.h>
#include <kconfiggroup.h>
#include <kpluginfactory.h>
#include <kpluginloader.h>
K_PLUGIN_FACTORY(KTimeZonedFactory, registerPlugin<KTimeZoned>();)
K_EXPORT_PLUGIN(KTimeZonedFactory("ktimezoned"))
// The maximum allowed length for reading a zone.tab line. This is set to
// provide plenty of leeway, given that the maximum length of lines in a valid
// zone.tab will be around 100 - 120 characters.
const int MAX_ZONE_TAB_LINE_LENGTH = 2000;
// Config file entry names
const char ZONEINFO_DIR[] = "ZoneinfoDir"; // path to zoneinfo/ directory
const char ZONE_TAB[] = "Zonetab"; // path & name of zone.tab
const char LOCAL_ZONE[] = "LocalZone"; // name of local time zone
KTimeZoned::KTimeZoned(QObject* parent, const QList<QVariant>& l)
: KTimeZonedBase(parent, l),
mSource(0),
mZonetabWatch(0),
mPollWatch(0)
{
init(false);
}
KTimeZoned::~KTimeZoned()
{
delete mSource;
mSource = 0;
delete mZonetabWatch;
mZonetabWatch = 0;
delete mPollWatch;
mPollWatch = 0;
}
void KTimeZoned::init(bool restart)
{
if (restart)
{
kDebug(1221) << "KTimeZoned::init(restart)";
delete mSource;
mSource = 0;
delete mZonetabWatch;
mZonetabWatch = 0;
delete mPollWatch;
mPollWatch = 0;
}
KConfig config(QLatin1String("ktimezonedrc"));
if (restart)
config.reparseConfiguration();
KConfigGroup group(&config, "TimeZones");
mZoneinfoDir = QDir::cleanPath(group.readEntry(ZONEINFO_DIR));
mZoneTab = group.readEntry(ZONE_TAB);
mConfigLocalZone = group.readEntry(LOCAL_ZONE);
if (mZoneinfoDir.length() > 1 && mZoneinfoDir.endsWith('/'))
mZoneinfoDir.truncate(mZoneinfoDir.length() - 1); // strip trailing '/'
kDebug(1221) << ZONEINFO_DIR << mZoneinfoDir;
kDebug(1221) << ZONE_TAB << mZoneTab;
kDebug(1221) << LOCAL_ZONE << mConfigLocalZone;
// For Unix, read zone.tab.
QString oldZoneinfoDir = mZoneinfoDir;
QString oldZoneTab = mZoneTab;
// Open zone.tab if we already know where it is
QFile f;
if (!mZoneTab.isEmpty() && !mZoneinfoDir.isEmpty())
{
f.setFileName(mZoneTab);
if (!f.open(QIODevice::ReadOnly)) {
mZoneTab.clear();
}
}
if (mZoneTab.isEmpty() || mZoneinfoDir.isEmpty())
{
// Search for zone.tab
if (!findZoneTab(f))
return;
mZoneTab = f.fileName();
if (mZoneinfoDir != oldZoneinfoDir
|| mZoneTab != oldZoneTab)
{
// Update config file and notify interested applications
group.writeEntry(ZONEINFO_DIR, mZoneinfoDir);
group.writeEntry(ZONE_TAB, mZoneTab);
group.sync();
QDBusMessage message = QDBusMessage::createSignal("/Daemon", "org.kde.KTimeZoned", "configChanged");
QDBusConnection::sessionBus().send(message);
}
}
// Read zone.tab and create a collection of KTimeZone instances
readZoneTab(f);
mZonetabWatch = new KDirWatch(this);
mZonetabWatch->addFile(mZoneTab);
connect(mZonetabWatch, SIGNAL(dirty(const QString&)), SLOT(zonetab_Changed(const QString&)));
mPollWatch = new QTimer();
// NOTE: super nasty hack #2, see dateandtime KCM
mPollWatch->start(3000);
// Watch for changes in the file defining the local time zone so as to be
// notified of any change in it.
connect(mPollWatch, SIGNAL(timeout()), SLOT(localChanged()));
// Find the local system time zone and set up file monitors to detect changes
findLocalZone();
}
// Check if the local zone has been updated, and if so, write the new
// zone to the config file and notify interested parties.
void KTimeZoned::updateLocalZone()
{
if (mConfigLocalZone != mLocalZone)
{
KConfig config(QLatin1String("ktimezonedrc"));
KConfigGroup group(&config, "TimeZones");
mConfigLocalZone = mLocalZone;
group.writeEntry(LOCAL_ZONE, mConfigLocalZone);
group.sync();
QDBusMessage message = QDBusMessage::createSignal("/Daemon", "org.kde.KTimeZoned", "configChanged");
QDBusConnection::sessionBus().send(message);
}
}
/*
* Find the location of the zoneinfo files and store in mZoneinfoDir.
* Open or if necessary create zone.tab.
*/
bool KTimeZoned::findZoneTab(QFile& f)
{
// NOTE: keep in sync with kcontrol/dateandtime/helper.cpp
static const QStringList zoneDirs = QStringList()
<< QLatin1String("/share/zoneinfo")
<< QLatin1String("/lib/zoneinfo")
<< QLatin1String("/usr/share/zoneinfo")
<< QLatin1String("/usr/lib/zoneinfo")
<< QLatin1String("/usr/local/share/zoneinfo")
<< QLatin1String("/usr/local/lib/zoneinfo")
<< (KStandardDirs::installPath("kdedir") + QLatin1String("/share/zoneinfo"))
<< (KStandardDirs::installPath("kdedir") + QLatin1String("/lib/zoneinfo"));
QString ZONE_TAB_FILE = "/zone.tab";
// /usr is kind of standard
QString ZONE_INFO_DIR = "/usr/share/zoneinfo";
foreach (const QString &zonedir, zoneDirs) {
if (QDir(zonedir).exists()) {
ZONE_INFO_DIR = zonedir;
break;
}
}
// Find and open zone.tab - it's all easy except knowing where to look.
QDir dir;
QString zoneinfoDir = ZONE_INFO_DIR;
// make a note if the dir exists; whether it contains zone.tab or not
if (dir.exists(zoneinfoDir))
{
mZoneinfoDir = QDir::cleanPath(zoneinfoDir);
f.setFileName(mZoneinfoDir + ZONE_TAB_FILE);
if (f.open(QIODevice::ReadOnly))
return true;
kDebug(1221) << "Can't open " << f.fileName();
}
zoneinfoDir = ::getenv("TZDIR");
if (!zoneinfoDir.isEmpty() && dir.exists(zoneinfoDir))
{
mZoneinfoDir = QDir::cleanPath(zoneinfoDir);
f.setFileName(mZoneinfoDir + ZONE_TAB_FILE);
if (f.open(QIODevice::ReadOnly))
return true;
kDebug(1221) << "Can't open " << f.fileName();
}
return false;
}
// Parse zone.tab and for each time zone, create a KSystemTimeZone instance.
// Note that only data needed by this module is specified to KSystemTimeZone.
void KTimeZoned::readZoneTab(QFile &f)
{
// Parse the already open real or fake zone.tab.
QRegExp lineSeparator("[ \t]");
if (!mSource)
mSource = new KSystemTimeZoneSource;
mZones.clear();
while (!f.atEnd())
{
// Read the next line, but limit its length to guard against crashing
// due to a corrupt very large zone.tab (see KDE bug 224868).
const QByteArray line = f.readLine(MAX_ZONE_TAB_LINE_LENGTH).trimmed();
if (line.isEmpty() || line[0] == '#')
continue;
const QString lineStr = QString::fromLatin1(line.constData(), line.size());
QStringList tokens = KStringHandler::perlSplit(lineSeparator, lineStr, 4);
int n = tokens.count();
if (n < 3)
{
kError(1221) << "readZoneTab(): invalid record: " << line << endl;
continue;
}
// Add entry to list.
if (tokens[0] == "??")
tokens[0] = "";
else if (!tokens[0].isEmpty())
mHaveCountryCodes = true;
mZones.add(KSystemTimeZone(mSource, tokens[2], tokens[0]));
}
f.close();
}
// Find the local time zone, starting from scratch.
void KTimeZoned::findLocalZone()
{
mLocalZone.clear();
mLocalIdFile.clear();
mLocalZoneDataFile.clear();
// SOLUTION 1: DEFINITIVE.
// First try the simplest solution of checking for well-formed TZ setting.
const char *envtz = ::getenv("TZ");
if (checkTZ(envtz)) {
mSavedTZ = envtz;
if (!mLocalZone.isEmpty()) {
kDebug(1221) << "TZ: " << mLocalZone;
}
}
if (mLocalZone.isEmpty() && !mZoneinfoDir.isEmpty()) {
// SOLUTION 2: DEFINITIVE.
// Try to follow any /etc/localtime symlink to a zoneinfo file.
// SOLUTION 3: DEFINITIVE.
// Try to match /etc/localtime against the list of zoneinfo files.
matchZoneFile(QLatin1String("/etc/localtime"));
}
if (mLocalZone.isEmpty()) {
// SOLUTION 4: DEFINITIVE.
// BSD & Linux support: local time zone id in /etc/timezone.
checkTimezone();
}
if (mLocalZone.isEmpty()) {
// The local time zone is not defined by a file.
// Watch for creation of /etc/localtime in case it gets created later.
mLocalIdFile = QLatin1String("/etc/localtime");
}
if (mLocalZone.isEmpty() && !mZoneinfoDir.isEmpty()) {
// SOLUTION 5: HEURISTIC.
// None of the deterministic stuff above has worked: try a heuristic. We
// try to find a pair of matching time zone abbreviations...that way, we'll
// likely return a value in the user's own country.
tzset();
QByteArray tzname0(tzname[0]); // store copies, because zone.parse() will change them
QByteArray tzname1(tzname[1]);
int bestOffset = INT_MAX;
KSystemTimeZoneSource::startParseBlock();
const KTimeZones::ZoneMap zmap = mZones.zones();
for (KTimeZones::ZoneMap::ConstIterator it = zmap.constBegin(), end = zmap.constEnd(); it != end; ++it) {
KTimeZone zone = it.value();
int candidateOffset = qAbs(zone.currentOffset(Qt::LocalTime));
if (candidateOffset < bestOffset && zone.parse()) {
QList<QByteArray> abbrs = zone.abbreviations();
if (abbrs.contains(tzname0) && abbrs.contains(tzname1)) {
kDebug(1221) << "local=" << zone.name();
mLocalZone = zone.name();
bestOffset = candidateOffset;
if (!bestOffset)
break;
}
}
}
KSystemTimeZoneSource::endParseBlock();
if (!mLocalZone.isEmpty()) {
kDebug(1221) << "tzname:" << mLocalZone;
}
}
if (mLocalZone.isEmpty()) {
// SOLUTION 6: FAILSAFE.
mLocalZone = KTimeZone::utc().name();
if (!mLocalZone.isEmpty()) {
kDebug(1221) << "Failsafe:" << mLocalZone;
}
}
// Finally, if the local zone identity has changed, store
// the new one in the config file.
updateLocalZone();
}
// Called when KDirWatch detects a change in zone.tab
void KTimeZoned::zonetab_Changed(const QString& path)
{
kDebug(1221) << "zone.tab changed";
if (path != mZoneTab) {
kError(1221) << "Wrong path (" << path << ") for zone.tab";
return;
}
QDBusMessage message = QDBusMessage::createSignal("/Daemon", "org.kde.KTimeZoned", "zonetabChanged");
QList<QVariant> args;
args += mZoneTab;
message.setArguments(args);
QDBusConnection::sessionBus().send(message);
// Reread zone.tab and recreate the collection of KTimeZone instances,
// in case any zones have been created or deleted and one of them
// subsequently becomes the local zone.
QFile f;
f.setFileName(mZoneTab);
if (!f.open(QIODevice::ReadOnly)) {
kError(1221) << "Could not open zone.tab (" << mZoneTab << ") to reread";
} else {
readZoneTab(f);
}
}
// Called when KDirWatch detects a change
void KTimeZoned::localChanged()
{
QByteArray envTz = qgetenv("TZ");
QFileInfo info(mLocalIdFile);
QDateTime currentstamp = info.lastModified();
if (currentstamp == mLocalStamp && mSavedTZ == envTz)
return;
mLocalStamp = currentstamp;
mSavedTZ = envTz;
findLocalZone();
}
bool KTimeZoned::checkTZ(const char *envZone)
{
// SOLUTION 1: DEFINITIVE.
// First try the simplest solution of checking for well-formed TZ setting.
if (envZone) {
if (envZone[0] == '\0') {
mLocalZone = KTimeZone::utc().name();
mLocalIdFile.clear();
mLocalZoneDataFile.clear();
return true;
}
if (envZone[0] == ':') {
// TZ specifies a file name, either relative to zoneinfo/ or absolute.
QString TZfile = QFile::decodeName(envZone + 1);
if (TZfile.startsWith(mZoneinfoDir)) {
// It's an absolute file name in the zoneinfo directory.
// Convert it to a file name relative to zoneinfo/.
TZfile = TZfile.mid(mZoneinfoDir.length());
}
if (TZfile.startsWith(QLatin1Char('/'))) {
// It's an absolute file name.
if (matchZoneFile(TZfile))
{
return true;
}
} else if (!TZfile.isEmpty()) {
// It's a file name relative to zoneinfo/
mLocalZone = TZfile;
if (!mLocalZone.isEmpty())
{
mLocalZoneDataFile = mZoneinfoDir + '/' + TZfile;
mLocalIdFile.clear();
return true;
}
}
}
}
return false;
}
bool KTimeZoned::checkTimezone()
{
// SOLUTION 2: DEFINITIVE.
// BSD support.
QFile f;
f.setFileName(QLatin1String("/etc/timezone"));
if (!f.open(QIODevice::ReadOnly)) {
return false;
}
// Read the first line of the file.
QByteArray zoneName;
if (!f.atEnd()) {
zoneName = f.readLine().trimmed();
}
f.close();
if (zoneName.isEmpty()) {
return false;
}
if (!setLocalZone(QString::fromLatin1(zoneName.constData(), zoneName.size()))) {
return false;
}
mLocalIdFile = f.fileName();
kDebug(1221) << "/etc/timezone:" << mLocalZone;
return true;
}
bool KTimeZoned::matchZoneFile(const QString &path)
{
// SOLUTION 2: DEFINITIVE.
// Try to follow any symlink to a zoneinfo file.
// Get the path of the file which the symlink points to.
QFile f;
f.setFileName(path);
QFileInfo fi(f);
if (fi.isSymLink()) {
// The file is a symlink.
QString zoneInfoFileName = fi.canonicalFilePath();
QFileInfo fiz(zoneInfoFileName);
if (fiz.exists() && fiz.isReadable()) {
if (zoneInfoFileName.startsWith(mZoneinfoDir)) {
// We've got the zoneinfo file path.
// The time zone name is the part of the path after the zoneinfo directory.
// Note that some systems (e.g. Gentoo) have zones under zoneinfo which
// are not in zone.tab, so don't validate against mZones.
mLocalZone = zoneInfoFileName.mid(mZoneinfoDir.length() + 1);
kDebug(1221) << "local=" << mLocalZone;
} else {
// It isn't a zoneinfo file or a copy thereof.
// Use the absolute path as the time zone name.
mLocalZone = f.fileName();
}
mLocalIdFile = f.fileName();
mLocalZoneDataFile = zoneInfoFileName;
kDebug(1221) << "symlink" << mLocalIdFile << ":" << mLocalZone;
return true;
}
} else if (f.open(QIODevice::ReadOnly)) {
// SOLUTION 3: DEFINITIVE.
// Try to match the file against the list of zoneinfo files.
KTimeZone local;
QString zoneName;
if (!mConfigLocalZone.isEmpty()) {
// We know the local zone from last time.
// Check whether the file still matches it.
KTimeZone tzone = mZones.zone(mConfigLocalZone);
if (tzone.isValid()) {
zoneName = local.name();
}
}
if (!local.isValid() && mHaveCountryCodes) {
/* Look for time zones with the user's country code.
* This has two advantages: 1) it shortens the search;
* 2) it increases the chance of the correctly titled time zone
* being found, since multiple time zones can have identical
* definitions. For example, Europe/Guernsey is identical to
* Europe/London, but the latter is more likely to be the right
* zone name for a user with 'gb' country code.
*/
QString country = KGlobal::locale()->country().toUpper();
const KTimeZones::ZoneMap zmap = mZones.zones();
for (KTimeZones::ZoneMap::ConstIterator zit = zmap.constBegin(), zend = zmap.constEnd(); zit != zend; ++zit) {
KTimeZone tzone = zit.value();
if (tzone.countryCode() == country) {
if (tzone.isValid()) {
zoneName = tzone.name();
break;
}
}
}
}
bool success = false;
if (local.isValid()) {
// The file matches a zoneinfo file
mLocalZone = zoneName;
mLocalZoneDataFile = mZoneinfoDir + '/' + zoneName;
success = true;
} else {
// The file doesn't match a zoneinfo file. If it's a TZfile, use it directly.
// Read the file type identifier.
char buff[4];
f.reset();
QDataStream str(&f);
if (str.readRawData(buff, 4) == 4
&& buff[0] == 'T' && buff[1] == 'Z' && buff[2] == 'i' && buff[3] == 'f')
{
// Use its absolute path as the zone name.
mLocalZone = f.fileName();
mLocalZoneDataFile.clear();
success = true;
}
}
f.close();
if (success) {
mLocalIdFile = f.fileName();
kDebug(1221) << "file" << mLocalIdFile << ":" << mLocalZone;
return true;
}
}
return false;
}
// Check whether the zone name is valid, either as a zone in zone.tab or
// as another file in the zoneinfo directory.
// If valid, set the local zone information.
bool KTimeZoned::setLocalZone(const QString &zoneName)
{
KTimeZone local = mZones.zone(zoneName);
const QString path = mZoneinfoDir + '/' + zoneName;
if (!local.isValid()) {
// It isn't a recognised zone in zone.tab.
// Note that some systems (e.g. Gentoo) have zones under zoneinfo which
// are not in zone.tab, so check if it points to another zone file.
if (mZoneinfoDir.isEmpty())
return false;
QFileInfo fi(path);
if (fi.isSymLink())
fi.setFile(fi.canonicalFilePath());
if (!fi.exists() || !fi.isReadable())
return false;
}
mLocalZone = zoneName;
mLocalZoneDataFile = mZoneinfoDir.isEmpty() ? QString() : path;
return true;
}

View file

@ -1,146 +0,0 @@
[Desktop Entry]
Type=Service
X-KDE-ServiceTypes=KDEDModule
X-KDE-Library=ktimezoned
X-KDE-DBus-ModuleName=ktimezoned
X-KDE-Kded-autoload=true
X-KDE-Kded-load-on-demand=true
Name=Time Zone
Name[ar]=المنطقة الزمنية
Name[ast]=Estaya horaria
Name[bg]=Часови пояс
Name[bn]=
Name[bs]=Vremenska zona
Name[ca]=Zona horària
Name[ca@valencia]=Zona horària
Name[cs]=Časové pásmo
Name[da]=Tidszone
Name[de]=Zeitzone
Name[el]=Ωρολογιακή ζώνη
Name[en_GB]=Time Zone
Name[eo]=Horzono
Name[es]=Zona horaria
Name[et]=Ajavöönd
Name[eu]=Ordu-zona
Name[fa]=ناحیه زمانی
Name[fi]=Aikavyöhyke
Name[fr]=Zone horaire
Name[ga]=Crios Ama
Name[gl]=Fuso horario
Name[gu]= િ
Name[he]=איזור זמן
Name[hi]=
Name[hr]=Vremenska zona
Name[hu]=Időzóna
Name[ia]=Fuso horari
Name[id]=Zona Waktu
Name[is]=Tímabelti
Name[it]=Fuso orario
Name[ja]=
Name[kk]=Уақыт белдеуі
Name[km]=
Name[kn]= ( )
Name[ko]=
Name[lt]=Laiko juosta
Name[lv]=Laika josla
Name[mai]=
Name[ml]=
Name[mr]=
Name[nb]=Tidssone
Name[nds]=Tietrebeet
Name[nl]=Tijdzone
Name[nn]=Tidssone
Name[pa]=
Name[pl]=Strefa czasowa
Name[pt]=Fuso-Horário
Name[pt_BR]=Fuso horário
Name[ro]=Fus orar
Name[ru]=Часовой пояс
Name[si]=
Name[sk]=Časové pásmo
Name[sl]=Časovni pas
Name[sr]=Временска зона
Name[sr@ijekavian]=Временска зона
Name[sr@ijekavianlatin]=Vremenska zona
Name[sr@latin]=Vremenska zona
Name[sv]=Tidszon
Name[tg]=Минтақаи вақт
Name[th]=
Name[tr]=Zaman Dilimi
Name[ug]=ۋاقىت رايونى
Name[uk]=Часовий пояс
Name[vi]=Múi gi
Name[wa]=Coisse ås eures
Name[x-test]=xxTime Zonexx
Name[zh_CN]=
Name[zh_TW]=
Comment=Provides the system's time zone to applications
Comment[ar]=يوفر منطقة زمنية النظام للتطبيقات
Comment[ast]=Ufre la estaya horaria del sistema a les aplicaciones
Comment[bg]=Предоставяне на системния часови пояс за програмите
Comment[bn]=ি- িি ি-
Comment[bs]=Ispostavlja programima sistemsku vremensku zonu
Comment[ca]=Proporciona la zona horària del sistema a les aplicacions
Comment[ca@valencia]=Proporciona la zona horària del sistema a les aplicacions
Comment[cs]=Poskytuje systémová časová pásma aplikacím
Comment[da]=Giver systemets tidszone til programmer
Comment[de]=Die Systemzeitzone den Anwendungen zur Verfügung stellen
Comment[el]=Παρέχει την ωρολογιακή ζώνη του συστήματος στις εφαρμογές
Comment[en_GB]=Provides the system's time zone to applications
Comment[eo]=Ĝi provizas la horzonon de sistemo al aplikaĵoj
Comment[es]=Proporciona la zona horaria del sistema a las aplicaciones
Comment[et]=Süsteemi ajavööndi edastamine rakendustele
Comment[eu]=Sistemaren ordu-zona adierazten die aplikazioei
Comment[fa]=منطقه زمانی سامانه را برای برنامهها فراهم میکند
Comment[fi]=Tarjoaa järjestelmän aikavyöhyketiedon ohjelmille
Comment[fr]=Fournit la zone horaire du système aux applications
Comment[ga]=Soláthraíonn sé crios ama an chórais d'fheidhmchláir
Comment[gl]=Fornece o fuso horario do sistema aos programas
Comment[gu]=િ િ
Comment[he]=מספק את אזור הזמן של המערכת עבור יישומים
Comment[hi]=
Comment[hr]=Omogućuje aplikacijama pristup sistemskoj vremenskoj zoni
Comment[hu]=A rendszer időzónájának biztosítása alkalmazásokhoz
Comment[ia]=Il forni le fuso horari de systema al applicationes
Comment[id]=Menyediakan zona waktu sistem untuk aplikasi
Comment[is]=Sér forritum fyrir stillingum á tímabelti kerfisins
Comment[it]=Dà il fuso orario di sistema alle applicazioni
Comment[ja]=
Comment[kk]=Қолданбаларға орнатылған уақыт белдеу мәліметін жеткізеді
Comment[km]=
Comment[kn]= ಿ ಿ
Comment[ko]=
Comment[lt]=Nurodo programoms sistemos laiko juostą
Comment[lv]=Sniedz informāciju par pašreizējo laika joslu dažādām programmām
Comment[ml]=ിി
Comment[mr]= ि
Comment[nb]=Viser systemets tidssone til programmer
Comment[nds]=Stellt dat Systeem-Tietrebeet för Programmen praat.
Comment[nl]=Levert de tijdzone van het systeem aan applicaties
Comment[nn]=Gjev programma rett tidssone
Comment[pa]=ਿ ਿ
Comment[pl]=Udostępnia systemową strefę czasową programom
Comment[pt]=Fornece o fuso-horário do sistema às aplicações
Comment[pt_BR]=Fornece o fuso horário do sistema para os aplicativos
Comment[ro]=Oferă aplicațiilor fusul orar al sistemului
Comment[ru]=Предоставляет данные о системном часовом поясе приложениям
Comment[si]=
Comment[sk]=Poskytuje systémové časové pásma aplikáciám
Comment[sl]=Programom omogoča dostop do sistemskega časovnega pasu
Comment[sr]=Испоставља програмима системску временску зону
Comment[sr@ijekavian]=Испоставља програмима системску временску зону
Comment[sr@ijekavianlatin]=Ispostavlja programima sistemsku vremensku zonu
Comment[sr@latin]=Ispostavlja programima sistemsku vremensku zonu
Comment[sv]=Tillhandahåller systemets tidszon till program
Comment[tg]=Минтақаи вақти системаро барои барномаҳо таъмин мекунад
Comment[th]=
Comment[tr]=Sistem zaman dilimini uygulamalara sunar
Comment[ug]=پروگراممىغا سىستېما ۋاقىت رايون ئۇچۇرى تەمىنلەيدۇ
Comment[uk]=Надає дані щодо часового поясу системи програмам
Comment[vi]=Cung cp múi gi h thng cho các ng dng
Comment[wa]=Dene ås programes li coisse ås eures då sistinme
Comment[x-test]=xxProvides the system's time zone to applicationsxx
Comment[zh_CN]=
Comment[zh_TW]=

View file

@ -1,75 +0,0 @@
/*
This file is part of the KDE libraries
Copyright (c) 2007,2009 David Jarvie <djarvie@kde.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
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.
*/
#ifndef KTIMEZONED_H
#define KTIMEZONED_H
#include "ktimezonedbase.h"
#include <QString>
#include <QByteArray>
#include <QFile>
#include <QTimer>
#include <kdedmodule.h>
#include <kdirwatch.h>
#include <ksystemtimezone.h>
class KTimeZoned : public KTimeZonedBase
{
Q_OBJECT
public:
KTimeZoned(QObject* parent, const QList<QVariant>&);
~KTimeZoned();
private Q_SLOTS:
void zonetab_Changed(const QString& path);
void localChanged();
private:
/** reimp */
void init(bool restart);
bool findZoneTab(QFile& f);
void readZoneTab(QFile& f);
void findLocalZone();
bool checkTZ(const char *envZone);
bool checkLocaltimeLink();
bool checkLocaltimeFile();
bool checkTimezone();
void updateLocalZone();
bool matchZoneFile(const QString &path);
bool setLocalZone(const QString &zoneName);
QString mZoneinfoDir; // path to zoneinfo directory
QString mZoneTab; // path to zone.tab file
QByteArray mSavedTZ; // last value of TZ if it's used to set local zone
KSystemTimeZoneSource *mSource;
KTimeZones mZones; // time zones collection
QString mLocalIdFile; // file containing pointer to local time zone definition
QString mLocalZoneDataFile; // zoneinfo file containing local time zone definition
KDirWatch *mZonetabWatch; // watch for zone.tab file changes
QTimer *mPollWatch; // watch for time zone definition file changes
bool mHaveCountryCodes; // true if zone.tab contains any country codes
QDateTime mLocalStamp; // mLocalIdFile modification time
};
#endif

View file

@ -1,75 +0,0 @@
/*
This file is part of the KDE libraries
Copyright (c) 2007-2009 David Jarvie <djarvie@kde.org>
Copyright (c) 2009 Till Adam <adam@kde.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
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.
*/
#ifndef KTIMEZONEDBASE_H
#define KTIMEZONEDBASE_H
#include <kdedmodule.h>
class KTimeZonedBase : public KDEDModule
{
Q_OBJECT
Q_CLASSINFO("D-Bus Interface", "org.kde.KTimeZoned")
public:
KTimeZonedBase(QObject* parent, const QList<QVariant>&)
:KDEDModule(parent) {}
virtual ~KTimeZonedBase() {};
public Q_SLOTS:
/** D-Bus call to initialize the module.
* @param reinit determines whether to reinitialize if the module has already
* initialized itself
*/
Q_SCRIPTABLE void initialize(bool reinit)
{
// If we reach here, the module has already been constructed and therefore
// initialized. So only do anything if reinit is true.
if (reinit)
init(true);
}
Q_SCRIPTABLE QString localZone() const { return mLocalZone; }
Q_SIGNALS:
/** D-Bus signal emitted when the time zone configuration has changed. */
void configChanged();
/** D-Bus signal emitted when zone.tab contents have changed.
* @param zonetab path to zone.tab
*/
void zonetabChanged(const QString &zonetab);
/** D-Bus signal emitted when the definition (not the identity) of the local
* system time zone has changed.
* @param zone path to time zone definition file
*/
void zoneDefinitionChanged(const QString &zone);
protected:
virtual void init(bool) = 0;
QString mLocalZone; // local system time zone name
QString mConfigLocalZone; // local system time zone name as stored in config file
};
#endif

View file

@ -1,19 +0,0 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name="org.kde.KTimeZoned">
<signal name="configChanged"/>
<signal name="zonetabChanged">
<arg name="zonetab" type="s" direction="out"/>
</signal>
<signal name="zoneDefinitionChanged">
<arg name="zone" type="s" direction="out"/>
</signal>
<method name="initialize">
<arg name="reinit" type="b" direction="in"/>
</method>
</interface>
</node>

View file

@ -50,12 +50,13 @@ TimeEngine::~TimeEngine()
void TimeEngine::init()
{
//QDBusInterface *ktimezoned = new QDBusInterface("org.kde.kded", "/modules/ktimezoned", "org.kde.KTimeZoned");
QDBusConnection dbus = QDBusConnection::sessionBus();
dbus.connect(QString(), QString(), "org.kde.KTimeZoned", "configChanged", this, SLOT(tzConfigChanged()));
dbus.connect(QString(), "/org/kde/kcmshell_clock", "org.kde.kcmshell_clock", "clockUpdated", this, SLOT(clockSkewed()));
connect( Solid::PowerManagement::notifier(), SIGNAL(resumingFromSuspend()), this , SLOT(clockSkewed()) );
connect(Solid::PowerManagement::notifier(), SIGNAL(resumingFromSuspend()), this , SLOT(clockSkewed()));
m_tz = KSystemTimeZones::local().name();
QTimer::singleShot(3000, this, SLOT(checkTZ()));
}
void TimeEngine::clockSkewed()
@ -65,15 +66,21 @@ void TimeEngine::clockSkewed()
forceImmediateUpdateOfAllVisualizations();
}
void TimeEngine::tzConfigChanged()
void TimeEngine::checkTZ()
{
TimeSource *s = qobject_cast<TimeSource *>(containerForSource("Local"));
const QString localtz = KSystemTimeZones::local().name();
if (localtz != m_tz) {
m_tz = localtz;
if (s) {
s->setTimeZone("Local");
TimeSource *s = qobject_cast<TimeSource *>(containerForSource("Local"));
if (s) {
s->setTimeZone("Local");
}
updateAllSources();
}
updateAllSources();
QTimer::singleShot(3000, this, SLOT(checkTZ()));
}
QStringList TimeEngine::sources() const

View file

@ -46,7 +46,10 @@ class TimeEngine : public Plasma::DataEngine
protected Q_SLOTS:
void clockSkewed(); // call when system time changed and all clocks should be updated
void tzConfigChanged();
void checkTZ();
private:
QString m_tz;
};
#endif // TIMEENGINE_H