diff --git a/kcms/dateandtime/CMakeLists.txt b/kcms/dateandtime/CMakeLists.txt --- a/kcms/dateandtime/CMakeLists.txt +++ b/kcms/dateandtime/CMakeLists.txt @@ -1,40 +1,35 @@ # KI18N Translation Domain for this library -add_definitions(-DTRANSLATION_DOMAIN=\"kcmkclock\") -########### next target ############### +add_definitions(-DTRANSLATION_DOMAIN=\"kcmclock\") -set(kcm_clock_PART_SRCS dtime.cpp main.cpp ) +set(kcmclock_PART_SRCS main.cpp ) -ki18n_wrap_ui(kcm_clock_PART_SRCS dateandtime.ui) +# needed for krdb +qt5_add_dbus_interface(kcmclock_PART_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/timedated1.xml timedated_interface) -qt5_add_dbus_interface(kcm_clock_PART_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/timedated1.xml timedated_interface) - -add_library(kcm_clock MODULE ${kcm_clock_PART_SRCS}) +add_library(kcmclock MODULE ${kcmclock_PART_SRCS}) +add_executable(kcmdatetimehelper helper.cpp ${helper_mocs}) -target_link_libraries(kcm_clock +target_link_libraries(kcmclock Qt5::DBus KF5::ItemViews KF5::AuthCore KF5::KCMUtils + KF5::CoreAddons KF5::I18n KF5::KIOCore KF5::KIOWidgets KF5::Plasma + KF5::QuickAddons KF5::KDELibs4Support ) - -install(TARGETS kcm_clock DESTINATION ${KDE_INSTALL_PLUGINDIR} ) - -########### next target ############### -#This is only needed when not using timedated and can be removed in future - -add_executable(kcmdatetimehelper helper.cpp ${helper_mocs}) target_link_libraries(kcmdatetimehelper KF5::AuthCore KF5::ConfigCore KF5::KDELibs4Support) +kcoreaddons_desktop_to_json(kcmclock "kcmclock.desktop") + +install(FILES kcmclock.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR}) +install(TARGETS kcmclock DESTINATION ${KDE_INSTALL_PLUGINDIR}/kcms ) install(TARGETS kcmdatetimehelper DESTINATION ${KAUTH_HELPER_INSTALL_DIR}) -kauth_install_helper_files(kcmdatetimehelper org.kde.kcontrol.kcmclock root) +kpackage_install_package(package kcmclock kcms) +kauth_install_helper_files(kcmdatetimehelper org.kde.kcontrol.kcmclock root) kauth_install_actions(org.kde.kcontrol.kcmclock kcmclock_actions.actions) - -########### install files ############### - -install( FILES clock.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR} ) diff --git a/kcms/dateandtime/dtime.h b/kcms/dateandtime/dtime.h deleted file mode 100644 --- a/kcms/dateandtime/dtime.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - * dtime.h - * - * Copyright (C) 1998 Luca Montecchiani - * - * 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 option) 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. - * - */ - -#ifndef dtime_included -#define dtime_included - -#include "ui_dateandtime.h" - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -class Kclock; -class QTimeEdit; - -namespace Plasma { - class Svg; -} - -class Dtime : public QWidget, public Ui::DateAndTime -{ - Q_OBJECT - public: - explicit Dtime( QWidget *parent, bool haveTimedated); - - void processHelperErrors( int code ); - void load(); - - QString selectedTimeZone() const; - QStringList ntpServers() const; - bool ntpEnabled() const; - QDateTime userTime() const; - - QString quickHelp() const; - -Q_SIGNALS: - void timeChanged(bool); - - private Q_SLOTS: - void configChanged(); - void serverTimeCheck(); - void timeout(); - void set_time(); - void changeDate(const QDate&); - -private: - void currentZone(); - void findNTPutility(); - QString ntpUtility; - - QTimeEdit *timeEdit; - - Kclock *kclock; - - QTime time; - QDate date; - QTimer internalTimer; - - QString timeServer; - int BufI; - bool refresh; - bool ontimeout; - bool m_haveTimedated; -}; - -class Kclock : public QWidget -{ - Q_OBJECT - -public: - Kclock( QWidget *parent=nullptr ); - ~Kclock() override; - - void setTime(const QTime&); - -protected: - void paintEvent( QPaintEvent *event ) override; - void showEvent( QShowEvent *event ) override; - void resizeEvent( QResizeEvent *event ) override; - -private: - void setClockSize(const QSize &size); - void drawHand(QPainter *p, const QRect &rect, const qreal verticalTranslation, const qreal rotation, const QString &handName); - void paintInterface(QPainter *p, const QRect &rect); - -private: - QTime time; - Plasma::Svg *m_theme; - enum RepaintCache { - RepaintNone, - RepaintAll, - RepaintHands - }; - RepaintCache m_repaintCache; - QPixmap m_faceCache; - QPixmap m_handsCache; - QPixmap m_glassCache; - qreal m_verticalTranslation; -}; - -#endif // dtime_included diff --git a/kcms/dateandtime/dtime.cpp b/kcms/dateandtime/dtime.cpp deleted file mode 100644 --- a/kcms/dateandtime/dtime.cpp +++ /dev/null @@ -1,489 +0,0 @@ -/* - * dtime.cpp - * - * Copyright (C) 1998 Luca Montecchiani - * - * Plasma analog-clock drawing code: - * - * Copyright 2007 by Aaron Seigo - * Copyright 2007 by Riccardo Iaconelli - * - * 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 option) 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. - * - */ -#include "dtime.h" - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "timedated_interface.h" - -#include "helper.h" - -Dtime::Dtime(QWidget * parent, bool haveTimeDated): - QWidget(parent), - m_haveTimedated(haveTimeDated) -{ - setupUi(this); - - connect(setDateTimeAuto, &QCheckBox::toggled, this, &Dtime::serverTimeCheck); - connect(setDateTimeAuto, &QCheckBox::toggled, this, &Dtime::configChanged); - - timeServerList->setEditable(false); - connect(timeServerList, static_cast(&QComboBox::activated), this, &Dtime::configChanged); - connect(timeServerList, &QComboBox::editTextChanged, this, &Dtime::configChanged); - connect(setDateTimeAuto, &QCheckBox::toggled, timeServerList, &QComboBox::setEnabled); - timeServerList->setEnabled(false); - timeServerList->setEditable(true); - - if (!haveTimeDated) { - findNTPutility(); - if (ntpUtility.isEmpty()) { - QString toolTip = i18n("No NTP utility has been found. " - "Install 'ntpdate' or 'rdate' command to enable automatic " - "updating of date and time."); - setDateTimeAuto->setEnabled(false); - setDateTimeAuto->setToolTip(toolTip); - timeServerList->setToolTip(toolTip); - } - } - - QVBoxLayout *v2 = new QVBoxLayout( timeBox ); - v2->setContentsMargins( 0, 0, 0, 0 ); - - kclock = new Kclock( timeBox ); - kclock->setObjectName(QStringLiteral("Kclock")); - kclock->setMinimumSize(150,150); - v2->addWidget( kclock ); - - v2->addSpacing( KDialog::spacingHint() ); - - QHBoxLayout *v3 = new QHBoxLayout( ); - v2->addLayout( v3 ); - - v3->addStretch(); - - timeEdit = new QTimeEdit( timeBox ); - timeEdit->setWrapping(true); - timeEdit->setDisplayFormat(KLocale::global()->use12Clock() ? "hh:mm:ss ap" : "HH:mm:ss"); - v3->addWidget(timeEdit); - - v3->addStretch(); - - QString wtstr = i18n("Here you can change the system time. Click into the" - " hours, minutes or seconds field to change the relevant value, either" - " using the up and down buttons to the right or by entering a new value."); - timeEdit->setWhatsThis( wtstr ); - - connect(timeEdit, &QTimeEdit::timeChanged, this, &Dtime::set_time); - connect(cal, &KDatePicker::dateChanged, this, &Dtime::changeDate); - - connect(&internalTimer, &QTimer::timeout, this, &Dtime::timeout); - - kclock->setEnabled(false); - - //Timezone - connect(tzonelist, &K4TimeZoneWidget::itemSelectionChanged, this, &Dtime::configChanged); - tzonesearch->setTreeWidget(tzonelist); -} - -void Dtime::currentZone() -{ - KTimeZone localZone = KSystemTimeZones::local(); - - if (localZone.abbreviations().isEmpty()) { - m_local->setText(i18nc("%1 is name of time zone", "Current local time zone: %1", - K4TimeZoneWidget::displayName(localZone))); - } else { - m_local->setText(i18nc("%1 is name of time zone, %2 is its abbreviation", - "Current local time zone: %1 (%2)", - K4TimeZoneWidget::displayName(localZone), - QString::fromUtf8(localZone.abbreviations().first()))); - } -} - -void Dtime::serverTimeCheck() { - // Enable time and date if the ntp utility is missing - bool enabled = ntpUtility.isEmpty() || !setDateTimeAuto->isChecked(); - cal->setEnabled(enabled); - timeEdit->setEnabled(enabled); - //kclock->setEnabled(enabled); -} - -void Dtime::findNTPutility(){ - QByteArray envpath = qgetenv("PATH"); - if (!envpath.isEmpty() && envpath.startsWith(':')) { - envpath.remove(0, 1); - } - - QString path = QStringLiteral("/sbin:/usr/sbin:"); - if (!envpath.isEmpty()) { - path += QFile::decodeName(envpath); - } else { - path += QLatin1String("/bin:/usr/bin"); - } - - foreach(const QString &possible_ntputility, QStringList() << "ntpdate" << "rdate" ) { - if( !((ntpUtility = KStandardDirs::findExe(possible_ntputility, path)).isEmpty()) ) { - qDebug() << "ntpUtility = " << ntpUtility; - return; - } - } - - qDebug() << "ntpUtility not found!"; -} - -void Dtime::set_time() -{ - if( ontimeout ) - return; - - internalTimer.stop(); - - time = timeEdit->time(); - kclock->setTime( time ); - - emit timeChanged( true ); -} - -void Dtime::changeDate(const QDate &d) -{ - date = d; - emit timeChanged( true ); -} - -void Dtime::configChanged(){ - emit timeChanged( true ); -} - -void Dtime::load() -{ - QString currentTimeZone; - - if (m_haveTimedated) { - OrgFreedesktopTimedate1Interface timeDatedIface(QStringLiteral("org.freedesktop.timedate1"), QStringLiteral("/org/freedesktop/timedate1"), QDBusConnection::systemBus()); - //the server list is not relevant for timesyncd, it fetches it from the network - timeServerList->setVisible(false); - timeServerLabel->setVisible(false); - setDateTimeAuto->setEnabled(timeDatedIface.canNTP()); - setDateTimeAuto->setChecked(timeDatedIface.nTP()); - - currentTimeZone = timeDatedIface.timezone(); - } else { - // The config is actually written to the system config, but the user does not have any local config, - // since there is nothing writing it. - KConfig _config( QStringLiteral("kcmclockrc"), KConfig::NoGlobals ); - KConfigGroup config(&_config, "NTP"); - timeServerList->clear(); - timeServerList->addItems(config.readEntry("servers", - i18n("Public Time Server (pool.ntp.org),\ - asia.pool.ntp.org,\ - europe.pool.ntp.org,\ - north-america.pool.ntp.org,\ - oceania.pool.ntp.org")).split(',', QString::SkipEmptyParts)); - setDateTimeAuto->setChecked(config.readEntry("enabled", false)); - - if (ntpUtility.isEmpty()) { - timeServerList->setEnabled(false); - } - currentTimeZone = KSystemTimeZones::local().name(); - } - - // Reset to the current date and time - time = QTime::currentTime(); - date = QDate::currentDate(); - cal->setDate(date); - - // start internal timer - internalTimer.start( 1000 ); - - timeout(); - - //Timezone - currentZone(); - - tzonelist->setSelected(currentTimeZone, true); - emit timeChanged(false); -} - -QString Dtime::selectedTimeZone() const -{ - QStringList selectedZones(tzonelist->selection()); - if (!selectedZones.isEmpty()) { - return selectedZones.first(); - } - - return QString(); -} - -QStringList Dtime::ntpServers() const -{ - // Save the order, but don't duplicate! - QStringList list; - if( timeServerList->count() != 0) - list.append(timeServerList->currentText()); - for ( int i=0; icount();i++ ) { - QString text = timeServerList->itemText(i); - if( !list.contains(text) ) - list.append(text); - // Limit so errors can go away and not stored forever - if( list.count() == 10) - break; - } - return list; -} - -bool Dtime::ntpEnabled() const -{ - return setDateTimeAuto->isChecked(); -} - -QDateTime Dtime::userTime() const -{ - return QDateTime(date, QTime(timeEdit->time())); -} - -void Dtime::processHelperErrors( int code ) -{ - if( code & ClockHelper::NTPError ) { - KMessageBox::error( this, i18n("Unable to contact time server: %1.", timeServer) ); - setDateTimeAuto->setChecked( false ); - } - if( code & ClockHelper::DateError ) { - KMessageBox::error( this, i18n("Can not set date.")); - } - if( code & ClockHelper::TimezoneError) - KMessageBox::error( this, i18n("Error setting new time zone."), - i18n("Time zone Error")); -} - -void Dtime::timeout() -{ - // get current time - time = QTime::currentTime(); - - ontimeout = true; - timeEdit->setTime(time); - ontimeout = false; - - kclock->setTime( time ); -} - -QString Dtime::quickHelp() const -{ - return i18n("

Date & Time

This system settings 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."); -} - -Kclock::Kclock(QWidget *parent) - : QWidget(parent) -{ - m_theme = new Plasma::Svg(this); - m_theme->setImagePath(QStringLiteral("widgets/clock")); - m_theme->setContainsMultipleImages(true); -} - -Kclock::~Kclock() -{ - delete m_theme; -} - -void Kclock::showEvent( QShowEvent *event ) -{ - setClockSize( size() ); - QWidget::showEvent( event ); -} - -void Kclock::resizeEvent( QResizeEvent * ) -{ - setClockSize( size() ); -} - -void Kclock::setClockSize(const QSize &size) -{ - int dim = qMin(size.width(), size.height()); - QSize newSize = QSize(dim, dim) * devicePixelRatioF(); - - if (newSize != m_faceCache.size()) { - m_faceCache = QPixmap(newSize); - m_handsCache = QPixmap(newSize); - m_glassCache = QPixmap(newSize); - m_faceCache.setDevicePixelRatio(devicePixelRatioF()); - m_handsCache.setDevicePixelRatio(devicePixelRatioF()); - m_glassCache.setDevicePixelRatio(devicePixelRatioF()); - - m_theme->resize(QSize(dim, dim)); - m_repaintCache = RepaintAll; - } -} - -void Kclock::setTime(const QTime &time) -{ - if (time.minute() != this->time.minute() || time.hour() != this->time.hour()) { - if (m_repaintCache == RepaintNone) { - m_repaintCache = RepaintHands; - } - } - this->time = time; - update(); -} - -void Kclock::drawHand(QPainter *p, const QRect &rect, const qreal verticalTranslation, const qreal rotation, const QString &handName) -{ - // this code assumes the following conventions in the svg file: - // - the _vertical_ position of the hands should be set with respect to the center of the face - // - the _horizontal_ position of the hands does not matter - // - the _shadow_ elements should have the same vertical position as their _hand_ element counterpart - - QRectF elementRect; - QString name = handName + "HandShadow"; - if (m_theme->hasElement(name)) { - p->save(); - - elementRect = m_theme->elementRect(name); - if( rect.height() < 64 ) - elementRect.setWidth( elementRect.width() * 2.5 ); - static const QPoint offset = QPoint(2, 3); - - p->translate(rect.x() + (rect.width() / 2) + offset.x(), rect.y() + (rect.height() / 2) + offset.y()); - p->rotate(rotation); - p->translate(-elementRect.width()/2, elementRect.y()-verticalTranslation); - m_theme->paint(p, QRectF(QPointF(0, 0), elementRect.size()), name); - - p->restore(); - } - - p->save(); - - name = handName + "Hand"; - elementRect = m_theme->elementRect(name); - if (rect.height() < 64) { - elementRect.setWidth(elementRect.width() * 2.5); - } - - p->translate(rect.x() + rect.width()/2, rect.y() + rect.height()/2); - p->rotate(rotation); - p->translate(-elementRect.width()/2, elementRect.y()-verticalTranslation); - m_theme->paint(p, QRectF(QPointF(0, 0), elementRect.size()), name); - - p->restore(); -} - -void Kclock::paintInterface(QPainter *p, const QRect &rect) -{ - const bool m_showSecondHand = true; - - // compute hand angles - const qreal minutes = 6.0 * time.minute() - 180; - const qreal hours = 30.0 * time.hour() - 180 + - ((time.minute() / 59.0) * 30.0); - qreal seconds = 0; - if (m_showSecondHand) { - static const double anglePerSec = 6; - seconds = anglePerSec * time.second() - 180; - } - - // paint face and glass cache - QRect faceRect = m_faceCache.rect(); - QRect targetRect = QRect(QPoint(0, 0), QSize(m_faceCache.width() / devicePixelRatioF(), m_faceCache.height() / devicePixelRatioF())); - - if (m_repaintCache == RepaintAll) { - m_faceCache.fill(Qt::transparent); - m_glassCache.fill(Qt::transparent); - - QPainter facePainter(&m_faceCache); - QPainter glassPainter(&m_glassCache); - facePainter.setRenderHint(QPainter::SmoothPixmapTransform); - glassPainter.setRenderHint(QPainter::SmoothPixmapTransform); - - m_theme->paint(&facePainter, targetRect, QStringLiteral("ClockFace")); - - glassPainter.save(); - QRectF elementRect = QRectF(QPointF(0, 0), m_theme->elementSize(QStringLiteral("HandCenterScrew"))); - glassPainter.translate(faceRect.width() / (2 * devicePixelRatioF()) - elementRect.width() / 2, faceRect.height() / (2 * devicePixelRatioF()) - elementRect.height() / 2); - m_theme->paint(&glassPainter, elementRect, QStringLiteral("HandCenterScrew")); - glassPainter.restore(); - - m_theme->paint(&glassPainter, targetRect, QStringLiteral("Glass")); - - // get vertical translation, see drawHand() for more details - m_verticalTranslation = m_theme->elementRect(QStringLiteral("ClockFace")).center().y(); - } - - // paint hour and minute hands cache - if (m_repaintCache == RepaintHands || m_repaintCache == RepaintAll) { - m_handsCache.fill(Qt::transparent); - - QPainter handsPainter(&m_handsCache); - handsPainter.drawPixmap(targetRect, m_faceCache, faceRect); - handsPainter.setRenderHint(QPainter::SmoothPixmapTransform); - - drawHand(&handsPainter, targetRect, m_verticalTranslation, hours, QStringLiteral("Hour")); - drawHand(&handsPainter, targetRect, m_verticalTranslation, minutes, QStringLiteral("Minute")); - } - - // reset repaint cache flag - m_repaintCache = RepaintNone; - - // paint caches and second hand - if (targetRect.width() < rect.width()) { - targetRect.moveLeft((rect.width() - targetRect.width()) / 2); - } - - p->drawPixmap(targetRect, m_handsCache, faceRect); - if (m_showSecondHand) { - p->setRenderHint(QPainter::SmoothPixmapTransform); - drawHand(p, targetRect, m_verticalTranslation, seconds, QStringLiteral("Second")); - } - p->drawPixmap(targetRect, m_glassCache, faceRect); -} - -void Kclock::paintEvent( QPaintEvent * ) -{ - QPainter paint(this); - - paint.setRenderHint(QPainter::Antialiasing); - paintInterface(&paint, rect()); -} - diff --git a/kcms/dateandtime/clock.desktop b/kcms/dateandtime/kcmclock.desktop rename from kcms/dateandtime/clock.desktop rename to kcms/dateandtime/kcmclock.desktop --- a/kcms/dateandtime/clock.desktop +++ b/kcms/dateandtime/kcmclock.desktop @@ -1,11 +1,11 @@ [Desktop Entry] -Exec=kcmshell5 clock +Exec=kcmshell5 kcmclock Icon=preferences-system-time Type=Service X-KDE-ServiceTypes=KCModule X-DocPath=kcontrol/clock/index.html -X-KDE-Library=kcm_clock +X-KDE-Library=kcmclock X-KDE-ParentApp=kcontrol #should this be in system settings when we can get to it through the panel? diff --git a/kcms/dateandtime/main.h b/kcms/dateandtime/main.h --- a/kcms/dateandtime/main.h +++ b/kcms/dateandtime/main.h @@ -22,29 +22,82 @@ #define main_included #include +#include +#include +#include class Dtime; class QTabWidget; - -class KclockModule : public KCModule +class KClockModule : public KQuickAddons::ConfigModule { - Q_OBJECT + Q_OBJECT + Q_PROPERTY(QTime time READ time WRITE setTime NOTIFY timeChanged) + Q_PROPERTY(QDate date READ date WRITE setDate NOTIFY dateChanged) + Q_PROPERTY(bool ntpEnabled READ ntpEnabled WRITE setNtpEnabled NOTIFY ntpEnabledChanged) + Q_PROPERTY(bool hasTimedated READ hasTimedated WRITE setHasTimedated NOTIFY hasTimedatedChanged) + Q_PROPERTY(QStringList ntpServers READ ntpServers WRITE setNtpServers NOTIFY ntpServersChanged) + Q_PROPERTY(QString localTimeZone READ localTimeZone WRITE setLocalTimeZone NOTIFY localTimeZoneChanged) + Q_PROPERTY(QString localTimeZoneAbreviation READ localTimeZoneAbreviation WRITE setLocalTimeZoneAbreviation NOTIFY localTimeZoneAbreviationChanged) + Q_PROPERTY(QString selectedTimeZone READ selectedTimeZone WRITE setSelectedTimeZone NOTIFY selectedTimeZoneChanged) + Q_PROPERTY(QString errorMessage READ errorMessage WRITE setErrorMessage NOTIFY errorMessageChanged) public: - explicit KclockModule(QWidget *parent, const QVariantList &); + explicit KClockModule(QObject *parent, const QVariantList &args); + void save() override; + void load() override; + + QTime time() const; + QDate date() const; + bool ntpEnabled() const; + bool hasTimedated() const; + QStringList ntpServers() const; + QString localTimeZone() const; + QString localTimeZoneAbreviation() const; + QString selectedTimeZone() const; + QString errorMessage() const; + + void setTime(const QTime& value); + void setDate(const QDate& value); + void setNtpEnabled(bool value); + void setHasTimedated(bool value); + void setNtpServers(const QStringList& value); + void setLocalTimeZone(const QString& value); + void setLocalTimeZoneAbreviation(const QString& value); + void setSelectedTimeZone(const QString& value); + void setErrorMessage(const QString& value); + QDateTime userTime() const; + + /* Qt lacks a method to deal with Time Zones in Qml. */ + Q_INVOKABLE QStringList timeZoneList() const; - void save() override; - void load() override; +Q_SIGNALS: + void timeChanged(); + void dateChanged(); + void ntpEnabledChanged(); + void hasTimedatedChanged(); + void ntpServersChanged(); + void localTimeZoneChanged(); + void localTimeZoneAbreviationChanged(); + void selectedTimeZoneChanged(); + void errorMessageChanged(); private: - bool kauthSave(); - bool timedatedSave(); + bool kauthSave(); + bool timedatedSave(); + void findNTPutility(); - QTabWidget *tab; - Dtime *dtime; + bool m_hasTimedated; + bool m_ntpEnabled; - bool m_haveTimedated = false; + QStringList m_ntpServers; + QTime m_time; + QDate m_date; + QString m_ntpUtility; + QString m_localTimeZone; + QString m_localTimeZoneAbreviation; + QString m_selectedTimeZone; + QString m_errorMessage; }; #endif // main_included diff --git a/kcms/dateandtime/main.cpp b/kcms/dateandtime/main.cpp --- a/kcms/dateandtime/main.cpp +++ b/kcms/dateandtime/main.cpp @@ -28,106 +28,108 @@ #include #include -#include -#include -#include -#include -#include - -#include "dtime.h" -#include "helper.h" - -#include -#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include "timedated_interface.h" -K_PLUGIN_FACTORY(KlockModuleFactory, registerPlugin();) -K_EXPORT_PLUGIN(KlockModuleFactory("kcmkclock")) - +K_PLUGIN_FACTORY_WITH_JSON(KClockFactory, "kcmclock.json", registerPlugin();) -KclockModule::KclockModule(QWidget *parent, const QVariantList &) - : KCModule(parent) +KClockModule::KClockModule(QObject *parent, const QVariantList &args) + : KQuickAddons::ConfigModule(parent, args) { - auto reply = QDBusConnection::systemBus().call(QDBusMessage::createMethodCall(QStringLiteral("org.freedesktop.DBus"), - QStringLiteral("/org/freedesktop/DBus"), - QStringLiteral("org.freedesktop.DBus"), - QStringLiteral("ListActivatableNames"))); - - if (!reply.arguments().isEmpty() && reply.arguments().first().value().contains(QLatin1String("org.freedesktop.timedate1"))) { - m_haveTimedated = true; - } - - KAboutData *about = - new KAboutData(QStringLiteral("kcmclock"), i18n("KDE Clock Control Module"), QStringLiteral("1.0"), - QString(), KAboutLicense::GPL, - i18n("(c) 1996 - 2001 Luca Montecchiani")); - - about->addAuthor(i18n("Luca Montecchiani"), i18n("Original author"), QStringLiteral("m.luca@usa.net")); - about->addAuthor(i18n("Paul Campbell"), i18n("Current Maintainer"), QStringLiteral("paul@taniwha.com")); - about->addAuthor(i18n("Benjamin Meyer"), i18n("Added NTP support"), QStringLiteral("ben+kcmclock@meyerhome.net")); - setAboutData( about ); - setQuickHelp( i18n("

Date & Time

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.")); - - - QVBoxLayout *layout = new QVBoxLayout(this); - layout->setContentsMargins(0, 0, 0, 0); - layout->setSpacing(KDialog::spacingHint()); - - dtime = new Dtime(this, m_haveTimedated); - layout->addWidget(dtime); - connect(dtime, SIGNAL(timeChanged(bool)), this, SIGNAL(changed(bool))); - - setButtons(Help|Apply); + findNTPutility(); + + auto reply = QDBusConnection::systemBus() + .call(QDBusMessage::createMethodCall( + QStringLiteral("org.freedesktop.DBus"), + QStringLiteral("/org/freedesktop/DBus"), + QStringLiteral("org.freedesktop.DBus"), + QStringLiteral("ListActivatableNames")) + ); + + if (!reply.arguments().isEmpty() && reply.arguments().first().value().contains(QLatin1String("org.freedesktop.timedate1"))) { + m_hasTimedated = true; + qDebug() << "Has timedated"; + } else { + qDebug() << "Does not have timedated"; + } - if (m_haveTimedated) { - setAuthAction(KAuth::Action(QStringLiteral("org.freedesktop.timedate1.set-time"))); + auto *about = new KAboutData(QStringLiteral("kcmclock"), i18n("KDE Clock Control Module"), QStringLiteral("1.0"), + QString(), KAboutLicense::GPL, + i18n("(c) 1996 - 2001 Luca Montecchiani")); + + about->addAuthor(i18n("Luca Montecchiani"), i18n("Original author"), QStringLiteral("m.luca@usa.net")); + about->addAuthor(i18n("Paul Campbell"), i18n("Current Maintainer"), QStringLiteral("paul@taniwha.com")); + about->addAuthor(i18n("Benjamin Meyer"), i18n("Added NTP support"), QStringLiteral("ben+kcmclock@meyerhome.net")); + about->addAuthor(i18n("Benjamin Meyer"), i18n("Port to Qml"), QStringLiteral("ben+kcmclock@meyerhome.net")); + + setAboutData( about ); + setQuickHelp( i18n("

Date & Time

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.")); + + if (m_hasTimedated) { + // TODO: Re Enable + setAuthActionName(QStringLiteral("org.freedesktop.timedate1.set-time")); } else { //auth action name will be automatically guessed from the KCM name qWarning() << "Timedated not found, using legacy saving mode"; - setNeedsAuthorization(true); + // setNeedsAuthorization(true); } + load(); } -bool KclockModule::kauthSave() +bool KClockModule::kauthSave() { - QVariantMap helperargs; - helperargs[QStringLiteral("ntp")] = true; - helperargs[QStringLiteral("ntpServers")] = dtime->ntpServers(); - helperargs[QStringLiteral("ntpEnabled")] = dtime->ntpEnabled(); - - if (!dtime->ntpEnabled()) { - QDateTime newTime = dtime->userTime(); - qDebug() << "Set date to " << dtime->userTime(); - helperargs[QStringLiteral("date")] = true; - helperargs[QStringLiteral("newdate")] = QString::number(newTime.toTime_t()); - helperargs[QStringLiteral("olddate")] = QString::number(::time(nullptr)); - } + QVariantMap helperargs = { + {QStringLiteral("ntp"), true}, + {QStringLiteral("ntpServers"), ntpServers()}, + {QStringLiteral("ntpEnabled"), ntpEnabled()} + }; + + if (ntpEnabled()) { + QDateTime newTime = userTime(); + helperargs[QStringLiteral("date")] = true; + helperargs[QStringLiteral("newdate")] = QString::number(newTime.toTime_t()); + helperargs[QStringLiteral("olddate")] = QString::number(::time(nullptr)); + } - QString selectedTimeZone = dtime->selectedTimeZone(); - if (!selectedTimeZone.isEmpty()) { - helperargs[QStringLiteral("tz")] = true; - helperargs[QStringLiteral("tzone")] = selectedTimeZone; - } else { - helperargs[QStringLiteral("tzreset")] = true; // make the helper reset the timezone - } + if (!m_selectedTimeZone.isEmpty()) { + helperargs[QStringLiteral("tz")] = true; + helperargs[QStringLiteral("tzone")] = m_selectedTimeZone; + } else { + helperargs[QStringLiteral("tzreset")] = true; // make the helper reset the timezone + } - Action action = authAction(); - action.setArguments(helperargs); + //TODO: What to do with authAction()? - ExecuteJob *job = action.execute(); - bool rc = job->exec(); - if (!rc) { - KMessageBox::error(this, i18n("Unable to authenticate/execute the action: %1, %2", job->error(), job->errorString())); - } - return rc; + KAuth::Action action = KAuth::Action(authActionName()); + action.setArguments(helperargs); + + // ExecuteJob *job = action.execute(); + // bool rc = job->exec(); + // if (!rc) { + // TODO: Move this away from a Message Box. + // KMessageBox::error(nullptr, i18n("Unable to authenticate/execute the action: %1, %2", job->error(), job->errorString())); + // } + return true; // rc; } -bool KclockModule::timedatedSave() +bool KClockModule::timedatedSave() { OrgFreedesktopTimedate1Interface timedateIface(QStringLiteral("org.freedesktop.timedate1"), QStringLiteral("/org/freedesktop/timedate1"), QDBusConnection::systemBus()); @@ -138,75 +140,230 @@ //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 //timedated processes these in parallel and will return an error otherwise - auto reply = timedateIface.SetNTP(dtime->ntpEnabled(), true); + auto reply = timedateIface.SetNTP(ntpEnabled(), true); reply.waitForFinished(); if (reply.isError()) { - KMessageBox::error(this, i18n("Unable to change NTP settings")); + setErrorMessage(i18n("Unable to change NTP settings")); qWarning() << "Failed to enable NTP" << reply.error().name() << reply.error().message(); rc = false; } - - if (!dtime->ntpEnabled()) { - qint64 timeDiff = dtime->userTime().toMSecsSinceEpoch() - QDateTime::currentMSecsSinceEpoch(); + if (!ntpEnabled()) { + qint64 timeDiff = userTime().toMSecsSinceEpoch() - QDateTime::currentMSecsSinceEpoch(); //*1000 for milliseconds -> microseconds auto reply = timedateIface.SetTime(timeDiff * 1000, true, true); reply.waitForFinished(); if (reply.isError()) { - KMessageBox::error(this, i18n("Unable to set current time")); + setErrorMessage(i18n("Unable to set current time")); qWarning() << "Failed to set current time" << reply.error().name() << reply.error().message(); rc = false; } } - QString selectedTimeZone = dtime->selectedTimeZone(); - if (!selectedTimeZone.isEmpty()) { - auto reply = timedateIface.SetTimezone(selectedTimeZone, true); + if (!m_selectedTimeZone.isEmpty()) { + auto reply = timedateIface.SetTimezone(m_selectedTimeZone, true); reply.waitForFinished(); if (reply.isError()) { - KMessageBox::error(this, i18n("Unable to set timezone")); + setErrorMessage(i18n("Unable to set timezone")); qWarning() << "Failed to set timezone" << reply.error().name() << reply.error().message(); rc = false; } } return rc; } -void KclockModule::save() +void KClockModule::save() { - setDisabled(true); + const bool success = m_hasTimedated ? timedatedSave() : kauthSave(); + + if (success) { + QDBusMessage msg = QDBusMessage::createSignal( + QStringLiteral("/org/kde/kcmshell_clock"), + QStringLiteral("org.kde.kcmshell_clock"), + QStringLiteral("clockUpdated")); + QDBusConnection::sessionBus().send(msg); + } - bool success = false; - if (m_haveTimedated) { - success = timedatedSave(); - } else { - success = kauthSave(); - } + // 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())); +} + +void KClockModule::load() +{ + + QString currentTimeZone; + + if (m_hasTimedated) { + OrgFreedesktopTimedate1Interface timeDatedIface( + QStringLiteral("org.freedesktop.timedate1"), + QStringLiteral("/org/freedesktop/timedate1"), + QDBusConnection::systemBus() + ); + currentTimeZone = timeDatedIface.timezone(); + } else { + // The config is actually written to the system config, but the user does not have any local config, + // since there is nothing writing it. + KConfig _config( QStringLiteral("kcmclockrc"), KConfig::NoGlobals ); + KConfigGroup config(&_config, "NTP"); + + m_ntpServers.clear(); + setNtpServers(config.readEntry("servers", + i18n("Public Time Server (pool.ntp.org),\ + asia.pool.ntp.org,\ + europe.pool.ntp.org,\ + north-america.pool.ntp.org,\ + oceania.pool.ntp.org")) + .split(',', QString::SkipEmptyParts)); + setNtpEnabled(config.readEntry("enabled", false)); + + currentTimeZone = QTimeZone::systemTimeZone().displayName(QDateTime::currentDateTime()); + } + + // Reset to the current date and time + setTime(QTime::currentTime()); + setDate(QDate::currentDate()); + setLocalTimeZone(QTimeZone::systemTimeZone().displayName(QDateTime::currentDateTime())); +} - if (success) { - QDBusMessage msg = QDBusMessage::createSignal(QStringLiteral("/org/kde/kcmshell_clock"), QStringLiteral("org.kde.kcmshell_clock"), QStringLiteral("clockUpdated")); - QDBusConnection::sessionBus().send(msg); +void KClockModule::findNTPutility(){ + QByteArray envpath = qgetenv("PATH"); + if (!envpath.isEmpty() && envpath.startsWith(':')) { + envpath.remove(0, 1); } - // 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. + QString path = QStringLiteral("/sbin:/usr/sbin:") + + (!envpath.isEmpty() ? QFile::decodeName(envpath) : QLatin1String("/bin:/usr/bin")); - // setDisabled(false) happens in load(), since QTimer::singleShot is non-blocking - if (!m_haveTimedated) { - QTimer::singleShot(5000, this, SLOT(load())); - } else { - load(); + for(const QString &possible_ntputility : {QStringLiteral("ntpdate"), QStringLiteral("rdate")} ) { + const QString executable = KStandardDirs::findExe(possible_ntputility, path); + if(!executable.isEmpty()) { + m_ntpUtility = executable; + return; + } } +} +/* There's no Qml module for Timezones in the Free Qt Version */ +QStringList KClockModule::timeZoneList() const +{ + static QStringList availableTimezones; + if (availableTimezones.isEmpty()) { + const auto timeZones = QTimeZone::availableTimeZoneIds(); + for(auto &timeZone : timeZones) { + availableTimezones.append(timeZone); + } + } + return availableTimezones; } -void KclockModule::load() +QDateTime KClockModule::userTime() const { - dtime->load(); - setDisabled(false); + return QDateTime(m_date, m_time); +} + +QTime KClockModule::time() const { + return m_time; +} + +QDate KClockModule::date() const { + return m_date; +} + +bool KClockModule::ntpEnabled() const { + return m_ntpEnabled; +} + +bool KClockModule::hasTimedated() const { + return m_hasTimedated; +} + +QStringList KClockModule::ntpServers() const { + return m_ntpServers; +} + +QString KClockModule::localTimeZone() const { + return m_localTimeZone; +} + +QString KClockModule::localTimeZoneAbreviation() const { + return m_localTimeZoneAbreviation; +} + +QString KClockModule::selectedTimeZone() const { + return m_selectedTimeZone; +} + +QString KClockModule::errorMessage() const { + return m_errorMessage; +} + + +void KClockModule::setTime(const QTime& value) { + if (m_time != value) { + m_time = value; + emit timeChanged(); + } +} + +void KClockModule::setDate(const QDate& value) { + if (m_date != value) { + m_date = value; + emit dateChanged(); + } } +void KClockModule::setNtpEnabled(bool value) { + if (m_ntpEnabled != value) { + m_ntpEnabled = value; + emit ntpEnabledChanged(); + } +} + +void KClockModule::setHasTimedated(bool value) { + if (m_hasTimedated != value) { + m_hasTimedated = value; + emit hasTimedatedChanged(); + } +} + +void KClockModule::setNtpServers(const QStringList& value) { + if (m_ntpServers != value) { + m_ntpServers = value; + emit ntpServersChanged(); + } +} + +void KClockModule::setLocalTimeZone(const QString& value) { + if (m_localTimeZone != value) { + m_localTimeZone = value; + emit localTimeZoneChanged(); + } +} + +void KClockModule::setLocalTimeZoneAbreviation(const QString& value) { + if (m_localTimeZoneAbreviation != value) { + m_localTimeZoneAbreviation = value; + emit localTimeZoneAbreviationChanged(); + } +} + +void KClockModule::setSelectedTimeZone(const QString& value) { + if (m_selectedTimeZone != value) { + m_selectedTimeZone = value; + emit selectedTimeZoneChanged(); + } +} + +void KClockModule::setErrorMessage(const QString& value) { + if (m_errorMessage != value) { + m_errorMessage = value; + emit errorMessageChanged(); + } +} + + #include "main.moc" diff --git a/kcms/dateandtime/package/contents/ui/Clock.qml b/kcms/dateandtime/package/contents/ui/Clock.qml new file mode 100644 --- /dev/null +++ b/kcms/dateandtime/package/contents/ui/Clock.qml @@ -0,0 +1,99 @@ +import QtQuick 2.0 + +Item { + id : clock + width: { + if (ListView.view && ListView.view.width >= 200) + return ListView.view.width / Math.floor(ListView.view.width / 200.0); + else + return 200; + } + + height: { + if (ListView.view && ListView.view.height >= 240) + return ListView.view.height; + else + return 240; + } + + property alias city: cityLabel.text + property int hours + property int minutes + property int seconds + property real shift + property bool night: false + property bool internationalTime: true //Unset for local time + + function timeChanged() { + var date = new Date; + hours = internationalTime ? date.getUTCHours() + Math.floor(clock.shift) : date.getHours() + night = ( hours < 7 || hours > 19 ) + minutes = internationalTime ? date.getUTCMinutes() + ((clock.shift % 1) * 60) : date.getMinutes() + seconds = date.getUTCSeconds(); + } + + Timer { + interval: 100; running: true; repeat: true; + onTriggered: clock.timeChanged() + } + + Item { + anchors.centerIn: parent + width: 200; height: 240 + + Image { id: background; source: "clock.png"; visible: clock.night == false } + Image { source: "clock-night.png"; visible: clock.night == true } + + Image { + x: 92.5; y: 27 + source: "hour.png" + transform: Rotation { + id: hourRotation + origin.x: 7.5; origin.y: 73; + angle: (clock.hours * 30) + (clock.minutes * 0.5) + Behavior on angle { + SpringAnimation { spring: 2; damping: 0.2; modulus: 360 } + } + } + } + + Image { + x: 93.5; y: 17 + source: "minute.png" + transform: Rotation { + id: minuteRotation + origin.x: 6.5; origin.y: 83; + angle: clock.minutes * 6 + Behavior on angle { + SpringAnimation { spring: 2; damping: 0.2; modulus: 360 } + } + } + } + + Image { + x: 97.5; y: 20 + source: "second.png" + transform: Rotation { + id: secondRotation + origin.x: 2.5; origin.y: 80; + angle: clock.seconds * 6 + Behavior on angle { + SpringAnimation { spring: 2; damping: 0.2; modulus: 360 } + } + } + } + + Image { + anchors.centerIn: background; source: "center.png" + } + + Text { + id: cityLabel + y: 210; anchors.horizontalCenter: parent.horizontalCenter + color: "white" + font.family: "Helvetica" + font.bold: true; font.pixelSize: 16 + style: Text.Raised; styleColor: "black" + } + } +} diff --git a/kcms/dateandtime/package/contents/ui/center.png b/kcms/dateandtime/package/contents/ui/center.png new file mode 100644 index 0000000000000000000000000000000000000000..7fbd802a44e4242cb2ce11fd78efa0e2e9123591 GIT binary patch literal 765 zc$@+K0s{SsP)wm?cmZyN`*KT0&&bzT5WB7@L(auxOrlE<9L|IL z&i8)L&uf>4S*T)OE8F->35(24d5sX5GeKScQ1}Zk0{U)AOeg56F@@r z9&i_k$@vIi#IHYN1sVpTz-?fBeSQ6DCX;#L`@V5q_xHlW!biXb&PAI*M>7u%0F42O z&CSilY&QEQkw`q(Y+9|>+rz`dd@7ZCCyf6B4GRvyQa(U#F>=uz;8CGacvY|0gJD{& zR*!%=;GskpvRQC?*oNeXsg;$Lg75nb(|9~ScW`jV&hDzY)D;F81#ZpE%q)7I$4wLnZ)|KVO0gq?V>GZMsffhm@h95(I@ZZ# z@|p5Cm%2j9NTbnchQr~}K4*QUR;xAXnTaa{0<=q|(&w9`!7|R}a-RSX+iE?)KF|i5 zdwY9dZUWrtbf{D+rE0Z$O1Fn?9|syZpgTcsu~% z2a54IaFR}^*UIJc*Fkx8UH5EjYin(1XXi+K>f-M$<%5e|vAb&Q;)&8-GE=~VTrQWI zpPx@oPftIdoSeL0E|vh*lr=Z!!jm-Q2}+N`W?w>U9_n|b&dh-G77}8A*@a$++Si(L{Cv$O@m%xtVMFJ vUl6^??F-^D;CUJdtS*47?_QuH>?{8O-DBHcK9x2C00000NkvXXu0mjfY~)gG literal 0 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 literal 0 Hc$@S5XZA=gNem21n~>K_tJtn1s_6$UOZIsR+L`EXE2xEdi5^!9X!;Qq6YdPEf@op znzW5GVK%I>#h~<{?7$Dg&irToyGv52TB?T%2Z9kQkrAE|Cf4IZ6pc&9g(%Pf9atn5 zfGp;zE($dv%#vssSQl6onq+tbKA8)1z#6a#>;SvOHn2fWv4M&WRAH({Vk}rK6bf6m zZCkZk?a;C;Y_I|>@#&}$C!^TF2JLqH+;N<{YPD)tDwUgNv)Sl&yBC_K zt<`Fsn5KEw@AsMKc@e!{Ps!)=r=3oxOxsgMaePh1V)4jz-8aUV7AN2t)&|hvSh&tl z;;7Crj6FPA5GW$J9bMP=#p0xxJD3&hJ8|lmDo$D!tSj@KENx5M()Rzc{bTX0{mQG7 zwx#XA_dd(3lD2w)}~eU(b2(d6GgC60tZW;UtCa$u#i@cuz6e2gZ@OR1f*o z02rhY5BYR)awHDJa0nL1Q*4hgNAAY4ZJLe?LnwHfVc&<`BMk{r6Q4G>@B980Ou>I7 zUTJ@bi))a(=E5&mg^T4|-3fx=0E+K{7r+A^V9kWwGZ$if06Au)A-PzA_y7O^07*qo IM6N<$g8KRIG5`Po literal 0 Hc$@ + +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 option) 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, see . +*********************************************************************/ +import QtQuick 2.12 +import QtQuick.Layouts 1.13 +import QtQuick.Controls 2.5 as QQC2 +import QtQuick.Controls 1.4 as QQC1 // calendar + +import org.kde.kirigami 2.5 as Kirigami +import org.kde.kcm 1.2 as KCM + +import org.kde.colorcorrect 0.1 as CC + +KCM.SimpleKCM { + id: root + ColumnLayout { + QQC2.TabBar { + id: tabBar + Layout.fillWidth: true + QQC2.TabButton { + text: i18n("Date and Time") + } + QQC2.TabButton { + text: i18n("Time Zones") + } + } + + StackLayout { + currentIndex: tabBar.currentIndex + + // ---- Date and Time + ColumnLayout { + Layout.fillWidth: true + Layout.fillHeight: true + QQC2.CheckBox { + Layout.fillWidth: true + text: "Set date and time automatically" + checked: kcm.ntpEnabled + onCheckedChanged: kcm.ntpEnabled = checked + } + RowLayout { + Layout.fillWidth: true + QQC2.Label { + text: i18n("Time Server") + } + QQC2.ComboBox { + Layout.fillWidth: true + model: kcm.ntpServers + } + } + RowLayout { + QQC1.Calendar { + Layout.fillWidth: true + Layout.fillHeight: true + } + Clock { + Layout.fillWidth: true + Layout.fillHeight: true + } + } + } + + // ---- Time Zones + ColumnLayout { + Layout.fillWidth: true + Layout.fillHeight: true + QQC2.Label { + Layout.fillWidth: true + text: i18n("To change the local time zone, select your area from the list below.") + } + QQC2.Label { + Layout.fillWidth: true + text: i18n("Current local time zone:") + } + QQC2.TextField { + Layout.fillWidth: true + placeholderText: i18n("Search....") + } + + /* This is not working as I tougth it would, it fails to be properly a scroll view. */ + QQC2.ScrollView { + id: bgObject + Component.onCompleted: bgObject.background.visible = true + Layout.fillWidth: true + Layout.fillHeight: true + clip: true + + /* If I uncommment this list view to show the time zones, the list is infinite =/ */ + /* + ListView { + id: timeZonesList + + model: kcm.timeZoneList() + highlight: Rectangle { color: "lightsteelblue" } + focus: true + + delegate: MouseArea { + width: timeZonesList.width + height: childrenRect.height + + QQC2.Label { + text: modelData + } + + onClicked: { + timeZonesList.currentIndex = index + } + } + + Component.onCompleted : { + timeZonesList.currentIndex = -1 + } + } + */ + } + } + } + } +} diff --git a/kcms/dateandtime/package/contents/ui/minute.png b/kcms/dateandtime/package/contents/ui/minute.png new file mode 100644 index 0000000000000000000000000000000000000000..e2f216c897a743df08d1777ec463b5b9b1586b67 GIT binary patch literal 528 zc$@(c0`L8aP)ZrkLwR+a=cFRJDQXI#-;GbxfWV%w{ z!Z18wFk?ax1p8*pFA_d&n8_?sL08gDWRk`i&r&gz3iDN(mc%BVBA=ktc`HPQnpm9D z;&L+c8MjVWN}k)CtdtC*v{@(lUpj)>DDipbBy4h$vsO>$Xq}v$dqYW{^Dh5%f9~aY z=dzh|a$X2wvo(bKt&!6m`(M#jgp{} zj`*MwX31&rW5mM~d|40te^Smnpf}<)dd2&x8n3h@sk{N6AV?bJSAMLK2BxQ`@B%@? zP*PKV#`{uB%YprW)MDud@jPx$X5h2C&KG>8 h(|ZK^Jumn`d;`g8&$yBJ4|V_m002ovPDHLkV1hcFVi*7b literal 0 Hc$@