Warning, file /utilities/kclock/src/plasmoid/KClock_KWeather_3x3/kclock_kweather_3x3.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 SPDX-FileCopyrightText: 2020 HanY <hanyoung@protonmail.com> 0003 SPDX-License-Identifier: LGPL-2.1-or-later 0004 */ 0005 0006 #include "kclock_kweather_3x3.h" 0007 0008 #include <KLocalizedString> 0009 0010 #include <QDBusConnection> 0011 #include <QDBusInterface> 0012 #include <QDBusReply> 0013 #include <QJsonArray> 0014 #include <QJsonDocument> 0015 #include <QProcess> 0016 #include <QTimer> 0017 #include <QXmlStreamReader> 0018 0019 KClock_KWeather_3x3::KClock_KWeather_3x3(QObject *parent, const QVariantList &args) 0020 : Plasma::Applet(parent, args) 0021 { 0022 // KWeather 0023 auto system = QLocale::system().measurementSystem(); 0024 if (system == QLocale::MetricSystem || system == QLocale::ImperialUKSystem) 0025 m_isCelsius = true; 0026 else 0027 m_isCelsius = false; 0028 QDBusConnection::sessionBus().connect(QStringLiteral("org.kde.kweather"), 0029 QStringLiteral("/"), 0030 QStringLiteral("org.kde.kweather.LocationModel"), 0031 QStringLiteral("removed"), 0032 this, 0033 SLOT(addCity(QString))); 0034 QDBusConnection::sessionBus().connect(QStringLiteral("org.kde.kweather"), 0035 QStringLiteral("/"), 0036 QStringLiteral("org.kde.kweather.LocationModel"), 0037 QStringLiteral("added"), 0038 this, 0039 SLOT(removeCity(QString))); 0040 QDBusInterface *interface = new QDBusInterface(QStringLiteral("org.kde.kweather"), 0041 QStringLiteral("/locations"), 0042 QStringLiteral("org.freedesktop.DBus.Introspectable"), 0043 QDBusConnection::sessionBus(), 0044 this); 0045 QDBusReply<QString> reply = interface->call(QStringLiteral("Introspect")); 0046 if (reply.isValid()) { 0047 auto xmlMsg = reply.value(); 0048 QXmlStreamReader xml(xmlMsg); 0049 while (!xml.atEnd()) { 0050 xml.readNext(); 0051 if (xml.name() == "node" && xml.attributes().hasAttribute("name")) { 0052 m_location = xml.attributes().value("name").toString(); 0053 break; 0054 } 0055 } 0056 } 0057 delete interface; 0058 if (!m_location.isEmpty()) { 0059 m_KWeatherInterface = new QDBusInterface(QStringLiteral("org.kde.kweather"), 0060 QStringLiteral("/locations/") + m_location, 0061 QStringLiteral("org.kde.kweather.WeatherLocation"), 0062 QDBusConnection::sessionBus(), 0063 this); 0064 QDBusConnection::sessionBus().connect(QStringLiteral("org.kde.kweather"), 0065 QStringLiteral("/locations/") + m_location, 0066 QStringLiteral("org.kde.kweather.WeatherLocation"), 0067 QStringLiteral("currentForecastChange"), 0068 this, 0069 SLOT(update())); 0070 0071 QDBusReply<QString> reply = m_KWeatherInterface->call("getWeatherData"); 0072 this->parse(QJsonDocument::fromJson(reply.value().toUtf8())); 0073 this->m_cityName = m_KWeatherInterface->property("name").toString(); 0074 Q_EMIT locationChanged(); 0075 } 0076 0077 // KClock 0078 m_timer = new QTimer(this); 0079 connect(m_timer, &QTimer::timeout, this, &KClock_KWeather_3x3::initialTimeUpdate); 0080 m_timer->setSingleShot(true); 0081 0082 m_minutesCounter = QTime::currentTime().msecsSinceStartOfDay() / (1000 * 60); // seconds since start of the day 0083 // initial interval is milliseconds to next minute 0084 m_timer->start((60 - (QTime::currentTime().msecsSinceStartOfDay() / 1000) % 60) * 1000); // seconds to next minute 0085 0086 if (!QDBusConnection::sessionBus().connect(QStringLiteral("org.kde.kclockd"), 0087 QStringLiteral("/Alarms"), 0088 QStringLiteral("org.kde.kclock.AlarmModel"), 0089 QStringLiteral("nextAlarm"), 0090 this, 0091 SLOT(updateAlarm(qulonglong)))) 0092 m_string = QStringLiteral("connect failed"); 0093 0094 interface = new QDBusInterface(QStringLiteral("org.kde.kclockd"), 0095 QStringLiteral("/Alarms"), 0096 QStringLiteral("org.kde.kclock.AlarmModel"), 0097 QDBusConnection::sessionBus(), 0098 this); 0099 QDBusReply<quint64> KClock_reply = interface->call(QStringLiteral("getNextAlarm")); 0100 if (reply.isValid()) { 0101 auto alarmTime = KClock_reply.value(); 0102 if (alarmTime > 0) { 0103 auto dateTime = QDateTime::fromSecsSinceEpoch(alarmTime).toLocalTime(); 0104 m_string = QStringLiteral("%1 %2").arg(m_local.standaloneDayName(dateTime.date().dayOfWeek(), QLocale::ShortFormat), 0105 m_local.toString(dateTime.time(), QStringLiteral("hh:mm"))); 0106 m_hasAlarm = true; 0107 } else 0108 m_hasAlarm = false; 0109 } 0110 emit propertyChanged(); 0111 } 0112 0113 void KClock_KWeather_3x3::parse(QJsonDocument doc) 0114 { 0115 QJsonArray dailyArray = doc[QStringLiteral("dailyForecasts")].toArray(); 0116 QJsonArray hourlyArray = doc[QStringLiteral("hourlyForecasts")].toArray(); 0117 m_description = hourlyArray.at(0).toObject()[QStringLiteral("weatherDescription")].toString(); 0118 m_weatherIcon = hourlyArray.at(0).toObject()[QStringLiteral("weatherIcon")].toString(); 0119 if (m_isCelsius) 0120 m_tempNow = QString::number(hourlyArray.at(0).toObject()[QStringLiteral("temperature")].toDouble()) + QStringLiteral("°C"); 0121 else 0122 m_tempNow = QString::number(hourlyArray.at(0).toObject()[QStringLiteral("temperature")].toDouble() * 1.8 + 32) + QStringLiteral("°"); 0123 0124 if (m_isCelsius) { 0125 m_maxTemp = static_cast<int>(dailyArray.first().toObject()[QStringLiteral("maxTemp")].toDouble()); 0126 m_minTemp = static_cast<int>(dailyArray.first().toObject()[QStringLiteral("minTemp")].toDouble()); 0127 } else { 0128 m_maxTemp = dailyArray.first().toObject()[QStringLiteral("maxTemp")].toDouble() * 1.8 + 32; 0129 m_minTemp = dailyArray.first().toObject()[QStringLiteral("minTemp")].toDouble() * 1.8 + 32; 0130 } 0131 Q_EMIT dataUpdated(); 0132 } 0133 void KClock_KWeather_3x3::updateAlarm(qulonglong time) 0134 { 0135 auto dateTime = QDateTime::fromSecsSinceEpoch(time).toLocalTime(); 0136 if (time > 0) { 0137 m_string = QStringLiteral("%1 %2").arg(m_local.standaloneDayName(dateTime.date().dayOfWeek(), QLocale::ShortFormat), 0138 m_local.toString(dateTime.time(), QStringLiteral("hh:mm"))); 0139 m_hasAlarm = true; 0140 } else { 0141 m_hasAlarm = false; 0142 } 0143 emit propertyChanged(); 0144 } 0145 void KClock_KWeather_3x3::openKClock() 0146 { 0147 m_process = new QProcess(this); 0148 m_process->start(QStringLiteral("kclock"), QStringList()); 0149 } 0150 void KClock_KWeather_3x3::initialTimeUpdate() 0151 { 0152 emit timeChanged(); 0153 disconnect(m_timer, &QTimer::timeout, this, &KClock_KWeather_3x3::initialTimeUpdate); // disconnect 0154 m_timer->setSingleShot(false); 0155 connect(m_timer, &QTimer::timeout, this, &KClock_KWeather_3x3::updateTime); 0156 m_timer->start(60000); // update every minute 0157 } 0158 0159 void KClock_KWeather_3x3::updateTime() 0160 { 0161 Q_EMIT timeChanged(); 0162 m_minutesCounter++; 0163 if (m_minutesCounter >= 60 * 24) { 0164 m_minutesCounter = 0; 0165 Q_EMIT dateChanged(); 0166 } 0167 } 0168 QString KClock_KWeather_3x3::time() 0169 { 0170 return m_local.toString(QTime::currentTime(), QStringLiteral("hh:mm")); 0171 } 0172 QString KClock_KWeather_3x3::date() 0173 { 0174 return m_local.toString(QDate::currentDate(), QStringLiteral("ddd, MMMM d")); 0175 } 0176 KClock_KWeather_3x3::~KClock_KWeather_3x3() 0177 { 0178 } 0179 0180 K_PLUGIN_CLASS(KClock_KWeather_3x3) 0181 0182 #include "kclock_kweather_3x3.moc"