Added BroadcastTcpLinkProvider
This commit is contained in:
parent
04c5955526
commit
e6dfaa5916
12 changed files with 384 additions and 25 deletions
|
@ -3,6 +3,7 @@ set(kded_kdeconnect_SRCS
|
|||
linkproviders/linkprovider.cpp
|
||||
linkproviders/loopbacklinkprovider.cpp
|
||||
linkproviders/avahitcplinkprovider.cpp
|
||||
linkproviders/broadcasttcplinkprovider.cpp
|
||||
|
||||
devicelinks/devicelink.cpp
|
||||
devicelinks/echodevicelink.cpp
|
||||
|
|
|
@ -29,27 +29,25 @@
|
|||
#include "packageinterfaces/batterypackageinterface.h"
|
||||
#include "packageinterfaces/mpriscontrolpackageinterface.h"
|
||||
|
||||
#include "linkproviders/broadcasttcplinkprovider.h"
|
||||
#include "linkproviders/avahitcplinkprovider.h"
|
||||
#include "linkproviders/loopbacklinkprovider.h"
|
||||
|
||||
#include <QtNetwork/QUdpSocket>
|
||||
#include <QFile>
|
||||
#include <quuid.h>
|
||||
#include <QUuid>
|
||||
#include <QDBusConnection>
|
||||
#include <QNetworkSession>
|
||||
#include <QNetworkConfigurationManager>
|
||||
|
||||
#include <KIcon>
|
||||
#include <KConfigGroup>
|
||||
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
|
||||
K_PLUGIN_FACTORY(KdeConnectFactory, registerPlugin<Daemon>();)
|
||||
K_EXPORT_PLUGIN(KdeConnectFactory("kdeconnect", "kdeconnect"))
|
||||
|
||||
Daemon::Daemon(QObject *parent, const QList<QVariant>&)
|
||||
: KDEDModule(parent)
|
||||
{
|
||||
|
||||
KSharedConfigPtr config = KSharedConfig::openConfig("kdeconnectrc");
|
||||
|
||||
if (!config->group("myself").hasKey("id")) {
|
||||
|
@ -70,7 +68,8 @@ Daemon::Daemon(QObject *parent, const QList<QVariant>&)
|
|||
|
||||
//TODO: Do not hardcode the load of the device locators
|
||||
//use: https://techbase.kde.org/Development/Tutorials/Services/Plugins
|
||||
mLinkProviders.insert(new AvahiTcpLinkProvider());
|
||||
mLinkProviders.insert(new BroadcastTcpLinkProvider());
|
||||
//mLinkProviders.insert(new AvahiTcpLinkProvider());
|
||||
//mLinkProviders.insert(new LoopbackLinkProvider());
|
||||
|
||||
//Read remebered paired devices
|
||||
|
@ -90,8 +89,12 @@ Daemon::Daemon(QObject *parent, const QList<QVariant>&)
|
|||
}
|
||||
}
|
||||
|
||||
QNetworkSession* network = new QNetworkSession(QNetworkConfigurationManager().defaultConfiguration());
|
||||
|
||||
//Listen to incomming connections
|
||||
Q_FOREACH (LinkProvider* a, mLinkProviders) {
|
||||
connect(network, SIGNAL(stateChanged(QNetworkSession::State)),
|
||||
a, SLOT(onNetworkChange(QNetworkSession::State)));
|
||||
connect(a,SIGNAL(onNewDeviceLink(NetworkPackage,DeviceLink*)),
|
||||
this,SLOT(onNewDeviceLink(NetworkPackage,DeviceLink*)));
|
||||
}
|
||||
|
@ -105,10 +108,19 @@ void Daemon::setDiscoveryEnabled(bool b)
|
|||
{
|
||||
//Listen to incomming connections
|
||||
Q_FOREACH (LinkProvider* a, mLinkProviders) {
|
||||
a->setDiscoverable(b);
|
||||
if (b)
|
||||
a->onStart();
|
||||
else
|
||||
a->onStop();
|
||||
}
|
||||
|
||||
}
|
||||
void Daemon::forceOnNetworkChange()
|
||||
{
|
||||
Q_FOREACH (LinkProvider* a, mLinkProviders) {
|
||||
a->onNetworkChange(QNetworkSession::Connected);
|
||||
}
|
||||
}
|
||||
|
||||
QStringList Daemon::devices()
|
||||
{
|
||||
|
|
|
@ -60,6 +60,8 @@ public Q_SLOTS:
|
|||
//After calling this, signal deviceDiscovered will be triggered for each device
|
||||
Q_SCRIPTABLE void setDiscoveryEnabled(bool b);
|
||||
|
||||
Q_SCRIPTABLE void forceOnNetworkChange();
|
||||
|
||||
//Returns a list of ids. The respective devices can be manipulated using the dbus path: "/modules/kdeconnect/Devices/"+id
|
||||
Q_SCRIPTABLE QStringList devices();
|
||||
|
||||
|
|
|
@ -19,9 +19,9 @@
|
|||
*/
|
||||
|
||||
#include "tcpdevicelink.h"
|
||||
#include "linkproviders/avahitcplinkprovider.h"
|
||||
#include "linkproviders/linkprovider.h"
|
||||
|
||||
TcpDeviceLink::TcpDeviceLink(const QString& d, AvahiTcpLinkProvider* a, QTcpSocket* socket)
|
||||
TcpDeviceLink::TcpDeviceLink(const QString& d, LinkProvider* a, QTcpSocket* socket)
|
||||
: DeviceLink(d, a)
|
||||
{
|
||||
mSocket = socket;
|
||||
|
|
|
@ -36,7 +36,7 @@ class TcpDeviceLink
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TcpDeviceLink(const QString& d, AvahiTcpLinkProvider* a, QTcpSocket* socket);
|
||||
TcpDeviceLink(const QString& d, LinkProvider* a, QTcpSocket* socket);
|
||||
|
||||
bool sendPackage(const NetworkPackage& np);
|
||||
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
AvahiTcpLinkProvider::AvahiTcpLinkProvider()
|
||||
{
|
||||
QString serviceType = "_kdeconnect._tcp";
|
||||
quint16 port = 10602;
|
||||
|
||||
//http://api.kde.org/4.x-api/kdelibs-apidocs/dnssd/html/index.html
|
||||
|
||||
|
@ -36,10 +35,27 @@ AvahiTcpLinkProvider::AvahiTcpLinkProvider()
|
|||
|
||||
mServer = new QTcpServer(this);
|
||||
connect(mServer,SIGNAL(newConnection()),this, SLOT(newConnection()));
|
||||
mServer->listen(QHostAddress::Any, port);
|
||||
|
||||
}
|
||||
|
||||
void AvahiTcpLinkProvider::onStart()
|
||||
{
|
||||
|
||||
mServer->listen(QHostAddress::Any, port);
|
||||
service->publishAsync();
|
||||
}
|
||||
|
||||
void AvahiTcpLinkProvider::onStop()
|
||||
{
|
||||
mServer->close();
|
||||
service->stop();
|
||||
|
||||
}
|
||||
void AvahiTcpLinkProvider::onNetworkChange(QNetworkSession::State state)
|
||||
{
|
||||
//Nothing to do, Avahi will handle it
|
||||
}
|
||||
|
||||
void AvahiTcpLinkProvider::newConnection()
|
||||
{
|
||||
qDebug() << "AvahiTcpLinkProvider newConnection";
|
||||
|
@ -104,9 +120,3 @@ AvahiTcpLinkProvider::~AvahiTcpLinkProvider()
|
|||
delete service;
|
||||
}
|
||||
|
||||
void AvahiTcpLinkProvider::setDiscoverable(bool b)
|
||||
{
|
||||
qDebug() << "AvahiTcpLinkProvider discoverable:" << b;
|
||||
if (b) service->publishAsync();
|
||||
}
|
||||
|
||||
|
|
|
@ -42,7 +42,10 @@ public:
|
|||
QString name() { return "AvahiTcpLinkProvider"; }
|
||||
int priority() { return PRIORITY_HIGH + 1; }
|
||||
|
||||
void setDiscoverable(bool b);
|
||||
public Q_SLOTS:
|
||||
virtual void onNetworkChange(QNetworkSession::State state);
|
||||
virtual void onStart();
|
||||
virtual void onStop();
|
||||
|
||||
private Q_SLOTS:
|
||||
void newConnection();
|
||||
|
@ -53,6 +56,7 @@ private:
|
|||
DNSSD::PublicService* service;
|
||||
QTcpServer* mServer;
|
||||
|
||||
static const quint16 port = 10602;
|
||||
QMap<QString, DeviceLink*> links;
|
||||
|
||||
};
|
||||
|
|
193
daemon/linkproviders/broadcasttcplinkprovider.cpp
Normal file
193
daemon/linkproviders/broadcasttcplinkprovider.cpp
Normal file
|
@ -0,0 +1,193 @@
|
|||
/**
|
||||
* Copyright 2013 Albert Vaca <albertvaka@gmail.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "broadcasttcplinkprovider.h"
|
||||
|
||||
#include "devicelinks/tcpdevicelink.h"
|
||||
|
||||
#include <QHostInfo>
|
||||
#include <QTcpServer>
|
||||
#include <QUdpSocket>
|
||||
|
||||
BroadcastTcpLinkProvider::BroadcastTcpLinkProvider()
|
||||
{
|
||||
|
||||
mUdpServer = new QUdpSocket(this);
|
||||
connect(mUdpServer, SIGNAL(readyRead()), this, SLOT(newUdpConnection()));
|
||||
|
||||
mTcpServer = new QTcpServer(this);
|
||||
connect(mTcpServer,SIGNAL(newConnection()),this, SLOT(newConnection()));
|
||||
|
||||
}
|
||||
|
||||
void BroadcastTcpLinkProvider::onStart()
|
||||
{
|
||||
mUdpServer->bind(QHostAddress::Broadcast, port, QUdpSocket::ShareAddress);
|
||||
mTcpServer->listen(QHostAddress::Any, port);
|
||||
|
||||
onNetworkChange(QNetworkSession::Connected);
|
||||
}
|
||||
|
||||
void BroadcastTcpLinkProvider::onStop()
|
||||
{
|
||||
mUdpServer->close();
|
||||
mTcpServer->close();
|
||||
}
|
||||
|
||||
//I'm in a new network, let's be polite and introduce myself
|
||||
void BroadcastTcpLinkProvider::onNetworkChange(QNetworkSession::State state) {
|
||||
qDebug() << "onNetworkChange" << state;
|
||||
NetworkPackage np("");
|
||||
NetworkPackage::createIdentityPackage(&np);
|
||||
QUdpSocket().writeDatagram(np.serialize(),QHostAddress("255.255.255.255"), port);
|
||||
}
|
||||
|
||||
//I'm the existing device, a new device is kindly introducing itself (I will create a TcpSocket)
|
||||
void BroadcastTcpLinkProvider::newUdpConnection()
|
||||
{
|
||||
while (mUdpServer->hasPendingDatagrams()) {
|
||||
QByteArray datagram;
|
||||
datagram.resize(mUdpServer->pendingDatagramSize());
|
||||
QHostAddress sender;
|
||||
quint16 senderPort;
|
||||
|
||||
mUdpServer->readDatagram(datagram.data(), datagram.size(), &sender, &senderPort);
|
||||
|
||||
NetworkPackage np("");
|
||||
NetworkPackage::unserialize(datagram,&np);
|
||||
|
||||
if (np.version() > 0 && np.type() == PACKAGE_TYPE_IDENTITY) {
|
||||
|
||||
NetworkPackage np2("");
|
||||
NetworkPackage::createIdentityPackage(&np2);
|
||||
|
||||
if (np.get<QString>("deviceId") == np2.get<QString>("deviceId")) {
|
||||
qDebug() << "I can't fuck myself!";
|
||||
return;
|
||||
}
|
||||
|
||||
const QString& id = np.get<QString>("deviceId");
|
||||
if (links.contains(id)) {
|
||||
//Delete old link if we already know it, probably it is down if this happens.
|
||||
qDebug() << "Destroying old link";
|
||||
delete links[id];
|
||||
links.remove(id);
|
||||
}
|
||||
|
||||
QTcpSocket* socket = new QTcpSocket(this);
|
||||
|
||||
qDebug() << "Received Udp presentation from" << sender << "asking for a tcp connection...";
|
||||
socket->connectToHost(sender, port);
|
||||
socket->waitForConnected();
|
||||
qDebug() << "Connected" << socket->isWritable();
|
||||
|
||||
TcpDeviceLink* dl = new TcpDeviceLink(id, this, socket);
|
||||
|
||||
connect(dl,SIGNAL(destroyed(QObject*)),this,SLOT(deviceLinkDestroyed(QObject*)));
|
||||
|
||||
links[id] = dl;
|
||||
bool success = dl->sendPackage(np2);
|
||||
if (!success) { //FIXME: Why is this happening?
|
||||
qDebug() << "Fallback, try reverse connection";
|
||||
QUdpSocket().writeDatagram(np2.serialize(),sender, port);
|
||||
}
|
||||
|
||||
qDebug() << "Handshaking done (i'm the existing device)";
|
||||
|
||||
emit onNewDeviceLink(np, dl);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//I'm the new device and this is the answer to my UDP introduction (no data received yet)
|
||||
void BroadcastTcpLinkProvider::newConnection()
|
||||
{
|
||||
qDebug() << "BroadcastTcpLinkProvider newConnection";
|
||||
|
||||
QTcpSocket* socket = mTcpServer->nextPendingConnection();
|
||||
socket->setSocketOption(QAbstractSocket::KeepAliveOption, 1);
|
||||
|
||||
connect(socket,SIGNAL(readyRead()),this,SLOT(dataReceived()));
|
||||
|
||||
/*
|
||||
NetworkPackage np(PACKAGE_TYPE_IDENTITY);
|
||||
NetworkPackage::createIdentityPackage(&np);
|
||||
int written = socket->write(np.serialize());
|
||||
|
||||
qDebug() << "BroadcastTcpLinkProvider sent package." << written << " bytes written, waiting for reply";
|
||||
*/
|
||||
}
|
||||
|
||||
//I'm the new device and this is the answer to my UDP introduction (data received)
|
||||
void BroadcastTcpLinkProvider::dataReceived()
|
||||
{
|
||||
QTcpSocket* socket = (QTcpSocket*) QObject::sender();
|
||||
|
||||
QByteArray data = socket->readLine();
|
||||
|
||||
qDebug() << "BroadcastTcpLinkProvider received reply:" << data;
|
||||
|
||||
NetworkPackage np("");
|
||||
NetworkPackage::unserialize(data,&np);
|
||||
|
||||
if (np.version() > 0 && np.type() == PACKAGE_TYPE_IDENTITY) {
|
||||
|
||||
const QString& id = np.get<QString>("deviceId");
|
||||
TcpDeviceLink* dl = new TcpDeviceLink(id, this, socket);
|
||||
|
||||
connect(dl,SIGNAL(destroyed(QObject*)),this,SLOT(deviceLinkDestroyed(QObject*)));
|
||||
|
||||
if (links.contains(id)) {
|
||||
//Delete old link if we already know it, probably it is down if this happens.
|
||||
qDebug() << "Destroying old link";
|
||||
delete links[id];
|
||||
}
|
||||
links[id] = dl;
|
||||
|
||||
//qDebug() << "BroadcastTcpLinkProvider creating link to device" << id << "(" << socket->peerAddress() << ")";
|
||||
|
||||
qDebug() << "Handshaking done (i'm the new device)";
|
||||
|
||||
emit onNewDeviceLink(np, dl);
|
||||
|
||||
disconnect(socket,SIGNAL(readyRead()),this,SLOT(dataReceived()));
|
||||
|
||||
} else {
|
||||
qDebug() << "BroadcastTcpLinkProvider/newConnection: Not an identification package (wuh?)";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void BroadcastTcpLinkProvider::deviceLinkDestroyed(QObject* deviceLink)
|
||||
{
|
||||
const QString& id = ((DeviceLink*)deviceLink)->deviceId();
|
||||
qDebug() << "deviceLinkDestroyed";
|
||||
if (links.contains(id)) {
|
||||
qDebug() << "removing link from link list";
|
||||
links.remove(id);
|
||||
}
|
||||
}
|
||||
|
||||
BroadcastTcpLinkProvider::~BroadcastTcpLinkProvider()
|
||||
{
|
||||
|
||||
}
|
64
daemon/linkproviders/broadcasttcplinkprovider.h
Normal file
64
daemon/linkproviders/broadcasttcplinkprovider.h
Normal file
|
@ -0,0 +1,64 @@
|
|||
/**
|
||||
* Copyright 2013 Albert Vaca <albertvaka@gmail.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef BROADCASTTCPLINKPROVIDER_H
|
||||
#define BROADCASTTCPLINKPROVIDER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QTcpServer>
|
||||
#include <QUdpSocket>
|
||||
|
||||
#include "linkprovider.h"
|
||||
#include "netaddress.h"
|
||||
|
||||
|
||||
class BroadcastTcpLinkProvider
|
||||
: public LinkProvider
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
BroadcastTcpLinkProvider();
|
||||
~BroadcastTcpLinkProvider();
|
||||
|
||||
QString name() { return "BroadcastTcpLinkProvider"; }
|
||||
int priority() { return PRIORITY_HIGH + 5; }
|
||||
|
||||
public Q_SLOTS:
|
||||
virtual void onNetworkChange(QNetworkSession::State state);
|
||||
virtual void onStart();
|
||||
virtual void onStop();
|
||||
|
||||
private Q_SLOTS:
|
||||
void newUdpConnection();
|
||||
void newConnection();
|
||||
void dataReceived();
|
||||
void deviceLinkDestroyed(QObject*);
|
||||
|
||||
private:
|
||||
QTcpServer* mTcpServer;
|
||||
QUdpSocket* mUdpServer;
|
||||
const static quint16 port = 1714;
|
||||
|
||||
QMap<QString, DeviceLink*> links;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
|
@ -21,8 +21,9 @@
|
|||
#ifndef LINKPROVIDER_H
|
||||
#define LINKPROVIDER_H
|
||||
|
||||
#include <qvector.h>
|
||||
#include <QObject>
|
||||
#include <QVector>
|
||||
#include <QNetworkSession>
|
||||
|
||||
#include "devicelinks/devicelink.h"
|
||||
#include "device.h"
|
||||
|
@ -46,7 +47,10 @@ public:
|
|||
virtual QString name() = 0;
|
||||
virtual int priority() = 0;
|
||||
|
||||
virtual void setDiscoverable(bool b) = 0;
|
||||
public Q_SLOTS:
|
||||
virtual void onStart() = 0;
|
||||
virtual void onStop() = 0;
|
||||
virtual void onNetworkChange(QNetworkSession::State state) = 0;
|
||||
|
||||
Q_SIGNALS:
|
||||
//NOTE: The provider will to destroy the DeviceLink when it's no longer accessible,
|
||||
|
|
|
@ -23,23 +23,40 @@
|
|||
#include <QDebug>
|
||||
#include <kicon.h>
|
||||
|
||||
NotificationPackageInterface::NotificationPackageInterface(QObject* parent)
|
||||
: PackageInterface(parent)
|
||||
{
|
||||
//TODO: Split in EventNotificationInterface and NotificationDrawerSyncInterface
|
||||
|
||||
trayIcon = new KStatusNotifierItem(parent);
|
||||
trayIcon->setIconByName("pda");
|
||||
trayIcon->setTitle("KdeConnect");
|
||||
connect(trayIcon,SIGNAL(activateRequested(bool,QPoint)),this,SLOT(showPendingNotifications()));
|
||||
}
|
||||
|
||||
KNotification* NotificationPackageInterface::createNotification(const QString& deviceName, const NetworkPackage& np)
|
||||
{
|
||||
|
||||
QString id = QString::number(np.id());
|
||||
|
||||
QString npType = np.get<QString>("notificationType");
|
||||
|
||||
QString title, content, type, icon;
|
||||
bool transient;
|
||||
|
||||
title = deviceName;
|
||||
|
||||
|
||||
if (npType == "ringing") {
|
||||
type = "callReceived";
|
||||
icon = "call-start";
|
||||
content = "Incoming call from " + np.get<QString>("phoneNumber","unknown number");
|
||||
transient = false;
|
||||
} else if (npType == "missedCall") {
|
||||
type = "missedCall";
|
||||
icon = "call-start";
|
||||
content = "Missed call from " + np.get<QString>("phoneNumber","unknown number");
|
||||
transient = true;
|
||||
} else if (npType == "sms") {
|
||||
type = "smsReceived";
|
||||
icon = "mail-receive";
|
||||
|
@ -47,33 +64,76 @@ KNotification* NotificationPackageInterface::createNotification(const QString& d
|
|||
+ np.get<QString>("phoneNumber","unknown number")
|
||||
+ ":\n"
|
||||
+ np.get<QString>("messageBody","");
|
||||
transient = true;
|
||||
} else if (npType == "battery") {
|
||||
type = "battery100";
|
||||
icon = "battery-100";
|
||||
content = "Battery at " + np.get<QString>("batteryLevel") + "%";
|
||||
transient = false;
|
||||
} else if (npType == "notification") {
|
||||
type = "pingReceived";
|
||||
icon = "dialog-ok";
|
||||
content = np.get<QString>("notificationContent");
|
||||
transient = false;
|
||||
} else {
|
||||
//TODO: return NULL if !debug
|
||||
type = "unknownEvent";
|
||||
icon = "pda";
|
||||
content = "Unknown notification type: " + npType;
|
||||
transient = false;
|
||||
}
|
||||
|
||||
qDebug() << "Creating notification with type:" << type;
|
||||
|
||||
|
||||
if (transient) {
|
||||
trayIcon->setStatus(KStatusNotifierItem::Active);
|
||||
|
||||
KNotification* notification = new KNotification(type); //KNotification::Persistent
|
||||
notification->setPixmap(KIcon(icon).pixmap(48, 48));
|
||||
notification->setComponentData(KComponentData("kdeconnect", "kdeconnect"));
|
||||
notification->setTitle(title);
|
||||
notification->setText(content);
|
||||
|
||||
pendingNotifications.insert(id, notification);
|
||||
}
|
||||
|
||||
KNotification* notification = new KNotification(type); //KNotification::Persistent
|
||||
notification->setPixmap(KIcon(icon).pixmap(48, 48));
|
||||
notification->setComponentData(KComponentData("kdeconnect", "kdeconnect"));
|
||||
notification->setTitle(title);
|
||||
notification->setText(content);
|
||||
notification->setProperty("id",id);
|
||||
|
||||
connect(notification,SIGNAL(activated()),this,SLOT(notificationAttended()));
|
||||
connect(notification,SIGNAL(closed()),this,SLOT(notificationAttended()));
|
||||
|
||||
return notification;
|
||||
|
||||
}
|
||||
|
||||
void NotificationPackageInterface::notificationAttended()
|
||||
{
|
||||
KNotification* normalNotification = (KNotification*)sender();
|
||||
QString id = normalNotification->property("id").toString();
|
||||
if (pendingNotifications.contains(id)) {
|
||||
delete pendingNotifications[id];
|
||||
pendingNotifications.remove(id);
|
||||
if (pendingNotifications.isEmpty()) {
|
||||
trayIcon->setStatus(KStatusNotifierItem::Passive);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NotificationPackageInterface::showPendingNotifications()
|
||||
{
|
||||
trayIcon->setStatus(KStatusNotifierItem::Passive);
|
||||
Q_FOREACH (KNotification* notification, pendingNotifications) {
|
||||
notification->sendEvent();
|
||||
}
|
||||
pendingNotifications.clear();
|
||||
}
|
||||
|
||||
bool NotificationPackageInterface::receivePackage(const Device& device, const NetworkPackage& np)
|
||||
{
|
||||
|
||||
|
|
|
@ -25,17 +25,26 @@
|
|||
|
||||
#include "packageinterface.h"
|
||||
|
||||
#include <KStatusNotifierItem>
|
||||
|
||||
class NotificationPackageInterface
|
||||
: public PackageInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
NotificationPackageInterface(QObject* parent = 0);
|
||||
|
||||
virtual bool receivePackage(const Device&, const NetworkPackage& np);
|
||||
|
||||
private:
|
||||
static KNotification* createNotification(const QString& deviceName,const NetworkPackage& np);
|
||||
|
||||
KNotification* createNotification(const QString& deviceName,const NetworkPackage& np);
|
||||
KStatusNotifierItem* trayIcon;
|
||||
QHash<QString, KNotification*> pendingNotifications;
|
||||
|
||||
public slots:
|
||||
void showPendingNotifications();
|
||||
void notificationAttended();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue