Changeset View
Changeset View
Standalone View
Standalone View
kcms/dateandtime/main.cpp
Show All 22 Lines | |||||
23 | 23 | | |||
24 | #include <unistd.h> | 24 | #include <unistd.h> | ||
25 | #include <time.h> | 25 | #include <time.h> | ||
26 | 26 | | |||
27 | 27 | | |||
28 | #include <QVBoxLayout> | 28 | #include <QVBoxLayout> | ||
29 | 29 | | |||
30 | #include <QDBusConnection> | 30 | #include <QDBusConnection> | ||
31 | #include <kaboutdata.h> | 31 | #include <KLocalizedString> | ||
32 | #include <kdialog.h> | | |||
33 | #include <kpluginfactory.h> | | |||
34 | #include <kpluginloader.h> | | |||
35 | #include <kmessagebox.h> | | |||
36 | 32 | | |||
37 | #include "dtime.h" | 33 | #include <KAboutData> | ||
38 | #include "helper.h" | 34 | #include <KDialog> | ||
39 | 35 | #include <KPluginFactory> | |||
40 | #include <kauthaction.h> | 36 | #include <KPluginLoader> | ||
41 | #include <kauthexecutejob.h> | 37 | #include <KMessageBox> | ||
38 | #include <KAuthAction> | ||||
39 | #include <KAuthExecuteJob> | ||||
40 | #include <QTimeZone> | ||||
41 | #include <KConfig> | ||||
42 | #include <KStandardDirs> | ||||
43 | #include <QTimer> | ||||
42 | 44 | | |||
43 | #include "timedated_interface.h" | 45 | #include "timedated_interface.h" | ||
44 | 46 | | |||
45 | K_PLUGIN_FACTORY(KlockModuleFactory, registerPlugin<KclockModule>();) | 47 | K_PLUGIN_FACTORY_WITH_JSON(KClockFactory, "kcmclock.json", registerPlugin<KClockModule>();) | ||
46 | K_EXPORT_PLUGIN(KlockModuleFactory("kcmkclock")) | | |||
47 | | ||||
48 | 48 | | |||
49 | KclockModule::KclockModule(QWidget *parent, const QVariantList &) | 49 | KClockModule::KClockModule(QObject *parent, const QVariantList &args) | ||
50 | : KCModule(parent) | 50 | : KQuickAddons::ConfigModule(parent, args) | ||
51 | { | 51 | { | ||
52 | auto reply = QDBusConnection::systemBus().call(QDBusMessage::createMethodCall(QStringLiteral("org.freedesktop.DBus"), | 52 | findNTPutility(); | ||
53 | | ||||
54 | auto reply = QDBusConnection::systemBus() | ||||
55 | .call(QDBusMessage::createMethodCall( | ||||
56 | QStringLiteral("org.freedesktop.DBus"), | ||||
53 | QStringLiteral("/org/freedesktop/DBus"), | 57 | QStringLiteral("/org/freedesktop/DBus"), | ||
54 | QStringLiteral("org.freedesktop.DBus"), | 58 | QStringLiteral("org.freedesktop.DBus"), | ||
55 | QStringLiteral("ListActivatableNames"))); | 59 | QStringLiteral("ListActivatableNames")) | ||
60 | ); | ||||
56 | 61 | | |||
57 | if (!reply.arguments().isEmpty() && reply.arguments().first().value<QStringList>().contains(QLatin1String("org.freedesktop.timedate1"))) { | 62 | if (!reply.arguments().isEmpty() && reply.arguments().first().value<QStringList>().contains(QLatin1String("org.freedesktop.timedate1"))) { | ||
58 | m_haveTimedated = true; | 63 | m_hasTimedated = true; | ||
64 | qDebug() << "Has timedated"; | ||||
65 | } else { | ||||
66 | qDebug() << "Does not have timedated"; | ||||
59 | } | 67 | } | ||
60 | 68 | | |||
61 | KAboutData *about = | 69 | auto *about = new KAboutData(QStringLiteral("kcmclock"), i18n("KDE Clock Control Module"), QStringLiteral("1.0"), | ||
62 | new KAboutData(QStringLiteral("kcmclock"), i18n("KDE Clock Control Module"), QStringLiteral("1.0"), | | |||
63 | QString(), KAboutLicense::GPL, | 70 | QString(), KAboutLicense::GPL, | ||
64 | i18n("(c) 1996 - 2001 Luca Montecchiani")); | 71 | i18n("(c) 1996 - 2001 Luca Montecchiani")); | ||
65 | 72 | | |||
66 | about->addAuthor(i18n("Luca Montecchiani"), i18n("Original author"), QStringLiteral("m.luca@usa.net")); | 73 | about->addAuthor(i18n("Luca Montecchiani"), i18n("Original author"), QStringLiteral("m.luca@usa.net")); | ||
67 | about->addAuthor(i18n("Paul Campbell"), i18n("Current Maintainer"), QStringLiteral("paul@taniwha.com")); | 74 | about->addAuthor(i18n("Paul Campbell"), i18n("Current Maintainer"), QStringLiteral("paul@taniwha.com")); | ||
68 | about->addAuthor(i18n("Benjamin Meyer"), i18n("Added NTP support"), QStringLiteral("ben+kcmclock@meyerhome.net")); | 75 | about->addAuthor(i18n("Benjamin Meyer"), i18n("Added NTP support"), QStringLiteral("ben+kcmclock@meyerhome.net")); | ||
76 | about->addAuthor(i18n("Benjamin Meyer"), i18n("Port to Qml"), QStringLiteral("ben+kcmclock@meyerhome.net")); | ||||
77 | | ||||
69 | setAboutData( about ); | 78 | setAboutData( about ); | ||
70 | setQuickHelp( i18n("<h1>Date & Time</h1> This control module can be used to set the system date and" | 79 | setQuickHelp( i18n("<h1>Date & Time</h1> This control module can be used to set the system date and" | ||
71 | " time. As these settings do not only affect you as a user, but rather the whole system, you" | 80 | " time. As these settings do not only affect you as a user, but rather the whole system, you" | ||
72 | " can only change these settings when you start the System Settings as root. If you do not have" | 81 | " can only change these settings when you start the System Settings as root. If you do not have" | ||
73 | " the root password, but feel the system time should be corrected, please contact your system" | 82 | " the root password, but feel the system time should be corrected, please contact your system" | ||
74 | " administrator.")); | 83 | " administrator.")); | ||
75 | 84 | | |||
76 | 85 | if (m_hasTimedated) { | |||
77 | QVBoxLayout *layout = new QVBoxLayout(this); | 86 | // TODO: Re Enable | ||
78 | layout->setContentsMargins(0, 0, 0, 0); | 87 | setAuthActionName(QStringLiteral("org.freedesktop.timedate1.set-time")); | ||
79 | layout->setSpacing(KDialog::spacingHint()); | | |||
80 | | ||||
81 | dtime = new Dtime(this, m_haveTimedated); | | |||
82 | layout->addWidget(dtime); | | |||
83 | connect(dtime, SIGNAL(timeChanged(bool)), this, SIGNAL(changed(bool))); | | |||
84 | | ||||
85 | setButtons(Help|Apply); | | |||
86 | | ||||
87 | if (m_haveTimedated) { | | |||
88 | setAuthAction(KAuth::Action(QStringLiteral("org.freedesktop.timedate1.set-time"))); | | |||
89 | } else { | 88 | } else { | ||
90 | //auth action name will be automatically guessed from the KCM name | 89 | //auth action name will be automatically guessed from the KCM name | ||
91 | qWarning() << "Timedated not found, using legacy saving mode"; | 90 | qWarning() << "Timedated not found, using legacy saving mode"; | ||
92 | setNeedsAuthorization(true); | 91 | // setNeedsAuthorization(true); | ||
93 | } | 92 | } | ||
93 | load(); | ||||
94 | } | 94 | } | ||
95 | 95 | | |||
96 | bool KclockModule::kauthSave() | 96 | bool KClockModule::kauthSave() | ||
97 | { | 97 | { | ||
98 | QVariantMap helperargs; | 98 | QVariantMap helperargs = { | ||
99 | helperargs[QStringLiteral("ntp")] = true; | 99 | {QStringLiteral("ntp"), true}, | ||
100 | helperargs[QStringLiteral("ntpServers")] = dtime->ntpServers(); | 100 | {QStringLiteral("ntpServers"), ntpServers()}, | ||
101 | helperargs[QStringLiteral("ntpEnabled")] = dtime->ntpEnabled(); | 101 | {QStringLiteral("ntpEnabled"), ntpEnabled()} | ||
102 | }; | ||||
102 | 103 | | |||
103 | if (!dtime->ntpEnabled()) { | 104 | if (ntpEnabled()) { | ||
104 | QDateTime newTime = dtime->userTime(); | 105 | QDateTime newTime = userTime(); | ||
105 | qDebug() << "Set date to " << dtime->userTime(); | | |||
106 | helperargs[QStringLiteral("date")] = true; | 106 | helperargs[QStringLiteral("date")] = true; | ||
107 | helperargs[QStringLiteral("newdate")] = QString::number(newTime.toTime_t()); | 107 | helperargs[QStringLiteral("newdate")] = QString::number(newTime.toTime_t()); | ||
108 | helperargs[QStringLiteral("olddate")] = QString::number(::time(nullptr)); | 108 | helperargs[QStringLiteral("olddate")] = QString::number(::time(nullptr)); | ||
109 | } | 109 | } | ||
110 | 110 | | |||
111 | QString selectedTimeZone = dtime->selectedTimeZone(); | 111 | if (!m_selectedTimeZone.isEmpty()) { | ||
112 | if (!selectedTimeZone.isEmpty()) { | | |||
113 | helperargs[QStringLiteral("tz")] = true; | 112 | helperargs[QStringLiteral("tz")] = true; | ||
114 | helperargs[QStringLiteral("tzone")] = selectedTimeZone; | 113 | helperargs[QStringLiteral("tzone")] = m_selectedTimeZone; | ||
115 | } else { | 114 | } else { | ||
116 | helperargs[QStringLiteral("tzreset")] = true; // make the helper reset the timezone | 115 | helperargs[QStringLiteral("tzreset")] = true; // make the helper reset the timezone | ||
117 | } | 116 | } | ||
118 | 117 | | |||
119 | Action action = authAction(); | 118 | //TODO: What to do with authAction()? | ||
119 | | ||||
120 | KAuth::Action action = KAuth::Action(authActionName()); | ||||
120 | action.setArguments(helperargs); | 121 | action.setArguments(helperargs); | ||
121 | 122 | | |||
122 | ExecuteJob *job = action.execute(); | 123 | // ExecuteJob *job = action.execute(); | ||
123 | bool rc = job->exec(); | 124 | // bool rc = job->exec(); | ||
124 | if (!rc) { | 125 | // if (!rc) { | ||
125 | KMessageBox::error(this, i18n("Unable to authenticate/execute the action: %1, %2", job->error(), job->errorString())); | 126 | // TODO: Move this away from a Message Box. | ||
126 | } | 127 | // KMessageBox::error(nullptr, i18n("Unable to authenticate/execute the action: %1, %2", job->error(), job->errorString())); | ||
127 | return rc; | 128 | // } | ||
129 | return true; // rc; | ||||
128 | } | 130 | } | ||
129 | 131 | | |||
130 | bool KclockModule::timedatedSave() | 132 | bool KClockModule::timedatedSave() | ||
131 | { | 133 | { | ||
132 | 134 | | |||
133 | OrgFreedesktopTimedate1Interface timedateIface(QStringLiteral("org.freedesktop.timedate1"), QStringLiteral("/org/freedesktop/timedate1"), QDBusConnection::systemBus()); | 135 | OrgFreedesktopTimedate1Interface timedateIface(QStringLiteral("org.freedesktop.timedate1"), QStringLiteral("/org/freedesktop/timedate1"), QDBusConnection::systemBus()); | ||
134 | 136 | | |||
135 | bool rc = true; | 137 | bool rc = true; | ||
136 | //final arg in each method is "user-interaction" i.e whether it's OK for polkit to ask for auth | 138 | //final arg in each method is "user-interaction" i.e whether it's OK for polkit to ask for auth | ||
137 | 139 | | |||
138 | //we cannot send requests up front then block for all replies as we need NTP to be disabled before we can make a call to SetTime | 140 | //we cannot send requests up front then block for all replies as we need NTP to be disabled before we can make a call to SetTime | ||
139 | //timedated processes these in parallel and will return an error otherwise | 141 | //timedated processes these in parallel and will return an error otherwise | ||
140 | 142 | | |||
141 | auto reply = timedateIface.SetNTP(dtime->ntpEnabled(), true); | 143 | auto reply = timedateIface.SetNTP(ntpEnabled(), true); | ||
142 | reply.waitForFinished(); | 144 | reply.waitForFinished(); | ||
143 | if (reply.isError()) { | 145 | if (reply.isError()) { | ||
144 | KMessageBox::error(this, i18n("Unable to change NTP settings")); | 146 | setErrorMessage(i18n("Unable to change NTP settings")); | ||
145 | qWarning() << "Failed to enable NTP" << reply.error().name() << reply.error().message(); | 147 | qWarning() << "Failed to enable NTP" << reply.error().name() << reply.error().message(); | ||
146 | rc = false; | 148 | rc = false; | ||
147 | } | 149 | } | ||
148 | 150 | | |||
149 | 151 | if (!ntpEnabled()) { | |||
150 | if (!dtime->ntpEnabled()) { | 152 | qint64 timeDiff = userTime().toMSecsSinceEpoch() - QDateTime::currentMSecsSinceEpoch(); | ||
151 | qint64 timeDiff = dtime->userTime().toMSecsSinceEpoch() - QDateTime::currentMSecsSinceEpoch(); | | |||
152 | //*1000 for milliseconds -> microseconds | 153 | //*1000 for milliseconds -> microseconds | ||
153 | auto reply = timedateIface.SetTime(timeDiff * 1000, true, true); | 154 | auto reply = timedateIface.SetTime(timeDiff * 1000, true, true); | ||
154 | reply.waitForFinished(); | 155 | reply.waitForFinished(); | ||
155 | if (reply.isError()) { | 156 | if (reply.isError()) { | ||
156 | KMessageBox::error(this, i18n("Unable to set current time")); | 157 | setErrorMessage(i18n("Unable to set current time")); | ||
157 | qWarning() << "Failed to set current time" << reply.error().name() << reply.error().message(); | 158 | qWarning() << "Failed to set current time" << reply.error().name() << reply.error().message(); | ||
158 | rc = false; | 159 | rc = false; | ||
159 | } | 160 | } | ||
160 | } | 161 | } | ||
161 | QString selectedTimeZone = dtime->selectedTimeZone(); | 162 | if (!m_selectedTimeZone.isEmpty()) { | ||
162 | if (!selectedTimeZone.isEmpty()) { | 163 | auto reply = timedateIface.SetTimezone(m_selectedTimeZone, true); | ||
163 | auto reply = timedateIface.SetTimezone(selectedTimeZone, true); | | |||
164 | reply.waitForFinished(); | 164 | reply.waitForFinished(); | ||
165 | if (reply.isError()) { | 165 | if (reply.isError()) { | ||
166 | KMessageBox::error(this, i18n("Unable to set timezone")); | 166 | setErrorMessage(i18n("Unable to set timezone")); | ||
167 | qWarning() << "Failed to set timezone" << reply.error().name() << reply.error().message(); | 167 | qWarning() << "Failed to set timezone" << reply.error().name() << reply.error().message(); | ||
168 | rc = false; | 168 | rc = false; | ||
169 | } | 169 | } | ||
170 | } | 170 | } | ||
171 | 171 | | |||
172 | return rc; | 172 | return rc; | ||
173 | } | 173 | } | ||
174 | 174 | | |||
175 | void KclockModule::save() | 175 | void KClockModule::save() | ||
176 | { | 176 | { | ||
177 | setDisabled(true); | 177 | const bool success = m_hasTimedated ? timedatedSave() : kauthSave(); | ||
178 | | ||||
179 | bool success = false; | | |||
180 | if (m_haveTimedated) { | | |||
181 | success = timedatedSave(); | | |||
182 | } else { | | |||
183 | success = kauthSave(); | | |||
184 | } | | |||
185 | 178 | | |||
186 | if (success) { | 179 | if (success) { | ||
187 | QDBusMessage msg = QDBusMessage::createSignal(QStringLiteral("/org/kde/kcmshell_clock"), QStringLiteral("org.kde.kcmshell_clock"), QStringLiteral("clockUpdated")); | 180 | QDBusMessage msg = QDBusMessage::createSignal( | ||
181 | QStringLiteral("/org/kde/kcmshell_clock"), | ||||
182 | QStringLiteral("org.kde.kcmshell_clock"), | ||||
183 | QStringLiteral("clockUpdated")); | ||||
188 | QDBusConnection::sessionBus().send(msg); | 184 | QDBusConnection::sessionBus().send(msg); | ||
189 | } | 185 | } | ||
190 | 186 | | |||
191 | // NOTE: super nasty hack #1 | 187 | // NOTE: super nasty hack #1 | ||
192 | // Try to work around time mismatch between KSystemTimeZones' update of local | 188 | // Try to work around time mismatch between KSystemTimeZones' update of local | ||
193 | // timezone and reloading of data, so that the new timezone is taken into account. | 189 | // timezone and reloading of data, so that the new timezone is taken into account. | ||
194 | // The Ultimate solution to this would be if KSTZ emitted a signal when a new | 190 | // The Ultimate solution to this would be if KSTZ emitted a signal when a new | ||
195 | // local timezone was found. | 191 | // local timezone was found. | ||
196 | | ||||
197 | // setDisabled(false) happens in load(), since QTimer::singleShot is non-blocking | | |||
198 | if (!m_haveTimedated) { | | |||
199 | QTimer::singleShot(5000, this, SLOT(load())); | 192 | QTimer::singleShot(5000, this, SLOT(load())); | ||
193 | } | ||||
194 | | ||||
195 | void KClockModule::load() | ||||
196 | { | ||||
197 | | ||||
198 | QString currentTimeZone; | ||||
199 | | ||||
200 | if (m_hasTimedated) { | ||||
201 | OrgFreedesktopTimedate1Interface timeDatedIface( | ||||
202 | QStringLiteral("org.freedesktop.timedate1"), | ||||
203 | QStringLiteral("/org/freedesktop/timedate1"), | ||||
204 | QDBusConnection::systemBus() | ||||
205 | ); | ||||
206 | currentTimeZone = timeDatedIface.timezone(); | ||||
200 | } else { | 207 | } else { | ||
201 | load(); | 208 | // The config is actually written to the system config, but the user does not have any local config, | ||
209 | // since there is nothing writing it. | ||||
210 | KConfig _config( QStringLiteral("kcmclockrc"), KConfig::NoGlobals ); | ||||
211 | KConfigGroup config(&_config, "NTP"); | ||||
212 | | ||||
213 | m_ntpServers.clear(); | ||||
214 | setNtpServers(config.readEntry("servers", | ||||
215 | i18n("Public Time Server (pool.ntp.org),\ | ||||
216 | asia.pool.ntp.org,\ | ||||
217 | europe.pool.ntp.org,\ | ||||
218 | north-america.pool.ntp.org,\ | ||||
219 | oceania.pool.ntp.org")) | ||||
220 | .split(',', QString::SkipEmptyParts)); | ||||
221 | setNtpEnabled(config.readEntry("enabled", false)); | ||||
222 | | ||||
223 | currentTimeZone = QTimeZone::systemTimeZone().displayName(QDateTime::currentDateTime()); | ||||
224 | } | ||||
225 | | ||||
226 | // Reset to the current date and time | ||||
227 | setTime(QTime::currentTime()); | ||||
228 | setDate(QDate::currentDate()); | ||||
229 | setLocalTimeZone(QTimeZone::systemTimeZone().displayName(QDateTime::currentDateTime())); | ||||
202 | } | 230 | } | ||
203 | 231 | | |||
232 | void KClockModule::findNTPutility(){ | ||||
233 | QByteArray envpath = qgetenv("PATH"); | ||||
234 | if (!envpath.isEmpty() && envpath.startsWith(':')) { | ||||
235 | envpath.remove(0, 1); | ||||
236 | } | ||||
237 | | ||||
238 | QString path = QStringLiteral("/sbin:/usr/sbin:") | ||||
239 | + (!envpath.isEmpty() ? QFile::decodeName(envpath) : QLatin1String("/bin:/usr/bin")); | ||||
240 | | ||||
241 | for(const QString &possible_ntputility : {QStringLiteral("ntpdate"), QStringLiteral("rdate")} ) { | ||||
242 | const QString executable = KStandardDirs::findExe(possible_ntputility, path); | ||||
243 | if(!executable.isEmpty()) { | ||||
244 | m_ntpUtility = executable; | ||||
245 | return; | ||||
246 | } | ||||
247 | } | ||||
204 | } | 248 | } | ||
205 | 249 | | |||
206 | void KclockModule::load() | 250 | /* There's no Qml module for Timezones in the Free Qt Version */ | ||
251 | QStringList KClockModule::timeZoneList() const | ||||
207 | { | 252 | { | ||
208 | dtime->load(); | 253 | static QStringList availableTimezones; | ||
209 | setDisabled(false); | 254 | if (availableTimezones.isEmpty()) { | ||
255 | const auto timeZones = QTimeZone::availableTimeZoneIds(); | ||||
256 | for(auto &timeZone : timeZones) { | ||||
257 | availableTimezones.append(timeZone); | ||||
210 | } | 258 | } | ||
259 | } | ||||
260 | return availableTimezones; | ||||
261 | } | ||||
262 | | ||||
263 | QDateTime KClockModule::userTime() const | ||||
264 | { | ||||
265 | return QDateTime(m_date, m_time); | ||||
266 | } | ||||
267 | | ||||
268 | QTime KClockModule::time() const { | ||||
269 | return m_time; | ||||
270 | } | ||||
271 | | ||||
272 | QDate KClockModule::date() const { | ||||
273 | return m_date; | ||||
274 | } | ||||
275 | | ||||
276 | bool KClockModule::ntpEnabled() const { | ||||
277 | return m_ntpEnabled; | ||||
278 | } | ||||
279 | | ||||
280 | bool KClockModule::hasTimedated() const { | ||||
281 | return m_hasTimedated; | ||||
282 | } | ||||
283 | | ||||
284 | QStringList KClockModule::ntpServers() const { | ||||
285 | return m_ntpServers; | ||||
286 | } | ||||
287 | | ||||
288 | QString KClockModule::localTimeZone() const { | ||||
289 | return m_localTimeZone; | ||||
290 | } | ||||
291 | | ||||
292 | QString KClockModule::localTimeZoneAbreviation() const { | ||||
293 | return m_localTimeZoneAbreviation; | ||||
294 | } | ||||
295 | | ||||
296 | QString KClockModule::selectedTimeZone() const { | ||||
297 | return m_selectedTimeZone; | ||||
298 | } | ||||
299 | | ||||
300 | QString KClockModule::errorMessage() const { | ||||
301 | return m_errorMessage; | ||||
302 | } | ||||
303 | | ||||
304 | | ||||
305 | void KClockModule::setTime(const QTime& value) { | ||||
306 | if (m_time != value) { | ||||
307 | m_time = value; | ||||
308 | emit timeChanged(); | ||||
309 | } | ||||
310 | } | ||||
311 | | ||||
312 | void KClockModule::setDate(const QDate& value) { | ||||
313 | if (m_date != value) { | ||||
314 | m_date = value; | ||||
315 | emit dateChanged(); | ||||
316 | } | ||||
317 | } | ||||
318 | | ||||
319 | void KClockModule::setNtpEnabled(bool value) { | ||||
320 | if (m_ntpEnabled != value) { | ||||
321 | m_ntpEnabled = value; | ||||
322 | emit ntpEnabledChanged(); | ||||
323 | } | ||||
324 | } | ||||
325 | | ||||
326 | void KClockModule::setHasTimedated(bool value) { | ||||
327 | if (m_hasTimedated != value) { | ||||
328 | m_hasTimedated = value; | ||||
329 | emit hasTimedatedChanged(); | ||||
330 | } | ||||
331 | } | ||||
332 | | ||||
333 | void KClockModule::setNtpServers(const QStringList& value) { | ||||
334 | if (m_ntpServers != value) { | ||||
335 | m_ntpServers = value; | ||||
336 | emit ntpServersChanged(); | ||||
337 | } | ||||
338 | } | ||||
339 | | ||||
340 | void KClockModule::setLocalTimeZone(const QString& value) { | ||||
341 | if (m_localTimeZone != value) { | ||||
342 | m_localTimeZone = value; | ||||
343 | emit localTimeZoneChanged(); | ||||
344 | } | ||||
345 | } | ||||
346 | | ||||
347 | void KClockModule::setLocalTimeZoneAbreviation(const QString& value) { | ||||
348 | if (m_localTimeZoneAbreviation != value) { | ||||
349 | m_localTimeZoneAbreviation = value; | ||||
350 | emit localTimeZoneAbreviationChanged(); | ||||
351 | } | ||||
352 | } | ||||
353 | | ||||
354 | void KClockModule::setSelectedTimeZone(const QString& value) { | ||||
355 | if (m_selectedTimeZone != value) { | ||||
356 | m_selectedTimeZone = value; | ||||
357 | emit selectedTimeZoneChanged(); | ||||
358 | } | ||||
359 | } | ||||
360 | | ||||
361 | void KClockModule::setErrorMessage(const QString& value) { | ||||
362 | if (m_errorMessage != value) { | ||||
363 | m_errorMessage = value; | ||||
364 | emit errorMessageChanged(); | ||||
365 | } | ||||
366 | } | ||||
367 | | ||||
211 | 368 | | |||
212 | #include "main.moc" | 369 | #include "main.moc" |