diff --git a/CMakeLists.txt b/CMakeLists.txt index 1b8e18f49..b081b5748 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -51,6 +51,7 @@ add_subdirectory(daemon) add_subdirectory(plugins) add_subdirectory(plasmoid) add_subdirectory(cli) +add_subdirectory(indicator) add_subdirectory(fileitemactionplugin) if(KF5DocTools_FOUND) add_subdirectory(doc) diff --git a/indicator/CMakeLists.txt b/indicator/CMakeLists.txt new file mode 100644 index 000000000..3652aeae1 --- /dev/null +++ b/indicator/CMakeLists.txt @@ -0,0 +1,2 @@ +add_executable(kdeconnect-indicator main.cpp deviceindicator.cpp) +target_link_libraries(kdeconnect-indicator Qt5::Widgets KF5::CoreAddons KF5::I18n kdeconnectinterfaces) diff --git a/indicator/deviceindicator.cpp b/indicator/deviceindicator.cpp new file mode 100644 index 000000000..93a0528ca --- /dev/null +++ b/indicator/deviceindicator.cpp @@ -0,0 +1,83 @@ +/* + * Copyright 2016 Aleix Pol Gonzalez + * + * 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) version 3 or any later version + * accepted by the membership of KDE e.V. (or its successor approved + * by the membership of KDE e.V.), which shall act as a proxy + * defined in Section 14 of version 3 of the license. + * + * 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 . + */ + +#include "deviceindicator.h" +#include + +template +static void setWhenAvailable(const QDBusPendingReply &pending, W func, QObject* parent) +{ + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pending, parent); + QObject::connect(watcher, &QDBusPendingCallWatcher::finished, + parent, [func](QDBusPendingCallWatcher* watcher) { + watcher->deleteLater(); + QDBusPendingReply reply = *watcher; + func(reply.value()); + }); +} + +class BatteryAction : public QAction +{ +Q_OBJECT +public: + BatteryAction(DeviceDbusInterface* device) + : QAction() + , m_batteryIface(new DeviceBatteryDbusInterface(device->id(), this)) + { + setWhenAvailable(m_batteryIface->charge(), [this](int charge) { setCharge(charge); }, this); + setWhenAvailable(m_batteryIface->isCharging(), [this](bool charging) { setCharging(charging); }, this); + + connect(m_batteryIface, SIGNAL(chargeChanged(int)), this, SLOT(setCharge(int))); + connect(m_batteryIface, SIGNAL(stateChanged(bool)), this, SLOT(setCharging(bool))); + + update(); + } + + void update() { + if (m_charge < 0) + setText(i18n("No Battery")); + else if (m_charging) + setText(i18n("Battery: %1 (Charging)", m_charge)); + else + setText(i18n("Battery: %1", m_charge)); + } + +private Q_SLOTS: + void setCharge(int charge) { m_charge = charge; update(); } + void setCharging(bool charging) { m_charging = charging; update(); } + +private: + DeviceBatteryDbusInterface* m_batteryIface; + int m_charge = -1; + bool m_charging = false; +}; + + +DeviceIndicator::DeviceIndicator(DeviceDbusInterface* device) + : QMenu(device->name(), nullptr) + , m_device(device) +{ + setIcon(QIcon::fromTheme(device->iconName())); + setToolTip(device->type()); + + addAction(new BatteryAction(device)); +} + +#include "deviceindicator.moc" diff --git a/indicator/deviceindicator.h b/indicator/deviceindicator.h new file mode 100644 index 000000000..e2f71347b --- /dev/null +++ b/indicator/deviceindicator.h @@ -0,0 +1,37 @@ +/* + * Copyright 2016 Aleix Pol Gonzalez + * + * 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) version 3 or any later version + * accepted by the membership of KDE e.V. (or its successor approved + * by the membership of KDE e.V.), which shall act as a proxy + * defined in Section 14 of version 3 of the license. + * + * 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 . + */ + +#ifndef DEVICEINDICATOR_H +#define DEVICEINDICATOR_H + +#include +#include "interfaces/dbusinterfaces.h" + +class DeviceIndicator : public QMenu +{ + Q_OBJECT + public: + DeviceIndicator(DeviceDbusInterface* device); + + private: + DeviceDbusInterface* m_device; +}; + +#endif // DEVICEINDICATOR_H diff --git a/indicator/main.cpp b/indicator/main.cpp new file mode 100644 index 000000000..df59edd8d --- /dev/null +++ b/indicator/main.cpp @@ -0,0 +1,69 @@ +/* + * Copyright 2016 Aleix Pol Gonzalez + * + * 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) version 3 or any later version + * accepted by the membership of KDE e.V. (or its successor approved + * by the membership of KDE e.V.), which shall act as a proxy + * defined in Section 14 of version 3 of the license. + * + * 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 . + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "interfaces/devicesmodel.h" +#include "interfaces/notificationsmodel.h" +#include "interfaces/dbusinterfaces.h" +#include "kdeconnect-version.h" +#include "deviceindicator.h" + +int main(int argc, char** argv) +{ + QApplication app(argc, argv); + KAboutData about("kdeconnect-cli", + i18n("KDE Connect Indicator"), + QStringLiteral(KDECONNECT_VERSION_STRING), + i18n("KDE Connect Indicator tool"), + KAboutLicense::GPL, + i18n("(C) 2016 Aleix Pol Gonzalez")); + KAboutData::setApplicationData(about); + + DevicesModel model; + + QMenu menu; + QSystemTrayIcon systray; + systray.setIcon(QIcon::fromTheme("kdeconnect")); + systray.setContextMenu(&menu); + systray.setVisible(true); + + QObject::connect(&model, &DevicesModel::rowsInserted, &model, [&menu, &model](const QModelIndex& /*parent*/, int first, int last) { + qDebug() << "wooooo" << first << last; + for (int i=first; i<=last; ++i) { + DeviceDbusInterface* device = model.getDevice(first); + auto indicator = new DeviceIndicator(device); + QObject::connect(device, &DeviceDbusInterface::destroyed, indicator, &QObject::deleteLater); + + menu.addMenu(indicator); + } + }); + + return app.exec(); +} diff --git a/interfaces/devicesmodel.h b/interfaces/devicesmodel.h index 28014b670..26e8af3ba 100644 --- a/interfaces/devicesmodel.h +++ b/interfaces/devicesmodel.h @@ -72,6 +72,8 @@ public: Q_SCRIPTABLE DeviceDbusInterface* getDevice(int row) const; QHash roleNames() const override; + QVector devices() const { return m_deviceList; } + private Q_SLOTS: void deviceAdded(const QString& id); void deviceRemoved(const QString& id);