diff --git a/modules/time/timesettings.cpp b/modules/time/timesettings.cpp index 0b05897..178c8db 100644 --- a/modules/time/timesettings.cpp +++ b/modules/time/timesettings.cpp @@ -1,393 +1,393 @@ /************************************************************************** * * * Copyright 2005 S.R.Haque . * * Copyright 2009 David Faure * * Copyright 2011-2015 Sebastian Kügler * * Copyright 2015 David Edmundson * * * * 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 "timesettings.h" #include "timezone.h" #include "timezonesmodel.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "timedated_interface.h" #define FORMAT24H "HH:mm:ss" #define FORMAT12H "h:mm:ss ap" K_PLUGIN_FACTORY_WITH_JSON(TimeSettingsFactory, "timesettings.json", registerPlugin();) class TimeSettingsPrivate { public: TimeSettings *q; QString timeFormat; QString timezone; QObject *timeZonesModel; QString timeZoneFilter; QString currentTimeText; QTime currentTime; QDate currentDate; QTimer *timer; bool useNtp; QString errorString; void initSettings(); void initTimeZones(); QString displayName(const KTimeZone &zone); KSharedConfigPtr localeConfig; KConfigGroup localeSettings; KTimeZones *timeZones; QList timezones; }; TimeSettings::TimeSettings(QObject* parent, const QVariantList& args) : KQuickAddons::ConfigModule(parent, args) { qDebug() << "time settings init"; d = new TimeSettingsPrivate; d->q = this; d->timeZones = nullptr; d->timeZonesModel = nullptr; setTimeZone(KSystemTimeZones::local().name()); KAboutData* about = new KAboutData("kcm_mobile_time", i18n("Configure Date and Time"), "0.1", QString(), KAboutLicense::LGPL); about->addAuthor(i18n("Sebastian Kügler"), QString(), "sebas@kde.org"); setAboutData(about); setButtons(Apply | Default); d->initSettings(); // Just for testing that data gets through d->timer = new QTimer(this); d->timer->setInterval(1000); connect(d->timer, &QTimer::timeout, this, &TimeSettings::timeout); d->timer->start(); qDebug() << "TimeSettings module loaded."; } TimeSettings::~TimeSettings() { delete d; } void TimeSettingsPrivate::initTimeZones() { // Collect zones by localized city names, so that they can be sorted properly. QStringList cities; QStringList tz; QHash zonesByCity; if (!timeZones) { timeZones = KSystemTimeZones::timeZones(); // add UTC to the defaults default KTimeZone utc = KTimeZone::utc(); cities.append(utc.name()); zonesByCity.insert(utc.name(), utc); } //qDebug() << " TZ: cities: " << cities; const KTimeZones::ZoneMap zones = timeZones->zones(); QList _zones; QStandardItemModel *_zonesModel = new TimeZonesModel(q); for ( KTimeZones::ZoneMap::ConstIterator it = zones.begin(); it != zones.end(); ++it ) { const KTimeZone zone = it.value(); if (timeZoneFilter.isEmpty() || zone.name().contains(timeZoneFilter, Qt::CaseInsensitive)) { - TimeZone *_zone = new TimeZone(zone); + auto *_zone = new TimeZone(zone); _zones.append(_zone); QStandardItem *item = new QStandardItem(_zone->name()); item->setData(_zone->name().split('/').first(), Qt::UserRole+1); _zonesModel->appendRow(item); } } qDebug() << "Found: " << _zones.count() << " timezones."; //qSort( cities.begin(), cities.end(), localeLessThan ); q->setTimeZones(_zones); q->setTimeZonesModel(_zonesModel); } QString TimeSettingsPrivate::displayName( const KTimeZone &zone ) { return zone.name().toUtf8().replace( '_', ' ' ); } void TimeSettingsPrivate::initSettings() { localeConfig = KSharedConfig::openConfig("kdeglobals", KConfig::SimpleConfig); localeSettings = KConfigGroup(localeConfig, "Locale"); q->setTimeFormat( localeSettings.readEntry( "TimeFormat", QString(FORMAT24H) ) ); // FIXME?! OrgFreedesktopTimedate1Interface timeDatedIface("org.freedesktop.timedate1", "/org/freedesktop/timedate1", QDBusConnection::systemBus()); //the server list is not relevant for timesyncd, it fetches it from the network useNtp = timeDatedIface.nTP(); } void TimeSettings::timeout() { setCurrentTime(QTime::currentTime()); setCurrentDate(QDate::currentDate()); notify(); } QString TimeSettings::currentTimeText() { return d->currentTimeText; } QTime TimeSettings::currentTime() const { return d->currentTime; } void TimeSettings::setCurrentTime(const QTime ¤tTime) { if (d->currentTime != currentTime) { d->currentTime = currentTime; d->currentTimeText = QLocale().toString(QTime::currentTime(), d->timeFormat); emit currentTimeChanged(); } } QDate TimeSettings::currentDate() const { return d->currentDate; } void TimeSettings::setCurrentDate(const QDate ¤tDate) { if (d->currentDate != currentDate) { d->currentDate = currentDate; emit currentDateChanged(); } } bool TimeSettings::useNtp() const { return d->useNtp; } void TimeSettings::setUseNtp(bool ntp) { if (d->useNtp != ntp) { d->useNtp = ntp; saveTime(); emit useNtpChanged(); } } bool TimeSettings::saveTime() { OrgFreedesktopTimedate1Interface timedateIface("org.freedesktop.timedate1", "/org/freedesktop/timedate1", QDBusConnection::systemBus()); bool rc = true; //final arg in each method is "user-interaction" i.e whether it's OK for polkit to ask for auth //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(useNtp(), true); reply.waitForFinished(); if (reply.isError()) { d->errorString = i18n("Unable to change NTP settings"); emit errorStringChanged(); qWarning() << "Failed to enable NTP" << reply.error().name() << reply.error().message(); rc = false; } if (!useNtp()) { QDateTime userTime; userTime.setTime(currentTime()); userTime.setDate(currentDate()); qDebug() << "Setting userTime: " << userTime; qint64 timeDiff = userTime.toMSecsSinceEpoch() - QDateTime::currentMSecsSinceEpoch(); //*1000 for milliseconds -> microseconds auto reply = timedateIface.SetTime(timeDiff * 1000, true, true); reply.waitForFinished(); if (reply.isError()) { d->errorString = i18n("Unable to set current time"); emit errorStringChanged(); qWarning() << "Failed to set current time" << reply.error().name() << reply.error().message(); rc = false; } } saveTimeZone(timeZone()); return rc; } void TimeSettings::saveTimeZone(const QString &newtimezone) { qDebug() << "Saving timezone to config: " << newtimezone; OrgFreedesktopTimedate1Interface timedateIface("org.freedesktop.timedate1", "/org/freedesktop/timedate1", QDBusConnection::systemBus()); if (!newtimezone.isEmpty()) { qDebug() << "Setting timezone: " << newtimezone; auto reply = timedateIface.SetTimezone(newtimezone, true); reply.waitForFinished(); if (reply.isError()) { d->errorString = i18n("Unable to set timezone"); emit errorStringChanged(); qWarning() << "Failed to set timezone" << reply.error().name() << reply.error().message(); } } setTimeZone(newtimezone); emit timeZoneChanged(); notify(); } QString TimeSettings::timeFormat() { return d->timeFormat; } void TimeSettings::setTimeFormat(const QString &timeFormat) { if (d->timeFormat != timeFormat) { d->timeFormat = timeFormat; d->localeSettings.writeEntry("TimeFormat", timeFormat); d->localeConfig->sync(); QDBusMessage msg = QDBusMessage::createSignal("/org/kde/kcmshell_clock", "org.kde.kcmshell_clock", "clockUpdated"); QDBusConnection::sessionBus().send(msg); qDebug() << "time format is now: " << QLocale().toString(QTime::currentTime(), d->timeFormat); emit timeFormatChanged(); timeout(); } } QString TimeSettings::timeZone() { return d->timezone; } void TimeSettings::setTimeZone(const QString &timezone) { if (d->timezone != timezone) { d->timezone = timezone; qDebug() << "timezone changed to: " << timezone; emit timeZoneChanged(); timeout(); } } QList TimeSettings::timeZones() { if (!d->timeZones) { d->initTimeZones(); } return d->timezones; } void TimeSettings::setTimeZones(QList timezones) { d->timezones = timezones; emit timeZonesChanged(); } QObject* TimeSettings::timeZonesModel() { if (!d->timeZones) { d->initTimeZones(); } return d->timeZonesModel; } void TimeSettings::setTimeZonesModel(QObject* timezones) { d->timeZonesModel = timezones; emit timeZonesModelChanged(); } void TimeSettings::timeZoneFilterChanged(const QString &filter) { d->timeZoneFilter = filter; d->timeZoneFilter.replace(' ', '_'); d->initTimeZones(); emit timeZonesChanged(); } bool TimeSettings::twentyFour() { return timeFormat() == FORMAT24H; } void TimeSettings::setTwentyFour(bool t) { if (twentyFour() != t) { if (t) { setTimeFormat(FORMAT24H); } else { setTimeFormat(FORMAT12H); } qDebug() << "T24 toggled: " << t << d->timeFormat; emit twentyFourChanged(); emit currentTimeChanged(); timeout(); } } QString TimeSettings::errorString() { return d->errorString; } void TimeSettings::notify() { QDBusMessage msg = QDBusMessage::createSignal("/org/kde/kcmshell_clock", "org.kde.kcmshell_clock", "clockUpdated"); QDBusConnection::sessionBus().send(msg); } #include "timesettings.moc" diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index af7b617..2471495 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,22 +1,21 @@ - # These are only needed here, consider porting away from both! find_package(Qt5 REQUIRED NO_MODULE COMPONENTS Gui) set(plasma-settings_SRCS main.cpp settingsapp.cpp ) add_executable(plasma-settings ${plasma-settings_SRCS}) target_link_libraries(plasma-settings Qt5::Quick Qt5::Gui KF5::Package KF5::DBusAddons KF5::Declarative KF5::I18n KF5::WindowSystem ) install( TARGETS plasma-settings ${INSTALL_TARGETS_DEFAULT_ARGS} ) diff --git a/src/main.cpp b/src/main.cpp index 937c3f0..becfcde 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,164 +1,164 @@ /*************************************************************************** * * * Copyright 2011-2015 Sebastian Kügler * * * * 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 . * ***************************************************************************/ // std #include #include //own #include "settingsapp.h" // Qt #include #include #include #include #include #include #include // Frameworks #include #include #include #include #include #include #include #include #include static const char description[] = I18N_NOOP("Plasma Mobile Settings"); static const char version[] = "2.0"; static const char HOME_URL[] = "http://plasma-mobile.org"; int main(int argc, char **argv) { QApplication app(argc, argv); KLocalizedString::setApplicationDomain("plasma-settings"); // About data KAboutData aboutData("mobile.plasmasettings", i18n("Settings"), version, i18n("Touch-friendly settings application."), KAboutLicense::GPL, i18n("Copyright 2011-2015, Sebastian Kügler")); aboutData.addAuthor(i18n("Sebastian Kügler"), i18n("Maintainer"), "sebas@kde.org"); aboutData.addAuthor(i18n("Marco Martin"), i18n("Maintainer"), "mart@kde.org"); aboutData.setDesktopFileName("org.kde.mobile.plasmasettings"); KAboutData::setApplicationData(aboutData); app.setWindowIcon(QIcon::fromTheme("preferences-system")); const static auto _l = QStringLiteral("list"); const static auto _m = QStringLiteral("module"); const static auto _f = QStringLiteral("fullscreen"); const static auto _ui = QStringLiteral("layout"); const static auto _ff = QStringLiteral("formfactor"); QCommandLineOption _list = QCommandLineOption(QStringList() << QStringLiteral("l") << _l, i18n("List available settings modules")); QCommandLineOption _module = QCommandLineOption(QStringList() << QStringLiteral("m") << _m, i18n("Settings module to open"), i18n("modulename")); QCommandLineOption _fullscreen = QCommandLineOption(QStringList() << QStringLiteral("f") << _f, i18n("Start window fullscreen")); QCommandLineOption _layout = QCommandLineOption(QStringList() << _ui, i18n("Package to use for the UI (default org.kde.mobile.settings)"), i18n("packagename")); QCommandLineOption _formfactor = QCommandLineOption(QStringList() << QStringLiteral("x") << _ff, i18n("Limit to modules suitable for , e.g. handset, tablet, mediacenter, desktop, test, all (default handset)"), i18n("formfactor")); QCommandLineParser parser; parser.addOption(_list); parser.addOption(_formfactor); parser.addOption(_module); parser.addOption(_fullscreen); parser.addOption(_layout); aboutData.setupCommandLine(&parser); parser.process(app); aboutData.processCommandLine(&parser); if (parser.isSet(_list)) { int nameWidth = 24; QSet seen; std::cout << std::setfill('.'); auto formfactor = parser.value("formfactor"); for (auto plugin : KPackage::PackageLoader::self()->listPackages(QString(), "kpackage/kcms/")) { if (seen.contains(plugin.pluginId())) { continue; } // Filter out modules that are not explicitely suitable for the "handset" formfactor //const QStringList &formFactors = plugin.formFactors(); if (!formfactor.isEmpty() && !plugin.formFactors().contains(formfactor) && formfactor != QStringLiteral("all")) { continue; } const int len = plugin.pluginId().length(); if (len > nameWidth) { nameWidth = len; } seen << plugin.pluginId(); std::cout << plugin.pluginId().toLocal8Bit().data() << ' ' << std::setw(nameWidth - plugin.pluginId().length() + 2) << '.' << ' ' << plugin.description().toLocal8Bit().data() << std::endl; //qDebug() << "Formafactors: " << formFactors; } for (auto plugin : KPluginLoader::findPlugins("kcms")) { if (seen.contains(plugin.pluginId())) { continue; } if (!formfactor.isEmpty() && !plugin.formFactors().contains(formfactor) && formfactor != QStringLiteral("all")) { continue; } const int len = plugin.pluginId().length(); if (len > nameWidth) { nameWidth = len; } std::cout << plugin.pluginId().toLocal8Bit().data() << ' ' << std::setw(nameWidth - plugin.pluginId().length() + 2) << '.' << ' ' << plugin.description().toLocal8Bit().data() << std::endl; } return 0; } const QString module = parser.value(_m); QString ui = parser.isSet(_ui) ? parser.value(_ui) : "org.kde.plasma.settings"; KPackage::Package package = KPackage::PackageLoader::self()->loadPackage("KPackage/GenericQML"); package.setPath(ui); - SettingsApp *settingsApp = new SettingsApp(parser); + auto *settingsApp = new SettingsApp(parser); QQmlApplicationEngine engine; engine.rootContext()->setContextProperty("settingsApp", settingsApp); engine.rootContext()->setContextProperty("startModule", module); engine.load(package.filePath("mainscript")); return app.exec(); }