diff --git a/kdeui/widgets/ktitlewidget.cpp b/kdeui/widgets/ktitlewidget.cpp index cae2a254..7541e6c9 100644 --- a/kdeui/widgets/ktitlewidget.cpp +++ b/kdeui/widgets/ktitlewidget.cpp @@ -50,8 +50,7 @@ public: { // FIXME: we need the usability color styles to implement different // yet palette appropriate colours for the different use cases! - // also .. should we include an icon here, - // perhaps using the imageLabel? + // also .. should we include an icon here, perhaps using the imageLabel? switch (messageType) { case InfoMessage: case WarningMessage: diff --git a/kutils/knetworkmanager/CMakeLists.txt b/kutils/knetworkmanager/CMakeLists.txt index 1d9d1c7d..03bf0471 100644 --- a/kutils/knetworkmanager/CMakeLists.txt +++ b/kutils/knetworkmanager/CMakeLists.txt @@ -37,4 +37,4 @@ install( DESTINATION ${KDE4_LIB_INSTALL_DIR} ) -# add_subdirectory(kded) +add_subdirectory(kded) diff --git a/kutils/knetworkmanager/kded/CMakeLists.txt b/kutils/knetworkmanager/kded/CMakeLists.txt new file mode 100644 index 00000000..07af5f22 --- /dev/null +++ b/kutils/knetworkmanager/kded/CMakeLists.txt @@ -0,0 +1,36 @@ +########### next target ############### + +set(kded_knetworkmanager_SRCS + kded_knetworkmanager.cpp + ${CMAKE_CURRENT_BINARY_DIR}/org.kde.knetworkmanager.xml +) + +qt4_generate_dbus_interface(kded_knetworkmanager.h org.kde.knetworkmanager.xml) + +kde4_add_plugin(kded_knetworkmanager ${kded_knetworkmanager_SRCS}) +target_link_libraries(kded_knetworkmanager PRIVATE + ${QT_QTDBUS_LIBRARY} + kdecore + kdeui + knetworkmanager +) + +install( + TARGETS kded_knetworkmanager + DESTINATION ${KDE4_PLUGIN_INSTALL_DIR} +) + +install( + FILES knetworkmanager.desktop + DESTINATION ${KDE4_SERVICES_INSTALL_DIR}/kded +) + +install( + FILES ${CMAKE_CURRENT_BINARY_DIR}/org.kde.knetworkmanager.xml + DESTINATION ${KDE4_DBUS_INTERFACES_INSTALL_DIR} +) + +install( + FILES knetworkmanager.notifyrc + DESTINATION ${KDE4_DATA_INSTALL_DIR}/knetworkmanager +) diff --git a/kutils/knetworkmanager/kded/kded_knetworkmanager.cpp b/kutils/knetworkmanager/kded/kded_knetworkmanager.cpp new file mode 100644 index 00000000..bb828d70 --- /dev/null +++ b/kutils/knetworkmanager/kded/kded_knetworkmanager.cpp @@ -0,0 +1,80 @@ +/* This file is part of the KDE libraries + Copyright (C) 2023 Ivailo Monev + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2, as published by the Free Software Foundation. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "kded_knetworkmanager.h" +#include "kpluginfactory.h" +#include "knotification.h" +#include "klocale.h" +#include "kdebug.h" + +K_PLUGIN_FACTORY(KNetworkManagerModuleFactory, registerPlugin();) +K_EXPORT_PLUGIN(KNetworkManagerModuleFactory("knetworkmanager")) + +KNetworkManagerModule::KNetworkManagerModule(QObject *parent, const QList &args) + : KDEDModule(parent), + m_networkmanager(nullptr) +{ + Q_UNUSED(args); + + m_networkmanager = new KNetworkManager(this); + connect( + m_networkmanager, SIGNAL(statusChanged(KNetworkManager::KNetworkStatus)), + this, SLOT(slotStatusChanged(KNetworkManager::KNetworkStatus)) + ); +} + +KNetworkManagerModule::~KNetworkManagerModule() +{ + m_networkmanager->deleteLater(); +} + +int KNetworkManagerModule::status() const +{ + return static_cast(m_networkmanager->status()); +} + +void KNetworkManagerModule::slotStatusChanged(const KNetworkManager::KNetworkStatus status) +{ + KNotification *knotification = nullptr; + switch (status) { + case KNetworkManager::UnknownStatus: { + knotification = new KNotification("Unknown"); + knotification->setComponentData(KComponentData("knetworkmanager")); + knotification->setTitle(i18n("Network status changed")); + knotification->setText(i18n("Network status is unknown")); + break; + } + case KNetworkManager::ConnectedStatus: { + knotification = new KNotification("Connected"); + knotification->setComponentData(KComponentData("knetworkmanager")); + knotification->setTitle(i18n("Network status changed")); + knotification->setText(i18n("Network status is connected")); + break; + } + case KNetworkManager::DisconnectedStatus: { + knotification = new KNotification("Disconnected"); + knotification->setComponentData(KComponentData("knetworkmanager")); + knotification->setTitle(i18n("Network status changed")); + knotification->setText(i18n("Network status is offline")); + break; + } + } + knotification->sendEvent(); +} + +#include "moc_kded_knetworkmanager.cpp" diff --git a/kutils/knetworkmanager/kded/kded_knetworkmanager.h b/kutils/knetworkmanager/kded/kded_knetworkmanager.h new file mode 100644 index 00000000..d3cfa78b --- /dev/null +++ b/kutils/knetworkmanager/kded/kded_knetworkmanager.h @@ -0,0 +1,45 @@ +/* This file is part of the KDE libraries + Copyright (C) 2023 Ivailo Monev + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2, as published by the Free Software Foundation. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KNETWORKMANAGER_KDED_H +#define KNETWORKMANAGER_KDED_H + +#include "kdedmodule.h" +#include "knetworkmanager.h" + +#include + +class KNetworkManagerModule: public KDEDModule +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "org.kde.knetworkmanager") + +public: + KNetworkManagerModule(QObject *parent, const QList &args); + ~KNetworkManagerModule(); + + Q_SCRIPTABLE int status() const; + +private Q_SLOTS: + void slotStatusChanged(const KNetworkManager::KNetworkStatus status); + +private: + KNetworkManager *m_networkmanager; +}; + +#endif // KNETWORKMANAGER_KDED_H diff --git a/kutils/knetworkmanager/kded/knetworkmanager.desktop b/kutils/knetworkmanager/kded/knetworkmanager.desktop new file mode 100644 index 00000000..be7bd687 --- /dev/null +++ b/kutils/knetworkmanager/kded/knetworkmanager.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Icon=network-connect +Name=Network Manager +Comment=Notifies about network status changes +Type=Service +X-KDE-ServiceTypes=KDEDModule +X-KDE-Library=knetworkmanager +X-KDE-DBus-ModuleName=knetworkmanager +X-KDE-Kded-autoload=true +X-KDE-Kded-load-on-demand=true +OnlyShowIn=KDE; diff --git a/kutils/knetworkmanager/kded/knetworkmanager.notifyrc b/kutils/knetworkmanager/kded/knetworkmanager.notifyrc new file mode 100644 index 00000000..8111a660 --- /dev/null +++ b/kutils/knetworkmanager/kded/knetworkmanager.notifyrc @@ -0,0 +1,22 @@ +[Global] +Name=knetworkmanager +Comment=Network manager +IconName=network-workgroup + +[Event/Unknown] +Name=Network status is unknown +Action=Sound|Popup +Sound=KDE-Im-Cant-Connect.ogg +IconName=dialog-warning + +[Event/Disconnected] +Name=Network status is disconnected +Action=Sound|Popup +Sound=KDE-Im-Contact-Out.ogg +IconName=network-disconnect + +[Event/Connected] +Name=Network status is connected +Action=Sound|Popup +Sound=KDE-Im-Contact-In.ogg +IconName=network-connect \ No newline at end of file diff --git a/kutils/knetworkmanager/knetworkmanager.cpp b/kutils/knetworkmanager/knetworkmanager.cpp index 32173404..5a9ba390 100644 --- a/kutils/knetworkmanager/knetworkmanager.cpp +++ b/kutils/knetworkmanager/knetworkmanager.cpp @@ -19,11 +19,131 @@ #include "knetworkmanager.h" #include "kdebug.h" -#include +#include +#include +#include +#include #include -static KNetworkManager::KNetworkStatus kGetNetworkStatus() +// for reference: +// https://developer-old.gnome.org/NetworkManager/stable/gdbus-org.freedesktop.NetworkManager.html +// https://git.kernel.org/pub/scm/network/connman/connman.git/tree/doc/overview-api.txt +// https://git.kernel.org/pub/scm/network/connman/connman.git/tree/doc/manager-api.txt + +typedef QMap ConnmanPropertiesType; + +class KNetworkManagerPrivate : public QObject { + Q_OBJECT +public: + KNetworkManagerPrivate(KNetworkManager *parent); + ~KNetworkManagerPrivate(); + + KNetworkManager::KNetworkStatus status() const; + +protected: + // QObject reimplementation + void timerEvent(QTimerEvent *event) final; + +private Q_SLOTS: + void nmStateChanged(const uint nmstate); + void cmStateChanged(const QString &cmname, const QDBusVariant &cmvalue); + +private: + void emitSignals(); + + KNetworkManager* m_q; + QDBusInterface m_nm; + QDBusInterface m_cm; + int m_timerid; + KNetworkManager::KNetworkStatus m_status; +}; + +KNetworkManagerPrivate::KNetworkManagerPrivate(KNetworkManager *parent) + : QObject(parent), + m_q(parent), + m_nm("org.freedesktop.NetworkManager", "/org/freedesktop/NetworkManager", "org.freedesktop.NetworkManager", QDBusConnection::systemBus()), + m_cm("net.connman", "/", "net.connman.Manager", QDBusConnection::systemBus()), + m_timerid(0), + m_status(KNetworkManager::UnknownStatus) +{ + m_status = status(); + if (m_nm.isValid()) { + kDebug() << "Using org.freedesktop.NetworkManager"; + connect( + &m_nm, SIGNAL(StateChanged(uint)), + this, SLOT(nmStateChanged(uint)) + ); + } else if (m_cm.isValid()) { + kDebug() << "Using net.connman"; + connect( + &m_cm, SIGNAL(PropertyChanged(QString,QDBusVariant)), + this, SLOT(cmStateChanged(QString,QDBusVariant)) + ); + } else { + kDebug() << "Using fallback"; + m_timerid = startTimer(2000); + } +} + +KNetworkManagerPrivate::~KNetworkManagerPrivate() +{ + if (m_timerid > 0) { + killTimer(m_timerid); + } +} + +KNetworkManager::KNetworkStatus KNetworkManagerPrivate::status() const +{ + if (m_nm.isValid()) { + QDBusReply nmreply = m_nm.call("state"); + const uint nmstate = nmreply.value(); + KNetworkManager::KNetworkStatus result = KNetworkManager::UnknownStatus; + switch (nmstate) { + case 0: + case 10: + case 20: { + result = KNetworkManager::DisconnectedStatus; + break; + } + case 50: + case 60: + case 70: { + result = KNetworkManager::ConnectedStatus; + break; + } + case 30: + case 40: { + // connecting/disconnecting + break; + } + default: { + kWarning() << "Unknown org.freedesktop.NetworkManager state" << nmstate; + break; + } + } + return result; + } + + if (m_cm.isValid()) { + KNetworkManager::KNetworkStatus result = KNetworkManager::UnknownStatus; + QDBusReply connmanreply = m_cm.call("GetProperties"); + const ConnmanPropertiesType connmanproperties = connmanreply.value(); + const QString connmanstate = connmanproperties.value("State").toString(); + if (connmanstate == QLatin1String("ready") || connmanstate == QLatin1String("online")) { + result = KNetworkManager::ConnectedStatus; + } else if (connmanstate == QLatin1String("association") || connmanstate == QLatin1String("configuration") + || connmanstate == QLatin1String("disconnect")) { + // connecting/disconnecting + result = KNetworkManager::UnknownStatus; + } else if (connmanstate == QLatin1String("offline") || connmanstate == QLatin1String("idle")) { + result = KNetworkManager::DisconnectedStatus; + } else { + kWarning() << "Unknown net.connman state" << connmanstate; + } + return result; + } + KNetworkManager::KNetworkStatus result = KNetworkManager::DisconnectedStatus; foreach (const QNetworkInterface &iface, QNetworkInterface::allInterfaces()) { const QNetworkInterface::InterfaceFlags iflags = iface.flags(); @@ -35,30 +155,46 @@ static KNetworkManager::KNetworkStatus kGetNetworkStatus() return result; } -class KNetworkManagerPrivate - { -public: - KNetworkManagerPrivate(); - - KNetworkManager::KNetworkStatus status; - QTimer* statustimer; -}; - -KNetworkManagerPrivate::KNetworkManagerPrivate() - : status(KNetworkManager::UnknownStatus), - statustimer(nullptr) +void KNetworkManagerPrivate::timerEvent(QTimerEvent *event) { + if (event->timerId() == m_timerid) { + emitSignals(); + event->accept(); + } else { + event->ignore(); + } } +void KNetworkManagerPrivate::emitSignals() +{ + const int oldstatus = m_status; + m_status = status(); + + kDebug() << "Old status" << oldstatus << "new status" << m_status; + + if (oldstatus != m_status) { + emit m_q->statusChanged(m_status); + } +} + +void KNetworkManagerPrivate::nmStateChanged(const uint nmstate) +{ + Q_UNUSED(nmstate); + emitSignals(); +} + +void KNetworkManagerPrivate::cmStateChanged(const QString &name, const QDBusVariant &value) +{ + Q_UNUSED(name); + Q_UNUSED(value); + emitSignals(); +} + + KNetworkManager::KNetworkManager(QObject *parent) : QObject(parent), - d(new KNetworkManagerPrivate()) + d(new KNetworkManagerPrivate(this)) { - d->status = kGetNetworkStatus(); - - d->statustimer = new QTimer(this); - connect(d->statustimer, SIGNAL(timeout()), this, SLOT(_checkStatus())); - d->statustimer->start(2000); } KNetworkManager::~KNetworkManager() @@ -68,7 +204,7 @@ KNetworkManager::~KNetworkManager() KNetworkManager::KNetworkStatus KNetworkManager::status() const { - return d->status; + return d->status(); } bool KNetworkManager::isSupported() @@ -76,14 +212,5 @@ bool KNetworkManager::isSupported() return true; } -void KNetworkManager::_checkStatus() -{ - KNetworkManager::KNetworkStatus newstatus = kGetNetworkStatus(); - if (d->status != newstatus) { - d->status = newstatus; - kDebug() << "Status changed to" << newstatus; - emit statusChanged(newstatus); - } -} - #include "moc_knetworkmanager.cpp" +#include "knetworkmanager.moc" diff --git a/kutils/knetworkmanager/knetworkmanager.h b/kutils/knetworkmanager/knetworkmanager.h index 2fc8ecfc..8c835d01 100644 --- a/kutils/knetworkmanager/knetworkmanager.h +++ b/kutils/knetworkmanager/knetworkmanager.h @@ -22,6 +22,7 @@ #include "knetworkmanager_export.h" #include +#include class KNetworkManagerPrivate; @@ -64,12 +65,13 @@ Q_SIGNALS: */ void statusChanged(const KNetworkManager::KNetworkStatus status); -private Q_SLOTS: - void _checkStatus(); - private: Q_DISABLE_COPY(KNetworkManager); KNetworkManagerPrivate *d; + + friend KNetworkManagerPrivate; }; +Q_DECLARE_METATYPE(KNetworkManager::KNetworkStatus); + #endif // KNETWORKMANAGER_H diff --git a/kutils/kpasswdstore/kded/CMakeLists.txt b/kutils/kpasswdstore/kded/CMakeLists.txt index 8bd9aacd..c274ac5c 100644 --- a/kutils/kpasswdstore/kded/CMakeLists.txt +++ b/kutils/kpasswdstore/kded/CMakeLists.txt @@ -6,7 +6,7 @@ set(kded_kpasswdstore_SRCS ${CMAKE_CURRENT_BINARY_DIR}/org.kde.kpasswdstore.xml ) -qt4_generate_dbus_interface(kded_kpasswdstore.h org.kde.kpasswdstore.xml ) +qt4_generate_dbus_interface(kded_kpasswdstore.h org.kde.kpasswdstore.xml) kde4_add_plugin(kded_kpasswdstore ${kded_kpasswdstore_SRCS}) target_link_libraries(kded_kpasswdstore PRIVATE