diff --git a/kcms/colors/package/metadata.desktop b/kcms/colors/package/metadata.desktop --- a/kcms/colors/package/metadata.desktop +++ b/kcms/colors/package/metadata.desktop @@ -1,131 +1,13 @@ [Desktop Entry] -Name=Colors -Name[af]=Kleure -Name[ar]=الألوان -Name[be]=Колеры -Name[be@latin]=Kolery -Name[bg]=Цветове -Name[bn]=রং -Name[bn_IN]=রং -Name[br]=Livioù -Name[bs]=Boje -Name[ca]=Colors -Name[ca@valencia]=Colors -Name[cs]=Barvy -Name[csb]=Farwë -Name[cy]=Lliwiau -Name[da]=Farver -Name[de]=Farben -Name[el]=Χρώματα -Name[en_GB]=Colours -Name[eo]=Koloroj -Name[es]=Colores -Name[et]=Värvid -Name[eu]=Koloreak -Name[fa]=رنگها -Name[fi]=Värit -Name[fr]=Couleurs -Name[fy]=Kleuren -Name[ga]=Dathanna -Name[gl]=Cores -Name[gu]=રંગો -Name[he]=צבעים -Name[hi]=रंग -Name[hne]=रंग -Name[hr]=Boje -Name[hsb]=Barby -Name[hu]=Színek -Name[ia]=Colores -Name[id]=Warna -Name[is]=Litir -Name[it]=Colori -Name[ja]=色 -Name[ka]=ცვეტები -Name[kk]=Түстер -Name[km]=ពណ៌ -Name[kn]=ಬಣ್ಣಗಳು -Name[ko]=색상 -Name[ku]=Reng -Name[lt]=Spalvos -Name[lv]=Krāsas -Name[mai]=रँग -Name[mk]=Бои -Name[ml]=നിറങ്ങള്‍ -Name[mr]=रंग -Name[ms]=Warna -Name[nb]=Farger -Name[nds]=Klören -Name[ne]=रङ -Name[nl]=Kleuren -Name[nn]=Fargar -Name[oc]=Colors -Name[or]=ରଙ୍ଗ -Name[pa]=ਰੰਗ -Name[pl]=Kolory -Name[pt]=Cores -Name[pt_BR]=Cores -Name[ro]=Culori -Name[ru]=Цвета -Name[se]=Ivnnit -Name[si]=වර්‍ණ -Name[sk]=Farby -Name[sl]=Barve -Name[sr]=Боје -Name[sr@ijekavian]=Боје -Name[sr@ijekavianlatin]=Boje -Name[sr@latin]=Boje -Name[sv]=Färger -Name[ta]=வண்ணங்கள் -Name[te]=రంగులు -Name[tg]=Рангҳо -Name[th]=สี -Name[tr]=Renkler -Name[ug]=رەڭلەر -Name[uk]=Кольори -Name[uz]=Ranglar -Name[uz@cyrillic]=Ранглар -Name[vi]=Màu sắc -Name[wa]=Coleurs -Name[xh]=Imibala -Name[x-test]=xxColorsxx -Name[zh_CN]=颜色 -Name[zh_TW]=顏色 -Comment=Choose color scheme -Comment[ca]=Trieu l'esquema de colors -Comment[ca@valencia]=Trieu l'esquema de colors -Comment[cs]=Vyberte barevné schéma -Comment[de]=Farbschema auswählen -Comment[en_GB]=Choose colour scheme -Comment[es]=Escoger un esquema de color -Comment[eu]=Hautatu kolore-antolaera -Comment[fi]=Valitse väriteema -Comment[fr]=Choisissez le schéma de couleurs -Comment[gl]=Escoller un esquema de cores -Comment[id]=Pilihlah skema warna -Comment[it]=Scegli schema di colori -Comment[ja]=カラースキームを選択 -Comment[ko]=색 배열 선택 -Comment[lt]=Pasirinkti spalvų rinkinį -Comment[nl]=Kleurenschema kiezen -Comment[nn]=Vel fargeoppsett -Comment[pl]=Wybierz zestaw kolorów -Comment[pt]=Escolher o esquema de cores -Comment[pt_BR]=Escolha o esquema de cores -Comment[ru]=Выбор цветовой схемы -Comment[sk]=Vyberte farebnú schému -Comment[sv]=Välj färgschema -Comment[tg]=Нақшаи рангҳоро интихоб намоед -Comment[uk]=Вибір схеми кольорів -Comment[x-test]=xxChoose color schemexx -Comment[zh_CN]=选择配色方案 -Comment[zh_TW]=選擇色彩主題 +Name=Clock +Comment=Configure System Clock -Icon=preferences-desktop-color +Icon=preferences-system-time Type=Service X-KDE-PluginInfo-Author=Kai Uwe Broulik X-KDE-PluginInfo-Email=kde@privat.broulik.de X-KDE-PluginInfo-License=GPL -X-KDE-PluginInfo-Name=kcm_colors +X-KDE-PluginInfo-Name=kcm_clock X-KDE-PluginInfo-Version= X-KDE-PluginInfo-Website= X-KDE-ServiceTypes=Plasma/Generic 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=\"kcm_clock\") -set(kcm_clock_PART_SRCS dtime.cpp main.cpp ) - -ki18n_wrap_ui(kcm_clock_PART_SRCS dateandtime.ui) +set(kcm_clock_PART_SRCS main.cpp ) +# needed for krdb 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_executable(kcmdatetimehelper helper.cpp ${helper_mocs}) target_link_libraries(kcm_clock 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(kcm_clock "kcm_clock.desktop") +kpackage_install_package(package kcm_clock kcms) + +install(FILES kcm_clock.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR}) +install(TARGETS kcm_clock DESTINATION ${KDE_INSTALL_PLUGINDIR}/kcms ) install(TARGETS kcmdatetimehelper DESTINATION ${KAUTH_HELPER_INSTALL_DIR}) -kauth_install_helper_files(kcmdatetimehelper org.kde.kcontrol.kcmclock root) +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/kcm_clock.desktop rename from kcms/dateandtime/clock.desktop rename to kcms/dateandtime/kcm_clock.desktop --- a/kcms/dateandtime/clock.desktop +++ b/kcms/dateandtime/kcm_clock.desktop @@ -1,5 +1,5 @@ [Desktop Entry] -Exec=kcmshell5 clock +Exec=kcmshell5 kcm_clock Icon=preferences-system-time Type=Service X-KDE-ServiceTypes=KCModule 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,79 @@ #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 hasTimedated) + 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; - 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,104 @@ #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, "kcm_clock.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; + } - 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 + // setAuthAction(KAuth::Action(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); } } -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; + // Action action = authAction(); + // 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 +136,217 @@ //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())); +} - if (success) { - QDBusMessage msg = QDBusMessage::createSignal(QStringLiteral("/org/kde/kcmshell_clock"), QStringLiteral("org.kde.kcmshell_clock"), QStringLiteral("clockUpdated")); - QDBusConnection::sessionBus().send(msg); - } +void KClockModule::load() +{ - // 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 currentTimeZone; - // setDisabled(false) happens in load(), since QTimer::singleShot is non-blocking - if (!m_haveTimedated) { - QTimer::singleShot(5000, this, SLOT(load())); - } else { - load(); + 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())); +} + +void KClockModule::findNTPutility(){ + QByteArray envpath = qgetenv("PATH"); + if (!envpath.isEmpty() && envpath.startsWith(':')) { + envpath.remove(0, 1); } + QString path = QStringLiteral("/sbin:/usr/sbin:") + + (!envpath.isEmpty() ? QFile::decodeName(envpath) : QLatin1String("/bin:/usr/bin")); + + for(const QString &possible_ntputility : {QStringLiteral("ntpdate"), QStringLiteral("rdate")} ) { + const QString executable = KStandardDirs::findExe(possible_ntputility, path); + if(!executable.isEmpty()) { + m_ntpUtility = executable; + return; + } + } } -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/main.qml b/kcms/dateandtime/package/contents/ui/main.qml new file mode 100644 diff --git a/kcms/dateandtime/package/metadata.desktop b/kcms/dateandtime/package/metadata.desktop new file mode 100644