diff --git a/app/main.cpp b/app/main.cpp index 1ef1c186..28a0ee14 100644 --- a/app/main.cpp +++ b/app/main.cpp @@ -1,51 +1,51 @@ /* * Copyright (C) 2014 Aleix Pol Gonzalez * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include -int main(int argc, char *argv[]) +int main(int argc, char* argv[]) { QApplication app(argc, argv); KAboutData aboutData(QStringLiteral("kdeconnect.app"), i18n("KDE Connect App"), QStringLiteral("1.0"), i18n("KDE Connect App"), KAboutLicense::GPL, i18n("(c) 2015, Aleix Pol Gonzalez")); aboutData.addAuthor(i18n("Aleix Pol Gonzalez"), i18n("Maintainer"), QStringLiteral("aleixpol@kde.org")); KAboutData::setApplicationData(aboutData); { QCommandLineParser parser; aboutData.setupCommandLine(&parser); parser.addVersionOption(); parser.addHelpOption(); parser.process(app); aboutData.processCommandLine(&parser); } QQmlApplicationEngine engine; KDeclarative::KDeclarative kdeclarative; kdeclarative.setDeclarativeEngine(&engine); kdeclarative.setupBindings(); engine.load(QUrl(QStringLiteral("qrc:/qml/main.qml"))); return app.exec(); } diff --git a/app/org.kde.kdeconnect.app.desktop b/app/org.kde.kdeconnect.app.desktop index 9d46a146..e8dc2173 100644 --- a/app/org.kde.kdeconnect.app.desktop +++ b/app/org.kde.kdeconnect.app.desktop @@ -1,118 +1,115 @@ [Desktop Entry] Name=KDE Connect Application Name[ar]=تطبيق كدي المتّصل Name[ast]=Aplicación KDE Connect Name[ca]=Aplicació KDE Connect Name[ca@valencia]=Aplicació KDE Connect Name[cs]=Aplikace KDE Connect Name[da]=Programmet KDE Connect Name[de]=KDE-Connect-Anwendung Name[el]=Εφαρμογή KDE Connect Name[en_GB]=KDE Connect Application Name[es]=Aplicación KDE Connect Name[et]=KDE Connecti rakendus -Name[eu]=KDE Connect aplikazioa Name[fi]=KDE Connect -sovellus Name[fr]=Application KDE Connect Name[gl]=Aplicativo de KDE Connect Name[he]=היישום KDE Connect Name[hu]=KDE Connect alkalmazás Name[it]=Applicazione KDE Connect Name[ko]=KDE Connect 프로그램 Name[nl]=KDE Connect-toepassing Name[nn]=KDE Connect-program Name[pl]=Program KDE Connect Name[pt]=Aplicação do KDE Connect Name[pt_BR]=Aplicativo KDE Connect Name[ru]=Приложение KDE Connect Name[sk]=KDE Connect aplikácia Name[sr]=КДЕ‑конекцијин програм Name[sr@ijekavian]=КДЕ‑конекцијин програм Name[sr@ijekavianlatin]=KDE‑konekcijin program Name[sr@latin]=KDE‑konekcijin program Name[sv]=Programmet KDE-anslut Name[tr]=KDE Connect Uygulaması Name[uk]=Програма KDE Connect Name[x-test]=xxKDE Connect Applicationxx Name[zh_CN]=KDE Connect 应用程序 Name[zh_TW]=KDE 連線應用程式 GenericName=Device Synchronization GenericName[ar]=مزامنة الأجهزة GenericName[ast]=Sincronización de preseos GenericName[ca]=Sincronització de dispositius GenericName[ca@valencia]=Sincronització de dispositius GenericName[cs]=Synchronizace zařízení GenericName[da]=Enhedssynkronisering GenericName[de]=Geräteabgleich GenericName[el]=Συγχρονισμός συσκευών GenericName[en_GB]=Device Synchronisation GenericName[es]=Sincronización de dispositivos GenericName[et]=Seadmete sünkroonimine -GenericName[eu]=Galuak sinkronizatzea GenericName[fi]=Laitteiden synkronointi GenericName[fr]=Synchronisation de périphériques GenericName[gl]=Sincronización de dispositivos GenericName[he]=סנכרון התקן GenericName[hu]=Eszközszinkronizáció GenericName[it]=Sincronizzazione dispositivo GenericName[ko]=장치 동기화 GenericName[lt]=Įrenginių sinchronizavimas GenericName[nl]=Synchronisatie van apparaat GenericName[nn]=Einingssynkronisering GenericName[pl]=Synchronizacja urządzenia GenericName[pt]=Sincronização de Dispositivos GenericName[pt_BR]=Sincronização de dispositivo GenericName[ru]=Синхронизация с мобильным устройством GenericName[sk]=Synchronizácia zariadení GenericName[sr]=Синхронизација уређаја GenericName[sr@ijekavian]=Синхронизација уређаја GenericName[sr@ijekavianlatin]=Sinhronizacija uređaja GenericName[sr@latin]=Sinhronizacija uređaja GenericName[sv]=Enhetssynkronisering GenericName[tr]=Aygıt Eşzamanlaması GenericName[uk]=Синхронізація із пристроями GenericName[x-test]=xxDevice Synchronizationxx GenericName[zh_CN]=设备同步 GenericName[zh_TW]=設備同步 Comment=Make all your devices one Comment[ar]=اجعل أجهزتك كلّها واحدًا Comment[ast]=Fai tolos tos preseos ún Comment[ca]=Fa que tots els vostres dispositius siguin un Comment[ca@valencia]=Fa que tots els vostres dispositius siguen un Comment[cs]=Sjednoťte svá zařízení Comment[da]=Gør alle dine enheder til en Comment[de]=Gleichen Sie alle Ihre Geräte ab Comment[el]=Όλες οι συσκευές σας σε μία Comment[en_GB]=Make all your devices one Comment[es]=Convertir todos sus dispositivos en uno Comment[et]=Kõigi seadmete ühendamine -Comment[eu]=Bat egin zure gailu guztiak Comment[fi]=Yhdistä kaikki laitteesi toisiinsa Comment[fr]=Unifiez vos périphériques Comment[gl]=Unifique os seus dispositivos. Comment[he]=הפוך את כך ההתקנים שלך לאחד Comment[hu]=Egyesítse eszközeit Comment[it]=Fai di tutti i tuoi dispositivi un solo dispositivo Comment[ko]=모든 장치를 하나로 동기화 Comment[nl]=Al uw apparaten een maken Comment[nn]=Slå alle einingane dine saman Comment[pl]=Uczyń wszystkie swoje urządzenia jednym Comment[pt]=Unifique todos os seus dispositivos Comment[pt_BR]=Torne todos os seus dispositivos em um Comment[ru]=Объедините все ваши устройства Comment[sk]=Urobiť z vašich zariadení jedno Comment[sr]=Обједините своје уређаје Comment[sr@ijekavian]=Обједините своје уређаје Comment[sr@ijekavianlatin]=Objedinite svoje uređaje Comment[sr@latin]=Objedinite svoje uređaje Comment[sv]=Gör alla enheter till en Comment[tr]=Tüm aygıtlarınızı birleştirin Comment[uk]=Поєднайте усі ваші пристрої Comment[x-test]=xxMake all your devices onexx Comment[zh_CN]=连接您所有设备 Comment[zh_TW]=讓您的設備內容全面同步 Exec=kcapp Icon=kdeconnect Type=Application Terminal=false Categories=Qt;KDE;Network diff --git a/cli/kdeconnect-cli.cpp b/cli/kdeconnect-cli.cpp index 0552d525..9ead2584 100644 --- a/cli/kdeconnect-cli.cpp +++ b/cli/kdeconnect-cli.cpp @@ -1,250 +1,250 @@ /* * Copyright 2015 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 "interfaces/devicesmodel.h" #include "interfaces/notificationsmodel.h" #include "interfaces/dbusinterfaces.h" #include "interfaces/dbushelpers.h" #include "kdeconnect-version.h" int main(int argc, char** argv) { QCoreApplication app(argc, argv); KAboutData about(QStringLiteral("kdeconnect-cli"), QStringLiteral("kdeconnect-cli"), QStringLiteral(KDECONNECT_VERSION_STRING), i18n("KDE Connect CLI tool"), KAboutLicense::GPL, i18n("(C) 2015 Aleix Pol Gonzalez")); KAboutData::setApplicationData(about); about.addAuthor( i18n("Aleix Pol Gonzalez"), QString(), QStringLiteral("aleixpol@kde.org") ); about.addAuthor( i18n("Albert Vaca Cintora"), QString(), QStringLiteral("albertvaka@gmail.com") ); QCommandLineParser parser; parser.addOption(QCommandLineOption(QStringList(QStringLiteral("l")) << QStringLiteral("list-devices"), i18n("List all devices"))); parser.addOption(QCommandLineOption(QStringList(QStringLiteral("a")) << QStringLiteral("list-available"), i18n("List available (paired and reachable) devices"))); parser.addOption(QCommandLineOption(QStringLiteral("id-only"), i18n("Make --list-devices or --list-available print only the devices id, to ease scripting"))); parser.addOption(QCommandLineOption(QStringLiteral("refresh"), i18n("Search for devices in the network and re-establish connections"))); parser.addOption(QCommandLineOption(QStringLiteral("pair"), i18n("Request pairing to a said device"))); parser.addOption(QCommandLineOption(QStringLiteral("ring"), i18n("Find the said device by ringing it."))); parser.addOption(QCommandLineOption(QStringLiteral("unpair"), i18n("Stop pairing to a said device"))); parser.addOption(QCommandLineOption(QStringLiteral("ping"), i18n("Sends a ping to said device"))); parser.addOption(QCommandLineOption(QStringLiteral("ping-msg"), i18n("Same as ping but you can set the message to display"), i18n("message"))); parser.addOption(QCommandLineOption(QStringLiteral("share"), i18n("Share a file to a said device"), QStringLiteral("path"))); parser.addOption(QCommandLineOption(QStringLiteral("list-notifications"), i18n("Display the notifications on a said device"))); parser.addOption(QCommandLineOption(QStringLiteral("lock"), i18n("Lock the specified device"))); parser.addOption(QCommandLineOption(QStringLiteral("send-sms"), i18n("Sends an SMS. Requires destination"), i18n("message"))); parser.addOption(QCommandLineOption(QStringLiteral("destination"), i18n("Phone number to send the message"), i18n("phone number"))); parser.addOption(QCommandLineOption(QStringList(QStringLiteral("device")) << QStringLiteral("d"), i18n("Device ID"), QStringLiteral("dev"))); parser.addOption(QCommandLineOption(QStringList(QStringLiteral("name")) << QStringLiteral("n"), i18n("Device Name"), QStringLiteral("name"))); parser.addOption(QCommandLineOption(QStringLiteral("encryption-info"), i18n("Get encryption info about said device"))); parser.addOption(QCommandLineOption(QStringLiteral("list-commands"), i18n("Lists remote commands and their ids"))); parser.addOption(QCommandLineOption(QStringLiteral("execute-command"), i18n("Executes a remote command by id"), QStringLiteral("id"))); parser.addOption(QCommandLineOption(QStringList{QStringLiteral("k"), QStringLiteral("send-keys")}, i18n("Sends keys to a said device"))); parser.addOption(QCommandLineOption(QStringLiteral("my-id"), i18n("Display this device's id and exit"))); about.setupCommandLine(&parser); parser.addHelpOption(); parser.process(app); about.processCommandLine(&parser); const QString id = "kdeconnect-cli-"+QString::number(QCoreApplication::applicationPid()); DaemonDbusInterface iface; if (parser.isSet(QStringLiteral("my-id"))) { QTextStream(stdout) << iface.selfId() << endl; } else if (parser.isSet(QStringLiteral("l")) || parser.isSet(QStringLiteral("a"))) { bool paired = true, reachable = false; if (parser.isSet(QStringLiteral("a"))) { reachable = true; } else { blockOnReply(iface.acquireDiscoveryMode(id)); QThread::sleep(2); } const QStringList devices = blockOnReply(iface.devices(paired, reachable)); for (const QString& id : devices) { if (parser.isSet(QStringLiteral("id-only"))) { QTextStream(stdout) << id << endl; } else { DeviceDbusInterface deviceIface(id); QString statusInfo; const bool isReachable = deviceIface.isReachable(); const bool isTrusted = deviceIface.isTrusted(); if (isReachable && isTrusted) { statusInfo = i18n("(paired and reachable)"); } else if (isReachable) { statusInfo = i18n("(reachable)"); } else if (isTrusted) { statusInfo = i18n("(paired)"); } QTextStream(stdout) << "- " << deviceIface.name() << ": " << deviceIface.id() << ' ' << statusInfo << endl; } } if (!parser.isSet(QStringLiteral("id-only"))) { QTextStream(stdout) << i18np("1 device found", "%1 devices found", devices.size()) << endl; } else if (devices.isEmpty()) { QTextStream(stderr) << i18n("No devices found") << endl; } blockOnReply(iface.releaseDiscoveryMode(id)); } else if(parser.isSet(QStringLiteral("refresh"))) { QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.kde.kdeconnect"), QStringLiteral("/modules/kdeconnect"), QStringLiteral("org.kde.kdeconnect.daemon"), QStringLiteral("forceOnNetworkChange")); blockOnReply(QDBusConnection::sessionBus().asyncCall(msg)); } else { QString device = parser.value(QStringLiteral("device")); if (device.isEmpty() && parser.isSet(QStringLiteral("name"))) { device = blockOnReply(iface.deviceIdByName(parser.value(QStringLiteral("name")))); if (device.isEmpty()) { QTextStream(stderr) << "Couldn't find device: " << parser.value(QStringLiteral("name")) << endl; return 1; } } if(device.isEmpty()) { QTextStream(stderr) << i18n("No device specified") << endl; parser.showHelp(1); } if(parser.isSet(QStringLiteral("share"))) { QUrl url = QUrl::fromUserInput(parser.value(QStringLiteral("share")), QDir::currentPath()); parser.clearPositionalArguments(); if(!url.isEmpty() && !device.isEmpty()) { QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.kde.kdeconnect"), "/modules/kdeconnect/devices/"+device+"/share", QStringLiteral("org.kde.kdeconnect.device.share"), QStringLiteral("shareUrl")); msg.setArguments(QVariantList() << url.toString()); blockOnReply(QDBusConnection::sessionBus().asyncCall(msg)); } else { QTextStream(stderr) << (i18n("Couldn't share %1", url.toString())) << endl; } } else if(parser.isSet(QStringLiteral("pair"))) { DeviceDbusInterface dev(device); if (!dev.isReachable()) { //Device doesn't exist, go into discovery mode and wait up to 30 seconds for the device to appear QEventLoop wait; QTextStream(stderr) << i18n("waiting for device...") << endl; blockOnReply(iface.acquireDiscoveryMode(id)); - QObject::connect(&iface, &DaemonDbusInterface::deviceAdded, [&](const QString &deviceAddedId) { + QObject::connect(&iface, &DaemonDbusInterface::deviceAdded, [&](const QString& deviceAddedId) { if (device == deviceAddedId) { wait.quit(); } }); QTimer::singleShot(30 * 1000, &wait, &QEventLoop::quit); wait.exec(); } if (!dev.isReachable()) { QTextStream(stderr) << i18n("Device not found") << endl; } else if(blockOnReply(dev.isTrusted())) { QTextStream(stderr) << i18n("Already paired") << endl; } else { QTextStream(stderr) << i18n("Pair requested") << endl; blockOnReply(dev.requestPair()); } blockOnReply(iface.releaseDiscoveryMode(id)); } else if(parser.isSet(QStringLiteral("unpair"))) { DeviceDbusInterface dev(device); if (!dev.isReachable()) { QTextStream(stderr) << i18n("Device does not exist") << endl; } else if(!dev.isTrusted()) { QTextStream(stderr) << i18n("Already not paired") << endl; } else { QTextStream(stderr) << i18n("Unpaired") << endl; blockOnReply(dev.unpair()); } } else if(parser.isSet(QStringLiteral("ping")) || parser.isSet(QStringLiteral("ping-msg"))) { QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.kde.kdeconnect"), "/modules/kdeconnect/devices/"+device+"/ping", QStringLiteral("org.kde.kdeconnect.device.ping"), QStringLiteral("sendPing")); if (parser.isSet(QStringLiteral("ping-msg"))) { QString message = parser.value(QStringLiteral("ping-msg")); msg.setArguments(QVariantList() << message); } blockOnReply(QDBusConnection::sessionBus().asyncCall(msg)); } else if(parser.isSet(QStringLiteral("send-sms"))) { if (parser.isSet(QStringLiteral("destination"))) { QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.kde.kdeconnect"), "/modules/kdeconnect/devices/"+device+"/telephony", QStringLiteral("org.kde.kdeconnect.device.telephony"), QStringLiteral("sendSms")); msg.setArguments({ parser.value("destination"), parser.value("send-sms") }); blockOnReply(QDBusConnection::sessionBus().asyncCall(msg)); } else { QTextStream(stderr) << i18n("error: should specify the SMS's recipient by passing --destination "); return 1; } } else if(parser.isSet(QStringLiteral("ring"))) { QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.kde.kdeconnect"), "/modules/kdeconnect/devices/"+device+"/findmyphone", QStringLiteral("org.kde.kdeconnect.device.findmyphone"), QStringLiteral("ring")); blockOnReply(QDBusConnection::sessionBus().asyncCall(msg)); } else if(parser.isSet("send-keys")) { QString seq = parser.value("send-keys"); QDBusMessage msg = QDBusMessage::createMethodCall("org.kde.kdeconnect", "/modules/kdeconnect/devices/"+device+"/remotekeyboard", "org.kde.kdeconnect.device.remotekeyboard", "sendKeyPress"); if (seq.trimmed() == QLatin1String("-")) { // from file QFile in; if(in.open(stdin,QIODevice::ReadOnly | QIODevice::Unbuffered)) { while (!in.atEnd()) { QByteArray line = in.readLine(); // sanitize to ASCII-codes > 31? msg.setArguments({QString(line), -1, false, false, false}); blockOnReply(QDBusConnection::sessionBus().asyncCall(msg)); } in.close(); } } else { msg.setArguments({seq, -1, false, false, false}); blockOnReply(QDBusConnection::sessionBus().asyncCall(msg)); } } else if(parser.isSet(QStringLiteral("list-notifications"))) { NotificationsModel notifications; notifications.setDeviceId(device); for(int i=0, rows=notifications.rowCount(); itoObject(); QTextStream(stdout) << it.key() << ": " << cont.value(QStringLiteral("name")).toString() << ": " << cont.value(QStringLiteral("command")).toString() << endl; } } else if(parser.isSet(QStringLiteral("execute-command"))) { RemoteCommandsDbusInterface iface(device); blockOnReply(iface.triggerCommand(parser.value(QStringLiteral("execute-command")))); } else if(parser.isSet(QStringLiteral("encryption-info"))) { DeviceDbusInterface dev(device); QString info = blockOnReply(dev.encryptionInfo()); // QSsl::Der = 1 QTextStream(stdout) << info << endl; } else { QTextStream(stderr) << i18n("Nothing to be done") << endl; } } QMetaObject::invokeMethod(&app, "quit", Qt::QueuedConnection); return app.exec(); } diff --git a/core/backends/bluetooth/bluetoothdownloadjob.cpp b/core/backends/bluetooth/bluetoothdownloadjob.cpp index 158abd2c..1557e13d 100644 --- a/core/backends/bluetooth/bluetoothdownloadjob.cpp +++ b/core/backends/bluetooth/bluetoothdownloadjob.cpp @@ -1,40 +1,40 @@ /* * Copyright 2016 Saikrishna Arcot * * 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 "bluetoothdownloadjob.h" -BluetoothDownloadJob::BluetoothDownloadJob(const QBluetoothAddress &remoteAddress, const QVariantMap &transferInfo, QObject *parent) +BluetoothDownloadJob::BluetoothDownloadJob(const QBluetoothAddress& remoteAddress, const QVariantMap& transferInfo, QObject* parent) : QObject(parent) , mRemoteAddress(remoteAddress) , mTransferUuid(QBluetoothUuid(transferInfo.value("uuid").toString())) , mSocket(new QBluetoothSocket(QBluetoothServiceInfo::RfcommProtocol)) { } QSharedPointer BluetoothDownloadJob::payload() const { return mSocket.staticCast(); } void BluetoothDownloadJob::start() { connect(mSocket.data(), SIGNAL(disconnected()), this, SLOT(deleteLater())); mSocket->connectToService(mRemoteAddress, mTransferUuid, QIODevice::ReadOnly); } diff --git a/core/backends/bluetooth/bluetoothdownloadjob.h b/core/backends/bluetooth/bluetoothdownloadjob.h index 69754702..6206d0f7 100644 --- a/core/backends/bluetooth/bluetoothdownloadjob.h +++ b/core/backends/bluetooth/bluetoothdownloadjob.h @@ -1,47 +1,47 @@ /* * Copyright 2016 Saikrishna Arcot * * 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 BLUETOOTHDOWNLOADJOB_H #define BLUETOOTHDOWNLOADJOB_H #include #include #include #include #include #include #include class BluetoothDownloadJob : public QObject { Q_OBJECT public: - explicit BluetoothDownloadJob(const QBluetoothAddress &remoteAddress, const QVariantMap &transferInfo, QObject* parent = 0); + explicit BluetoothDownloadJob(const QBluetoothAddress& remoteAddress, const QVariantMap& transferInfo, QObject* parent = 0); QSharedPointer payload() const; void start(); private: QBluetoothAddress mRemoteAddress; QBluetoothUuid mTransferUuid; QSharedPointer mSocket; }; #endif // BLUETOOTHDOWNLOADJOB_H diff --git a/core/backends/bluetooth/bluetoothuploadjob.cpp b/core/backends/bluetooth/bluetoothuploadjob.cpp index 17c7f5f4..1137b1a3 100644 --- a/core/backends/bluetooth/bluetoothuploadjob.cpp +++ b/core/backends/bluetooth/bluetoothuploadjob.cpp @@ -1,85 +1,85 @@ /* * Copyright 2016 Saikrishna Arcot * * 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 "bluetoothuploadjob.h" #include #include "core_debug.h" #include -BluetoothUploadJob::BluetoothUploadJob(const QSharedPointer &data, const QBluetoothAddress &remoteAddress, QObject *parent) +BluetoothUploadJob::BluetoothUploadJob(const QSharedPointer& data, const QBluetoothAddress& remoteAddress, QObject* parent) : QObject(parent) , mData(data) , mRemoteAddress(remoteAddress) , mTransferUuid(QBluetoothUuid::createUuid()) , mServer(new QBluetoothServer(QBluetoothServiceInfo::RfcommProtocol, this)) { mServer->setSecurityFlags(QBluetooth::Encryption | QBluetooth::Secure); } QVariantMap BluetoothUploadJob::transferInfo() const { QVariantMap ret; ret["uuid"] = mTransferUuid.toString().mid(1, 36); return ret; } void BluetoothUploadJob::start() { connect(mServer, SIGNAL(newConnection()), this, SLOT(newConnection())); mServiceInfo = mServer->listen(mTransferUuid, "KDE Connect Transfer Job"); Q_ASSERT(mServiceInfo.isValid()); } void BluetoothUploadJob::newConnection() { QBluetoothSocket* socket = mServer->nextPendingConnection(); connect(socket, SIGNAL(disconnected()), socket, SLOT(deleteLater())); if (socket->peerAddress() != mRemoteAddress) { socket->close(); } else { mServer->close(); disconnect(mServer, SIGNAL(newConnection()), this, SLOT(newConnection())); mServiceInfo.unregisterService(); if (!mData->open(QIODevice::ReadOnly)) { qCWarning(KDECONNECT_CORE) << "error when opening the input to upload"; socket->close(); deleteLater(); return; } } while (mData->bytesAvailable() > 0 && socket->isWritable()) { qint64 bytes = qMin(mData->bytesAvailable(), (qint64)4096); int w = socket->write(mData->read(bytes)); if (w < 0) { qCWarning(KDECONNECT_CORE()) << "error when writing data to upload" << bytes << mData->bytesAvailable(); break; } else { QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents, 2000); } } mData->close(); socket->close(); deleteLater(); } diff --git a/core/backends/bluetooth/bluetoothuploadjob.h b/core/backends/bluetooth/bluetoothuploadjob.h index 7621f6b5..a2bd2280 100644 --- a/core/backends/bluetooth/bluetoothuploadjob.h +++ b/core/backends/bluetooth/bluetoothuploadjob.h @@ -1,53 +1,53 @@ /* * Copyright 2016 Saikrishna Arcot * * 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 BLUETOOTHUPLOADJOB_H #define BLUETOOTHUPLOADJOB_H #include #include #include #include #include #include #include class BluetoothUploadJob : public QObject { Q_OBJECT public: - explicit BluetoothUploadJob(const QSharedPointer &data, const QBluetoothAddress &remoteAddress, QObject* parent = 0); + explicit BluetoothUploadJob(const QSharedPointer& data, const QBluetoothAddress& remoteAddress, QObject* parent = 0); QVariantMap transferInfo() const; void start(); private: QSharedPointer mData; QBluetoothAddress mRemoteAddress; QBluetoothUuid mTransferUuid; QBluetoothServer* mServer; QBluetoothServiceInfo mServiceInfo; private Q_SLOTS: void newConnection(); }; #endif // BLUETOOTHUPLOADJOB_H diff --git a/core/backends/devicelinereader.cpp b/core/backends/devicelinereader.cpp index bba0bdaa..c95fe74f 100644 --- a/core/backends/devicelinereader.cpp +++ b/core/backends/devicelinereader.cpp @@ -1,55 +1,55 @@ /** * Copyright 2013 Albert Vaca * Copyright 2014 Alejandro Fiestas Olivares * * 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 "devicelinereader.h" DeviceLineReader::DeviceLineReader(QIODevice* device, QObject* parent) : QObject(parent) - , mDevice(device) + , m_device(device) { - connect(mDevice, SIGNAL(readyRead()), + connect(m_device, SIGNAL(readyRead()), this, SLOT(dataReceived())); - connect(mDevice, SIGNAL(disconnected()), + connect(m_device, SIGNAL(disconnected()), this, SIGNAL(disconnected())); } void DeviceLineReader::dataReceived() { - while(mDevice->canReadLine()) { - const QByteArray line = mDevice->readLine(); + while(m_device->canReadLine()) { + const QByteArray line = m_device->readLine(); if (line.length() > 1) { - mPackages.enqueue(line);//we don't want single \n + m_packages.enqueue(line);//we don't want single \n } } //If we still have things to read from the device, call dataReceived again //We do this manually because we do not trust readyRead to be emitted again //So we call this method again just in case. - if (mDevice->bytesAvailable() > 0) { + if (m_device->bytesAvailable() > 0) { QMetaObject::invokeMethod(this, "dataReceived", Qt::QueuedConnection); return; } //If we have any packages, tell it to the world. - if (!mPackages.isEmpty()) { + if (!m_packages.isEmpty()) { Q_EMIT readyRead(); } } diff --git a/core/backends/devicelinereader.h b/core/backends/devicelinereader.h index 8fe66296..f4bd987a 100644 --- a/core/backends/devicelinereader.h +++ b/core/backends/devicelinereader.h @@ -1,60 +1,60 @@ /** * Copyright 2013 Albert Vaca * * 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 DEVICELINEREADER_H #define DEVICELINEREADER_H #include #include #include #include /* * Encapsulates a QIODevice and implements the same methods of its API that are * used by LanDeviceLink and BluetoothDeviceLink, but readyRead is emitted only * when a newline is found. */ class DeviceLineReader : public QObject { Q_OBJECT public: DeviceLineReader(QIODevice* device, QObject* parent = 0); - QByteArray readLine() { return mPackages.dequeue(); } - qint64 write(const QByteArray& data) { return mDevice->write(data); } - qint64 bytesAvailable() const { return mPackages.size(); } + QByteArray readLine() { return m_packages.dequeue(); } + qint64 write(const QByteArray& data) { return m_device->write(data); } + qint64 bytesAvailable() const { return m_packages.size(); } Q_SIGNALS: void readyRead(); void disconnected(); private Q_SLOTS: void dataReceived(); private: - QByteArray lastChunk; - QIODevice* mDevice; - QQueue mPackages; + QByteArray m_lastChunk; + QIODevice* m_device; + QQueue m_packages; }; #endif diff --git a/core/backends/devicelink.cpp b/core/backends/devicelink.cpp index 569f0b98..f59312cf 100644 --- a/core/backends/devicelink.cpp +++ b/core/backends/devicelink.cpp @@ -1,44 +1,44 @@ /** * Copyright 2013 Albert Vaca * * 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 "devicelink.h" #include "kdeconnectconfig.h" #include "linkprovider.h" DeviceLink::DeviceLink(const QString& deviceId, LinkProvider* parent) : QObject(parent) - , mPrivateKey(KdeConnectConfig::instance()->privateKey()) - , mDeviceId(deviceId) - , mLinkProvider(parent) - , mPairStatus(NotPaired) + , m_privateKey(KdeConnectConfig::instance()->privateKey()) + , m_deviceId(deviceId) + , m_linkProvider(parent) + , m_pairStatus(NotPaired) { Q_ASSERT(!deviceId.isEmpty()); setProperty("deviceId", deviceId); } void DeviceLink::setPairStatus(DeviceLink::PairStatus status) { - if (mPairStatus != status) { - mPairStatus = status; + if (m_pairStatus != status) { + m_pairStatus = status; Q_EMIT pairStatusChanged(status); } } diff --git a/core/backends/devicelink.h b/core/backends/devicelink.h index e4ba5a51..deb53293 100644 --- a/core/backends/devicelink.h +++ b/core/backends/devicelink.h @@ -1,79 +1,79 @@ /** * Copyright 2013 Albert Vaca * * 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 DEVICELINK_H #define DEVICELINK_H #include #include #include "core/networkpackage.h" class PairingHandler; class NetworkPackage; class LinkProvider; class Device; class DeviceLink : public QObject { Q_OBJECT public: enum PairStatus { NotPaired, Paired }; DeviceLink(const QString& deviceId, LinkProvider* parent); virtual ~DeviceLink() = default; virtual QString name() = 0; - const QString& deviceId() const { return mDeviceId; } - LinkProvider* provider() { return mLinkProvider; } + const QString& deviceId() const { return m_deviceId; } + LinkProvider* provider() { return m_linkProvider; } virtual bool sendPackage(NetworkPackage& np) = 0; //user actions virtual void userRequestsPair() = 0; virtual void userRequestsUnpair() = 0; - PairStatus pairStatus() const { return mPairStatus; } + PairStatus pairStatus() const { return m_pairStatus; } virtual void setPairStatus(PairStatus status); //The daemon will periodically destroy unpaired links if this returns false virtual bool linkShouldBeKeptAlive() { return false; } Q_SIGNALS: void pairingRequest(PairingHandler* handler); void pairingRequestExpired(PairingHandler* handler); void pairStatusChanged(DeviceLink::PairStatus status); - void pairingError(const QString &error); + void pairingError(const QString& error); void receivedPackage(const NetworkPackage& np); protected: - QCA::PrivateKey mPrivateKey; + QCA::PrivateKey m_privateKey; private: - const QString mDeviceId; - LinkProvider* mLinkProvider; - PairStatus mPairStatus; + const QString m_deviceId; + LinkProvider* m_linkProvider; + PairStatus m_pairStatus; }; #endif diff --git a/core/backends/lan/downloadjob.cpp b/core/backends/lan/downloadjob.cpp index 8db5901f..e861af3d 100644 --- a/core/backends/lan/downloadjob.cpp +++ b/core/backends/lan/downloadjob.cpp @@ -1,79 +1,79 @@ /* * Copyright 2013 Albert Vaca * * 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 "downloadjob.h" #ifndef Q_OS_WIN #include #include #include #include #endif #include "kdeconnectconfig.h" #include "lanlinkprovider.h" #include "core/core_debug.h" -DownloadJob::DownloadJob(const QHostAddress &address, const QVariantMap &transferInfo) +DownloadJob::DownloadJob(const QHostAddress& address, const QVariantMap& transferInfo) : KJob() - , mAddress(address) - , mPort(transferInfo[QStringLiteral("port")].toInt()) - , mSocket(new QSslSocket) - , mBuffer(new QBuffer) + , m_address(address) + , m_port(transferInfo[QStringLiteral("port")].toInt()) + , m_socket(new QSslSocket) + , m_buffer(new QBuffer) { - LanLinkProvider::configureSslSocket(mSocket.data(), transferInfo.value(QStringLiteral("deviceId")).toString(), true); + LanLinkProvider::configureSslSocket(m_socket.data(), transferInfo.value(QStringLiteral("deviceId")).toString(), true); - connect(mSocket.data(), SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(socketFailed(QAbstractSocket::SocketError))); + connect(m_socket.data(), SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(socketFailed(QAbstractSocket::SocketError))); // connect(mSocket.data(), &QAbstractSocket::stateChanged, [](QAbstractSocket::SocketState state){ qDebug() << "statechange" << state; }); } DownloadJob::~DownloadJob() { } void DownloadJob::start() { //TODO: Timeout? // Cannot use read only, might be due to ssl handshake, getting QIODevice::ReadOnly error and no connection - mSocket->connectToHostEncrypted(mAddress.toString(), mPort, QIODevice::ReadWrite); + m_socket->connectToHostEncrypted(m_address.toString(), m_port, QIODevice::ReadWrite); - bool b = mBuffer->open(QBuffer::ReadWrite); + bool b = m_buffer->open(QBuffer::ReadWrite); Q_ASSERT(b); } void DownloadJob::socketFailed(QAbstractSocket::SocketError error) { if (error != QAbstractSocket::RemoteHostClosedError) { //remote host closes when finishes - qWarning(KDECONNECT_CORE) << "error..." << mSocket->errorString(); + qWarning(KDECONNECT_CORE) << "error..." << m_socket->errorString(); setError(error + 1); - setErrorText(mSocket->errorString()); + setErrorText(m_socket->errorString()); } else { - auto ba = mSocket->readAll(); - mBuffer->write(ba); - mBuffer->seek(0); + auto ba = m_socket->readAll(); + m_buffer->write(ba); + m_buffer->seek(0); } emitResult(); } QSharedPointer DownloadJob::getPayload() { - return mBuffer.staticCast(); + return m_buffer.staticCast(); } diff --git a/core/backends/lan/downloadjob.h b/core/backends/lan/downloadjob.h index daa898eb..a84dc626 100644 --- a/core/backends/lan/downloadjob.h +++ b/core/backends/lan/downloadjob.h @@ -1,57 +1,57 @@ /* * Copyright 2013 Albert Vaca * * 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 DOWNLOADJOB_H #define DOWNLOADJOB_H #include #include #include #include #include #include #include #include "kdeconnectcore_export.h" class KDECONNECTCORE_EXPORT DownloadJob : public KJob { Q_OBJECT public: - DownloadJob(const QHostAddress &address, const QVariantMap &transferInfo); + DownloadJob(const QHostAddress& address, const QVariantMap& transferInfo); ~DownloadJob() override; void start() override; QSharedPointer getPayload(); private: - QHostAddress mAddress; - qint16 mPort; - QSharedPointer mSocket; - QSharedPointer mBuffer; + QHostAddress m_address; + qint16 m_port; + QSharedPointer m_socket; + QSharedPointer m_buffer; private Q_SLOTS: void socketFailed(QAbstractSocket::SocketError error); }; #endif // UPLOADJOB_H diff --git a/core/backends/lan/landevicelink.cpp b/core/backends/lan/landevicelink.cpp index 0a8302a7..8df7d97a 100644 --- a/core/backends/lan/landevicelink.cpp +++ b/core/backends/lan/landevicelink.cpp @@ -1,178 +1,178 @@ /** * Copyright 2013 Albert Vaca * * 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 "landevicelink.h" #include "core_debug.h" #include "kdeconnectconfig.h" #include "backends/linkprovider.h" #include "uploadjob.h" #include "downloadjob.h" #include "socketlinereader.h" #include "lanlinkprovider.h" LanDeviceLink::LanDeviceLink(const QString& deviceId, LinkProvider* parent, QSslSocket* socket, ConnectionStarted connectionSource) : DeviceLink(deviceId, parent) - , mSocketLineReader(nullptr) + , m_socketLineReader(nullptr) { reset(socket, connectionSource); } void LanDeviceLink::reset(QSslSocket* socket, ConnectionStarted connectionSource) { - if (mSocketLineReader) { - disconnect(mSocketLineReader->mSocket, &QAbstractSocket::disconnected, this, &QObject::deleteLater); - delete mSocketLineReader; + if (m_socketLineReader) { + disconnect(m_socketLineReader->m_socket, &QAbstractSocket::disconnected, this, &QObject::deleteLater); + delete m_socketLineReader; } - mSocketLineReader = new SocketLineReader(socket, this); + m_socketLineReader = new SocketLineReader(socket, this); connect(socket, &QAbstractSocket::disconnected, this, &QObject::deleteLater); - connect(mSocketLineReader, &SocketLineReader::readyRead, this, &LanDeviceLink::dataReceived); + connect(m_socketLineReader, &SocketLineReader::readyRead, this, &LanDeviceLink::dataReceived); //We take ownership of the socket. //When the link provider destroys us, //the socket (and the reader) will be //destroyed as well - socket->setParent(mSocketLineReader); + socket->setParent(m_socketLineReader); - mConnectionSource = connectionSource; + m_connectionSource = connectionSource; QString certString = KdeConnectConfig::instance()->getDeviceProperty(deviceId(), QStringLiteral("certificate")); DeviceLink::setPairStatus(certString.isEmpty()? PairStatus::NotPaired : PairStatus::Paired); } QHostAddress LanDeviceLink::hostAddress() const { - if (!mSocketLineReader) { + if (!m_socketLineReader) { return QHostAddress::Null; } - QHostAddress addr = mSocketLineReader->mSocket->peerAddress(); + QHostAddress addr = m_socketLineReader->m_socket->peerAddress(); if (addr.protocol() == QAbstractSocket::IPv6Protocol) { bool success; QHostAddress convertedAddr = QHostAddress(addr.toIPv4Address(&success)); if (success) { qCDebug(KDECONNECT_CORE) << "Converting IPv6" << addr << "to IPv4" << convertedAddr; addr = convertedAddr; } } return addr; } QString LanDeviceLink::name() { return QStringLiteral("LanLink"); // Should be same in both android and kde version } bool LanDeviceLink::sendPackage(NetworkPackage& np) { if (np.hasPayload()) { np.setPayloadTransferInfo(sendPayload(np)->transferInfo()); } - int written = mSocketLineReader->write(np.serialize()); + int written = m_socketLineReader->write(np.serialize()); //Actually we can't detect if a package is received or not. We keep TCP //"ESTABLISHED" connections that look legit (return true when we use them), //but that are actually broken (until keepalive detects that they are down). return (written != -1); } UploadJob* LanDeviceLink::sendPayload(const NetworkPackage& np) { UploadJob* job = new UploadJob(np.payload(), deviceId()); job->start(); return job; } void LanDeviceLink::dataReceived() { - if (mSocketLineReader->bytesAvailable() == 0) return; + if (m_socketLineReader->bytesAvailable() == 0) return; - const QByteArray serializedPackage = mSocketLineReader->readLine(); + const QByteArray serializedPackage = m_socketLineReader->readLine(); NetworkPackage package(QString::null); NetworkPackage::unserialize(serializedPackage, &package); //qCDebug(KDECONNECT_CORE) << "LanDeviceLink dataReceived" << serializedPackage; if (package.type() == PACKAGE_TYPE_PAIR) { //TODO: Handle pair/unpair requests and forward them (to the pairing handler?) qobject_cast(provider())->incomingPairPackage(this, package); return; } if (package.hasPayloadTransferInfo()) { //qCDebug(KDECONNECT_CORE) << "HasPayloadTransferInfo"; QVariantMap transferInfo = package.payloadTransferInfo(); //FIXME: The next two lines shouldn't be needed! Why are they here? transferInfo.insert(QStringLiteral("useSsl"), true); transferInfo.insert(QStringLiteral("deviceId"), deviceId()); - DownloadJob* job = new DownloadJob(mSocketLineReader->peerAddress(), transferInfo); + DownloadJob* job = new DownloadJob(m_socketLineReader->peerAddress(), transferInfo); job->start(); package.setPayload(job->getPayload(), package.payloadSize()); } Q_EMIT receivedPackage(package); - if (mSocketLineReader->bytesAvailable() > 0) { + if (m_socketLineReader->bytesAvailable() > 0) { QMetaObject::invokeMethod(this, "dataReceived", Qt::QueuedConnection); } } void LanDeviceLink::userRequestsPair() { - if (mSocketLineReader->peerCertificate().isNull()) { + if (m_socketLineReader->peerCertificate().isNull()) { Q_EMIT pairingError(i18n("This device cannot be paired because it is running an old version of KDE Connect.")); } else { qobject_cast(provider())->userRequestsPair(deviceId()); } } void LanDeviceLink::userRequestsUnpair() { qobject_cast(provider())->userRequestsUnpair(deviceId()); } void LanDeviceLink::setPairStatus(PairStatus status) { - if (status == Paired && mSocketLineReader->peerCertificate().isNull()) { + if (status == Paired && m_socketLineReader->peerCertificate().isNull()) { Q_EMIT pairingError(i18n("This device cannot be paired because it is running an old version of KDE Connect.")); return; } DeviceLink::setPairStatus(status); if (status == Paired) { Q_ASSERT(KdeConnectConfig::instance()->trustedDevices().contains(deviceId())); - Q_ASSERT(!mSocketLineReader->peerCertificate().isNull()); - KdeConnectConfig::instance()->setDeviceProperty(deviceId(), QStringLiteral("certificate"), mSocketLineReader->peerCertificate().toPem()); + Q_ASSERT(!m_socketLineReader->peerCertificate().isNull()); + KdeConnectConfig::instance()->setDeviceProperty(deviceId(), QStringLiteral("certificate"), m_socketLineReader->peerCertificate().toPem()); } } bool LanDeviceLink::linkShouldBeKeptAlive() { return true; //FIXME: Current implementation is broken, so for now we will keep links always established //We keep the remotely initiated connections, since the remotes require them if they want to request //pairing to us, or connections that are already paired. TODO: Keep connections in the process of pairing //return (mConnectionSource == ConnectionStarted::Remotely || pairStatus() == Paired); } diff --git a/core/backends/lan/landevicelink.h b/core/backends/lan/landevicelink.h index 6c0cd9cb..adb2a4b5 100644 --- a/core/backends/lan/landevicelink.h +++ b/core/backends/lan/landevicelink.h @@ -1,68 +1,68 @@ /** * Copyright 2013 Albert Vaca * * 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 LANDEVICELINK_H #define LANDEVICELINK_H #include #include #include #include #include #include "backends/devicelink.h" #include "uploadjob.h" class SocketLineReader; class KDECONNECTCORE_EXPORT LanDeviceLink : public DeviceLink { Q_OBJECT public: enum ConnectionStarted : bool { Locally, Remotely }; LanDeviceLink(const QString& deviceId, LinkProvider* parent, QSslSocket* socket, ConnectionStarted connectionSource); void reset(QSslSocket* socket, ConnectionStarted connectionSource); QString name() override; bool sendPackage(NetworkPackage& np) override; UploadJob* sendPayload(const NetworkPackage& np); void userRequestsPair() override; void userRequestsUnpair() override; void setPairStatus(PairStatus status) override; bool linkShouldBeKeptAlive() override; QHostAddress hostAddress() const; private Q_SLOTS: void dataReceived(); private: - SocketLineReader* mSocketLineReader; - ConnectionStarted mConnectionSource; - QHostAddress mHostAddress; + SocketLineReader* m_socketLineReader; + ConnectionStarted m_connectionSource; + QHostAddress m_hostAddress; }; #endif diff --git a/core/backends/lan/lanlinkprovider.cpp b/core/backends/lan/lanlinkprovider.cpp index 91963e0d..87c2abd9 100644 --- a/core/backends/lan/lanlinkprovider.cpp +++ b/core/backends/lan/lanlinkprovider.cpp @@ -1,538 +1,538 @@ /** * Copyright 2013 Albert Vaca * * 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 "lanlinkprovider.h" #include "core_debug.h" #ifndef Q_OS_WIN #include #include #include #include #endif #include #include #include #include #include #include #include #include #include "daemon.h" #include "landevicelink.h" #include "lanpairinghandler.h" #include "kdeconnectconfig.h" #define MIN_VERSION_WITH_SSL_SUPPORT 6 LanLinkProvider::LanLinkProvider(bool testMode) - : mTestMode(testMode) + : m_testMode(testMode) { - mTcpPort = 0; + m_tcpPort = 0; - combineBroadcastsTimer.setInterval(0); // increase this if waiting a single event-loop iteration is not enough - combineBroadcastsTimer.setSingleShot(true); - connect(&combineBroadcastsTimer, &QTimer::timeout, this, &LanLinkProvider::broadcastToNetwork); + m_combineBroadcastsTimer.setInterval(0); // increase this if waiting a single event-loop iteration is not enough + m_combineBroadcastsTimer.setSingleShot(true); + connect(&m_combineBroadcastsTimer, &QTimer::timeout, this, &LanLinkProvider::broadcastToNetwork); - connect(&mUdpSocket, &QIODevice::readyRead, this, &LanLinkProvider::newUdpConnection); + connect(&m_udpSocket, &QIODevice::readyRead, this, &LanLinkProvider::newUdpConnection); - mServer = new Server(this); - mServer->setProxy(QNetworkProxy::NoProxy); - connect(mServer,&QTcpServer::newConnection,this, &LanLinkProvider::newConnection); + m_server = new Server(this); + m_server->setProxy(QNetworkProxy::NoProxy); + connect(m_server,&QTcpServer::newConnection,this, &LanLinkProvider::newConnection); - mUdpSocket.setProxy(QNetworkProxy::NoProxy); + m_udpSocket.setProxy(QNetworkProxy::NoProxy); //Detect when a network interface changes status, so we announce ourelves in the new network QNetworkConfigurationManager* networkManager = new QNetworkConfigurationManager(this); connect(networkManager, &QNetworkConfigurationManager::configurationChanged, this, &LanLinkProvider::onNetworkConfigurationChanged); } -void LanLinkProvider::onNetworkConfigurationChanged(const QNetworkConfiguration &config) +void LanLinkProvider::onNetworkConfigurationChanged(const QNetworkConfiguration& config) { if (m_lastConfig != config && config.state() == QNetworkConfiguration::Active) { m_lastConfig = config; onNetworkChange(); } } LanLinkProvider::~LanLinkProvider() { } void LanLinkProvider::onStart() { - const QHostAddress bindAddress = mTestMode? QHostAddress::LocalHost : QHostAddress::Any; + const QHostAddress bindAddress = m_testMode? QHostAddress::LocalHost : QHostAddress::Any; - bool success = mUdpSocket.bind(bindAddress, UDP_PORT, QUdpSocket::ShareAddress); + bool success = m_udpSocket.bind(bindAddress, UDP_PORT, QUdpSocket::ShareAddress); Q_ASSERT(success); qCDebug(KDECONNECT_CORE) << "onStart"; - mTcpPort = MIN_TCP_PORT; - while (!mServer->listen(bindAddress, mTcpPort)) { - mTcpPort++; - if (mTcpPort > MAX_TCP_PORT) { //No ports available? + m_tcpPort = MIN_TCP_PORT; + while (!m_server->listen(bindAddress, m_tcpPort)) { + m_tcpPort++; + if (m_tcpPort > MAX_TCP_PORT) { //No ports available? qCritical(KDECONNECT_CORE) << "Error opening a port in range" << MIN_TCP_PORT << "-" << MAX_TCP_PORT; - mTcpPort = 0; + m_tcpPort = 0; return; } } onNetworkChange(); } void LanLinkProvider::onStop() { qCDebug(KDECONNECT_CORE) << "onStop"; - mUdpSocket.close(); - mServer->close(); + m_udpSocket.close(); + m_server->close(); } void LanLinkProvider::onNetworkChange() { - if (combineBroadcastsTimer.isActive()) { + if (m_combineBroadcastsTimer.isActive()) { qCDebug(KDECONNECT_CORE()) << "Preventing duplicate broadcasts"; return; } - combineBroadcastsTimer.start(); + m_combineBroadcastsTimer.start(); } //I'm in a new network, let's be polite and introduce myself void LanLinkProvider::broadcastToNetwork() { - if (!mServer->isListening()) { + if (!m_server->isListening()) { //Not started return; } - Q_ASSERT(mTcpPort != 0); + Q_ASSERT(m_tcpPort != 0); qCDebug(KDECONNECT_CORE()) << "Broadcasting identity packet"; - QHostAddress destAddress = mTestMode? QHostAddress::LocalHost : QHostAddress(QStringLiteral("255.255.255.255")); + QHostAddress destAddress = m_testMode? QHostAddress::LocalHost : QHostAddress(QStringLiteral("255.255.255.255")); NetworkPackage np(QLatin1String("")); NetworkPackage::createIdentityPackage(&np); - np.set(QStringLiteral("tcpPort"), mTcpPort); + np.set(QStringLiteral("tcpPort"), m_tcpPort); #ifdef Q_OS_WIN //On Windows we need to broadcast from every local IP address to reach all networks QUdpSocket sendSocket; sendSocket.setProxy(QNetworkProxy::NoProxy); - for (const QNetworkInterface &iface : QNetworkInterface::allInterfaces()) { + for (const QNetworkInterface& iface : QNetworkInterface::allInterfaces()) { if ( (iface.flags() & QNetworkInterface::IsUp) && (iface.flags() & QNetworkInterface::IsRunning) && (iface.flags() & QNetworkInterface::CanBroadcast)) { - for (const QNetworkAddressEntry &ifaceAddress : iface.addressEntries()) { + for (const QNetworkAddressEntry& ifaceAddress : iface.addressEntries()) { QHostAddress sourceAddress = ifaceAddress.ip(); if (sourceAddress.protocol() == QAbstractSocket::IPv4Protocol && sourceAddress != QHostAddress::LocalHost) { qCDebug(KDECONNECT_CORE()) << "Broadcasting as" << sourceAddress; sendSocket.bind(sourceAddress, UDP_PORT); sendSocket.writeDatagram(np.serialize(), destAddress, UDP_PORT); sendSocket.close(); } } } } #else - mUdpSocket.writeDatagram(np.serialize(), destAddress, UDP_PORT); + m_udpSocket.writeDatagram(np.serialize(), destAddress, UDP_PORT); #endif } //I'm the existing device, a new device is kindly introducing itself. //I will create a TcpSocket and try to connect. This can result in either connected() or connectError(). void LanLinkProvider::newUdpConnection() //udpBroadcastReceived { - while (mUdpSocket.hasPendingDatagrams()) { + while (m_udpSocket.hasPendingDatagrams()) { QByteArray datagram; - datagram.resize(mUdpSocket.pendingDatagramSize()); + datagram.resize(m_udpSocket.pendingDatagramSize()); QHostAddress sender; - mUdpSocket.readDatagram(datagram.data(), datagram.size(), &sender); + m_udpSocket.readDatagram(datagram.data(), datagram.size(), &sender); - if (sender.isLoopback() && !mTestMode) + if (sender.isLoopback() && !m_testMode) continue; NetworkPackage* receivedPackage = new NetworkPackage(QLatin1String("")); bool success = NetworkPackage::unserialize(datagram, receivedPackage); //qCDebug(KDECONNECT_CORE) << "udp connection from " << receivedPackage->; //qCDebug(KDECONNECT_CORE) << "Datagram " << datagram.data() ; if (!success || receivedPackage->type() != PACKAGE_TYPE_IDENTITY) { delete receivedPackage; continue; } if (receivedPackage->get(QStringLiteral("deviceId")) == KdeConnectConfig::instance()->deviceId()) { //qCDebug(KDECONNECT_CORE) << "Ignoring my own broadcast"; delete receivedPackage; continue; } int tcpPort = receivedPackage->get(QStringLiteral("tcpPort")); //qCDebug(KDECONNECT_CORE) << "Received Udp identity package from" << sender << " asking for a tcp connection on port " << tcpPort; QSslSocket* socket = new QSslSocket(this); socket->setProxy(QNetworkProxy::NoProxy); - receivedIdentityPackages[socket].np = receivedPackage; - receivedIdentityPackages[socket].sender = sender; + m_receivedIdentityPackages[socket].np = receivedPackage; + m_receivedIdentityPackages[socket].sender = sender; connect(socket, &QAbstractSocket::connected, this, &LanLinkProvider::connected); connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(connectError())); socket->connectToHost(sender, tcpPort); } } void LanLinkProvider::connectError() { QSslSocket* socket = qobject_cast(sender()); if (!socket) return; disconnect(socket, &QAbstractSocket::connected, this, &LanLinkProvider::connected); disconnect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(connectError())); qCDebug(KDECONNECT_CORE) << "Fallback (1), try reverse connection (send udp packet)" << socket->errorString(); NetworkPackage np(QLatin1String("")); NetworkPackage::createIdentityPackage(&np); - np.set(QStringLiteral("tcpPort"), mTcpPort); - mUdpSocket.writeDatagram(np.serialize(), receivedIdentityPackages[socket].sender, UDP_PORT); + np.set(QStringLiteral("tcpPort"), m_tcpPort); + m_udpSocket.writeDatagram(np.serialize(), m_receivedIdentityPackages[socket].sender, UDP_PORT); //The socket we created didn't work, and we didn't manage //to create a LanDeviceLink from it, deleting everything. - delete receivedIdentityPackages.take(socket).np; + delete m_receivedIdentityPackages.take(socket).np; delete socket; } //We received a UDP package and answered by connecting to them by TCP. This gets called on a succesful connection. void LanLinkProvider::connected() { QSslSocket* socket = qobject_cast(sender()); if (!socket) return; disconnect(socket, &QAbstractSocket::connected, this, &LanLinkProvider::connected); disconnect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(connectError())); configureSocket(socket); // If socket disconnects due to any reason after connection, link on ssl faliure connect(socket, &QAbstractSocket::disconnected, socket, &QObject::deleteLater); - NetworkPackage* receivedPackage = receivedIdentityPackages[socket].np; + NetworkPackage* receivedPackage = m_receivedIdentityPackages[socket].np; const QString& deviceId = receivedPackage->get(QStringLiteral("deviceId")); //qCDebug(KDECONNECT_CORE) << "Connected" << socket->isWritable(); // If network is on ssl, do not believe when they are connected, believe when handshake is completed NetworkPackage np2(QLatin1String("")); NetworkPackage::createIdentityPackage(&np2); socket->write(np2.serialize()); bool success = socket->waitForBytesWritten(); if (success) { qCDebug(KDECONNECT_CORE) << "TCP connection done (i'm the existing device)"; // if ssl supported if (receivedPackage->get(QStringLiteral("protocolVersion")) >= MIN_VERSION_WITH_SSL_SUPPORT) { bool isDeviceTrusted = KdeConnectConfig::instance()->trustedDevices().contains(deviceId); configureSslSocket(socket, deviceId, isDeviceTrusted); qCDebug(KDECONNECT_CORE) << "Starting server ssl (I'm the client TCP socket)"; connect(socket, &QSslSocket::encrypted, this, &LanLinkProvider::encrypted); if (isDeviceTrusted) { connect(socket, SIGNAL(sslErrors(QList)), this, SLOT(sslErrors(QList))); } socket->startServerEncryption(); return; // Return statement prevents from deleting received package, needed in slot "encrypted" } else { qWarning() << receivedPackage->get(QStringLiteral("deviceName")) << "uses an old protocol version, this won't work"; //addLink(deviceId, socket, receivedPackage, LanDeviceLink::Remotely); } } else { //I think this will never happen, but if it happens the deviceLink //(or the socket that is now inside it) might not be valid. Delete them. qCDebug(KDECONNECT_CORE) << "Fallback (2), try reverse connection (send udp packet)"; - mUdpSocket.writeDatagram(np2.serialize(), receivedIdentityPackages[socket].sender, UDP_PORT); + m_udpSocket.writeDatagram(np2.serialize(), m_receivedIdentityPackages[socket].sender, UDP_PORT); } - delete receivedIdentityPackages.take(socket).np; + delete m_receivedIdentityPackages.take(socket).np; //We don't delete the socket because now it's owned by the LanDeviceLink } void LanLinkProvider::encrypted() { qCDebug(KDECONNECT_CORE) << "Socket succesfully stablished an SSL connection"; QSslSocket* socket = qobject_cast(sender()); if (!socket) return; disconnect(socket, &QSslSocket::encrypted, this, &LanLinkProvider::encrypted); disconnect(socket, SIGNAL(sslErrors(QList)), this, SLOT(sslErrors(QList))); Q_ASSERT(socket->mode() != QSslSocket::UnencryptedMode); LanDeviceLink::ConnectionStarted connectionOrigin = (socket->mode() == QSslSocket::SslClientMode)? LanDeviceLink::Locally : LanDeviceLink::Remotely; - NetworkPackage* receivedPackage = receivedIdentityPackages[socket].np; + NetworkPackage* receivedPackage = m_receivedIdentityPackages[socket].np; const QString& deviceId = receivedPackage->get(QStringLiteral("deviceId")); addLink(deviceId, socket, receivedPackage, connectionOrigin); // Copied from connected slot, now delete received package - delete receivedIdentityPackages.take(socket).np; + delete m_receivedIdentityPackages.take(socket).np; } void LanLinkProvider::sslErrors(const QList& errors) { QSslSocket* socket = qobject_cast(sender()); if (!socket) return; disconnect(socket, &QSslSocket::encrypted, this, &LanLinkProvider::encrypted); disconnect(socket, SIGNAL(sslErrors(QList)), this, SLOT(sslErrors(QList))); qCDebug(KDECONNECT_CORE) << "Failing due to " << errors; - Device *device = Daemon::instance()->getDevice(socket->peerVerifyName()); + Device* device = Daemon::instance()->getDevice(socket->peerVerifyName()); if (device) { device->unpair(); } - delete receivedIdentityPackages.take(socket).np; + delete m_receivedIdentityPackages.take(socket).np; // Socket disconnects itself on ssl error and will be deleted by deleteLater slot, no need to delete manually } //I'm the new device and this is the answer to my UDP identity package (no data received yet). They are connecting to us through TCP, and they should send an identity. void LanLinkProvider::newConnection() { //qCDebug(KDECONNECT_CORE) << "LanLinkProvider newConnection"; - while (mServer->hasPendingConnections()) { - QSslSocket* socket = mServer->nextPendingConnection(); + while (m_server->hasPendingConnections()) { + QSslSocket* socket = m_server->nextPendingConnection(); configureSocket(socket); //This socket is still managed by us (and child of the QTcpServer), if //it disconnects before we manage to pass it to a LanDeviceLink, it's //our responsibility to delete it. We do so with this connection. connect(socket, &QAbstractSocket::disconnected, socket, &QObject::deleteLater); connect(socket, &QIODevice::readyRead, this, &LanLinkProvider::dataReceived); } } //I'm the new device and this is the answer to my UDP identity package (data received) void LanLinkProvider::dataReceived() { QSslSocket* socket = qobject_cast(sender()); const QByteArray data = socket->readLine(); //qCDebug(KDECONNECT_CORE) << "LanLinkProvider received reply:" << data; NetworkPackage* np = new NetworkPackage(QLatin1String("")); bool success = NetworkPackage::unserialize(data, np); if (!success) { delete np; return; } if (np->type() != PACKAGE_TYPE_IDENTITY) { qCWarning(KDECONNECT_CORE) << "LanLinkProvider/newConnection: Expected identity, received " << np->type(); delete np; return; } // Needed in "encrypted" if ssl is used, similar to "connected" - receivedIdentityPackages[socket].np = np; + m_receivedIdentityPackages[socket].np = np; const QString& deviceId = np->get(QStringLiteral("deviceId")); //qCDebug(KDECONNECT_CORE) << "Handshaking done (i'm the new device)"; //This socket will now be owned by the LanDeviceLink or we don't want more data to be received, forget about it disconnect(socket, &QIODevice::readyRead, this, &LanLinkProvider::dataReceived); if (np->get(QStringLiteral("protocolVersion")) >= MIN_VERSION_WITH_SSL_SUPPORT) { bool isDeviceTrusted = KdeConnectConfig::instance()->trustedDevices().contains(deviceId); configureSslSocket(socket, deviceId, isDeviceTrusted); qCDebug(KDECONNECT_CORE) << "Starting client ssl (but I'm the server TCP socket)"; connect(socket, &QSslSocket::encrypted, this, &LanLinkProvider::encrypted); if (isDeviceTrusted) { connect(socket, SIGNAL(sslErrors(QList)), this, SLOT(sslErrors(QList))); } socket->startClientEncryption(); } else { qWarning() << np->get(QStringLiteral("deviceName")) << "uses an old protocol version, this won't work"; //addLink(deviceId, socket, np, LanDeviceLink::Locally); - delete receivedIdentityPackages.take(socket).np; + delete m_receivedIdentityPackages.take(socket).np; } } void LanLinkProvider::deviceLinkDestroyed(QObject* destroyedDeviceLink) { const QString id = destroyedDeviceLink->property("deviceId").toString(); //qCDebug(KDECONNECT_CORE) << "deviceLinkDestroyed" << id; - Q_ASSERT(mLinks.key(static_cast(destroyedDeviceLink)) == id); - QMap< QString, LanDeviceLink* >::iterator linkIterator = mLinks.find(id); - if (linkIterator != mLinks.end()) { + Q_ASSERT(m_links.key(static_cast(destroyedDeviceLink)) == id); + QMap< QString, LanDeviceLink* >::iterator linkIterator = m_links.find(id); + if (linkIterator != m_links.end()) { Q_ASSERT(linkIterator.value() == destroyedDeviceLink); - mLinks.erase(linkIterator); - mPairingHandlers.take(id)->deleteLater(); + m_links.erase(linkIterator); + m_pairingHandlers.take(id)->deleteLater(); } } void LanLinkProvider::configureSslSocket(QSslSocket* socket, const QString& deviceId, bool isDeviceTrusted) { // Setting supported ciphers manually // Top 3 ciphers are for new Android devices, botton two are for old Android devices // FIXME : These cipher suites should be checked whether they are supported or not on device QList socketCiphers; socketCiphers.append(QSslCipher(QStringLiteral("ECDHE-ECDSA-AES256-GCM-SHA384"))); socketCiphers.append(QSslCipher(QStringLiteral("ECDHE-ECDSA-AES128-GCM-SHA256"))); socketCiphers.append(QSslCipher(QStringLiteral("ECDHE-RSA-AES128-SHA"))); socketCiphers.append(QSslCipher(QStringLiteral("RC4-SHA"))); socketCiphers.append(QSslCipher(QStringLiteral("RC4-MD5"))); // Configure for ssl QSslConfiguration sslConfig; sslConfig.setCiphers(socketCiphers); sslConfig.setProtocol(QSsl::TlsV1_0); socket->setSslConfiguration(sslConfig); socket->setLocalCertificate(KdeConnectConfig::instance()->certificate()); socket->setPrivateKey(KdeConnectConfig::instance()->privateKeyPath()); socket->setPeerVerifyName(deviceId); if (isDeviceTrusted) { QString certString = KdeConnectConfig::instance()->getDeviceProperty(deviceId, QStringLiteral("certificate"), QString()); socket->addCaCertificate(QSslCertificate(certString.toLatin1())); socket->setPeerVerifyMode(QSslSocket::VerifyPeer); } else { socket->setPeerVerifyMode(QSslSocket::QueryPeer); } //Usually SSL errors are only bad for trusted devices. Uncomment this section to log errors in any case, for debugging. //QObject::connect(socket, static_cast&)>(&QSslSocket::sslErrors), [](const QList& errors) //{ - // Q_FOREACH (const QSslError &error, errors) { + // Q_FOREACH (const QSslError& error, errors) { // qCDebug(KDECONNECT_CORE) << "SSL Error:" << error.errorString(); // } //}); } void LanLinkProvider::configureSocket(QSslSocket* socket) { socket->setProxy(QNetworkProxy::NoProxy); socket->setSocketOption(QAbstractSocket::KeepAliveOption, QVariant(1)); #ifdef TCP_KEEPIDLE // time to start sending keepalive packets (seconds) int maxIdle = 10; setsockopt(socket->socketDescriptor(), IPPROTO_TCP, TCP_KEEPIDLE, &maxIdle, sizeof(maxIdle)); #endif #ifdef TCP_KEEPINTVL // interval between keepalive packets after the initial period (seconds) int interval = 5; setsockopt(socket->socketDescriptor(), IPPROTO_TCP, TCP_KEEPINTVL, &interval, sizeof(interval)); #endif #ifdef TCP_KEEPCNT // number of missed keepalive packets before disconnecting int count = 3; setsockopt(socket->socketDescriptor(), IPPROTO_TCP, TCP_KEEPCNT, &count, sizeof(count)); #endif } void LanLinkProvider::addLink(const QString& deviceId, QSslSocket* socket, NetworkPackage* receivedPackage, LanDeviceLink::ConnectionStarted connectionOrigin) { // Socket disconnection will now be handled by LanDeviceLink disconnect(socket, &QAbstractSocket::disconnected, socket, &QObject::deleteLater); LanDeviceLink* deviceLink; //Do we have a link for this device already? - QMap< QString, LanDeviceLink* >::iterator linkIterator = mLinks.find(deviceId); - if (linkIterator != mLinks.end()) { + QMap< QString, LanDeviceLink* >::iterator linkIterator = m_links.find(deviceId); + if (linkIterator != m_links.end()) { //qCDebug(KDECONNECT_CORE) << "Reusing link to" << deviceId; deviceLink = linkIterator.value(); deviceLink->reset(socket, connectionOrigin); } else { deviceLink = new LanDeviceLink(deviceId, this, socket, connectionOrigin); connect(deviceLink, &QObject::destroyed, this, &LanLinkProvider::deviceLinkDestroyed); - mLinks[deviceId] = deviceLink; - if (mPairingHandlers.contains(deviceId)) { + m_links[deviceId] = deviceLink; + if (m_pairingHandlers.contains(deviceId)) { //We shouldn't have a pairinghandler if we didn't have a link. //Crash if debug, recover if release (by setting the new devicelink to the old pairinghandler) - Q_ASSERT(mPairingHandlers.contains(deviceId)); - mPairingHandlers[deviceId]->setDeviceLink(deviceLink); + Q_ASSERT(m_pairingHandlers.contains(deviceId)); + m_pairingHandlers[deviceId]->setDeviceLink(deviceLink); } Q_EMIT onConnectionReceived(*receivedPackage, deviceLink); } } LanPairingHandler* LanLinkProvider::createPairingHandler(DeviceLink* link) { - LanPairingHandler* ph = mPairingHandlers.value(link->deviceId()); + LanPairingHandler* ph = m_pairingHandlers.value(link->deviceId()); if (!ph) { ph = new LanPairingHandler(link); qCDebug(KDECONNECT_CORE) << "creating pairing handler for" << link->deviceId(); connect (ph, &LanPairingHandler::pairingError, link, &DeviceLink::pairingError); - mPairingHandlers[link->deviceId()] = ph; + m_pairingHandlers[link->deviceId()] = ph; } return ph; } void LanLinkProvider::userRequestsPair(const QString& deviceId) { - LanPairingHandler* ph = createPairingHandler(mLinks.value(deviceId)); + LanPairingHandler* ph = createPairingHandler(m_links.value(deviceId)); ph->requestPairing(); } void LanLinkProvider::userRequestsUnpair(const QString& deviceId) { - LanPairingHandler* ph = createPairingHandler(mLinks.value(deviceId)); + LanPairingHandler* ph = createPairingHandler(m_links.value(deviceId)); ph->unpair(); } void LanLinkProvider::incomingPairPackage(DeviceLink* deviceLink, const NetworkPackage& np) { LanPairingHandler* ph = createPairingHandler(deviceLink); ph->packageReceived(np); } diff --git a/core/backends/lan/lanlinkprovider.h b/core/backends/lan/lanlinkprovider.h index 30f798a2..983fe758 100644 --- a/core/backends/lan/lanlinkprovider.h +++ b/core/backends/lan/lanlinkprovider.h @@ -1,100 +1,100 @@ /** * Copyright 2013 Albert Vaca * * 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 LANLINKPROVIDER_H #define LANLINKPROVIDER_H #include #include #include #include #include #include #include #include "kdeconnectcore_export.h" #include "backends/linkprovider.h" #include "server.h" #include "landevicelink.h" class LanPairingHandler; class KDECONNECTCORE_EXPORT LanLinkProvider : public LinkProvider { Q_OBJECT public: LanLinkProvider(bool testMode = false); ~LanLinkProvider() override; QString name() override { return QStringLiteral("LanLinkProvider"); } int priority() override { return PRIORITY_HIGH; } - void userRequestsPair(const QString &deviceId); - void userRequestsUnpair(const QString &deviceId); + void userRequestsPair(const QString& deviceId); + void userRequestsUnpair(const QString& deviceId); void incomingPairPackage(DeviceLink* device, const NetworkPackage& np); static void configureSslSocket(QSslSocket* socket, const QString& deviceId, bool isDeviceTrusted); static void configureSocket(QSslSocket* socket); const static quint16 UDP_PORT = 1716; const static quint16 MIN_TCP_PORT = 1716; const static quint16 MAX_TCP_PORT = 1764; public Q_SLOTS: void onNetworkChange() override; void onStart() override; void onStop() override; void connected(); void encrypted(); void connectError(); private Q_SLOTS: void newUdpConnection(); void newConnection(); void dataReceived(); void deviceLinkDestroyed(QObject* destroyedDeviceLink); void sslErrors(const QList& errors); void broadcastToNetwork(); private: LanPairingHandler* createPairingHandler(DeviceLink* link); - void onNetworkConfigurationChanged(const QNetworkConfiguration &config); + void onNetworkConfigurationChanged(const QNetworkConfiguration& config); void addLink(const QString& deviceId, QSslSocket* socket, NetworkPackage* receivedPackage, LanDeviceLink::ConnectionStarted connectionOrigin); - Server* mServer; - QUdpSocket mUdpSocket; - quint16 mTcpPort; + Server* m_server; + QUdpSocket m_udpSocket; + quint16 m_tcpPort; - QMap mLinks; - QMap mPairingHandlers; + QMap m_links; + QMap m_pairingHandlers; struct PendingConnect { NetworkPackage* np; QHostAddress sender; }; - QMap receivedIdentityPackages; + QMap m_receivedIdentityPackages; QNetworkConfiguration m_lastConfig; - const bool mTestMode; - QTimer combineBroadcastsTimer; + const bool m_testMode; + QTimer m_combineBroadcastsTimer; }; #endif diff --git a/core/backends/lan/server.cpp b/core/backends/lan/server.cpp index 345c4903..0ad416e4 100644 --- a/core/backends/lan/server.cpp +++ b/core/backends/lan/server.cpp @@ -1,62 +1,62 @@ /** * Copyright 2015 Vineet Garg * * 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 "server.h" #include "kdeconnectconfig.h" #include "lanlinkprovider.h" #include #include #include Server::Server(QObject * parent) :QTcpServer(parent) { connect(this, &QTcpServer::acceptError, this, &Server::errorFound); } void Server::incomingConnection(qintptr socketDescriptor) { - QSslSocket *serverSocket = new QSslSocket(parent()); + QSslSocket* serverSocket = new QSslSocket(parent()); if (serverSocket->setSocketDescriptor(socketDescriptor)) { pendingConnections.append(serverSocket); Q_EMIT newConnection(); } else { qWarning() << "setSocketDescriptor failed " + serverSocket->errorString(); delete serverSocket; } } QSslSocket* Server::nextPendingConnection() { if (pendingConnections.isEmpty()) { return Q_NULLPTR; } else { return pendingConnections.takeFirst(); } } bool Server::hasPendingConnections() const { return !pendingConnections.isEmpty(); } void Server::errorFound(QAbstractSocket::SocketError socketError) { qDebug() << "error:" << socketError; } diff --git a/core/backends/lan/socketlinereader.cpp b/core/backends/lan/socketlinereader.cpp index 78b93586..3a9cc0fe 100644 --- a/core/backends/lan/socketlinereader.cpp +++ b/core/backends/lan/socketlinereader.cpp @@ -1,53 +1,53 @@ /** * Copyright 2013 Albert Vaca * Copyright 2014 Alejandro Fiestas Olivares * * 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 "socketlinereader.h" SocketLineReader::SocketLineReader(QSslSocket* socket, QObject* parent) : QObject(parent) - , mSocket(socket) + , m_socket(socket) { - connect(mSocket, &QIODevice::readyRead, + connect(m_socket, &QIODevice::readyRead, this, &SocketLineReader::dataReceived); } void SocketLineReader::dataReceived() { - while (mSocket->canReadLine()) { - const QByteArray line = mSocket->readLine(); + while (m_socket->canReadLine()) { + const QByteArray line = m_socket->readLine(); if (line.length() > 1) { //we don't want a single \n - mPackages.enqueue(line); + m_packages.enqueue(line); } } //If we still have things to read from the socket, call dataReceived again //We do this manually because we do not trust readyRead to be emitted again //So we call this method again just in case. - if (mSocket->bytesAvailable() > 0) { + if (m_socket->bytesAvailable() > 0) { QMetaObject::invokeMethod(this, "dataReceived", Qt::QueuedConnection); return; } //If we have any packages, tell it to the world. - if (!mPackages.isEmpty()) { + if (!m_packages.isEmpty()) { Q_EMIT readyRead(); } } diff --git a/core/backends/lan/socketlinereader.h b/core/backends/lan/socketlinereader.h index bdaf24ae..cebfb822 100644 --- a/core/backends/lan/socketlinereader.h +++ b/core/backends/lan/socketlinereader.h @@ -1,63 +1,63 @@ /** * Copyright 2013 Albert Vaca * * 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 SOCKETLINEREADER_H #define SOCKETLINEREADER_H #include #include #include #include #include /* * Encapsulates a QTcpSocket and implements the same methods of its API that are * used by LanDeviceLink, but readyRead is emitted only when a newline is found. */ class KDECONNECTCORE_EXPORT SocketLineReader : public QObject { Q_OBJECT public: explicit SocketLineReader(QSslSocket* socket, QObject* parent = nullptr); - QByteArray readLine() { return mPackages.dequeue(); } - qint64 write(const QByteArray& data) { return mSocket->write(data); } - QHostAddress peerAddress() const { return mSocket->peerAddress(); } - QSslCertificate peerCertificate() const { return mSocket->peerCertificate(); } - qint64 bytesAvailable() const { return mPackages.size(); } + QByteArray readLine() { return m_packages.dequeue(); } + qint64 write(const QByteArray& data) { return m_socket->write(data); } + QHostAddress peerAddress() const { return m_socket->peerAddress(); } + QSslCertificate peerCertificate() const { return m_socket->peerCertificate(); } + qint64 bytesAvailable() const { return m_packages.size(); } - QSslSocket* mSocket; + QSslSocket* m_socket; Q_SIGNALS: void readyRead(); private Q_SLOTS: void dataReceived(); private: - QByteArray lastChunk; - QQueue mPackages; + QByteArray m_lastChunk; + QQueue m_packages; }; #endif diff --git a/core/backends/lan/uploadjob.cpp b/core/backends/lan/uploadjob.cpp index c10204a6..573cd89c 100644 --- a/core/backends/lan/uploadjob.cpp +++ b/core/backends/lan/uploadjob.cpp @@ -1,133 +1,133 @@ /* * Copyright 2013 Albert Vaca * * 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 "uploadjob.h" #include #include "lanlinkprovider.h" #include "kdeconnectconfig.h" #include "core_debug.h" UploadJob::UploadJob(const QSharedPointer& source, const QString& deviceId) : KJob() - , mInput(source) - , mServer(new Server(this)) - , mSocket(nullptr) - , mPort(0) - , mDeviceId(deviceId) // We will use this info if link is on ssl, to send encrypted payload + , m_input(source) + , m_server(new Server(this)) + , m_socket(nullptr) + , m_port(0) + , m_deviceId(deviceId) // We will use this info if link is on ssl, to send encrypted payload { - connect(mInput.data(), &QIODevice::readyRead, this, &UploadJob::startUploading); - connect(mInput.data(), &QIODevice::aboutToClose, this, &UploadJob::aboutToClose); + connect(m_input.data(), &QIODevice::readyRead, this, &UploadJob::startUploading); + connect(m_input.data(), &QIODevice::aboutToClose, this, &UploadJob::aboutToClose); } void UploadJob::start() { - mPort = MIN_PORT; - while (!mServer->listen(QHostAddress::Any, mPort)) { - mPort++; - if (mPort > MAX_PORT) { //No ports available? + m_port = MIN_PORT; + while (!m_server->listen(QHostAddress::Any, m_port)) { + m_port++; + if (m_port > MAX_PORT) { //No ports available? qCWarning(KDECONNECT_CORE) << "Error opening a port in range" << MIN_PORT << "-" << MAX_PORT; - mPort = 0; + m_port = 0; setError(1); setErrorText(i18n("Couldn't find an available port")); emitResult(); return; } } - connect(mServer, &QTcpServer::newConnection, this, &UploadJob::newConnection); + connect(m_server, &QTcpServer::newConnection, this, &UploadJob::newConnection); } void UploadJob::newConnection() { - if (!mInput->open(QIODevice::ReadOnly)) { + if (!m_input->open(QIODevice::ReadOnly)) { qCWarning(KDECONNECT_CORE) << "error when opening the input to upload"; return; //TODO: Handle error, clean up... } Server* server = qobject_cast(sender()); // FIXME : It is called again when payload sending is finished. Unsolved mystery :( - disconnect(mServer, &QTcpServer::newConnection, this, &UploadJob::newConnection); - - mSocket = server->nextPendingConnection(); - mSocket->setParent(this); - connect(mSocket, &QSslSocket::disconnected, this, &UploadJob::cleanup); - connect(mSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(socketFailed(QAbstractSocket::SocketError))); - connect(mSocket, SIGNAL(sslErrors(QList)), this, SLOT(sslErrors(QList))); - connect(mSocket, &QSslSocket::encrypted, this, &UploadJob::startUploading); + disconnect(m_server, &QTcpServer::newConnection, this, &UploadJob::newConnection); + + m_socket = server->nextPendingConnection(); + m_socket->setParent(this); + connect(m_socket, &QSslSocket::disconnected, this, &UploadJob::cleanup); + connect(m_socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(socketFailed(QAbstractSocket::SocketError))); + connect(m_socket, SIGNAL(sslErrors(QList)), this, SLOT(sslErrors(QList))); + connect(m_socket, &QSslSocket::encrypted, this, &UploadJob::startUploading); // connect(mSocket, &QAbstractSocket::stateChanged, [](QAbstractSocket::SocketState state){ qDebug() << "statechange" << state; }); - LanLinkProvider::configureSslSocket(mSocket, mDeviceId, true); + LanLinkProvider::configureSslSocket(m_socket, m_deviceId, true); - mSocket->startServerEncryption(); + m_socket->startServerEncryption(); } void UploadJob::startUploading() { - while ( mInput->bytesAvailable() > 0 ) + while ( m_input->bytesAvailable() > 0 ) { - qint64 bytes = qMin(mInput->bytesAvailable(), (qint64)4096); - int w = mSocket->write(mInput->read(bytes)); + qint64 bytes = qMin(m_input->bytesAvailable(), (qint64)4096); + int w = m_socket->write(m_input->read(bytes)); if (w<0) { - qCWarning(KDECONNECT_CORE) << "error when writing data to upload" << bytes << mInput->bytesAvailable(); + qCWarning(KDECONNECT_CORE) << "error when writing data to upload" << bytes << m_input->bytesAvailable(); break; } else { - while ( mSocket->flush() ); + while ( m_socket->flush() ); } } - mInput->close(); + m_input->close(); } void UploadJob::aboutToClose() { // qDebug() << "closing..."; - mSocket->disconnectFromHost(); + m_socket->disconnectFromHost(); } void UploadJob::cleanup() { - mSocket->close(); + m_socket->close(); // qDebug() << "closed!"; emitResult(); } QVariantMap UploadJob::transferInfo() { - Q_ASSERT(mPort != 0); - return {{"port", mPort}}; + Q_ASSERT(m_port != 0); + return {{"port", m_port}}; } void UploadJob::socketFailed(QAbstractSocket::SocketError error) { qWarning() << "error uploading" << error; setError(2); emitResult(); - mSocket->close(); + m_socket->close(); } void UploadJob::sslErrors(const QList& errors) { qWarning() << "ssl errors" << errors; setError(1); emitResult(); - mSocket->close(); + m_socket->close(); } diff --git a/core/backends/lan/uploadjob.h b/core/backends/lan/uploadjob.h index 6724456e..e449e415 100644 --- a/core/backends/lan/uploadjob.h +++ b/core/backends/lan/uploadjob.h @@ -1,63 +1,63 @@ /* * Copyright 2013 Albert Vaca * * 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 UPLOADJOB_H #define UPLOADJOB_H #include #include #include #include #include #include "server.h" class KDECONNECTCORE_EXPORT UploadJob : public KJob { Q_OBJECT public: explicit UploadJob(const QSharedPointer& source, const QString& deviceId); void start() override; QVariantMap transferInfo(); private: - const QSharedPointer mInput; - Server * const mServer; - QSslSocket* mSocket; - quint16 mPort; - const QString mDeviceId; + const QSharedPointer m_input; + Server * const m_server; + QSslSocket* m_socket; + quint16 m_port; + const QString m_deviceId; const static quint16 MIN_PORT = 1739; const static quint16 MAX_PORT = 1764; private Q_SLOTS: void startUploading(); void newConnection(); void aboutToClose(); void cleanup(); void socketFailed(QAbstractSocket::SocketError); - void sslErrors(const QList &errors); + void sslErrors(const QList& errors); }; #endif // UPLOADJOB_H diff --git a/core/backends/pairinghandler.cpp b/core/backends/pairinghandler.cpp index f280742e..04574f93 100644 --- a/core/backends/pairinghandler.cpp +++ b/core/backends/pairinghandler.cpp @@ -1,40 +1,40 @@ /** * Copyright 2015 Albert Vaca Cintora * * 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 "pairinghandler.h" PairingHandler::PairingHandler(DeviceLink* parent) : QObject(parent) , m_deviceLink(parent) { } -void PairingHandler::setDeviceLink(DeviceLink *dl) +void PairingHandler::setDeviceLink(DeviceLink* dl) { setParent(dl); m_deviceLink = dl; } DeviceLink* PairingHandler::deviceLink() const { return m_deviceLink; } diff --git a/core/core_debug.cpp b/core/core_debug.cpp index 24be1fd3..8d1fd92f 100644 --- a/core/core_debug.cpp +++ b/core/core_debug.cpp @@ -1,40 +1,40 @@ /** * Copyright 2013 Albert Vaca * * 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 "core_debug.h" Q_LOGGING_CATEGORY(KDECONNECT_CORE, "kdeconnect.core") #ifdef Q_OS_LINUX #include #include #include #endif void logBacktrace() { #ifdef Q_OS_LINUX - void *array[32]; + void* array[32]; size_t size = backtrace (array, 32); - char **strings = backtrace_symbols (array, size); + char** strings = backtrace_symbols (array, size); backtrace_symbols_fd(array, size, STDERR_FILENO); free (strings); #endif } diff --git a/core/daemon.cpp b/core/daemon.cpp index 01aba12b..6e786afd 100644 --- a/core/daemon.cpp +++ b/core/daemon.cpp @@ -1,287 +1,287 @@ /** * Copyright 2013 Albert Vaca * * 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 "daemon.h" #include #include #include #include #include "core_debug.h" #include "kdeconnectconfig.h" #include "networkpackage.h" #ifdef KDECONNECT_BLUETOOTH #include "backends/bluetooth/bluetoothlinkprovider.h" #endif #include "backends/lan/lanlinkprovider.h" #include "backends/loopback/loopbacklinkprovider.h" #include "device.h" #include "backends/devicelink.h" #include "backends/linkprovider.h" static Daemon* s_instance = nullptr; struct DaemonPrivate { //Different ways to find devices and connect to them - QSet mLinkProviders; + QSet m_linkProviders; //Every known device - QMap mDevices; + QMap m_devices; - QSet mDiscoveryModeAcquisitions; + QSet m_discoveryModeAcquisitions; }; Daemon* Daemon::instance() { Q_ASSERT(s_instance != nullptr); return s_instance; } -Daemon::Daemon(QObject *parent, bool testMode) +Daemon::Daemon(QObject* parent, bool testMode) : QObject(parent) , d(new DaemonPrivate) { Q_ASSERT(!s_instance); s_instance = this; qCDebug(KDECONNECT_CORE) << "KdeConnect daemon starting"; //Load backends if (testMode) - d->mLinkProviders.insert(new LoopbackLinkProvider()); + d->m_linkProviders.insert(new LoopbackLinkProvider()); else { - d->mLinkProviders.insert(new LanLinkProvider()); + d->m_linkProviders.insert(new LanLinkProvider()); #ifdef KDECONNECT_BLUETOOTH d->mLinkProviders.insert(new BluetoothLinkProvider()); #endif } //Read remebered paired devices const QStringList& list = KdeConnectConfig::instance()->trustedDevices(); for (const QString& id : list) { addDevice(new Device(this, id)); } //Listen to new devices - for (LinkProvider* a : qAsConst(d->mLinkProviders)) { + for (LinkProvider* a : qAsConst(d->m_linkProviders)) { connect(a, &LinkProvider::onConnectionReceived, this, &Daemon::onNewDeviceLink); a->onStart(); } //Register on DBus QDBusConnection::sessionBus().registerService(QStringLiteral("org.kde.kdeconnect")); QDBusConnection::sessionBus().registerObject(QStringLiteral("/modules/kdeconnect"), this, QDBusConnection::ExportScriptableContents); qCDebug(KDECONNECT_CORE) << "KdeConnect daemon started"; } -void Daemon::acquireDiscoveryMode(const QString &key) +void Daemon::acquireDiscoveryMode(const QString& key) { - bool oldState = d->mDiscoveryModeAcquisitions.isEmpty(); + bool oldState = d->m_discoveryModeAcquisitions.isEmpty(); - d->mDiscoveryModeAcquisitions.insert(key); + d->m_discoveryModeAcquisitions.insert(key); - if (oldState != d->mDiscoveryModeAcquisitions.isEmpty()) { + if (oldState != d->m_discoveryModeAcquisitions.isEmpty()) { forceOnNetworkChange(); } } -void Daemon::releaseDiscoveryMode(const QString &key) +void Daemon::releaseDiscoveryMode(const QString& key) { - bool oldState = d->mDiscoveryModeAcquisitions.isEmpty(); + bool oldState = d->m_discoveryModeAcquisitions.isEmpty(); - d->mDiscoveryModeAcquisitions.remove(key); + d->m_discoveryModeAcquisitions.remove(key); - if (oldState != d->mDiscoveryModeAcquisitions.isEmpty()) { + if (oldState != d->m_discoveryModeAcquisitions.isEmpty()) { cleanDevices(); } } void Daemon::removeDevice(Device* device) { - d->mDevices.remove(device->id()); + d->m_devices.remove(device->id()); device->deleteLater(); Q_EMIT deviceRemoved(device->id()); } void Daemon::cleanDevices() { - for (Device* device : qAsConst(d->mDevices)) { + for (Device* device : qAsConst(d->m_devices)) { if (device->isTrusted()) { continue; } device->cleanUnneededLinks(); //If there are no links remaining if (!device->isReachable()) { removeDevice(device); } } } void Daemon::forceOnNetworkChange() { - qCDebug(KDECONNECT_CORE) << "Sending onNetworkChange to " << d->mLinkProviders.size() << " LinkProviders"; - for (LinkProvider* a : qAsConst(d->mLinkProviders)) { + qCDebug(KDECONNECT_CORE) << "Sending onNetworkChange to " << d->m_linkProviders.size() << " LinkProviders"; + for (LinkProvider* a : qAsConst(d->m_linkProviders)) { a->onNetworkChange(); } } Device*Daemon::getDevice(const QString& deviceId) { - for (Device* device : qAsConst(d->mDevices)) { + for (Device* device : qAsConst(d->m_devices)) { if (device->id() == deviceId) { return device; } } return Q_NULLPTR; } QStringList Daemon::devices(bool onlyReachable, bool onlyTrusted) const { QStringList ret; - for (Device* device : qAsConst(d->mDevices)) { + for (Device* device : qAsConst(d->m_devices)) { if (onlyReachable && !device->isReachable()) continue; if (onlyTrusted && !device->isTrusted()) continue; ret.append(device->id()); } return ret; } void Daemon::onNewDeviceLink(const NetworkPackage& identityPackage, DeviceLink* dl) { const QString& id = identityPackage.get(QStringLiteral("deviceId")); //qCDebug(KDECONNECT_CORE) << "Device discovered" << id << "via" << dl->provider()->name(); - if (d->mDevices.contains(id)) { + if (d->m_devices.contains(id)) { qCDebug(KDECONNECT_CORE) << "It is a known device" << identityPackage.get(QStringLiteral("deviceName")); - Device* device = d->mDevices[id]; + Device* device = d->m_devices[id]; bool wasReachable = device->isReachable(); device->addLink(identityPackage, dl); if (!wasReachable) { Q_EMIT deviceVisibilityChanged(id, true); } } else { qCDebug(KDECONNECT_CORE) << "It is a new device" << identityPackage.get(QStringLiteral("deviceName")); Device* device = new Device(this, identityPackage, dl); //we discard the connections that we created but it's not paired. if (!isDiscoveringDevices() && !device->isTrusted() && !dl->linkShouldBeKeptAlive()) { device->deleteLater(); } else { addDevice(device); } } } void Daemon::onDeviceStatusChanged() { Device* device = (Device*)sender(); //qCDebug(KDECONNECT_CORE) << "Device" << device->name() << "status changed. Reachable:" << device->isReachable() << ". Paired: " << device->isPaired(); if (!device->isReachable() && !device->isTrusted()) { //qCDebug(KDECONNECT_CORE) << "Destroying device" << device->name(); removeDevice(device); } else { Q_EMIT deviceVisibilityChanged(device->id(), device->isReachable()); } } -void Daemon::setAnnouncedName(const QString &name) +void Daemon::setAnnouncedName(const QString& name) { qCDebug(KDECONNECT_CORE()) << "Announcing name"; KdeConnectConfig::instance()->setName(name); forceOnNetworkChange(); Q_EMIT announcedNameChanged(name); } QString Daemon::announcedName() { return KdeConnectConfig::instance()->name(); } QNetworkAccessManager* Daemon::networkAccessManager() { static QPointer manager; if (!manager) { manager = new QNetworkAccessManager(this); } return manager; } QList Daemon::devicesList() const { - return d->mDevices.values(); + return d->m_devices.values(); } bool Daemon::isDiscoveringDevices() const { - return !d->mDiscoveryModeAcquisitions.isEmpty(); + return !d->m_discoveryModeAcquisitions.isEmpty(); } -QString Daemon::deviceIdByName(const QString &name) const +QString Daemon::deviceIdByName(const QString& name) const { - for (Device* device : qAsConst(d->mDevices)) { + for (Device* device : qAsConst(d->m_devices)) { if (device->name() == name && device->isTrusted()) return device->id(); } return {}; } void Daemon::addDevice(Device* device) { const QString id = device->id(); connect(device, &Device::reachableChanged, this, &Daemon::onDeviceStatusChanged); connect(device, &Device::trustedChanged, this, &Daemon::onDeviceStatusChanged); connect(device, &Device::hasPairingRequestsChanged, this, &Daemon::pairingRequestsChanged); connect(device, &Device::hasPairingRequestsChanged, this, [this, device](bool hasPairingRequests) { if (hasPairingRequests) askPairingConfirmation(device); } ); - d->mDevices[id] = device; + d->m_devices[id] = device; Q_EMIT deviceAdded(id); } QStringList Daemon::pairingRequests() const { QStringList ret; - for(Device* dev: d->mDevices) { + for(Device* dev: d->m_devices) { if (dev->hasPairingRequests()) ret += dev->id(); } return ret; } Daemon::~Daemon() { } QString Daemon::selfId() const { return KdeConnectConfig::instance()->deviceId(); } diff --git a/core/daemon.h b/core/daemon.h index 8682e561..cda42b5f 100644 --- a/core/daemon.h +++ b/core/daemon.h @@ -1,96 +1,96 @@ /** * Copyright 2013 Albert Vaca * * 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 KDECONNECT_DAEMON_H #define KDECONNECT_DAEMON_H #include #include #include #include "kdeconnectcore_export.h" #include "device.h" class NetworkPackage; class DeviceLink; class Device; class QNetworkAccessManager; class KDECONNECTCORE_EXPORT Daemon : public QObject { Q_OBJECT Q_CLASSINFO("D-Bus Interface", "org.kde.kdeconnect.daemon") Q_PROPERTY(bool isDiscoveringDevices READ isDiscoveringDevices) Q_PROPERTY(QStringList pairingRequests READ pairingRequests NOTIFY pairingRequestsChanged) public: - explicit Daemon(QObject *parent, bool testMode = false); + explicit Daemon(QObject* parent, bool testMode = false); ~Daemon() override; static Daemon* instance(); QList devicesList() const; - virtual void askPairingConfirmation(Device *device) = 0; - virtual void reportError(const QString &title, const QString &description) = 0; + virtual void askPairingConfirmation(Device* device) = 0; + virtual void reportError(const QString& title, const QString& description) = 0; virtual QNetworkAccessManager* networkAccessManager(); Device* getDevice(const QString& deviceId); QStringList pairingRequests() const; Q_SCRIPTABLE QString selfId() const; public Q_SLOTS: - Q_SCRIPTABLE void acquireDiscoveryMode(const QString &id); - Q_SCRIPTABLE void releaseDiscoveryMode(const QString &id); + Q_SCRIPTABLE void acquireDiscoveryMode(const QString& id); + Q_SCRIPTABLE void releaseDiscoveryMode(const QString& id); Q_SCRIPTABLE void forceOnNetworkChange(); ///don't try to turn into Q_PROPERTY, it doesn't work Q_SCRIPTABLE QString announcedName(); - Q_SCRIPTABLE void setAnnouncedName(const QString &name); + Q_SCRIPTABLE void setAnnouncedName(const QString& name); //Returns a list of ids. The respective devices can be manipulated using the dbus path: "/modules/kdeconnect/Devices/"+id Q_SCRIPTABLE QStringList devices(bool onlyReachable = false, bool onlyPaired = false) const; - Q_SCRIPTABLE QString deviceIdByName(const QString &name) const; + Q_SCRIPTABLE QString deviceIdByName(const QString& name) const; Q_SIGNALS: Q_SCRIPTABLE void deviceAdded(const QString& id); Q_SCRIPTABLE void deviceRemoved(const QString& id); //Note that paired devices will never be removed Q_SCRIPTABLE void deviceVisibilityChanged(const QString& id, bool isVisible); - Q_SCRIPTABLE void announcedNameChanged(const QString &announcedName); + Q_SCRIPTABLE void announcedNameChanged(const QString& announcedName); Q_SCRIPTABLE void pairingRequestsChanged(); private Q_SLOTS: void onNewDeviceLink(const NetworkPackage& identityPackage, DeviceLink* dl); void onDeviceStatusChanged(); private: void addDevice(Device* device); bool isDiscoveringDevices() const; void removeDevice(Device* d); void cleanDevices(); QScopedPointer d; }; #endif diff --git a/core/device.cpp b/core/device.cpp index 3ad8dcdf..1afb8f1a 100644 --- a/core/device.cpp +++ b/core/device.cpp @@ -1,489 +1,489 @@ /** * Copyright 2013 Albert Vaca * * 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 "device.h" #ifdef interface // MSVC language extension, QDBusConnection uses this as a variable name #undef interface #endif #include #include #include #include #include #include "core_debug.h" #include "kdeconnectplugin.h" #include "pluginloader.h" #include "backends/devicelink.h" #include "backends/lan/landevicelink.h" #include "backends/linkprovider.h" #include "networkpackage.h" #include "kdeconnectconfig.h" #include "daemon.h" -static void warn(const QString &info) +static void warn(const QString& info) { qWarning() << "Device pairing error" << info; } Device::Device(QObject* parent, const QString& id) : QObject(parent) , m_deviceId(id) - , m_protocolVersion(NetworkPackage::ProtocolVersion) //We don't know it yet + , m_protocolVersion(NetworkPackage::s_protocolVersion) //We don't know it yet { KdeConnectConfig::DeviceInfo info = KdeConnectConfig::instance()->getTrustedDevice(id); m_deviceName = info.deviceName; m_deviceType = str2type(info.deviceType); //Register in bus QDBusConnection::sessionBus().registerObject(dbusPath(), this, QDBusConnection::ExportScriptableContents | QDBusConnection::ExportAdaptors); //Assume every plugin is supported until addLink is called and we can get the actual list m_supportedPlugins = PluginLoader::instance()->getPluginList().toSet(); connect(this, &Device::pairingError, this, &warn); } Device::Device(QObject* parent, const NetworkPackage& identityPackage, DeviceLink* dl) : QObject(parent) , m_deviceId(identityPackage.get(QStringLiteral("deviceId"))) , m_deviceName(identityPackage.get(QStringLiteral("deviceName"))) { addLink(identityPackage, dl); //Register in bus QDBusConnection::sessionBus().registerObject(dbusPath(), this, QDBusConnection::ExportScriptableContents | QDBusConnection::ExportAdaptors); connect(this, &Device::pairingError, this, &warn); } Device::~Device() { qDeleteAll(m_deviceLinks); m_deviceLinks.clear(); } bool Device::hasPlugin(const QString& name) const { return m_plugins.contains(name); } QStringList Device::loadedPlugins() const { return m_plugins.keys(); } void Device::reloadPlugins() { QHash newPluginMap, oldPluginMap = m_plugins; QMultiMap newPluginsByIncomingCapability; if (isTrusted() && isReachable()) { //Do not load any plugin for unpaired devices, nor useless loading them for unreachable devices PluginLoader* loader = PluginLoader::instance(); for (const QString& pluginName : qAsConst(m_supportedPlugins)) { const KPluginMetaData service = loader->getPluginInfo(pluginName); const bool pluginEnabled = isPluginEnabled(pluginName); const QSet incomingCapabilities = KPluginMetaData::readStringList(service.rawData(), QStringLiteral("X-KdeConnect-SupportedPackageType")).toSet(); if (pluginEnabled) { KdeConnectPlugin* plugin = m_plugins.take(pluginName); if (!plugin) { plugin = loader->instantiatePluginForDevice(pluginName, this); } Q_ASSERT(plugin); for (const QString& interface : incomingCapabilities) { newPluginsByIncomingCapability.insert(interface, plugin); } newPluginMap[pluginName] = plugin; } } } const bool differentPlugins = oldPluginMap != newPluginMap; //Erase all left plugins in the original map (meaning that we don't want //them anymore, otherwise they would have been moved to the newPluginMap) qDeleteAll(m_plugins); m_plugins = newPluginMap; m_pluginsByIncomingCapability = newPluginsByIncomingCapability; QDBusConnection bus = QDBusConnection::sessionBus(); for (KdeConnectPlugin* plugin : qAsConst(m_plugins)) { //TODO: see how it works in Android (only done once, when created) plugin->connected(); const QString dbusPath = plugin->dbusPath(); if (!dbusPath.isEmpty()) { bus.registerObject(dbusPath, plugin, QDBusConnection::ExportAllProperties | QDBusConnection::ExportScriptableInvokables | QDBusConnection::ExportScriptableSignals | QDBusConnection::ExportScriptableSlots); } } if (differentPlugins) { Q_EMIT pluginsChanged(); } } QString Device::pluginsConfigFile() const { return KdeConnectConfig::instance()->deviceConfigDir(id()).absoluteFilePath(QStringLiteral("config")); } void Device::requestPair() { if (isTrusted()) { Q_EMIT pairingError(i18n("Already paired")); return; } if (!isReachable()) { Q_EMIT pairingError(i18n("Device not reachable")); return; } for (DeviceLink* dl : qAsConst(m_deviceLinks)) { dl->userRequestsPair(); } } void Device::unpair() { for (DeviceLink* dl : qAsConst(m_deviceLinks)) { dl->userRequestsUnpair(); } KdeConnectConfig::instance()->removeTrustedDevice(id()); Q_EMIT trustedChanged(false); } void Device::pairStatusChanged(DeviceLink::PairStatus status) { if (status == DeviceLink::NotPaired) { KdeConnectConfig::instance()->removeTrustedDevice(id()); for (DeviceLink* dl : qAsConst(m_deviceLinks)) { if (dl != sender()) { dl->setPairStatus(DeviceLink::NotPaired); } } } else { KdeConnectConfig::instance()->addTrustedDevice(id(), name(), type()); } reloadPlugins(); //Will load/unload plugins bool isTrusted = (status == DeviceLink::Paired); Q_EMIT trustedChanged(isTrusted); Q_ASSERT(isTrusted == this->isTrusted()); } static bool lessThan(DeviceLink* p1, DeviceLink* p2) { return p1->provider()->priority() > p2->provider()->priority(); } void Device::addLink(const NetworkPackage& identityPackage, DeviceLink* link) { //qCDebug(KDECONNECT_CORE) << "Adding link to" << id() << "via" << link->provider(); Q_ASSERT(!m_deviceLinks.contains(link)); m_protocolVersion = identityPackage.get(QStringLiteral("protocolVersion"), -1); - if (m_protocolVersion != NetworkPackage::ProtocolVersion) { - qCWarning(KDECONNECT_CORE) << m_deviceName << "- warning, device uses a different protocol version" << m_protocolVersion << "expected" << NetworkPackage::ProtocolVersion; + if (m_protocolVersion != NetworkPackage::s_protocolVersion) { + qCWarning(KDECONNECT_CORE) << m_deviceName << "- warning, device uses a different protocol version" << m_protocolVersion << "expected" << NetworkPackage::s_protocolVersion; } connect(link, &QObject::destroyed, this, &Device::linkDestroyed); m_deviceLinks.append(link); //re-read the device name from the identityPackage because it could have changed setName(identityPackage.get(QStringLiteral("deviceName"))); m_deviceType = str2type(identityPackage.get(QStringLiteral("deviceType"))); //Theoretically we will never add two links from the same provider (the provider should destroy //the old one before this is called), so we do not have to worry about destroying old links. //-- Actually, we should not destroy them or the provider will store an invalid ref! connect(link, &DeviceLink::receivedPackage, this, &Device::privateReceivedPackage); qSort(m_deviceLinks.begin(), m_deviceLinks.end(), lessThan); const bool capabilitiesSupported = identityPackage.has(QStringLiteral("incomingCapabilities")) || identityPackage.has(QStringLiteral("outgoingCapabilities")); if (capabilitiesSupported) { const QSet outgoingCapabilities = identityPackage.get(QStringLiteral("outgoingCapabilities")).toSet() , incomingCapabilities = identityPackage.get(QStringLiteral("incomingCapabilities")).toSet(); m_supportedPlugins = PluginLoader::instance()->pluginsForCapabilities(incomingCapabilities, outgoingCapabilities); //qDebug() << "new plugins for" << m_deviceName << m_supportedPlugins << incomingCapabilities << outgoingCapabilities; } else { m_supportedPlugins = PluginLoader::instance()->getPluginList().toSet(); } reloadPlugins(); if (m_deviceLinks.size() == 1) { Q_EMIT reachableChanged(true); } connect(link, &DeviceLink::pairStatusChanged, this, &Device::pairStatusChanged); connect(link, &DeviceLink::pairingRequest, this, &Device::addPairingRequest); connect(link, &DeviceLink::pairingRequestExpired, this, &Device::removePairingRequest); connect(link, &DeviceLink::pairingError, this, &Device::pairingError); } void Device::addPairingRequest(PairingHandler* handler) { const bool wasEmpty = m_pairRequests.isEmpty(); m_pairRequests.insert(handler); if (wasEmpty != m_pairRequests.isEmpty()) Q_EMIT hasPairingRequestsChanged(!m_pairRequests.isEmpty()); } void Device::removePairingRequest(PairingHandler* handler) { const bool wasEmpty = m_pairRequests.isEmpty(); m_pairRequests.remove(handler); if (wasEmpty != m_pairRequests.isEmpty()) Q_EMIT hasPairingRequestsChanged(!m_pairRequests.isEmpty()); } bool Device::hasPairingRequests() const { return !m_pairRequests.isEmpty(); } void Device::acceptPairing() { if (m_pairRequests.isEmpty()) qWarning() << "no pair requests to accept!"; //copying because the pairing handler will be removed upon accept const auto prCopy = m_pairRequests; for (auto ph: prCopy) ph->acceptPairing(); } void Device::rejectPairing() { if (m_pairRequests.isEmpty()) qWarning() << "no pair requests to reject!"; //copying because the pairing handler will be removed upon reject const auto prCopy = m_pairRequests; for (auto ph: prCopy) ph->rejectPairing(); } void Device::linkDestroyed(QObject* o) { removeLink(static_cast(o)); } void Device::removeLink(DeviceLink* link) { m_deviceLinks.removeAll(link); //qCDebug(KDECONNECT_CORE) << "RemoveLink" << m_deviceLinks.size() << "links remaining"; if (m_deviceLinks.isEmpty()) { reloadPlugins(); Q_EMIT reachableChanged(false); } } bool Device::sendPackage(NetworkPackage& np) { Q_ASSERT(np.type() != PACKAGE_TYPE_PAIR); Q_ASSERT(isTrusted()); //Maybe we could block here any package that is not an identity or a pairing package to prevent sending non encrypted data for (DeviceLink* dl : qAsConst(m_deviceLinks)) { if (dl->sendPackage(np)) return true; } return false; } void Device::privateReceivedPackage(const NetworkPackage& np) { Q_ASSERT(np.type() != PACKAGE_TYPE_PAIR); if (isTrusted()) { const QList plugins = m_pluginsByIncomingCapability.values(np.type()); if (plugins.isEmpty()) { qWarning() << "discarding unsupported package" << np.type() << "for" << name(); } for (KdeConnectPlugin* plugin : plugins) { plugin->receivePackage(np); } } else { qCDebug(KDECONNECT_CORE) << "device" << name() << "not paired, ignoring package" << np.type(); unpair(); } } bool Device::isTrusted() const { return KdeConnectConfig::instance()->trustedDevices().contains(id()); } QStringList Device::availableLinks() const { QStringList sl; sl.reserve(m_deviceLinks.size()); for (DeviceLink* dl : qAsConst(m_deviceLinks)) { sl.append(dl->provider()->name()); } return sl; } void Device::cleanUnneededLinks() { if (isTrusted()) { return; } for(int i = 0; i < m_deviceLinks.size(); ) { DeviceLink* dl = m_deviceLinks[i]; if (!dl->linkShouldBeKeptAlive()) { dl->deleteLater(); m_deviceLinks.remove(i); } else { i++; } } } QHostAddress Device::getLocalIpAddress() const { for (DeviceLink* dl : m_deviceLinks) { LanDeviceLink* ldl = dynamic_cast(dl); if (ldl) { return ldl->hostAddress(); } } return QHostAddress::Null; } -Device::DeviceType Device::str2type(const QString &deviceType) { +Device::DeviceType Device::str2type(const QString& deviceType) { if (deviceType == QLatin1String("desktop")) return Desktop; if (deviceType == QLatin1String("laptop")) return Laptop; if (deviceType == QLatin1String("smartphone") || deviceType == QLatin1String("phone")) return Phone; if (deviceType == QLatin1String("tablet")) return Tablet; return Unknown; } QString Device::type2str(Device::DeviceType deviceType) { if (deviceType == Desktop) return QStringLiteral("desktop"); if (deviceType == Laptop) return QStringLiteral("laptop"); if (deviceType == Phone) return QStringLiteral("smartphone"); if (deviceType == Tablet) return QStringLiteral("tablet"); return QStringLiteral("unknown"); } QString Device::statusIconName() const { return iconForStatus(isReachable(), isTrusted()); } QString Device::iconName() const { return iconForStatus(true, false); } QString Device::iconForStatus(bool reachable, bool trusted) const { Device::DeviceType deviceType = m_deviceType; if (deviceType == Device::Unknown) { deviceType = Device::Phone; //Assume phone if we don't know the type } else if (deviceType == Device::Desktop) { deviceType = Device::Device::Laptop; // We don't have desktop icon yet } QString status = (reachable? (trusted? QStringLiteral("connected") : QStringLiteral("disconnected")) : QStringLiteral("trusted")); QString type = type2str(deviceType); return type+status; } -void Device::setName(const QString &name) +void Device::setName(const QString& name) { if (m_deviceName != name) { m_deviceName = name; Q_EMIT nameChanged(name); } } KdeConnectPlugin* Device::plugin(const QString& pluginName) const { return m_plugins[pluginName]; } void Device::setPluginEnabled(const QString& pluginName, bool enabled) { KConfigGroup pluginStates = KSharedConfig::openConfig(pluginsConfigFile())->group("Plugins"); const QString enabledKey = pluginName + QStringLiteral("Enabled"); pluginStates.writeEntry(enabledKey, enabled); reloadPlugins(); } bool Device::isPluginEnabled(const QString& pluginName) const { const QString enabledKey = pluginName + QStringLiteral("Enabled"); KConfigGroup pluginStates = KSharedConfig::openConfig(pluginsConfigFile())->group("Plugins"); return (pluginStates.hasKey(enabledKey) ? pluginStates.readEntry(enabledKey, false) : PluginLoader::instance()->getPluginInfo(pluginName).isEnabledByDefault()); } QString Device::encryptionInfo() const { QString result; QCryptographicHash::Algorithm digestAlgorithm = QCryptographicHash::Algorithm::Sha1; QString localSha1 = QString::fromLatin1(KdeConnectConfig::instance()->certificate().digest(digestAlgorithm).toHex()); for (int i = 2; igetDeviceProperty(id(), QStringLiteral("certificate")).toStdString(); QSslCertificate remoteCertificate = QSslCertificate(QByteArray(remotePem.c_str(), (int)remotePem.size())); QString remoteSha1 = QString::fromLatin1(remoteCertificate.digest(digestAlgorithm).toHex()); for (int i = 2; i < remoteSha1.size(); i += 3) { remoteSha1.insert(i, ':'); // Improve readability } result += i18n("SHA1 fingerprint of remote device certificate is: %1\n", remoteSha1); return result; } diff --git a/core/device.h b/core/device.h index 326adf86..8cde9440 100644 --- a/core/device.h +++ b/core/device.h @@ -1,164 +1,164 @@ /** * Copyright 2013 Albert Vaca * * 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 DEVICE_H #define DEVICE_H #include #include #include #include #include #include "networkpackage.h" #include "backends/devicelink.h" class DeviceLink; class KdeConnectPlugin; class KDECONNECTCORE_EXPORT Device : public QObject { Q_OBJECT Q_CLASSINFO("D-Bus Interface", "org.kde.kdeconnect.device") Q_PROPERTY(QString type READ type CONSTANT) Q_PROPERTY(QString name READ name NOTIFY nameChanged) Q_PROPERTY(QString iconName READ iconName CONSTANT) Q_PROPERTY(QString statusIconName READ statusIconName) Q_PROPERTY(bool isReachable READ isReachable NOTIFY reachableChanged) Q_PROPERTY(bool isTrusted READ isTrusted NOTIFY trustedChanged) Q_PROPERTY(QStringList supportedPlugins READ supportedPlugins NOTIFY pluginsChanged) Q_PROPERTY(bool hasPairingRequests READ hasPairingRequests NOTIFY hasPairingRequestsChanged) public: enum DeviceType { Unknown, Desktop, Laptop, Phone, Tablet, }; /** * Restores the @p device from the saved configuration * * We already know it but we need to wait for an incoming DeviceLink to communicate */ Device(QObject* parent, const QString& id); /** * Device known via an incoming connection sent to us via a devicelink. * * We know everything but we don't trust it yet */ Device(QObject* parent, const NetworkPackage& np, DeviceLink* dl); ~Device() override; QString id() const { return m_deviceId; } QString name() const { return m_deviceName; } QString dbusPath() const { return "/modules/kdeconnect/devices/"+id(); } QString type() const { return type2str(m_deviceType); } QString iconName() const; QString statusIconName() const; Q_SCRIPTABLE QString encryptionInfo() const; //Add and remove links void addLink(const NetworkPackage& identityPackage, DeviceLink*); void removeLink(DeviceLink*); Q_SCRIPTABLE bool isTrusted() const; Q_SCRIPTABLE QStringList availableLinks() const; bool isReachable() const { return !m_deviceLinks.isEmpty(); } Q_SCRIPTABLE QStringList loadedPlugins() const; Q_SCRIPTABLE bool hasPlugin(const QString& name) const; Q_SCRIPTABLE QString pluginsConfigFile() const; KdeConnectPlugin* plugin(const QString& pluginName) const; void setPluginEnabled(const QString& pluginName, bool enabled); bool isPluginEnabled(const QString& pluginName) const; void cleanUnneededLinks(); int protocolVersion() { return m_protocolVersion; } QStringList supportedPlugins() const { return m_supportedPlugins.toList(); } QHostAddress getLocalIpAddress() const; public Q_SLOTS: ///sends a @p np package to the device ///virtual for testing purposes. virtual bool sendPackage(NetworkPackage& np); //Dbus operations public Q_SLOTS: Q_SCRIPTABLE void requestPair(); //to all links Q_SCRIPTABLE void unpair(); //from all links Q_SCRIPTABLE void reloadPlugins(); //from kconf Q_SCRIPTABLE void acceptPairing(); Q_SCRIPTABLE void rejectPairing(); Q_SCRIPTABLE bool hasPairingRequests() const; private Q_SLOTS: void privateReceivedPackage(const NetworkPackage& np); void linkDestroyed(QObject* o); void pairStatusChanged(DeviceLink::PairStatus current); void addPairingRequest(PairingHandler* handler); void removePairingRequest(PairingHandler* handler); Q_SIGNALS: Q_SCRIPTABLE void pluginsChanged(); Q_SCRIPTABLE void reachableChanged(bool reachable); Q_SCRIPTABLE void trustedChanged(bool trusted); Q_SCRIPTABLE void pairingError(const QString& error); Q_SCRIPTABLE void nameChanged(const QString& name); Q_SCRIPTABLE void hasPairingRequestsChanged(bool hasPairingRequests); private: //Methods - static DeviceType str2type(const QString &deviceType); + static DeviceType str2type(const QString& deviceType); static QString type2str(DeviceType deviceType); - void setName(const QString &name); + void setName(const QString& name); QString iconForStatus(bool reachable, bool paired) const; private: //Fields (TODO: dPointer!) const QString m_deviceId; QString m_deviceName; DeviceType m_deviceType; int m_protocolVersion; QVector m_deviceLinks; QHash m_plugins; //Capabilities stuff QMultiMap m_pluginsByIncomingCapability; QSet m_supportedPlugins; QSet m_pairRequests; }; Q_DECLARE_METATYPE(Device*) #endif // DEVICE_H diff --git a/core/filetransferjob.cpp b/core/filetransferjob.cpp index 8bb9e7ed..0602737b 100644 --- a/core/filetransferjob.cpp +++ b/core/filetransferjob.cpp @@ -1,132 +1,132 @@ /* * Copyright 2013 Albert Vaca * Copyright 2015 Aleix Pol i 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 "filetransferjob.h" #include "daemon.h" #include #include #include #include #include FileTransferJob::FileTransferJob(const QSharedPointer& origin, qint64 size, const QUrl& destination) : KJob() - , mOrigin(origin) - , mReply(Q_NULLPTR) - , mFrom(QStringLiteral("KDE Connect")) - , mDestination(destination) - , mSpeedBytes(0) - , mWritten(0) + , m_origin(origin) + , m_reply(Q_NULLPTR) + , m_from(QStringLiteral("KDE Connect")) + , m_destination(destination) + , m_speedBytes(0) + , m_written(0) { - Q_ASSERT(mOrigin); - Q_ASSERT(mOrigin->isReadable()); - if (mDestination.scheme().isEmpty()) { - qCWarning(KDECONNECT_CORE) << "Destination QUrl" << mDestination << "lacks a scheme. Setting its scheme to 'file'."; - mDestination.setScheme(QStringLiteral("file")); + Q_ASSERT(m_origin); + Q_ASSERT(m_origin->isReadable()); + if (m_destination.scheme().isEmpty()) { + qCWarning(KDECONNECT_CORE) << "Destination QUrl" << m_destination << "lacks a scheme. Setting its scheme to 'file'."; + m_destination.setScheme(QStringLiteral("file")); } if (size >= 0) { setTotalAmount(Bytes, size); } setCapabilities(Killable); qCDebug(KDECONNECT_CORE) << "FileTransferJob Downloading payload to" << destination; } void FileTransferJob::start() { QMetaObject::invokeMethod(this, "doStart", Qt::QueuedConnection); //qCDebug(KDECONNECT_CORE) << "FileTransferJob start"; } void FileTransferJob::doStart() { description(this, i18n("Receiving file over KDE Connect"), - { i18nc("File transfer origin", "From"), mFrom } + { i18nc("File transfer origin", "From"), m_from } ); - if (mDestination.isLocalFile() && QFile::exists(mDestination.toLocalFile())) { + if (m_destination.isLocalFile() && QFile::exists(m_destination.toLocalFile())) { setError(2); setErrorText(i18n("Filename already present")); emitResult(); return; } - if (mOrigin->bytesAvailable()) + if (m_origin->bytesAvailable()) startTransfer(); - connect(mOrigin.data(), &QIODevice::readyRead, this, &FileTransferJob::startTransfer); + connect(m_origin.data(), &QIODevice::readyRead, this, &FileTransferJob::startTransfer); } void FileTransferJob::startTransfer() { setProcessedAmount(Bytes, 0); - mTimer.start(); + m_timer.start(); description(this, i18n("Receiving file over KDE Connect"), - { i18nc("File transfer origin", "From"), mFrom }, - { i18nc("File transfer destination", "To"), mDestination.toLocalFile() }); + { i18nc("File transfer origin", "From"), m_from }, + { i18nc("File transfer destination", "To"), m_destination.toLocalFile() }); - QNetworkRequest req(mDestination); + QNetworkRequest req(m_destination); req.setHeader(QNetworkRequest::ContentLengthHeader, totalAmount(Bytes)); - mReply = Daemon::instance()->networkAccessManager()->put(req, mOrigin.data()); + m_reply = Daemon::instance()->networkAccessManager()->put(req, m_origin.data()); - connect(mReply, &QNetworkReply::uploadProgress, this, [this](qint64 bytesSent, qint64 /*bytesTotal*/) { + connect(m_reply, &QNetworkReply::uploadProgress, this, [this](qint64 bytesSent, qint64 /*bytesTotal*/) { setProcessedAmount(Bytes, bytesSent); - const auto elapsed = mTimer.elapsed(); + const auto elapsed = m_timer.elapsed(); if (elapsed > 0) { emitSpeed(bytesSent / elapsed); } }); - connect(mReply, static_cast(&QNetworkReply::error), + connect(m_reply, static_cast(&QNetworkReply::error), this, &FileTransferJob::transferFailed); - connect(mReply, &QNetworkReply::finished, this, &FileTransferJob::transferFinished); + connect(m_reply, &QNetworkReply::finished, this, &FileTransferJob::transferFinished); } void FileTransferJob::transferFailed(QNetworkReply::NetworkError error) { - qCDebug(KDECONNECT_CORE) << "Couldn't transfer the file successfully" << error << mReply->errorString(); + qCDebug(KDECONNECT_CORE) << "Couldn't transfer the file successfully" << error << m_reply->errorString(); setError(error); - setErrorText(i18n("Received incomplete file: %1", mReply->errorString())); + setErrorText(i18n("Received incomplete file: %1", m_reply->errorString())); emitResult(); - mReply->close(); + m_reply->close(); } void FileTransferJob::transferFinished() { //TODO: MD5-check the file - qCDebug(KDECONNECT_CORE) << "Finished transfer" << mDestination; + qCDebug(KDECONNECT_CORE) << "Finished transfer" << m_destination; emitResult(); } bool FileTransferJob::doKill() { - if (mReply) { - mReply->close(); + if (m_reply) { + m_reply->close(); } - if (mOrigin) { - mOrigin->close(); + if (m_origin) { + m_origin->close(); } return true; } diff --git a/core/filetransferjob.h b/core/filetransferjob.h index a94b38c0..83575a01 100644 --- a/core/filetransferjob.h +++ b/core/filetransferjob.h @@ -1,77 +1,77 @@ /* * Copyright 2013 Albert Vaca * Copyright 2015 Aleix Pol i 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 FILETRANSFERJOB_H #define FILETRANSFERJOB_H #include #include #include #include #include #include #include "kdeconnectcore_export.h" /** * @short It will stream a device into a url destination * * Given a QIODevice, the file transfer job will use the system's QNetworkAccessManager * for putting the stream into the requested location. */ class KDECONNECTCORE_EXPORT FileTransferJob : public KJob { Q_OBJECT public: /** * @p origin specifies the data to read from. * @p size specifies the expected size of the stream we're reading. * @p destination specifies where these contents should be stored */ - FileTransferJob(const QSharedPointer& origin, qint64 size, const QUrl &destination); + FileTransferJob(const QSharedPointer& origin, qint64 size, const QUrl& destination); void start() override; - QUrl destination() const { return mDestination; } - void setOriginName(const QString& from) { mFrom = from; } + QUrl destination() const { return m_destination; } + void setOriginName(const QString& from) { m_from = from; } private Q_SLOTS: void doStart(); protected: bool doKill() override; private: void startTransfer(); void transferFailed(QNetworkReply::NetworkError error); void transferFinished(); - QSharedPointer mOrigin; - QNetworkReply* mReply; - QString mFrom; - QUrl mDestination; - QElapsedTimer mTimer; - qulonglong mSpeedBytes; - qint64 mWritten; + QSharedPointer m_origin; + QNetworkReply* m_reply; + QString m_from; + QUrl m_destination; + QElapsedTimer m_timer; + qulonglong m_speedBytes; + qint64 m_written; }; #endif diff --git a/core/kdeconnectconfig.cpp b/core/kdeconnectconfig.cpp index fdee69f1..e8e94581 100644 --- a/core/kdeconnectconfig.cpp +++ b/core/kdeconnectconfig.cpp @@ -1,273 +1,273 @@ /** * Copyright 2015 Albert Vaca * * 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 "kdeconnectconfig.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include "core_debug.h" #include "dbushelper.h" #include "daemon.h" struct KdeConnectConfigPrivate { // The Initializer object sets things up, and also does cleanup when it goes out of scope // Note it's not being used anywhere. That's intended - QCA::Initializer mQcaInitializer; + QCA::Initializer m_qcaInitializer; - QCA::PrivateKey privateKey; - QSslCertificate certificate; // Use QSslCertificate instead of QCA::Certificate due to compatibility with QSslSocket + QCA::PrivateKey m_privateKey; + QSslCertificate m_certificate; // Use QSslCertificate instead of QCA::Certificate due to compatibility with QSslSocket - QSettings* config; - QSettings* trusted_devices; + QSettings* m_config; + QSettings* m_trustedDevices; }; KdeConnectConfig* KdeConnectConfig::instance() { static KdeConnectConfig* kcc = new KdeConnectConfig(); return kcc; } KdeConnectConfig::KdeConnectConfig() : d(new KdeConnectConfigPrivate) { //qCDebug(KDECONNECT_CORE) << "QCA supported capabilities:" << QCA::supportedFeatures().join(","); if(!QCA::isSupported("rsa")) { qCritical() << "Could not find support for RSA in your QCA installation"; Daemon::instance()->reportError( i18n("KDE Connect failed to start"), i18n("Could not find support for RSA in your QCA installation. If your " "distribution provides separate packages for QCA-ossl and QCA-gnupg, " "make sure you have them installed and try again.")); return; } //Make sure base directory exists QDir().mkpath(baseConfigDir().path()); //.config/kdeconnect/config - d->config = new QSettings(baseConfigDir().absoluteFilePath(QStringLiteral("config")), QSettings::IniFormat); - d->trusted_devices = new QSettings(baseConfigDir().absoluteFilePath(QStringLiteral("trusted_devices")), QSettings::IniFormat); + d->m_config = new QSettings(baseConfigDir().absoluteFilePath(QStringLiteral("config")), QSettings::IniFormat); + d->m_trustedDevices = new QSettings(baseConfigDir().absoluteFilePath(QStringLiteral("trusted_devices")), QSettings::IniFormat); const QFile::Permissions strict = QFile::ReadOwner | QFile::WriteOwner | QFile::ReadUser | QFile::WriteUser; QString keyPath = privateKeyPath(); QFile privKey(keyPath); if (privKey.exists() && privKey.open(QIODevice::ReadOnly)) { - d->privateKey = QCA::PrivateKey::fromPEM(privKey.readAll()); + d->m_privateKey = QCA::PrivateKey::fromPEM(privKey.readAll()); } else { - d->privateKey = QCA::KeyGenerator().createRSA(2048); + d->m_privateKey = QCA::KeyGenerator().createRSA(2048); if (!privKey.open(QIODevice::ReadWrite | QIODevice::Truncate)) { Daemon::instance()->reportError(QStringLiteral("KDE Connect"), i18n("Could not store private key file: %1", keyPath)); } else { privKey.setPermissions(strict); - privKey.write(d->privateKey.toPEM().toLatin1()); + privKey.write(d->m_privateKey.toPEM().toLatin1()); } } QString certPath = certificatePath(); QFile cert(certPath); if (cert.exists() && cert.open(QIODevice::ReadOnly)) { - d->certificate = QSslCertificate::fromPath(certPath).at(0); + d->m_certificate = QSslCertificate::fromPath(certPath).at(0); } else { // No certificate yet. Probably first run. Let's generate one! QString uuid = QUuid::createUuid().toString(); DbusHelper::filterNonExportableCharacters(uuid); qCDebug(KDECONNECT_CORE) << "My id:" << uuid; // FIXME: We only use QCA here to generate the cert and key, would be nice to get rid of it completely. // The same thing we are doing with QCA could be done invoking openssl (altought it's potentially less portable): // openssl req -new -x509 -sha256 -newkey rsa:2048 -nodes -keyout privateKey.pem -days 3650 -out certificate.pem -subj "/O=KDE/OU=KDE Connect/CN=_e6e29ad4_2b31_4b6d_8f7a_9872dbaa9095_" QCA::CertificateOptions certificateOptions = QCA::CertificateOptions(); QDateTime startTime = QDateTime::currentDateTime().addYears(-1); QDateTime endTime = startTime.addYears(10); QCA::CertificateInfo certificateInfo; certificateInfo.insert(QCA::CommonName, uuid); certificateInfo.insert(QCA::Organization,QStringLiteral("KDE")); certificateInfo.insert(QCA::OrganizationalUnit,QStringLiteral("Kde connect")); certificateOptions.setInfo(certificateInfo); certificateOptions.setFormat(QCA::PKCS10); certificateOptions.setSerialNumber(QCA::BigInteger(10)); certificateOptions.setValidityPeriod(startTime, endTime); - d->certificate = QSslCertificate(QCA::Certificate(certificateOptions, d->privateKey).toPEM().toLatin1()); + d->m_certificate = QSslCertificate(QCA::Certificate(certificateOptions, d->m_privateKey).toPEM().toLatin1()); if (!cert.open(QIODevice::ReadWrite | QIODevice::Truncate)) { Daemon::instance()->reportError(QStringLiteral("KDE Connect"), i18n("Could not store certificate file: %1", certPath)); } else { cert.setPermissions(strict); - cert.write(d->certificate.toPem()); + cert.write(d->m_certificate.toPem()); } } //Extra security check if (QFile::permissions(keyPath) != strict) { qCWarning(KDECONNECT_CORE) << "Warning: KDE Connect private key file has too open permissions " << keyPath; } } QString KdeConnectConfig::name() { QString defaultName = qgetenv("USER") + '@' + QHostInfo::localHostName(); - QString name = d->config->value(QStringLiteral("name"), defaultName).toString(); + QString name = d->m_config->value(QStringLiteral("name"), defaultName).toString(); return name; } void KdeConnectConfig::setName(const QString& name) { - d->config->setValue(QStringLiteral("name"), name); - d->config->sync(); + d->m_config->setValue(QStringLiteral("name"), name); + d->m_config->sync(); } QString KdeConnectConfig::deviceType() { return QStringLiteral("desktop"); // TODO } QString KdeConnectConfig::deviceId() { - return d->certificate.subjectInfo( QSslCertificate::CommonName ).constFirst(); + return d->m_certificate.subjectInfo( QSslCertificate::CommonName ).constFirst(); } QString KdeConnectConfig::privateKeyPath() { return baseConfigDir().absoluteFilePath(QStringLiteral("privateKey.pem")); } QCA::PrivateKey KdeConnectConfig::privateKey() { - return d->privateKey; + return d->m_privateKey; } QCA::PublicKey KdeConnectConfig::publicKey() { - return d->privateKey.toPublicKey(); + return d->m_privateKey.toPublicKey(); } QString KdeConnectConfig::certificatePath() { return baseConfigDir().absoluteFilePath(QStringLiteral("certificate.pem")); } QSslCertificate KdeConnectConfig::certificate() { - return d->certificate; + return d->m_certificate; } QDir KdeConnectConfig::baseConfigDir() { QString configPath = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation); QString kdeconnectConfigPath = QDir(configPath).absoluteFilePath(QStringLiteral("kdeconnect")); return QDir(kdeconnectConfigPath); } QStringList KdeConnectConfig::trustedDevices() { - const QStringList& list = d->trusted_devices->childGroups(); + const QStringList& list = d->m_trustedDevices->childGroups(); return list; } -void KdeConnectConfig::addTrustedDevice(const QString &id, const QString &name, const QString &type) +void KdeConnectConfig::addTrustedDevice(const QString& id, const QString& name, const QString& type) { - d->trusted_devices->beginGroup(id); - d->trusted_devices->setValue(QStringLiteral("name"), name); - d->trusted_devices->setValue(QStringLiteral("type"), type); - d->trusted_devices->endGroup(); - d->trusted_devices->sync(); + d->m_trustedDevices->beginGroup(id); + d->m_trustedDevices->setValue(QStringLiteral("name"), name); + d->m_trustedDevices->setValue(QStringLiteral("type"), type); + d->m_trustedDevices->endGroup(); + d->m_trustedDevices->sync(); QDir().mkpath(deviceConfigDir(id).path()); } -KdeConnectConfig::DeviceInfo KdeConnectConfig::getTrustedDevice(const QString &id) +KdeConnectConfig::DeviceInfo KdeConnectConfig::getTrustedDevice(const QString& id) { - d->trusted_devices->beginGroup(id); + d->m_trustedDevices->beginGroup(id); KdeConnectConfig::DeviceInfo info; - info.deviceName = d->trusted_devices->value(QStringLiteral("name"), QLatin1String("unnamed")).toString(); - info.deviceType = d->trusted_devices->value(QStringLiteral("type"), QLatin1String("unknown")).toString(); + info.deviceName = d->m_trustedDevices->value(QStringLiteral("name"), QLatin1String("unnamed")).toString(); + info.deviceType = d->m_trustedDevices->value(QStringLiteral("type"), QLatin1String("unknown")).toString(); - d->trusted_devices->endGroup(); + d->m_trustedDevices->endGroup(); return info; } -void KdeConnectConfig::removeTrustedDevice(const QString &deviceId) +void KdeConnectConfig::removeTrustedDevice(const QString& deviceId) { - d->trusted_devices->remove(deviceId); - d->trusted_devices->sync(); + d->m_trustedDevices->remove(deviceId); + d->m_trustedDevices->sync(); //We do not remove the config files. } // Utility functions to set and get a value void KdeConnectConfig::setDeviceProperty(const QString& deviceId, const QString& key, const QString& value) { - d->trusted_devices->beginGroup(deviceId); - d->trusted_devices->setValue(key, value); - d->trusted_devices->endGroup(); - d->trusted_devices->sync(); + d->m_trustedDevices->beginGroup(deviceId); + d->m_trustedDevices->setValue(key, value); + d->m_trustedDevices->endGroup(); + d->m_trustedDevices->sync(); } QString KdeConnectConfig::getDeviceProperty(const QString& deviceId, const QString& key, const QString& defaultValue) { QString value; - d->trusted_devices->beginGroup(deviceId); - value = d->trusted_devices->value(key, defaultValue).toString(); - d->trusted_devices->endGroup(); + d->m_trustedDevices->beginGroup(deviceId); + value = d->m_trustedDevices->value(key, defaultValue).toString(); + d->m_trustedDevices->endGroup(); return value; } -QDir KdeConnectConfig::deviceConfigDir(const QString &deviceId) +QDir KdeConnectConfig::deviceConfigDir(const QString& deviceId) { QString deviceConfigPath = baseConfigDir().absoluteFilePath(deviceId); return QDir(deviceConfigPath); } -QDir KdeConnectConfig::pluginConfigDir(const QString &deviceId, const QString &pluginName) +QDir KdeConnectConfig::pluginConfigDir(const QString& deviceId, const QString& pluginName) { QString deviceConfigPath = baseConfigDir().absoluteFilePath(deviceId); QString pluginConfigDir = QDir(deviceConfigPath).absoluteFilePath(pluginName); return QDir(pluginConfigDir); } diff --git a/core/kdeconnectconfig.h b/core/kdeconnectconfig.h index 8ed4c1bc..35609f7d 100644 --- a/core/kdeconnectconfig.h +++ b/core/kdeconnectconfig.h @@ -1,88 +1,88 @@ /** * Copyright 2015 Albert Vaca * * 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 KDECONNECTCONFIG_H #define KDECONNECTCONFIG_H #include #include "kdeconnectcore_export.h" class QSslCertificate; namespace QCA { class PrivateKey; class PublicKey; } class KDECONNECTCORE_EXPORT KdeConnectConfig { public: struct DeviceInfo { QString deviceName; QString deviceType; }; static KdeConnectConfig* instance(); /* * Our own info */ QString deviceId(); QString name(); QString deviceType(); QString privateKeyPath(); QCA::PrivateKey privateKey(); QCA::PublicKey publicKey(); QString certificatePath(); QSslCertificate certificate(); void setName(const QString& name); /* * Trusted devices */ QStringList trustedDevices(); //list of ids - void removeTrustedDevice(const QString &id); - void addTrustedDevice(const QString &id, const QString &name, const QString &type); - KdeConnectConfig::DeviceInfo getTrustedDevice(const QString &id); + void removeTrustedDevice(const QString& id); + void addTrustedDevice(const QString& id, const QString& name, const QString& type); + KdeConnectConfig::DeviceInfo getTrustedDevice(const QString& id); void setDeviceProperty(const QString& deviceId, const QString& name, const QString& value); QString getDeviceProperty(const QString& deviceId, const QString& name, const QString& defaultValue = QString()); /* * Paths for config files, there is no guarantee the directories already exist */ QDir baseConfigDir(); - QDir deviceConfigDir(const QString &deviceId); - QDir pluginConfigDir(const QString &deviceId, const QString &pluginName); //Used by KdeConnectPluginConfig + QDir deviceConfigDir(const QString& deviceId); + QDir pluginConfigDir(const QString& deviceId, const QString& pluginName); //Used by KdeConnectPluginConfig private: KdeConnectConfig(); private: struct KdeConnectConfigPrivate* d; }; #endif diff --git a/core/kdeconnectplugin.cpp b/core/kdeconnectplugin.cpp index b922e6fe..27adcdeb 100644 --- a/core/kdeconnectplugin.cpp +++ b/core/kdeconnectplugin.cpp @@ -1,82 +1,82 @@ /** * Copyright 2013 Albert Vaca * * 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 "kdeconnectplugin.h" #include "core_debug.h" struct KdeConnectPluginPrivate { - Device* mDevice; - QString mPluginName; - QSet mOutgoingCapabilties; - KdeConnectPluginConfig* mConfig; + Device* m_device; + QString m_pluginName; + QSet m_outgoingCapabilties; + KdeConnectPluginConfig* m_config; }; KdeConnectPlugin::KdeConnectPlugin(QObject* parent, const QVariantList& args) : QObject(parent) , d(new KdeConnectPluginPrivate) { - d->mDevice = qvariant_cast< Device* >(args.at(0)); - d->mPluginName = args.at(1).toString(); - d->mOutgoingCapabilties = args.at(2).toStringList().toSet(); - d->mConfig = nullptr; + d->m_device = qvariant_cast< Device* >(args.at(0)); + d->m_pluginName = args.at(1).toString(); + d->m_outgoingCapabilties = args.at(2).toStringList().toSet(); + d->m_config = nullptr; } KdeConnectPluginConfig* KdeConnectPlugin::config() const { //Create on demand, because not every plugin will use it - if (!d->mConfig) { - d->mConfig = new KdeConnectPluginConfig(d->mDevice->id(), d->mPluginName); + if (!d->m_config) { + d->m_config = new KdeConnectPluginConfig(d->m_device->id(), d->m_pluginName); } - return d->mConfig; + return d->m_config; } KdeConnectPlugin::~KdeConnectPlugin() { - if (d->mConfig) { - delete d->mConfig; + if (d->m_config) { + delete d->m_config; } } const Device* KdeConnectPlugin::device() { - return d->mDevice; + return d->m_device; } Device const* KdeConnectPlugin::device() const { - return d->mDevice; + return d->m_device; } bool KdeConnectPlugin::sendPackage(NetworkPackage& np) const { - if(!d->mOutgoingCapabilties.contains(np.type())) { - qCWarning(KDECONNECT_CORE) << metaObject()->className() << "tried to send an unsupported package type" << np.type() << ". Supported:" << d->mOutgoingCapabilties; + if(!d->m_outgoingCapabilties.contains(np.type())) { + qCWarning(KDECONNECT_CORE) << metaObject()->className() << "tried to send an unsupported package type" << np.type() << ". Supported:" << d->m_outgoingCapabilties; return false; } // qCWarning(KDECONNECT_CORE) << metaObject()->className() << "sends" << np.type() << ". Supported:" << d->mOutgoingTypes; - return d->mDevice->sendPackage(np); + return d->m_device->sendPackage(np); } QString KdeConnectPlugin::dbusPath() const { return {}; } diff --git a/core/kdeconnectpluginconfig.cpp b/core/kdeconnectpluginconfig.cpp index 9f33d571..9e304597 100644 --- a/core/kdeconnectpluginconfig.cpp +++ b/core/kdeconnectpluginconfig.cpp @@ -1,100 +1,100 @@ /** * Copyright 2015 Albert Vaca * * 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 "kdeconnectpluginconfig.h" #include #include #include #include #include "kdeconnectconfig.h" struct KdeConnectPluginConfigPrivate { - QDir mConfigDir; - QSettings* mConfig; - QDBusMessage signal; + QDir m_configDir; + QSettings* m_config; + QDBusMessage m_signal; }; KdeConnectPluginConfig::KdeConnectPluginConfig(const QString& deviceId, const QString& pluginName) : d(new KdeConnectPluginConfigPrivate()) { - d->mConfigDir = KdeConnectConfig::instance()->pluginConfigDir(deviceId, pluginName); - QDir().mkpath(d->mConfigDir.path()); + d->m_configDir = KdeConnectConfig::instance()->pluginConfigDir(deviceId, pluginName); + QDir().mkpath(d->m_configDir.path()); - d->mConfig = new QSettings(d->mConfigDir.absoluteFilePath(QStringLiteral("config")), QSettings::IniFormat); + d->m_config = new QSettings(d->m_configDir.absoluteFilePath(QStringLiteral("config")), QSettings::IniFormat); - d->signal = QDBusMessage::createSignal("/kdeconnect/"+deviceId+"/"+pluginName, QStringLiteral("org.kde.kdeconnect.config"), QStringLiteral("configChanged")); + d->m_signal = QDBusMessage::createSignal("/kdeconnect/"+deviceId+"/"+pluginName, QStringLiteral("org.kde.kdeconnect.config"), QStringLiteral("configChanged")); QDBusConnection::sessionBus().connect(QLatin1String(""), "/kdeconnect/"+deviceId+"/"+pluginName, QStringLiteral("org.kde.kdeconnect.config"), QStringLiteral("configChanged"), this, SLOT(slotConfigChanged())); } KdeConnectPluginConfig::~KdeConnectPluginConfig() { - delete d->mConfig; + delete d->m_config; } QVariant KdeConnectPluginConfig::get(const QString& key, const QVariant& defaultValue) { - d->mConfig->sync(); - return d->mConfig->value(key, defaultValue); + d->m_config->sync(); + return d->m_config->value(key, defaultValue); } QVariantList KdeConnectPluginConfig::getList(const QString& key, const QVariantList& defaultValue) { QVariantList list; - d->mConfig->sync(); // note: need sync() to get recent changes signalled from other process - int size = d->mConfig->beginReadArray(key); + d->m_config->sync(); // note: need sync() to get recent changes signalled from other process + int size = d->m_config->beginReadArray(key); if (size < 1) { - d->mConfig->endArray(); + d->m_config->endArray(); return defaultValue; } for (int i = 0; i < size; ++i) { - d->mConfig->setArrayIndex(i); - list << d->mConfig->value(QStringLiteral("value")); + d->m_config->setArrayIndex(i); + list << d->m_config->value(QStringLiteral("value")); } - d->mConfig->endArray(); + d->m_config->endArray(); return list; } void KdeConnectPluginConfig::set(const QString& key, const QVariant& value) { - d->mConfig->setValue(key, value); - d->mConfig->sync(); - QDBusConnection::sessionBus().send(d->signal); + d->m_config->setValue(key, value); + d->m_config->sync(); + QDBusConnection::sessionBus().send(d->m_signal); } void KdeConnectPluginConfig::setList(const QString& key, const QVariantList& list) { - d->mConfig->beginWriteArray(key); + d->m_config->beginWriteArray(key); for (int i = 0; i < list.size(); ++i) { - d->mConfig->setArrayIndex(i); - d->mConfig->setValue(QStringLiteral("value"), list.at(i)); + d->m_config->setArrayIndex(i); + d->m_config->setValue(QStringLiteral("value"), list.at(i)); } - d->mConfig->endArray(); - d->mConfig->sync(); - QDBusConnection::sessionBus().send(d->signal); + d->m_config->endArray(); + d->m_config->sync(); + QDBusConnection::sessionBus().send(d->m_signal); } void KdeConnectPluginConfig::slotConfigChanged() { Q_EMIT configChanged(); } diff --git a/core/networkpackage.cpp b/core/networkpackage.cpp index dd5e12e5..54ca7c77 100644 --- a/core/networkpackage.cpp +++ b/core/networkpackage.cpp @@ -1,172 +1,172 @@ /** * Copyright 2013 Albert Vaca * * 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 "networkpackage.h" #include "core_debug.h" #include #include #include #include #include #include #include #include "dbushelper.h" #include "filetransferjob.h" #include "pluginloader.h" #include "kdeconnectconfig.h" QDebug operator<<(QDebug s, const NetworkPackage& pkg) { s.nospace() << "NetworkPackage(" << pkg.type() << ':' << pkg.body(); if (pkg.hasPayload()) { s.nospace() << ":withpayload"; } s.nospace() << ')'; return s.space(); } -const int NetworkPackage::ProtocolVersion = 7; - -NetworkPackage::NetworkPackage(const QString& type, const QVariantMap &body) - : mId(QString::number(QDateTime::currentMSecsSinceEpoch())) - , mType(type) - , mBody(body) - , mPayload() - , mPayloadSize(0) +const int NetworkPackage::s_protocolVersion = 7; + +NetworkPackage::NetworkPackage(const QString& type, const QVariantMap& body) + : m_id(QString::number(QDateTime::currentMSecsSinceEpoch())) + , m_type(type) + , m_body(body) + , m_payload() + , m_payloadSize(0) { } void NetworkPackage::createIdentityPackage(NetworkPackage* np) { KdeConnectConfig* config = KdeConnectConfig::instance(); - np->mId = QString::number(QDateTime::currentMSecsSinceEpoch()); - np->mType = PACKAGE_TYPE_IDENTITY; - np->mPayload = QSharedPointer(); - np->mPayloadSize = 0; + np->m_id = QString::number(QDateTime::currentMSecsSinceEpoch()); + np->m_type = PACKAGE_TYPE_IDENTITY; + np->m_payload = QSharedPointer(); + np->m_payloadSize = 0; np->set(QStringLiteral("deviceId"), config->deviceId()); np->set(QStringLiteral("deviceName"), config->name()); np->set(QStringLiteral("deviceType"), config->deviceType()); - np->set(QStringLiteral("protocolVersion"), NetworkPackage::ProtocolVersion); + np->set(QStringLiteral("protocolVersion"), NetworkPackage::s_protocolVersion); np->set(QStringLiteral("incomingCapabilities"), PluginLoader::instance()->incomingCapabilities()); np->set(QStringLiteral("outgoingCapabilities"), PluginLoader::instance()->outgoingCapabilities()); //qCDebug(KDECONNECT_CORE) << "createIdentityPackage" << np->serialize(); } template QVariantMap qobject2qvariant(const T* object) { QVariantMap map; auto metaObject = T::staticMetaObject; for(int i = metaObject.propertyOffset(); i < metaObject.propertyCount(); ++i) { QMetaProperty prop = metaObject.property(i); map.insert(QString::fromLatin1(prop.name()), prop.readOnGadget(object)); } return map; } QByteArray NetworkPackage::serialize() const { //Object -> QVariant //QVariantMap variant; //variant["id"] = mId; //variant["type"] = mType; //variant["body"] = mBody; QVariantMap variant = qobject2qvariant(this); if (hasPayload()) { //qCDebug(KDECONNECT_CORE) << "Serializing payloadTransferInfo"; variant[QStringLiteral("payloadSize")] = payloadSize(); - variant[QStringLiteral("payloadTransferInfo")] = mPayloadTransferInfo; + variant[QStringLiteral("payloadTransferInfo")] = m_payloadTransferInfo; } //QVariant -> json auto jsonDocument = QJsonDocument::fromVariant(variant); QByteArray json = jsonDocument.toJson(QJsonDocument::Compact); if (json.isEmpty()) { qCDebug(KDECONNECT_CORE) << "Serialization error:"; } else { /*if (!isEncrypted()) { //qCDebug(KDECONNECT_CORE) << "Serialized package:" << json; }*/ json.append('\n'); } return json; } template void qvariant2qobject(const QVariantMap& variant, T* object) { for ( QVariantMap::const_iterator iter = variant.begin(); iter != variant.end(); ++iter ) { const int propertyIndex = T::staticMetaObject.indexOfProperty(iter.key().toLatin1()); if (propertyIndex < 0) { qCWarning(KDECONNECT_CORE) << "missing property" << object << iter.key(); continue; } QMetaProperty property = T::staticMetaObject.property(propertyIndex); bool ret = property.writeOnGadget(object, *iter); if (!ret) { qCWarning(KDECONNECT_CORE) << "couldn't set" << object << "->" << property.name() << '=' << *iter; } } } bool NetworkPackage::unserialize(const QByteArray& a, NetworkPackage* np) { //Json -> QVariant QJsonParseError parseError; auto parser = QJsonDocument::fromJson(a, &parseError); if (parser.isNull()) { qCDebug(KDECONNECT_CORE) << "Unserialization error:" << parseError.errorString(); return false; } auto variant = parser.toVariant().toMap(); qvariant2qobject(variant, np); - np->mPayloadSize = variant[QStringLiteral("payloadSize")].toInt(); //Will return 0 if was not present, which is ok - if (np->mPayloadSize == -1) { - np->mPayloadSize = np->get(QStringLiteral("size"), -1); + np->m_payloadSize = variant[QStringLiteral("payloadSize")].toInt(); //Will return 0 if was not present, which is ok + if (np->m_payloadSize == -1) { + np->m_payloadSize = np->get(QStringLiteral("size"), -1); } - np->mPayloadTransferInfo = variant[QStringLiteral("payloadTransferInfo")].toMap(); //Will return an empty qvariantmap if was not present, which is ok + np->m_payloadTransferInfo = variant[QStringLiteral("payloadTransferInfo")].toMap(); //Will return an empty qvariantmap if was not present, which is ok //Ids containing characters that are not allowed as dbus paths would make app crash - if (np->mBody.contains(QStringLiteral("deviceId"))) + if (np->m_body.contains(QStringLiteral("deviceId"))) { QString deviceId = np->get(QStringLiteral("deviceId")); DbusHelper::filterNonExportableCharacters(deviceId); np->set(QStringLiteral("deviceId"), deviceId); } return true; } -FileTransferJob* NetworkPackage::createPayloadTransferJob(const QUrl &destination) const +FileTransferJob* NetworkPackage::createPayloadTransferJob(const QUrl& destination) const { return new FileTransferJob(payload(), payloadSize(), destination); } diff --git a/core/networkpackage.h b/core/networkpackage.h index a659181d..0afb81ae 100644 --- a/core/networkpackage.h +++ b/core/networkpackage.h @@ -1,101 +1,101 @@ /** * Copyright 2013 Albert Vaca * * 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 NETWORKPACKAGE_H #define NETWORKPACKAGE_H #include "networkpackagetypes.h" #include #include #include #include //#include #include #include #include "kdeconnectcore_export.h" class FileTransferJob; class KDECONNECTCORE_EXPORT NetworkPackage { Q_GADGET Q_PROPERTY( QString id READ id WRITE setId ) Q_PROPERTY( QString type READ type WRITE setType ) Q_PROPERTY( QVariantMap body READ body WRITE setBody ) Q_PROPERTY( QVariantMap payloadTransferInfo READ payloadTransferInfo WRITE setPayloadTransferInfo ) Q_PROPERTY( qint64 payloadSize READ payloadSize WRITE setPayloadSize ) public: //const static QCA::EncryptionAlgorithm EncryptionAlgorithm; - const static int ProtocolVersion; + const static int s_protocolVersion; - explicit NetworkPackage(const QString& type, const QVariantMap &body = {}); + explicit NetworkPackage(const QString& type, const QVariantMap& body = {}); static void createIdentityPackage(NetworkPackage*); QByteArray serialize() const; static bool unserialize(const QByteArray& json, NetworkPackage* out); - const QString& id() const { return mId; } - const QString& type() const { return mType; } - QVariantMap& body() { return mBody; } - const QVariantMap& body() const { return mBody; } + const QString& id() const { return m_id; } + const QString& type() const { return m_type; } + QVariantMap& body() { return m_body; } + const QVariantMap& body() const { return m_body; } //Get and set info from body. Note that id and type can not be accessed through these. template T get(const QString& key, const T& defaultValue = {}) const { - return mBody.value(key,defaultValue).template value(); //Important note: Awesome template syntax is awesome + return m_body.value(key,defaultValue).template value(); //Important note: Awesome template syntax is awesome } - template void set(const QString& key, const T& value) { mBody[key] = QVariant(value); } - bool has(const QString& key) const { return mBody.contains(key); } + template void set(const QString& key, const T& value) { m_body[key] = QVariant(value); } + bool has(const QString& key) const { return m_body.contains(key); } - QSharedPointer payload() const { return mPayload; } - void setPayload(const QSharedPointer& device, qint64 payloadSize) { mPayload = device; mPayloadSize = payloadSize; Q_ASSERT(mPayloadSize >= -1); } - bool hasPayload() const { return (mPayloadSize != 0); } - qint64 payloadSize() const { return mPayloadSize; } //-1 means it is an endless stream - FileTransferJob* createPayloadTransferJob(const QUrl &destination) const; + QSharedPointer payload() const { return m_payload; } + void setPayload(const QSharedPointer& device, qint64 payloadSize) { m_payload = device; m_payloadSize = payloadSize; Q_ASSERT(m_payloadSize >= -1); } + bool hasPayload() const { return (m_payloadSize != 0); } + qint64 payloadSize() const { return m_payloadSize; } //-1 means it is an endless stream + FileTransferJob* createPayloadTransferJob(const QUrl& destination) const; //To be called by a particular DeviceLink - QVariantMap payloadTransferInfo() const { return mPayloadTransferInfo; } - void setPayloadTransferInfo(const QVariantMap& map) { mPayloadTransferInfo = map; } - bool hasPayloadTransferInfo() const { return !mPayloadTransferInfo.isEmpty(); } + QVariantMap payloadTransferInfo() const { return m_payloadTransferInfo; } + void setPayloadTransferInfo(const QVariantMap& map) { m_payloadTransferInfo = map; } + bool hasPayloadTransferInfo() const { return !m_payloadTransferInfo.isEmpty(); } private: - void setId(const QString& id) { mId = id; } - void setType(const QString& t) { mType = t; } - void setBody(const QVariantMap& b) { mBody = b; } - void setPayloadSize(qint64 s) { mPayloadSize = s; } + void setId(const QString& id) { m_id = id; } + void setType(const QString& t) { m_type = t; } + void setBody(const QVariantMap& b) { m_body = b; } + void setPayloadSize(qint64 s) { m_payloadSize = s; } - QString mId; - QString mType; - QVariantMap mBody; + QString m_id; + QString m_type; + QVariantMap m_body; - QSharedPointer mPayload; - qint64 mPayloadSize; - QVariantMap mPayloadTransferInfo; + QSharedPointer m_payload; + qint64 m_payloadSize; + QVariantMap m_payloadTransferInfo; }; KDECONNECTCORE_EXPORT QDebug operator<<(QDebug s, const NetworkPackage& pkg); #endif // NETWORKPACKAGE_H diff --git a/core/pluginloader.cpp b/core/pluginloader.cpp index 681e0c8a..c63b7797 100644 --- a/core/pluginloader.cpp +++ b/core/pluginloader.cpp @@ -1,131 +1,131 @@ /** * Copyright 2013 Albert Vaca * * 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 "pluginloader.h" #include #include #include #include "core_debug.h" #include "device.h" #include "kdeconnectplugin.h" PluginLoader* PluginLoader::instance() { static PluginLoader* instance = new PluginLoader(); return instance; } PluginLoader::PluginLoader() { const QVector data = KPluginLoader::findPlugins(QStringLiteral("kdeconnect/")); for (const KPluginMetaData& metadata : data) { plugins[metadata.pluginId()] = metadata; } } QStringList PluginLoader::getPluginList() const { return plugins.keys(); } KPluginMetaData PluginLoader::getPluginInfo(const QString& name) const { return plugins.value(name); } KdeConnectPlugin* PluginLoader::instantiatePluginForDevice(const QString& pluginName, Device* device) const { KdeConnectPlugin* ret = Q_NULLPTR; KPluginMetaData service = plugins.value(pluginName); if (!service.isValid()) { qCDebug(KDECONNECT_CORE) << "Plugin unknown" << pluginName; return ret; } KPluginLoader loader(service.fileName()); - KPluginFactory *factory = loader.factory(); + KPluginFactory* factory = loader.factory(); if (!factory) { qCDebug(KDECONNECT_CORE) << "KPluginFactory could not load the plugin:" << service.pluginId() << loader.errorString(); return ret; } const QStringList outgoingInterfaces = KPluginMetaData::readStringList(service.rawData(), QStringLiteral("X-KdeConnect-OutgoingPackageType")); QVariant deviceVariant = QVariant::fromValue(device); ret = factory->create(device, QVariantList() << deviceVariant << pluginName << outgoingInterfaces); if (!ret) { qCDebug(KDECONNECT_CORE) << "Error loading plugin"; return ret; } //qCDebug(KDECONNECT_CORE) << "Loaded plugin:" << service.pluginId(); return ret; } QStringList PluginLoader::incomingCapabilities() const { QSet ret; for (const KPluginMetaData& service : qAsConst(plugins)) { ret += KPluginMetaData::readStringList(service.rawData(), QStringLiteral("X-KdeConnect-SupportedPackageType")).toSet(); } return ret.toList(); } QStringList PluginLoader::outgoingCapabilities() const { QSet ret; for (const KPluginMetaData& service : qAsConst(plugins)) { ret += KPluginMetaData::readStringList(service.rawData(), QStringLiteral("X-KdeConnect-OutgoingPackageType")).toSet(); } return ret.toList(); } QSet PluginLoader::pluginsForCapabilities(const QSet& incoming, const QSet& outgoing) { QSet ret; for (const KPluginMetaData& service : qAsConst(plugins)) { const QSet pluginIncomingCapabilities = KPluginMetaData::readStringList(service.rawData(), QStringLiteral("X-KdeConnect-SupportedPackageType")).toSet(); const QSet pluginOutgoingCapabilities = KPluginMetaData::readStringList(service.rawData(), QStringLiteral("X-KdeConnect-OutgoingPackageType")).toSet(); bool capabilitiesEmpty = (pluginIncomingCapabilities.isEmpty() && pluginOutgoingCapabilities.isEmpty()); #if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)) bool capabilitiesIntersect = (outgoing.intersects(pluginIncomingCapabilities) || incoming.intersects(pluginOutgoingCapabilities)); #else QSet commonIncoming = incoming; commonIncoming.intersect(pluginOutgoingCapabilities); QSet commonOutgoing = outgoing; commonOutgoing.intersect(pluginIncomingCapabilities); bool capabilitiesIntersect = (!commonIncoming.isEmpty() || !commonOutgoing.isEmpty()); #endif if (capabilitiesIntersect || capabilitiesEmpty) { ret += service.pluginId(); } else { qCDebug(KDECONNECT_CORE) << "Not loading plugin" << service.pluginId() << "because device doesn't support it"; } } return ret; } diff --git a/core/pluginloader.h b/core/pluginloader.h index d1a538f8..306431d2 100644 --- a/core/pluginloader.h +++ b/core/pluginloader.h @@ -1,54 +1,54 @@ /** * Copyright 2013 Albert Vaca * * 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 PLUGINLOADER_H #define PLUGINLOADER_H #include #include #include #include class Device; class KdeConnectPlugin; class PluginLoader { public: static PluginLoader* instance(); QStringList getPluginList() const; KPluginMetaData getPluginInfo(const QString& name) const; KdeConnectPlugin* instantiatePluginForDevice(const QString& name, Device* device) const; QStringList incomingCapabilities() const; QStringList outgoingCapabilities() const; - QSet pluginsForCapabilities(const QSet &incoming, const QSet &outgoing); + QSet pluginsForCapabilities(const QSet& incoming, const QSet& outgoing); private: PluginLoader(); QHash plugins; }; #endif diff --git a/daemon/kdeconnect.desktop b/daemon/kdeconnect.desktop index 05de252a..f027cb6f 100644 --- a/daemon/kdeconnect.desktop +++ b/daemon/kdeconnect.desktop @@ -1,91 +1,89 @@ [Desktop Entry] Type=Service Icon=preferences-system-power-management X-KDE-ServiceTypes=KDEDModule X-KDE-Library=kdeconnect X-DBUS-ServiceName=org.kde.kdeconnect X-KDE-DBus-ModuleName=kdeconnect X-KDE-Kded-autoload=true X-KDE-Kded-load-on-demand=false X-KDE-Kded-phase=1 Name=KDE Connect Name[ar]=كدي المتّصل Name[ast]=KDE Connect Name[bg]=KDE Connect Name[bs]=Konekcija KDE Name[ca]=KDE Connect Name[ca@valencia]=KDE Connect Name[cs]=KDE Connect Name[da]=KDE Connect Name[de]=KDE-Connect Name[el]=KDE Connect Name[en_GB]=KDE Connect Name[es]=KDE Connect Name[et]=KDE Connect -Name[eu]=KDE Connect Name[fi]=KDE Connect Name[fr]=KDE Connect Name[gl]=KDE Connect Name[he]=KDE Connect Name[hu]=KDE csatlakozás Name[it]=KDE Connect Name[ko]=KDE Connect Name[nl]=KDE Connect Name[nn]=KDE Connect Name[pl]=KDE Connect Name[pt]=KDE Connect Name[pt_BR]=KDE Connect Name[ro]=KDE Connect Name[ru]=KDE Connect Name[sk]=KDE Connect Name[sr]=КДЕ‑конекција Name[sr@ijekavian]=КДЕ‑конекција Name[sr@ijekavianlatin]=KDE‑konekcija Name[sr@latin]=KDE‑konekcija Name[sv]=KDE-anslut Name[tr]=KDE Connect Name[uk]=З’єднання KDE Name[x-test]=xxKDE Connectxx Name[zh_CN]=KDE Connect Name[zh_TW]=KDE 連線 Comment=Connect KDE with your smartphone Comment[ar]=أوصل كدي بهاتفك الذّكيّ Comment[ast]=Coneuta KDE col to teléfonu intelixente Comment[bg]=Свържете КДЕ с вашия смартфон Comment[bs]=Konektujte se na KDE sa Vašim mobitelom Comment[ca]=Connecta el KDE amb el vostre telèfon intel·ligent Comment[ca@valencia]=Connecta el KDE amb el vostre telèfon intel·ligent Comment[cs]=Propojte KDE s vaším telefonem Comment[da]=Forbind KDE med din smartphone Comment[de]=KDE mit Ihren Smartphone verbinden Comment[el]=Σύνδεση του KDE με το έξυπνο τηλέφωνό σας Comment[en_GB]=Connect KDE with your smartphone Comment[es]=Conecte KDE con su teléfono móvil Comment[et]=KDE ühendamine oma nutitelefoniga -Comment[eu]=Konektatu KDE zure mugikorrarekin Comment[fi]=Yhdistä KDE älypuhelimeesi Comment[fr]=Connectez KDE avec votre smartphone Comment[gl]=Conectar KDE co seu teléfono móbil. Comment[he]=חבר את KDE לפלאפון החכם שלך Comment[hu]=A KDE csatlakoztatása az okostelefonnal Comment[it]=Connetti KDE con il tuo smartphone Comment[ko]=KDE와 스마트폰 연결 Comment[nl]=KDE met uw smartphone verbinden Comment[nn]=Kopla KDE til smarttelefonen din Comment[pl]=Podłącz swój smartfon do KDE Comment[pt]=Ligue o KDE ao seu telemóvel Comment[pt_BR]=Conecte o KDE ao seu celular Comment[ru]=Подключайте смартфон к KDE Comment[sk]=Prepojiť KDE s vašim smartfónom Comment[sr]=Повежите КДЕ са својим паметним телефоном Comment[sr@ijekavian]=Повежите КДЕ са својим паметним телефоном Comment[sr@ijekavianlatin]=Povežite KDE sa svojim pametnim telefonom Comment[sr@latin]=Povežite KDE sa svojim pametnim telefonom Comment[sv]=Anslut KDE till din smartphone Comment[tr]=KDE'yi akıllı telefonunuz ile bağlayın Comment[uk]=З’єднання KDE з вашим смартфоном Comment[x-test]=xxConnect KDE with your smartphonexx Comment[zh_CN]=用您的智能手机连接到 KDE Comment[zh_TW]=將您的智慧型手機與KDE連線 diff --git a/daemon/kdeconnectd.desktop.cmake b/daemon/kdeconnectd.desktop.cmake index a7ec7ccb..701c1e85 100644 --- a/daemon/kdeconnectd.desktop.cmake +++ b/daemon/kdeconnectd.desktop.cmake @@ -1,47 +1,46 @@ [Desktop Entry] Type=Application Exec=${KDE_INSTALL_FULL_LIBEXECDIR}/kdeconnectd X-KDE-StartupNotify=false X-KDE-autostart-phase=0 X-GNOME-Autostart-enabled=true OnlyShowIn=KDE;GNOME;Unity;XFCE; NoDisplay=true Name=KDEConnect daemon Name[ar]=عفريت KDEConnect Name[ast]=Degorriu KDEConnect Name[bg]=Услуга KDE Connect Name[ca]=Dimoni del KDEConnect Name[ca@valencia]=Dimoni del KDEConnect Name[cs]=Démon KDE Connect Name[da]=KDEConnect-dæmon Name[de]=KDE-Connect-Dienst Name[el]=Δαίμονας του KDEConnect Name[en_GB]=KDEConnect daemon Name[es]=Demonio de KDE Connect Name[et]=KDEConnecti deemon -Name[eu]=KDEConnect daimona Name[fi]=KDEConnect-taustapalvelu Name[fr]=Démon KDE Connect Name[gl]=Servizo de KDE Connect Name[he]=דמון KDEConnect Name[hu]=KDEConnect szolgáltatás Name[it]=Demone KDE Connect Name[ko]=KDE Connect 데몬 Name[nl]=KDEConnect-daemon Name[nn]=KDEConnect-teneste Name[pl]=Usługa KDEConnect Name[pt]=Serviço do KDE Connect Name[pt_BR]=Serviço do KDE Connect Name[ru]=Служба KDE Connect Name[sk]=KDEConnect démon Name[sr]=КДЕ‑конекцијин демон Name[sr@ijekavian]=КДЕ‑конекцијин демон Name[sr@ijekavianlatin]=KDE‑konekcijin demon Name[sr@latin]=KDE‑konekcijin demon Name[sv]=Demon för KDE-anslut Name[tr]=KDEConnect süreci Name[uk]=Фонова служба KDEConnect Name[x-test]=xxKDEConnect daemonxx Name[zh_CN]=KDEConnect 守护进程 Name[zh_TW]=KDE連線作業 diff --git a/fileitemactionplugin/kdeconnectsendfile.desktop b/fileitemactionplugin/kdeconnectsendfile.desktop index 56c5c0ab..c3bee385 100644 --- a/fileitemactionplugin/kdeconnectsendfile.desktop +++ b/fileitemactionplugin/kdeconnectsendfile.desktop @@ -1,86 +1,84 @@ [Desktop Entry] Type=Service Name=Send file via KDE Connect service Name[ar]=أرسل ملفًّا عبر خدمة «كدي المتّصل» Name[ast]=Unviar ficheru pel serviciu de KDE Connect Name[bg]=Изпращане на файл през услугата KDE Connect Name[bs]=Pošalji datoteku putem KDE Connect servisa Name[ca]=Envia un fitxer a través del servei KDE Connect Name[ca@valencia]=Envia un fitxer a través del servei KDE Connect Name[cs]=Poslat soubor přes službu KDE Connect Name[da]=Send fil via KDE Connect-tjeneste Name[de]=Datei mit KDE-Connect -Dienst versenden Name[el]=Αποστολή αρχείου μέσω της υπηρεσίας KDE Connect Name[en_GB]=Send file via KDE Connect service Name[es]=Enviar archivo usando el servicio KDE Connect Name[et]=Faili saatmine KDE Connecti teenuse kaudu -Name[eu]=Bidali fitxategia KDE Connect zerbitzuaren bidez Name[fi]=Lähetä tiedosto KDE Connect -palvelulla Name[fr]=Envoyer un fichier via le service KDE Connect Name[gl]=Enviar un ficheiro mediante o servizo de KDE Connect Name[he]=שלח קובץ דרך שירות KDE Connect Name[hu]=Fájl küldése a KDE csatlakozás szolgáltatáson keresztül Name[it]=Invia un file tramite il servizio KDE Connect Name[ko]=KDE Connect 서비스로 파일 보내기 Name[nl]=Bestand via de service KDE Connect versturen Name[nn]=Send fil med KDE Connect-tenesta Name[pl]=Wyślij plik przez usługę KDE Connect Name[pt]=Enviar um ficheiro pelo serviço KDE Connect Name[pt_BR]=Enviar arquivo pelo serviço KDE Connect Name[ru]=Отправить файл через KDE Connect Name[sk]=Poslať súbor cez službu KDE Connect Name[sr]=Шаљи фајл преко КДЕ‑конекцијиног сервиса Name[sr@ijekavian]=Шаљи фајл преко КДЕ‑конекцијиног сервиса Name[sr@ijekavianlatin]=Šalji fajl preko KDE‑konekcijinog servisa Name[sr@latin]=Šalji fajl preko KDE‑konekcijinog servisa Name[sv]=Skicka fil via KDE:s anslutningstjänst Name[tr]=KDE Connect servisi ile dosya gönderin Name[uk]=Надсилання файла за допомогою служби з’єднання KDE Name[x-test]=xxSend file via KDE Connect servicexx Name[zh_CN]=通过 KDE Connect 服务发送文件 Name[zh_TW]=以已經連結到KDE之服務或裝置來傳送檔案 X-KDE-Library=kdeconnectfileitemaction X-KDE-Submenu=Connect X-KDE-Submenu[ar]=اتّصل,اتصل X-KDE-Submenu[ast]=Coneutar X-KDE-Submenu[bg]=Свързване X-KDE-Submenu[bs]=Uspostavi vezu X-KDE-Submenu[ca]=Connecta X-KDE-Submenu[ca@valencia]=Connecta X-KDE-Submenu[cs]=Připojit X-KDE-Submenu[da]=Forbind X-KDE-Submenu[de]=Verbinden X-KDE-Submenu[el]=Σύνδεση X-KDE-Submenu[en_GB]=Connect X-KDE-Submenu[es]=Conectar X-KDE-Submenu[et]=Ühendus -X-KDE-Submenu[eu]=Konektatu X-KDE-Submenu[fi]=Yhdistä X-KDE-Submenu[fr]=Connecter X-KDE-Submenu[gl]=Conectar X-KDE-Submenu[he]=חיבור X-KDE-Submenu[hu]=Csatlakozás X-KDE-Submenu[ia]=Connecte X-KDE-Submenu[it]=Connetti X-KDE-Submenu[ko]=연결 X-KDE-Submenu[nl]=Verbinden X-KDE-Submenu[nn]=Kopla til X-KDE-Submenu[pl]=Połącz X-KDE-Submenu[pt]=Ligar X-KDE-Submenu[pt_BR]=Conectar X-KDE-Submenu[ru]=KDE Connect X-KDE-Submenu[sk]=Pripojiť X-KDE-Submenu[sr]=Повежи се X-KDE-Submenu[sr@ijekavian]=Повежи се X-KDE-Submenu[sr@ijekavianlatin]=Poveži se X-KDE-Submenu[sr@latin]=Poveži se X-KDE-Submenu[sv]=Anslut X-KDE-Submenu[tr]=Bağlan X-KDE-Submenu[uk]=З’єднання X-KDE-Submenu[x-test]=xxConnectxx X-KDE-Submenu[zh_CN]=连接 X-KDE-Submenu[zh_TW]=連線 Icon=preferences-system-network ServiceTypes=KFileItemAction/Plugin MimeType=application/octet-stream diff --git a/fileitemactionplugin/sendfileitemaction.cpp b/fileitemactionplugin/sendfileitemaction.cpp index 3a999361..2006e1c9 100644 --- a/fileitemactionplugin/sendfileitemaction.cpp +++ b/fileitemactionplugin/sendfileitemaction.cpp @@ -1,99 +1,99 @@ /* * Copyright (C) 2011 Alejandro Fiestas Olivares * Copyright (C) 2014 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) 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 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 "sendfileitemaction.h" #include #include #include #include #include #include #include #include #include #include #include #include K_PLUGIN_FACTORY(SendFileItemActionFactory, registerPlugin();) Q_LOGGING_CATEGORY(KDECONNECT_FILEITEMACTION, "kdeconnect.fileitemaction") SendFileItemAction::SendFileItemAction(QObject* parent, const QVariantList& ): KAbstractFileItemActionPlugin(parent) { } QList SendFileItemAction::actions(const KFileItemListProperties& fileItemInfos, QWidget* parentWidget) { QList actions; DaemonDbusInterface iface; if (!iface.isValid()) { return actions; } QDBusPendingReply reply = iface.devices(true, true); reply.waitForFinished(); const QStringList devices = reply.value(); for (const QString& id : devices) { DeviceDbusInterface deviceIface(id); if (!deviceIface.isValid()) { continue; } if (!deviceIface.hasPlugin(QStringLiteral("kdeconnect_share"))) { continue; } QAction* action = new QAction(QIcon::fromTheme(deviceIface.iconName()), deviceIface.name(), parentWidget); action->setProperty("id", id); action->setProperty("urls", QVariant::fromValue(fileItemInfos.urlList())); action->setProperty("parentWidget", QVariant::fromValue(parentWidget)); connect(action, &QAction::triggered, this, &SendFileItemAction::sendFile); actions += action; } if (actions.count() > 1) { - QAction *menuAction = new QAction(QIcon::fromTheme(QStringLiteral("preferences-system-network")), i18n("Send via KDE Connect"), parentWidget); - QMenu *menu = new QMenu(parentWidget); + QAction* menuAction = new QAction(QIcon::fromTheme(QStringLiteral("preferences-system-network")), i18n("Send via KDE Connect"), parentWidget); + QMenu* menu = new QMenu(parentWidget); menu->addActions(actions); menuAction->setMenu(menu); return QList() << menuAction; } else { if(actions.count() == 1) { actions.first()->setText(i18n("Send to '%1' via KDE Connect", actions.first()->text())); } return actions; } } void SendFileItemAction::sendFile() { const QList urls = sender()->property("urls").value>(); QString id = sender()->property("id").toString(); for (const QUrl& url : urls) { QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.kde.kdeconnect"), "/modules/kdeconnect/devices/"+id+"/share", QStringLiteral("org.kde.kdeconnect.device.share"), QStringLiteral("shareUrl")); msg.setArguments(QVariantList() << url.toString()); QDBusConnection::sessionBus().call(msg); } } #include "sendfileitemaction.moc" diff --git a/fileitemactionplugin/sendfileitemaction.h b/fileitemactionplugin/sendfileitemaction.h index 3e4d99f4..6020a23d 100644 --- a/fileitemactionplugin/sendfileitemaction.h +++ b/fileitemactionplugin/sendfileitemaction.h @@ -1,45 +1,45 @@ /* * Copyright (C) 2011 Alejandro Fiestas Olivares * Copyright (C) 2014 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) 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 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 SENDFILEITEMACTION_H #define SENDFILEITEMACTION_H #include #include #include class QAction; class KFileItemListProperties; class QWidget; Q_DECLARE_LOGGING_CATEGORY(KDECONNECT_FILEITEMACTION) class SendFileItemAction : public KAbstractFileItemActionPlugin { Q_OBJECT public: - SendFileItemAction(QObject* parent, const QVariantList &args); + SendFileItemAction(QObject* parent, const QVariantList& args); QList< QAction* > actions(const KFileItemListProperties& fileItemInfos, QWidget* parentWidget) override; private Q_SLOTS: void sendFile(); }; #endif // SENDFILEITEMACTION_H diff --git a/indicator/deviceindicator.h b/indicator/deviceindicator.h index 3e3446d0..7d197e38 100644 --- a/indicator/deviceindicator.h +++ b/indicator/deviceindicator.h @@ -1,40 +1,40 @@ /* * 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); public Q_SLOTS: - void setText(const QString &text) { setTitle(text); } + void setText(const QString& text) { setTitle(text); } private: DeviceDbusInterface* m_device; }; #endif // DEVICEINDICATOR_H diff --git a/indicator/main.cpp b/indicator/main.cpp index c0162f0c..415ac581 100644 --- a/indicator/main.cpp +++ b/indicator/main.cpp @@ -1,132 +1,132 @@ /* * 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 #ifdef QSYSTRAY #include #else #include #endif #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-indicator", i18n("KDE Connect Indicator"), QStringLiteral(KDECONNECT_VERSION_STRING), i18n("KDE Connect Indicator tool"), KAboutLicense::GPL, i18n("(C) 2016 Aleix Pol Gonzalez")); KAboutData::setApplicationData(about); #ifdef Q_OS_WIN QProcess::startDetached("kdeconnectd.exe"); #endif KDBusService dbusService(KDBusService::Unique); DevicesModel model; model.setDisplayFilter(DevicesModel::Reachable | DevicesModel::Paired); - QMenu *menu = new QMenu; + QMenu* menu = new QMenu; DaemonDbusInterface iface; auto refreshMenu = [&iface, &model, &menu]() { menu->clear(); auto configure = menu->addAction(i18n("Configure...")); QObject::connect(configure, &QAction::triggered, configure, [](){ KCMultiDialog* dialog = new KCMultiDialog; dialog->addModule("kcm_kdeconnect"); dialog->setAttribute(Qt::WA_DeleteOnClose); dialog->show(); }); for (int i=0, count = model.rowCount(); iaddMenu(indicator); } const QStringList requests = iface.pairingRequests(); if (!requests.isEmpty()) { menu->addSection(i18n("Pairing requests")); - for(const auto &req: requests) { - DeviceDbusInterface *dev = new DeviceDbusInterface(req, menu); + for(const auto& req: requests) { + DeviceDbusInterface* dev = new DeviceDbusInterface(req, menu); auto pairMenu = menu->addMenu(dev->name()); pairMenu->addAction(i18n("Pair"), dev, &DeviceDbusInterface::acceptPairing); pairMenu->addAction(i18n("Reject"), dev, &DeviceDbusInterface::rejectPairing); } } }; QObject::connect(&iface, &DaemonDbusInterface::pairingRequestsChangedProxy, &model, refreshMenu); QObject::connect(&model, &DevicesModel::rowsInserted, &model, refreshMenu); QObject::connect(&model, &DevicesModel::rowsRemoved, &model, refreshMenu); #ifdef QSYSTRAY QSystemTrayIcon systray; systray.setIcon(QIcon::fromTheme("kdeconnect")); systray.setVisible(true); systray.setToolTip("KDE Connect"); QObject::connect(&model, &DevicesModel::rowsChanged, &model, [&systray, &model]() { systray.setToolTip(i18np("%1 device connected", "%1 devices connected", model.rowCount())); }); systray.setContextMenu(menu); #else KStatusNotifierItem systray; systray.setIconByName(QStringLiteral("kdeconnect")); systray.setToolTip(QStringLiteral("kdeconnect"), "KDE Connect", "KDE Connect"); systray.setCategory(KStatusNotifierItem::Communications); systray.setStatus(KStatusNotifierItem::Passive); systray.setStandardActionsEnabled(false); QObject::connect(&model, &DevicesModel::rowsChanged, &model, [&systray, &model]() { const auto count = model.rowCount(); systray.setStatus(count == 0 ? KStatusNotifierItem::Passive : KStatusNotifierItem::Active); systray.setToolTip(QStringLiteral("kdeconnect"), QStringLiteral("KDE Connect"), i18np("%1 device connected", "%1 devices connected", count)); }); systray.setContextMenu(menu); #endif refreshMenu(); app.setQuitOnLastWindowClosed(false); return app.exec(); } diff --git a/indicator/org.kde.kdeconnect.nonplasma.desktop b/indicator/org.kde.kdeconnect.nonplasma.desktop index 2ea61f0a..91674321 100755 --- a/indicator/org.kde.kdeconnect.nonplasma.desktop +++ b/indicator/org.kde.kdeconnect.nonplasma.desktop @@ -1,68 +1,66 @@ [Desktop Entry] Name=KDE Connect Indicator Name[ca]=Indicador del KDE Connect Name[ca@valencia]=Indicador del KDE Connect Name[cs]=Indikátor KDE Connect Name[da]=KDE Connect-indikator Name[de]=KDE-Connect-Anzeige Name[es]=Indicador de KDE Connect -Name[eu]=KDE Connect adierazlea Name[fr]=Indicateur de KDE Connect Name[gl]=Indicador de KDE Connect Name[it]=Indicatore di KDE Connect Name[nl]=KDE-Connect indicator Name[nn]=KDE Connect-indikator Name[pl]=Wskaźnik KDE Connect Name[pt]=Indicador do KDE Connect Name[sr]=КДЕ‑конекцијин показатељ Name[sr@ijekavian]=КДЕ‑конекцијин показатељ Name[sr@ijekavianlatin]=KDE‑konekcijin pokazatelj Name[sr@latin]=KDE‑konekcijin pokazatelj Name[sv]=KDE-anslut indikator Name[tr]=KDE Connect Göstergesi Name[uk]=Індикатор KDE Connect Name[x-test]=xxKDE Connect Indicatorxx Comment=Display information about your devices Comment[ar]=اعرض معلومات عن أجهزتك Comment[ast]=Amuesa información tocante a los tos preseos Comment[ca]=Mostra la informació dels vostres dispositius Comment[ca@valencia]=Mostra la informació dels vostres dispositius Comment[cs]=Zobrazit informace o vašich zařízeních Comment[da]=Vis information om dine enheder Comment[de]=Anzeige von Informationen über Ihre Geräte Comment[el]=Προβολή πληροφοριών σχετικά με τις συσκευές σας Comment[en_GB]=Display information about your devices Comment[es]=Mostrar información sobre sus dispositivos Comment[et]=Teabe kuvamine seadmete kohta -Comment[eu]=Bistaratu zure gailuei buruzko informazioa Comment[fi]=Näyttää tietoa laitteistasi Comment[fr]=Afficher les informations de vos périphériques Comment[gl]=Mostrar información sobre os dispositivos Comment[he]=הצג מידע עך ההתקנים שלך Comment[hu]=Információk megjelenítése az eszközeiről Comment[it]=Visualizza informazioni sui tuoi dispositivi Comment[ko]=장치 정보 표시 Comment[nl]=Toon informatie over uw apparaten Comment[nn]=Vis informasjon om einingane dine Comment[pl]=Wyświetl informacje o twoich urządzeniach Comment[pt]=Mostrar informações sobre os seus dispositivos Comment[pt_BR]=Mostra informações sobre seus dispositivos Comment[ru]=Просмотр информации о мобильных устройствах Comment[sk]=Zobraziť informácie o vašich zariadeniach Comment[sr]=Приказује податке о вашем телефону Comment[sr@ijekavian]=Приказује податке о вашем телефону Comment[sr@ijekavianlatin]=Prikazuje podatke o vašem telefonu Comment[sr@latin]=Prikazuje podatke o vašem telefonu Comment[sv]=Visa information om enheter Comment[tr]=Aygıtlarınız hakkında bilgi görüntüleyin Comment[uk]=Показати дані щодо ваших пристроїв Comment[x-test]=xxDisplay information about your devicesxx Comment[zh_CN]=显示您设备的信息 Comment[zh_TW]=顯示關於您的裝置資訊 Exec=kdeconnect-indicator Icon=kdeconnect Type=Application Terminal=false Categories=Qt;KDE;Network; NotShowIn=KDE; diff --git a/interfaces/dbusinterfaces.cpp b/interfaces/dbusinterfaces.cpp index d288f44d..d15702dd 100644 --- a/interfaces/dbusinterfaces.cpp +++ b/interfaces/dbusinterfaces.cpp @@ -1,168 +1,168 @@ /** * Copyright 2013 Albert Vaca * * 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 "dbusinterfaces.h" QString DaemonDbusInterface::activatedService() { static const QString service = QStringLiteral("org.kde.kdeconnect"); QDBusConnection::sessionBus().interface()->startService(service); if (!QDBusConnection::sessionBus().interface()->isValid()) { qWarning() << "error activating kdeconnectd:" << QDBusConnection::sessionBus().interface()->lastError(); } return service; } DaemonDbusInterface::DaemonDbusInterface(QObject* parent) : OrgKdeKdeconnectDaemonInterface(DaemonDbusInterface::activatedService(), QStringLiteral("/modules/kdeconnect"), QDBusConnection::sessionBus(), parent) { connect(this, &OrgKdeKdeconnectDaemonInterface::pairingRequestsChanged, this, &DaemonDbusInterface::pairingRequestsChangedProxy); } DaemonDbusInterface::~DaemonDbusInterface() { } DeviceDbusInterface::DeviceDbusInterface(const QString& id, QObject* parent) : OrgKdeKdeconnectDeviceInterface(DaemonDbusInterface::activatedService(), "/modules/kdeconnect/devices/"+id, QDBusConnection::sessionBus(), parent) , m_id(id) { connect(this, &OrgKdeKdeconnectDeviceInterface::trustedChanged, this, &DeviceDbusInterface::trustedChangedProxy); connect(this, &OrgKdeKdeconnectDeviceInterface::reachableChanged, this, &DeviceDbusInterface::reachableChangedProxy); connect(this, &OrgKdeKdeconnectDeviceInterface::nameChanged, this, &DeviceDbusInterface::nameChangedProxy); connect(this, &OrgKdeKdeconnectDeviceInterface::hasPairingRequestsChanged, this, &DeviceDbusInterface::hasPairingRequestsChangedProxy); } DeviceDbusInterface::~DeviceDbusInterface() { } QString DeviceDbusInterface::id() const { return m_id; } -void DeviceDbusInterface::pluginCall(const QString &plugin, const QString &method) +void DeviceDbusInterface::pluginCall(const QString& plugin, const QString& method) { QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.kde.kdeconnect"), "/modules/kdeconnect/devices/"+id()+'/'+plugin, "org.kde.kdeconnect.device."+plugin, method); QDBusConnection::sessionBus().asyncCall(msg); } DeviceBatteryDbusInterface::DeviceBatteryDbusInterface(const QString& id, QObject* parent) : OrgKdeKdeconnectDeviceBatteryInterface(DaemonDbusInterface::activatedService(), "/modules/kdeconnect/devices/"+id, QDBusConnection::sessionBus(), parent) { } DeviceBatteryDbusInterface::~DeviceBatteryDbusInterface() { } DeviceNotificationsDbusInterface::DeviceNotificationsDbusInterface(const QString& id, QObject* parent) : OrgKdeKdeconnectDeviceNotificationsInterface(DaemonDbusInterface::activatedService(), "/modules/kdeconnect/devices/"+id, QDBusConnection::sessionBus(), parent) { } DeviceNotificationsDbusInterface::~DeviceNotificationsDbusInterface() { } NotificationDbusInterface::NotificationDbusInterface(const QString& deviceId, const QString& notificationId, QObject* parent) : OrgKdeKdeconnectDeviceNotificationsNotificationInterface(DaemonDbusInterface::activatedService(), "/modules/kdeconnect/devices/"+deviceId+"/notifications/"+notificationId, QDBusConnection::sessionBus(), parent) , id(notificationId) { } NotificationDbusInterface::~NotificationDbusInterface() { } SftpDbusInterface::SftpDbusInterface(const QString& id, QObject* parent) : OrgKdeKdeconnectDeviceSftpInterface(DaemonDbusInterface::activatedService(), "/modules/kdeconnect/devices/" + id + "/sftp", QDBusConnection::sessionBus(), parent) { } SftpDbusInterface::~SftpDbusInterface() { } MprisDbusInterface::MprisDbusInterface(const QString& id, QObject* parent) : OrgKdeKdeconnectDeviceMprisremoteInterface(DaemonDbusInterface::activatedService(), "/modules/kdeconnect/devices/" + id + "/mprisremote", QDBusConnection::sessionBus(), parent) { connect(this, &OrgKdeKdeconnectDeviceMprisremoteInterface::propertiesChanged, this, &MprisDbusInterface::propertiesChangedProxy); } MprisDbusInterface::~MprisDbusInterface() { } RemoteControlDbusInterface::RemoteControlDbusInterface(const QString& id, QObject* parent) : OrgKdeKdeconnectDeviceRemotecontrolInterface(DaemonDbusInterface::activatedService(), "/modules/kdeconnect/devices/" + id + "/remotecontrol", QDBusConnection::sessionBus(), parent) { } RemoteControlDbusInterface::~RemoteControlDbusInterface() { } LockDeviceDbusInterface::LockDeviceDbusInterface(const QString& id, QObject* parent) : OrgKdeKdeconnectDeviceLockdeviceInterface(DaemonDbusInterface::activatedService(), "/modules/kdeconnect/devices/" + id + "/lockdevice", QDBusConnection::sessionBus(), parent) { connect(this, &OrgKdeKdeconnectDeviceLockdeviceInterface::lockedChanged, this, &LockDeviceDbusInterface::lockedChangedProxy); Q_ASSERT(isValid()); } LockDeviceDbusInterface::~LockDeviceDbusInterface() { } FindMyPhoneDeviceDbusInterface::FindMyPhoneDeviceDbusInterface(const QString& deviceId, QObject* parent): OrgKdeKdeconnectDeviceFindmyphoneInterface(DaemonDbusInterface::activatedService(), "/modules/kdeconnect/devices/" + deviceId + "/findmyphone", QDBusConnection::sessionBus(), parent) { } FindMyPhoneDeviceDbusInterface::~FindMyPhoneDeviceDbusInterface() { } RemoteCommandsDbusInterface::RemoteCommandsDbusInterface(const QString& deviceId, QObject* parent): OrgKdeKdeconnectDeviceRemotecommandsInterface(DaemonDbusInterface::activatedService(), "/modules/kdeconnect/devices/" + deviceId + "/remotecommands", QDBusConnection::sessionBus(), parent) { } RemoteCommandsDbusInterface::~RemoteCommandsDbusInterface() = default; RemoteKeyboardDbusInterface::RemoteKeyboardDbusInterface(const QString& deviceId, QObject* parent): OrgKdeKdeconnectDeviceRemotekeyboardInterface(DaemonDbusInterface::activatedService(), "/modules/kdeconnect/devices/" + deviceId + "/remotekeyboard", QDBusConnection::sessionBus(), parent) { connect(this, &OrgKdeKdeconnectDeviceRemotekeyboardInterface::remoteStateChanged, this, &RemoteKeyboardDbusInterface::remoteStateChanged); } RemoteKeyboardDbusInterface::~RemoteKeyboardDbusInterface() = default; #include "dbusinterfaces.moc" diff --git a/interfaces/dbusinterfaces.h b/interfaces/dbusinterfaces.h index 15bf84b8..4b2029d0 100644 --- a/interfaces/dbusinterfaces.h +++ b/interfaces/dbusinterfaces.h @@ -1,211 +1,211 @@ /** * Copyright 2013 Albert Vaca * * 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 DBUSINTERFACES_H #define DBUSINTERFACES_H #include "interfaces/kdeconnectinterfaces_export.h" #include "interfaces/daemoninterface.h" #include "interfaces/deviceinterface.h" #include "interfaces/devicebatteryinterface.h" #include "interfaces/devicesftpinterface.h" #include "interfaces/devicefindmyphoneinterface.h" #include "interfaces/devicenotificationsinterface.h" #include "interfaces/notificationinterface.h" #include "interfaces/mprisremoteinterface.h" #include "interfaces/remotecontrolinterface.h" #include "interfaces/lockdeviceinterface.h" #include "interfaces/remotecommandsinterface.h" #include "interfaces/remotekeyboardinterface.h" /** * Using these "proxy" classes just in case we need to rename the * interface, so we can change the class name in a single place. */ class KDECONNECTINTERFACES_EXPORT DaemonDbusInterface : public OrgKdeKdeconnectDaemonInterface { Q_OBJECT public: explicit DaemonDbusInterface(QObject* parent = nullptr); ~DaemonDbusInterface() override; static QString activatedService(); Q_SIGNALS: - void deviceAdded(const QString &id); + void deviceAdded(const QString& id); void pairingRequestsChangedProxy(); }; class KDECONNECTINTERFACES_EXPORT DeviceDbusInterface : public OrgKdeKdeconnectDeviceInterface { Q_OBJECT // TODO: Workaround because OrgKdeKdeconnectDeviceInterface is not generating // the signals for the properties Q_PROPERTY(bool isReachable READ isReachable NOTIFY reachableChangedProxy) Q_PROPERTY(bool isTrusted READ isTrusted NOTIFY trustedChangedProxy) Q_PROPERTY(QString name READ name NOTIFY nameChangedProxy) Q_PROPERTY(bool hasPairingRequests READ hasPairingRequests NOTIFY hasPairingRequestsChangedProxy) public: explicit DeviceDbusInterface(const QString& deviceId, QObject* parent = nullptr); ~DeviceDbusInterface() override; Q_SCRIPTABLE QString id() const; - Q_SCRIPTABLE void pluginCall(const QString &plugin, const QString &method); + Q_SCRIPTABLE void pluginCall(const QString& plugin, const QString& method); Q_SIGNALS: - void nameChangedProxy(const QString &name); + void nameChangedProxy(const QString& name); void trustedChangedProxy(bool paired); void reachableChangedProxy(bool reachable); void hasPairingRequestsChangedProxy(bool); private: const QString m_id; }; class KDECONNECTINTERFACES_EXPORT DeviceBatteryDbusInterface : public OrgKdeKdeconnectDeviceBatteryInterface { Q_OBJECT public: explicit DeviceBatteryDbusInterface(const QString& deviceId, QObject* parent = nullptr); ~DeviceBatteryDbusInterface() override; }; class KDECONNECTINTERFACES_EXPORT DeviceNotificationsDbusInterface : public OrgKdeKdeconnectDeviceNotificationsInterface { Q_OBJECT public: explicit DeviceNotificationsDbusInterface(const QString& deviceId, QObject* parent = nullptr); ~DeviceNotificationsDbusInterface() override; }; class KDECONNECTINTERFACES_EXPORT NotificationDbusInterface : public OrgKdeKdeconnectDeviceNotificationsNotificationInterface { Q_OBJECT public: NotificationDbusInterface(const QString& deviceId, const QString& notificationId, QObject* parent = nullptr); ~NotificationDbusInterface() override; QString notificationId() { return id; } private: const QString id; }; class KDECONNECTINTERFACES_EXPORT SftpDbusInterface : public OrgKdeKdeconnectDeviceSftpInterface { Q_OBJECT public: explicit SftpDbusInterface(const QString& deviceId, QObject* parent = nullptr); ~SftpDbusInterface() override; }; class KDECONNECTINTERFACES_EXPORT MprisDbusInterface : public OrgKdeKdeconnectDeviceMprisremoteInterface { Q_OBJECT // TODO: Workaround because qdbusxml2cpp is not generating // the signals for the properties Q_PROPERTY(bool isPlaying READ isPlaying NOTIFY propertiesChangedProxy) Q_PROPERTY(int length READ length NOTIFY propertiesChangedProxy) Q_PROPERTY(QString nowPlaying READ nowPlaying NOTIFY propertiesChangedProxy) Q_PROPERTY(QStringList playerList READ playerList NOTIFY propertiesChangedProxy) Q_PROPERTY(int volume READ volume WRITE setVolume NOTIFY propertiesChangedProxy) Q_PROPERTY(int position READ position WRITE setPosition NOTIFY propertiesChangedProxy) public: explicit MprisDbusInterface(const QString& deviceId, QObject* parent = nullptr); ~MprisDbusInterface() override; Q_SIGNALS: void propertiesChangedProxy(); }; class KDECONNECTINTERFACES_EXPORT RemoteControlDbusInterface : public OrgKdeKdeconnectDeviceRemotecontrolInterface { Q_OBJECT public: explicit RemoteControlDbusInterface(const QString& deviceId, QObject* parent = nullptr); ~RemoteControlDbusInterface() override; }; class KDECONNECTINTERFACES_EXPORT LockDeviceDbusInterface : public OrgKdeKdeconnectDeviceLockdeviceInterface { Q_OBJECT Q_PROPERTY(bool isLocked READ isLocked WRITE setIsLocked NOTIFY lockedChangedProxy) public: explicit LockDeviceDbusInterface(const QString& deviceId, QObject* parent = nullptr); ~LockDeviceDbusInterface() override; Q_SIGNALS: void lockedChangedProxy(bool isLocked); }; class KDECONNECTINTERFACES_EXPORT FindMyPhoneDeviceDbusInterface : public OrgKdeKdeconnectDeviceFindmyphoneInterface { Q_OBJECT public: explicit FindMyPhoneDeviceDbusInterface(const QString& deviceId, QObject* parent = nullptr); ~FindMyPhoneDeviceDbusInterface() override; }; class KDECONNECTINTERFACES_EXPORT RemoteCommandsDbusInterface : public OrgKdeKdeconnectDeviceRemotecommandsInterface { Q_OBJECT public: explicit RemoteCommandsDbusInterface(const QString& deviceId, QObject* parent = nullptr); ~RemoteCommandsDbusInterface() override; }; class KDECONNECTINTERFACES_EXPORT RemoteKeyboardDbusInterface : public OrgKdeKdeconnectDeviceRemotekeyboardInterface { Q_OBJECT Q_PROPERTY(bool remoteState READ remoteState NOTIFY remoteStateChanged) public: explicit RemoteKeyboardDbusInterface(const QString& deviceId, QObject* parent = nullptr); ~RemoteKeyboardDbusInterface() override; Q_SIGNALS: void remoteStateChanged(bool state); }; template -static void setWhenAvailable(const QDBusPendingReply &pending, W func, QObject* parent) +static void setWhenAvailable(const QDBusPendingReply& pending, W func, QObject* parent) { - QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pending, parent); + QDBusPendingCallWatcher* watcher = new QDBusPendingCallWatcher(pending, parent); QObject::connect(watcher, &QDBusPendingCallWatcher::finished, parent, [func](QDBusPendingCallWatcher* watcher) { watcher->deleteLater(); QDBusPendingReply reply = *watcher; func(reply.value()); }); } #endif diff --git a/interfaces/devicesmodel.cpp b/interfaces/devicesmodel.cpp index cb0da81a..baafd3fe 100644 --- a/interfaces/devicesmodel.cpp +++ b/interfaces/devicesmodel.cpp @@ -1,314 +1,314 @@ /** * Copyright 2013 Albert Vaca * * 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 "devicesmodel.h" #include "interfaces_debug.h" #include #include #include #include #include #include #include "dbusinterfaces.h" // #include "modeltest.h" Q_LOGGING_CATEGORY(KDECONNECT_INTERFACES, "kdeconnect.interfaces"); static QString createId() { return QCoreApplication::instance()->applicationName()+QString::number(QCoreApplication::applicationPid()); } Q_GLOBAL_STATIC_WITH_ARGS(QString, s_keyId, (createId())); -DevicesModel::DevicesModel(QObject *parent) +DevicesModel::DevicesModel(QObject* parent) : QAbstractListModel(parent) , m_dbusInterface(new DaemonDbusInterface(this)) , m_displayFilter(StatusFilterFlag::NoFilter) { //new ModelTest(this, this); connect(this, &QAbstractItemModel::rowsRemoved, this, &DevicesModel::rowsChanged); connect(this, &QAbstractItemModel::rowsInserted, this, &DevicesModel::rowsChanged); connect(m_dbusInterface, SIGNAL(deviceAdded(QString)), this, SLOT(deviceAdded(QString))); connect(m_dbusInterface, &OrgKdeKdeconnectDaemonInterface::deviceVisibilityChanged, this, &DevicesModel::deviceUpdated); connect(m_dbusInterface, &OrgKdeKdeconnectDaemonInterface::deviceRemoved, this, &DevicesModel::deviceRemoved); QDBusServiceWatcher* watcher = new QDBusServiceWatcher(DaemonDbusInterface::activatedService(), QDBusConnection::sessionBus(), QDBusServiceWatcher::WatchForOwnerChange, this); connect(watcher, &QDBusServiceWatcher::serviceRegistered, this, &DevicesModel::refreshDeviceList); connect(watcher, &QDBusServiceWatcher::serviceUnregistered, this, &DevicesModel::clearDevices); //refresh the view, acquireDiscoveryMode if necessary setDisplayFilter(NoFilter); } QHash< int, QByteArray > DevicesModel::roleNames() const { QHash names = QAbstractItemModel::roleNames(); names.insert(IdModelRole, "deviceId"); names.insert(IconNameRole, "iconName"); names.insert(DeviceRole, "device"); names.insert(StatusModelRole, "status"); return names; } DevicesModel::~DevicesModel() { m_dbusInterface->releaseDiscoveryMode(*s_keyId); } int DevicesModel::rowForDevice(const QString& id) const { for (int i = 0, c=m_deviceList.size(); iid() == id) { return i; } } return -1; } void DevicesModel::deviceAdded(const QString& id) { if (rowForDevice(id) >= 0) { Q_ASSERT_X(false, "deviceAdded", "Trying to add a device twice"); return; } DeviceDbusInterface* dev = new DeviceDbusInterface(id, this); Q_ASSERT(dev->isValid()); if (! passesFilter(dev)) { delete dev; return; } beginInsertRows(QModelIndex(), m_deviceList.size(), m_deviceList.size()); appendDevice(dev); endInsertRows(); } void DevicesModel::deviceRemoved(const QString& id) { int row = rowForDevice(id); if (row>=0) { beginRemoveRows(QModelIndex(), row, row); delete m_deviceList.takeAt(row); endRemoveRows(); } } void DevicesModel::deviceUpdated(const QString& id, bool isVisible) { Q_UNUSED(isVisible); int row = rowForDevice(id); if (row < 0) { // FIXME: when m_dbusInterface is not valid refreshDeviceList() does // nothing and we can miss some devices. // Someone can reproduce this problem by restarting kdeconnectd while // kdeconnect's plasmoid is still running. // Another reason for this branch is that we removed the device previously // because of the filter settings. qCDebug(KDECONNECT_INTERFACES) << "Adding missing or previously removed device" << id; deviceAdded(id); } else { - DeviceDbusInterface *dev = getDevice(row); + DeviceDbusInterface* dev = getDevice(row); if (! passesFilter(dev)) { beginRemoveRows(QModelIndex(), row, row); delete m_deviceList.takeAt(row); endRemoveRows(); qCDebug(KDECONNECT_INTERFACES) << "Removed changed device " << id; } else { const QModelIndex idx = index(row); Q_EMIT dataChanged(idx, idx); } } } int DevicesModel::displayFilter() const { return m_displayFilter; } void DevicesModel::setDisplayFilter(int flags) { m_displayFilter = (StatusFilterFlag)flags; const bool reachableNeeded = (m_displayFilter & StatusFilterFlag::Reachable); if (reachableNeeded) m_dbusInterface->acquireDiscoveryMode(*s_keyId); else m_dbusInterface->releaseDiscoveryMode(*s_keyId); refreshDeviceList(); } void DevicesModel::refreshDeviceList() { if (!m_dbusInterface->isValid()) { clearDevices(); qCWarning(KDECONNECT_INTERFACES) << "dbus interface not valid"; return; } bool onlyPaired = (m_displayFilter & StatusFilterFlag::Paired); bool onlyReachable = (m_displayFilter & StatusFilterFlag::Reachable); QDBusPendingReply pendingDeviceIds = m_dbusInterface->devices(onlyReachable, onlyPaired); - QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingDeviceIds, this); + QDBusPendingCallWatcher* watcher = new QDBusPendingCallWatcher(pendingDeviceIds, this); QObject::connect(watcher, &QDBusPendingCallWatcher::finished, this, &DevicesModel::receivedDeviceList); } void DevicesModel::receivedDeviceList(QDBusPendingCallWatcher* watcher) { watcher->deleteLater(); clearDevices(); QDBusPendingReply pendingDeviceIds = *watcher; if (pendingDeviceIds.isError()) { qCWarning(KDECONNECT_INTERFACES) << "error while refreshing device list" << pendingDeviceIds.error().message(); return; } Q_ASSERT(m_deviceList.isEmpty()); const QStringList deviceIds = pendingDeviceIds.value(); if (deviceIds.isEmpty()) return; beginInsertRows(QModelIndex(), 0, deviceIds.count()-1); for (const QString& id : deviceIds) { appendDevice(new DeviceDbusInterface(id, this)); } endInsertRows(); } void DevicesModel::appendDevice(DeviceDbusInterface* dev) { m_deviceList.append(dev); connect(dev, &OrgKdeKdeconnectDeviceInterface::nameChanged, this, &DevicesModel::nameChanged); } void DevicesModel::nameChanged(const QString& newName) { Q_UNUSED(newName); DeviceDbusInterface* device = static_cast(sender()); Q_ASSERT(rowForDevice(device->id()) >= 0); deviceUpdated(device->id(), true); } void DevicesModel::clearDevices() { if (!m_deviceList.isEmpty()) { beginRemoveRows(QModelIndex(), 0, m_deviceList.size() - 1); qDeleteAll(m_deviceList); m_deviceList.clear(); endRemoveRows(); } } QVariant DevicesModel::data(const QModelIndex& index, int role) const { if (!index.isValid() || index.row() < 0 || index.row() >= m_deviceList.size()) { return QVariant(); } Q_ASSERT(m_dbusInterface->isValid()); DeviceDbusInterface* device = m_deviceList[index.row()]; Q_ASSERT(device->isValid()); //This function gets called lots of times, producing lots of dbus calls. Add a cache? switch (role) { case Qt::SizeHintRole: return QSize(0, 32); case IconModelRole: { QString icon = data(index, IconNameRole).toString(); return QIcon::fromTheme(icon); } case IdModelRole: return device->id(); case NameModelRole: return device->name(); case Qt::ToolTipRole: { bool trusted = device->isTrusted(); bool reachable = device->isReachable(); QString status = reachable? (trusted? i18n("Device trusted and connected") : i18n("Device not trusted")) : i18n("Device disconnected"); return status; } case StatusModelRole: { int status = StatusFilterFlag::NoFilter; if (device->isReachable()) { status |= StatusFilterFlag::Reachable; } if (device->isTrusted()) { status |= StatusFilterFlag::Paired; } return status; } case IconNameRole: return device->statusIconName(); case DeviceRole: return QVariant::fromValue(device); default: return QVariant(); } } DeviceDbusInterface* DevicesModel::getDevice(int row) const { if (row < 0 || row >= m_deviceList.size()) { return nullptr; } return m_deviceList[row]; } int DevicesModel::rowCount(const QModelIndex& parent) const { if(parent.isValid()) { //Return size 0 if we are a child because this is not a tree return 0; } return m_deviceList.size(); } bool DevicesModel::passesFilter(DeviceDbusInterface* dev) const { bool onlyPaired = (m_displayFilter & StatusFilterFlag::Paired); bool onlyReachable = (m_displayFilter & StatusFilterFlag::Reachable); return !((onlyReachable && !dev->isReachable()) || (onlyPaired && !dev->isTrusted())); } diff --git a/interfaces/devicesmodel.h b/interfaces/devicesmodel.h index 28014b67..f208136f 100644 --- a/interfaces/devicesmodel.h +++ b/interfaces/devicesmodel.h @@ -1,99 +1,99 @@ /** * Copyright 2013 Albert Vaca * * 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 DEVICESMODEL_H #define DEVICESMODEL_H #include #include #include #include "interfaces/kdeconnectinterfaces_export.h" class QDBusPendingCallWatcher; class DaemonDbusInterface; class DeviceDbusInterface; class KDECONNECTINTERFACES_EXPORT DevicesModel : public QAbstractListModel { Q_OBJECT Q_PROPERTY(int displayFilter READ displayFilter WRITE setDisplayFilter) Q_PROPERTY(int count READ rowCount NOTIFY rowsChanged) public: enum ModelRoles { NameModelRole = Qt::DisplayRole, IconModelRole = Qt::DecorationRole, StatusModelRole = Qt::InitialSortOrderRole, IdModelRole = Qt::UserRole, IconNameRole, DeviceRole }; Q_ENUM(ModelRoles); // A device is always paired or reachable or both // You can combine the Paired and Reachable flags enum StatusFilterFlag { NoFilter = 0x00, Paired = 0x01, // show device only if it's paired Reachable = 0x02 // show device only if it's reachable }; Q_DECLARE_FLAGS(StatusFilterFlags, StatusFilterFlag) Q_FLAGS(StatusFilterFlags) Q_ENUM(StatusFilterFlag) - explicit DevicesModel(QObject *parent = nullptr); + explicit DevicesModel(QObject* parent = nullptr); ~DevicesModel() override; void setDisplayFilter(int flags); int displayFilter() const; QVariant data(const QModelIndex& index, int role) const override; int rowCount(const QModelIndex& parent = QModelIndex()) const override; Q_SCRIPTABLE DeviceDbusInterface* getDevice(int row) const; QHash roleNames() const override; private Q_SLOTS: void deviceAdded(const QString& id); void deviceRemoved(const QString& id); void deviceUpdated(const QString& id, bool isVisible); void refreshDeviceList(); void receivedDeviceList(QDBusPendingCallWatcher* watcher); void nameChanged(const QString& newName); Q_SIGNALS: void rowsChanged(); private: int rowForDevice(const QString& id) const; void clearDevices(); void appendDevice(DeviceDbusInterface* dev); - bool passesFilter(DeviceDbusInterface *dev) const; + bool passesFilter(DeviceDbusInterface* dev) const; DaemonDbusInterface* m_dbusInterface; QVector m_deviceList; StatusFilterFlag m_displayFilter; }; //Q_DECLARE_OPERATORS_FOR_FLAGS(DevicesModel::StatusFilterFlag) #endif // DEVICESMODEL_H diff --git a/interfaces/devicessortproxymodel.cpp b/interfaces/devicessortproxymodel.cpp index 979e751f..688ae9ca 100644 --- a/interfaces/devicessortproxymodel.cpp +++ b/interfaces/devicessortproxymodel.cpp @@ -1,74 +1,74 @@ /** * Copyright 2013 Albert Vaca * * 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 "devicessortproxymodel.h" #include #include DevicesSortProxyModel::DevicesSortProxyModel(DevicesModel* devicesModel) : QSortFilterProxyModel(devicesModel) { setSourceModel(devicesModel); } -void DevicesSortProxyModel::setSourceModel(QAbstractItemModel *devicesModel) +void DevicesSortProxyModel::setSourceModel(QAbstractItemModel* devicesModel) { QSortFilterProxyModel::setSourceModel(devicesModel); if (devicesModel) { setSortRole(DevicesModel::StatusModelRole); connect(devicesModel, &QAbstractItemModel::dataChanged, this, &DevicesSortProxyModel::sourceDataChanged); } sort(0); } void DevicesSortProxyModel::sourceDataChanged() { sort(0); } bool DevicesSortProxyModel::lessThan(const QModelIndex& left, const QModelIndex& right) const { QAbstractItemModel* model = sourceModel(); Q_ASSERT(qobject_cast(model)); //Show connected devices first int statusLeft = model->data(left, DevicesModel::StatusModelRole).toInt(); int statusRight = model->data(right, DevicesModel::StatusModelRole).toInt(); if (statusLeft != statusRight) { return statusLeft > statusRight; } //Fallback to alphabetical order QString nameLeft = model->data(left, DevicesModel::NameModelRole).toString(); QString nameRight = model->data(right, DevicesModel::NameModelRole).toString(); return nameLeft > nameRight; } bool DevicesSortProxyModel::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const { Q_UNUSED(source_row); Q_UNUSED(source_parent); //Possible to-do: Implement filter return true; } diff --git a/interfaces/devicessortproxymodel.h b/interfaces/devicessortproxymodel.h index 501a9d3e..c5ccaf55 100644 --- a/interfaces/devicessortproxymodel.h +++ b/interfaces/devicessortproxymodel.h @@ -1,42 +1,42 @@ /** * Copyright 2013 Albert Vaca * * 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 DEVICESSORTPROXYMODEL_H #define DEVICESSORTPROXYMODEL_H #include #include "interfaces/kdeconnectinterfaces_export.h" class DevicesModel; class KDECONNECTINTERFACES_EXPORT DevicesSortProxyModel : public QSortFilterProxyModel { Q_OBJECT public: explicit DevicesSortProxyModel(DevicesModel* devicesModel = Q_NULLPTR); bool lessThan(const QModelIndex& left, const QModelIndex& right) const override; bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const override; - void setSourceModel(QAbstractItemModel *sourceModel) override; + void setSourceModel(QAbstractItemModel* sourceModel) override; public Q_SLOTS: void sourceDataChanged(); }; #endif // DEVICESSORTPROXYMODEL_H diff --git a/interfaces/modeltest.cpp b/interfaces/modeltest.cpp index 3305bf1d..c3c86aeb 100644 --- a/interfaces/modeltest.cpp +++ b/interfaces/modeltest.cpp @@ -1,539 +1,539 @@ /**************************************************************************** ** ** Copyright (C) 2007 Trolltech ASA. All rights reserved. ** ** This file is part of the Qt Concurrent project on Trolltech Labs. ** ** This file may be used under the terms of the GNU General Public ** License version 2.0 as published by the Free Software Foundation ** and appearing in the file LICENSE.GPL included in the packaging of ** this file. Please review the following information to ensure GNU ** General Public Licensing requirements will be met: ** http://www.trolltech.com/products/qt/opensource.html ** ** If you are unsure which license is appropriate for your use, please ** review the following information: ** http://www.trolltech.com/products/qt/licensing.html or contact the ** sales department at sales@trolltech.com. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ****************************************************************************/ #include "modeltest.h" #include Q_DECLARE_METATYPE(QModelIndex) /*! Connect to all of the models signals. Whenever anything happens recheck everything. */ -ModelTest::ModelTest(QAbstractItemModel *_model, QObject *parent) : QObject(parent), model(_model), fetchingMore(false) +ModelTest::ModelTest(QAbstractItemModel *_model, QObject* parent) : QObject(parent), model(_model), fetchingMore(false) { Q_ASSERT(model); connect(model, SIGNAL(columnsAboutToBeInserted(QModelIndex,int,int)), this, SLOT(runAllTests())); connect(model, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)), this, SLOT(runAllTests())); connect(model, SIGNAL(columnsInserted(QModelIndex,int,int)), this, SLOT(runAllTests())); connect(model, SIGNAL(columnsRemoved(QModelIndex,int,int)), this, SLOT(runAllTests())); connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(runAllTests())); connect(model, SIGNAL(headerDataChanged(Qt::Orientation,int,int)), this, SLOT(runAllTests())); connect(model, SIGNAL(layoutAboutToBeChanged()), this, SLOT(runAllTests())); connect(model, SIGNAL(layoutChanged()), this, SLOT(runAllTests())); connect(model, SIGNAL(modelReset()), this, SLOT(runAllTests())); connect(model, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)), this, SLOT(runAllTests())); connect(model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), this, SLOT(runAllTests())); connect(model, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(runAllTests())); connect(model, SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SLOT(runAllTests())); // Special checks for inserting/removing connect(model, SIGNAL(layoutAboutToBeChanged()), this, SLOT(layoutAboutToBeChanged())); connect(model, SIGNAL(layoutChanged()), this, SLOT(layoutChanged())); connect(model, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)), this, SLOT(rowsAboutToBeInserted(QModelIndex,int,int))); connect(model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), this, SLOT(rowsAboutToBeRemoved(QModelIndex,int,int))); connect(model, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(rowsInserted(QModelIndex,int,int))); connect(model, SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SLOT(rowsRemoved(QModelIndex,int,int))); runAllTests(); } void ModelTest::runAllTests() { if (fetchingMore) return; nonDestructiveBasicTest(); rowCount(); columnCount(); hasIndex(); index(); parent(); data(); } /*! nonDestructiveBasicTest tries to call a number of the basic functions (not all) to make sure the model doesn't outright segfault, testing the functions that makes sense. */ void ModelTest::nonDestructiveBasicTest() { Q_ASSERT(model->buddy(QModelIndex()) == QModelIndex()); model->canFetchMore(QModelIndex()); Q_ASSERT(model->columnCount(QModelIndex()) >= 0); Q_ASSERT(model->data(QModelIndex()) == QVariant()); fetchingMore = true; model->fetchMore(QModelIndex()); fetchingMore = false; Qt::ItemFlags flags = model->flags(QModelIndex()); Q_ASSERT(flags == Qt::ItemIsDropEnabled || flags == 0); model->hasChildren(QModelIndex()); model->hasIndex(0, 0); model->headerData(0, Qt::Horizontal); model->index(0, 0); Q_ASSERT(model->index(-1, -1) == QModelIndex()); model->itemData(QModelIndex()); QVariant cache; model->match(QModelIndex(), -1, cache); model->mimeTypes(); Q_ASSERT(model->parent(QModelIndex()) == QModelIndex()); Q_ASSERT(model->rowCount() >= 0); QVariant variant; model->setData(QModelIndex(), variant, -1); model->setHeaderData(-1, Qt::Horizontal, QVariant()); model->setHeaderData(0, Qt::Horizontal, QVariant()); model->setHeaderData(999999, Qt::Horizontal, QVariant()); QMap roles; model->sibling(0, 0, QModelIndex()); model->span(QModelIndex()); model->supportedDropActions(); } /*! Tests model's implementation of QAbstractItemModel::rowCount() and hasChildren() Models that are dynamically populated are not as fully tested here. */ void ModelTest::rowCount() { // check top row QModelIndex topIndex = model->index(0, 0, QModelIndex()); int rows = model->rowCount(topIndex); Q_ASSERT(rows >= 0); if (rows > 0) Q_ASSERT(model->hasChildren(topIndex) == true); QModelIndex secondLevelIndex = model->index(0, 0, topIndex); if (secondLevelIndex.isValid()) { // not the top level // check a row count where parent is valid rows = model->rowCount(secondLevelIndex); Q_ASSERT(rows >= 0); if (rows > 0) Q_ASSERT(model->hasChildren(secondLevelIndex) == true); } // The models rowCount() is tested more extensively in checkChildren(), // but this catches the big mistakes } /*! Tests model's implementation of QAbstractItemModel::columnCount() and hasChildren() */ void ModelTest::columnCount() { // check top row QModelIndex topIndex = model->index(0, 0, QModelIndex()); Q_ASSERT(model->columnCount(topIndex) >= 0); // check a column count where parent is valid QModelIndex childIndex = model->index(0, 0, topIndex); if (childIndex.isValid()) Q_ASSERT(model->columnCount(childIndex) >= 0); // columnCount() is tested more extensively in checkChildren(), // but this catches the big mistakes } /*! Tests model's implementation of QAbstractItemModel::hasIndex() */ void ModelTest::hasIndex() { // Make sure that invalid values returns an invalid index Q_ASSERT(model->hasIndex(-2, -2) == false); Q_ASSERT(model->hasIndex(-2, 0) == false); Q_ASSERT(model->hasIndex(0, -2) == false); int rows = model->rowCount(); int columns = model->columnCount(); // check out of bounds Q_ASSERT(model->hasIndex(rows, columns) == false); Q_ASSERT(model->hasIndex(rows + 1, columns + 1) == false); if (rows > 0) Q_ASSERT(model->hasIndex(0, 0) == true); // hasIndex() is tested more extensively in checkChildren(), // but this catches the big mistakes } /*! Tests model's implementation of QAbstractItemModel::index() */ void ModelTest::index() { // Make sure that invalid values returns an invalid index Q_ASSERT(model->index(-2, -2) == QModelIndex()); Q_ASSERT(model->index(-2, 0) == QModelIndex()); Q_ASSERT(model->index(0, -2) == QModelIndex()); int rows = model->rowCount(); int columns = model->columnCount(); if (rows == 0) return; // Catch off by one errors Q_ASSERT(model->index(rows, columns) == QModelIndex()); Q_ASSERT(model->index(0, 0).isValid() == true); - // Make sure that the same index is *always* returned + // Make sure that the same index is* always* returned QModelIndex a = model->index(0, 0); QModelIndex b = model->index(0, 0); Q_ASSERT(a == b); // index() is tested more extensively in checkChildren(), // but this catches the big mistakes } /*! Tests model's implementation of QAbstractItemModel::parent() */ void ModelTest::parent() { // Make sure the model wont crash and will return an invalid QModelIndex // when asked for the parent of an invalid index. Q_ASSERT(model->parent(QModelIndex()) == QModelIndex()); if (model->rowCount() == 0) return; // Column 0 | Column 1 | // QModelIndex() | | // \- topIndex | topIndex1 | // \- childIndex | childIndex1 | // Common error test #1, make sure that a top level index has a parent // that is a invalid QModelIndex. QModelIndex topIndex = model->index(0, 0, QModelIndex()); Q_ASSERT(model->parent(topIndex) == QModelIndex()); // Common error test #2, make sure that a second level index has a parent // that is the first level index. if (model->rowCount(topIndex) > 0) { QModelIndex childIndex = model->index(0, 0, topIndex); Q_ASSERT(model->parent(childIndex) == topIndex); } // Common error test #3, the second column should NOT have the same children // as the first column in a row. // Usually the second column shouldn't have children. QModelIndex topIndex1 = model->index(0, 1, QModelIndex()); if (model->rowCount(topIndex1) > 0) { QModelIndex childIndex = model->index(0, 0, topIndex); QModelIndex childIndex1 = model->index(0, 0, topIndex1); Q_ASSERT(childIndex != childIndex1); } // Full test, walk n levels deep through the model making sure that all // parent's children correctly specify their parent. checkChildren(QModelIndex()); } /*! Called from the parent() test. A model that returns an index of parent X should also return X when asking for the parent of the index. This recursive function does pretty extensive testing on the whole model in an effort to catch edge cases. This function assumes that rowCount(), columnCount() and index() already work. If they have a bug it will point it out, but the above tests should have already found the basic bugs because it is easier to figure out the problem in those tests then this one. */ void ModelTest::checkChildren(const QModelIndex &parent, int currentDepth) { // First just try walking back up the tree. QModelIndex p = parent; while (p.isValid()) p = p.parent(); // For models that are dynamically populated if (model->canFetchMore(parent)) { fetchingMore = true; model->fetchMore(parent); fetchingMore = false; } int rows = model->rowCount(parent); int columns = model->columnCount(parent); if (rows > 0) Q_ASSERT(model->hasChildren(parent)); // Some further testing against rows(), columns(), and hasChildren() Q_ASSERT(rows >= 0); Q_ASSERT(columns >= 0); if (rows > 0) Q_ASSERT(model->hasChildren(parent) == true); //qDebug() << "parent:" << model->data(parent).toString() << "rows:" << rows // << "columns:" << columns << "parent column:" << parent.column(); Q_ASSERT(model->hasIndex(rows + 1, 0, parent) == false); for (int r = 0; r < rows; ++r) { if (model->canFetchMore(parent)) { fetchingMore = true; model->fetchMore(parent); fetchingMore = false; } Q_ASSERT(model->hasIndex(r, columns + 1, parent) == false); for (int c = 0; c < columns; ++c) { Q_ASSERT(model->hasIndex(r, c, parent) == true); QModelIndex index = model->index(r, c, parent); // rowCount() and columnCount() said that it existed... Q_ASSERT(index.isValid() == true); // index() should always return the same index when called twice in a row QModelIndex modifiedIndex = model->index(r, c, parent); Q_ASSERT(index == modifiedIndex); // Make sure we get the same index if we request it twice in a row QModelIndex a = model->index(r, c, parent); QModelIndex b = model->index(r, c, parent); Q_ASSERT(a == b); // Some basic checking on the index that is returned Q_ASSERT(index.model() == model); Q_ASSERT(index.row() == r); Q_ASSERT(index.column() == c); // While you can technically return a QVariant usually this is a sign // of an bug in data() Disable if this really is ok in your model. //Q_ASSERT(model->data(index, Qt::DisplayRole).isValid() == true); // If the next test fails here is some somewhat useful debug you play with. /* if (model->parent(index) != parent) { qDebug() << r << c << currentDepth << model->data(index).toString() << model->data(parent).toString(); qDebug() << index << parent << model->parent(index); // And a view that you can even use to show the model. //QTreeView view; //view.setModel(model); //view.show(); }*/ // Check that we can get back our real parent. QModelIndex p = model->parent(index); //qDebug() << "child:" << index; //qDebug() << p; //qDebug() << parent; Q_ASSERT(p == parent); // recursively go down the children if (model->hasChildren(index) && currentDepth < 10 ) { //qDebug() << r << c << "has children" << model->rowCount(index); checkChildren(index, ++currentDepth); }/* else { if (currentDepth >= 10) qDebug() << "checked 10 deep"; };*/ // make sure that after testing the children that the index doesn't change. QModelIndex newerIndex = model->index(r, c, parent); Q_ASSERT(index == newerIndex); } } } /*! Tests model's implementation of QAbstractItemModel::data() */ void ModelTest::data() { // Invalid index should return an invalid qvariant Q_ASSERT(!model->data(QModelIndex()).isValid()); if (model->rowCount() == 0) return; // A valid index should have a valid QVariant data Q_ASSERT(model->index(0, 0).isValid()); // shouldn't be able to set data on an invalid index Q_ASSERT(model->setData(QModelIndex(), QLatin1String("foo"), Qt::DisplayRole) == false); // General Purpose roles that should return a QString QVariant variant = model->data(model->index(0, 0), Qt::ToolTipRole); if (variant.isValid()) { Q_ASSERT(variant.canConvert()); } variant = model->data(model->index(0, 0), Qt::StatusTipRole); if (variant.isValid()) { Q_ASSERT(variant.canConvert()); } variant = model->data(model->index(0, 0), Qt::WhatsThisRole); if (variant.isValid()) { Q_ASSERT(variant.canConvert()); } // General Purpose roles that should return a QSize variant = model->data(model->index(0, 0), Qt::SizeHintRole); if (variant.isValid()) { Q_ASSERT(variant.canConvert()); } // General Purpose roles that should return a QFont QVariant fontVariant = model->data(model->index(0, 0), Qt::FontRole); if (fontVariant.isValid()) { Q_ASSERT(fontVariant.canConvert()); } // Check that the alignment is one we know about QVariant textAlignmentVariant = model->data(model->index(0, 0), Qt::TextAlignmentRole); if (textAlignmentVariant.isValid()) { int alignment = textAlignmentVariant.toInt(); Q_ASSERT(alignment == Qt::AlignLeft || alignment == Qt::AlignRight || alignment == Qt::AlignHCenter || alignment == Qt::AlignJustify || alignment == Qt::AlignTop || alignment == Qt::AlignBottom || alignment == Qt::AlignVCenter || alignment == Qt::AlignCenter || alignment == Qt::AlignAbsolute || alignment == Qt::AlignLeading || alignment == Qt::AlignTrailing); } // General Purpose roles that should return a QColor QVariant colorVariant = model->data(model->index(0, 0), Qt::BackgroundColorRole); if (colorVariant.isValid()) { Q_ASSERT(colorVariant.canConvert()); } colorVariant = model->data(model->index(0, 0), Qt::TextColorRole); if (colorVariant.isValid()) { Q_ASSERT(colorVariant.canConvert()); } // Check that the "check state" is one we know about. QVariant checkStateVariant = model->data(model->index(0, 0), Qt::CheckStateRole); if (checkStateVariant.isValid()) { int state = checkStateVariant.toInt(); Q_ASSERT(state == Qt::Unchecked || state == Qt::PartiallyChecked || state == Qt::Checked); } } /*! Store what is about to be inserted to make sure it actually happens \sa rowsInserted() */ void ModelTest::rowsAboutToBeInserted(const QModelIndex &parent, int start, int end) { Q_UNUSED(end); Changing c; c.parent = parent; c.oldSize = model->rowCount(parent); c.last = model->data(model->index(start - 1, 0, parent)); c.next = model->data(model->index(start, 0, parent)); insert.push(c); } /*! Confirm that what was said was going to happen actually did \sa rowsAboutToBeInserted() */ void ModelTest::rowsInserted(const QModelIndex & parent, int start, int end) { Changing c = insert.pop(); Q_ASSERT(c.parent == parent); Q_ASSERT(c.oldSize + (end - start + 1) == model->rowCount(parent)); Q_ASSERT(c.last == model->data(model->index(start - 1, 0, c.parent))); /* if (c.next != model->data(model->index(end + 1, 0, c.parent))) { qDebug() << start << end; for (int i=0; i < model->rowCount(); ++i) qDebug() << model->index(i, 0).data().toString(); qDebug() << c.next << model->data(model->index(end + 1, 0, c.parent)); } */ Q_ASSERT(c.next == model->data(model->index(end + 1, 0, c.parent))); } void ModelTest::layoutAboutToBeChanged() { for (int i = 0; i < qBound(0, model->rowCount(), 100); ++i) changing.append(QPersistentModelIndex(model->index(i, 0))); } void ModelTest::layoutChanged() { for (int i = 0; i < changing.count(); ++i) { QPersistentModelIndex p = changing[i]; Q_ASSERT(p == model->index(p.row(), p.column(), p.parent())); } changing.clear(); } /*! Store what is about to be inserted to make sure it actually happens \sa rowsRemoved() */ void ModelTest::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end) { Changing c; c.parent = parent; c.oldSize = model->rowCount(parent); c.last = model->data(model->index(start - 1, 0, parent)); c.next = model->data(model->index(end + 1, 0, parent)); remove.push(c); } /*! Confirm that what was said was going to happen actually did \sa rowsAboutToBeRemoved() */ void ModelTest::rowsRemoved(const QModelIndex & parent, int start, int end) { Changing c = remove.pop(); Q_ASSERT(c.parent == parent); Q_ASSERT(c.oldSize - (end - start + 1) == model->rowCount(parent)); Q_ASSERT(c.last == model->data(model->index(start - 1, 0, c.parent))); Q_ASSERT(c.next == model->data(model->index(start, 0, c.parent))); } diff --git a/interfaces/modeltest.h b/interfaces/modeltest.h index 80a294be..befe270e 100644 --- a/interfaces/modeltest.h +++ b/interfaces/modeltest.h @@ -1,76 +1,76 @@ /**************************************************************************** ** ** Copyright (C) 2007 Trolltech ASA. All rights reserved. ** ** This file is part of the Qt Concurrent project on Trolltech Labs. ** ** This file may be used under the terms of the GNU General Public ** License version 2.0 as published by the Free Software Foundation ** and appearing in the file LICENSE.GPL included in the packaging of ** this file. Please review the following information to ensure GNU ** General Public Licensing requirements will be met: ** http://www.trolltech.com/products/qt/opensource.html ** ** If you are unsure which license is appropriate for your use, please ** review the following information: ** http://www.trolltech.com/products/qt/licensing.html or contact the ** sales department at sales@trolltech.com. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ****************************************************************************/ #ifndef MODELTEST_H #define MODELTEST_H #include #include #include class ModelTest : public QObject { Q_OBJECT public: - explicit ModelTest(QAbstractItemModel *model, QObject *parent = 0); + explicit ModelTest(QAbstractItemModel* model, QObject* parent = 0); private Q_SLOTS: void nonDestructiveBasicTest(); void rowCount(); void columnCount(); void hasIndex(); void index(); void parent(); void data(); protected Q_SLOTS: void runAllTests(); void layoutAboutToBeChanged(); void layoutChanged(); - void rowsAboutToBeInserted(const QModelIndex &parent, int start, int end); + void rowsAboutToBeInserted(const QModelIndex& parent, int start, int end); void rowsInserted(const QModelIndex & parent, int start, int end); - void rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end); + void rowsAboutToBeRemoved(const QModelIndex& parent, int start, int end); void rowsRemoved(const QModelIndex & parent, int start, int end); private: - void checkChildren(const QModelIndex &parent, int currentDepth = 0); + void checkChildren(const QModelIndex& parent, int currentDepth = 0); - QAbstractItemModel *model; + QAbstractItemModel* model; struct Changing { QModelIndex parent; int oldSize; QVariant last; QVariant next; }; QStack insert; QStack remove; bool fetchingMore; QList changing; }; #endif diff --git a/interfaces/notificationsmodel.cpp b/interfaces/notificationsmodel.cpp index 5c8c0922..2edaa19b 100644 --- a/interfaces/notificationsmodel.cpp +++ b/interfaces/notificationsmodel.cpp @@ -1,263 +1,263 @@ /** * Copyright 2013 Albert Vaca * * 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 "notificationsmodel.h" #include "interfaces_debug.h" #include #include #include #include //#include "modeltest.h" NotificationsModel::NotificationsModel(QObject* parent) : QAbstractListModel(parent) , m_dbusInterface(nullptr) { //new ModelTest(this, this); connect(this, &QAbstractItemModel::rowsInserted, this, &NotificationsModel::rowsChanged); connect(this, &QAbstractItemModel::rowsRemoved, this, &NotificationsModel::rowsChanged); connect(this, &QAbstractItemModel::dataChanged, this, &NotificationsModel::anyDismissableChanged); connect(this, &QAbstractItemModel::rowsInserted, this, &NotificationsModel::anyDismissableChanged); QDBusServiceWatcher* watcher = new QDBusServiceWatcher(DaemonDbusInterface::activatedService(), QDBusConnection::sessionBus(), QDBusServiceWatcher::WatchForOwnerChange, this); connect(watcher, &QDBusServiceWatcher::serviceRegistered, this, &NotificationsModel::refreshNotificationList); connect(watcher, &QDBusServiceWatcher::serviceUnregistered, this, &NotificationsModel::clearNotifications); } QHash NotificationsModel::roleNames() const { //Role names for QML QHash names = QAbstractItemModel::roleNames(); names.insert(DbusInterfaceRole, "dbusInterface"); names.insert(AppNameModelRole, "appName"); names.insert(IdModelRole, "notificationId"); names.insert(DismissableModelRole, "dismissable"); names.insert(RepliableModelRole, "repliable"); names.insert(IconPathModelRole, "appIcon"); names.insert(TitleModelRole, "title"); names.insert(TextModelRole, "notitext"); return names; } NotificationsModel::~NotificationsModel() { } QString NotificationsModel::deviceId() const { return m_deviceId; } void NotificationsModel::setDeviceId(const QString& deviceId) { m_deviceId = deviceId; if (m_dbusInterface) { delete m_dbusInterface; } m_dbusInterface = new DeviceNotificationsDbusInterface(deviceId, this); connect(m_dbusInterface, &OrgKdeKdeconnectDeviceNotificationsInterface::notificationPosted, this, &NotificationsModel::notificationAdded); connect(m_dbusInterface, &OrgKdeKdeconnectDeviceNotificationsInterface::notificationRemoved, this, &NotificationsModel::notificationRemoved); connect(m_dbusInterface, &OrgKdeKdeconnectDeviceNotificationsInterface::allNotificationsRemoved, this, &NotificationsModel::clearNotifications); refreshNotificationList(); Q_EMIT deviceIdChanged(deviceId); } void NotificationsModel::notificationAdded(const QString& id) { int currentSize = m_notificationList.size(); beginInsertRows(QModelIndex(), currentSize, currentSize); NotificationDbusInterface* dbusInterface = new NotificationDbusInterface(m_deviceId, id, this); m_notificationList.append(dbusInterface); endInsertRows(); } void NotificationsModel::notificationRemoved(const QString& id) { for (int i = 0; i < m_notificationList.size(); ++i) { if (m_notificationList[i]->notificationId() == id) { beginRemoveRows(QModelIndex(), i, i); m_notificationList.removeAt(i); endRemoveRows(); return; } } qCWarning(KDECONNECT_INTERFACES) << "Attempted to remove unknown notification: " << id; } void NotificationsModel::refreshNotificationList() { if (!m_dbusInterface) { return; } clearNotifications(); if (!m_dbusInterface->isValid()) { qCWarning(KDECONNECT_INTERFACES) << "dbus interface not valid"; return; } QDBusPendingReply pendingNotificationIds = m_dbusInterface->activeNotifications(); - QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingNotificationIds, this); + QDBusPendingCallWatcher* watcher = new QDBusPendingCallWatcher(pendingNotificationIds, this); QObject::connect(watcher, &QDBusPendingCallWatcher::finished, this, &NotificationsModel::receivedNotifications); } void NotificationsModel::receivedNotifications(QDBusPendingCallWatcher* watcher) { watcher->deleteLater(); clearNotifications(); QDBusPendingReply pendingNotificationIds = *watcher; if (pendingNotificationIds.isError()) { qCWarning(KDECONNECT_INTERFACES) << pendingNotificationIds.error(); return; } const QStringList notificationIds = pendingNotificationIds.value(); if (notificationIds.isEmpty()) { return; } beginInsertRows(QModelIndex(), 0, notificationIds.size() - 1); for (const QString& notificationId : notificationIds) { NotificationDbusInterface* dbusInterface = new NotificationDbusInterface(m_deviceId, notificationId, this); m_notificationList.append(dbusInterface); } endInsertRows(); } QVariant NotificationsModel::data(const QModelIndex& index, int role) const { if (!index.isValid() || index.row() < 0 || index.row() >= m_notificationList.count() || !m_notificationList[index.row()]->isValid()) { return QVariant(); } if (!m_dbusInterface || !m_dbusInterface->isValid()) { return QVariant(); } NotificationDbusInterface* notification = m_notificationList[index.row()]; //FIXME: This function gets called lots of times, producing lots of dbus calls. Add a cache? switch (role) { case IconModelRole: return QIcon::fromTheme(QStringLiteral("device-notifier")); case IdModelRole: return notification->internalId(); case NameModelRole: return notification->ticker(); case ContentModelRole: return QString(); //To implement in the Android side case AppNameModelRole: return notification->appName(); case DbusInterfaceRole: return qVariantFromValue(notification); case DismissableModelRole: return notification->dismissable(); case RepliableModelRole: return !notification->replyId().isEmpty(); case IconPathModelRole: return notification->iconPath(); case TitleModelRole: return notification->title(); case TextModelRole: return notification->text(); default: return QVariant(); } } NotificationDbusInterface* NotificationsModel::getNotification(const QModelIndex& index) const { if (!index.isValid()) { return nullptr; } int row = index.row(); if (row < 0 || row >= m_notificationList.size()) { return nullptr; } return m_notificationList[row]; } int NotificationsModel::rowCount(const QModelIndex& parent) const { if (parent.isValid()) { //Return size 0 if we are a child because this is not a tree return 0; } return m_notificationList.count(); } bool NotificationsModel::isAnyDimissable() const { for (NotificationDbusInterface* notification : qAsConst(m_notificationList)) { if (notification->dismissable()) { return true; } } return false; } void NotificationsModel::dismissAll() { for (NotificationDbusInterface* notification : qAsConst(m_notificationList)) { if (notification->dismissable()) { notification->dismiss(); } } } void NotificationsModel::clearNotifications() { if (!m_notificationList.isEmpty()) { beginRemoveRows(QModelIndex(), 0, m_notificationList.size() - 1); qDeleteAll(m_notificationList); m_notificationList.clear(); endRemoveRows(); } } diff --git a/kcm/kcm.cpp b/kcm/kcm.cpp index 43462b19..2da1c982 100644 --- a/kcm/kcm.cpp +++ b/kcm/kcm.cpp @@ -1,373 +1,373 @@ /** * Copyright 2013 Albert Vaca * * 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 "kcm.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ui_kcm.h" #include "interfaces/dbusinterfaces.h" #include "interfaces/devicesmodel.h" #include "devicessortproxymodel.h" #include "kdeconnect-version.h" K_PLUGIN_FACTORY(KdeConnectKcmFactory, registerPlugin();) static QString createId() { return QStringLiteral("kcm")+QString::number(QCoreApplication::applicationPid()); } -KdeConnectKcm::KdeConnectKcm(QWidget *parent, const QVariantList&) +KdeConnectKcm::KdeConnectKcm(QWidget* parent, const QVariantList&) : KCModule(KAboutData::pluginData(QStringLiteral("kdeconnect-kcm")), parent) , kcmUi(new Ui::KdeConnectKcmUi()) , daemon(new DaemonDbusInterface(this)) , devicesModel(new DevicesModel(this)) , currentDevice(nullptr) { - KAboutData *about = new KAboutData(QStringLiteral("kdeconnect-kcm"), + KAboutData* about = new KAboutData(QStringLiteral("kdeconnect-kcm"), i18n("KDE Connect Settings"), QStringLiteral(KDECONNECT_VERSION_STRING), i18n("KDE Connect Settings module"), KAboutLicense::KAboutLicense::GPL_V2, i18n("(C) 2015 Albert Vaca Cintora"), QString(), QStringLiteral("https://community.kde.org/KDEConnect") ); about->addAuthor(i18n("Albert Vaca Cintora")); setAboutData(about); kcmUi->setupUi(this); sortProxyModel = new DevicesSortProxyModel(devicesModel); kcmUi->deviceList->setModel(sortProxyModel); kcmUi->deviceInfo->setVisible(false); kcmUi->progressBar->setVisible(false); kcmUi->messages->setVisible(false); //Workaround: If we set this directly (or if we set it in the .ui file), the layout breaks kcmUi->noDeviceLinks->setWordWrap(false); QTimer::singleShot(0, [this] { kcmUi->noDeviceLinks->setWordWrap(true); }); setWhenAvailable(daemon->announcedName(), [this](const QString& announcedName) { kcmUi->rename_label->setText(announcedName); kcmUi->rename_edit->setText(announcedName); }, this); connect(daemon, SIGNAL(announcedNameChanged(QString)), kcmUi->rename_edit, SLOT(setText(QString))); connect(daemon, SIGNAL(announcedNameChanged(QString)), kcmUi->rename_label, SLOT(setText(QString))); setRenameMode(false); setButtons(KCModule::Help | KCModule::NoAdditionalButton); connect(devicesModel, &QAbstractItemModel::dataChanged, this, &KdeConnectKcm::resetSelection); connect(kcmUi->deviceList->selectionModel(), &QItemSelectionModel::currentChanged, this, &KdeConnectKcm::deviceSelected); connect(kcmUi->accept_button, &QAbstractButton::clicked, this, &KdeConnectKcm::acceptPairing); connect(kcmUi->reject_button, &QAbstractButton::clicked, this, &KdeConnectKcm::rejectPairing); connect(kcmUi->pair_button, &QAbstractButton::clicked, this, &KdeConnectKcm::requestPair); connect(kcmUi->unpair_button, &QAbstractButton::clicked, this, &KdeConnectKcm::unpair); connect(kcmUi->ping_button, &QAbstractButton::clicked, this, &KdeConnectKcm::sendPing); connect(kcmUi->refresh_button,&QAbstractButton::clicked, this, &KdeConnectKcm::refresh); connect(kcmUi->rename_edit,&QLineEdit::returnPressed, this, &KdeConnectKcm::renameDone); connect(kcmUi->renameDone_button,&QAbstractButton::clicked, this, &KdeConnectKcm::renameDone); connect(kcmUi->renameShow_button,&QAbstractButton::clicked, this, &KdeConnectKcm::renameShow); daemon->acquireDiscoveryMode(createId()); } void KdeConnectKcm::renameShow() { setRenameMode(true); } void KdeConnectKcm::renameDone() { QString newName = kcmUi->rename_edit->text(); if (newName.isEmpty()) { //Rollback changes kcmUi->rename_edit->setText(kcmUi->rename_label->text()); } else { kcmUi->rename_label->setText(newName); daemon->setAnnouncedName(newName); } setRenameMode(false); } void KdeConnectKcm::setRenameMode(bool b) { kcmUi->renameDone_button->setVisible(b); kcmUi->rename_edit->setVisible(b); kcmUi->renameShow_button->setVisible(!b); kcmUi->rename_label->setVisible(!b); } KdeConnectKcm::~KdeConnectKcm() { daemon->releaseDiscoveryMode(createId()); delete kcmUi; } void KdeConnectKcm::refresh() { daemon->acquireDiscoveryMode(createId()); daemon->forceOnNetworkChange(); } void KdeConnectKcm::resetSelection() { if (!currentDevice) { return; } kcmUi->deviceList->selectionModel()->setCurrentIndex(sortProxyModel->mapFromSource(currentIndex), QItemSelectionModel::ClearAndSelect); } void KdeConnectKcm::deviceSelected(const QModelIndex& current) { if (currentDevice) { disconnect(currentDevice, 0, this, 0); } //Store previous device config pluginsConfigChanged(); if (!current.isValid()) { currentDevice = nullptr; kcmUi->deviceInfo->setVisible(false); return; } currentIndex = sortProxyModel->mapToSource(current); currentDevice = devicesModel->getDevice(currentIndex.row()); kcmUi->noDevicePlaceholder->setVisible(false); bool valid = (currentDevice != nullptr && currentDevice->isValid()); kcmUi->deviceInfo->setVisible(valid); if (!valid) { return; } kcmUi->messages->setVisible(false); resetDeviceView(); connect(currentDevice, SIGNAL(pluginsChanged()), this, SLOT(resetCurrentDevice())); connect(currentDevice, SIGNAL(trustedChanged(bool)), this, SLOT(trustedChanged(bool))); connect(currentDevice, SIGNAL(pairingError(QString)), this, SLOT(pairingFailed(QString))); connect(currentDevice, &DeviceDbusInterface::hasPairingRequestsChangedProxy, this, &KdeConnectKcm::currentDevicePairingChanged); } void KdeConnectKcm::currentDevicePairingChanged(bool pairing) { if (pairing) { setCurrentDeviceTrusted(RequestedByPeer); } else { setWhenAvailable(currentDevice->isTrusted(), [this](bool trusted) { setCurrentDeviceTrusted(trusted ? Trusted : NotTrusted); }, this); } } void KdeConnectKcm::resetCurrentDevice() { const QStringList supportedPluginNames = currentDevice->supportedPlugins(); if (m_oldSupportedPluginNames != supportedPluginNames) { resetDeviceView(); } } void KdeConnectKcm::resetDeviceView() { //KPluginSelector has no way to remove a list of plugins and load another, so we need to destroy and recreate it each time delete kcmUi->pluginSelector; kcmUi->pluginSelector = new KPluginSelector(this); kcmUi->deviceInfo_layout->addWidget(kcmUi->pluginSelector); kcmUi->pluginSelector->setConfigurationArguments(QStringList(currentDevice->id())); kcmUi->name_label->setText(currentDevice->name()); setWhenAvailable(currentDevice->isTrusted(), [this](bool trusted) { if (trusted) setCurrentDeviceTrusted(Trusted); else setWhenAvailable(currentDevice->hasPairingRequests(), [this](bool haspr) { setCurrentDeviceTrusted(haspr ? RequestedByPeer : NotTrusted); }, this); }, this); const QList pluginInfo = KPluginInfo::fromMetaData(KPluginLoader::findPlugins(QStringLiteral("kdeconnect/"))); QList availablePluginInfo; m_oldSupportedPluginNames = currentDevice->supportedPlugins(); for (auto it = pluginInfo.cbegin(), itEnd = pluginInfo.cend(); it!=itEnd; ++it) { if (m_oldSupportedPluginNames.contains(it->pluginName())) { availablePluginInfo.append(*it); } } KSharedConfigPtr deviceConfig = KSharedConfig::openConfig(currentDevice->pluginsConfigFile()); kcmUi->pluginSelector->addPlugins(availablePluginInfo, KPluginSelector::ReadConfigFile, i18n("Available plugins"), QString(), deviceConfig); connect(kcmUi->pluginSelector, &KPluginSelector::changed, this, &KdeConnectKcm::pluginsConfigChanged); } void KdeConnectKcm::requestPair() { if (!currentDevice) { return; } kcmUi->messages->hide(); setCurrentDeviceTrusted(Requested); currentDevice->requestPair(); } void KdeConnectKcm::unpair() { if (!currentDevice) { return; } setCurrentDeviceTrusted(NotTrusted); currentDevice->unpair(); } void KdeConnectKcm::acceptPairing() { if (!currentDevice) { return; } currentDevice->acceptPairing(); } void KdeConnectKcm::rejectPairing() { if (!currentDevice) { return; } currentDevice->rejectPairing(); } void KdeConnectKcm::pairingFailed(const QString& error) { if (sender() != currentDevice) return; setCurrentDeviceTrusted(NotTrusted); kcmUi->messages->setText(i18n("Error trying to pair: %1",error)); kcmUi->messages->animatedShow(); } void KdeConnectKcm::trustedChanged(bool trusted) { DeviceDbusInterface* senderDevice = (DeviceDbusInterface*) sender(); if (senderDevice == currentDevice) setCurrentDeviceTrusted(trusted ? Trusted : NotTrusted); } void KdeConnectKcm::setCurrentDeviceTrusted(KdeConnectKcm::TrustStatus trusted) { kcmUi->accept_button->setVisible(trusted == RequestedByPeer); kcmUi->reject_button->setVisible(trusted == RequestedByPeer); kcmUi->pair_button->setVisible(trusted == NotTrusted); kcmUi->unpair_button->setVisible(trusted == Trusted); kcmUi->progressBar->setVisible(trusted == Requested); kcmUi->ping_button->setVisible(trusted == Trusted); switch (trusted) { case Trusted: kcmUi->status_label->setText(i18n("(paired)")); break; case NotTrusted: kcmUi->status_label->setText(i18n("(not paired)")); break; case Requested: kcmUi->status_label->setText(i18n("(incoming pair request)")); break; case RequestedByPeer: kcmUi->status_label->setText(i18n("(pairing requested)")); break; } } void KdeConnectKcm::pluginsConfigChanged() { //Store previous selection if (!currentDevice) return; DeviceDbusInterface* auxCurrentDevice = currentDevice; currentDevice = nullptr; //HACK to avoid infinite recursion (for some reason calling save on pluginselector emits changed) kcmUi->pluginSelector->save(); currentDevice = auxCurrentDevice; currentDevice->reloadPlugins(); } void KdeConnectKcm::save() { pluginsConfigChanged(); KCModule::save(); } void KdeConnectKcm::sendPing() { if (!currentDevice) return; currentDevice->pluginCall(QStringLiteral("ping"), QStringLiteral("sendPing")); } QSize KdeConnectKcm::sizeHint() const { return QSize(890,550); //Golden ratio :D } QSize KdeConnectKcm::minimumSizeHint() const { return QSize(500,300); } #include "kcm.moc" #include "moc_kcm.cpp" diff --git a/kcm/kcm.h b/kcm/kcm.h index cf290008..67f7cf8a 100644 --- a/kcm/kcm.h +++ b/kcm/kcm.h @@ -1,84 +1,84 @@ /** * Copyright 2013 Albert Vaca * * 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 KDECONNECTKCM_H #define KDECONNECTKCM_H #include #include class QModelIndex; class DeviceDbusInterface; class DaemonDbusInterface; class DevicesModel; class DevicesSortProxyModel; namespace Ui { class KdeConnectKcmUi; } class KdeConnectKcm : public KCModule { Q_OBJECT public: - KdeConnectKcm(QWidget *parent, const QVariantList&); + KdeConnectKcm(QWidget* parent, const QVariantList&); ~KdeConnectKcm() override; private: void save() override; QSize sizeHint() const override; QSize minimumSizeHint() const override; private Q_SLOTS: void deviceSelected(const QModelIndex& current); void requestPair(); void pluginsConfigChanged(); void sendPing(); void resetSelection(); void trustedChanged(bool); void pairingFailed(const QString& error); void refresh(); void renameShow(); void renameDone(); void setRenameMode(bool b); void resetCurrentDevice(); void currentDevicePairingChanged(bool pairing); void acceptPairing(); void rejectPairing(); private: enum TrustStatus { NotTrusted, Requested, RequestedByPeer, Trusted }; void setCurrentDeviceTrusted(TrustStatus trusted); void resetDeviceView(); Ui::KdeConnectKcmUi* kcmUi; DaemonDbusInterface* daemon; DevicesModel* devicesModel; DevicesSortProxyModel* sortProxyModel; DeviceDbusInterface* currentDevice; QModelIndex currentIndex; QStringList m_oldSupportedPluginNames; public Q_SLOTS: void unpair(); }; #endif diff --git a/kcm/kcm_kdeconnect.desktop b/kcm/kcm_kdeconnect.desktop index 4c69a543..a51a44ac 100755 --- a/kcm/kcm_kdeconnect.desktop +++ b/kcm/kcm_kdeconnect.desktop @@ -1,134 +1,131 @@ [Desktop Entry] Exec=kcmshell5 kcm_kdeconnect Icon=kdeconnect Type=Service X-KDE-ServiceTypes=KCModule X-KDE-Library=kcm_kdeconnect X-KDE-ParentApp=kcontrol X-KDE-System-Settings-Parent-Category=hardware Name=KDE Connect Name[ar]=كدي المتّصل Name[ast]=KDE Connect Name[bg]=KDE Connect Name[bs]=Konekcija KDE Name[ca]=KDE Connect Name[ca@valencia]=KDE Connect Name[cs]=KDE Connect Name[da]=KDE Connect Name[de]=KDE-Connect Name[el]=KDE Connect Name[en_GB]=KDE Connect Name[es]=KDE Connect Name[et]=KDE Connect -Name[eu]=KDE Connect Name[fi]=KDE Connect Name[fr]=KDE Connect Name[gl]=KDE Connect Name[he]=KDE Connect Name[hu]=KDE csatlakozás Name[it]=KDE Connect Name[ko]=KDE Connect Name[nl]=KDE Connect Name[nn]=KDE Connect Name[pl]=KDE Connect Name[pt]=KDE Connect Name[pt_BR]=KDE Connect Name[ro]=KDE Connect Name[ru]=KDE Connect Name[sk]=KDE Connect Name[sr]=КДЕ‑конекција Name[sr@ijekavian]=КДЕ‑конекција Name[sr@ijekavianlatin]=KDE‑konekcija Name[sr@latin]=KDE‑konekcija Name[sv]=KDE-anslut Name[tr]=KDE Connect Name[uk]=З’єднання KDE Name[x-test]=xxKDE Connectxx Name[zh_CN]=KDE Connect Name[zh_TW]=KDE 連線 Comment=Connect and sync your devices Comment[ar]=اتّصل وزامن أجهزتك Comment[ast]=Coneuta y sincroniza los tos preseos Comment[ca]=Connecta i sincronitza els vostres dispositius Comment[ca@valencia]=Connecta i sincronitza els vostres dispositius Comment[cs]=Připojte a synchronizujte svá zařízení Comment[da]=Forbind og synkronisér dine enheder Comment[de]=Verbinden und Abgleichen Ihrer Geräte Comment[el]=Σύνδεση και συγχρονισμός των συσκευών σας Comment[en_GB]=Connect and sync your devices Comment[es]=Conecte y sincronice sus dispositivos Comment[et]=Oma seadmete ühendamine ja sünkroonimine -Comment[eu]=Konektatu eta sinkronizatu zure gailuak Comment[fi]=Yhdistä ja synkronoi laitteitasi Comment[fr]=Connectez et synchronisez vos périphériques Comment[gl]=Conecte e sincronice os seus dispositivos. Comment[he]=חבר וסנכרן את ההתקנים שלך Comment[hu]=Csatlakoztassa és szinkronizálja eszközeit Comment[it]=Connetti e sincronizza i tuoi dispositivi Comment[ko]=내 장치에 연결하고 동기화 Comment[nl]=Uw apparaten verbinden en synchroniseren Comment[nn]=Kopla til og synkroniser einingar Comment[pl]=Podłącz i zsynchronizuj swoje urządzenia Comment[pt]=Ligue e sincronize os seus dispositivos Comment[pt_BR]=Conecta e sincroniza seus dispositivos Comment[ru]=Подключение и синхронизация с мобильными устройствами Comment[sk]=Pripojiť a synchronizovať vaše zariadenia Comment[sr]=Повежите и синхронизујте своје уређаје Comment[sr@ijekavian]=Повежите и синхронизујте своје уређаје Comment[sr@ijekavianlatin]=Povežite i sinhronizujte svoje uređaje Comment[sr@latin]=Povežite i sinhronizujte svoje uređaje Comment[sv]=Anslut och synkronisera dina apparater Comment[tr]=Aygıtlarınıza bağlanın ve eşitleyin Comment[uk]=З’єднання і синхронізація ваших пристроїв Comment[x-test]=xxConnect and sync your devicesxx Comment[zh_CN]=连接并同步您的设备 Comment[zh_TW]=連線並且同步您的裝置 X-KDE-Keywords=Network,Android,Devices X-KDE-Keywords[ar]=شبكة,أندرويد,اندرويد,جهاز,أجهزة X-KDE-Keywords[ast]=Rede,Android,Preseos X-KDE-Keywords[bg]=Мрежа,Андроид,Устройства X-KDE-Keywords[bs]=Mreža,Android,Uređaji X-KDE-Keywords[ca]=Xarxa,Android,Dispositius X-KDE-Keywords[ca@valencia]=Xarxa,Android,Dispositius X-KDE-Keywords[cs]=Síť,Android,Zařízení X-KDE-Keywords[da]=Netværk,Android,Enheder X-KDE-Keywords[de]=Netzwerk,Android,Geräte X-KDE-Keywords[el]=Δίκτυο,Android,Συσκευές X-KDE-Keywords[en_GB]=Network,Android,Devices X-KDE-Keywords[es]=Red,Android,Dispositivos X-KDE-Keywords[et]=Võrk,Android,Seadmed -X-KDE-Keywords[eu]=Sarea,Android,Gailuak X-KDE-Keywords[fi]=Verkko,Android,Laitteet X-KDE-Keywords[fr]=Réseau,Android,Périphériques X-KDE-Keywords[gl]=rede,Android,dispositivos X-KDE-Keywords[he]=Network,Android,Devices,רשתות,אנדרואיד,התקנים,מכשירים X-KDE-Keywords[hu]=Hálózat,Android,Eszközök X-KDE-Keywords[it]=Rete,Android,Dispositivi X-KDE-Keywords[ko]=Network,Android,Devices,네트워크,안드로이드,장치 X-KDE-Keywords[nl]=Netwerk,Android,Apparaten X-KDE-Keywords[nn]=nettverk,Android,einingar X-KDE-Keywords[pl]=Sieć,Android,Urządzenia X-KDE-Keywords[pt]=Rede,Android,Dispositivos X-KDE-Keywords[pt_BR]=Rede,Android,Dispositivos X-KDE-Keywords[ru]=Network,Android,Devices,сеть,Андроид,устройства,мобильные устройства X-KDE-Keywords[sk]=Sieť,Android,Zariadenia X-KDE-Keywords[sr]=Network,Android,Devices,мрежа,Андроид,уређаји X-KDE-Keywords[sr@ijekavian]=Network,Android,Devices,мрежа,Андроид,уређаји X-KDE-Keywords[sr@ijekavianlatin]=Network,Android,Devices,mreža,Android,uređaji X-KDE-Keywords[sr@latin]=Network,Android,Devices,mreža,Android,uređaji X-KDE-Keywords[sv]=Nätverk, Android, apparater X-KDE-Keywords[tr]=Ağ,Android,Cihazlar,Aygıtlar X-KDE-Keywords[uk]=Network,Android,Devices,мережа,андроїд,пристрої X-KDE-Keywords[x-test]=xxNetworkxx,xxAndroidxx,xxDevicesxx X-KDE-Keywords[zh_CN]=Network,Android,Devices,网络,安卓,设备 X-KDE-Keywords[zh_TW]=網路,Android裝置,設備 X-DocPath=kdeconnect/index.html Categories=Qt;KDE;X-KDE-settings-kdeconnect; diff --git a/kcm/org.kde.kdeconnect.kcm.desktop b/kcm/org.kde.kdeconnect.kcm.desktop index 8e33f44d..a750e4e2 100755 --- a/kcm/org.kde.kdeconnect.kcm.desktop +++ b/kcm/org.kde.kdeconnect.kcm.desktop @@ -1,81 +1,79 @@ [Desktop Entry] Type=Application Icon=kdeconnect Terminal=false Exec=kcmshell5 kcm_kdeconnect Name=KDE Connect Settings Name[ar]=إعدادات كدي المتّصل Name[ast]=Axustes de KDE Connect Name[ca]=Arranjament del KDE Connect Name[ca@valencia]=Arranjament del KDE Connect Name[cs]=Nastavení KDE Connect Name[da]=Indstilling af KDE Connect Name[de]=KDE-Connect-Einstellungen Name[el]=Ρυθμίσεις KDE Connect Name[en_GB]=KDE Connect Settings Name[es]=Ajustes de KDE Connect Name[et]=KDE Connecti seadistused -Name[eu]=KDE Connect ezarpenak Name[fi]=KDE Connectin asetukset Name[fr]=Paramètres de KDE Connect Name[gl]=Configuración de KDE Connect Name[he]=הגדרות KDE Connect Name[hu]=A KDE Connect beállításai Name[it]=Impostazioni di KDE Connect Name[ko]=KDE Connect 설정 Name[nl]=Instellingen van KDE Connect Name[nn]=Innstillingar for KDE Connect Name[pl]=Ustawienia KDE Connect Name[pt]=Configuração do KDE Connect Name[pt_BR]=Configurações do KDE Connect Name[ru]=Настройка KDE Connect Name[sk]=Nastavenia KDE Connect Name[sr]=Поставке за КДЕ‑конекцију Name[sr@ijekavian]=Поставке за КДЕ‑конекцију Name[sr@ijekavianlatin]=Postavke za KDE‑konekciju Name[sr@latin]=Postavke za KDE‑konekciju Name[sv]=Inställning av KDE-anslut Name[tr]=KDE Connect Ayarları Name[uk]=Параметри KDE Connect Name[x-test]=xxKDE Connect Settingsxx Name[zh_CN]=KDE Connect 设置 Name[zh_TW]=KDE 連線設定 GenericName=Connect and sync your devices GenericName[ar]=اتّصل وزامن أجهزتك GenericName[ast]=Coneuta y sincroniza los tos preseos GenericName[ca]=Connecta i sincronitza els vostres dispositius GenericName[ca@valencia]=Connecta i sincronitza els vostres dispositius GenericName[cs]=Připojte a synchronizujte svá zařízení GenericName[da]=Forbind og synkronisér dine enheder GenericName[de]=Verbinden und Abgleichen Ihrer Geräte GenericName[el]=Σύνδεση και συγχρονισμός των συσκευών σας GenericName[en_GB]=Connect and sync your devices GenericName[es]=Conecte y sincronice sus dispositivos GenericName[et]=Oma seadmete ühendamine ja sünkroonimine -GenericName[eu]=Konektatu eta sinkronizatu zure gailuak GenericName[fi]=Yhdistä ja synkronoi laitteitasi GenericName[fr]=Connectez et synchronisez vos périphériques GenericName[gl]=Conecte e sincronice os seus dispositivos GenericName[he]=Connect and sync your devices GenericName[hu]=Csatlakoztassa és szinkronizálja eszközeit GenericName[it]=Connetti e sincronizza i tuoi dispositivi GenericName[ko]=내 장치에 연결하고 동기화 GenericName[nl]=Uw apparaten verbinden en synchroniseren GenericName[nn]=Kopla til og synkroniser einingar GenericName[pl]=Podłącz i zsynchronizuj swoje urządzenia GenericName[pt]=Ligue e sincronize os seus dispositivos GenericName[pt_BR]=Conecta e sincroniza seus dispositivos GenericName[ru]=Подключение и синхронизация с мобильными устройствами GenericName[sk]=Pripojiť a synchronizovať vaše zariadenia GenericName[sr]=Повежите и синхронизујте своје уређаје GenericName[sr@ijekavian]=Повежите и синхронизујте своје уређаје GenericName[sr@ijekavianlatin]=Povežite i sinhronizujte svoje uređaje GenericName[sr@latin]=Povežite i sinhronizujte svoje uređaje GenericName[sv]=Anslut och synkronisera dina apparater GenericName[tr]=Aygıtlarınıza bağlanın ve eşitleyin GenericName[uk]=З’єднання і синхронізація ваших пристроїв GenericName[x-test]=xxConnect and sync your devicesxx GenericName[zh_CN]=连接并同步您的设备 GenericName[zh_TW]=連線並且同步您的裝置 Categories=Qt;KDE;Settings;HardwareSettings; NotShowIn=KDE; diff --git a/kcmplugin/kdeconnectpluginkcm.cpp b/kcmplugin/kdeconnectpluginkcm.cpp index 8efd36f2..9b8cc6c0 100644 --- a/kcmplugin/kdeconnectpluginkcm.cpp +++ b/kcmplugin/kdeconnectpluginkcm.cpp @@ -1,60 +1,60 @@ /** * Copyright 2013 Albert Vaca * * 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 "kdeconnectpluginkcm.h" #include #include struct KdeConnectPluginKcmPrivate { - QString mDeviceId; - QString mPluginName; - KdeConnectPluginConfig* mConfig; + QString m_deviceId; + QString m_pluginName; + KdeConnectPluginConfig* m_config; }; KdeConnectPluginKcm::KdeConnectPluginKcm(QWidget* parent, const QVariantList& args, const QString& componentName) : KCModule(KAboutData::pluginData(componentName), parent, args) , d(new KdeConnectPluginKcmPrivate()) { - d->mDeviceId = args.at(0).toString(); + d->m_deviceId = args.at(0).toString(); //The parent of the config should be the plugin itself - d->mPluginName = KService::serviceByDesktopName(componentName).constData()->property(QStringLiteral("X-KDE-ParentComponents")).toString(); + d->m_pluginName = KService::serviceByDesktopName(componentName).constData()->property(QStringLiteral("X-KDE-ParentComponents")).toString(); - d->mConfig = new KdeConnectPluginConfig(d->mDeviceId, d->mPluginName); + d->m_config = new KdeConnectPluginConfig(d->m_deviceId, d->m_pluginName); } KdeConnectPluginKcm::~KdeConnectPluginKcm() { - delete d->mConfig; + delete d->m_config; } KdeConnectPluginConfig* KdeConnectPluginKcm::config() const { - return d->mConfig; + return d->m_config; } QString KdeConnectPluginKcm::deviceId() const { - return d->mDeviceId; + return d->m_deviceId; } diff --git a/kio/kiokdeconnect.cpp b/kio/kiokdeconnect.cpp index 05cda9fe..02243d09 100644 --- a/kio/kiokdeconnect.cpp +++ b/kio/kiokdeconnect.cpp @@ -1,234 +1,234 @@ /** * Copyright 2013 Albert Vaca * * 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 "kiokdeconnect.h" #include #include #include #include Q_LOGGING_CATEGORY(KDECONNECT_KIO, "kdeconnect.kio") -extern "C" int Q_DECL_EXPORT kdemain(int argc, char **argv) +extern "C" int Q_DECL_EXPORT kdemain(int argc, char** argv) { if (argc != 4) { fprintf(stderr, "Usage: kio_kdeconnect protocol pool app\n"); exit(-1); } KioKdeconnect slave(argv[2], argv[3]); slave.dispatchLoop(); return 0; } //Some useful error mapping KIO::Error toKioError(const QDBusError::ErrorType type) { switch (type) { case QDBusError::NoError: return KIO::Error(KJob::NoError); case QDBusError::NoMemory: return KIO::ERR_OUT_OF_MEMORY; case QDBusError::Timeout: return KIO::ERR_SERVER_TIMEOUT; case QDBusError::TimedOut: return KIO::ERR_SERVER_TIMEOUT; default: return KIO::ERR_INTERNAL; }; }; template bool handleDBusError(QDBusReply& reply, KIO::SlaveBase* slave) { if (!reply.isValid()) { qCDebug(KDECONNECT_KIO) << "Error in DBus request:" << reply.error(); slave->error(toKioError(reply.error().type()),reply.error().message()); return true; } return false; } -KioKdeconnect::KioKdeconnect(const QByteArray &pool, const QByteArray &app) +KioKdeconnect::KioKdeconnect(const QByteArray& pool, const QByteArray& app) : SlaveBase("kdeconnect", pool, app), m_dbusInterface(new DaemonDbusInterface(this)) { } void KioKdeconnect::listAllDevices() { infoMessage(i18n("Listing devices...")); //TODO: Change to all devices and show different icons for connected and disconnected? const QStringList devices = m_dbusInterface->devices(true, true); for (const QString& deviceId : devices) { DeviceDbusInterface interface(deviceId); if (!interface.hasPlugin(QStringLiteral("kdeconnect_sftp"))) continue; const QString path = QStringLiteral("kdeconnect://").append(deviceId).append("/"); const QString name = interface.name(); const QString icon = QStringLiteral("kdeconnect"); KIO::UDSEntry entry; entry.insert(KIO::UDSEntry::UDS_NAME, name); entry.insert(KIO::UDSEntry::UDS_ICON_NAME, icon); entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR); entry.insert(KIO::UDSEntry::UDS_ACCESS, S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); entry.insert(KIO::UDSEntry::UDS_MIME_TYPE, QLatin1String("")); entry.insert(KIO::UDSEntry::UDS_URL, path); listEntry(entry); } // We also need a non-null and writable UDSentry for "." KIO::UDSEntry entry; entry.insert(KIO::UDSEntry::UDS_NAME, QStringLiteral(".")); entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR); entry.insert(KIO::UDSEntry::UDS_SIZE, 0); entry.insert(KIO::UDSEntry::UDS_ACCESS, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IXOTH); listEntry(entry); infoMessage(QLatin1String("")); finished(); } void KioKdeconnect::listDevice() { infoMessage(i18n("Accessing device...")); qCDebug(KDECONNECT_KIO) << "ListDevice" << m_currentDevice; SftpDbusInterface interface(m_currentDevice); QDBusReply mountreply = interface.mountAndWait(); if (handleDBusError(mountreply, this)) { return; } if (!mountreply.value()) { error(KIO::ERR_COULD_NOT_MOUNT, i18n("Could not mount device filesystem")); return; } QDBusReply< QVariantMap > urlreply = interface.getDirectories(); if (handleDBusError(urlreply, this)) { return; } QVariantMap urls = urlreply.value(); for (QVariantMap::iterator it = urls.begin(); it != urls.end(); ++it) { const QString path = it.key(); const QString name = it.value().toString(); const QString icon = QStringLiteral("folder"); KIO::UDSEntry entry; entry.insert(KIO::UDSEntry::UDS_NAME, QStringLiteral("files")); entry.insert(KIO::UDSEntry::UDS_DISPLAY_NAME, name); entry.insert(KIO::UDSEntry::UDS_ICON_NAME, icon); entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR); entry.insert(KIO::UDSEntry::UDS_ACCESS, S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); entry.insert(KIO::UDSEntry::UDS_MIME_TYPE, QLatin1String("")); entry.insert(KIO::UDSEntry::UDS_URL, QUrl::fromLocalFile(path).toString()); listEntry(entry); } // We also need a non-null and writable UDSentry for "." KIO::UDSEntry entry; entry.insert(KIO::UDSEntry::UDS_NAME, QStringLiteral(".")); entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR); entry.insert(KIO::UDSEntry::UDS_SIZE, 0); entry.insert(KIO::UDSEntry::UDS_ACCESS, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IXOTH); listEntry(entry); infoMessage(QLatin1String("")); finished(); } -void KioKdeconnect::listDir(const QUrl &url) +void KioKdeconnect::listDir(const QUrl& url) { qCDebug(KDECONNECT_KIO) << "Listing..." << url; /// Url is not used here because all we could care about the url is the host, and that's already /// handled in @p setHost Q_UNUSED(url); if (!m_dbusInterface->isValid()) { infoMessage(i18n("Could not contact background service.")); finished(); return; } if (m_currentDevice.isEmpty()) { listAllDevices(); } else { listDevice(); } } -void KioKdeconnect::stat(const QUrl &url) +void KioKdeconnect::stat(const QUrl& url) { qCDebug(KDECONNECT_KIO) << "Stat: " << url; KIO::UDSEntry entry; entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR); statEntry(entry); finished(); } -void KioKdeconnect::get(const QUrl &url) +void KioKdeconnect::get(const QUrl& url) { qCDebug(KDECONNECT_KIO) << "Get: " << url; mimeType(QLatin1String("")); finished(); } -void KioKdeconnect::setHost(const QString &hostName, quint16 port, const QString &user, const QString &pass) +void KioKdeconnect::setHost(const QString& hostName, quint16 port, const QString& user, const QString& pass) { //This is called before everything else to set the file we want to show qCDebug(KDECONNECT_KIO) << "Setting host: " << hostName; // In this kio only the hostname is used Q_UNUSED(port) Q_UNUSED(user) Q_UNUSED(pass) m_currentDevice = hostName; } diff --git a/kio/kiokdeconnect.h b/kio/kiokdeconnect.h index 2586f9eb..1f5bf4dd 100644 --- a/kio/kiokdeconnect.h +++ b/kio/kiokdeconnect.h @@ -1,64 +1,64 @@ /** * Copyright 2013 Albert Vaca * * 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 KIOKDECONNECT_H #define KIOKDECONNECT_H #include #include #include #include "interfaces/dbusinterfaces.h" Q_DECLARE_LOGGING_CATEGORY(KDECONNECT_KIO) class KioKdeconnect : public QObject, public KIO::SlaveBase { Q_OBJECT public: - KioKdeconnect(const QByteArray &pool, const QByteArray &app); + KioKdeconnect(const QByteArray& pool, const QByteArray& app); - void get(const QUrl &url) override; - void listDir(const QUrl &url) override; - void stat(const QUrl &url) override; + void get(const QUrl& url) override; + void listDir(const QUrl& url) override; + void stat(const QUrl& url) override; - void setHost(const QString &constHostname, quint16 port, const QString &user, const QString &pass) override; + void setHost(const QString& constHostname, quint16 port, const QString& user, const QString& pass) override; void listAllDevices(); //List all devices exported by m_dbusInterface void listDevice(); //List m_currentDevice private: /** * Contains the ID of the current device or is empty when no device is set. */ QString m_currentDevice; /** * KDED DBus interface, used to communicate to the daemon since we need some status (like connected) */ - DaemonDbusInterface *m_dbusInterface; + DaemonDbusInterface* m_dbusInterface; }; #endif diff --git a/plasmoid/declarativeplugin/kdeconnectdeclarativeplugin.cpp b/plasmoid/declarativeplugin/kdeconnectdeclarativeplugin.cpp index 38c5960d..5683335d 100644 --- a/plasmoid/declarativeplugin/kdeconnectdeclarativeplugin.cpp +++ b/plasmoid/declarativeplugin/kdeconnectdeclarativeplugin.cpp @@ -1,135 +1,135 @@ /** * Copyright 2013 Albert Vaca * * 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 "kdeconnectdeclarativeplugin.h" #include #include #include #include #include #include "objectfactory.h" #include "responsewaiter.h" #include "processrunner.h" #include "interfaces/devicessortproxymodel.h" #include "interfaces/devicesmodel.h" #include "interfaces/notificationsmodel.h" -QObject* createDeviceDbusInterface(const QVariant &deviceId) +QObject* createDeviceDbusInterface(const QVariant& deviceId) { return new DeviceDbusInterface(deviceId.toString()); } -QObject* createDeviceBatteryDbusInterface(const QVariant &deviceId) +QObject* createDeviceBatteryDbusInterface(const QVariant& deviceId) { return new DeviceBatteryDbusInterface(deviceId.toString()); } -QObject* createFindMyPhoneInterface(const QVariant &deviceId) +QObject* createFindMyPhoneInterface(const QVariant& deviceId) { return new FindMyPhoneDeviceDbusInterface(deviceId.toString()); } -QObject* createRemoteKeyboardInterface(const QVariant &deviceId) +QObject* createRemoteKeyboardInterface(const QVariant& deviceId) { return new RemoteKeyboardDbusInterface(deviceId.toString()); } -QObject* createSftpInterface(const QVariant &deviceId) +QObject* createSftpInterface(const QVariant& deviceId) { return new SftpDbusInterface(deviceId.toString()); } -QObject* createRemoteControlInterface(const QVariant &deviceId) +QObject* createRemoteControlInterface(const QVariant& deviceId) { return new RemoteControlDbusInterface(deviceId.toString()); } -QObject* createMprisInterface(const QVariant &deviceId) +QObject* createMprisInterface(const QVariant& deviceId) { return new MprisDbusInterface(deviceId.toString()); } -QObject* createDeviceLockInterface(const QVariant &deviceId) +QObject* createDeviceLockInterface(const QVariant& deviceId) { Q_ASSERT(!deviceId.toString().isEmpty()); return new LockDeviceDbusInterface(deviceId.toString()); } QObject* createDBusResponse() { return new DBusAsyncResponse(); } void KdeConnectDeclarativePlugin::registerTypes(const char* uri) { qmlRegisterType(uri, 1, 0, "DevicesModel"); qmlRegisterType(uri, 1, 0, "NotificationsModel"); qmlRegisterType(uri, 1, 0, "DBusAsyncResponse"); qmlRegisterType(uri, 1, 0, "ProcessRunner"); qmlRegisterType(uri, 1, 0, "DevicesSortProxyModel"); qmlRegisterUncreatableType(uri, 1, 0, "MprisDbusInterface", QStringLiteral("You're not supposed to instantiate interfacess")); qmlRegisterUncreatableType(uri, 1, 0, "LockDeviceDbusInterface", QStringLiteral("You're not supposed to instantiate interfacess")); qmlRegisterUncreatableType(uri, 1, 0, "FindMyPhoneDbusInterface", QStringLiteral("You're not supposed to instantiate interfacess")); qmlRegisterUncreatableType(uri, 1, 0, "RemoteKeyboardDbusInterface", QStringLiteral("You're not supposed to instantiate interfacess")); qmlRegisterUncreatableType(uri, 1, 0, "DeviceDbusInterface", QStringLiteral("You're not supposed to instantiate interfacess")); qmlRegisterSingletonType(uri, 1, 0, "DaemonDbusInterface", [](QQmlEngine*, QJSEngine*) -> QObject* { return new DaemonDbusInterface; } ); } void KdeConnectDeclarativePlugin::initializeEngine(QQmlEngine* engine, const char* uri) { QQmlExtensionPlugin::initializeEngine(engine, uri); engine->rootContext()->setContextProperty(QStringLiteral("DeviceDbusInterfaceFactory") , new ObjectFactory(engine, createDeviceDbusInterface)); engine->rootContext()->setContextProperty(QStringLiteral("DeviceBatteryDbusInterfaceFactory") , new ObjectFactory(engine, createDeviceBatteryDbusInterface)); engine->rootContext()->setContextProperty(QStringLiteral("FindMyPhoneDbusInterfaceFactory") , new ObjectFactory(engine, createFindMyPhoneInterface)); engine->rootContext()->setContextProperty(QStringLiteral("SftpDbusInterfaceFactory") , new ObjectFactory(engine, createSftpInterface)); engine->rootContext()->setContextProperty(QStringLiteral("RemoteKeyboardDbusInterfaceFactory") , new ObjectFactory(engine, createRemoteKeyboardInterface)); engine->rootContext()->setContextProperty(QStringLiteral("MprisDbusInterfaceFactory") , new ObjectFactory(engine, createMprisInterface)); engine->rootContext()->setContextProperty(QStringLiteral("RemoteControlDbusInterfaceFactory") , new ObjectFactory(engine, createRemoteControlInterface)); engine->rootContext()->setContextProperty(QStringLiteral("LockDeviceDbusInterfaceFactory") , new ObjectFactory(engine, createDeviceLockInterface)); engine->rootContext()->setContextProperty(QStringLiteral("DBusResponseFactory") , new ObjectFactory(engine, createDBusResponse)); engine->rootContext()->setContextProperty(QStringLiteral("DBusResponseWaiter") , DBusResponseWaiter::instance()); } diff --git a/plasmoid/declarativeplugin/kdeconnectdeclarativeplugin.h b/plasmoid/declarativeplugin/kdeconnectdeclarativeplugin.h index bdbef534..f823418d 100644 --- a/plasmoid/declarativeplugin/kdeconnectdeclarativeplugin.h +++ b/plasmoid/declarativeplugin/kdeconnectdeclarativeplugin.h @@ -1,36 +1,36 @@ /** * Copyright 2013 Albert Vaca * * 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 KDECONNECTDECLARATIVEPLUGIN_H #define KDECONNECTDECLARATIVEPLUGIN_H #include class KdeConnectDeclarativePlugin : public QQmlExtensionPlugin { Q_OBJECT Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface") void registerTypes(const char* uri) override; - void initializeEngine(QQmlEngine *engine, const char *uri) override; + void initializeEngine(QQmlEngine* engine, const char* uri) override; }; #endif // KDECONNECTDECLARATIVEPLUGIN_H diff --git a/plasmoid/declarativeplugin/objectfactory.h b/plasmoid/declarativeplugin/objectfactory.h index dc9e95e4..bb597441 100644 --- a/plasmoid/declarativeplugin/objectfactory.h +++ b/plasmoid/declarativeplugin/objectfactory.h @@ -1,46 +1,46 @@ #ifndef QOBJECT_FACTORY_H #define QOBJECT_FACTORY_H #include #include //Wraps a factory function with QObject class to be exposed to qml context as named factory class ObjectFactory : public QObject { Q_OBJECT typedef QObject* (*Func0)(); typedef QObject* (*Func1)(const QVariant&); typedef QObject* (*Func2)(const QVariant&, const QVariant&); public: ObjectFactory(QObject* parent, Func0 f0) : QObject(parent), m_f0(f0), m_f1(nullptr), m_f2(nullptr) {} ObjectFactory(QObject* parent, Func1 f1) : QObject(parent), m_f0(nullptr), m_f1(f1), m_f2(nullptr) {} ObjectFactory(QObject* parent, Func2 f2) : QObject(parent), m_f0(nullptr), m_f1(nullptr), m_f2(f2) {} ~ObjectFactory() override = default; Q_INVOKABLE QObject* create() { if (m_f0) return m_f0(); return nullptr; } - Q_INVOKABLE QObject* create(const QVariant &arg1) { + Q_INVOKABLE QObject* create(const QVariant& arg1) { if (m_f1) return m_f1(arg1); return nullptr; } - Q_INVOKABLE QObject* create(const QVariant &arg1, const QVariant &arg2) { + Q_INVOKABLE QObject* create(const QVariant& arg1, const QVariant& arg2) { if (m_f2) return m_f2(arg1, arg2); return nullptr; } private: Func0 m_f0; Func1 m_f1; Func2 m_f2; }; #endif diff --git a/plasmoid/declarativeplugin/processrunner.cpp b/plasmoid/declarativeplugin/processrunner.cpp index 04d5c363..70e51bc3 100644 --- a/plasmoid/declarativeplugin/processrunner.cpp +++ b/plasmoid/declarativeplugin/processrunner.cpp @@ -1,35 +1,35 @@ /*************************************************************************** * Copyright (C) 2013 by Eike Hein * * * * 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 "processrunner.h" #include -ProcessRunner::ProcessRunner(QObject *parent) : QObject(parent) +ProcessRunner::ProcessRunner(QObject* parent) : QObject(parent) { } ProcessRunner::~ProcessRunner() { } void ProcessRunner::runKdeconnectKCM() { QProcess::startDetached(QStringLiteral("kcmshell5"), QStringList() << QStringLiteral("kcm_kdeconnect")); } diff --git a/plasmoid/declarativeplugin/processrunner.h b/plasmoid/declarativeplugin/processrunner.h index 880b82c1..7c6c25a0 100644 --- a/plasmoid/declarativeplugin/processrunner.h +++ b/plasmoid/declarativeplugin/processrunner.h @@ -1,36 +1,36 @@ /*************************************************************************** * Copyright (C) 2013 by Eike Hein * * * * 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 . * ***************************************************************************/ #ifndef PROCESSRUNNER_H #define PROCESSRUNNER_H #include class ProcessRunner : public QObject { Q_OBJECT public: - explicit ProcessRunner(QObject *parent = nullptr); + explicit ProcessRunner(QObject* parent = nullptr); ~ProcessRunner() override; Q_INVOKABLE void runKdeconnectKCM(); }; #endif diff --git a/plasmoid/declarativeplugin/responsewaiter.h b/plasmoid/declarativeplugin/responsewaiter.h index 68a75f7a..35c8abc8 100644 --- a/plasmoid/declarativeplugin/responsewaiter.h +++ b/plasmoid/declarativeplugin/responsewaiter.h @@ -1,61 +1,61 @@ #ifndef RESPONSE_WAITER_H #define RESPONSE_WAITER_H #include #include #include class QDBusPendingCall; class QDBusPendingCallWatcher; class DBusResponseWaiter : public QObject { Q_OBJECT public: static DBusResponseWaiter* instance(); ///extract QDbusPendingCall from \p variant and blocks untill completed Q_INVOKABLE QVariant waitForReply(QVariant variant) const; const QDBusPendingCall* extractPendingCall(QVariant& variant) const; private: DBusResponseWaiter(); static DBusResponseWaiter* m_instance; QList m_registered; }; class DBusAsyncResponse : public QObject { Q_OBJECT Q_PROPERTY(bool autoDelete READ autodelete WRITE setAutodelete) public: explicit DBusAsyncResponse(QObject* parent = nullptr); ~DBusAsyncResponse() override = default; Q_INVOKABLE void setPendingCall(QVariant e); void setAutodelete(bool b) {m_autodelete = b;}; bool autodelete() const {return m_autodelete;} Q_SIGNALS: - void success(const QVariant &result); - void error(const QString &message); + void success(const QVariant& result); + void error(const QString& message); private Q_SLOTS: void onCallFinished(QDBusPendingCallWatcher* watcher); void onTimeout(); private: QTimer m_timeout; bool m_autodelete; }; #endif diff --git a/plasmoid/package/metadata.desktop b/plasmoid/package/metadata.desktop index be02f27a..c0092b89 100644 --- a/plasmoid/package/metadata.desktop +++ b/plasmoid/package/metadata.desktop @@ -1,99 +1,97 @@ [Desktop Entry] Name=KDE Connect Name[ar]=كدي المتّصل Name[ast]=KDE Connect Name[bg]=KDE Connect Name[bs]=Konekcija KDE Name[ca]=KDE Connect Name[ca@valencia]=KDE Connect Name[cs]=KDE Connect Name[da]=KDE Connect Name[de]=KDE-Connect Name[el]=KDE Connect Name[en_GB]=KDE Connect Name[es]=KDE Connect Name[et]=KDE Connect -Name[eu]=KDE Connect Name[fi]=KDE Connect Name[fr]=KDE Connect Name[gl]=KDE Connect Name[he]=KDE Connect Name[hu]=KDE csatlakozás Name[it]=KDE Connect Name[ko]=KDE Connect Name[nl]=KDE Connect Name[nn]=KDE Connect Name[pl]=KDE Connect Name[pt]=KDE Connect Name[pt_BR]=KDE Connect Name[ro]=KDE Connect Name[ru]=KDE Connect Name[sk]=KDE Connect Name[sr]=КДЕ‑конекција Name[sr@ijekavian]=КДЕ‑конекција Name[sr@ijekavianlatin]=KDE‑konekcija Name[sr@latin]=KDE‑konekcija Name[sv]=KDE-anslut Name[tr]=KDE Connect Name[uk]=З’єднання KDE Name[x-test]=xxKDE Connectxx Name[zh_CN]=KDE Connect Name[zh_TW]=KDE 連線 Comment=Show notifications from your devices using KDE Connect Comment[ar]=أظهر الإخطارات من أجهزتك باستخدام «كدي المتّصل» Comment[ast]=Amuesa avisos de los tos preseos qu'usen KDE Connect Comment[bg]=Показване на уведомления от вашите устройства чрез KDE Connect Comment[bs]=Prikaži obavlještenja sa uređaja koji koriste KDE konekciju Comment[ca]=Mostra les notificacions dels vostres dispositius emprant el KDE Connect Comment[ca@valencia]=Mostra les notificacions dels vostres dispositius emprant el KDE Connect Comment[cs]=Zobrazit upozornění z vašich zařízení pomocí KDE Connect Comment[da]=Vis bekendtgørelser fra dine enheder med KDE Connect Comment[de]=Zeigt Benachrichtigungen von Ihren Geräten mit KDE-Connect Comment[el]=Προβολή ειδοποιήσεων από τις συσκευές σας με το KDE Connect Comment[en_GB]=Show notifications from your devices using KDE Connect Comment[es]=Mostrar notificaciones de sus dispositivos usando KDE Connect Comment[et]=Seadmete märguannete näitamine KDE Connecti vahendusel -Comment[eu]=Ikusi zure gailuetako jakinarazpenak KDE Connect erabiliz Comment[fi]=Näytä laitteidesi ilmoitukset KDE Connectilla Comment[fr]=Afficher les notifications provenant de vos périphériques à l'aide de KDE Connect Comment[gl]=Mostrar notificacións de dispositivos usando KDE Connect. Comment[he]=הראה התראות מההתקן שלך באמצעות KDE Connect Comment[hu]=Az eszközökről származó értesítések megjelenítése a KDE csatlakozás használatával Comment[it]=Mostra le notifiche dei tuoi dispositivi tramite KDE Connect Comment[ko]=KDE Connect로 장치에 표시된 알림 보기 Comment[nl]=Meldingen van uw apparaten met KDE Connect tonen Comment[nn]=Vis varslingar frå einingane dine med KDE Connect Comment[pl]=Pokazuje powiadomienia z urządzeń z KDE Connect Comment[pt]=Mostrar notificações dos seus dispositivos usando o KDE Connect Comment[pt_BR]=Mostrar notificações dos seus dispositivos usando o KDE Connect Comment[ru]=Просмотр уведомлений с мобильных устройств с помощью KDE Connect Comment[sk]=Zobraziť oznámenia z vašich zariadení pomocou KDE Connect Comment[sr]=Приказује обавештења са вашег уређаја помоћу КДЕ‑конекције Comment[sr@ijekavian]=Приказује обавештења са вашег уређаја помоћу КДЕ‑конекције Comment[sr@ijekavianlatin]=Prikazuje obaveštenja sa vašeg uređaja pomoću KDE‑konekcije Comment[sr@latin]=Prikazuje obaveštenja sa vašeg uređaja pomoću KDE‑konekcije Comment[sv]=Visa underrättelser från apparater med KDE anslut Comment[tr]=KDE Connect kullanılarak cihazınızdan bildirimleri görüntüleyin Comment[uk]=Показ сповіщень з ваших пристроїв за допомогою програми «З’єднання KDE» Comment[x-test]=xxShow notifications from your devices using KDE Connectxx Comment[zh_CN]=通过 KDE Connect 显示来自您的设备的通知 Comment[zh_TW]=使用KDE 連線來顯示您的裝置通知 Icon=kdeconnect Type=Service X-KDE-ServiceTypes=Plasma/Applet X-Plasma-API=declarativeappletscript X-Plasma-MainScript=ui/main.qml X-Plasma-NotificationArea=true X-Plasma-ConfigPlugins=kcm_kdeconnect X-KDE-PluginInfo-Author=Albert Vaca Cintora X-KDE-PluginInfo-Email=albertvaka@gmail.com X-KDE-PluginInfo-Name=org.kde.kdeconnect X-KDE-PluginInfo-Version=0.1 X-KDE-PluginInfo-Website=http://albertvaka.wordpress.com X-KDE-PluginInfo-Category=System Information X-KDE-PluginInfo-Depends= X-KDE-PluginInfo-License=GPL X-KDE-PluginInfo-EnabledByDefault=true diff --git a/plugins/battery/batterydbusinterface.cpp b/plugins/battery/batterydbusinterface.cpp index d836dff7..1d475281 100644 --- a/plugins/battery/batterydbusinterface.cpp +++ b/plugins/battery/batterydbusinterface.cpp @@ -1,63 +1,63 @@ /** * Copyright 2013 Albert Vaca * * 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 "batterydbusinterface.h" #include "batteryplugin.h" #include #include QMap BatteryDbusInterface::s_dbusInterfaces; -BatteryDbusInterface::BatteryDbusInterface(const Device *device) +BatteryDbusInterface::BatteryDbusInterface(const Device* device) : QDBusAbstractAdaptor(const_cast(device)) - , mCharge(-1) - , mIsCharging(false) + , m_charge(-1) + , m_isCharging(false) { // FIXME: Workaround to prevent memory leak. // This makes the old BatteryDdbusInterface be deleted only after the new one is // fully operational. That seems to prevent the crash mentioned in BatteryPlugin's // destructor. QMap::iterator oldInterfaceIter = s_dbusInterfaces.find(device->id()); if (oldInterfaceIter != s_dbusInterfaces.end()) { qCDebug(KDECONNECT_PLUGIN_BATTERY) << "Deleting stale BatteryDbusInterface for" << device->name(); //FIXME: This still crashes sometimes even after the workaround made in 38aa970, commented out by now //oldInterfaceIter.value()->deleteLater(); s_dbusInterfaces.erase(oldInterfaceIter); } s_dbusInterfaces[device->id()] = this; } BatteryDbusInterface::~BatteryDbusInterface() { qCDebug(KDECONNECT_PLUGIN_BATTERY) << "Destroying BatteryDbusInterface"; } void BatteryDbusInterface::updateValues(bool isCharging, int currentCharge) { - mIsCharging = isCharging; - mCharge = currentCharge; + m_isCharging = isCharging; + m_charge = currentCharge; - Q_EMIT stateChanged(mIsCharging); - Q_EMIT chargeChanged(mCharge); + Q_EMIT stateChanged(m_isCharging); + Q_EMIT chargeChanged(m_charge); } diff --git a/plugins/battery/batterydbusinterface.h b/plugins/battery/batterydbusinterface.h index e21d9c58..c49e5c33 100644 --- a/plugins/battery/batterydbusinterface.h +++ b/plugins/battery/batterydbusinterface.h @@ -1,55 +1,55 @@ /** * Copyright 2013 Albert Vaca * * 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 BATTERYDBUSINTERFACE_H #define BATTERYDBUSINTERFACE_H #include class Device; class BatteryDbusInterface : public QDBusAbstractAdaptor { Q_OBJECT Q_CLASSINFO("D-Bus Interface", "org.kde.kdeconnect.device.battery") public: - explicit BatteryDbusInterface(const Device *device); + explicit BatteryDbusInterface(const Device* device); ~BatteryDbusInterface() override; - Q_SCRIPTABLE int charge() const { return mCharge; } - Q_SCRIPTABLE bool isCharging() const { return mIsCharging; } + Q_SCRIPTABLE int charge() const { return m_charge; } + Q_SCRIPTABLE bool isCharging() const { return m_isCharging; } void updateValues(bool isCharging, int currentCharge); Q_SIGNALS: Q_SCRIPTABLE void stateChanged(bool charging); Q_SCRIPTABLE void chargeChanged(int charge); private: - int mCharge; - bool mIsCharging; + int m_charge; + bool m_isCharging; // Map to save current BatteryDbusInterface for each device. static QMap s_dbusInterfaces; }; #endif diff --git a/plugins/battery/batteryplugin.cpp b/plugins/battery/batteryplugin.cpp index 10c38184..d79eea7f 100644 --- a/plugins/battery/batteryplugin.cpp +++ b/plugins/battery/batteryplugin.cpp @@ -1,86 +1,86 @@ /** * Copyright 2013 Albert Vaca * * 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 "batteryplugin.h" #include #include #include #include #include "batterydbusinterface.h" K_PLUGIN_FACTORY_WITH_JSON( KdeConnectPluginFactory, "kdeconnect_battery.json", registerPlugin< BatteryPlugin >(); ) Q_LOGGING_CATEGORY(KDECONNECT_PLUGIN_BATTERY, "kdeconnect.plugin.battery") -BatteryPlugin::BatteryPlugin(QObject *parent, const QVariantList &args) +BatteryPlugin::BatteryPlugin(QObject* parent, const QVariantList& args) : KdeConnectPlugin(parent, args) , batteryDbusInterface(new BatteryDbusInterface(device())) { //TODO: Add battery reporting, could be based on: // http://kde-apps.org/content/show.php/battery+plasmoid+with+remaining+time?content=120309 } void BatteryPlugin::connected() { NetworkPackage np(PACKAGE_TYPE_BATTERY_REQUEST, {{"request",true}}); sendPackage(np); } BatteryPlugin::~BatteryPlugin() { //FIXME: Qt dbus does not allow to remove an adaptor! (it causes a crash in // the next dbus access to its parent). The implication of not deleting this // is that disabling the plugin does not remove the interface (that will // return outdated values) and that enabling it again instantiates a second // adaptor. This is also a memory leak until the entire device is destroyed. //batteryDbusInterface->deleteLater(); } bool BatteryPlugin::receivePackage(const NetworkPackage& np) { bool isCharging = np.get(QStringLiteral("isCharging"), false); int currentCharge = np.get(QStringLiteral("currentCharge"), -1); int thresholdEvent = np.get(QStringLiteral("thresholdEvent"), (int)ThresholdNone); if (batteryDbusInterface->charge() != currentCharge || batteryDbusInterface->isCharging() != isCharging ) { batteryDbusInterface->updateValues(isCharging, currentCharge); } if ( thresholdEvent == ThresholdBatteryLow && !isCharging ) { KNotification* notification = new KNotification(QStringLiteral("batteryLow")); notification->setIconName(QStringLiteral("battery-040")); notification->setComponentName(QStringLiteral("kdeconnect")); notification->setTitle(i18nc("device name: low battery", "%1: Low Battery", device()->name())); notification->setText(i18n("Battery at %1%", currentCharge)); notification->sendEvent(); } return true; } #include "batteryplugin.moc" diff --git a/plugins/battery/batteryplugin.h b/plugins/battery/batteryplugin.h index cc78479c..aff21146 100644 --- a/plugins/battery/batteryplugin.h +++ b/plugins/battery/batteryplugin.h @@ -1,56 +1,56 @@ /** * Copyright 2013 Albert Vaca * * 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 BATTERYPLUGIN_H #define BATTERYPLUGIN_H #include #include #define PACKAGE_TYPE_BATTERY_REQUEST QStringLiteral("kdeconnect.battery.request") Q_DECLARE_LOGGING_CATEGORY(KDECONNECT_PLUGIN_BATTERY) class BatteryDbusInterface; class BatteryPlugin : public KdeConnectPlugin { Q_OBJECT public: - explicit BatteryPlugin(QObject *parent, const QVariantList &args); + explicit BatteryPlugin(QObject* parent, const QVariantList& args); ~BatteryPlugin() override; bool receivePackage(const NetworkPackage& np) override; void connected() override; private: // Keep these values in sync with THRESHOLD* constants in // kdeconnect-android:BatteryPlugin.java // see README for their meaning enum ThresholdBatteryEvent { ThresholdNone = 0, ThresholdBatteryLow = 1 }; BatteryDbusInterface* batteryDbusInterface; }; #endif diff --git a/plugins/battery/kdeconnect_battery.json b/plugins/battery/kdeconnect_battery.json index f8e6317d..4999816b 100644 --- a/plugins/battery/kdeconnect_battery.json +++ b/plugins/battery/kdeconnect_battery.json @@ -1,100 +1,98 @@ { "Encoding": "UTF-8", "KPlugin": { "Authors": [ { "Email": "albertvaka@gmail.com", "Name": "Albert Vaca", "Name[sr@ijekavian]": "Алберт Вака Синтора", "Name[sr@ijekavianlatin]": "Albert Vaka Sintora", "Name[sr@latin]": "Albert Vaka Sintora", "Name[sr]": "Алберт Вака Синтора", "Name[x-test]": "xxAlbert Vacaxx" } ], "Description": "Show your phone battery next to your computer battery", "Description[ar]": "أظهر بطّاريّة الهاتف بجانب بطّاريّة الحاسوب", "Description[ca@valencia]": "Mostra la bateria del telèfon al costat de la bateria de l'ordinador", "Description[ca]": "Mostra la bateria del telèfon al costat de la bateria de l'ordinador", "Description[cs]": "Zobrazit baterii vedle baterie počítače", "Description[da]": "Vis din telefons batteri ved siden af dit computerbatteri", "Description[de]": "Zeigt den Akku Ihres Telefons neben dem Akku des Rechners", "Description[el]": "Εμφάνιση μπαταρίας συσκευής δίπλα στη μπαταρία του υπολογιστή", "Description[es]": "Mostrar la batería del teléfono junto a la batería del equipo", "Description[et]": "Telefoniaku näitamine otse arvutiaku kõrval", - "Description[eu]": "Erakutsi telefonoaren bateria ordenagailuaren bateriaren ondoan", "Description[fi]": "Näytä puhelimesi akku tietokoneen akun rinnalla", "Description[fr]": "Affichez la batterie de votre téléphone à côté de la batterie de votre ordinateur", "Description[gl]": "Mostra o nivel de batería do teléfono canda o nivel de batería do computador.", "Description[hu]": "A telefon akkumulátorának megjelenítése a számítógépé mellett", "Description[it]": "Mostra la batteria del telefono accanto alla batteria del computer", "Description[ko]": "컴퓨터 배터리와 함께 휴대폰 배터리 표시", "Description[nl]": "Uw telefoonbatterij naast uw computerbatterij tonen", "Description[nn]": "Vis telefonbatteriet ved sida av datamaskinbatteriet", "Description[pl]": "Pokaż baterię swojego telefonu obok baterii komputera", "Description[pt]": "Mostrar a bateria do seu telefone ao lado da do seu computador", "Description[pt_BR]": "Mostra a bateria do seu celular ao lado da bateria do computador", "Description[ru]": "Показ уровня заряда батареи телефона рядом с индикатором батареи компьютера", "Description[sk]": "Zobraziť batériu vášho telefónu pri batérii počítača", "Description[sr@ijekavian]": "Приказ батерије телефона у системској касети", "Description[sr@ijekavianlatin]": "Prikaz baterije telefona u sistemskoj kaseti", "Description[sr@latin]": "Prikaz baterije telefona u sistemskoj kaseti", "Description[sr]": "Приказ батерије телефона у системској касети", "Description[sv]": "Visa telefonens batteri intill datorbatteriet", "Description[tr]": "Bilgisayar pilinizin yanında telefon pil durumunu göster", "Description[uk]": "Показ даних щодо рівня заряду акумулятора на телефоні поряд з даними щодо рівня заряду акумулятора комп’ютера", "Description[x-test]": "xxShow your phone battery next to your computer batteryxx", "Description[zh_CN]": "在计算机电池旁显示手机电池", "Description[zh_TW]": "在您的電腦電池電量旁邊顯示手機電池電量", "EnabledByDefault": true, "Icon": "preferences-system-power-management", "Id": "kdeconnect_battery", "License": "GPL", "Name": "Battery monitor", "Name[ar]": "مرقاب البطّاريّة", "Name[ca@valencia]": "Monitor de la bateria", "Name[ca]": "Monitor de la bateria", "Name[cs]": "Monitor baterie", "Name[da]": "Batteriovervågning", "Name[de]": "Akkuüberwachung", "Name[el]": "Παρακολούθηση μπαταρίας", "Name[es]": "Monitor de batería", "Name[et]": "Aku jälgija", - "Name[eu]": "Bateriaren monitorea", "Name[fi]": "Akkuvalvonta", "Name[fr]": "Moniteur de batterie", "Name[gl]": "Vixilante da batería", "Name[hu]": "Akkumulátorfigyelő", "Name[ia]": "Controlator de batteria", "Name[it]": "Monitor della batteria", "Name[ko]": "배터리 모니터", "Name[nl]": "Batterijmonitor", "Name[nn]": "Batteriovervaking", "Name[pl]": "Monitor baterii", "Name[pt]": "Monitor da bateria", "Name[pt_BR]": "Monitor de bateria", "Name[ru]": "Индикатор батареи", "Name[sk]": "Monitor batérie", "Name[sr@ijekavian]": "Надзор батерије", "Name[sr@ijekavianlatin]": "Nadzor baterije", "Name[sr@latin]": "Nadzor baterije", "Name[sr]": "Надзор батерије", "Name[sv]": "Batteriövervakare", "Name[tr]": "Pil izleyici", "Name[uk]": "Монітор акумулятора", "Name[x-test]": "xxBattery monitorxx", "Name[zh_CN]": "电池监视器", "Name[zh_TW]": "電池監視器", "ServiceTypes": [ "KdeConnect/Plugin" ], "Version": "0.1", "Website": "http://albertvaka.wordpress.com" }, "X-KdeConnect-OutgoingPackageType": [ "kdeconnect.battery.request" ], "X-KdeConnect-SupportedPackageType": [ "kdeconnect.battery" ] } diff --git a/plugins/clipboard/clipboardplugin.cpp b/plugins/clipboard/clipboardplugin.cpp index 347e5065..7149adff 100644 --- a/plugins/clipboard/clipboardplugin.cpp +++ b/plugins/clipboard/clipboardplugin.cpp @@ -1,51 +1,51 @@ /** * Copyright 2013 Albert Vaca * * 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 "clipboardplugin.h" #include "clipboardlistener.h" #include K_PLUGIN_FACTORY_WITH_JSON( KdeConnectPluginFactory, "kdeconnect_clipboard.json", registerPlugin< ClipboardPlugin >(); ) Q_LOGGING_CATEGORY(KDECONNECT_PLUGIN_CLIPBOARD, "kdeconnect.plugin.clipboard") -ClipboardPlugin::ClipboardPlugin(QObject *parent, const QVariantList &args) +ClipboardPlugin::ClipboardPlugin(QObject* parent, const QVariantList& args) : KdeConnectPlugin(parent, args) { connect(ClipboardListener::instance(), &ClipboardListener::clipboardChanged, this, &ClipboardPlugin::propagateClipboard); } void ClipboardPlugin::propagateClipboard(const QString& content) { NetworkPackage np(PACKAGE_TYPE_CLIPBOARD, {{"content", content}}); sendPackage(np); } bool ClipboardPlugin::receivePackage(const NetworkPackage& np) { QString content = np.get(QStringLiteral("content")); ClipboardListener::instance()->setText(content); return true; } #include "clipboardplugin.moc" diff --git a/plugins/clipboard/clipboardplugin.h b/plugins/clipboard/clipboardplugin.h index 243ca2c3..873da10c 100644 --- a/plugins/clipboard/clipboardplugin.h +++ b/plugins/clipboard/clipboardplugin.h @@ -1,48 +1,48 @@ /** * Copyright 2013 Albert Vaca * * 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 CLIPBOARDPLUGIN_H #define CLIPBOARDPLUGIN_H #include #include #include #include Q_DECLARE_LOGGING_CATEGORY(KDECONNECT_PLUGIN_CLIPBOARD) #define PACKAGE_TYPE_CLIPBOARD QStringLiteral("kdeconnect.clipboard") class ClipboardPlugin : public KdeConnectPlugin { Q_OBJECT public: - explicit ClipboardPlugin(QObject *parent, const QVariantList &args); + explicit ClipboardPlugin(QObject* parent, const QVariantList& args); bool receivePackage(const NetworkPackage& np) override; void connected() override { } private Q_SLOTS: void propagateClipboard(const QString& content); }; #endif diff --git a/plugins/clipboard/kdeconnect_clipboard.json b/plugins/clipboard/kdeconnect_clipboard.json index b68d796c..8d52da73 100644 --- a/plugins/clipboard/kdeconnect_clipboard.json +++ b/plugins/clipboard/kdeconnect_clipboard.json @@ -1,100 +1,98 @@ { "Encoding": "UTF-8", "KPlugin": { "Authors": [ { "Email": "albertvaka@gmail.com", "Name": "Albert Vaca", "Name[sr@ijekavian]": "Алберт Вака Синтора", "Name[sr@ijekavianlatin]": "Albert Vaka Sintora", "Name[sr@latin]": "Albert Vaka Sintora", "Name[sr]": "Алберт Вака Синтора", "Name[x-test]": "xxAlbert Vacaxx" } ], "Description": "Share the clipboard between devices", "Description[ar]": "شارك الحافظة بين الجهازين", "Description[ca@valencia]": "Comparteix el porta-retalls entre dispositius", "Description[ca]": "Comparteix el porta-retalls entre dispositius", "Description[cs]": "Sdílet obsah schránky mezi zařízeními", "Description[da]": "Del udklipsholderen mellem enheder", "Description[de]": "Die Zwischenablage mit Geräten teilen", "Description[el]": "Διαμοιρασμός του προχείρου μεταξύ συσκευών", "Description[es]": "Compartir portapapeles entre dispositivos", "Description[et]": "Lõikepuhvri jagamine seadmete vahel", - "Description[eu]": "Partekatu arbela gailuen artean", "Description[fi]": "Jaa leikepöytä laitteiden välillä", "Description[fr]": "Partagez le presse-papiers entre périphériques", "Description[gl]": "Comparta o portapapeis entre os dispositivos.", "Description[hu]": "A vágólap megosztása az eszközök között", "Description[it]": "Condividi gli appunti tra i dispositivi", "Description[ko]": "장치간 클립보드 공유", "Description[nl]": "Het klembord tussen apparaten delen", "Description[nn]": "Del utklippstavla mellom einingar", "Description[pl]": "Współdziel schowek pomiędzy urządzeniami", "Description[pt]": "Partilhar a área de transferência entre dispositivos", "Description[pt_BR]": "Compartilha a área de transferência entre dispositivos", "Description[ru]": "Общий буфер обмена между устройствами", "Description[sk]": "Zdieľať schránku medzi zariadeniami", "Description[sr@ijekavian]": "Дељење клипборда између уређаја", "Description[sr@ijekavianlatin]": "Deljenje klipborda između uređaja", "Description[sr@latin]": "Deljenje klipborda između uređaja", "Description[sr]": "Дељење клипборда између уређаја", "Description[sv]": "Dela klippbordet mellan apparater", "Description[tr]": "Aygıtlar arasında panoyu paylaştır", "Description[uk]": "Спільне використання буфера обміну даними на пристроях", "Description[x-test]": "xxShare the clipboard between devicesxx", "Description[zh_CN]": "在设备间共享剪贴板", "Description[zh_TW]": "在設備之間共享剪貼板", "EnabledByDefault": true, "Icon": "klipper", "Id": "kdeconnect_clipboard", "License": "GPL", "Name": "Clipboard", "Name[ar]": "الحافظة", "Name[ca@valencia]": "Porta-retalls", "Name[ca]": "Porta-retalls", "Name[cs]": "Schránka", "Name[da]": "Udklipsholder", "Name[de]": "Zwischenablage", "Name[el]": "Πρόχειρο", "Name[es]": "Portapapeles", "Name[et]": "Lõikepuhver", - "Name[eu]": "Arbela", "Name[fi]": "Leikepöytä", "Name[fr]": "Presse-papiers", "Name[gl]": "Portapapeis", "Name[hu]": "Vágólap", "Name[ia]": "Area de transferentia", "Name[it]": "Appunti", "Name[ko]": "클립보드", "Name[nl]": "Klembord", "Name[nn]": "Utklippstavle", "Name[pl]": "Schowek", "Name[pt]": "Área de Transferência", "Name[pt_BR]": "Área de transferência", "Name[ru]": "Буфер обмена", "Name[sk]": "Schránka", "Name[sr@ijekavian]": "Клипборд", "Name[sr@ijekavianlatin]": "Klipbord", "Name[sr@latin]": "Klipbord", "Name[sr]": "Клипборд", "Name[sv]": "Klippbord", "Name[tr]": "Geçici taşıma panosu", "Name[uk]": "Буфер обміну", "Name[x-test]": "xxClipboardxx", "Name[zh_CN]": "剪贴板", "Name[zh_TW]": "剪貼板", "ServiceTypes": [ "KdeConnect/Plugin" ], "Version": "0.1", "Website": "http://albertvaka.wordpress.com" }, "X-KdeConnect-OutgoingPackageType": [ "kdeconnect.clipboard" ], "X-KdeConnect-SupportedPackageType": [ "kdeconnect.clipboard" ] } diff --git a/plugins/findmyphone/findmyphoneplugin.h b/plugins/findmyphone/findmyphoneplugin.h index 94f9b4ea..95349d24 100644 --- a/plugins/findmyphone/findmyphoneplugin.h +++ b/plugins/findmyphone/findmyphoneplugin.h @@ -1,47 +1,47 @@ /** * Copyright 2014 Apoorv Parle * * 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 PINGPLUGIN_H #define PINGPLUGIN_H #include #include #define PACKAGE_TYPE_FINDMYPHONE_REQUEST QStringLiteral("kdeconnect.findmyphone.request") class FindMyPhonePlugin : public KdeConnectPlugin { Q_OBJECT Q_CLASSINFO("D-Bus Interface", "org.kde.kdeconnect.device.findmyphone") public: - explicit FindMyPhonePlugin(QObject *parent, const QVariantList &args); + explicit FindMyPhonePlugin(QObject* parent, const QVariantList& args); ~FindMyPhonePlugin() override; Q_SCRIPTABLE void ring(); QString dbusPath() const override; void connected() override {} bool receivePackage(const NetworkPackage& np) override; }; #endif diff --git a/plugins/findmyphone/kdeconnect_findmyphone.json b/plugins/findmyphone/kdeconnect_findmyphone.json index a64f117a..1e687401 100644 --- a/plugins/findmyphone/kdeconnect_findmyphone.json +++ b/plugins/findmyphone/kdeconnect_findmyphone.json @@ -1,103 +1,101 @@ { "KPlugin": { "Authors": [ { "Email": "apparle@gmail.com", "Name": "Apoorv Parle", "Name[sr@ijekavian]": "Апорв Парле", "Name[sr@ijekavianlatin]": "Aporv Parle", "Name[sr@latin]": "Aporv Parle", "Name[sr]": "Апорв Парле", "Name[x-test]": "xxApoorv Parlexx" }, { "Email": "davidedmundson@kde.org", "Name": "David Edmundson", "Name[sr@ijekavian]": "Дејвид Едмундсон", "Name[sr@ijekavianlatin]": "Dejvid Edmundson", "Name[sr@latin]": "Dejvid Edmundson", "Name[sr]": "Дејвид Едмундсон", "Name[x-test]": "xxDavid Edmundsonxx" } ], "Description": "Find your lost phone by making it play an alarm sound", "Description[ar]": "جِد هاتفك الضّائع بتشغيل صوت المنبّه", "Description[ca@valencia]": "Troba el vostre telèfon perdut fent que reproduïsca un so d'alarma", "Description[ca]": "Troba el vostre telèfon perdut fent que reprodueixi un so d'alarma", "Description[cs]": "Najděte svůj telefon tím, že jej necháte přehrát zvuk upomínky", "Description[da]": "Find din forsvundne telefon ved at få den til at afspille en alarm", "Description[de]": "Finden Sie Ihr verlegtes Telefon, indem Sie mit ihm eine Warnton abspielen", "Description[el]": "Βρείτε το χαμένο σας τηλέφωνο με ηχητική ειδοποίηση", "Description[es]": "Encuentre su teléfono perdido haciéndole reproducir un sonido de alarma", "Description[et]": "Kaotsi läinud telefoni leidmine sellel häireheli esitamisega", - "Description[eu]": "Aurkitu galdutako telefonoa alarma-soinu bat jo araziz", "Description[fi]": "Löydä hukkaamasi puhelin laittamalla se soittamaan hälytysääntä", "Description[fr]": "Trouver votre téléphone perdu en déclenchant une alarme", "Description[gl]": "Reproducir un son de alarma nun teléfono móbil perdido para atopalo.", "Description[it]": "Trova il tuo telefono smarrito facendogli suonare un allarme sonoro", "Description[ko]": "알람 소리를 울려서 잃어버린 휴대폰 찾기", "Description[nl]": "Zoek uw verloren telefoon door het een wekkersignaal te laten spelen", "Description[nn]": "Finn telefonen din ved å la han spela eit lydsignal", "Description[pl]": "Znajdź twój zgubiony telefon odgrywając na nim dźwięk", "Description[pt]": "Descobrir o seu telefone perdido, fazendo-o tocar um som de alarme", "Description[pt_BR]": "Encontre seu telefone fazendo ele reproduzir um som", "Description[ru]": "Поиск утерянного телефона при помощи звукового сигнала", "Description[sk]": "Nájsť váš stratený telefón zahraním zvuku budíka", "Description[sr@ijekavian]": "Нађите изгубљени телефон активирањем звука аларма", "Description[sr@ijekavianlatin]": "Nađite izgubljeni telefon aktiviranjem zvuka alarma", "Description[sr@latin]": "Nađite izgubljeni telefon aktiviranjem zvuka alarma", "Description[sr]": "Нађите изгубљени телефон активирањем звука аларма", "Description[sv]": "Hitta din förlorade telefon genom att få den att spela ett alarmljud", "Description[tr]": "Bir alarm sesi çalarak kayıp telefonunuzu bulun ", "Description[uk]": "Знайти загублений телефон, наказавши йому відтворити дзвінок", "Description[x-test]": "xxFind your lost phone by making it play an alarm soundxx", "Description[zh_CN]": "通过播放闹铃声来找到您不见的手机", "Description[zh_TW]": "讓您的手機發出警報聲,讓您找到您遺失的手機。", "EnabledByDefault": true, "Encoding": "UTF-8", "Icon": "edit-find", "Id": "kdeconnect_findmyphone", "License": "GPL", "Name": "Ring my phone", "Name[ar]": "رنّ هاتفي", "Name[ca@valencia]": "Fes sonar el meu telèfon", "Name[ca]": "Fes sonar el meu telèfon", "Name[cs]": "Prozvonit můj telefon", "Name[da]": "Ring min telefon op", "Name[de]": "Mein Telefon anklingeln", "Name[el]": "Κουδούνισμα του τηλεφώνου μου", "Name[es]": "Hacer sonar mi teléfono", "Name[et]": "Helista minu telefonile", - "Name[eu]": "Jo nire telefonoaren dei-doinua", "Name[fi]": "Soita puhelimeeni", "Name[fr]": "Faire sonner mon téléphone", "Name[gl]": "Facer soar o meu móbil", "Name[it]": "Fai squillare il mio telefono", "Name[ko]": "내 휴대폰 울리기", "Name[nl]": "Bel mijn telefoon", "Name[nn]": "Ring telefonen", "Name[pl]": "Dzwoń z mojego telefonu", "Name[pt]": "Tocar o meu telefone", "Name[pt_BR]": "Tocar meu telefone", "Name[ru]": "Поиск телефона", "Name[sk]": "Prezvoniť môj telefón", "Name[sr@ijekavian]": "Звони мој телефону", "Name[sr@ijekavianlatin]": "Zvoni moj telefonu", "Name[sr@latin]": "Zvoni moj telefonu", "Name[sr]": "Звони мој телефону", "Name[sv]": "Hitta min telefon", "Name[tr]": "Telefonumu çaldır", "Name[uk]": "Дзвінок на вашому телефоні", "Name[x-test]": "xxRing my phonexx", "Name[zh_CN]": "让我的手机响铃", "Name[zh_TW]": "撥打我的電話", "ServiceTypes": [ "KdeConnect/Plugin" ], "Version": "0.1", "Website": "http://kde.org" }, "X-KdeConnect-OutgoingPackageType": [ "kdeconnect.findmyphone.request" ] } diff --git a/plugins/kdeconnect.notifyrc b/plugins/kdeconnect.notifyrc index 09e50741..70ed6376 100644 --- a/plugins/kdeconnect.notifyrc +++ b/plugins/kdeconnect.notifyrc @@ -1,730 +1,712 @@ [Global] IconName=kdeconnect Name=KDE Connect Name[ar]=كدي المتّصل Name[ast]=KDE Connect Name[bg]=KDE Connect Name[bs]=Konekcija KDE Name[ca]=KDE Connect Name[ca@valencia]=KDE Connect Name[cs]=KDE Connect Name[da]=KDE Connect Name[de]=KDE-Connect Name[el]=KDE Connect Name[en_GB]=KDE Connect Name[es]=KDE Connect Name[et]=KDE Connect -Name[eu]=KDE Connect Name[fi]=KDE Connect Name[fr]=KDE Connect Name[gl]=KDE Connect Name[he]=KDE Connect Name[hu]=KDE csatlakozás Name[it]=KDE Connect Name[ko]=KDE Connect Name[nl]=KDE Connect Name[nn]=KDE Connect Name[pl]=KDE Connect Name[pt]=KDE Connect Name[pt_BR]=KDE Connect Name[ro]=KDE Connect Name[ru]=KDE Connect Name[sk]=KDE Connect Name[sr]=КДЕ‑конекција Name[sr@ijekavian]=КДЕ‑конекција Name[sr@ijekavianlatin]=KDE‑konekcija Name[sr@latin]=KDE‑konekcija Name[sv]=KDE-anslut Name[tr]=KDE Connect Name[uk]=З’єднання KDE Name[x-test]=xxKDE Connectxx Name[zh_CN]=KDE Connect Name[zh_TW]=KDE 連線 Comment=Notifications from your devices Comment[ar]=الإخطارات من أجهزتك Comment[ast]=Avisos de los tos preseos Comment[bg]=Уведомления от устройствата ви Comment[bs]=Notifikacija sa Vašeg uređaja Comment[ca]=Notificacions dels vostres dispositius Comment[ca@valencia]=Notificacions dels vostres dispositius Comment[cs]=Oznamování z vašich zařízení Comment[da]=Bekendtgørelser fra dine enheder Comment[de]=Benachrichtigungen von Ihren Geräten Comment[el]=Ειδοποιήσεις από τις συσκευές σας Comment[en_GB]=Notifications from your devices Comment[es]=Notificaciones de sus dispositivos Comment[et]=Seadmete märguanded -Comment[eu]=Zure gailuetako jakinarazpenak Comment[fi]=Laitteesi ilmoitukset Comment[fr]=Notifications provenant de vos périphériques Comment[gl]=Notificacións de dispositivos. Comment[he]=התראות מההתקן שלך Comment[hu]=Az eszközökről származó értesítések Comment[it]=Notifiche dai tuoi dispositivi Comment[ko]=장치에 표시된 알림 Comment[nl]=Meldingen van uw apparaten Comment[nn]=Varslingar frå einingane dine Comment[pl]=Powiadomienia z urządzeń Comment[pt]=Notificações dos seus dispositivos Comment[pt_BR]=Notificações dos seus dispositivos Comment[ro]=Notificări de pe dispozitivele dumneavoastră Comment[ru]=Уведомления от мобильных устройств Comment[sk]=Oznámenia z vašich zariadení Comment[sr]=Обавештење са вашег уређаја Comment[sr@ijekavian]=Обавештење са вашег уређаја Comment[sr@ijekavianlatin]=Obaveštenje sa vašeg uređaja Comment[sr@latin]=Obaveštenje sa vašeg uređaja Comment[sv]=Underrättelser från dina apparater Comment[tr]=Cihazınızdan bildirimler Comment[uk]=Сповіщення з вашого пристрою Comment[x-test]=xxNotifications from your devicesxx Comment[zh_CN]=来自你设备的通知 Comment[zh_TW]=從您的裝置接收到通知 [Event/pairingRequest] Name=Pairing Request Name[ar]=طلب اقتران Name[ast]=Solicitú d'empareyamientu Name[bg]=Заявка за сдвояване Name[bs]=Zahtjev za uparivanje Name[ca]=Sol·licitud d'aparellament Name[ca@valencia]=Sol·licitud d'aparellament Name[cs]=Požadavek na párování Name[da]=Parringsanmodning Name[de]=Verbindungsanfrage Name[el]=Αίτημα σύζευξης Name[en_GB]=Pairing Request Name[es]=Petición de vinculación Name[et]=Paardumissoov -Name[eu]=Parekatzeko eskaria Name[fi]=Paripyyntö Name[fr]=Demande d'association Name[gl]=Solicitude de emparellamento Name[he]=בקשת התאמה Name[hu]=Párosítási kérés Name[it]=Richiesta di associazione Name[ko]=연결 요청 Name[nl]=Verzoek om een paar te maken Name[nn]=Parringsførespurnad Name[pl]=Żądanie parowania Name[pt]=Pedido de Emparelhamento Name[pt_BR]=Solicitação de emparelhamento Name[ru]=Запрос на сопряжение Name[sk]=Požiadavka na spárovanie Name[sr]=Захтев за упаривање Name[sr@ijekavian]=Захтев за упаривање Name[sr@ijekavianlatin]=Zahtev za uparivanje Name[sr@latin]=Zahtev za uparivanje Name[sv]=Begäran om ihopparning Name[tr]=Eşleşme İsteği Name[uk]=Запит щодо пов’язування Name[x-test]=xxPairing Requestxx Name[zh_CN]=配对请求 Name[zh_TW]=配對請求 Comment=Pairing request received from a device Comment[ar]=استُلم طلب اقتران من جهاز Comment[ast]=Recibióse una solicitú d'empareyamientu d'un preséu Comment[ca]=Les sol·licituds d'aparellament rebudes des d'un dispositiu Comment[ca@valencia]=Les sol·licituds d'aparellament rebudes des d'un dispositiu Comment[cs]=Požadavek na párování přijat ze zařízení Comment[da]=Parringsanmodning modtaget fra en enhed Comment[de]=Verbindungsanfrage von einem Gerät erhalten Comment[el]=Λήφθηκε αίτημα σύζευξης από μια συσκευή Comment[en_GB]=Pairing request received from a device Comment[es]=Petición de vinculación recibida desde un dispositivo Comment[et]=Seadmelt saadi paardumissoov -Comment[eu]=Parekatzeko eskaria jaso da gailu batetik Comment[fi]=Saatiin paripyyntö laitteelta Comment[fr]=Demande d'association provenant d'un périphérique Comment[gl]=Recibiuse unha solicitude de emparellamento dun dispositivo. Comment[he]=התקבלה בקשת התאמה מהתקן Comment[it]=Richiesta di associazione ricevuta da un dispositivo Comment[ko]=장치에서 연결 요청을 받음 Comment[nl]=Verzoek om een paar te maken ontvangen van apparaten Comment[nn]=Fekk parringsførespurnad frå eining Comment[pl]=Otrzymano żądanie parowania z urządzenia Comment[pt]=Pedido de emparelhamento recebido de um dispositivo Comment[pt_BR]=Solicitação de emparelhamento recebida de um dispositivo Comment[ru]=От мобильного устройства получен запрос на сопряжение Comment[sk]=Požiadavka na spárovanie prijatá zo zariadenia Comment[sr]=Захтев за упаривање примљен од уређаја Comment[sr@ijekavian]=Захтев за упаривање примљен од уређаја Comment[sr@ijekavianlatin]=Zahtev za uparivanje primljen od uređaja Comment[sr@latin]=Zahtev za uparivanje primljen od uređaja Comment[sv]=Begäran om ihopparning mottagen från en apparat Comment[tr]=Bir cihazdan alınan eşleştirme isteği Comment[uk]=Від пристрою отримано запит щодо пов’язування Comment[x-test]=xxPairing request received from a devicexx Comment[zh_CN]=收到来自一个设备的配对请求 Comment[zh_TW]=從您的裝置當中收到配對請求 Action=Popup [Event/callReceived] Name=Incoming Call Name[ar]=مكالمة واردة Name[ast]=Llamada entrante Name[bg]=Входящо обаждане Name[ca]=Trucada entrant Name[ca@valencia]=Trucada entrant Name[cs]=Příchozí hovor Name[da]=Indkommende opkald Name[de]=Eingehender Anruf Name[el]=Εισερχόμενη κλήση Name[en_GB]=Incoming Call Name[es]=Llamada entrante Name[et]=Sisenev kõne -Name[eu]=Sarrerako deia Name[fi]=Saapuva puhelu Name[fr]=Appel entrant Name[gl]=Chamada entrante Name[he]=שיחה נכנסת Name[hu]=Bejövő hívás Name[ia]=Appello in arrivata Name[it]=Chiamata in ingresso Name[ko]=수신 전화 Name[nl]=Inkomende oproep Name[nn]=Innkommande samtale Name[pl]=Rozmowa przychodząca Name[pt]=Chamada Recebida Name[pt_BR]=Chamada recebida Name[ru]=Входящий звонок Name[sk]=Prichádzajúci hovor Name[sr]=Долазни позив Name[sr@ijekavian]=Долазни позив Name[sr@ijekavianlatin]=Dolazni poziv Name[sr@latin]=Dolazni poziv Name[sv]=Inkommande samtal Name[tr]=Gelen Çağrı Name[uk]=Вхідний дзвінок Name[x-test]=xxIncoming Callxx Name[zh_CN]=收到呼叫 Name[zh_TW]=電話來電 Comment=Someone is calling you Comment[ar]=ثمّة من يتّصل بك Comment[ast]=Daquién ta llamándote Comment[bg]=Някой ви се обажда Comment[bs]=Neko Vas zove Comment[ca]=Algú us està trucant Comment[ca@valencia]=Algú vos està trucant Comment[cs]=Někdo vám volá Comment[da]=Nogen ringer til dig Comment[de]=Sie werden angerufen Comment[el]=Κάποιος σας καλεί Comment[en_GB]=Someone is calling you Comment[es]=Alguien le está llamando Comment[et]=Keegi helistab sulle -Comment[eu]=Norbait deitzen ari zaizu Comment[fi]=Sinulle soitetaan Comment[fr]=Quelqu'un vous appelle Comment[gl]=Está a recibir unha chamada de alguén. Comment[he]=מישהו מתקשר אילך Comment[hu]=Valaki hívja önt Comment[it]=Chiamata in arrivo Comment[ko]=누군가가 전화를 걸었음 Comment[nl]=Iemand belt u op Comment[nn]=Nokon ringjer deg Comment[pl]=Ktoś do ciebie dzwoni Comment[pt]=Alguém está a ligar-lhe Comment[pt_BR]=Alguém está chamando você Comment[ro]=Cineva vă apelează Comment[ru]=Вам кто-то звонит Comment[sk]=Niekto vám volá Comment[sr]=Неко вас зове Comment[sr@ijekavian]=Неко вас зове Comment[sr@ijekavianlatin]=Neko vas zove Comment[sr@latin]=Neko vas zove Comment[sv]=Någon ringer till dig Comment[tr]=Biri sizi arıyor Comment[uk]=Хтось телефонує вам Comment[x-test]=xxSomeone is calling youxx Comment[zh_CN]=某人正在呼叫您 Comment[zh_TW]=有人打電話給您 Action=Popup [Event/missedCall] Name=Missed Call Name[ar]=مكالمة فائتة Name[ast]=Llamada perdida Name[bg]=Пропуснато обаждане Name[ca]=Trucada perduda Name[ca@valencia]=Trucada perduda Name[cs]=Zmeškaný hovor Name[da]=Ubesvaret opkald Name[de]=Verpasster Anruf Name[el]=Αναπάντητη κλήση Name[en_GB]=Missed Call Name[es]=Llamada perdida Name[et]=Vastamata kõne -Name[eu]=Galdutako deia Name[fi]=Vastaamaton puhelu Name[fr]=Appel manqué Name[gl]=Chamada perdida Name[he]=שיחה שלא נענתה Name[hu]=Nem fogadott hívás Name[it]=Chiamate perse Name[ko]=부재 중 전화 Name[nl]=Gemiste oproep Name[nn]=Tapt oppringing Name[pl]=Połączenie nieodebrane Name[pt]=Chamada Não Atendida Name[pt_BR]=Chamada não atendida Name[ru]=Пропущенный звонок Name[sk]=Zmeškaný hovor Name[sr]=Пропуштен позив Name[sr@ijekavian]=Пропуштен позив Name[sr@ijekavianlatin]=Propušten poziv Name[sr@latin]=Propušten poziv Name[sv]=Missat samtal Name[tr]=Cevapsız Çağrı Name[uk]=Пропущений дзвінок Name[x-test]=xxMissed Callxx Name[zh_CN]=未接来电 Name[zh_TW]=未接來電 Comment=You have a missed call Comment[ar]=لقد فاتتك مكالمة Comment[ast]=Tienes una llamada perdida Comment[bg]=Имате неприето обаждане Comment[bs]=Imate propušten poziv Comment[ca]=Teniu una trucada perduda Comment[ca@valencia]=Teniu una trucada perduda Comment[cs]=Máte zmeškaný hovor Comment[da]=Du har et ubesvaret opkald Comment[de]=Sie haben einen Anruf verpasst Comment[el]=Έχετε μια αναπάντητη κλήση Comment[en_GB]=You have a missed call Comment[es]=Tiene una llamada perdida Comment[et]=Kõnele jäi vastamata -Comment[eu]=Galdutako dei bat duzu Comment[fi]=Sinulla on vastaamaton puhelu Comment[fr]=Vous avez un appel manqué Comment[gl]=Ten unha chamada perdida. Comment[he]=יש לך שיחה שלא נענטה Comment[hu]=Nem fogadott hívása van Comment[it]=Hai una chiamata persa Comment[ko]=부재 중 전화가 있음 Comment[nl]=U hebt een gemiste oproep Comment[nn]=Du har ei tapt oppringing Comment[pl]=Nie odebrałeś połączenia Comment[pt]=Tem uma chamada não atendida Comment[pt_BR]=Você tem uma chamada não atendida Comment[ro]=Ați pierdut un apel Comment[ru]=У вас есть пропущенный вызов Comment[sk]=Máte zmeškaný hovor Comment[sr]=Имате пропуштен позив Comment[sr@ijekavian]=Имате пропуштен позив Comment[sr@ijekavianlatin]=Imate propušten poziv Comment[sr@latin]=Imate propušten poziv Comment[sv]=Du har missat ett samtal Comment[tr]=Cevapsız çağrınız var Comment[uk]=Вами пропущено телефонний дзвінок Comment[x-test]=xxYou have a missed callxx Comment[zh_CN]=您有未接来电 Comment[zh_TW]=您有一通未接來電 Action=Popup [Event/smsReceived] Name=SMS Received Name[ar]=استُلمت رسالة Name[ast]=SMS recibíu Name[bg]=Получен SMS Name[ca]=S'ha rebut un SMS Name[ca@valencia]=S'ha rebut un SMS Name[cs]=SMS přijata Name[da]=SMS-modtaget Name[de]=SMS empfangen Name[el]=Λήφθηκε SMS Name[en_GB]=SMS Received Name[es]=SMS recibido Name[et]=SMS-i saamine -Name[eu]=SMS bat jaso da Name[fi]=Saatiin tekstiviesti Name[fr]=SMS reçu Name[gl]=Recibiuse un SMS Name[he]=התקבלה הודעת SMS Name[hu]=SMS érkezett Name[it]=SMS ricevuto Name[ko]=SMS 받음 Name[nl]=SMS ontvangen Name[nn]=SMS motteken Name[pl]=Otrzymano SMSa Name[pt]=SMS Recebido Name[pt_BR]=SMS recebido Name[ru]=Входящее SMS Name[sk]=Prijatá SMS Name[sr]=СМС примљен Name[sr@ijekavian]=СМС примљен Name[sr@ijekavianlatin]=SMS primljen Name[sr@latin]=SMS primljen Name[sv]=SMS mottaget Name[tr]=SMS Alındı Name[uk]=Отримано SMS Name[x-test]=xxSMS Receivedxx Name[zh_CN]=收到短信 Name[zh_TW]=您有收到短訊 Comment=Someone sent you an SMS Comment[ar]=ثمّة من أرسل رسالة إليك Comment[ast]=Daquién unvióte un SMS Comment[bg]=Някой ви изпрати текстово съобщение Comment[bs]=Neko Vam je poslao SMS poruku Comment[ca]=Algú us ha enviat un SMS Comment[ca@valencia]=Algú vos ha enviat un SMS Comment[cs]=Někdo vám poslal SMS Comment[da]=Nogen sendte dig en SMS Comment[de]=Jemand hat Ihnen eine SMS gesendet Comment[el]=Κάποιος σας έστειλε SMS Comment[en_GB]=Someone sent you an SMS Comment[es]=Alguien le ha enviado un SMS Comment[et]=Keegi saatis sulle SMS-i -Comment[eu]=Norbaitek SMS bat bidali dizu Comment[fi]=Sinulle lähetettiin tekstiviesti Comment[fr]=Quelqu'un vous a envoyé un SMS Comment[gl]=Recibiu unha mensaxe SMS de alguén. Comment[he]=מישהו שלח לך SMS Comment[hu]=Valaki SMS-t küldött önnek Comment[it]=Hai ricevuto un SMS Comment[ko]=누군가가 문자 메시지를 보냄 Comment[nl]=Iemand heeft u een SMS gestuurd Comment[nn]=Noko sende deg ein SMS Comment[pl]=Ktoś do ciebie wysłał SMSa Comment[pt]=Alguém lhe enviou um SMS Comment[pt_BR]=Alguém lhe enviou um SMS Comment[ro]=Cineva v-a trimis un SMS Comment[ru]=Вы получили SMS-сообщение Comment[sk]=Niekto vám poslal SMS Comment[sr]=Неко вам је послао СМС Comment[sr@ijekavian]=Неко вам је послао СМС Comment[sr@ijekavianlatin]=Neko vam je poslao SMS Comment[sr@latin]=Neko vam je poslao SMS Comment[sv]=Någon skickade ett SMS till dig Comment[tr]=Biri size SMS gönderdi Comment[uk]=Хтось надіслав вам SMS Comment[x-test]=xxSomeone sent you an SMSxx Comment[zh_CN]=某人给您发了短信 Comment[zh_TW]=有人送來一封簡訊 Action=Popup [Event/batteryLow] Name=Battery Low Name[ar]=البطّاريّة ضعيفة Name[ast]=Batería baxa Name[bg]=Изтощена батерия Name[ca]=Bateria baixa Name[ca@valencia]=Bateria baixa Name[cs]=Baterie je téměř vybitá Name[da]=Lavt batteri Name[de]=Akku-Ladestand niedrig Name[el]=Μπαταρία χαμηλή Name[en_GB]=Battery Low Name[es]=Batería baja Name[et]=Aku laetus on madal -Name[eu]=Bateria baxu Name[fi]=Akku vähissä Name[fr]=Batterie faible Name[gl]=Batería baixa Name[hu]=Alacsony töltöttség Name[ia]=Batteria basse Name[it]=Batteria a livello basso Name[ko]=배터리 부족 Name[nl]=Batterij op laag niveau Name[nn]=Lågt batterinivå Name[pl]=Bateria na niskim poziomie Name[pt]=Bateria Fraca Name[pt_BR]=Bateria fraca Name[ru]=Низкий заряд батареи Name[sk]=Batéria je slabá Name[sr]=Батерија при крају Name[sr@ijekavian]=Батерија при крају Name[sr@ijekavianlatin]=Baterija pri kraju Name[sr@latin]=Baterija pri kraju Name[sv]=Låg batteriladdning Name[tr]=Pil Zayıf Name[uk]=Низький рівень заряду Name[x-test]=xxBattery Lowxx Name[zh_CN]=电池电量低 Name[zh_TW]=電池低電量 Comment=Your battery is in low state Comment[ar]=بطّاريّتك في الحالة الضعيفة Comment[ast]=La to batería ta escosándose Comment[bg]=Батерията ви е с нисък заряд Comment[bs]=Vaša baterija je gotovo prazna Comment[ca]=La bateria està baixa Comment[ca@valencia]=La bateria està baixa Comment[cs]=Máte slabou baterii Comment[da]=Dit batteri er på lavt niveau Comment[de]=Der Ladestand Ihres Akkus ist niedrig Comment[el]=Η μπαταρία σας είναι σε χαμηλό επίπεδο Comment[en_GB]=Your battery is in low state Comment[es]=La batería está en nivel bajo Comment[et]=Aku täituvus on madal -Comment[eu]=Zure bateria egoera baxuan dago Comment[fi]=Akkusi virta on vähissä Comment[fr]=Votre batterie est faible Comment[gl]=A batería está esgotándose. Comment[he]=הבטריה שלך הולכת להגמר Comment[hu]=Az akkumulátora feszültsége alacsony Comment[it]=La tua batteria è al livello basso Comment[ko]=배터리가 부족함 Comment[nl]=Uw batterij is bijna leeg Comment[nn]=Det er lite batteri att Comment[pl]=Twoja bateria ma niski poziom naładowania Comment[pt]=A sua bateria está fraca Comment[pt_BR]=Sua bateria está com carga baixa Comment[ro]=Acumulatorul are un nivel scăzut Comment[ru]=Низкий заряд батареи мобильного устройства Comment[sk]=Vaša batéria je na nízkom stave Comment[sr]=Ваша батерија је на издисају Comment[sr@ijekavian]=Ваша батерија је на издисају Comment[sr@ijekavianlatin]=Vaša baterija je na izdisaju Comment[sr@latin]=Vaša baterija je na izdisaju Comment[sv]=Batteriet är nästan slut Comment[tr]=Pilinizin seviyesi düşük Comment[uk]=Рівень заряду акумулятора є низьким Comment[x-test]=xxYour battery is in low statexx Comment[zh_CN]=您的电池电量低 Comment[zh_TW]=您的電池處於低容量狀態 Action=Popup [Event/pingReceived] Name=Ping Received Name[ar]=استُلمت وكزة Name[ast]=Ping recibíu Name[bg]=Пингът е приет Name[ca]=S'ha rebut un ping Name[ca@valencia]=S'ha rebut un ping Name[cs]=Ping přijat Name[da]=Ping modtaget Name[de]=Ping empfangen Name[el]=Λήφθηκε ping Name[en_GB]=Ping Received Name[es]=Ping recibido Name[et]=Pingi saamine -Name[eu]=Ping jaso da Name[fi]=Saatiin tiedustelupaketti Name[fr]=Ping reçu Name[gl]=Recibiuse un ping Name[he]=התקבל פינג Name[hu]=Ping érkezett Name[it]=Ping ricevuto Name[ko]=핑 받음 Name[nl]=Ping ontvangen Name[nn]=Pingsignal motteke Name[pl]=Otrzymano ping Name[pt]=Contacto Recebido Name[pt_BR]=Ping recebido Name[ru]=Пинг получен Name[sk]=Prijatý ping Name[sr]=Примљен пинг Name[sr@ijekavian]=Примљен пинг Name[sr@ijekavianlatin]=Primljen ping Name[sr@latin]=Primljen ping Name[sv]=Ping mottaget Name[tr]=Ping Alındı Name[uk]=Отримано сигнал підтримки зв’язку Name[x-test]=xxPing Receivedxx Name[zh_CN]=收到 Ping Name[zh_TW]=收到Ping回應 Comment=Ping received Comment[ar]=استُلمت وكزة Comment[ast]=Recibióse un ping Comment[bg]=Пингът е приет Comment[bs]=Primili ste ping Comment[ca]=S'ha rebut un ping Comment[ca@valencia]=S'ha rebut un ping Comment[cs]=Ping přijat Comment[da]=Ping modtaget Comment[de]=Ping empfangen Comment[el]=Λήφθηκε ping Comment[en_GB]=Ping received Comment[es]=Ping recibido Comment[et]=Pingi saamine -Comment[eu]=Ping jaso da Comment[fi]=Saatiin tiedustelupaketti Comment[fr]=Ping reçu Comment[gl]=Recibiuse un “ping”. Comment[he]=התקבל פינג Comment[hu]=Ping érkezett Comment[it]=Hai ricevuto un ping Comment[ko]=핑 받음 Comment[nl]=Ping ontvangen Comment[nn]=Pingsignal motteke Comment[pl]=Otrzymano ping Comment[pt]=Pedido de rede recebido Comment[pt_BR]=Ping recebido Comment[ro]=Ping primit Comment[ru]=Получен тестовый сигнал Comment[sk]=Prijatý ping Comment[sr]=Примљен пинг Comment[sr@ijekavian]=Примљен пинг Comment[sr@ijekavianlatin]=Primljen ping Comment[sr@latin]=Primljen ping Comment[sv]=Ping mottaget Comment[tr]=Ping alındı Comment[uk]=Отримано сигнал підтримки зв’язку Comment[x-test]=xxPing receivedxx Comment[zh_CN]=收到 ping Comment[zh_TW]=接收到遠端的Ping回應封包 Action=Popup [Event/notification] Name=Generic Notification Name[ar]=إخطار عموميّ Name[ast]=Avisu xenéricu Name[bg]=Общо уведомление Name[ca]=Notificació genèrica Name[ca@valencia]=Notificació genèrica Name[cs]=Obecná hlášení Name[da]=Generisk bekendtgørelse Name[de]=Allgemeine Benachrichtigung Name[el]=Γενική ειδοποίηση Name[en_GB]=Generic Notification Name[es]=Notificación genérica Name[et]=Üldine märguanne -Name[eu]=Jakinarazpen arrunta Name[fi]=Yleinen ilmoitus Name[fr]=Notification Name[gl]=Notificación xenérica Name[he]=התראה כללית Name[hu]=Általános értesítés Name[it]=Notifica generica Name[ko]=일반 알림 Name[nl]=Algemene melding Name[nn]=Generell varsling Name[pl]=Zwykłe powiadomienie Name[pt]=Notificação Genérica Name[pt_BR]=Notificação genérica Name[ru]=Общее уведомление Name[sk]=Všeobecné upozornenie Name[sr]=Опште обавештење Name[sr@ijekavian]=Опште обавештење Name[sr@ijekavianlatin]=Opšte obaveštenje Name[sr@latin]=Opšte obaveštenje Name[sv]=Generell underrättelse Name[tr]=Genel Bildirim Name[uk]=Загальне сповіщення Name[x-test]=xxGeneric Notificationxx Name[zh_CN]=一般通知 Name[zh_TW]=通用通知 Comment=Notification received Comment[ar]=استُلم إخطار Comment[ast]=Recibióse un avisu Comment[bg]=Уведомлението е прието Comment[bs]=Primjeno obavještenje Comment[ca]=Notificació rebuda Comment[ca@valencia]=Notificació rebuda Comment[cs]=Bylo přijato upozornění Comment[da]=Bekendtgørelse modtaget Comment[de]=Benachrichtigung eingegangen Comment[el]=Λήφθηκε ειδοποίηση Comment[en_GB]=Notification received Comment[es]=Notificación recibida Comment[et]=Saadi märguanne -Comment[eu]=Jakinarazpena jaso da Comment[fi]=Saatiin ilmoitus Comment[fr]=Notification reçue Comment[gl]=Recibiuse unha notificación. Comment[he]=התראה התקבלה Comment[hu]=Értesítés érkezett Comment[it]=Hai ricevuto una notifica Comment[ko]=알림 받음 Comment[nl]=Melding ontvangen Comment[nn]=Varsling motteken Comment[pl]=Otrzymano powiadomienie Comment[pt]=Notificação recebida Comment[pt_BR]=Notificação recebida Comment[ro]=Notificare primită Comment[ru]=На мобильном устройстве получено уведомление Comment[sk]=Prijaté oznámenie Comment[sr]=Примљено је обавештење Comment[sr@ijekavian]=Примљено је обавештење Comment[sr@ijekavianlatin]=Primljeno je obaveštenje Comment[sr@latin]=Primljeno je obaveštenje Comment[sv]=Underrättelse mottagen Comment[tr]=Bildirim alındı Comment[uk]=Отримано сповіщення Comment[x-test]=xxNotification receivedxx Comment[zh_CN]=收到通知 Comment[zh_TW]=收到通知 Action=Popup [Event/transferReceived] Name=File Transfer Name[ar]=نقل الملفّات Name[ast]=Tresferencia de ficheros Name[bg]=Прехвърляне на файл Name[ca]=Transferència de fitxers Name[ca@valencia]=Transferència de fitxers Name[cs]=Přenos souboru Name[da]=Filoverførsel Name[de]=Dateiübertragung Name[el]=Μεταφορά αρχείου Name[en_GB]=File Transfer Name[es]=Transferencia de archivo Name[et]=Failiedastus -Name[eu]=Fitxategi-transferentzia Name[fi]=Tiedostonsiirto Name[fr]=Transfert de fichiers Name[gl]=Transferencia dun ficheiro Name[he]=העברת קובץ Name[hu]=Fájlátvitel Name[ia]=Transferimento de file Name[it]=Trasferimento file Name[ko]=파일 전송 Name[nl]=Bestandsoverdracht Name[nn]=Filoverføring Name[pl]=Przesył plików Name[pt]=Transferência de Ficheiros Name[pt_BR]=Transferência de arquivo Name[ru]=Передача файла Name[sk]=Prenos súboru Name[sr]=Пренос фајлова Name[sr@ijekavian]=Пренос фајлова Name[sr@ijekavianlatin]=Prenos fajlova Name[sr@latin]=Prenos fajlova Name[sv]=Filöverföring Name[tr]=Dosya Aktarımı Name[uk]=Перенесення файлів Name[x-test]=xxFile Transferxx Name[zh_CN]=文件传送 Name[zh_TW]=檔案傳輸 Comment=Incoming file Comment[ar]=ملفّ قادم Comment[ast]=Ficheru entrante Comment[bg]=Входящ файл Comment[ca]=Fitxer entrant Comment[ca@valencia]=Fitxer entrant Comment[cs]=Příchozí soubor Comment[da]=Indkommende fil Comment[de]=Eingehende Datei Comment[el]=Εισερχόμενο αρχείο Comment[en_GB]=Incoming file Comment[es]=Archivo entrante Comment[et]=Sisenev fail -Comment[eu]=Sarrerako fitxategia Comment[fi]=Saapuva tiedosto Comment[fr]=Fichier entrant Comment[gl]=Ficheiro entrante Comment[he]=קובץ מגיע Comment[hu]=Bejövő fájl Comment[it]=File in ingresso Comment[ko]=파일 수신 Comment[nl]=Inkomend bestand Comment[nn]=Innkommande fil Comment[pl]=Przychodzący plik Comment[pt]=Ficheiro recebido Comment[pt_BR]=Arquivo recebido Comment[ru]=С мобильного устройства отправлен файл Comment[sk]=Prichádzajúci súbor Comment[sr]=Долазни фајл Comment[sr@ijekavian]=Долазни фајл Comment[sr@ijekavianlatin]=Dolazni fajl Comment[sr@latin]=Dolazni fajl Comment[sv]=Inkommande fil Comment[tr]=Gelen dosya Comment[uk]=Вхідний файл Comment[x-test]=xxIncoming filexx Comment[zh_CN]=正在传入的文件 Comment[zh_TW]=接收檔案 Action=Popup diff --git a/plugins/kdeconnect_plugin.desktop b/plugins/kdeconnect_plugin.desktop index 5379fce9..28faacb0 100644 --- a/plugins/kdeconnect_plugin.desktop +++ b/plugins/kdeconnect_plugin.desktop @@ -1,51 +1,50 @@ [Desktop Entry] Type=ServiceType X-KDE-ServiceType=KdeConnect/Plugin X-KDE-Derived=KPluginInfo Name=KDEConnect Plugin Name[ar]=ملحقة KDEConnect Name[ast]=Complementu de KDEConnect Name[bg]=Приставка на KDEConnect Name[bs]=Priključak za KDE konekciju Name[ca]=Connector del KDE Connect Name[ca@valencia]=Connector del KDE Connect Name[cs]=Modul KDEConnect Name[da]=KDEConnect-plugin Name[de]=KDEConnect-Modul Name[el]=Πρόσθετο του KDEConnect Name[en_GB]=KDEConnect Plugin Name[es]=Complemento de KDEConnect Name[et]=KDEConnecti plugin -Name[eu]=KDEConnect plugina Name[fi]=KDE Connect -liitännäinen Name[fr]=Module externe KDEConnect Name[gl]=Complemento de KDE Connect Name[he]=תוספי KDEConnect Name[hu]=KDEConnect bővítmény Name[it]=Estensione KDEConnect Name[ko]=KDEConnect 플러그인 Name[nl]=Plug-in van KDEConnect Name[nn]=KDEConnect-tillegg Name[pl]=Wtyczka KDEConnect Name[pt]='Plugin' do KDEConnect Name[pt_BR]=Plugin do KDEConnect Name[ro]=Extensie KDEConnect Name[ru]=Модуль KDE Connect Name[sk]=Plugin KDEConnect Name[sr]=КДЕ‑конекцијин прикључак Name[sr@ijekavian]=КДЕ‑конекцијин прикључак Name[sr@ijekavianlatin]=KDE‑konekcijin priključak Name[sr@latin]=KDE‑konekcijin priključak Name[sv]=KDE anslutningsinsticksprogram Name[tr]=KDEConnect Eklentisi Name[uk]=Додаток KDEConnect Name[x-test]=xxKDEConnect Pluginxx Name[zh_CN]=KDEConnect 插件 Name[zh_TW]=KDE 連線擴展功能插件 # mandatory, list of all the package types supported [PropertyDef::X-KdeConnect-SupportedPackageType] Type=QStringList [PropertyDef::X-KdeConnect-OutgoingPackageType] Type=QStringList diff --git a/plugins/lockdevice/kdeconnect_lockdevice.json b/plugins/lockdevice/kdeconnect_lockdevice.json index 520a94bf..e9e95562 100644 --- a/plugins/lockdevice/kdeconnect_lockdevice.json +++ b/plugins/lockdevice/kdeconnect_lockdevice.json @@ -1,96 +1,94 @@ { "Encoding": "UTF-8", "KPlugin": { "Authors": [ { "Email": "aleixpol@kde.org", "Name": "Aleix Pol", "Name[sr@ijekavian]": "Алекс Пол Гонзалез", "Name[sr@ijekavianlatin]": "Aleks Pol Gonzalez", "Name[sr@latin]": "Aleks Pol Gonzalez", "Name[sr]": "Алекс Пол Гонзалез", "Name[x-test]": "xxAleix Polxx" } ], "Description": "Locks your systems", "Description[ar]": "أوصد الأنظمة", "Description[ca@valencia]": "Bloqueja els vostres sistemes", "Description[ca]": "Bloqueja els vostres sistemes", "Description[cs]": "Zamkne vaše systémy", "Description[da]": "Låser dine systemer", "Description[de]": "Sperrt Ihre Systeme", "Description[el]": "Κλειδώνει τα συστήματά σας", "Description[es]": "Bloquear sus sistemas", "Description[et]": "Oma süsteemide lukustamine", - "Description[eu]": "Zure sistemak blokeatzen ditu", "Description[fi]": "Lukitsee järjestelmäsi", "Description[fr]": "Bloque votre système", "Description[gl]": "Bloquea os seus sistemas.", "Description[it]": "Blocca i tuoi sistemi", "Description[ko]": "내 시스템 잠그기", "Description[nl]": "Vergrendeld uw systemen", "Description[nn]": "Lås systemet", "Description[pl]": "Zablokuj swoje systemy", "Description[pt]": "Bloqueia os seus sistemas", "Description[pt_BR]": "Bloqueia seus sistemas", "Description[ru]": "Блокировка ваших систем", "Description[sk]": "Zamkne vaše systémy", "Description[sr@ijekavian]": "Закључава ваш систем", "Description[sr@ijekavianlatin]": "Zaključava vaš sistem", "Description[sr@latin]": "Zaključava vaš sistem", "Description[sr]": "Закључава ваш систем", "Description[sv]": "Låser dina system", "Description[tr]": "Sistemlerinizi kilitler", "Description[uk]": "Блокує вашу систему", "Description[x-test]": "xxLocks your systemsxx", "Description[zh_CN]": "锁定您的系统", "Description[zh_TW]": "鎖定您的系統", "EnabledByDefault": true, "Icon": "applications-miscelaneaous", "Id": "kdeconnect_lockdevice", "License": "GPL", "Name": "LockDevice", "Name[ar]": "أوصد الجهاز", "Name[ca@valencia]": "Bloqueja el dispositiu", "Name[ca]": "Bloqueja el dispositiu", "Name[cs]": "Uzamknout zařízení", "Name[da]": "LåsEnhed", "Name[de]": "Gerätesperrung", "Name[es]": "Bloquear dispositivo", "Name[et]": "Seadme lukustamine", - "Name[eu]": "BlokeatuGailua", "Name[fi]": "Lukitse laite", "Name[gl]": "Bloqueo do dispositivo", "Name[it]": "Blocco dispositivo", "Name[ko]": "장치 잠금", "Name[nl]": "Apparaat vergrendelen", "Name[nn]": "Lås eining", "Name[pl]": "ZablokujUrządzenie", "Name[pt]": "Bloqueio de Dispositivo", "Name[pt_BR]": "Bloqueio de dispositivo", "Name[ru]": "Блокировка устройства", "Name[sk]": "Zamknúť zariadenie", "Name[sr@ijekavian]": "Катанац", "Name[sr@ijekavianlatin]": "Katanac", "Name[sr@latin]": "Katanac", "Name[sr]": "Катанац", "Name[sv]": "Lås enhet", "Name[tr]": "AygıtıKilitle", "Name[x-test]": "xxLockDevicexx", "Name[zh_CN]": "锁定设备", "Name[zh_TW]": "鎖定裝置", "ServiceTypes": [ "KdeConnect/Plugin" ], "Version": "0.1", "Website": "https://kde.org" }, "X-KdeConnect-OutgoingPackageType": [ "kdeconnect.lock.request", "kdeconnect.lock" ], "X-KdeConnect-SupportedPackageType": [ "kdeconnect.lock.request", "kdeconnect.lock" ] } diff --git a/plugins/lockdevice/lockdeviceplugin.h b/plugins/lockdevice/lockdeviceplugin.h index 44fc134b..24bb57e5 100644 --- a/plugins/lockdevice/lockdeviceplugin.h +++ b/plugins/lockdevice/lockdeviceplugin.h @@ -1,62 +1,62 @@ /** * Copyright 2015 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 LOCKDEVICEPLUGIN_H #define LOCKDEVICEPLUGIN_H #include #include class OrgFreedesktopScreenSaverInterface; #define PACKAGE_TYPE_LOCK QStringLiteral("kdeconnect.lock") #define PACKAGE_TYPE_LOCK_REQUEST QStringLiteral("kdeconnect.lock.request") class Q_DECL_EXPORT LockDevicePlugin : public KdeConnectPlugin { Q_OBJECT Q_CLASSINFO("D-Bus Interface", "org.kde.kdeconnect.device.lockdevice") Q_PROPERTY(bool isLocked READ isLocked WRITE setLocked NOTIFY lockedChanged) public: - explicit LockDevicePlugin(QObject *parent, const QVariantList &args); + explicit LockDevicePlugin(QObject* parent, const QVariantList &args); ~LockDevicePlugin() override; bool isLocked() const; void setLocked(bool b); QString dbusPath() const override; void connected() override; bool receivePackage(const NetworkPackage & np) override; Q_SIGNALS: void lockedChanged(bool locked); private: bool m_remoteLocked; OrgFreedesktopScreenSaverInterface* iface(); OrgFreedesktopScreenSaverInterface* m_iface; }; #endif diff --git a/plugins/mousepad/kdeconnect_mousepad.json b/plugins/mousepad/kdeconnect_mousepad.json index b7b052eb..4274644a 100644 --- a/plugins/mousepad/kdeconnect_mousepad.json +++ b/plugins/mousepad/kdeconnect_mousepad.json @@ -1,97 +1,95 @@ { "Encoding": "UTF-8", "KPlugin": { "Authors": [ { "Email": "ahmedibrahimkhali@gmail.com", "Name": "Ahmed I. Khalil", "Name[ar]": "أحمد إبراهيم خليل", "Name[sr@ijekavian]": "Ахмед И. Калил", "Name[sr@ijekavianlatin]": "Ahmed I. Kalil", "Name[sr@latin]": "Ahmed I. Kalil", "Name[sr]": "Ахмед И. Калил", "Name[x-test]": "xxAhmed I. Khalilxx" } ], "Description": "Use your phone as a touchpad and keyboard", "Description[ar]": "استخدم الهاتف كفأرة ولوحة مفاتيح", "Description[ca@valencia]": "Empra el telèfon com un ratolí tàctil i teclat", "Description[ca]": "Empra el telèfon com un ratolí tàctil i teclat", "Description[cs]": "Používejte svůj telefon jako touchpad a klávesnici", "Description[da]": "Brug din telefon som touchpad og tastatur", "Description[de]": "Verwendet Ihr Handy als Touchpad und Tastatur", "Description[el]": "Χρήση του τηλεφώνου σας ως οθόνη αφής και πληκτρολογίου", "Description[es]": "Usar teléfono como panel táctil y teclado", "Description[et]": "Telefoni kasutamine puutepadja ja klaviatuurina", - "Description[eu]": "Erabili zure telefonoa touchpad eta teklatu gisa", "Description[fi]": "Käytä puhelintasi kosketuslevynä ja näppäimistönä", "Description[fr]": "Utilisez votre téléphone comme un pavé tactile et un clavier", "Description[gl]": "Usar o teléfono móbil como touchpad e teclado.", "Description[hu]": "A telefon használata érintőtáblaként és billentyűzetként", "Description[it]": "Usa il telefono come touchpad e tastiera", "Description[ko]": "휴대폰을 터치패드와 키보드로 사용", "Description[nl]": "Uw telefoon gebruiken als een touchpad en toetsenbord", "Description[nn]": "Bruk telefonen som styreplate og tastatur", "Description[pl]": "Używaj swojego telefonu jako gładzika i klawiatury", "Description[pt]": "Use o seu telefone como um rato e teclado por toque", "Description[pt_BR]": "Use seu telefone como um touchpad e teclado", "Description[ru]": "Использование телефона в качестве сенсорной панели и клавиатуры", "Description[sk]": "Použite váš telefón ako touchpad a klávesnicu", "Description[sr@ijekavian]": "Користите телефон као додирник и тастатуру", "Description[sr@ijekavianlatin]": "Koristite telefon kao dodirnik i tastaturu", "Description[sr@latin]": "Koristite telefon kao dodirnik i tastaturu", "Description[sr]": "Користите телефон као додирник и тастатуру", "Description[sv]": "Använd telefonen som mus och tangentbord", "Description[tr]": "Telefonunuzu dokunmatik yüzey ve klayve olarak kullanın", "Description[uk]": "Скористайтеся телефоном як замінником сенсорної панелі і клавіатури", "Description[x-test]": "xxUse your phone as a touchpad and keyboardxx", "Description[zh_CN]": "用您的手机作为触摸板和键盘", "Description[zh_TW]": "讓您的智慧型手機當作觸碰板與鍵盤", "EnabledByDefault": true, "Icon": "edit-select", "Id": "kdeconnect_mousepad", "License": "GPL", "Name": "Virtual input", "Name[ar]": "دخل وهميّ", "Name[ca@valencia]": "Entrada virtual", "Name[ca]": "Entrada virtual", "Name[cs]": "Virtuální vstup", "Name[da]": "Virtuelt input", "Name[de]": "Virtuelle Eingabe", "Name[el]": "Εικονικά στοιχεία εισόδου", "Name[es]": "Entrada virtual", "Name[et]": "Virtuaalsisestus", - "Name[eu]": "Sarrera birtuala", "Name[fi]": "Virtuaalinen syöttö", "Name[fr]": "Entrée virtuelle", "Name[gl]": "Entrada virtual", "Name[hu]": "Virtuális bevitel", "Name[it]": "Inserimento virtuale", "Name[ko]": "가상 입력", "Name[nl]": "Virtuele invoer", "Name[nn]": "Virtuelt tastatur", "Name[pl]": "Wirtualna obsługa", "Name[pt]": "Entrada virtual", "Name[pt_BR]": "Entrada virtual", "Name[ru]": "Виртуальный ввод", "Name[sk]": "Virtuálny vstup", "Name[sr@ijekavian]": "Виртуелни унос", "Name[sr@ijekavianlatin]": "Virtuelni unos", "Name[sr@latin]": "Virtuelni unos", "Name[sr]": "Виртуелни унос", "Name[sv]": "Virtuell inmatning", "Name[tr]": "Sanal içe aktarma", "Name[uk]": "Віртуальне введення даних", "Name[x-test]": "xxVirtual inputxx", "Name[zh_CN]": "虚拟输入", "Name[zh_TW]": "虛擬輸入", "ServiceTypes": [ "KdeConnect/Plugin" ], "Version": "0.1" }, "X-KdeConnect-OutgoingPackageType": [], "X-KdeConnect-SupportedPackageType": [ "kdeconnect.mousepad.request" ] } diff --git a/plugins/mousepad/mousepadplugin.cpp b/plugins/mousepad/mousepadplugin.cpp index 24846698..48689eef 100644 --- a/plugins/mousepad/mousepadplugin.cpp +++ b/plugins/mousepad/mousepadplugin.cpp @@ -1,337 +1,337 @@ /** * Copyright 2014 Ahmed I. Khalil * Copyright 2015 Martin Gräßlin * * 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 "mousepadplugin.h" #include #include #include #include #if HAVE_X11 #include #include #include #include #endif #if HAVE_WAYLAND #include #include #include #endif K_PLUGIN_FACTORY_WITH_JSON( KdeConnectPluginFactory, "kdeconnect_mousepad.json", registerPlugin< MousepadPlugin >(); ) enum MouseButtons { LeftMouseButton = 1, MiddleMouseButton = 2, RightMouseButton = 3, MouseWheelUp = 4, MouseWheelDown = 5 }; #if HAVE_X11 //Translation table to keep in sync within all the implementations int SpecialKeysMap[] = { 0, // Invalid XK_BackSpace, // 1 XK_Tab, // 2 XK_Linefeed, // 3 XK_Left, // 4 XK_Up, // 5 XK_Right, // 6 XK_Down, // 7 XK_Page_Up, // 8 XK_Page_Down, // 9 XK_Home, // 10 XK_End, // 11 XK_Return, // 12 XK_Delete, // 13 XK_Escape, // 14 XK_Sys_Req, // 15 XK_Scroll_Lock, // 16 0, // 17 0, // 18 0, // 19 0, // 20 XK_F1, // 21 XK_F2, // 22 XK_F3, // 23 XK_F4, // 24 XK_F5, // 25 XK_F6, // 26 XK_F7, // 27 XK_F8, // 28 XK_F9, // 29 XK_F10, // 30 XK_F11, // 31 XK_F12, // 32 }; #endif template size_t arraySize(T(&arr)[N]) { (void)arr; return N; } MousepadPlugin::MousepadPlugin(QObject* parent, const QVariantList& args) : KdeConnectPlugin(parent, args) #if HAVE_X11 , m_fakekey(nullptr) , m_x11(QX11Info::isPlatformX11()) #else , m_x11(false) #endif #if HAVE_WAYLAND , m_waylandInput(nullptr) , m_waylandAuthenticationRequested(false) #endif { #if HAVE_WAYLAND setupWaylandIntegration(); #endif } MousepadPlugin::~MousepadPlugin() { #if HAVE_X11 if (m_fakekey) { free(m_fakekey); m_fakekey = nullptr; } #endif } bool MousepadPlugin::receivePackage(const NetworkPackage& np) { #if HAVE_X11 if (m_x11) { return handlePackageX11(np); } #endif #if HAVE_WAYLAND if (m_waylandInput) { if (!m_waylandAuthenticationRequested) { m_waylandInput->authenticate(i18n("KDE Connect"), i18n("Use your phone as a touchpad and keyboard")); m_waylandAuthenticationRequested = true; } handPackageWayland(np); } #endif return false; } #if HAVE_X11 bool isLeftHanded(Display * display) { unsigned char map[20]; int num_buttons = XGetPointerMapping(display, map, 20); if( num_buttons == 1 ) { return false; } else if( num_buttons == 2 ) { return ( (int)map[0] == 2 && (int)map[1] == 1 ); } else { return ( (int)map[0] == 3 && (int)map[2] == 1 ); } } #endif #if HAVE_X11 -bool MousepadPlugin::handlePackageX11(const NetworkPackage &np) +bool MousepadPlugin::handlePackageX11(const NetworkPackage& np) { //qDebug() << np.serialize(); //TODO: Split mouse/keyboard in two different plugins to avoid this big if statement float dx = np.get(QStringLiteral("dx"), 0); float dy = np.get(QStringLiteral("dy"), 0); bool isSingleClick = np.get(QStringLiteral("singleclick"), false); bool isDoubleClick = np.get(QStringLiteral("doubleclick"), false); bool isMiddleClick = np.get(QStringLiteral("middleclick"), false); bool isRightClick = np.get(QStringLiteral("rightclick"), false); bool isSingleHold = np.get(QStringLiteral("singlehold"), false); bool isSingleRelease = np.get(QStringLiteral("singlerelease"), false); bool isScroll = np.get(QStringLiteral("scroll"), false); QString key = np.get(QStringLiteral("key"), QLatin1String("")); int specialKey = np.get(QStringLiteral("specialKey"), 0); if (isSingleClick || isDoubleClick || isMiddleClick || isRightClick || isSingleHold || isScroll || !key.isEmpty() || specialKey) { - Display *display = QX11Info::display(); + Display* display = QX11Info::display(); if(!display) { return false; } bool leftHanded = isLeftHanded(display); int mainMouseButton = leftHanded? RightMouseButton : LeftMouseButton; int secondaryMouseButton = leftHanded? LeftMouseButton : RightMouseButton; if (isSingleClick) { XTestFakeButtonEvent(display, mainMouseButton, True, 0); XTestFakeButtonEvent(display, mainMouseButton, False, 0); } else if (isDoubleClick) { XTestFakeButtonEvent(display, mainMouseButton, True, 0); XTestFakeButtonEvent(display, mainMouseButton, False, 0); XTestFakeButtonEvent(display, mainMouseButton, True, 0); XTestFakeButtonEvent(display, mainMouseButton, False, 0); } else if (isMiddleClick) { XTestFakeButtonEvent(display, MiddleMouseButton, True, 0); XTestFakeButtonEvent(display, MiddleMouseButton, False, 0); } else if (isRightClick) { XTestFakeButtonEvent(display, secondaryMouseButton, True, 0); XTestFakeButtonEvent(display, secondaryMouseButton, False, 0); } else if (isSingleHold){ //For drag'n drop XTestFakeButtonEvent(display, mainMouseButton, True, 0); } else if (isSingleRelease){ //For drag'n drop. NEVER USED (release is done by tapping, which actually triggers a isSingleClick). Kept here for future-proofnes. XTestFakeButtonEvent(display, mainMouseButton, False, 0); } else if (isScroll) { if (dy < 0) { XTestFakeButtonEvent(display, MouseWheelDown, True, 0); XTestFakeButtonEvent(display, MouseWheelDown, False, 0); } else if (dy > 0) { XTestFakeButtonEvent(display, MouseWheelUp, True, 0); XTestFakeButtonEvent(display, MouseWheelUp, False, 0); } } else if (!key.isEmpty() || specialKey) { bool ctrl = np.get(QStringLiteral("ctrl"), false); bool alt = np.get(QStringLiteral("alt"), false); bool shift = np.get(QStringLiteral("shift"), false); if (ctrl) XTestFakeKeyEvent (display, XKeysymToKeycode(display, XK_Control_L), True, 0); if (alt) XTestFakeKeyEvent (display, XKeysymToKeycode(display, XK_Alt_L), True, 0); if (shift) XTestFakeKeyEvent (display, XKeysymToKeycode(display, XK_Shift_L), True, 0); if (specialKey) { if (specialKey >= (int)arraySize(SpecialKeysMap)) { qWarning() << "Unsupported special key identifier"; return false; } int keycode = XKeysymToKeycode(display, SpecialKeysMap[specialKey]); XTestFakeKeyEvent (display, keycode, True, 0); XTestFakeKeyEvent (display, keycode, False, 0); } else { if (!m_fakekey) { m_fakekey = fakekey_init(display); if (!m_fakekey) { qWarning() << "Failed to initialize libfakekey"; return false; } } //We use fakekey here instead of XTest (above) because it can handle utf characters instead of keycodes. for (int i=0;icreate(connection); connect(registry, &Registry::fakeInputAnnounced, this, [this, registry] (quint32 name, quint32 version) { m_waylandInput = registry->createFakeInput(name, version, this); } ); registry->setup(); } -bool MousepadPlugin::handPackageWayland(const NetworkPackage &np) +bool MousepadPlugin::handPackageWayland(const NetworkPackage& np) { const float dx = np.get(QStringLiteral("dx"), 0); const float dy = np.get(QStringLiteral("dy"), 0); const bool isSingleClick = np.get(QStringLiteral("singleclick"), false); const bool isDoubleClick = np.get(QStringLiteral("doubleclick"), false); const bool isMiddleClick = np.get(QStringLiteral("middleclick"), false); const bool isRightClick = np.get(QStringLiteral("rightclick"), false); const bool isSingleHold = np.get(QStringLiteral("singlehold"), false); const bool isSingleRelease = np.get(QStringLiteral("singlerelease"), false); const bool isScroll = np.get(QStringLiteral("scroll"), false); const QString key = np.get(QStringLiteral("key"), QLatin1String("")); const int specialKey = np.get(QStringLiteral("specialKey"), 0); if (isSingleClick || isDoubleClick || isMiddleClick || isRightClick || isSingleHold || isScroll || !key.isEmpty() || specialKey) { if (isSingleClick) { m_waylandInput->requestPointerButtonClick(Qt::LeftButton); } else if (isDoubleClick) { m_waylandInput->requestPointerButtonClick(Qt::LeftButton); m_waylandInput->requestPointerButtonClick(Qt::LeftButton); } else if (isMiddleClick) { m_waylandInput->requestPointerButtonClick(Qt::MiddleButton); } else if (isRightClick) { m_waylandInput->requestPointerButtonClick(Qt::RightButton); } else if (isSingleHold){ //For drag'n drop m_waylandInput->requestPointerButtonPress(Qt::LeftButton); } else if (isSingleRelease){ //For drag'n drop. NEVER USED (release is done by tapping, which actually triggers a isSingleClick). Kept here for future-proofnes. m_waylandInput->requestPointerButtonRelease(Qt::LeftButton); } else if (isScroll) { m_waylandInput->requestPointerAxis(Qt::Vertical, dy); } else if (!key.isEmpty() || specialKey) { // TODO: implement key support } } else { //Is a mouse move event m_waylandInput->requestPointerMove(QSizeF(dx, dy)); } return true; } #endif #include "mousepadplugin.moc" diff --git a/plugins/mousepad/mousepadplugin.h b/plugins/mousepad/mousepadplugin.h index e9017322..3bb45fd2 100644 --- a/plugins/mousepad/mousepadplugin.h +++ b/plugins/mousepad/mousepadplugin.h @@ -1,71 +1,71 @@ /** * Copyright 2014 Ahmed I. Khalil * * 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 MOUSEPADPLUGIN_H #define MOUSEPADPLUGIN_H #include #include #include struct FakeKey; #if HAVE_WAYLAND namespace KWayland { namespace Client { class FakeInput; } } #endif class MousepadPlugin : public KdeConnectPlugin { Q_OBJECT public: - explicit MousepadPlugin(QObject *parent, const QVariantList &args); + explicit MousepadPlugin(QObject* parent, const QVariantList& args); ~MousepadPlugin() override; bool receivePackage(const NetworkPackage& np) override; void connected() override { } private: #if HAVE_X11 bool handlePackageX11(const NetworkPackage& np); #endif #if HAVE_WAYLAND void setupWaylandIntegration(); bool handPackageWayland(const NetworkPackage& np); #endif #if HAVE_X11 FakeKey* m_fakekey; #endif const bool m_x11; #if HAVE_WAYLAND - KWayland::Client::FakeInput *m_waylandInput; + KWayland::Client::FakeInput* m_waylandInput; bool m_waylandAuthenticationRequested; #endif }; #endif diff --git a/plugins/mousepad_windows/kdeconnect_mousepad.json b/plugins/mousepad_windows/kdeconnect_mousepad.json index b7b052eb..4274644a 100644 --- a/plugins/mousepad_windows/kdeconnect_mousepad.json +++ b/plugins/mousepad_windows/kdeconnect_mousepad.json @@ -1,97 +1,95 @@ { "Encoding": "UTF-8", "KPlugin": { "Authors": [ { "Email": "ahmedibrahimkhali@gmail.com", "Name": "Ahmed I. Khalil", "Name[ar]": "أحمد إبراهيم خليل", "Name[sr@ijekavian]": "Ахмед И. Калил", "Name[sr@ijekavianlatin]": "Ahmed I. Kalil", "Name[sr@latin]": "Ahmed I. Kalil", "Name[sr]": "Ахмед И. Калил", "Name[x-test]": "xxAhmed I. Khalilxx" } ], "Description": "Use your phone as a touchpad and keyboard", "Description[ar]": "استخدم الهاتف كفأرة ولوحة مفاتيح", "Description[ca@valencia]": "Empra el telèfon com un ratolí tàctil i teclat", "Description[ca]": "Empra el telèfon com un ratolí tàctil i teclat", "Description[cs]": "Používejte svůj telefon jako touchpad a klávesnici", "Description[da]": "Brug din telefon som touchpad og tastatur", "Description[de]": "Verwendet Ihr Handy als Touchpad und Tastatur", "Description[el]": "Χρήση του τηλεφώνου σας ως οθόνη αφής και πληκτρολογίου", "Description[es]": "Usar teléfono como panel táctil y teclado", "Description[et]": "Telefoni kasutamine puutepadja ja klaviatuurina", - "Description[eu]": "Erabili zure telefonoa touchpad eta teklatu gisa", "Description[fi]": "Käytä puhelintasi kosketuslevynä ja näppäimistönä", "Description[fr]": "Utilisez votre téléphone comme un pavé tactile et un clavier", "Description[gl]": "Usar o teléfono móbil como touchpad e teclado.", "Description[hu]": "A telefon használata érintőtáblaként és billentyűzetként", "Description[it]": "Usa il telefono come touchpad e tastiera", "Description[ko]": "휴대폰을 터치패드와 키보드로 사용", "Description[nl]": "Uw telefoon gebruiken als een touchpad en toetsenbord", "Description[nn]": "Bruk telefonen som styreplate og tastatur", "Description[pl]": "Używaj swojego telefonu jako gładzika i klawiatury", "Description[pt]": "Use o seu telefone como um rato e teclado por toque", "Description[pt_BR]": "Use seu telefone como um touchpad e teclado", "Description[ru]": "Использование телефона в качестве сенсорной панели и клавиатуры", "Description[sk]": "Použite váš telefón ako touchpad a klávesnicu", "Description[sr@ijekavian]": "Користите телефон као додирник и тастатуру", "Description[sr@ijekavianlatin]": "Koristite telefon kao dodirnik i tastaturu", "Description[sr@latin]": "Koristite telefon kao dodirnik i tastaturu", "Description[sr]": "Користите телефон као додирник и тастатуру", "Description[sv]": "Använd telefonen som mus och tangentbord", "Description[tr]": "Telefonunuzu dokunmatik yüzey ve klayve olarak kullanın", "Description[uk]": "Скористайтеся телефоном як замінником сенсорної панелі і клавіатури", "Description[x-test]": "xxUse your phone as a touchpad and keyboardxx", "Description[zh_CN]": "用您的手机作为触摸板和键盘", "Description[zh_TW]": "讓您的智慧型手機當作觸碰板與鍵盤", "EnabledByDefault": true, "Icon": "edit-select", "Id": "kdeconnect_mousepad", "License": "GPL", "Name": "Virtual input", "Name[ar]": "دخل وهميّ", "Name[ca@valencia]": "Entrada virtual", "Name[ca]": "Entrada virtual", "Name[cs]": "Virtuální vstup", "Name[da]": "Virtuelt input", "Name[de]": "Virtuelle Eingabe", "Name[el]": "Εικονικά στοιχεία εισόδου", "Name[es]": "Entrada virtual", "Name[et]": "Virtuaalsisestus", - "Name[eu]": "Sarrera birtuala", "Name[fi]": "Virtuaalinen syöttö", "Name[fr]": "Entrée virtuelle", "Name[gl]": "Entrada virtual", "Name[hu]": "Virtuális bevitel", "Name[it]": "Inserimento virtuale", "Name[ko]": "가상 입력", "Name[nl]": "Virtuele invoer", "Name[nn]": "Virtuelt tastatur", "Name[pl]": "Wirtualna obsługa", "Name[pt]": "Entrada virtual", "Name[pt_BR]": "Entrada virtual", "Name[ru]": "Виртуальный ввод", "Name[sk]": "Virtuálny vstup", "Name[sr@ijekavian]": "Виртуелни унос", "Name[sr@ijekavianlatin]": "Virtuelni unos", "Name[sr@latin]": "Virtuelni unos", "Name[sr]": "Виртуелни унос", "Name[sv]": "Virtuell inmatning", "Name[tr]": "Sanal içe aktarma", "Name[uk]": "Віртуальне введення даних", "Name[x-test]": "xxVirtual inputxx", "Name[zh_CN]": "虚拟输入", "Name[zh_TW]": "虛擬輸入", "ServiceTypes": [ "KdeConnect/Plugin" ], "Version": "0.1" }, "X-KdeConnect-OutgoingPackageType": [], "X-KdeConnect-SupportedPackageType": [ "kdeconnect.mousepad.request" ] } diff --git a/plugins/mousepad_windows/mousepadplugin_windows.h b/plugins/mousepad_windows/mousepadplugin_windows.h index df81d4c6..165d204c 100644 --- a/plugins/mousepad_windows/mousepadplugin_windows.h +++ b/plugins/mousepad_windows/mousepadplugin_windows.h @@ -1,42 +1,42 @@ /** * Copyright 2014 Ahmed I. Khalil * * 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 MOUSEPADPLUGIN_H #define MOUSEPADPLUGIN_H #include #include #include class MousepadPlugin : public KdeConnectPlugin { Q_OBJECT public: - explicit MousepadPlugin(QObject *parent, const QVariantList &args); + explicit MousepadPlugin(QObject* parent, const QVariantList &args); ~MousepadPlugin() override; bool receivePackage(const NetworkPackage& np) override; void connected() override { } }; #endif diff --git a/plugins/mpriscontrol/kdeconnect_mpriscontrol.json b/plugins/mpriscontrol/kdeconnect_mpriscontrol.json index d846f0a0..2500354a 100644 --- a/plugins/mpriscontrol/kdeconnect_mpriscontrol.json +++ b/plugins/mpriscontrol/kdeconnect_mpriscontrol.json @@ -1,99 +1,97 @@ { "Encoding": "UTF-8", "KPlugin": { "Authors": [ { "Email": "albertvaka@gmail.com", "Name": "Albert Vaca", "Name[sr@ijekavian]": "Алберт Вака Синтора", "Name[sr@ijekavianlatin]": "Albert Vaka Sintora", "Name[sr@latin]": "Albert Vaka Sintora", "Name[sr]": "Алберт Вака Синтора", "Name[x-test]": "xxAlbert Vacaxx" } ], "Description": "Remote control your music and videos", "Description[ar]": "تحكّم بالموسيقى والفيديو عن بعد", "Description[ca@valencia]": "Comandament a distància per a la vostra música i vídeos", "Description[ca]": "Comandament a distància per a la vostra música i vídeos", "Description[cs]": "Ovládejte vzdáleně vaši hudbu a videa", "Description[da]": "Fjernbetjen din musik og videoer", "Description[de]": "Fernbedienung für Musik und Videos", "Description[el]": "Απομακρυσμένος έλεγχος της μουσικής σας και των βίντεο", "Description[es]": "Controlar remotamente vídeos y música", "Description[et]": "Oma muusika ja videote kaugjuhtimine", - "Description[eu]": "Kontrolatu urrunetik zure musika eta bideoak", "Description[fi]": "Kauko-ohjain musiikkiisi ja videoihisi", "Description[fr]": "Contrôlez à distance votre musique et vos vidéos", "Description[gl]": "Use o teléfono móbil como mando a distancia para música e vídeos.", "Description[hu]": "A zene- és videolejátszás irányítása távolról", "Description[it]": "Controlla da remoto la tua musica e i video", "Description[ko]": "음악과 동영상 원격 제어", "Description[nl]": "Op afstand bedienen van uw muziek en video's", "Description[nn]": "Fjernkontroller musikk og video", "Description[pl]": "Steruj zdalnie swoją muzyką i filmami", "Description[pt]": "Comandar à distância a sua música e vídeos", "Description[pt_BR]": "Controle suas músicas e vídeos remotamente", "Description[ru]": "Удалённое управление воспроизведением музыки и видео", "Description[sk]": "Vzdialene ovládať vašu hudbu a videá", "Description[sr@ijekavian]": "Даљински контролишите вашу музику и видео", "Description[sr@ijekavianlatin]": "Daljinski kontrolišite vašu muziku i video", "Description[sr@latin]": "Daljinski kontrolišite vašu muziku i video", "Description[sr]": "Даљински контролишите вашу музику и видео", "Description[sv]": "Fjärrstyr musik och videor", "Description[tr]": "Müzik ve videonuzu uzaktan kontrol edin", "Description[uk]": "Віддалене керування відтворенням музики та відео", "Description[x-test]": "xxRemote control your music and videosxx", "Description[zh_CN]": "远程控制您的音乐和视频", "Description[zh_TW]": "遠端控制您的音樂與影片", "EnabledByDefault": true, "Icon": "media-playback-start", "Id": "kdeconnect_mpriscontrol", "License": "GPL", "Name": "Multimedia control receiver", "Name[ar]": "مستقبل تحكّمات الوسائط المتعدّدة", "Name[ca@valencia]": "Receptor del comandament multimèdia", "Name[ca]": "Receptor del comandament multimèdia", "Name[cs]": "Dálkový ovladač multimédií", "Name[da]": "Modtager til multimediekontrol", "Name[de]": "Steuerung für Multimedia-Empfänger", "Name[el]": "Δέκτης ελέγχου πολυμέσων", "Name[es]": "Receptor de control multimedia", "Name[et]": "Multimeedia juhtimine", - "Name[eu]": "Multimedia-kontroladore hartzailea", "Name[fi]": "Multimediakauko-ohjain", "Name[fr]": "Receveur de contrôle multimédia", "Name[gl]": "Receptor de controis multimedia", "Name[hu]": "Multimédiavezérlő", "Name[it]": "Ricevitore di controllo multimediale", "Name[ko]": "멀티미디어 제어 수신기", "Name[nl]": "Ontvanger van bediening voor multimedia", "Name[nn]": "Mediefjernkontroll", "Name[pl]": "Odbiornik sterowania multimediami", "Name[pt]": "Receptor de controlo multimédia", "Name[pt_BR]": "Receptor de controle multimídia", "Name[ru]": "Управление мультимедиа", "Name[sk]": "Prijímač ovládania multimédií", "Name[sr@ijekavian]": "Мултимедијалне контроле", "Name[sr@ijekavianlatin]": "Multimedijalne kontrole", "Name[sr@latin]": "Multimedijalne kontrole", "Name[sr]": "Мултимедијалне контроле", "Name[sv]": "Mottagare av multimediastyrning", "Name[tr]": "Çokluortam kontrol alıcısı", "Name[uk]": "Отримувач команд щодо керування мультимедійними функціями", "Name[x-test]": "xxMultimedia control receiverxx", "Name[zh_CN]": "多媒体控制接收器", "Name[zh_TW]": "多媒體控制接收器", "ServiceTypes": [ "KdeConnect/Plugin" ], "Version": "0.1", "Website": "http://albertvaka.wordpress.com" }, "X-KdeConnect-OutgoingPackageType": [ "kdeconnect.mpris" ], "X-KdeConnect-SupportedPackageType": [ "kdeconnect.mpris.request" ] } diff --git a/plugins/mpriscontrol/mpriscontrolplugin.h b/plugins/mpriscontrol/mpriscontrolplugin.h index 77345493..51ce61d8 100644 --- a/plugins/mpriscontrol/mpriscontrolplugin.h +++ b/plugins/mpriscontrol/mpriscontrolplugin.h @@ -1,62 +1,62 @@ /** * Copyright 2013 Albert Vaca * * 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 MPRISCONTROLPLUGIN_H #define MPRISCONTROLPLUGIN_H #include #include #include #include #include #define PACKAGE_TYPE_MPRIS QStringLiteral("kdeconnect.mpris") Q_DECLARE_LOGGING_CATEGORY(KDECONNECT_PLUGIN_MPRIS) class MprisControlPlugin : public KdeConnectPlugin { Q_OBJECT public: - explicit MprisControlPlugin(QObject *parent, const QVariantList &args); + explicit MprisControlPlugin(QObject* parent, const QVariantList& args); bool receivePackage(const NetworkPackage& np) override; void connected() override { } private Q_SLOTS: void propertiesChanged(const QString& propertyInterface, const QVariantMap& properties); void seeked(qlonglong); private: void serviceOwnerChanged(const QString& serviceName, const QString& oldOwner, const QString& newOwner); void addPlayer(const QString& ifaceName); void removePlayer(const QString& ifaceName); void sendPlayerList(); QHash playerList; int prevVolume; QDBusServiceWatcher* m_watcher; }; #endif diff --git a/plugins/mprisremote/kdeconnect_mprisremote.json b/plugins/mprisremote/kdeconnect_mprisremote.json index b286bcf5..482da905 100644 --- a/plugins/mprisremote/kdeconnect_mprisremote.json +++ b/plugins/mprisremote/kdeconnect_mprisremote.json @@ -1,79 +1,78 @@ { "Encoding": "UTF-8", "KPlugin": { "Authors": [ { "Email": "aleixpol@kde.org", "Name": "Aleix Pol", "Name[sr@ijekavian]": "Алекс Пол Гонзалез", "Name[sr@ijekavianlatin]": "Aleks Pol Gonzalez", "Name[sr@latin]": "Aleks Pol Gonzalez", "Name[sr]": "Алекс Пол Гонзалез", "Name[x-test]": "xxAleix Polxx" } ], "Description": "Control MPRIS services", "Description[ar]": "تحكّم بخدمات MPRIS", "Description[ca@valencia]": "Serveis de control del MPRIS", "Description[ca]": "Serveis de control del MPRIS", "Description[cs]": "Ovládejte služby MPRIS", "Description[da]": "Kontrollér MPRIS-tjenester", "Description[de]": "Steuerung von MPRIS-Diensten", "Description[el]": "Έλεγχος υπηρεσιών MPRIS", "Description[es]": "Controlar los servicios MPRIS", "Description[et]": "MPRIS-teenuste juhtimine", - "Description[eu]": "Kontrolatu MPRIS zerbitzuak", "Description[fi]": "Ohjaa MPRIS-palveluita", "Description[fr]": "Controllez les services MPRIS", "Description[gl]": "Controle servizos de MPRIS.", "Description[it]": "Servizi di controllo MPRIS", "Description[ko]": "MPRIS 서비스 제어", "Description[nl]": "MPRIS-services besturen", "Description[nn]": "Kontroller MPRIS-tenester", "Description[pl]": "Sterowanie usługami MPRIS", "Description[pt]": "Controlar os serviços MPRIS", "Description[pt_BR]": "Controle dos serviços MPRIS", "Description[ru]": "Управление службами MPRIS", "Description[sk]": "Ovládať MPRIS služby", "Description[sr@ijekavian]": "Контрола МПРИС сервиса", "Description[sr@ijekavianlatin]": "Kontrola MPRIS servisa", "Description[sr@latin]": "Kontrola MPRIS servisa", "Description[sr]": "Контрола МПРИС сервиса", "Description[sv]": "Styr MPRIS-tjänster", "Description[tr]": "MPRIS servislerini kontrol et", "Description[uk]": "Керування службами MPRIS", "Description[x-test]": "xxControl MPRIS servicesxx", "Description[zh_CN]": "控制 MPRIS 服务", "Description[zh_TW]": "控制 MPRIS 服務", "EnabledByDefault": true, "Icon": "applications-multimedia", "Id": "kdeconnect_mprisremote", "License": "GPL", "Name": "MprisRemote", "Name[ar]": "‏Mpris عن بعد", "Name[et]": "Kaug-Mpris", "Name[fi]": "MPRIS-kauko-ohjain", "Name[nn]": "MPRIS-fjernkontroll", "Name[pl]": "PilotMPRIS", "Name[pt]": "Comando MPRIS", "Name[ru]": "Удалённое управление MPRIS", "Name[sr@ijekavian]": "МПРИС даљински", "Name[sr@ijekavianlatin]": "MPRIS daljinski", "Name[sr@latin]": "MPRIS daljinski", "Name[sr]": "МПРИС даљински", "Name[sv]": "MPRIS-fjärrkontroll", "Name[x-test]": "xxMprisRemotexx", "Name[zh_CN]": "远程 Mpris", "ServiceTypes": [ "KdeConnect/Plugin" ], "Version": "0.1", "Website": "https://kde.org" }, "X-KdeConnect-OutgoingPackageType": [ "kdeconnect.mpris.request" ], "X-KdeConnect-SupportedPackageType": [ "kdeconnect.mpris" ] } diff --git a/plugins/mprisremote/mprisremoteplugin.h b/plugins/mprisremote/mprisremoteplugin.h index 508190b9..e7e419d2 100644 --- a/plugins/mprisremote/mprisremoteplugin.h +++ b/plugins/mprisremote/mprisremoteplugin.h @@ -1,84 +1,84 @@ /** * Copyright 2013 Albert Vaca * * 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 MPRISREMOTEPLUGIN_H #define MPRISREMOTEPLUGIN_H #include #include #define PACKAGE_TYPE_MPRIS_REQUEST QStringLiteral("kdeconnect.mpris.request") #define PACKAGE_TYPE_MPRIS QStringLiteral("kdeconnect.mpris") class Q_DECL_EXPORT MprisRemotePlugin : public KdeConnectPlugin { Q_OBJECT Q_CLASSINFO("D-Bus Interface", "org.kde.kdeconnect.device.mprisremote") Q_PROPERTY(int volume READ volume WRITE setVolume NOTIFY propertiesChanged) Q_PROPERTY(int length READ length NOTIFY propertiesChanged) Q_PROPERTY(bool isPlaying READ isPlaying NOTIFY propertiesChanged) Q_PROPERTY(int position READ position WRITE setPosition NOTIFY propertiesChanged) Q_PROPERTY(QStringList playerList READ playerList NOTIFY propertiesChanged) Q_PROPERTY(QString player READ player WRITE setPlayer) Q_PROPERTY(QString nowPlaying READ nowPlaying NOTIFY propertiesChanged) public: - explicit MprisRemotePlugin(QObject *parent, const QVariantList &args); + explicit MprisRemotePlugin(QObject* parent, const QVariantList &args); ~MprisRemotePlugin() override; long position() const; int volume() const { return m_volume; } int length() const { return m_length; } bool isPlaying() const { return m_playing; } QStringList playerList() const { return m_playerList; } QString player() const { return m_player; } QString nowPlaying() const { return m_nowPlaying; } void setVolume(int volume); void setPosition(int position); void setPlayer(const QString& player); bool receivePackage(const NetworkPackage& np) override; void connected() override {} QString dbusPath() const override; Q_SCRIPTABLE void seek(int offset) const; Q_SCRIPTABLE void requestPlayerList(); Q_SCRIPTABLE void sendAction(const QString& action); Q_SIGNALS: void propertiesChanged(); private: void requestPlayerStatus(); QString m_player; bool m_playing; QString m_nowPlaying; int m_volume; long m_length; long m_lastPosition; qint64 m_lastPositionTime; QStringList m_playerList; }; #endif diff --git a/plugins/notifications/kdeconnect_notifications.json b/plugins/notifications/kdeconnect_notifications.json index 56e79427..89e9a0ab 100644 --- a/plugins/notifications/kdeconnect_notifications.json +++ b/plugins/notifications/kdeconnect_notifications.json @@ -1,98 +1,96 @@ { "Encoding": "UTF-8", "KPlugin": { "Authors": [ { "Email": "albertvaka@gmail.com", "Name": "Albert Vaca", "Name[sr@ijekavian]": "Алберт Вака Синтора", "Name[sr@ijekavianlatin]": "Albert Vaka Sintora", "Name[sr@latin]": "Albert Vaka Sintora", "Name[sr]": "Алберт Вака Синтора", "Name[x-test]": "xxAlbert Vacaxx" } ], "Description": "Show device's notifications on this computer and keep them in sync", "Description[ar]": "أظهر إخطارات الجهاز على هذا الحاسوب وأبقها متزامنة", "Description[ca@valencia]": "Mostra les notificacions del dispositiu a l'ordinador i les manté sincronitzades", "Description[ca]": "Mostra les notificacions del dispositiu a l'ordinador i les manté sincronitzades", "Description[cs]": "Zobrazit upozornění telefonu v počítači a udržovat je synchronizovaná", "Description[da]": "Vis enhedens bekendtgørelser på denne computer og hold dem synkroniseret", "Description[de]": "Benachrichtigungen des Geräts auf diesem Rechner anzeigen und abgleichen", "Description[el]": "Εμφάνιση ειδοποιήσεων συσκευής στον υπολογιστή αυτόν και συγχρονισμός τους", "Description[es]": "Mostrar notificaciones del dispositivo en este equipo y mantenerlas en sincronía", "Description[et]": "Seadme märguannete näitamine arvutis ja nende sünkroonis hoidmine", - "Description[eu]": "Erakutsi gailuaren jakinarazpenak ordenagailu honetan eta mantendu sinkronizatuta", "Description[fi]": "Näytä laitteen ilmoitukset tällä tietokoneella ja pidä ne ajan tasalla", "Description[fr]": "Affichez les notifications du téléphone sur l'ordinateur et synchronisez-les", "Description[gl]": "Mostrar as notificacións do dispositivo neste computador e mantelas sincronizadas.", "Description[it]": "Mostra le notifiche del telefono sul tuo computer e tienile sincronizzate", "Description[ko]": "휴대폰 알림을 컴퓨터에 표시하고 동기화하기", "Description[nl]": "Apparaatmeldingen op deze computer tonen en ze gesynchroniseerd houden", "Description[nn]": "Vis telefonvarslingar på datamaskina og hald dei synkronisert", "Description[pl]": "Pokaż powiadomienia urządzenia na swoim komputerze i synchronizuj je", "Description[pt]": "Mostrar as notificações do dispositivo neste computador e mantê-las sincronizadas", "Description[pt_BR]": "Mostra as notificações do aparelho neste computador e as mantém sincronizadas", "Description[ru]": "Показ уведомлений с устройства на компьютере и их синхронизация", "Description[sk]": "Zobraziť oznámenia telefónu na vašom počítači a udržať ich synchronizované", "Description[sr@ijekavian]": "Приказује обавештења са уређаја на рачунару и одржава их ажурним", "Description[sr@ijekavianlatin]": "Prikazuje obaveštenja sa uređaja na računaru i održava ih ažurnim", "Description[sr@latin]": "Prikazuje obaveštenja sa uređaja na računaru i održava ih ažurnim", "Description[sr]": "Приказује обавештења са уређаја на рачунару и одржава их ажурним", "Description[sv]": "Visa enhetens underrättelser på datorn och håll dem synkroniserade", "Description[tr]": "Aygıtın bildirimlerini bilgisayarda göster ve eşzamanlı tut", "Description[uk]": "Показ сповіщень з пристрою на цьому комп’ютері та підтримання синхронізації даних сповіщень", "Description[x-test]": "xxShow device's notifications on this computer and keep them in syncxx", "Description[zh_CN]": "在电脑显示手机通知并保持同步", "Description[zh_TW]": "在電腦上顯示裝置通知並且保持同步", "EnabledByDefault": true, "Icon": "preferences-desktop-notification", "Id": "kdeconnect_notifications", "License": "GPL", "Name": "Receive notifications", "Name[ar]": "استقبل الإخطارات", "Name[ca@valencia]": "Recepció de les notificacions", "Name[ca]": "Recepció de les notificacions", "Name[cs]": "Přijímat oznámení", "Name[da]": "Modtag bekendtgørelser", "Name[de]": "Benachrichtigungen empfangen", "Name[el]": "Λήψη ειδοποιήσεων", "Name[es]": "Recibir notificaciones", "Name[et]": "Märguannete vastuvõtmine", - "Name[eu]": "Jaso jakinarazpenak", "Name[fi]": "Vastaanota ilmoituksia", "Name[fr]": "Recevoir les notifications", "Name[gl]": "Recibir notificacións", "Name[it]": "Ricevi notifiche", "Name[ko]": "알림 받기", "Name[nl]": "Meldingen ontvangen", "Name[nn]": "Få varslingar", "Name[pl]": "Otrzymuj powiadomienia", "Name[pt]": "Receber as notificações", "Name[pt_BR]": "Receber notificações", "Name[ru]": "Получение уведомлений", "Name[sk]": "Prijať upozornenia", "Name[sr@ijekavian]": "Пријем обавештења", "Name[sr@ijekavianlatin]": "Prijem obaveštenja", "Name[sr@latin]": "Prijem obaveštenja", "Name[sr]": "Пријем обавештења", "Name[sv]": "Ta emot underrättelser", "Name[tr]": "Bildirimleri al", "Name[uk]": "Отримати сповіщення", "Name[x-test]": "xxReceive notificationsxx", "Name[zh_CN]": "接收通知", "Name[zh_TW]": "收到通知", "ServiceTypes": [ "KdeConnect/Plugin" ], "Version": "0.1", "Website": "http://albertvaka.wordpress.com" }, "X-KdeConnect-OutgoingPackageType": [ "kdeconnect.notification.request", "kdeconnect.notification.reply" ], "X-KdeConnect-SupportedPackageType": [ "kdeconnect.notification" ] } diff --git a/plugins/notifications/notification.cpp b/plugins/notifications/notification.cpp index c9ae4f6f..21042da0 100644 --- a/plugins/notifications/notification.cpp +++ b/plugins/notifications/notification.cpp @@ -1,155 +1,154 @@ /** * Copyright 2013 Albert Vaca * * 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 "notification.h" #include #include #include #include #include #include #include Notification::Notification(const NetworkPackage& np, QObject* parent) : QObject(parent) { - mImagesDir = QDir::temp().absoluteFilePath(QStringLiteral("kdeconnect")); - mImagesDir.mkpath(mImagesDir.absolutePath()); - mClosed = false; + m_imagesDir = QDir::temp().absoluteFilePath(QStringLiteral("kdeconnect")); + m_imagesDir.mkpath(m_imagesDir.absolutePath()); + m_closed = false; parseNetworkPackage(np); createKNotification(false, np); } Notification::~Notification() { } void Notification::dismiss() { - if (mDismissable) { - Q_EMIT dismissRequested(mInternalId); + if (m_dismissable) { + Q_EMIT dismissRequested(m_internalId); } } void Notification::show() { - Q_EMIT ready(); - if (!mSilent) { - mClosed = false; - mNotification->sendEvent(); + if (!m_silent) { + m_closed = false; + m_notification->sendEvent(); } } void Notification::applyIconAndShow() { - if (!mSilent) { - QPixmap icon(mIconPath, "PNG"); - mNotification->setPixmap(icon); + if (!m_silent) { + QPixmap icon(m_iconPath, "PNG"); + m_notification->setPixmap(icon); show(); } } -void Notification::update(const NetworkPackage &np) +void Notification::update(const NetworkPackage& np) { parseNetworkPackage(np); - createKNotification(!mClosed, np); + createKNotification(!m_closed, np); } -KNotification* Notification::createKNotification(bool update, const NetworkPackage &np) +KNotification* Notification::createKNotification(bool update, const NetworkPackage& np) { if (!update) { - mNotification = new KNotification(QStringLiteral("notification"), KNotification::CloseOnTimeout, this); - mNotification->setComponentName(QStringLiteral("kdeconnect")); + m_notification = new KNotification(QStringLiteral("notification"), KNotification::CloseOnTimeout, this); + m_notification->setComponentName(QStringLiteral("kdeconnect")); } - QString escapedTitle = mTitle.toHtmlEscaped(); - QString escapedText = mText.toHtmlEscaped(); - QString escapedTicker = mTicker.toHtmlEscaped(); + QString escapedTitle = m_title.toHtmlEscaped(); + QString escapedText = m_text.toHtmlEscaped(); + QString escapedTicker = m_ticker.toHtmlEscaped(); - mNotification->setTitle(mAppName.toHtmlEscaped()); + m_notification->setTitle(m_appName.toHtmlEscaped()); - if (mTitle.isEmpty() && mText.isEmpty()) { - mNotification->setText(escapedTicker); - } else if (mAppName==mTitle) { - mNotification->setText(escapedText); - } else if (mTitle.isEmpty()){ - mNotification->setText(escapedText); - } else if (mText.isEmpty()){ - mNotification->setText(escapedTitle); + if (m_title.isEmpty() && m_text.isEmpty()) { + m_notification->setText(escapedTicker); + } else if (m_appName==m_title) { + m_notification->setText(escapedText); + } else if (m_title.isEmpty()){ + m_notification->setText(escapedText); + } else if (m_text.isEmpty()){ + m_notification->setText(escapedTitle); } else { - mNotification->setText(escapedTitle+": "+escapedText); + m_notification->setText(escapedTitle+": "+escapedText); } - if (!mHasIcon) { + if (!m_hasIcon) { //HACK The only way to display no icon at all is trying to load a non-existant icon - mNotification->setIconName(QString("not_a_real_icon")); + m_notification->setIconName(QString("not_a_real_icon")); show(); } else { - QString filename = mPayloadHash; + QString filename = m_payloadHash; if (filename.isEmpty()) { - mHasIcon = false; + m_hasIcon = false; } else { - mIconPath = mImagesDir.absoluteFilePath(filename); - QUrl destinationUrl(mIconPath); + m_iconPath = m_imagesDir.absoluteFilePath(filename); + QUrl destinationUrl(m_iconPath); FileTransferJob* job = np.createPayloadTransferJob(destinationUrl); job->start(); connect(job, &FileTransferJob::result, this, &Notification::applyIconAndShow); } } - if(!mRequestReplyId.isEmpty()) { - mNotification->setActions( QStringList(i18n("Reply")) ); - connect(mNotification, &KNotification::action1Activated, this, &Notification::reply); + if(!m_requestReplyId.isEmpty()) { + m_notification->setActions( QStringList(i18n("Reply")) ); + connect(m_notification, &KNotification::action1Activated, this, &Notification::reply); } - connect(mNotification, &KNotification::closed, this, &Notification::closed); + connect(m_notification, &KNotification::closed, this, &Notification::closed); - return mNotification; + return m_notification; } void Notification::reply() { Q_EMIT replyRequested(); } void Notification::closed() { - mClosed = true; + m_closed = true; } -void Notification::parseNetworkPackage(const NetworkPackage &np) +void Notification::parseNetworkPackage(const NetworkPackage& np) { - mInternalId = np.get(QStringLiteral("id")); - mAppName = np.get(QStringLiteral("appName")); - mTicker = np.get(QStringLiteral("ticker")); - mTitle = np.get(QStringLiteral("title")); - mText = np.get(QStringLiteral("text")); - mDismissable = np.get(QStringLiteral("isClearable")); - mHasIcon = np.hasPayload(); - mSilent = np.get(QStringLiteral("silent")); - mPayloadHash = np.get(QStringLiteral("payloadHash")); - mRequestReplyId = np.get(QStringLiteral("requestReplyId"), QString()); + m_internalId = np.get(QStringLiteral("id")); + m_appName = np.get(QStringLiteral("appName")); + m_ticker = np.get(QStringLiteral("ticker")); + m_title = np.get(QStringLiteral("title")); + m_text = np.get(QStringLiteral("text")); + m_dismissable = np.get(QStringLiteral("isClearable")); + m_hasIcon = np.hasPayload(); + m_silent = np.get(QStringLiteral("silent")); + m_payloadHash = np.get(QStringLiteral("payloadHash")); + m_requestReplyId = np.get(QStringLiteral("requestReplyId"), QString()); } diff --git a/plugins/notifications/notification.h b/plugins/notifications/notification.h index 1f287134..3f4c9ce8 100644 --- a/plugins/notifications/notification.h +++ b/plugins/notifications/notification.h @@ -1,95 +1,94 @@ /** * Copyright 2013 Albert Vaca * * 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 NOTIFICATION_H #define NOTIFICATION_H #include #include #include #include #include class Notification : public QObject { Q_OBJECT Q_CLASSINFO("D-Bus Interface", "org.kde.kdeconnect.device.notifications.notification") Q_PROPERTY(QString internalId READ internalId) Q_PROPERTY(QString appName READ appName) Q_PROPERTY(QString ticker READ ticker) Q_PROPERTY(QString title READ title) Q_PROPERTY(QString text READ text) Q_PROPERTY(QString iconPath READ iconPath) Q_PROPERTY(bool dismissable READ dismissable) Q_PROPERTY(bool hasIcon READ hasIcon) Q_PROPERTY(bool silent READ silent) Q_PROPERTY(QString replyId READ replyId) public: Notification(const NetworkPackage& np, QObject* parent); ~Notification() override; - QString internalId() const { return mInternalId; } - QString appName() const { return mAppName; } - QString ticker() const { return mTicker; } - QString title() const { return mTitle; } - QString text() const { return mText; } - QString iconPath() const { return mIconPath; } - bool dismissable() const { return mDismissable; } - QString replyId() const { return mRequestReplyId; } - bool hasIcon() const { return mHasIcon; } + QString internalId() const { return m_internalId; } + QString appName() const { return m_appName; } + QString ticker() const { return m_ticker; } + QString title() const { return m_title; } + QString text() const { return m_text; } + QString iconPath() const { return m_iconPath; } + bool dismissable() const { return m_dismissable; } + QString replyId() const { return m_requestReplyId; } + bool hasIcon() const { return m_hasIcon; } void show(); - bool silent() const { return mSilent; } - void update(const NetworkPackage &np); - KNotification* createKNotification(bool update, const NetworkPackage &np); + bool silent() const { return m_silent; } + void update(const NetworkPackage& np); + KNotification* createKNotification(bool update, const NetworkPackage& np); public Q_SLOTS: Q_SCRIPTABLE void dismiss(); Q_SCRIPTABLE void applyIconAndShow(); Q_SCRIPTABLE void reply(); void closed(); Q_SIGNALS: - void dismissRequested(const QString& mInternalId); + void dismissRequested(const QString& m_internalId); void replyRequested(); - void ready(); private: - QString mInternalId; - QString mAppName; - QString mTicker; - QString mTitle; - QString mText; - QString mIconPath; - QString mRequestReplyId; - bool mDismissable; - bool mHasIcon; - KNotification* mNotification; - QDir mImagesDir; - bool mSilent; - bool mClosed; - QString mPayloadHash; + QString m_internalId; + QString m_appName; + QString m_ticker; + QString m_title; + QString m_text; + QString m_iconPath; + QString m_requestReplyId; + bool m_dismissable; + bool m_hasIcon; + KNotification* m_notification; + QDir m_imagesDir; + bool m_silent; + bool m_closed; + QString m_payloadHash; void parseNetworkPackage(const NetworkPackage& np); }; #endif diff --git a/plugins/notifications/notificationsdbusinterface.cpp b/plugins/notifications/notificationsdbusinterface.cpp index 7e37797f..ed078da4 100644 --- a/plugins/notifications/notificationsdbusinterface.cpp +++ b/plugins/notifications/notificationsdbusinterface.cpp @@ -1,185 +1,176 @@ /** * Copyright 2013 Albert Vaca * * 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 "notificationsdbusinterface.h" #include "notification_debug.h" #include "notification.h" #include #include #include #include "notificationsplugin.h" #include "sendreplydialog.h" NotificationsDbusInterface::NotificationsDbusInterface(KdeConnectPlugin* plugin) : QDBusAbstractAdaptor(const_cast(plugin->device())) - , mDevice(plugin->device()) - , mPlugin(plugin) - , mLastId(0) + , m_device(plugin->device()) + , m_plugin(plugin) + , m_lastId(0) { } NotificationsDbusInterface::~NotificationsDbusInterface() { qCDebug(KDECONNECT_PLUGIN_NOTIFICATION) << "Destroying NotificationsDbusInterface"; } void NotificationsDbusInterface::clearNotifications() { - qDeleteAll(mNotifications); - mNotifications.clear(); + qDeleteAll(m_notifications); + m_notifications.clear(); Q_EMIT allNotificationsRemoved(); } QStringList NotificationsDbusInterface::activeNotifications() { - return mNotifications.keys(); + return m_notifications.keys(); } void NotificationsDbusInterface::processPackage(const NetworkPackage& np) { if (np.get(QStringLiteral("isCancel"))) { QString id = np.get(QStringLiteral("id")); // cut off kdeconnect-android's prefix if there: if (id.startsWith(QLatin1String("org.kde.kdeconnect_tp::"))) id = id.mid(id.indexOf(QLatin1String("::")) + 2); removeNotification(id); } else if (np.get(QStringLiteral("isRequest"))) { - for (const auto& n : qAsConst(mNotifications)) { + for (const auto& n : qAsConst(m_notifications)) { NetworkPackage np(PACKAGE_TYPE_NOTIFICATION_REQUEST, { {"id", n->internalId()}, {"appName", n->appName()}, {"ticker", n->ticker()}, {"isClearable", n->dismissable()}, {"requestAnswer", true} }); - mPlugin->sendPackage(np); + m_plugin->sendPackage(np); } } else if(np.get(QStringLiteral("requestAnswer"), false)) { } else { QString id = np.get(QStringLiteral("id")); - Notification* noti; - - if (!mInternalIdToPublicId.contains(id)) { - noti = new Notification(np, this); + if (!m_internalIdToPublicId.contains(id)) { + Notification* noti = new Notification(np, this); + addNotification(noti); } else { - QString pubId = mInternalIdToPublicId[id]; - noti = mNotifications[pubId]; - noti->update(np); + QString pubId = m_internalIdToPublicId[id]; + m_notifications[pubId]->update(np); } - - connect(noti, &Notification::ready, this, [this, noti]{ - addNotification(noti); - }); } } void NotificationsDbusInterface::addNotification(Notification* noti) { const QString& internalId = noti->internalId(); - if (mInternalIdToPublicId.contains(internalId)) { - removeNotification(internalId, KeepNotification); + if (m_internalIdToPublicId.contains(internalId)) { + removeNotification(internalId); } //qCDebug(KDECONNECT_PLUGIN_NOTIFICATION) << "addNotification" << internalId; connect(noti, &Notification::dismissRequested, this, &NotificationsDbusInterface::dismissRequested); - - connect(noti, &Notification::replyRequested, this, [this,noti]{ - replyRequested(noti); + + connect(noti, &Notification::replyRequested, this, [this,noti]{ + replyRequested(noti); }); const QString& publicId = newId(); - mNotifications[publicId] = noti; - mInternalIdToPublicId[internalId] = publicId; + m_notifications[publicId] = noti; + m_internalIdToPublicId[internalId] = publicId; - QDBusConnection::sessionBus().registerObject(mDevice->dbusPath()+"/notifications/"+publicId, noti, QDBusConnection::ExportScriptableContents); + QDBusConnection::sessionBus().registerObject(m_device->dbusPath()+"/notifications/"+publicId, noti, QDBusConnection::ExportScriptableContents); Q_EMIT notificationPosted(publicId); } -void NotificationsDbusInterface::removeNotification(const QString& internalId, RemoveType removetype) +void NotificationsDbusInterface::removeNotification(const QString& internalId) { //qCDebug(KDECONNECT_PLUGIN_NOTIFICATION) << "removeNotification" << internalId; - if (!mInternalIdToPublicId.contains(internalId)) { - //qCDebug(KDECONNECT_PLUGIN_NOTIFICATION) << "Not found noti by internal Id: " << internalId; + if (!m_internalIdToPublicId.contains(internalId)) { + qCDebug(KDECONNECT_PLUGIN_NOTIFICATION) << "Not found noti by internal Id: " << internalId; return; } - QString publicId = mInternalIdToPublicId.take(internalId); + QString publicId = m_internalIdToPublicId.take(internalId); - Notification* noti = mNotifications.take(publicId); + Notification* noti = m_notifications.take(publicId); if (!noti) { - //qCDebug(KDECONNECT_PLUGIN_NOTIFICATION) << "Not found noti by public Id: " << publicId; + qCDebug(KDECONNECT_PLUGIN_NOTIFICATION) << "Not found noti by public Id: " << publicId; return; } //Deleting the notification will unregister it automatically - if (removetype==KeepNotification){ - QDBusConnection::sessionBus().unregisterObject(mDevice->dbusPath()+"/notifications/"+publicId); - } else if (removetype==DestroyNotification){ - noti->deleteLater(); - } + //QDBusConnection::sessionBus().unregisterObject(mDevice->dbusPath()+"/notifications/"+publicId); + noti->deleteLater(); Q_EMIT notificationRemoved(publicId); } void NotificationsDbusInterface::dismissRequested(const QString& internalId) { NetworkPackage np(PACKAGE_TYPE_NOTIFICATION_REQUEST); np.set(QStringLiteral("cancel"), internalId); - mPlugin->sendPackage(np); + m_plugin->sendPackage(np); //Workaround: we erase notifications without waiting a repsonse from the //phone because we won't receive a response if we are out of sync and this //notification no longer exists. Ideally, each time we reach the phone //after some time disconnected we should re-sync all the notifications. removeNotification(internalId); } void NotificationsDbusInterface::replyRequested(Notification* noti) { QString replyId = noti->replyId(); QString appName = noti->appName(); QString originalMessage = noti->ticker(); SendReplyDialog* dialog = new SendReplyDialog(originalMessage, replyId, appName); connect(dialog, &SendReplyDialog::sendReply, this, &NotificationsDbusInterface::sendReply); dialog->show(); } void NotificationsDbusInterface::sendReply(const QString& replyId, const QString& message) { NetworkPackage np(PACKAGE_TYPE_NOTIFICATION_REPLY); np.set(QStringLiteral("requestReplyId"), replyId); np.set(QStringLiteral("message"), message); - mPlugin->sendPackage(np); + m_plugin->sendPackage(np); } QString NotificationsDbusInterface::newId() { - return QString::number(++mLastId); + return QString::number(++m_lastId); } diff --git a/plugins/notifications/notificationsdbusinterface.h b/plugins/notifications/notificationsdbusinterface.h index f6b5b70c..fa9049aa 100644 --- a/plugins/notifications/notificationsdbusinterface.h +++ b/plugins/notifications/notificationsdbusinterface.h @@ -1,76 +1,72 @@ /** * Copyright 2013 Albert Vaca * * 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 NOTIFICATIONSDBUSINTERFACE_H #define NOTIFICATIONSDBUSINTERFACE_H #include #include #include #include #include #include "notification.h" class KdeConnectPlugin; class Device; class NotificationsDbusInterface : public QDBusAbstractAdaptor { Q_OBJECT Q_CLASSINFO("D-Bus Interface", "org.kde.kdeconnect.device.notifications") public: - enum RemoveType{ - KeepNotification, DestroyNotification - }; - explicit NotificationsDbusInterface(KdeConnectPlugin* plugin); ~NotificationsDbusInterface() override; void processPackage(const NetworkPackage& np); void clearNotifications(); void dismissRequested(const QString& notification); void replyRequested(Notification* noti); void addNotification(Notification* noti); public Q_SLOTS: Q_SCRIPTABLE QStringList activeNotifications(); Q_SCRIPTABLE void sendReply(const QString& replyId, const QString& message); Q_SIGNALS: Q_SCRIPTABLE void notificationPosted(const QString& publicId); Q_SCRIPTABLE void notificationRemoved(const QString& publicId); Q_SCRIPTABLE void allNotificationsRemoved(); private /*methods*/: - void removeNotification(const QString& internalId, RemoveType removetype=DestroyNotification); + void removeNotification(const QString& internalId); QString newId(); //Generates successive identifitiers to use as public ids private /*attributes*/: - const Device* mDevice; - KdeConnectPlugin* mPlugin; - QHash mNotifications; - QHash mInternalIdToPublicId; - int mLastId; + const Device* m_device; + KdeConnectPlugin* m_plugin; + QHash m_notifications; + QHash m_internalIdToPublicId; + int m_lastId; }; #endif diff --git a/plugins/notifications/notificationsplugin.h b/plugins/notifications/notificationsplugin.h index 5f2b101c..efbac648 100644 --- a/plugins/notifications/notificationsplugin.h +++ b/plugins/notifications/notificationsplugin.h @@ -1,57 +1,57 @@ /** * Copyright 2013 Albert Vaca * * 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 NOTIFICATIONSPLUGIN_H #define NOTIFICATIONSPLUGIN_H #include #include #define PACKAGE_TYPE_NOTIFICATION_REQUEST QStringLiteral("kdeconnect.notification.request") #define PACKAGE_TYPE_NOTIFICATION_REPLY QStringLiteral("kdeconnect.notification.reply") /* * This class is just a proxy for NotificationsDbusInterface * because it can not inherit from QDBusAbstractAdaptor and * KdeConnectPlugin at the same time (both are QObject) */ class NotificationsDbusInterface; class NotificationsListener; class NotificationsPlugin : public KdeConnectPlugin { Q_OBJECT public: - explicit NotificationsPlugin(QObject *parent, const QVariantList &args); + explicit NotificationsPlugin(QObject* parent, const QVariantList& args); ~NotificationsPlugin() override; bool receivePackage(const NetworkPackage& np) override; void connected() override; protected: NotificationsDbusInterface* notificationsDbusInterface; NotificationsListener* notificationsListener; }; #endif diff --git a/plugins/notifications/sendreplydialog.cpp b/plugins/notifications/sendreplydialog.cpp index e40c2170..ca883d76 100644 --- a/plugins/notifications/sendreplydialog.cpp +++ b/plugins/notifications/sendreplydialog.cpp @@ -1,64 +1,64 @@ /** * Copyright 2015 Albert Vaca * * 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 "sendreplydialog.h" #include #include #include #include #include SendReplyDialog::SendReplyDialog(const QString& originalMessage, const QString& replyId, const QString& topicName, QWidget* parent) : QDialog(parent) - , mReplyId(replyId) + , m_replyId(replyId) { QVBoxLayout* layout = new QVBoxLayout; QTextEdit* textView = new QTextEdit(this); textView->setReadOnly(true); textView->setText(topicName + ": \n" + originalMessage); layout->addWidget(textView); - mTextEdit = new QTextEdit(this); - layout->addWidget(mTextEdit); + m_textEdit = new QTextEdit(this); + layout->addWidget(m_textEdit); QPushButton* sendButton = new QPushButton(i18n("Send"), this); connect(sendButton, &QAbstractButton::clicked, this, &SendReplyDialog::sendButtonClicked); layout->addWidget(sendButton); setLayout(layout); setWindowTitle(topicName); setWindowIcon(QIcon::fromTheme(QStringLiteral("kdeconnect"))); setAttribute(Qt::WA_DeleteOnClose); } void SendReplyDialog::sendButtonClicked() { - Q_EMIT sendReply(mReplyId, mTextEdit->toPlainText()); + Q_EMIT sendReply(m_replyId, m_textEdit->toPlainText()); close(); } QSize SendReplyDialog::sizeHint() const { return QSize(512, 64); } diff --git a/plugins/notifications/sendreplydialog.h b/plugins/notifications/sendreplydialog.h index 8540d5a5..5880d879 100644 --- a/plugins/notifications/sendreplydialog.h +++ b/plugins/notifications/sendreplydialog.h @@ -1,50 +1,50 @@ /** * Copyright 2015 Albert Vaca * * 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 SENDREPLYDIALOG_H #define SENDREPLYDIALOG_H #include #include class QTextEdit; class QLineEdit; class QPushButton; class SendReplyDialog : public QDialog { Q_OBJECT public: - explicit SendReplyDialog(const QString& originalMessage, const QString& replyId, const QString& topicName, QWidget *parent = nullptr); + explicit SendReplyDialog(const QString& originalMessage, const QString& replyId, const QString& topicName, QWidget* parent = nullptr); QSize sizeHint() const override; private Q_SLOTS: void sendButtonClicked(); Q_SIGNALS: void sendReply(const QString& replyId, const QString& messageBody); private: - QString mReplyId; - QTextEdit *mTextEdit; + QString m_replyId; + QTextEdit* m_textEdit; }; #endif diff --git a/plugins/pausemusic/kdeconnect_pausemusic.json b/plugins/pausemusic/kdeconnect_pausemusic.json index 338135bf..c0b97488 100644 --- a/plugins/pausemusic/kdeconnect_pausemusic.json +++ b/plugins/pausemusic/kdeconnect_pausemusic.json @@ -1,96 +1,94 @@ { "Encoding": "UTF-8", "KPlugin": { "Authors": [ { "Email": "albertvaka@gmail.com", "Name": "Albert Vaca", "Name[sr@ijekavian]": "Алберт Вака Синтора", "Name[sr@ijekavianlatin]": "Albert Vaka Sintora", "Name[sr@latin]": "Albert Vaka Sintora", "Name[sr]": "Алберт Вака Синтора", "Name[x-test]": "xxAlbert Vacaxx" } ], "Description": "Pause music/videos during a phone call", "Description[ar]": "ألبث الموسيقى/الفيديو أثناء المكالمات الهاتفيّة", "Description[ca@valencia]": "Pausa la música/vídeos durant una trucada telefònica", "Description[ca]": "Pausa la música/vídeos durant una trucada telefònica", "Description[cs]": "Pozastavit hudbu/video během telefonátu", "Description[da]": "Sæt musik/videoer på pause under opkald", "Description[de]": "Hält Musik oder Videos während eines Anrufs an", "Description[el]": "Παύση μουσικής/βίντεο κατά τη διάρκεια κλήσης", "Description[es]": "Pausar música/video durante las llamadas telefónicas", "Description[et]": "Muusika või video peatamine telefonikõne ajal", - "Description[eu]": "Pausatu musika / bideoak deietan", "Description[fi]": "Keskeytä musiikki ja videot puhelun aikana", "Description[fr]": "Mettre en pause la musique / les vidéos pendant un appel téléphonique", "Description[gl]": "Deter a reprodución de música ou vídeos durante as chamadas.", "Description[hu]": "A médialejátszás szüneteltetése telefonhívások közben", "Description[it]": "Sospendi musica/video durante una chiamata", "Description[ko]": "휴대폰 통화 중 음악/동영상 일시 정지", "Description[nl]": "Muziek/video's pauzeren tijdens een telefoongesprek", "Description[nn]": "Set avspeling på pause ved oppringingar", "Description[pl]": "Wstrzymaj muzykę/film przy dzwonieniu", "Description[pt]": "Pausar a música/vídeos durante uma chamada telefónica", "Description[pt_BR]": "Pausa a música/vídeo durante uma chamada", "Description[ru]": "Приостановка воспроизведения музыки и видео во время телефонного звонка", "Description[sk]": "Pozastaviť hudbu/videá počas telefónneho hovoru", "Description[sr@ijekavian]": "Паузира музику или видео током телефонског позива", "Description[sr@ijekavianlatin]": "Pauzira muziku ili video tokom telefonskog poziva", "Description[sr@latin]": "Pauzira muziku ili video tokom telefonskog poziva", "Description[sr]": "Паузира музику или видео током телефонског позива", "Description[sv]": "Pausa musik eller videor under ett telefonsamtal", "Description[tr]": "Bir telefon çağrısı sırasında müzik/videoları duraklat", "Description[uk]": "Призупинка відтворення музики і відео на час телефонних дзвінків", "Description[x-test]": "xxPause music/videos during a phone callxx", "Description[zh_CN]": "手机来电时暂停音乐/视频", "Description[zh_TW]": "在通話過程中暫停音樂與影片", "EnabledByDefault": true, "Icon": "media-playback-pause", "Id": "kdeconnect_pausemusic", "License": "GPL", "Name": "Pause media during calls", "Name[ar]": "ألبث الوسائط أثناء المكالمات", "Name[ca@valencia]": "Pausa els suports durant les trucades", "Name[ca]": "Pausa els suports durant les trucades", "Name[cs]": "Pozastavit média během telefonátu", "Name[da]": "Sæt medier på pause under opkald", "Name[de]": "Medium bei Anrufen anhalten", "Name[el]": "Παύση πολυμέσων στη διάρκεια κλήσεων", "Name[es]": "Pausar medios durante las llamadas", "Name[et]": "Meedia peatamine kõne ajal", - "Name[eu]": "Pausatu media deietan", "Name[fi]": "Keskeytä toisto puhelujen aikana", "Name[fr]": "Mettre en pause le média pendant les appels", "Name[gl]": "Deter a reprodución durante as chamadas.", "Name[hu]": "Médialejátszás felfüggesztése", "Name[it]": "Sospendi i lettori multimediali", "Name[ko]": "통화 중 미디어 일시 정지", "Name[nl]": "Media pauzeren tijdens oproepen", "Name[nn]": "Set avspeling på pause ved oppringingar", "Name[pl]": "Wstrzymaj multimedia przy dzwonieniu", "Name[pt]": "Pausar a reprodução durante as chamadas", "Name[pt_BR]": "Pausar os conteúdos multimídia durante as chamadas", "Name[ru]": "Приостановка воспроизведения во время звонка", "Name[sk]": "Pozastaviť médiá počas hovorov", "Name[sr@ijekavian]": "Паузирање медија током позива", "Name[sr@ijekavianlatin]": "Pauziranje medija tokom poziva", "Name[sr@latin]": "Pauziranje medija tokom poziva", "Name[sr]": "Паузирање медија током позива", "Name[sv]": "Pausa media under samtal", "Name[tr]": "Çağrılar sırasında ortamı duraklat", "Name[uk]": "Призупинка відтворення під час дзвінків", "Name[x-test]": "xxPause media during callsxx", "Name[zh_CN]": "来电时暂停媒体", "Name[zh_TW]": "在通話過程中暫停媒體", "ServiceTypes": [ "KdeConnect/Plugin" ], "Version": "0.1", "Website": "http://albertvaka.wordpress.com" }, "X-KdeConnect-SupportedPackageType": [ "kdeconnect.telephony" ] } diff --git a/plugins/pausemusic/kdeconnect_pausemusic_config.desktop b/plugins/pausemusic/kdeconnect_pausemusic_config.desktop index 96da36b6..4291fd2b 100644 --- a/plugins/pausemusic/kdeconnect_pausemusic_config.desktop +++ b/plugins/pausemusic/kdeconnect_pausemusic_config.desktop @@ -1,48 +1,47 @@ [Desktop Entry] Type=Service X-KDE-ServiceTypes=KCModule X-KDE-Library=kdeconnect_pausemusic_config X-KDE-ParentComponents=kdeconnect_pausemusic Name=Pause Music plugin settings Name[ar]=إعدادات ملحقة إلباث الموسيقى Name[ast]=Axustes del complementu de posar música Name[bg]=Настройки на приставката за поставяне на пауза Name[bs]=Zaustavi Muziku postavke dodatka Name[ca]=Ajustaments del connector Pausa la música Name[ca@valencia]=Ajustaments del connector Pausa la música Name[cs]=Nastavení modulu Pozastavení hudby Name[da]=Indstilling af plugin til at sætte musik på pause Name[de]=Modul-Einstellungen für das Anhalten der Musikwiedergabe Name[el]=Ρυθμίσεις προσθέτου παύσης μουσικής Name[en_GB]=Pause Music plugin settings Name[es]=Ajustes del complemento PauseMusic Name[et]=Muusika peatamise plugina seadistused -Name[eu]=Pausatu-musika pluginaren ezarpenak Name[fi]=Keskeytä musiikki -liitännäisen asetukset Name[fr]=Paramètres du module de mise en pause Name[gl]=Configuración do complemento para deter a música Name[he]=הגדרות התוספת השהיית המוזיקה Name[hu]=Zene szüneteltetése bővítmény beállításai Name[it]=Impostazioni estensione Sospendi musica Name[ko]=음악 일시 정지 플러그인 설정 Name[nl]=Plug-in-instellingen voor muziek pauzeren Name[nn]=Innstillingar for tillegg for pausing av musikk Name[pl]=Ustawienia wtyczki wstrzymywania muzyki Name[pt]=Configuração do 'plugin' de Pausa da Música Name[pt_BR]=Pausar as configurações do plugin Músicas Name[ru]=Настройка модуля приостановки музыки Name[sk]=Nastavenia pluginu pozastavenia hudby Name[sr]=Поставке прикључка паузирања музике Name[sr@ijekavian]=Поставке прикључка паузирања музике Name[sr@ijekavianlatin]=Postavke priključka pauziranja muzike Name[sr@latin]=Postavke priključka pauziranja muzike Name[sv]=Inställningar av insticksprogram för paus i musik Name[tr]=Müziği Duraklat eklenti ayarları Name[uk]=Параметри додатка призупинення відтворення музики Name[x-test]=xxPause Music plugin settingsxx Name[zh_CN]=暂停音乐插件设置 Name[zh_TW]=暫停音樂擴展插件設定 Categories=Qt;KDE;X-KDE-settings-kdeconnect; diff --git a/plugins/pausemusic/pausemusic_config.cpp b/plugins/pausemusic/pausemusic_config.cpp index 022f90f1..fde7a3ba 100644 --- a/plugins/pausemusic/pausemusic_config.cpp +++ b/plugins/pausemusic/pausemusic_config.cpp @@ -1,79 +1,79 @@ /** * Copyright 2013 Albert Vaca * * 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 "pausemusic_config.h" #include "ui_pausemusic_config.h" #include K_PLUGIN_FACTORY(PauseMusicConfigFactory, registerPlugin();) -PauseMusicConfig::PauseMusicConfig(QWidget *parent, const QVariantList& args) +PauseMusicConfig::PauseMusicConfig(QWidget* parent, const QVariantList& args) : KdeConnectPluginKcm(parent, args, QStringLiteral("kdeconnect_pausemusic_config")) , m_ui(new Ui::PauseMusicConfigUi()) { m_ui->setupUi(this); connect(m_ui->rad_ringing, SIGNAL(toggled(bool)), this, SLOT(changed())); connect(m_ui->rad_talking, SIGNAL(toggled(bool)), this, SLOT(changed())); connect(m_ui->check_pause, SIGNAL(toggled(bool)), this, SLOT(changed())); connect(m_ui->check_mute, SIGNAL(toggled(bool)), this, SLOT(changed())); } PauseMusicConfig::~PauseMusicConfig() { delete m_ui; } void PauseMusicConfig::defaults() { KCModule::defaults(); m_ui->rad_talking->setChecked(false); m_ui->rad_ringing->setChecked(true); m_ui->check_pause->setChecked(true); m_ui->check_mute->setChecked(false); Q_EMIT changed(true); } void PauseMusicConfig::load() { KCModule::load(); bool talking = config()->get(QStringLiteral("conditionTalking"), false); m_ui->rad_talking->setChecked(talking); m_ui->rad_ringing->setChecked(!talking); bool pause = config()->get(QStringLiteral("actionPause"), true); bool mute = config()->get(QStringLiteral("actionMute"), false); m_ui->check_pause->setChecked(pause); m_ui->check_mute->setChecked(mute); Q_EMIT changed(false); } void PauseMusicConfig::save() { config()->set(QStringLiteral("conditionTalking"), m_ui->rad_talking->isChecked()); config()->set(QStringLiteral("actionPause"), m_ui->check_pause->isChecked()); config()->set(QStringLiteral("actionMute"), m_ui->check_mute->isChecked()); KCModule::save(); Q_EMIT changed(false); } #include "pausemusic_config.moc" diff --git a/plugins/pausemusic/pausemusic_config.h b/plugins/pausemusic/pausemusic_config.h index 62ff6f6d..4140dd63 100644 --- a/plugins/pausemusic/pausemusic_config.h +++ b/plugins/pausemusic/pausemusic_config.h @@ -1,48 +1,48 @@ /** * Copyright 2013 Albert Vaca * * 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 PAUSEMUSIC_CONFIG_H #define PAUSEMUSIC_CONFIG_H #include "kcmplugin/kdeconnectpluginkcm.h" namespace Ui { class PauseMusicConfigUi; } class PauseMusicConfig : public KdeConnectPluginKcm { Q_OBJECT public: - PauseMusicConfig(QWidget *parent, const QVariantList&); + PauseMusicConfig(QWidget* parent, const QVariantList&); ~PauseMusicConfig() override; public Q_SLOTS: void save() override; void load() override; void defaults() override; private: Ui::PauseMusicConfigUi* m_ui; }; #endif diff --git a/plugins/pausemusic/pausemusicplugin.h b/plugins/pausemusic/pausemusicplugin.h index bfa5bafc..8f0ff241 100644 --- a/plugins/pausemusic/pausemusicplugin.h +++ b/plugins/pausemusic/pausemusicplugin.h @@ -1,53 +1,53 @@ /** * Copyright 2013 Albert Vaca * * 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 PAUSEMUSICPLUGIN_H #define PAUSEMUSICPLUGIN_H #include #include #include #include class PauseMusicPlugin : public KdeConnectPlugin { Q_OBJECT public: - explicit PauseMusicPlugin(QObject *parent, const QVariantList &args); + explicit PauseMusicPlugin(QObject* parent, const QVariantList& args); bool receivePackage(const NetworkPackage& np) override; void connected() override { } public Q_SLOTS: /** * @returns 0 if not muted, 1 if muted or -1 if there was an error */ int isKMixMuted(); private: QSet pausedSources; bool muted; }; #endif diff --git a/plugins/ping/kdeconnect_ping.json b/plugins/ping/kdeconnect_ping.json index 929d3878..15936e55 100644 --- a/plugins/ping/kdeconnect_ping.json +++ b/plugins/ping/kdeconnect_ping.json @@ -1,78 +1,77 @@ { "Encoding": "UTF-8", "KPlugin": { "Authors": [ { "Email": "albertvaka@gmail.com", "Name": "Albert Vaca", "Name[sr@ijekavian]": "Алберт Вака Синтора", "Name[sr@ijekavianlatin]": "Albert Vaka Sintora", "Name[sr@latin]": "Albert Vaka Sintora", "Name[sr]": "Алберт Вака Синтора", "Name[x-test]": "xxAlbert Vacaxx" } ], "Description": "Send and receive pings", "Description[ar]": "أرسل الوخزات واستقبلها", "Description[ca@valencia]": "Envia i rep pings", "Description[ca]": "Envia i rep pings", "Description[cs]": "Posílat a přijímat ping", "Description[da]": "Send og modtag ping", "Description[de]": "Senden und Empfangen von Pings", "Description[el]": "Αποστολή και λήψη pings", "Description[es]": "Enviar y recibir pings", "Description[et]": "Pingide saatmine ja vastuvõtmine", - "Description[eu]": "Bidali eta jaso pingak", "Description[fi]": "Lähetä ja vastaanota tiedustelupaketteja", "Description[fr]": "Envoie et reçoit des commandes « Ping »", "Description[gl]": "Enviar e recibir pings.", "Description[hu]": "Pingek küldése és fogadása", "Description[it]": "Invia e ricevi ping", "Description[ko]": "핑 보내고 받기", "Description[nl]": "Pings verzenden en ontvangen", "Description[nn]": "Send og ta imot pingsignal", "Description[pl]": "Wysyłaj i otrzymuj pingi", "Description[pt]": "Enviar e receber contactos", "Description[pt_BR]": "Envia e recebe pings", "Description[ru]": "Отправка и получение пингов", "Description[sk]": "Poslať a prijať pingy", "Description[sr@ijekavian]": "Шаље и прима пингове", "Description[sr@ijekavianlatin]": "Šalje i prima pingove", "Description[sr@latin]": "Šalje i prima pingove", "Description[sr]": "Шаље и прима пингове", "Description[sv]": "Skicka och ta emot ping", "Description[tr]": "Ping gönder ve al", "Description[uk]": "Надсилання і отримання сигналів підтримання зв’язку", "Description[x-test]": "xxSend and receive pingsxx", "Description[zh_CN]": "发送和接受 ping", "Description[zh_TW]": "傳送與接收Ping回應封包", "EnabledByDefault": true, "Icon": "dialog-ok", "Id": "kdeconnect_ping", "License": "GPL", "Name": "Ping", "Name[ar]": "وخزة", "Name[fi]": "Tiedustelupaketti", "Name[fr]": "Commande « Ping »", "Name[ko]": "핑", "Name[pt]": "Contacto", "Name[ru]": "Тестовый сигнал", "Name[sr@ijekavian]": "Пинг", "Name[sr]": "Пинг", "Name[sv]": "Pinga", "Name[uk]": "Луна-імпульс", "Name[x-test]": "xxPingxx", "Name[zh_TW]": "Ping回應封包", "ServiceTypes": [ "KdeConnect/Plugin" ], "Version": "0.1", "Website": "http://albertvaka.wordpress.com" }, "X-KdeConnect-OutgoingPackageType": [ "kdeconnect.ping" ], "X-KdeConnect-SupportedPackageType": [ "kdeconnect.ping" ] } diff --git a/plugins/ping/pingplugin.h b/plugins/ping/pingplugin.h index 2965a767..fb236223 100644 --- a/plugins/ping/pingplugin.h +++ b/plugins/ping/pingplugin.h @@ -1,49 +1,49 @@ /** * Copyright 2013 Albert Vaca * * 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 PINGPLUGIN_H #define PINGPLUGIN_H #include #include #define PACKAGE_TYPE_PING QStringLiteral("kdeconnect.ping") class Q_DECL_EXPORT PingPlugin : public KdeConnectPlugin { Q_OBJECT Q_CLASSINFO("D-Bus Interface", "org.kde.kdeconnect.device.ping") public: - explicit PingPlugin(QObject *parent, const QVariantList &args); + explicit PingPlugin(QObject* parent, const QVariantList& args); ~PingPlugin() override; Q_SCRIPTABLE void sendPing(); Q_SCRIPTABLE void sendPing(const QString& customMessage); bool receivePackage(const NetworkPackage& np) override; void connected() override {} QString dbusPath() const override; }; #endif diff --git a/plugins/remotecommands/kdeconnect_remotecommands.json b/plugins/remotecommands/kdeconnect_remotecommands.json index 87686695..eb6ec9dd 100644 --- a/plugins/remotecommands/kdeconnect_remotecommands.json +++ b/plugins/remotecommands/kdeconnect_remotecommands.json @@ -1,92 +1,90 @@ { "Encoding": "UTF-8", "KPlugin": { "Authors": [ { "Email": "aleixpol@kde.org", "Name": "Aleix Pol", "Name[sr@ijekavian]": "Алекс Пол Гонзалез", "Name[sr@ijekavianlatin]": "Aleks Pol Gonzalez", "Name[sr@latin]": "Aleks Pol Gonzalez", "Name[sr]": "Алекс Пол Гонзалез", "Name[x-test]": "xxAleix Polxx" } ], "Description": "Trigger commands predefined on the remote device", "Description[ar]": "نفّذ أوامر معرّفة مسبقًا في الجهاز البعيد", "Description[ca@valencia]": "Activa ordes predefinides en el dispositiu remot", "Description[ca]": "Activa ordres predefinides en el dispositiu remot", "Description[cs]": "Spouštět příkazy předpřipravené na vzdáleném zařízení", "Description[da]": "Udløs kommandoer som er prædefinerede på den eksterne enhed", "Description[de]": "Vordefinierte Befehle auf dem entfernten Gerät ausführen", "Description[el]": "Ενεργοποίηση προκαθορισμένων εντολών στην απομακρυσμένη συσκευή", "Description[es]": "Desencadenar órdenes predefinidas en el dispositivo remoto", "Description[et]": "Kaugseadmes määratud käskude käivitamine", - "Description[eu]": "Exekutatu urruneko gailuan aurretiaz zehaztutako komandoak", "Description[fi]": "Suorita ennakkoon määriteltyjä komentoja etälaitteella", "Description[fr]": "Exécuter des commandes prédéfinies sur le périphérique distant", "Description[gl]": "Provocar ordes predefinidas no dispositivo remoto.", "Description[it]": "Innesca comandi predefiniti sul dispositivo remoto", "Description[ko]": "원격 장치에 미리 정의한 트리거 명령", "Description[nl]": "Start commando's voorgedefinieerd op het apparaat op afstand", "Description[nn]": "Løys ut ferdigdefinerte kommandoar på eininga", "Description[pl]": "Wyzwalaj polecenia określone na zdalnym urządzeniu", "Description[pt]": "Despoletar os comandos predefinidos para o dispositivo remoto", "Description[ru]": "Вызов команд, предопределённых на удалённом устройстве", "Description[sk]": "Vyvolať príkazy preddefinované na vzdialenom zariadení", "Description[sr@ijekavian]": "Окида наредбе предефинисане на удаљеном уређају", "Description[sr@ijekavianlatin]": "Okida naredbe predefinisane na udaljenom uređaju", "Description[sr@latin]": "Okida naredbe predefinisane na udaljenom uređaju", "Description[sr]": "Окида наредбе предефинисане на удаљеном уређају", "Description[sv]": "Utför kommandon fördefinierade på den andra apparaten", "Description[tr]": "Uzak aygıta önceden tanımlanmış komutları tetikleyin", "Description[uk]": "Запуск команд, попередньо визначених на віддаленому пристрої", "Description[x-test]": "xxTrigger commands predefined on the remote devicexx", "Description[zh_CN]": "出发远程设备的预设命令", "Description[zh_TW]": "預先設定在遠端設備上的執行命令", "EnabledByDefault": true, "Icon": "system-run", "Id": "kdeconnect_remotecommands", "License": "GPL", "Name": "Host remote commands", "Name[ar]": "استضف الأوامر البعيدة", "Name[ca@valencia]": "Allotja ordes remotes", "Name[ca]": "Allotja ordres remotes", "Name[cs]": "Přijímat vzdálené příkazy", "Name[da]": "Vært for eksterne kommandoer", "Name[el]": "Απομακρυσμένη εκτέλεση εντολών", "Name[es]": "Órdenes en servidor remoto", "Name[et]": "Kaugkäsud", - "Name[eu]": "Ostalariaren urruneko komandoak", "Name[fi]": "Etäkomennot", "Name[fr]": "Exécuter des commandes distantes", "Name[gl]": "Ordes remotas do servidor", "Name[it]": "Comandi remoti host", "Name[ko]": "호스트 원격 명령", "Name[nl]": "Host voor commando's op afstand", "Name[nn]": "Fjernkommandoar", "Name[pl]": "Wykonuj polecenia zdalne", "Name[pt]": "Alojar os comandos remotos", "Name[ru]": "Выполнение команд на устройстве", "Name[sr@ijekavian]": "Даљинске наредбе домаћина", "Name[sr@ijekavianlatin]": "Daljinske naredbe domaćina", "Name[sr@latin]": "Daljinske naredbe domaćina", "Name[sr]": "Даљинске наредбе домаћина", "Name[sv]": "Fjärrkommandon för värddator", "Name[tr]": "Sunucu uzaktan komutları", "Name[uk]": "Віддалені команди вузлу", "Name[x-test]": "xxHost remote commandsxx", "Name[zh_CN]": "主机远程命令", "Name[zh_TW]": "主機與遠端指令", "ServiceTypes": [ "KdeConnect/Plugin" ], "Version": "0.1" }, "X-KdeConnect-OutgoingPackageType": [ "kdeconnect.runcommand.request" ], "X-KdeConnect-SupportedPackageType": [ "kdeconnect.runcommand" ] } diff --git a/plugins/remotecommands/remotecommandsplugin.cpp b/plugins/remotecommands/remotecommandsplugin.cpp index d8a4109f..0d24a59d 100644 --- a/plugins/remotecommands/remotecommandsplugin.cpp +++ b/plugins/remotecommands/remotecommandsplugin.cpp @@ -1,85 +1,85 @@ /** * 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 "remotecommandsplugin.h" #include #include #include #include #include #include #include #include #include #include #define PACKAGE_TYPE_RUNCOMMAND_REQUEST QLatin1String("kdeconnect.runcommand.request") K_PLUGIN_FACTORY_WITH_JSON( KdeConnectPluginFactory, "kdeconnect_remotecommands.json", registerPlugin< RemoteCommandsPlugin >(); ) Q_LOGGING_CATEGORY(KDECONNECT_PLUGIN_REMOTECOMMANDS, "kdeconnect.plugin.remotecommands") RemoteCommandsPlugin::RemoteCommandsPlugin(QObject* parent, const QVariantList& args) : KdeConnectPlugin(parent, args) , m_commands("{}") { } RemoteCommandsPlugin::~RemoteCommandsPlugin() = default; bool RemoteCommandsPlugin::receivePackage(const NetworkPackage& np) { if (np.has(QStringLiteral("commandList"))) { setCommands(np.get(QStringLiteral("commandList"))); return true; } return false; } void RemoteCommandsPlugin::connected() { NetworkPackage np(PACKAGE_TYPE_RUNCOMMAND_REQUEST, {{"requestCommandList", true}}); sendPackage(np); } QString RemoteCommandsPlugin::dbusPath() const { return "/modules/kdeconnect/devices/" + device()->id() + "/remotecommands"; } -void RemoteCommandsPlugin::setCommands(const QByteArray &cmds) +void RemoteCommandsPlugin::setCommands(const QByteArray& cmds) { if (m_commands != cmds) { m_commands = cmds; Q_EMIT commandsChanged(m_commands); } } -void RemoteCommandsPlugin::triggerCommand(const QString &key) +void RemoteCommandsPlugin::triggerCommand(const QString& key) { NetworkPackage np(PACKAGE_TYPE_RUNCOMMAND_REQUEST, {{ "key", key }}); sendPackage(np); } #include "remotecommandsplugin.moc" diff --git a/plugins/remotecommands/remotecommandsplugin.h b/plugins/remotecommands/remotecommandsplugin.h index a5416f0c..d592c76b 100644 --- a/plugins/remotecommands/remotecommandsplugin.h +++ b/plugins/remotecommands/remotecommandsplugin.h @@ -1,60 +1,60 @@ /** * 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 REMOTECOMMANDSPLUGIN_H #define REMOTECOMMANDSPLUGIN_H #include #include #include #include #include #include #include class Q_DECL_EXPORT RemoteCommandsPlugin : public KdeConnectPlugin { Q_OBJECT Q_CLASSINFO("D-Bus Interface", "org.kde.kdeconnect.device.remotecommands") Q_PROPERTY(QByteArray commands READ commands NOTIFY commandsChanged) public: - explicit RemoteCommandsPlugin(QObject *parent, const QVariantList &args); + explicit RemoteCommandsPlugin(QObject* parent, const QVariantList& args); ~RemoteCommandsPlugin() override; - Q_SCRIPTABLE void triggerCommand(const QString &key); + Q_SCRIPTABLE void triggerCommand(const QString& key); QByteArray commands() const { return m_commands; } bool receivePackage(const NetworkPackage& np) override; void connected() override; QString dbusPath() const override; Q_SIGNALS: void commandsChanged(const QByteArray& commands); private: - void setCommands(const QByteArray &commands); + void setCommands(const QByteArray& commands); QByteArray m_commands; }; #endif diff --git a/plugins/remotecontrol/kdeconnect_remotecontrol.json b/plugins/remotecontrol/kdeconnect_remotecontrol.json index ce6ec936..f56db818 100644 --- a/plugins/remotecontrol/kdeconnect_remotecontrol.json +++ b/plugins/remotecontrol/kdeconnect_remotecontrol.json @@ -1,92 +1,90 @@ { "Encoding": "UTF-8", "KPlugin": { "Authors": [ { "Email": "aleixpol@kde.org", "Name": "Aleix Pol", "Name[sr@ijekavian]": "Алекс Пол Гонзалез", "Name[sr@ijekavianlatin]": "Aleks Pol Gonzalez", "Name[sr@latin]": "Aleks Pol Gonzalez", "Name[sr]": "Алекс Пол Гонзалез", "Name[x-test]": "xxAleix Polxx" } ], "Description": "Control Remote systems", "Description[ar]": "تحكّم بالأنظمة البعيدة", "Description[ca@valencia]": "Sistemes de control remot", "Description[ca]": "Sistemes de control remot", "Description[cs]": "Ovládejte vzdálené systémy", "Description[da]": "Kontrollér eksterne systemer", "Description[de]": "Entfernte Systeme steuern", "Description[el]": "Έλεγχος ανταπόκρισης απομακρυσμένων συστημάτων", "Description[es]": "Controlar sistemas remotos", "Description[et]": "Kaugjuhtimissüsteemid", - "Description[eu]": "Kontrolatu urruneko sistemak", "Description[fi]": "Ohjaa järjestelmiä etänä", "Description[fr]": "Controllez les systèmes distants", "Description[gl]": "Controla sistemas remotos.", "Description[it]": "Controlla i sistemi remoti", "Description[ko]": "원격 시스템 제어", "Description[nl]": "Systemen op afstand bedienen", "Description[nn]": "Fjernkontroller system", "Description[pl]": "Sterowanie zdalnymi systemami", "Description[pt]": "Comandar sistemas à distância", "Description[pt_BR]": "Controle remoto de sistemas", "Description[ru]": "Управление удалёнными системами", "Description[sk]": "Ovládať vzdialené systémy", "Description[sr@ijekavian]": "Контролише удаљене системе", "Description[sr@ijekavianlatin]": "Kontroliše udaljene sisteme", "Description[sr@latin]": "Kontroliše udaljene sisteme", "Description[sr]": "Контролише удаљене системе", "Description[sv]": "Styr externt system", "Description[tr]": "Uzak Sistemleri Kontrol Et", "Description[uk]": "Системи віддаленого керування", "Description[x-test]": "xxControl Remote systemsxx", "Description[zh_CN]": "控制远程系统", "Description[zh_TW]": "控制遠端系統", "EnabledByDefault": true, "Icon": "applications-multimedia", "Id": "kdeconnect_remotecontrol", "License": "GPL", "Name": "RemoteControl", "Name[ar]": "التّحكّم عن بعد", "Name[ca@valencia]": "Control remot", "Name[ca]": "Control remot", "Name[cs]": "Dálkové ovládání", "Name[da]": "FjernBetjening", "Name[de]": "Fernsteuerung", "Name[es]": "Control remoto", "Name[et]": "Kaugjuhtimine", - "Name[eu]": "UrrunekoKontrola", "Name[fi]": "Kauko-ohjain", "Name[gl]": "Mando a distancia", "Name[it]": "Telecomando", "Name[ko]": "원격 제어", "Name[nl]": "Afstandsbediening", "Name[nn]": "Fjernkontroll", "Name[pl]": "ZdalneSterowanie", "Name[pt]": "Comando à Distância", "Name[pt_BR]": "Controle remoto", "Name[ru]": "Удалённое управление", "Name[sk]": "Diaľkové ovládanie", "Name[sr@ijekavian]": "Удаљене контроле", "Name[sr@ijekavianlatin]": "Udaljene kontrole", "Name[sr@latin]": "Udaljene kontrole", "Name[sr]": "Удаљене контроле", "Name[sv]": "Fjärrkontroll", "Name[tr]": "UzaktanKumanda", "Name[x-test]": "xxRemoteControlxx", "Name[zh_CN]": "远程控制", "Name[zh_TW]": "遠端控制", "ServiceTypes": [ "KdeConnect/Plugin" ], "Version": "0.1", "Website": "https://kde.org" }, "X-KdeConnect-OutgoingPackageType": [ "kdeconnect.mousepad.request" ], "X-KdeConnect-SupportedPackageType": [] } diff --git a/plugins/remotecontrol/remotecontrolplugin.cpp b/plugins/remotecontrol/remotecontrolplugin.cpp index a0e95897..96c6ce79 100644 --- a/plugins/remotecontrol/remotecontrolplugin.cpp +++ b/plugins/remotecontrol/remotecontrolplugin.cpp @@ -1,65 +1,65 @@ /** * Copyright 2015 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 "remotecontrolplugin.h" #include #include #include #include #include #include #include K_PLUGIN_FACTORY_WITH_JSON( KdeConnectPluginFactory, "kdeconnect_remotecontrol.json", registerPlugin< RemoteControlPlugin >(); ) Q_LOGGING_CATEGORY(KDECONNECT_PLUGIN_REMOTECONTROL, "kdeconnect.plugin.remotecontrol") -RemoteControlPlugin::RemoteControlPlugin(QObject *parent, const QVariantList &args) +RemoteControlPlugin::RemoteControlPlugin(QObject* parent, const QVariantList &args) : KdeConnectPlugin(parent, args) { } RemoteControlPlugin::~RemoteControlPlugin() {} void RemoteControlPlugin::moveCursor(const QPoint &p) { NetworkPackage np(PACKAGE_TYPE_MOUSEPAD_REQUEST, { {"dx", p.x()}, {"dy", p.y()} }); sendPackage(np); } void RemoteControlPlugin::sendCommand(const QString &name, bool val) { NetworkPackage np(PACKAGE_TYPE_MOUSEPAD_REQUEST, {{name, val}}); sendPackage(np); } QString RemoteControlPlugin::dbusPath() const { return "/modules/kdeconnect/devices/" + device()->id() + "/remotecontrol"; } #include "remotecontrolplugin.moc" diff --git a/plugins/remotecontrol/remotecontrolplugin.h b/plugins/remotecontrol/remotecontrolplugin.h index 53d2fece..40c01a87 100644 --- a/plugins/remotecontrol/remotecontrolplugin.h +++ b/plugins/remotecontrol/remotecontrolplugin.h @@ -1,48 +1,48 @@ /** * Copyright 2015 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 REMOTECONTROLPLUGIN_H #define REMOTECONTROLPLUGIN_H #include #include #define PACKAGE_TYPE_MOUSEPAD_REQUEST QStringLiteral("kdeconnect.mousepad.request") class Q_DECL_EXPORT RemoteControlPlugin : public KdeConnectPlugin { Q_OBJECT Q_CLASSINFO("D-Bus Interface", "org.kde.kdeconnect.device.remotecontrol") public: - explicit RemoteControlPlugin(QObject *parent, const QVariantList &args); + explicit RemoteControlPlugin(QObject* parent, const QVariantList &args); ~RemoteControlPlugin() override; bool receivePackage(const NetworkPackage& /*np*/) override { return false; } void connected() override {} QString dbusPath() const override; Q_SCRIPTABLE void moveCursor(const QPoint &p); Q_SCRIPTABLE void sendCommand(const QString &name, bool val); }; #endif diff --git a/plugins/remotekeyboard/kdeconnect_remotekeyboard.json b/plugins/remotekeyboard/kdeconnect_remotekeyboard.json index a6dca629..2ae2042e 100644 --- a/plugins/remotekeyboard/kdeconnect_remotekeyboard.json +++ b/plugins/remotekeyboard/kdeconnect_remotekeyboard.json @@ -1,79 +1,77 @@ { "Encoding": "UTF-8", "KPlugin": { "Authors": [ { "Email": "holger.k@elberer.de", "Name": "Holger Kaelberer", "Name[sr@ijekavian]": "Холгер Келберер", "Name[sr@ijekavianlatin]": "Holger Kelberer", "Name[sr@latin]": "Holger Kelberer", "Name[sr]": "Холгер Келберер", "Name[x-test]": "xxHolger Kaelbererxx" } ], "Description": "Use your keyboard to send key-events to your paired device", "Description[ca@valencia]": "Useu el vostre teclat per enviar esdeveniments de tecla al dispositiu enllaçat", "Description[ca]": "Useu el vostre teclat per enviar esdeveniments de tecla al dispositiu enllaçat", "Description[cs]": "Používejte svoji klávesnici pro odesílání událostí kláves na spárované zařízení", "Description[da]": "Brug dit tastatur til at sende tastehændelser til din parrede enhed", "Description[es]": "Use su teclado para enviar eventos de teclado a su dispositivo vinculado", - "Description[eu]": "Erabili zure teklatua tekla-gertaerak zure parekatutako gailura bidaltzeko", "Description[fr]": "Utiliser votre clavier pour envoyer des évènements de touche au périphérique associé", "Description[gl]": "Usar o teclado para enviar eventos de tecla ao dispositivo emparellado.", "Description[it]": "Utilizza la tua tastiera per inviare eventi di pressione dei tasti al dispositivo associato", "Description[nl]": "Uw toetsenbord gebruiken om toetsgebeurtenissen naar uw gepaarde apparaat te verzenden", "Description[nn]": "Bruk tastaturet til å senda tastetrykk til den para eininga", "Description[pl]": "Użyj swojej klawiatury do wysyłania naciśnięć klawiszy do swojego sparowanego urządzenia", "Description[pt]": "Usar o seu teclado para enviar eventos de teclas para o seu dispositivo emparelhado", "Description[ru]": "Используйте клавиатуру для отправки нажатий клавиш на сопряжённое устройство", "Description[sr@ijekavian]": "Користите тастатуру за куцање на упареном уређају", "Description[sr@ijekavianlatin]": "Koristite tastaturu za kucanje na uparenom uređaju", "Description[sr@latin]": "Koristite tastaturu za kucanje na uparenom uređaju", "Description[sr]": "Користите тастатуру за куцање на упареном уређају", "Description[sv]": "Använd tangentbordet för att skicka tangenthändelser till den parade enheten", "Description[tr]": "Eşleşmiş cihazınıza önemli etkinlikler göndermek için klavyenizi kullanın", "Description[uk]": "Скористайтеся вашою клавіатурою для надсилання подій натискання клавіш на пов’язаний пристрій", "Description[x-test]": "xxUse your keyboard to send key-events to your paired devicexx", "Description[zh_CN]": "使用您的键盘发送按键事件给配对的设备", "EnabledByDefault": true, "Icon": "edit-select", "Id": "kdeconnect_remotekeyboard", "License": "GPL", "Name": "Remote keyboard from the desktop", "Name[ca@valencia]": "Teclat remot des de l'escriptori", "Name[ca]": "Teclat remot des de l'escriptori", "Name[cs]": "Vzdálená klávesnice pro plochu", "Name[da]": "Eksternt tastatur fra desktoppen", "Name[es]": "Teclado remoto desde el equipo de escritorio", - "Name[eu]": "Urruneko teklatua mahaigainetik", "Name[fr]": "Clavier distant depuis le bureau", "Name[gl]": "Teclado remoto do escritorio", "Name[it]": "Tastiera remota dal desktop", "Name[nl]": "Toetsenbord op afstand vanaf het bureaublad", "Name[nn]": "Fjerntastatur frå skrivebordet", "Name[pl]": "Zdalna klawiatura z pulpitu", "Name[pt]": "Teclado remoto do ambiente de trabalho", "Name[ru]": "Удалённая клавиатура с компьютера", "Name[sr@ijekavian]": "Даљинска тастатура са радне површи", "Name[sr@ijekavianlatin]": "Daljinska tastatura sa radne površi", "Name[sr@latin]": "Daljinska tastatura sa radne površi", "Name[sr]": "Даљинска тастатура са радне површи", "Name[sv]": "Externt tangentbord från skrivbordet", "Name[tr]": "Masaüstünden uzak klavye", "Name[uk]": "Віддалена клавіатура з комп’ютера", "Name[x-test]": "xxRemote keyboard from the desktopxx", "Name[zh_CN]": "来自桌面的远程键盘", "ServiceTypes": [ "KdeConnect/Plugin" ], "Version": "0.1" }, "X-KdeConnect-OutgoingPackageType": [ "kdeconnect.mousepad.request" ], "X-KdeConnect-SupportedPackageType": [ "kdeconnect.mousepad.echo", "kdeconnect.mousepad.keyboardstate" ] } diff --git a/plugins/remotekeyboard/remotekeyboardplugin.h b/plugins/remotekeyboard/remotekeyboardplugin.h index 439981bc..28ac1db2 100644 --- a/plugins/remotekeyboard/remotekeyboardplugin.h +++ b/plugins/remotekeyboard/remotekeyboardplugin.h @@ -1,73 +1,73 @@ /** * Copyright 2017 Holger Kaelberer * * 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 REMOTEKEYBOARDPLUGIN_H #define REMOTEKEYBOARDPLUGIN_H #include #include #include #include struct FakeKey; Q_DECLARE_LOGGING_CATEGORY(KDECONNECT_PLUGIN_REMOTEKEYBOARD); #define PACKAGE_TYPE_MOUSEPAD_REQUEST QLatin1String("kdeconnect.mousepad.request") #define PACKAGE_TYPE_MOUSEPAD_ECHO QLatin1String("kdeconnect.mousepad.echo") #define PACKAGE_TYPE_MOUSEPAD_KEYBOARDSTATE QLatin1String("kdeconnect.mousepad.keyboardstate") class RemoteKeyboardPlugin : public KdeConnectPlugin { Q_OBJECT Q_CLASSINFO("D-Bus Interface", "org.kde.kdeconnect.device.remotekeyboard") Q_PROPERTY(bool remoteState READ remoteState NOTIFY remoteStateChanged) private: bool m_remoteState; public: - explicit RemoteKeyboardPlugin(QObject *parent, const QVariantList &args); + explicit RemoteKeyboardPlugin(QObject* parent, const QVariantList& args); ~RemoteKeyboardPlugin() override; bool receivePackage(const NetworkPackage& np) override; QString dbusPath() const override; void connected() override; bool remoteState() const { return m_remoteState; } Q_SCRIPTABLE void sendKeyPress(const QString& key, int specialKey = 0, bool shift = false, bool ctrl = false, bool alt = false, bool sendAck = true) const; Q_SCRIPTABLE void sendQKeyEvent(const QVariantMap& keyEvent, bool sendAck = true) const; Q_SCRIPTABLE int translateQtKey(int qtKey) const; Q_SIGNALS: Q_SCRIPTABLE void keyPressReceived(const QString& key, int specialKey = 0, bool shift = false, bool ctrl = false, bool alt = false) const; Q_SCRIPTABLE void remoteStateChanged(bool state) const; }; #endif diff --git a/plugins/runcommand/kdeconnect_runcommand.json b/plugins/runcommand/kdeconnect_runcommand.json index aab56251..9b983e13 100644 --- a/plugins/runcommand/kdeconnect_runcommand.json +++ b/plugins/runcommand/kdeconnect_runcommand.json @@ -1,107 +1,105 @@ { "Encoding": "UTF-8", "KPlugin": { "Authors": [ { "Email": "albertvaka@gmail.com", "Name": "Albert Vaca", "Name[sr@ijekavian]": "Алберт Вака Синтора", "Name[sr@ijekavianlatin]": "Albert Vaka Sintora", "Name[sr@latin]": "Albert Vaka Sintora", "Name[sr]": "Алберт Вака Синтора", "Name[x-test]": "xxAlbert Vacaxx" }, { "Email": "david@davidedmundson.co.uk", "Name": "David Edmundson", "Name[sr@ijekavian]": "Дејвид Едмундсон", "Name[sr@ijekavianlatin]": "Dejvid Edmundson", "Name[sr@latin]": "Dejvid Edmundson", "Name[sr]": "Дејвид Едмундсон", "Name[x-test]": "xxDavid Edmundsonxx" } ], "Description": "Execute console commands remotely", "Description[ar]": "نفّذ أوامر طرفيّة عن بعد", "Description[ca@valencia]": "Executa ordes de la consola de forma remota", "Description[ca]": "Executa ordres de la consola de forma remota", "Description[cs]": "Spouštět konzolové příkazy vzdáleně", "Description[da]": "Kør konsolkommandoer udefra", "Description[de]": "Entfernte Konsolenbefehle ausführen", "Description[el]": "Απομακρυσμένη εκτέλεση εντολών του τερματικού", "Description[es]": "Ejecute órdenes de consola remotamente", "Description[et]": "Konsoolikäskude kaugkäivitamine", - "Description[eu]": "Exekutatu kontsolako komandoak urrunetik", "Description[fi]": "Suorita konsolikomentoja etänä", "Description[fr]": "Exécute des commandes console à distance", "Description[gl]": "Executar ordes de consola remotamente.", "Description[it]": "Esegui da remoto comandi della console", "Description[ko]": "원격으로 콘솔 명령 실행", "Description[nl]": "Commando's in de terminal op afstand laten uitvoeren", "Description[nn]": "Køyr konsollkommandoar på eininga", "Description[pl]": "Wykonaj polecenie konsoli zdalnie", "Description[pt]": "Executar de forma remota comandos da consola", "Description[pt_BR]": "Executa comandos do console remotamente", "Description[ru]": "Выполнение консольных команд удалённо", "Description[sk]": "Spustiť priamo príkazy konzoly", "Description[sr@ijekavian]": "Даљински извршава наредбе у конзоли", "Description[sr@ijekavianlatin]": "Daljinski izvršava naredbe u konzoli", "Description[sr@latin]": "Daljinski izvršava naredbe u konzoli", "Description[sr]": "Даљински извршава наредбе у конзоли", "Description[sv]": "Kör terminalkommandon på distans", "Description[tr]": "Konsol komutlarını uzaktan çalıştır", "Description[uk]": "Віддалене виконання консольних команд", "Description[x-test]": "xxExecute console commands remotelyxx", "Description[zh_CN]": "远程执行控制台命令", "Description[zh_TW]": "遠程執行控制台命令", "EnabledByDefault": true, "Icon": "system-run", "Id": "kdeconnect_runcommand", "License": "GPL", "Name": "Run commands", "Name[ar]": "شغّل أوامر", "Name[ca@valencia]": "Executa ordes", "Name[ca]": "Executa ordres", "Name[cs]": "Spustit příkazy", "Name[da]": "Kør kommandoer", "Name[de]": "Befehle ausführen", "Name[el]": "Εκτέλεση εντολών", "Name[es]": "Ejecutar órdenes", "Name[et]": "Käskude käivitamine", - "Name[eu]": "Exekutatu komandoak", "Name[fi]": "Suorita komentoja", "Name[fr]": "Exécute des commandes", "Name[gl]": "Executar ordes", "Name[ia]": "Exeque commandos", "Name[it]": "Esegui comandi", "Name[ko]": "명령 실행", "Name[nl]": "Commando's uitvoeren", "Name[nn]": "Køyr kommandoar", "Name[pl]": "Wykonywanie polecenie", "Name[pt]": "Executar comandos", "Name[pt_BR]": "Executar comandos", "Name[ru]": "Выполнение команд", "Name[sk]": "Spustiť príkazy", "Name[sr@ijekavian]": "Изврши наредбе", "Name[sr@ijekavianlatin]": "Izvrši naredbe", "Name[sr@latin]": "Izvrši naredbe", "Name[sr]": "Изврши наредбе", "Name[sv]": "Kör kommandon", "Name[tr]": "Komut çalıştır", "Name[uk]": "Виконання команд", "Name[x-test]": "xxRun commandsxx", "Name[zh_CN]": "执行命令", "Name[zh_TW]": "執行命令", "ServiceTypes": [ "KdeConnect/Plugin" ], "Version": "0.1", "Website": "http://albertvaka.wordpress.com" }, "X-KdeConnect-OutgoingPackageType": [ "kdeconnect.runcommand" ], "X-KdeConnect-SupportedPackageType": [ "kdeconnect.runcommand.request" ] } diff --git a/plugins/runcommand/kdeconnect_runcommand_config.desktop b/plugins/runcommand/kdeconnect_runcommand_config.desktop index 52d8bc49..161dedee 100644 --- a/plugins/runcommand/kdeconnect_runcommand_config.desktop +++ b/plugins/runcommand/kdeconnect_runcommand_config.desktop @@ -1,45 +1,44 @@ [Desktop Entry] Type=Service X-KDE-ServiceTypes=KCModule X-KDE-Library=kdeconnect_runcommand_config X-KDE-ParentComponents=kdeconnect_runcommand Name=Run Command plugin settings Name[ar]=إعدادات ملحقة تشغيل الأوامر Name[ast]=Axustes del complementu d'execución de comandos Name[ca]=Ajustaments del connector Executa ordres Name[ca@valencia]=Ajustaments del connector Executa ordes Name[cs]=Nastavení modulu Spustit příkaz Name[da]=Indstilling af kør kommando-plugin Name[de]=Modul-Einstellungen für Befehlsausführung Name[el]=Ρυθμίσεις προσθέτου εκτέλεσης εντολής Name[en_GB]=Run Command plugin settings Name[es]=Ajustes del complemento de ejecución de órdenes Name[et]=Käsu käivitamise plugina seadistused -Name[eu]=Exekutatu komandoa pluginaren ezarpenak Name[fi]=Suorita komento -liitännäisen asetukset Name[fr]=Configuration du module externe d'exécution de commande Name[gl]=Configuración do complemento de orde de executar Name[he]=הגדרת התוסף הרץ פקודה Name[it]=Impostazioni estensione Esegui comando Name[ko]=명령 실행 플러그인 설정 Name[nl]=Plug-in-instellingen van commando Uitvoeren Name[nn]=Innstillingar for kommandokøyring Name[pl]=Ustawienia wtyczki wykonywania polecenia Name[pt]=Configuração do 'plugin' de execução de comandos Name[pt_BR]=Configurações do plugin de execução de comandos Name[ru]=Настройка модуля выполнения команд Name[sk]=Nastavenia pluginu spustenia príkazu Name[sr]=Поставке прикључка извршавања наредбе Name[sr@ijekavian]=Поставке прикључка извршавања наредбе Name[sr@ijekavianlatin]=Postavke priključka izvršavanja naredbe Name[sr@latin]=Postavke priključka izvršavanja naredbe Name[sv]=Inställningar av insticksprogram för kör kommando Name[tr]=Komut Çalıştır eklenti ayarları Name[uk]=Параметри додатка запуску команд Name[x-test]=xxRun Command plugin settingsxx Name[zh_CN]=执行命令插件设置 Name[zh_TW]=命令列擴展插件設定 Categories=Qt;KDE;X-KDE-settings-kdeconnect; diff --git a/plugins/runcommand/runcommand_config.cpp b/plugins/runcommand/runcommand_config.cpp index cfb3bb2c..648b474c 100644 --- a/plugins/runcommand/runcommand_config.cpp +++ b/plugins/runcommand/runcommand_config.cpp @@ -1,146 +1,146 @@ /** * 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) 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 "runcommand_config.h" #include #include #include #include #include #include #include #include #include #include K_PLUGIN_FACTORY(ShareConfigFactory, registerPlugin();) -RunCommandConfig::RunCommandConfig(QWidget *parent, const QVariantList& args) +RunCommandConfig::RunCommandConfig(QWidget* parent, const QVariantList& args) : KdeConnectPluginKcm(parent, args, QStringLiteral("kdeconnect_runcommand_config")) { - QTableView *table = new QTableView(this); + QTableView* table = new QTableView(this); table->horizontalHeader()->setStretchLastSection(true); table->verticalHeader()->setVisible(false); - QVBoxLayout *layout = new QVBoxLayout(this); + QVBoxLayout* layout = new QVBoxLayout(this); layout->addWidget(table); setLayout(layout); m_entriesModel = new QStandardItemModel(this); table->setModel(m_entriesModel); m_entriesModel->setHorizontalHeaderLabels(QStringList() << i18n("Name") << i18n("Command")); } RunCommandConfig::~RunCommandConfig() { } void RunCommandConfig::defaults() { KCModule::defaults(); m_entriesModel->clear(); Q_EMIT changed(true); } void RunCommandConfig::load() { KCModule::load(); QJsonDocument jsonDocument = QJsonDocument::fromJson(config()->get(QStringLiteral("commands"), "{}")); QJsonObject jsonConfig = jsonDocument.object(); const QStringList keys = jsonConfig.keys(); for (const QString& key : keys) { const QJsonObject entry = jsonConfig[key].toObject(); const QString name = entry[QStringLiteral("name")].toString(); const QString command = entry[QStringLiteral("command")].toString(); - QStandardItem *newName = new QStandardItem(name); + QStandardItem* newName = new QStandardItem(name); newName->setEditable(true); newName->setData(key); - QStandardItem *newCommand = new QStandardItem(command); + QStandardItem* newCommand = new QStandardItem(command); newName->setEditable(true); m_entriesModel->appendRow(QList() << newName << newCommand); } m_entriesModel->sort(0); insertEmptyRow(); connect(m_entriesModel, &QAbstractItemModel::dataChanged, this, &RunCommandConfig::onDataChanged); Q_EMIT changed(false); } void RunCommandConfig::save() { QJsonObject jsonConfig; for (int i=0;i < m_entriesModel->rowCount(); i++) { QString key = m_entriesModel->item(i, 0)->data().toString(); const QString name = m_entriesModel->item(i, 0)->text(); const QString command = m_entriesModel->item(i, 1)->text(); if (name.isEmpty() || command.isEmpty()) { continue; } if (key.isEmpty()) { key = QUuid::createUuid().toString(); } QJsonObject entry; entry[QStringLiteral("name")] = name; entry[QStringLiteral("command")] = command; jsonConfig[key] = entry; } QJsonDocument document; document.setObject(jsonConfig); config()->set(QStringLiteral("commands"), document.toJson(QJsonDocument::Compact)); KCModule::save(); Q_EMIT changed(false); } void RunCommandConfig::insertEmptyRow() { - QStandardItem *newName = new QStandardItem; + QStandardItem* newName = new QStandardItem; newName->setEditable(true); - QStandardItem *newCommand = new QStandardItem; + QStandardItem* newCommand = new QStandardItem; newName->setEditable(true); m_entriesModel->appendRow(QList() << newName << newCommand); } void RunCommandConfig::onDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) { changed(true); Q_UNUSED(topLeft); if (bottomRight.row() == m_entriesModel->rowCount() - 1) { //TODO check both entries are still empty insertEmptyRow(); } } #include "runcommand_config.moc" diff --git a/plugins/runcommand/runcommand_config.h b/plugins/runcommand/runcommand_config.h index a22693bf..13639cf7 100644 --- a/plugins/runcommand/runcommand_config.h +++ b/plugins/runcommand/runcommand_config.h @@ -1,50 +1,50 @@ /** * 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) 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 SHARE_CONFIG_H #define SHARE_CONFIG_H #include "kcmplugin/kdeconnectpluginkcm.h" class QStandardItemModel; class RunCommandConfig : public KdeConnectPluginKcm { Q_OBJECT public: - RunCommandConfig(QWidget *parent, const QVariantList&); + RunCommandConfig(QWidget* parent, const QVariantList&); ~RunCommandConfig() override; public Q_SLOTS: void save() override; void load() override; void defaults() override; private Q_SLOTS: - void onDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight); + void onDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight); private: void insertEmptyRow(); - QStandardItemModel *m_entriesModel; + QStandardItemModel* m_entriesModel; }; #endif diff --git a/plugins/runcommand/runcommandplugin.h b/plugins/runcommand/runcommandplugin.h index d362038f..f272548c 100644 --- a/plugins/runcommand/runcommandplugin.h +++ b/plugins/runcommand/runcommandplugin.h @@ -1,53 +1,53 @@ /** * Copyright 2015 Albert Vaca * * 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 RUNCOMMANDPLUGIN_H #define RUNCOMMANDPLUGIN_H #include #include #include #include #include #include #include class Q_DECL_EXPORT RunCommandPlugin : public KdeConnectPlugin { Q_OBJECT public: - explicit RunCommandPlugin(QObject *parent, const QVariantList &args); + explicit RunCommandPlugin(QObject* parent, const QVariantList& args); ~RunCommandPlugin() override; bool receivePackage(const NetworkPackage& np) override; void connected() override; private Q_SLOTS: void configChanged(); private: void sendConfig(); }; #endif diff --git a/plugins/screensaver-inhibit/kdeconnect_screensaver_inhibit.json b/plugins/screensaver-inhibit/kdeconnect_screensaver_inhibit.json index d013aa78..adf0c0bd 100644 --- a/plugins/screensaver-inhibit/kdeconnect_screensaver_inhibit.json +++ b/plugins/screensaver-inhibit/kdeconnect_screensaver_inhibit.json @@ -1,91 +1,89 @@ { "Encoding": "UTF-8", "KPlugin": { "Authors": [ { "Email": "pmdematagoda@mykolab.ch", "Name": "Pramod Dematagoda", "Name[sr@ijekavian]": "Прамод Дематагода", "Name[sr]": "Прамод Дематагода", "Name[x-test]": "xxPramod Dematagodaxx" } ], "Description": "Inhibit the screensaver when the device is connected", "Description[ar]": "امنع حافظة الشّاشة إن كان الجهاز متّصلًا", "Description[ca@valencia]": "Inhibeix l'estalvi de pantalla quan es connecta el dispositiu", "Description[ca]": "Inhibeix l'estalvi de pantalla quan es connecta el dispositiu", "Description[cs]": "Potlačit spořič pokud je zařízení připojeno", "Description[da]": "Tilbagehold pauseskærmen når enheden er tilsluttet", "Description[de]": "Bildschirmschoner unterbinden wenn ein Gerät angeschlossen ist", "Description[el]": "Απαγόρευση προστασίας οθόνης όταν η συσκευή είναι σε σύνδεση", "Description[es]": "Inhibir el salvapantallas cuando el dispositivo está conectado", "Description[et]": "Ekraanisäästja keelamine, kui seade on ühendatud", - "Description[eu]": "Gelditu pantaila-babeslea gailua konektatuta dagoenean", "Description[fi]": "Estä näytönsäästäjän käynnistyminen, kun laite on yhteydessä", "Description[fr]": "Inhiber l'économiseur d'écran quand le périphérique est connecté", "Description[gl]": "Desactivar o salvapantallas mentres o dispositivo estea conectado.", "Description[hu]": "A képernyővédő kikapcsolása, ha az eszköz csatlakoztatva van", "Description[it]": "Impedisci il salvaschermo quando il dispositivo è connesso", "Description[ko]": "장치가 연결되었을 때 화면 보호기 실행 중지", "Description[nl]": "Houdt de schermbeveiliging tegen wanneer het apparaat is verbonden", "Description[nn]": "Hindra pauseskjermen i å starta når eininga er kopla til", "Description[pl]": "Powstrzymaj wygaszacz ekrany po podłączeniu urządzenia", "Description[pt]": "Inibir o protector de ecrã quando o dispositivo estiver ligado", "Description[pt_BR]": "Inibe o protetor de tela quando o dispositivo estiver conectado", "Description[ru]": "Предотвращение запуска блокировщика экрана, когда устройство подключено", "Description[sk]": "Obmedziť šetrič obrazovky keď je pripojené zariadenie", "Description[sr@ijekavian]": "Онемогућава чувара екрана када је уређај повезан", "Description[sr@ijekavianlatin]": "Onemogućava čuvara ekrana kada je uređaj povezan", "Description[sr@latin]": "Onemogućava čuvara ekrana kada je uređaj povezan", "Description[sr]": "Онемогућава чувара екрана када је уређај повезан", "Description[sv]": "Stoppa skärmsläckaren när apparaten ansluts", "Description[tr]": "Aygıt bağlandığında ekran koruyucuyu durdur", "Description[uk]": "Забороняє зберігач екрана, якщо з’єднано пристрій", "Description[x-test]": "xxInhibit the screensaver when the device is connectedxx", "Description[zh_CN]": "连接设备时禁止屏保", "Description[zh_TW]": "當裝置連接中時停止螢幕保護", "EnabledByDefault": false, "Icon": "preferences-desktop-screensaver", "Id": "kdeconnect_screensaver_inhibit", "License": "GPL", "Name": "Inhibit screensaver", "Name[ar]": "امنع حافظة الشّاشة", "Name[ca@valencia]": "Inhibeix l'estalvi de pantalla", "Name[ca]": "Inhibeix l'estalvi de pantalla", "Name[cs]": "Potlačit spořič obrazovky", "Name[da]": "Tilbagehold pauseskærm", "Name[de]": "Bildschirmschoner unterbinden", "Name[el]": "Απαγόρευση προστασίας οθόνης", "Name[es]": "Inhibir salvapantallas", "Name[et]": "Ekraanisäästja keelamine", - "Name[eu]": "Gelditu pantaila-babeslea", "Name[fi]": "Estä näytönsäästäjän käynnistyminen", "Name[fr]": "Inhiber l'économiseur d'écran", "Name[gl]": "Desactivar o salvapantallas", "Name[hu]": "Képernyővédő letiltása", "Name[it]": "Impedisci il salvaschermo", "Name[ko]": "화면 보호기 중지", "Name[nl]": "Schermbeveiliging tegenhouden", "Name[nn]": "Hindra pauseskjerm", "Name[pl]": "Powstrzymaj wygaszacz ekranu", "Name[pt]": "Inibir o protector de ecrã", "Name[pt_BR]": "Inibir o protetor de tela", "Name[ru]": "Запрет блокировки экрана", "Name[sk]": "Obmedziť šetrič obrazovky", "Name[sr@ijekavian]": "Онемогући чувара екрана", "Name[sr@ijekavianlatin]": "Onemogući čuvara ekrana", "Name[sr@latin]": "Onemogući čuvara ekrana", "Name[sr]": "Онемогући чувара екрана", "Name[sv]": "Stoppa skärmsläckare", "Name[tr]": "Ekran koruyucuyu durdur", "Name[uk]": "Заборона зберігача екрана", "Name[x-test]": "xxInhibit screensaverxx", "Name[zh_CN]": "禁止屏保", "Name[zh_TW]": "停止螢幕保護", "ServiceTypes": [ "KdeConnect/Plugin" ], "Version": "0.1", "Website": "http://albertvaka.wordpress.com" } } diff --git a/plugins/screensaver-inhibit/screensaverinhibitplugin.h b/plugins/screensaver-inhibit/screensaverinhibitplugin.h index f54b6228..462a2233 100644 --- a/plugins/screensaver-inhibit/screensaverinhibitplugin.h +++ b/plugins/screensaver-inhibit/screensaverinhibitplugin.h @@ -1,44 +1,44 @@ /** * Copyright 2014 Pramod Dematagoda * * 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 SCREENSAVERINHIBITPLUGIN_H #define SCREENSAVERINHIBITPLUGIN_H #include #include class Q_DECL_EXPORT ScreensaverInhibitPlugin : public KdeConnectPlugin { Q_OBJECT public: - explicit ScreensaverInhibitPlugin(QObject *parent, const QVariantList &args); + explicit ScreensaverInhibitPlugin(QObject* parent, const QVariantList& args); ~ScreensaverInhibitPlugin() override; bool receivePackage(const NetworkPackage& np) override; void connected() override; private: uint inhibitCookie; }; #endif diff --git a/plugins/sendnotifications/kdeconnect_sendnotifications.json b/plugins/sendnotifications/kdeconnect_sendnotifications.json index 8f66faaa..5cbb3d82 100644 --- a/plugins/sendnotifications/kdeconnect_sendnotifications.json +++ b/plugins/sendnotifications/kdeconnect_sendnotifications.json @@ -1,96 +1,94 @@ { "Encoding": "UTF-8", "KPlugin": { "Authors": [ { "Email": "holger.k@elberer.de", "Name": "Holger Kaelberer", "Name[sr@ijekavian]": "Холгер Келберер", "Name[sr@ijekavianlatin]": "Holger Kelberer", "Name[sr@latin]": "Holger Kelberer", "Name[sr]": "Холгер Келберер", "Name[x-test]": "xxHolger Kaelbererxx" } ], "Description": "Broadcast this computer's notifications, so they can be shown on other devices.", "Description[ar]": "بُثّ إخطارات هذا الحاسوب، لتظهر على الأجهزة الأخرى.", "Description[ca@valencia]": "Transmet les notificacions d'este ordinador, perquè puguen mostrar-se en altres dispositius.", "Description[ca]": "Transmet les notificacions d'aquest ordinador, perquè puguin mostrar-se en altres dispositius.", "Description[cs]": "Posílat upozornění tohoto počítače, takže mohou být zobrazena na jiných zařízeních.", "Description[da]": "Udsend denne computers bekendtgørelser, så de kan vises på andre enheder.", "Description[de]": "Die Benachrichtigungen dieses Rechners aussenden, sodass sie auf anderen Geräten angezeigt werden können.", "Description[el]": "Μεταδώστε την ειδοποίηση αυτού του υπολογιστή, ώστε να εμφανιστεί σε άλλες συσκευές.", "Description[es]": "Difundir las notificaciones de este equipo, para que puedan mostrarse en otros dispositivos.", "Description[et]": "Arvuti märguannete levitamine, et neid oleks näha ka teistes seadmetes", - "Description[eu]": "Hedatu ordenagailu honen jakinarazpenak, beste gailuetan erakutsi ahal izateko", "Description[fi]": "Lähetä tämän tietokoneen ilmoitukset, jotta ne voidaan näyttää muilla laitteilla.", "Description[fr]": "Diffuser les notifications de cet ordinateur pour qu'elles puissent être vues par d'autres périphériques.", "Description[gl]": "Emitir as notificacións deste computador para que se mostren noutros dispositivos.", "Description[it]": "Trasmetti le notifiche di questo computer, affinché possano essere mostrate su altri dispositivi.", "Description[ko]": "이 컴퓨터의 알림을 다른 장치에도 표시합니다.", "Description[nl]": "De meldingen van deze computer rondsturen, zodat ze op andere apparaten getoond kunnen worden.", "Description[nn]": "Vidaresend varslingar frå datamaskina til andre einingar.", "Description[pl]": "Rozgłaszaj powiadomienia tego komputera, tak aby można je było wyświetlać na innych urządzeniach.", "Description[pt]": "Difunde as notificações deste computador, para que possam ser apresentadas noutros dispositivos.", "Description[ru]": "Трансляция уведомления с этого компьютера, чтобы они могли быть видны на других устройствах", "Description[sk]": "Vysielať upozornenia tohto počítača, aby sa zobrazili na druhom zariadení.", "Description[sr@ijekavian]": "Одашиље обавештења са овог рачунара, да се приказују на осталим уређајима.", "Description[sr@ijekavianlatin]": "Odašilje obaveštenja sa ovog računara, da se prikazuju na ostalim uređajima.", "Description[sr@latin]": "Odašilje obaveštenja sa ovog računara, da se prikazuju na ostalim uređajima.", "Description[sr]": "Одашиље обавештења са овог рачунара, да се приказују на осталим уређајима.", "Description[sv]": "Sänd ut datorns underrättelser så att de kan visas på andra enheter.", "Description[tr]": "Bu bilgisayarın bildirimlerini yayınlayın, böylece diğer cihazlarda gösterilebilirler.", "Description[uk]": "Транслювати сповіщення з цього комп’ютера так, щоб їх було показано на інших пристроях.", "Description[x-test]": "xxBroadcast this computer's notifications, so they can be shown on other devices.xx", "Description[zh_CN]": "广播此计算机的通知,以被其他设备显示。", "Description[zh_TW]": "廣播此電腦的通知,這樣可以顯示在其他裝置上。", "EnabledByDefault": false, "Icon": "preferences-desktop-notification", "Id": "kdeconnect_sendnotifications", "License": "GPL", "Name": "Send notifications", "Name[ar]": "أرسل إخطارات", "Name[ca@valencia]": "Envia les notificacions", "Name[ca]": "Envia les notificacions", "Name[cs]": "Posílat oznamování", "Name[da]": "Send bekendtgørelser", "Name[de]": "Benachrichtigungen senden", "Name[el]": "Αποστολή ειδοποιήσεων", "Name[es]": "Enviar notificaciones", "Name[et]": "Märguannete saatmine", - "Name[eu]": "Bidali jakinarazpenak", "Name[fi]": "Lähetä ilmoituksia", "Name[fr]": "Envoyer les notifications", "Name[gl]": "Enviar notificacións", "Name[it]": "Invia notifiche", "Name[ko]": "알림 보내기", "Name[nl]": "Stuur meldingen", "Name[nn]": "Send varslingar", "Name[pl]": "Wysyłaj powiadomienia", "Name[pt]": "Enviar as notificações", "Name[pt_BR]": "Enviar notificações", "Name[ru]": "Отправка уведомлений", "Name[sk]": "Posielať upozornenia", "Name[sr@ijekavian]": "Шаљи обавештења", "Name[sr@ijekavianlatin]": "Šalji obaveštenja", "Name[sr@latin]": "Šalji obaveštenja", "Name[sr]": "Шаљи обавештења", "Name[sv]": "Skicka underrättelser", "Name[tr]": "Bildirim gönder", "Name[uk]": "Надіслати сповіщення", "Name[x-test]": "xxSend notificationsxx", "Name[zh_CN]": "发送通知", "Name[zh_TW]": "傳送通知", "ServiceTypes": [ "KdeConnect/Plugin" ], "Version": "0.1", "Website": "http://albertvaka.wordpress.com" }, "X-KdeConnect-OutgoingPackageType": [ "kdeconnect.notification" ], "X-KdeConnect-SupportedPackageType": [ "kdeconnect.notification.request" ] } diff --git a/plugins/sendnotifications/kdeconnect_sendnotifications_config.desktop b/plugins/sendnotifications/kdeconnect_sendnotifications_config.desktop index 8e518c8d..1d06f462 100644 --- a/plugins/sendnotifications/kdeconnect_sendnotifications_config.desktop +++ b/plugins/sendnotifications/kdeconnect_sendnotifications_config.desktop @@ -1,45 +1,44 @@ [Desktop Entry] Type=Service X-KDE-ServiceTypes=KCModule X-KDE-Library=kdeconnect_sendnotifications_config X-KDE-ParentComponents=kdeconnect_sendnotifications Name=Notification synchronization plugin settings Name[ar]=إعدادات ملحقة مزامنة الإخطارات Name[ast]=Axustes del complementu de sincronización d'avisos Name[ca]=Ajustament del connector Sincronitza les notificacions Name[ca@valencia]=Ajustament del connector Sincronitza les notificacions Name[cs]=Nastavení modulu synchronizace upozornění Name[da]=Indstilling af plugin til bekendtgørelsessynkronisering Name[de]=Einstellungen für Benachrichtigungsabgleich-Modul Name[el]=Ρυθμίσεις πρόσθετου συγχρονισμού ειδοποιήσεων Name[en_GB]=Notification synchronisation plugin settings Name[es]=Preferencias del complemento de sincronización de notificaciones Name[et]=Märguande sünkroonimise plugina seaditused -Name[eu]=Jakinarazpenak sinkronizatzeko pluginaren ezarpenak Name[fi]=Ilmoitusten synkronointiliitännäisen asetukset Name[fr]=Configuration du module externe de synchronisation des notifications Name[gl]=Configuración do complemento de sincronización de notificacións Name[he]=הגדרת התוסף סנכרון התראות Name[it]=Impostazioni dell'estensione di sincronizzazione delle notifiche Name[ko]=알림 동기화 플러그인 설정 Name[nl]=Instellingen van plug-in voor synchronisatie van meldingen Name[nn]=Innstillingar for tillegg for synkronisering av varslingar Name[pl]=Ustawienia wtyczki synchronizującej powiadomienia Name[pt]=Configuração do 'plugin' de sincronização das notificações Name[pt_BR]=Configuração do plugin de sincronização das notificações Name[ru]=Настройка модуля синхронизации уведомлений Name[sk]=Nastavenia pluginu notifikácií synchronizácie Name[sr]=Поставке прикључка синхронизације обавештења Name[sr@ijekavian]=Поставке прикључка синхронизације обавештења Name[sr@ijekavianlatin]=Postavke priključka sinhronizacije obaveštenja Name[sr@latin]=Postavke priključka sinhronizacije obaveštenja Name[sv]=Inställningar av insticksprogram för underrättelsesynkronisering Name[tr]=Bildirim eşitleme eklentisi ayarları Name[uk]=Параметри додатка синхронізації сповіщень Name[x-test]=xxNotification synchronization plugin settingsxx Name[zh_CN]=通知同步插件设置 Name[zh_TW]=同步通知擴展插件設定 Categories=Qt;KDE;X-KDE-settings-kdeconnect; diff --git a/plugins/sendnotifications/notificationslistener.cpp b/plugins/sendnotifications/notificationslistener.cpp index 816d78e1..6209cda5 100644 --- a/plugins/sendnotifications/notificationslistener.cpp +++ b/plugins/sendnotifications/notificationslistener.cpp @@ -1,274 +1,274 @@ /** * Copyright 2015 Holger Kaelberer * * 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 #include #include #include #include "notificationslistener.h" #include "sendnotificationsplugin.h" #include "sendnotification_debug.h" #include "notifyingapplication.h" NotificationsListener::NotificationsListener(KdeConnectPlugin* aPlugin) : QDBusAbstractAdaptor(aPlugin), - mPlugin(aPlugin) + m_plugin(aPlugin) { qRegisterMetaTypeStreamOperators("NotifyingApplication"); bool ret = QDBusConnection::sessionBus() .registerObject(QStringLiteral("/org/freedesktop/Notifications"), this, QDBusConnection::ExportScriptableContents); if (!ret) qCWarning(KDECONNECT_PLUGIN_SENDNOTIFICATION) << "Error registering notifications listener for device" - << mPlugin->device()->name() << ":" + << m_plugin->device()->name() << ":" << QDBusConnection::sessionBus().lastError(); else qCDebug(KDECONNECT_PLUGIN_SENDNOTIFICATION) << "Registered notifications listener for device" - << mPlugin->device()->name(); + << m_plugin->device()->name(); QDBusInterface iface(QStringLiteral("org.freedesktop.DBus"), QStringLiteral("/org/freedesktop/DBus"), QStringLiteral("org.freedesktop.DBus")); iface.call(QStringLiteral("AddMatch"), "interface='org.freedesktop.Notifications',member='Notify',type='method_call',eavesdrop='true'"); setTranslatedAppName(); loadApplications(); - connect(mPlugin->config(), &KdeConnectPluginConfig::configChanged, this, &NotificationsListener::loadApplications); + connect(m_plugin->config(), &KdeConnectPluginConfig::configChanged, this, &NotificationsListener::loadApplications); } NotificationsListener::~NotificationsListener() { qCDebug(KDECONNECT_PLUGIN_SENDNOTIFICATION) << "Destroying NotificationsListener"; QDBusInterface iface(QStringLiteral("org.freedesktop.DBus"), QStringLiteral("/org/freedesktop/DBus"), QStringLiteral("org.freedesktop.DBus")); QDBusMessage res = iface.call(QStringLiteral("RemoveMatch"), "interface='org.freedesktop.Notifications',member='Notify',type='method_call',eavesdrop='true'"); QDBusConnection::sessionBus().unregisterObject(QStringLiteral("/org/freedesktop/Notifications")); } void NotificationsListener::setTranslatedAppName() { QString filePath = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("knotifications5/kdeconnect.notifyrc"), QStandardPaths::LocateFile); if (filePath.isEmpty()) { qCDebug(KDECONNECT_PLUGIN_SENDNOTIFICATION) << "Couldn't find kdeconnect.notifyrc to hide kdeconnect notifications on the devices. Using default name."; - mTranslatedAppName = QStringLiteral("KDE Connect"); + m_translatedAppName = QStringLiteral("KDE Connect"); return; } KConfig config(filePath, KConfig::OpenFlag::SimpleConfig); KConfigGroup globalgroup(&config, QStringLiteral("Global")); - mTranslatedAppName = globalgroup.readEntry(QStringLiteral("Name"), QStringLiteral("KDE Connect")); + m_translatedAppName = globalgroup.readEntry(QStringLiteral("Name"), QStringLiteral("KDE Connect")); } void NotificationsListener::loadApplications() { - applications.clear(); - const QVariantList list = mPlugin->config()->getList(QStringLiteral("applications")); + m_applications.clear(); + const QVariantList list = m_plugin->config()->getList(QStringLiteral("applications")); for (const auto& a : list) { NotifyingApplication app = a.value(); - if (!applications.contains(app.name)) - applications.insert(app.name, app); + if (!m_applications.contains(app.name)) + m_applications.insert(app.name, app); } //qCDebug(KDECONNECT_PLUGIN_SENDNOTIFICATION) << "Loaded" << applications.size() << " applications"; } bool NotificationsListener::parseImageDataArgument(const QVariant& argument, int& width, int& height, int& rowStride, int& bitsPerSample, int& channels, bool& hasAlpha, QByteArray& imageData) const { if (!argument.canConvert()) return false; const QDBusArgument dbusArg = argument.value(); dbusArg.beginStructure(); dbusArg >> width >> height >> rowStride >> hasAlpha >> bitsPerSample >> channels >> imageData; dbusArg.endStructure(); return true; } QSharedPointer NotificationsListener::iconForImageData(const QVariant& argument) const { int width, height, rowStride, bitsPerSample, channels; bool hasAlpha; QByteArray imageData; if (!parseImageDataArgument(argument, width, height, rowStride, bitsPerSample, channels, hasAlpha, imageData)) return QSharedPointer(); if (bitsPerSample != 8) { qCWarning(KDECONNECT_PLUGIN_SENDNOTIFICATION) << "Unsupported image format:" << "width=" << width << "height=" << height << "rowStride=" << rowStride << "bitsPerSample=" << bitsPerSample << "channels=" << channels << "hasAlpha=" << hasAlpha; return QSharedPointer(); } QImage image(reinterpret_cast(imageData.data()), width, height, rowStride, hasAlpha ? QImage::Format_ARGB32 : QImage::Format_RGB32); if (hasAlpha) image = image.rgbSwapped(); // RGBA --> ARGB QSharedPointer buffer = QSharedPointer(new QBuffer); if (!buffer || !buffer->open(QIODevice::WriteOnly) || !image.save(buffer.data(), "PNG")) { qCWarning(KDECONNECT_PLUGIN_SENDNOTIFICATION) << "Could not initialize image buffer"; return QSharedPointer(); } return buffer; } -QSharedPointer NotificationsListener::iconForIconName(const QString &iconName) const +QSharedPointer NotificationsListener::iconForIconName(const QString& iconName) const { int size = KIconLoader::SizeEnormous; // use big size to allow for good // quality on high-DPI mobile devices QString iconPath = KIconLoader::global()->iconPath(iconName, -size, true); if (!iconPath.isEmpty()) { if (!iconPath.endsWith(QLatin1String(".png")) && KIconLoader::global()->theme()->name() != QLatin1String("hicolor")) { // try falling back to hicolor theme: KIconTheme hicolor(QStringLiteral("hicolor")); if (hicolor.isValid()) { iconPath = hicolor.iconPath(iconName + ".png", size, KIconLoader::MatchBest); //qCDebug(KDECONNECT_PLUGIN_SENDNOTIFICATION) << "Found non-png icon in default theme trying fallback to hicolor:" << iconPath; } } } if (iconPath.endsWith(QLatin1String(".png"))) return QSharedPointer(new QFile(iconPath)); return QSharedPointer(); } -uint NotificationsListener::Notify(const QString &appName, uint replacesId, - const QString &appIcon, - const QString &summary, const QString &body, - const QStringList &actions, - const QVariantMap &hints, int timeout) +uint NotificationsListener::Notify(const QString& appName, uint replacesId, + const QString& appIcon, + const QString& summary, const QString& body, + const QStringList& actions, + const QVariantMap& hints, int timeout) { static int id = 0; Q_UNUSED(actions); //qCDebug(KDECONNECT_PLUGIN_SENDNOTIFICATION) << "Got notification appName=" << appName << "replacesId=" << replacesId << "appIcon=" << appIcon << "summary=" << summary << "body=" << body << "actions=" << actions << "hints=" << hints << "timeout=" << timeout; // skip our own notifications - if (appName == mTranslatedAppName) + if (appName == m_translatedAppName) return 0; NotifyingApplication app; - if (!applications.contains(appName)) { + if (!m_applications.contains(appName)) { // new application -> add to config app.name = appName; app.icon = appIcon; app.active = true; app.blacklistExpression = QRegularExpression(); - applications.insert(app.name, app); + m_applications.insert(app.name, app); // update config: QVariantList list; - for (const auto& a : qAsConst(applications)) + for (const auto& a : qAsConst(m_applications)) list << QVariant::fromValue(a); - mPlugin->config()->setList(QStringLiteral("applications"), list); + m_plugin->config()->setList(QStringLiteral("applications"), list); //qCDebug(KDECONNECT_PLUGIN_SENDNOTIFICATION) << "Added new application to config:" << app; } else - app = applications.value(appName); + app = m_applications.value(appName); if (!app.active) return 0; - if (timeout > 0 && mPlugin->config()->get(QStringLiteral("generalPersistent"), false)) + if (timeout > 0 && m_plugin->config()->get(QStringLiteral("generalPersistent"), false)) return 0; int urgency = -1; if (hints.contains(QStringLiteral("urgency"))) { bool ok; urgency = hints[QStringLiteral("urgency")].toInt(&ok); if (!ok) urgency = -1; } - if (urgency > -1 && urgency < mPlugin->config()->get(QStringLiteral("generalUrgency"), 0)) + if (urgency > -1 && urgency < m_plugin->config()->get(QStringLiteral("generalUrgency"), 0)) return 0; QString ticker = summary; - if (!body.isEmpty() && mPlugin->config()->get(QStringLiteral("generalIncludeBody"), true)) + if (!body.isEmpty() && m_plugin->config()->get(QStringLiteral("generalIncludeBody"), true)) ticker += QStringLiteral(": ") + body; if (app.blacklistExpression.isValid() && !app.blacklistExpression.pattern().isEmpty() && app.blacklistExpression.match(ticker).hasMatch()) return 0; //qCDebug(KDECONNECT_PLUGIN_SENDNOTIFICATION) << "Sending notification from" << appName << ":" < 0 ? replacesId : ++id)}, {"appName", appName}, {"ticker", ticker}, {"isClearable", timeout == 0} }); // KNotifications are persistent if // timeout == 0, for other notifications // clearability is pointless // sync any icon data? - if (mPlugin->config()->get(QStringLiteral("generalSynchronizeIcons"), true)) { + if (m_plugin->config()->get(QStringLiteral("generalSynchronizeIcons"), true)) { QSharedPointer iconSource; // try different image sources according to priorities in notifications- // spec version 1.2: if (hints.contains(QStringLiteral("image-data"))) iconSource = iconForImageData(hints[QStringLiteral("image-data")]); else if (hints.contains(QStringLiteral("image_data"))) // 1.1 backward compatibility iconSource = iconForImageData(hints[QStringLiteral("image_data")]); else if (hints.contains(QStringLiteral("image-path"))) iconSource = iconForIconName(hints[QStringLiteral("image-path")].toString()); else if (hints.contains(QStringLiteral("image_path"))) // 1.1 backward compatibility iconSource = iconForIconName(hints[QStringLiteral("image_path")].toString()); else if (!appIcon.isEmpty()) iconSource = iconForIconName(appIcon); else if (hints.contains(QStringLiteral("icon_data"))) // < 1.1 backward compatibility iconSource = iconForImageData(hints[QStringLiteral("icon_data")]); if (iconSource) np.setPayload(iconSource, iconSource->size()); } - mPlugin->sendPackage(np); + m_plugin->sendPackage(np); return (replacesId > 0 ? replacesId : id); } diff --git a/plugins/sendnotifications/notificationslistener.h b/plugins/sendnotifications/notificationslistener.h index 3076d0b0..adddfdc0 100644 --- a/plugins/sendnotifications/notificationslistener.h +++ b/plugins/sendnotifications/notificationslistener.h @@ -1,64 +1,64 @@ /** * Copyright 2015 Holger Kaelberer * * 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 class KdeConnectPlugin; class Notification; struct NotifyingApplication; class NotificationsListener : public QDBusAbstractAdaptor { Q_OBJECT Q_CLASSINFO("D-Bus Interface", "org.freedesktop.Notifications") public: explicit NotificationsListener(KdeConnectPlugin* aPlugin); ~NotificationsListener() override; protected: - KdeConnectPlugin* mPlugin; - QHash applications; + KdeConnectPlugin* m_plugin; + QHash m_applications; // virtual helper function to make testing possible (QDBusArgument can not // be injected without making a DBUS-call): virtual bool parseImageDataArgument(const QVariant& argument, int& width, int& height, int& rowStride, int& bitsPerSample, int& channels, bool& hasAlpha, QByteArray& imageData) const; QSharedPointer iconForImageData(const QVariant& argument) const; QSharedPointer iconForIconName(const QString& iconName) const; public Q_SLOTS: Q_SCRIPTABLE uint Notify(const QString&, uint, const QString&, const QString&, const QString&, const QStringList&, const QVariantMap&, int); private Q_SLOTS: void loadApplications(); private: void setTranslatedAppName(); - QString mTranslatedAppName; + QString m_translatedAppName; }; diff --git a/plugins/sendnotifications/notifyingapplication.cpp b/plugins/sendnotifications/notifyingapplication.cpp index dc1c3c15..185b9d65 100644 --- a/plugins/sendnotifications/notifyingapplication.cpp +++ b/plugins/sendnotifications/notifyingapplication.cpp @@ -1,50 +1,50 @@ /** * Copyright 2015 Holger Kaelberer * * 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 "notifyingapplication.h" #include #include -QDataStream &operator<<(QDataStream &out, const NotifyingApplication &app) +QDataStream& operator<<(QDataStream& out, const NotifyingApplication& app) { out << app.name << app.icon << app.active << app.blacklistExpression.pattern(); return out; } -QDataStream &operator>>(QDataStream &in, NotifyingApplication &app) +QDataStream& operator>>(QDataStream& in, NotifyingApplication& app) { QString pattern; in >> app.name; in >> app.icon; in >> app.active; in >> pattern; app.blacklistExpression.setPattern(pattern); return in; } QDebug operator<<(QDebug dbg, const NotifyingApplication& a) { dbg.nospace() << "{ name=" << a.name << ", icon=" << a.icon << ", active=" << a.active << ", blacklistExpression =" << a.blacklistExpression << " }"; return dbg.space(); } diff --git a/plugins/sendnotifications/notifyingapplication.h b/plugins/sendnotifications/notifyingapplication.h index d0d8226d..57d38949 100644 --- a/plugins/sendnotifications/notifyingapplication.h +++ b/plugins/sendnotifications/notifyingapplication.h @@ -1,43 +1,43 @@ /** * Copyright 2015 Holger Kaelberer * * 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 NOTIFYINGAPPLICATION_H #define NOTIFYINGAPPLICATION_H #include struct NotifyingApplication { QString name; QString icon; bool active; QRegularExpression blacklistExpression; bool operator==(const NotifyingApplication& other) const { return (name == other.name); } }; Q_DECLARE_METATYPE(NotifyingApplication); -QDataStream &operator<<(QDataStream &out, const NotifyingApplication &app); -QDataStream &operator>>(QDataStream &in, NotifyingApplication &app); -QDebug operator<<(QDebug dbg, const NotifyingApplication &a); +QDataStream& operator<<(QDataStream& out, const NotifyingApplication& app); +QDataStream& operator>>(QDataStream& in, NotifyingApplication& app); +QDebug operator<<(QDebug dbg, const NotifyingApplication& a); #endif //NOTIFYINGAPPLICATION_H diff --git a/plugins/sendnotifications/notifyingapplicationmodel.cpp b/plugins/sendnotifications/notifyingapplicationmodel.cpp index 7d7a0291..2ac3277b 100644 --- a/plugins/sendnotifications/notifyingapplicationmodel.cpp +++ b/plugins/sendnotifications/notifyingapplicationmodel.cpp @@ -1,238 +1,238 @@ /** * Copyright 2015 Holger Kaelberer * * 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 "notifyingapplicationmodel.h" #include #include #include #include #include //#include "modeltest.h" -NotifyingApplicationModel::NotifyingApplicationModel(QObject *parent) +NotifyingApplicationModel::NotifyingApplicationModel(QObject* parent) : QAbstractTableModel(parent) { } NotifyingApplicationModel::~NotifyingApplicationModel() { } QVector NotifyingApplicationModel::apps() { return m_apps; } void NotifyingApplicationModel::appendApp(const NotifyingApplication& app) { if (app.name.isEmpty() || apps().contains(app)) return; beginInsertRows(QModelIndex(), m_apps.size(), m_apps.size()); m_apps.append(app); endInsertRows(); } bool NotifyingApplicationModel::containsApp(const QString& name) const { for (const auto& a: m_apps) if (a.name == name) return true; return false; } Qt::ItemFlags NotifyingApplicationModel::flags(const QModelIndex& index) const { Qt::ItemFlags flags = Qt::ItemIsEnabled; if (index.isValid() && index.row() >= 0 && index.row() < m_apps.size() && index.column() < 3) { if (index.column() == 0) flags |= Qt::ItemIsEditable | Qt::ItemIsUserCheckable; else if (index.column() == 2) { if (m_apps[index.row()].active) flags |= Qt::ItemIsEditable; else flags ^= Qt::ItemIsEnabled; } else if (index.column() == 1) { if (!m_apps[index.row()].active) flags ^= Qt::ItemIsEnabled; } } return flags; } void NotifyingApplicationModel::clearApplications() { if (!m_apps.isEmpty()) { beginRemoveRows(QModelIndex(), 0, m_apps.size() - 1); m_apps.clear(); endRemoveRows(); } } QVariant NotifyingApplicationModel::data(const QModelIndex& index, int role) const { Q_UNUSED(role); if (!index.isValid() || index.row() < 0 || index.row() >= m_apps.size() || index.column() > 3) { return QVariant(); } switch (role) { case Qt::TextAlignmentRole: { if (index.column() == 0) return int(Qt::AlignCenter | Qt::AlignVCenter ); else return int(Qt::AlignLeft | Qt::AlignVCenter ); break; } case Qt::DisplayRole: { if (index.column() == 1) return m_apps[index.row()].name; else if (index.column() == 0) return QVariant();//m_apps[index.row()].active; else if (index.column() == 2) return m_apps[index.row()].blacklistExpression.pattern(); else return QVariant(); break; } case Qt::DecorationRole: { if (index.column() == 1) return QIcon::fromTheme(m_apps[index.row()].icon, QIcon::fromTheme(QStringLiteral("application-x-executable"))); else return QVariant(); break; } case Qt::EditRole: { if (index.column() == 0) return m_apps[index.row()].active ? Qt::Checked : Qt::Unchecked; else if (index.column() == 2) return m_apps[index.row()].blacklistExpression.pattern(); else return QVariant(); break; } case Qt::CheckStateRole: { if (index.column() == 0) return m_apps[index.row()].active ? Qt::Checked : Qt::Unchecked; else return QVariant(); break; } } return QVariant(); } -bool NotifyingApplicationModel::setData(const QModelIndex &index, const QVariant &value, int role) +bool NotifyingApplicationModel::setData(const QModelIndex& index, const QVariant& value, int role) { if (!index.isValid() || (index.column() != 0 && index.column() != 2) || index.row() < 0 || index.row() >= m_apps.size()) return false; bool res = false; QModelIndex bottomRight = createIndex(index.row(), index.column()); switch (role) { case Qt::CheckStateRole: { if (index.column() == 0) { m_apps[index.row()].active = ((Qt::CheckState)value.toInt() == Qt::Checked); bottomRight = createIndex(index.row(), index.column() + 1); res = true; } break; } case Qt::EditRole: { if (index.column() == 2) { m_apps[index.row()].blacklistExpression.setPattern(value.toString()); res = true; } } } if (res) { Q_EMIT dataChanged(index, bottomRight); Q_EMIT applicationsChanged(); // -> notify config that we need to save } return res; } void NotifyingApplicationModel::sort(int column, Qt::SortOrder order) { if (column != 1) return; if (order == Qt::AscendingOrder) std::sort(m_apps.begin(), m_apps.end(), [](const NotifyingApplication& a, const NotifyingApplication& b) { return (a.name.compare(b.name, Qt::CaseInsensitive) < 1); }); else std::sort(m_apps.begin(), m_apps.end(), [](const NotifyingApplication& a, const NotifyingApplication& b) { return (b.name.compare(a.name, Qt::CaseInsensitive) < 1); }); Q_EMIT dataChanged(createIndex(0, 0), createIndex(m_apps.size(), 2)); } QVariant NotifyingApplicationModel::headerData(int section, Qt::Orientation /*orientation*/, int role) const { switch (role) { case Qt::DisplayRole: { if (section == 1) return i18n("Name"); else if (section == 0) return QVariant(); //i18n("Sync"); else return i18n("Blacklisted"); } case Qt::ToolTipRole: { if (section == 1) return i18n("Name of a notifying application."); else if (section == 0) return i18n("Synchronize notifications of an application?"); else return i18n("Regular expression defining which notifications should not be sent.\nThis pattern is applied to the summary and, if selected above, the body of notifications."); } } return QVariant(); } int NotifyingApplicationModel::columnCount(const QModelIndex&) const { return 3; } int NotifyingApplicationModel::rowCount(const QModelIndex& parent) const { if(parent.isValid()) { //Return size 0 if we are a child because this is not a tree return 0; } return m_apps.size(); } diff --git a/plugins/sendnotifications/notifyingapplicationmodel.h b/plugins/sendnotifications/notifyingapplicationmodel.h index 7c729ff7..25e2e2f2 100644 --- a/plugins/sendnotifications/notifyingapplicationmodel.h +++ b/plugins/sendnotifications/notifyingapplicationmodel.h @@ -1,56 +1,56 @@ /** * Copyright 2015 Holger Kaelberer * * 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 NOTIFYINGAPPLICATIONMODEL_H #define NOTIFYINGAPPLICATIONMODEL_H #include #include "notifyingapplication.h" class NotifyingApplicationModel: public QAbstractTableModel { Q_OBJECT public: - explicit NotifyingApplicationModel(QObject *parent = nullptr); + explicit NotifyingApplicationModel(QObject* parent = nullptr); ~NotifyingApplicationModel() override; QVariant data(const QModelIndex& index, int role) const override; - bool setData(const QModelIndex &index, const QVariant &value, int role) override; + bool setData(const QModelIndex& index, const QVariant& value, int role) override; int rowCount(const QModelIndex& parent = QModelIndex()) const override; int columnCount(const QModelIndex& parent = QModelIndex()) const override; Qt::ItemFlags flags(const QModelIndex & index) const override; QVariant headerData(int section, Qt::Orientation orientation, int role) const override; void sort(int column, Qt::SortOrder order = Qt::AscendingOrder) override; QVector apps(); void clearApplications(); void appendApp(const NotifyingApplication& app); bool containsApp(const QString& name) const; Q_SIGNALS: void applicationsChanged(); private: QVector m_apps; }; #endif // NOTIFYINGAPPLICATIONMODEL_H diff --git a/plugins/sendnotifications/sendnotifications_config.cpp b/plugins/sendnotifications/sendnotifications_config.cpp index 7fc9e8f6..55645bbe 100644 --- a/plugins/sendnotifications/sendnotifications_config.cpp +++ b/plugins/sendnotifications/sendnotifications_config.cpp @@ -1,121 +1,121 @@ /** * Copyright 2015 Holger Kaelberer * * 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 "sendnotifications_config.h" #include "ui_sendnotifications_config.h" #include "notifyingapplicationmodel.h" #include #include K_PLUGIN_FACTORY(SendNotificationsConfigFactory, registerPlugin();) -SendNotificationsConfig::SendNotificationsConfig(QWidget *parent, const QVariantList& args) +SendNotificationsConfig::SendNotificationsConfig(QWidget* parent, const QVariantList& args) : KdeConnectPluginKcm(parent, args, QStringLiteral("kdeconnect_sendnotifications_config")) , m_ui(new Ui::SendNotificationsConfigUi()) , appModel(new NotifyingApplicationModel) { qRegisterMetaTypeStreamOperators("NotifyingApplication"); m_ui->setupUi(this); m_ui->appList->setIconSize(QSize(32,32)); m_ui->appList->setModel(appModel); m_ui->appList->horizontalHeader()->setSectionResizeMode(0, QHeaderView::QHeaderView::Fixed); m_ui->appList->horizontalHeader()->setSectionResizeMode(1, QHeaderView::QHeaderView::Stretch); m_ui->appList->horizontalHeader()->setSectionResizeMode(2, QHeaderView::QHeaderView::Stretch); for (int i = 0; i < 3; i++) m_ui->appList->resizeColumnToContents(i); connect(m_ui->appList->horizontalHeader(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), m_ui->appList, SLOT(sortByColumn(int))); connect(m_ui->check_persistent, SIGNAL(toggled(bool)), this, SLOT(changed())); connect(m_ui->spin_urgency, SIGNAL(editingFinished()), this, SLOT(changed())); connect(m_ui->check_body, SIGNAL(toggled(bool)), this, SLOT(changed())); connect(m_ui->check_icons, SIGNAL(toggled(bool)), this, SLOT(changed())); connect(appModel, SIGNAL(applicationsChanged()), this, SLOT(changed())); connect(config(), &KdeConnectPluginConfig::configChanged, this, &SendNotificationsConfig::loadApplications); } SendNotificationsConfig::~SendNotificationsConfig() { delete m_ui; } void SendNotificationsConfig::defaults() { KCModule::defaults(); m_ui->check_persistent->setChecked(false); m_ui->spin_urgency->setValue(0); m_ui->check_body->setChecked(true); m_ui->check_icons->setChecked(true); Q_EMIT changed(true); } void SendNotificationsConfig::loadApplications() { appModel->clearApplications(); QVariantList list = config()->getList(QStringLiteral("applications")); for (const auto& a: list) { NotifyingApplication app = a.value(); if (!appModel->containsApp(app.name)) { appModel->appendApp(app); } } } void SendNotificationsConfig::load() { KCModule::load(); bool persistent = config()->get(QStringLiteral("generalPersistent"), false); m_ui->check_persistent->setChecked(persistent); bool body = config()->get(QStringLiteral("generalIncludeBody"), true); m_ui->check_body->setChecked(body); bool icons = config()->get(QStringLiteral("generalSynchronizeIcons"), true); m_ui->check_icons->setChecked(icons); int urgency = config()->get(QStringLiteral("generalUrgency"), 0); m_ui->spin_urgency->setValue(urgency); loadApplications(); Q_EMIT changed(false); } void SendNotificationsConfig::save() { config()->set(QStringLiteral("generalPersistent"), m_ui->check_persistent->isChecked()); config()->set(QStringLiteral("generalIncludeBody"), m_ui->check_body->isChecked()); config()->set(QStringLiteral("generalSynchronizeIcons"), m_ui->check_icons->isChecked()); config()->set(QStringLiteral("generalUrgency"), m_ui->spin_urgency->value()); QVariantList list; list.reserve(appModel->apps().size()); for (const auto& a: appModel->apps()) { list.append(QVariant::fromValue(a)); } config()->setList(QStringLiteral("applications"), list); KCModule::save(); Q_EMIT changed(false); } #include "sendnotifications_config.moc" diff --git a/plugins/sendnotifications/sendnotifications_config.h b/plugins/sendnotifications/sendnotifications_config.h index f4d6d529..41b562b1 100644 --- a/plugins/sendnotifications/sendnotifications_config.h +++ b/plugins/sendnotifications/sendnotifications_config.h @@ -1,54 +1,54 @@ /** * Copyright 2015 Holger Kaelberer * * 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 SENDNOTIFICATIONS_CONFIG_H #define SENDNOTIFICATIONS_CONFIG_H #include "kcmplugin/kdeconnectpluginkcm.h" namespace Ui { class SendNotificationsConfigUi; } class NotifyingApplicationModel; class SendNotificationsConfig : public KdeConnectPluginKcm { Q_OBJECT public: - SendNotificationsConfig(QWidget *parent, const QVariantList&); + SendNotificationsConfig(QWidget* parent, const QVariantList&); ~SendNotificationsConfig() override; public Q_SLOTS: void save() override; void load() override; void defaults() override; private Q_SLOTS: void loadApplications(); private: Ui::SendNotificationsConfigUi* m_ui; NotifyingApplicationModel* appModel; }; #endif diff --git a/plugins/sendnotifications/sendnotificationsplugin.h b/plugins/sendnotifications/sendnotificationsplugin.h index 3c5807aa..1ddf3153 100644 --- a/plugins/sendnotifications/sendnotificationsplugin.h +++ b/plugins/sendnotifications/sendnotificationsplugin.h @@ -1,53 +1,53 @@ /** * Copyright 2013 Albert Vaca * * 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 SENDNOTIFICATIONSPLUGIN_H #define SENDNOTIFICATIONSPLUGIN_H #include "core/kdeconnectplugin.h" #define PACKAGE_TYPE_NOTIFICATION QStringLiteral("kdeconnect.notification") /* * This class is just a proxy for NotificationsDbusInterface * because it can not inherit from QDBusAbstractAdaptor and * KdeConnectPlugin at the same time (both are QObject) */ class NotificationsDbusInterface; class NotificationsListener; class SendNotificationsPlugin : public KdeConnectPlugin { Q_OBJECT public: - explicit SendNotificationsPlugin(QObject *parent, const QVariantList &args); + explicit SendNotificationsPlugin(QObject* parent, const QVariantList& args); ~SendNotificationsPlugin() override; bool receivePackage(const NetworkPackage& np) override; void connected() override; protected: NotificationsListener* notificationsListener; }; #endif diff --git a/plugins/sftp/kdeconnect_sftp.json b/plugins/sftp/kdeconnect_sftp.json index b3e20980..b84518b4 100644 --- a/plugins/sftp/kdeconnect_sftp.json +++ b/plugins/sftp/kdeconnect_sftp.json @@ -1,101 +1,99 @@ { "Encoding": "UTF-8", "KPlugin": { "Authors": [ { "Email": "kinnalru@gmail.com", "Name": "Samoilenko Yuri", "Name[ru]": "Юрий Самойленко", "Name[sr@ijekavian]": "Јуриј Самојленко", "Name[sr@ijekavianlatin]": "Jurij Samojlenko", "Name[sr@latin]": "Jurij Samojlenko", "Name[sr]": "Јуриј Самојленко", "Name[uk]": "Юрій Самойленко", "Name[x-test]": "xxSamoilenko Yurixx" } ], "Description": "Browse the remote device filesystem using SFTP", "Description[ar]": "تصفّح نظام ملفّات الجهاز البعيد باستخدام SFTP", "Description[ca@valencia]": "Navega pel sistema de fitxers del dispositiu remot emprant SFTP", "Description[ca]": "Navega pel sistema de fitxers del dispositiu remot emprant SFTP", "Description[cs]": "Prohlížejte souborový systém zařízení pomocí SFTP", "Description[da]": "Gennemse den eksterne enheds filsystem med SFTP", "Description[de]": "Browsen im Dateisystem des entfernten Geräts mit SFTP", "Description[el]": "Περιήγηση του απομακρυσμένου συστήματος αρχείων με χρήση SFTP", "Description[es]": "Navegar por el sistema de archivos del dispositivo remoto usando SFTP", "Description[et]": "Oma seadme failisüsteemi sirvimine SFTP vahendusel", - "Description[eu]": "Arakatu urruneko gailuaren fitxategi-sistema SFTP erabiliz", "Description[fi]": "Selaa etälaitteiden tiedostojärjestelmiä SFTP:llä", "Description[fr]": "Naviguer dans le système de fichiers du périphérique distant en utilisant SFTP", "Description[gl]": "Explore o sistema de ficheiros do dispositivo remoto mediante SFTP.", "Description[hu]": "Távoli fájlrendszerek böngészése SFTP-n keresztül", "Description[it]": "Sfoglia il filesystem del dispositivo remoto utilizzando SFTP", "Description[ko]": "SFTP로 원격 장치 파일 시스템 탐색", "Description[nl]": "Blader door het bestandssysteem met SFTP op het apparaat op afstand", "Description[nn]": "Bla gjennom filsystemet på eininga med SFTP", "Description[pl]": "Przeglądaj zdalny system plików przy użyciu SFTP", "Description[pt]": "Navegar pelo sistema de ficheiros de um dispositivo remoto por SFTP", "Description[pt_BR]": "Navegue pelo sistema de arquivos do dispositivo usando SFTP", "Description[ru]": "Просмотр файловой системы удалённого устройства с помощью SFTP", "Description[sk]": "Prehliadať súborový systém vzdialeného zariadenia pomocou SFTP", "Description[sr@ijekavian]": "Прегледање удаљеног фајл система помоћу СФТП‑а", "Description[sr@ijekavianlatin]": "Pregledanje udaljenog fajl sistema pomoću SFTP‑a", "Description[sr@latin]": "Pregledanje udaljenog fajl sistema pomoću SFTP‑a", "Description[sr]": "Прегледање удаљеног фајл система помоћу СФТП‑а", "Description[sv]": "Bläddra i den andra apparatens filsystem med SFTP", "Description[tr]": "Uzak aygıt dosya sistemine SFTP kullanarak göz atın", "Description[uk]": "Перегляд файлових систем на сторонніх пристроях за допомогою SFTP", "Description[x-test]": "xxBrowse the remote device filesystem using SFTPxx", "Description[zh_CN]": "通过 SFTP 浏览远程设备文件系统", "Description[zh_TW]": "使用SFTP來瀏覽遠端的檔案系統", "EnabledByDefault": true, "Icon": "folder-documents", "Id": "kdeconnect_sftp", "License": "GPL", "Name": "Remote filesystem browser", "Name[ar]": "متصفّح نظام الملفّات البعيد", "Name[ca@valencia]": "Navegador del sistema de fitxers remot", "Name[ca]": "Navegador del sistema de fitxers remot", "Name[cs]": "Vzdálený prohlížeč souborového systému", "Name[da]": "Browser til eksternt filsystem", "Name[de]": "Datei-Browser für entferne Systeme", "Name[el]": "Περιηγητής απομακρυσμένου συστήματος αρχείων", "Name[es]": "Navegador de sistema de archivos remoto", "Name[et]": "Kaug-failisüsteemi sirvija", - "Name[eu]": "Urruneko fitxategi-sistemaren arakatzailea", "Name[fi]": "Etätiedostojärjestelmäselain", "Name[fr]": "Explorateur à distance du système de fichiers", "Name[gl]": "Navegador do sistema de ficheiros remoto.", "Name[hu]": "Távoli fájlrendszer-böngésző", "Name[it]": "Navigazione del filesystem remoto", "Name[ko]": "원격 파일 시스템 탐색기", "Name[nl]": "Bestandssysteembrowser op afstand", "Name[nn]": "Bla gjennom eksternt filsystem", "Name[pl]": "Przeglądarka zdalnego systemu plików", "Name[pt]": "Navegador de sistemas de ficheiros remotos", "Name[pt_BR]": "Navegador do sistema de arquivos remoto", "Name[ru]": "Удалённый просмотр файловой системы", "Name[sk]": "Prehliadač vzdialeného súborového systému", "Name[sr@ijekavian]": "Прегледач удаљеног фајл система", "Name[sr@ijekavianlatin]": "Pregledač udaljenog fajl sistema", "Name[sr@latin]": "Pregledač udaljenog fajl sistema", "Name[sr]": "Прегледач удаљеног фајл система", "Name[sv]": "Extern filsystembläddrare", "Name[tr]": "Uzak dosya sistemi tarayıcısı", "Name[uk]": "Перегляд віддалених файлових систем", "Name[x-test]": "xxRemote filesystem browserxx", "Name[zh_CN]": "远程文件系统浏览器", "Name[zh_TW]": "遠端檔案瀏覽器", "ServiceTypes": [ "KdeConnect/Plugin" ], "Version": "0.1", "Website": "http://albertvaka.wordpress.com" }, "X-KdeConnect-OutgoingPackageType": [ "kdeconnect.sftp.request" ], "X-KdeConnect-SupportedPackageType": [ "kdeconnect.sftp" ] } diff --git a/plugins/sftp/mounter.h b/plugins/sftp/mounter.h index f02fc69b..fc94996b 100644 --- a/plugins/sftp/mounter.h +++ b/plugins/sftp/mounter.h @@ -1,68 +1,68 @@ /** * Copyright 2014 Samoilenko Yuri * * 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 SFTPPLUGIN_MOUNTJOB_H #define SFTPPLUGIN_MOUNTJOB_H #include #include #include #include "sftpplugin.h" class Mounter : public QObject { Q_OBJECT public: - explicit Mounter(SftpPlugin *sftp); + explicit Mounter(SftpPlugin* sftp); ~Mounter() override; bool wait(); bool isMounted() const { return m_started; } Q_SIGNALS: void mounted(); void unmounted(); void failed(const QString& message); private Q_SLOTS: void onPakcageReceived(const NetworkPackage& np); void onStarted(); void onError(QProcess::ProcessError error); void onFinished(int exitCode, QProcess::ExitStatus exitStatus); void onMountTimeout(); void start(); private: void unmount(bool finished); private: SftpPlugin* m_sftp; KProcess* m_proc; QTimer m_connectTimer; QString m_mountPoint; bool m_started; }; #endif diff --git a/plugins/sftp/sftpplugin.cpp b/plugins/sftp/sftpplugin.cpp index d629a193..dc7a18c4 100644 --- a/plugins/sftp/sftpplugin.cpp +++ b/plugins/sftp/sftpplugin.cpp @@ -1,192 +1,192 @@ /** * Copyright 2014 Samoilenko Yuri * * 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 "sftpplugin.h" #include #include #include #include #include #include #include #include #include #include "mounter.h" #include "sftp_debug.h" K_PLUGIN_FACTORY_WITH_JSON( KdeConnectPluginFactory, "kdeconnect_sftp.json", registerPlugin< SftpPlugin >(); ) Q_LOGGING_CATEGORY(KDECONNECT_PLUGIN_SFTP, "kdeconnect.plugin.sftp") static const QSet fields_c = QSet() << QStringLiteral("ip") << QStringLiteral("port") << QStringLiteral("user") << QStringLiteral("port") << QStringLiteral("path"); struct SftpPlugin::Pimpl { - Pimpl() : mounter(nullptr) {} + Pimpl() : m_mounter(nullptr) {} //Add KIO entry to Dolphin's Places - KFilePlacesModel placesModel; - Mounter* mounter; + KFilePlacesModel m_placesModel; + Mounter* m_mounter; }; -SftpPlugin::SftpPlugin(QObject *parent, const QVariantList &args) +SftpPlugin::SftpPlugin(QObject* parent, const QVariantList& args) : KdeConnectPlugin(parent, args) - , m_d(new Pimpl()) + , d(new Pimpl()) { deviceId = device()->id(); addToDolphin(); qCDebug(KDECONNECT_PLUGIN_SFTP) << "Created device:" << device()->name(); } SftpPlugin::~SftpPlugin() { QDBusConnection::sessionBus().unregisterObject(dbusPath(), QDBusConnection::UnregisterTree); removeFromDolphin(); unmount(); } void SftpPlugin::addToDolphin() { removeFromDolphin(); QUrl kioUrl("kdeconnect://"+deviceId+"/"); - m_d->placesModel.addPlace(device()->name(), kioUrl, QStringLiteral("kdeconnect")); + d->m_placesModel.addPlace(device()->name(), kioUrl, QStringLiteral("kdeconnect")); qCDebug(KDECONNECT_PLUGIN_SFTP) << "add to dolphin"; } void SftpPlugin::removeFromDolphin() { QUrl kioUrl("kdeconnect://"+deviceId+"/"); - QModelIndex index = m_d->placesModel.closestItem(kioUrl); + QModelIndex index = d->m_placesModel.closestItem(kioUrl); while (index.row() != -1) { - m_d->placesModel.removePlace(index); - index = m_d->placesModel.closestItem(kioUrl); + d->m_placesModel.removePlace(index); + index = d->m_placesModel.closestItem(kioUrl); } } void SftpPlugin::mount() { qCDebug(KDECONNECT_PLUGIN_SFTP) << "Mount device:" << device()->name(); - if (m_d->mounter) { + if (d->m_mounter) { return; } - m_d->mounter = new Mounter(this); - connect(m_d->mounter, &Mounter::mounted, this, &SftpPlugin::onMounted); - connect(m_d->mounter, &Mounter::unmounted, this, &SftpPlugin::onUnmounted); - connect(m_d->mounter, &Mounter::failed, this, &SftpPlugin::onFailed); + d->m_mounter = new Mounter(this); + connect(d->m_mounter, &Mounter::mounted, this, &SftpPlugin::onMounted); + connect(d->m_mounter, &Mounter::unmounted, this, &SftpPlugin::onUnmounted); + connect(d->m_mounter, &Mounter::failed, this, &SftpPlugin::onFailed); } void SftpPlugin::unmount() { - if (m_d->mounter) + if (d->m_mounter) { - m_d->mounter->deleteLater(); - m_d->mounter = nullptr; + d->m_mounter->deleteLater(); + d->m_mounter = nullptr; } } bool SftpPlugin::mountAndWait() { mount(); - return m_d->mounter->wait(); + return d->m_mounter->wait(); } bool SftpPlugin::isMounted() const { - return m_d->mounter && m_d->mounter->isMounted(); + return d->m_mounter && d->m_mounter->isMounted(); } bool SftpPlugin::startBrowsing() { if (mountAndWait()) { //return new KRun(QUrl::fromLocalFile(mountPoint()), 0); return new KRun(QUrl("kdeconnect://"+deviceId), nullptr); } return false; } bool SftpPlugin::receivePackage(const NetworkPackage& np) { if (!(fields_c - np.body().keys().toSet()).isEmpty()) { // package is invalid return false; } Q_EMIT packageReceived(np); remoteDirectories.clear(); if (np.has(QStringLiteral("multiPaths"))) { QStringList paths = np.get(QStringLiteral("multiPaths"),QStringList()); QStringList names = np.get(QStringLiteral("pathNames"),QStringList()); int size = qMin(names.size(), paths.size()); for (int i = 0; i < size; i++) { remoteDirectories.insert(mountPoint() + paths.at(i), names.at(i)); } } else { remoteDirectories.insert(mountPoint(), i18n("All files")); remoteDirectories.insert(mountPoint() + "/DCIM/Camera", i18n("Camera pictures")); } return true; } QString SftpPlugin::mountPoint() { QString runtimePath = QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation); if (runtimePath.isEmpty()) { runtimePath = QStandardPaths::writableLocation(QStandardPaths::TempLocation); } return QDir(runtimePath).absoluteFilePath(deviceId); } void SftpPlugin::onMounted() { qCDebug(KDECONNECT_PLUGIN_SFTP) << device()->name() << QStringLiteral("Remote filesystem mounted at %1").arg(mountPoint()); Q_EMIT mounted(); } void SftpPlugin::onUnmounted() { qCDebug(KDECONNECT_PLUGIN_SFTP) << device()->name() << "Remote filesystem unmounted"; unmount(); Q_EMIT unmounted(); } void SftpPlugin::onFailed(const QString& message) { KNotification::event(KNotification::Error, device()->name(), message); unmount(); Q_EMIT unmounted(); } QVariantMap SftpPlugin::getDirectories() { return remoteDirectories; } #include "sftpplugin.moc" diff --git a/plugins/sftp/sftpplugin.h b/plugins/sftp/sftpplugin.h index 8b8ce577..682e5a07 100644 --- a/plugins/sftp/sftpplugin.h +++ b/plugins/sftp/sftpplugin.h @@ -1,79 +1,79 @@ /** * Copyright 2014 Samoilenko Yuri * * 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 SFTPPLUGIN_H #define SFTPPLUGIN_H #include #include #define PACKAGE_TYPE_SFTP_REQUEST QStringLiteral("kdeconnect.sftp.request") class KNotification; class SftpPlugin : public KdeConnectPlugin { Q_OBJECT Q_CLASSINFO("D-Bus Interface", "org.kde.kdeconnect.device.sftp") public: - explicit SftpPlugin(QObject *parent, const QVariantList &args); + explicit SftpPlugin(QObject* parent, const QVariantList& args); ~SftpPlugin() override; bool receivePackage(const NetworkPackage& np) override; void connected() override {} QString dbusPath() const override { return "/modules/kdeconnect/devices/" + deviceId + "/sftp"; } Q_SIGNALS: void packageReceived(const NetworkPackage& np); Q_SCRIPTABLE void mounted(); Q_SCRIPTABLE void unmounted(); public Q_SLOTS: Q_SCRIPTABLE void mount(); Q_SCRIPTABLE void unmount(); Q_SCRIPTABLE bool mountAndWait(); Q_SCRIPTABLE bool isMounted() const; Q_SCRIPTABLE bool startBrowsing(); Q_SCRIPTABLE QString mountPoint(); Q_SCRIPTABLE QVariantMap getDirectories(); //Actually a QMap, but QDBus preffers this private Q_SLOTS: void onMounted(); void onUnmounted(); void onFailed(const QString& message); private: void knotify(int type, const QString& text, const QPixmap& icon) const; void addToDolphin(); void removeFromDolphin(); private: struct Pimpl; - QScopedPointer m_d; + QScopedPointer d; QString deviceId; //Storing it to avoid accessing device() from the destructor which could cause a crash QVariantMap remoteDirectories; //Actually a QMap, but QDBus preffers this }; #endif diff --git a/plugins/share/kdeconnect_share.json b/plugins/share/kdeconnect_share.json index 68d4194f..d8744b76 100644 --- a/plugins/share/kdeconnect_share.json +++ b/plugins/share/kdeconnect_share.json @@ -1,99 +1,97 @@ { "Encoding": "UTF-8", "KPlugin": { "Authors": [ { "Email": "albertvaka@gmail.com", "Name": "Albert Vaca", "Name[sr@ijekavian]": "Алберт Вака Синтора", "Name[sr@ijekavianlatin]": "Albert Vaka Sintora", "Name[sr@latin]": "Albert Vaka Sintora", "Name[sr]": "Алберт Вака Синтора", "Name[x-test]": "xxAlbert Vacaxx" } ], "Description": "Receive and send files, URLs or plain text easily", "Description[ar]": "استقبل الملفّات أو العناوين أو النّصوص الصّرفة وأرسلها بسهولة", "Description[ca@valencia]": "Rep i envia fitxers, URL o text pla amb facilitat", "Description[ca]": "Rep i envia fitxers, URL o text pla amb facilitat", "Description[cs]": "Snadno přijímejte a posílejte soubory, URL nebo čistý text", "Description[da]": "Modtag og send nemt filer, URL'er eller klartekst", "Description[de]": "Empfang und Senden von Dateien, URLs oder einfachem Text", "Description[el]": "Εύκολη λήψη και αποστολή αρχείων, URL ή απλού κειμένου", "Description[es]": "Recibir y enviar archivos, URL o texto sin formato fácilmente", "Description[et]": "Failide, URL-ide või lihtteksti hõlpus vastuvõtmine ja saatmine", - "Description[eu]": "Jaso eta bidali fitxategiak, URL-ak, edo testu soila erraz", "Description[fi]": "Vastaanota ja lähetä tiedostoja, verkko-osoitteita tai tekstiä helposti", "Description[fr]": "Recevoir et envoyer des fichiers, des URLs ou du texte brut facilement", "Description[gl]": "Comparta e reciba con facilidade ficheiros, enderezos URL ou texto simple.", "Description[hu]": "Fájlok, URL-ek és szöveg fogadása és küldése", "Description[it]": "Ricevi e invia facilmente file, URL o testo semplice", "Description[ko]": "파일, URL, 일반 텍스트 공유하고 받기", "Description[nl]": "Bestanden, URL's of platte tekst gemakkelijk ontvangen en verzenden", "Description[nn]": "Ta imot og send filer, nettadresser og tekst på ein enkel måte", "Description[pl]": "Udostępniaj i otrzymuj pliki, adresy URL lub zwykły tekst z łatwością", "Description[pt]": "Receber e enviar ficheiros, URL's ou texto normal de forma simples", "Description[pt_BR]": "Recebe e envia facilmente arquivos, URLs ou texto simples", "Description[ru]": "Получение и отправка файлов, URL адресов или простого текста", "Description[sk]": "Prijať a poslať súbory, URL alebo čisté texty jednoducho", "Description[sr@ijekavian]": "Примај и шаљи фајлове, УРЛ‑ове или обичан текст, са лакоћом", "Description[sr@ijekavianlatin]": "Primaj i šalji fajlove, URL‑ove ili običan tekst, sa lakoćom", "Description[sr@latin]": "Primaj i šalji fajlove, URL‑ove ili običan tekst, sa lakoćom", "Description[sr]": "Примај и шаљи фајлове, УРЛ‑ове или обичан текст, са лакоћом", "Description[sv]": "Ta emot och skicka filer, webbadresser eller vanlig text enkelt", "Description[tr]": "Dosyaları, adres ve düz metinleri kolayca alın ve gönderin", "Description[uk]": "Спрощене отримання і надсилання файлів, адрес або текстових фрагментів", "Description[x-test]": "xxReceive and send files, URLs or plain text easilyxx", "Description[zh_CN]": "简单地接收和发送文件,URL 或者文本", "Description[zh_TW]": "接收與傳送檔案,URL網址或純文字檔", "EnabledByDefault": true, "Icon": "folder-network", "Id": "kdeconnect_share", "License": "GPL", "Name": "Share and receive", "Name[ar]": "شارك واستقبل", "Name[ca@valencia]": "Comparteix i rep", "Name[ca]": "Comparteix i rep", "Name[cs]": "Sdílet a přijímat", "Name[da]": "Del og modtag", "Name[de]": "Senden und Empfangen", "Name[el]": "Διαμοιρασμός και λήψη", "Name[es]": "Compartir y recibir", "Name[et]": "Jagamine ja vastuvõtmine", - "Name[eu]": "Partekatu eta jaso", "Name[fi]": "Jaa ja vastaanota", "Name[fr]": "Partager et recevoir", "Name[gl]": "Compartir e recibir.", "Name[hu]": "Megosztás és fogadás", "Name[it]": "Condividi e ricevi", "Name[ko]": "공유하고 받기", "Name[nl]": "Delen en ontvangen", "Name[nn]": "Del og ta imot", "Name[pl]": "Udostępniaj i otrzymuj", "Name[pt]": "Partilhar e receber", "Name[pt_BR]": "Compartilhar e receber", "Name[ru]": "Общий доступ и получение", "Name[sk]": "Zdieľať a prijať", "Name[sr@ijekavian]": "Дели и примај", "Name[sr@ijekavianlatin]": "Deli i primaj", "Name[sr@latin]": "Deli i primaj", "Name[sr]": "Дели и примај", "Name[sv]": "Dela och ta emot", "Name[tr]": "Paylaş ve al", "Name[uk]": "Оприлюднення і отримання", "Name[x-test]": "xxShare and receivexx", "Name[zh_CN]": "分享和接收", "Name[zh_TW]": "共享與接收", "ServiceTypes": [ "KdeConnect/Plugin" ], "Version": "0.1", "Website": "http://albertvaka.wordpress.com" }, "X-KdeConnect-OutgoingPackageType": [ "kdeconnect.share.request" ], "X-KdeConnect-SupportedPackageType": [ "kdeconnect.share.request" ] } diff --git a/plugins/share/kdeconnect_share_config.desktop b/plugins/share/kdeconnect_share_config.desktop index 6f1a4218..5a0d6c67 100644 --- a/plugins/share/kdeconnect_share_config.desktop +++ b/plugins/share/kdeconnect_share_config.desktop @@ -1,48 +1,47 @@ [Desktop Entry] Type=Service X-KDE-ServiceTypes=KCModule X-KDE-Library=kdeconnect_share_config X-KDE-ParentComponents=kdeconnect_share Name=Share plugin settings Name[ar]=إعدادات ملحقة المشاركة Name[ast]=Axustes del complementu de compartición Name[bg]=Настройки на приставката за споделяне Name[bs]=Podijeli postavke dodatka Name[ca]=Ajustaments del connector Compartició Name[ca@valencia]=Ajustaments del connector Compartició Name[cs]=Nastavení modulu sdílení Name[da]=Indstilling af deling-plugin Name[de]=Modul-Einstellungen für Veröffentlichung Name[el]=Ρυθμίσεις προσθέτου κοινής χρήσης Name[en_GB]=Share plugin settings Name[es]=Ajustes del complemento para compartir Name[et]=Jagamisplugina seadistused -Name[eu]=Partekatu pluginaren ezarpenak Name[fi]=Jakoliitännäisen asetukset Name[fr]=Paramètres du module de partage Name[gl]=Configuración do complemento de compartir Name[he]=שתף את הגדרות התוספים Name[hu]=Megosztás bővítmény beállításai Name[it]=Impostazioni estensione Condivisione Name[ko]=공유 플러그인 설정 Name[nl]=Plug-in-instellingen van delen Name[nn]=Innstillingar for tillegg for deling Name[pl]=Ustawienia wtyczki udostępniania Name[pt]=Configuração do 'plugin' de partilha Name[pt_BR]=Compartilhar as configurações do plugin Name[ru]=Настройка модуля обмена файлами Name[sk]=Nastavenia pluginu zdieľania Name[sr]=Поставке прикључка дељења Name[sr@ijekavian]=Поставке прикључка дељења Name[sr@ijekavianlatin]=Postavke priključka deljenja Name[sr@latin]=Postavke priključka deljenja Name[sv]=Inställningar av delningsinsticksprogram Name[tr]=Paylaşma eklentisi ayarları Name[uk]=Параметри додатка оприлюднення даних Name[x-test]=xxShare plugin settingsxx Name[zh_CN]=分享插件设置 Name[zh_TW]=共享擴展插件設定 Categories=Qt;KDE;X-KDE-settings-kdeconnect; diff --git a/plugins/share/share_config.cpp b/plugins/share/share_config.cpp index 16e1184f..ccc8235f 100644 --- a/plugins/share/share_config.cpp +++ b/plugins/share/share_config.cpp @@ -1,75 +1,75 @@ /** * Copyright 2013 Albert Vaca * * 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 "share_config.h" #include "ui_share_config.h" #include #include #include K_PLUGIN_FACTORY(ShareConfigFactory, registerPlugin();) -ShareConfig::ShareConfig(QWidget *parent, const QVariantList& args) +ShareConfig::ShareConfig(QWidget* parent, const QVariantList& args) : KdeConnectPluginKcm(parent, args, QStringLiteral("kdeconnect_share_config")) , m_ui(new Ui::ShareConfigUi()) { m_ui->setupUi(this); // xgettext:no-c-format m_ui->commentLabel->setTextFormat(Qt::RichText); m_ui->commentLabel->setText(i18n("%1 in the path will be replaced with the specific device name.")); connect(m_ui->kurlrequester, SIGNAL(textChanged(QString)), this, SLOT(changed())); } ShareConfig::~ShareConfig() { delete m_ui; } void ShareConfig::defaults() { KCModule::defaults(); m_ui->kurlrequester->setUrl(QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::DownloadLocation))); Q_EMIT changed(true); } void ShareConfig::load() { KCModule::load(); m_ui->kurlrequester->setUrl(QUrl::fromLocalFile(config()->get(QStringLiteral("incoming_path"), QStandardPaths::writableLocation(QStandardPaths::DownloadLocation)))); Q_EMIT changed(false); } void ShareConfig::save() { config()->set(QStringLiteral("incoming_path"), m_ui->kurlrequester->text()); KCModule::save(); Q_EMIT changed(false); } #include "share_config.moc" diff --git a/plugins/share/share_config.h b/plugins/share/share_config.h index 6773a2ea..a0bb0a6a 100644 --- a/plugins/share/share_config.h +++ b/plugins/share/share_config.h @@ -1,48 +1,48 @@ /** * Copyright 2013 Albert Vaca * * 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 SHARE_CONFIG_H #define SHARE_CONFIG_H #include "kcmplugin/kdeconnectpluginkcm.h" namespace Ui { class ShareConfigUi; } class ShareConfig : public KdeConnectPluginKcm { Q_OBJECT public: - ShareConfig(QWidget *parent, const QVariantList&); + ShareConfig(QWidget* parent, const QVariantList&); ~ShareConfig() override; public Q_SLOTS: void save() override; void load() override; void defaults() override; private: Ui::ShareConfigUi* m_ui; }; #endif diff --git a/plugins/share/shareplugin.h b/plugins/share/shareplugin.h index 8eb0bca1..a8bfba53 100644 --- a/plugins/share/shareplugin.h +++ b/plugins/share/shareplugin.h @@ -1,60 +1,60 @@ /** * Copyright 2013 Albert Vaca * * 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 SHAREPLUGIN_H #define SHAREPLUGIN_H #include #include #include #define PACKAGE_TYPE_SHARE_REQUEST QStringLiteral("kdeconnect.share.request") class SharePlugin : public KdeConnectPlugin { Q_OBJECT Q_CLASSINFO("D-Bus Interface", "org.kde.kdeconnect.device.share") public: - explicit SharePlugin(QObject *parent, const QVariantList &args); + explicit SharePlugin(QObject* parent, const QVariantList& args); ///Helper method, QDBus won't recognize QUrl Q_SCRIPTABLE void shareUrl(const QString& url) { shareUrl(QUrl(url)); } bool receivePackage(const NetworkPackage& np) override; void connected() override {} QString dbusPath() const override; private Q_SLOTS: void finished(KJob*); void openDestinationFolder(); Q_SIGNALS: void shareReceived(const QUrl& url); private: void shareUrl(const QUrl& url); QUrl destinationDir() const; }; #endif diff --git a/plugins/telephony/kdeconnect_telephony.json b/plugins/telephony/kdeconnect_telephony.json index b2f368de..ad014894 100644 --- a/plugins/telephony/kdeconnect_telephony.json +++ b/plugins/telephony/kdeconnect_telephony.json @@ -1,97 +1,95 @@ { "Encoding": "UTF-8", "KPlugin": { "Authors": [ { "Email": "albertvaka@gmail.com", "Name": "Albert Vaca", "Name[sr@ijekavian]": "Алберт Вака Синтора", "Name[sr@ijekavianlatin]": "Albert Vaka Sintora", "Name[sr@latin]": "Albert Vaka Sintora", "Name[sr]": "Алберт Вака Синтора", "Name[x-test]": "xxAlbert Vacaxx" } ], "Description": "Show notifications for calls and SMS", "Description[ar]": "أظهر إخطارات المكالمات والرّسائل", "Description[ca@valencia]": "Mostra les notificacions de les trucades i els SMS", "Description[ca]": "Mostra les notificacions de les trucades i els SMS", "Description[cs]": "Zobrazit upozornění pro telefonáty a SMS", "Description[da]": "Vis bekendtgørelser for opkald og sms", "Description[de]": "Benachrichtigungen für Anrufe und SMS anzeigen", "Description[el]": "Εμφάνιση ειδοποιήσεων για κλήσεις και SMS", "Description[es]": "Mostrar notificaciones de llamadas y SMS", "Description[et]": "Kõnede ja SMS-ide märguannete näitamine", - "Description[eu]": "Erakutsi deien eta SMS mezuen jakinarazpenak", "Description[fi]": "Näytä puhelujen ja tekstiviestien ilmoitukset", "Description[fr]": "Affichez les notifications pour les appels et les SMS", "Description[gl]": "Mostrar notificacións de chamadas e mensaxes SMS.", "Description[it]": "Mostra notifiche per le chiamate e per gli SMS", "Description[ko]": "통화와 SMS 알림 표시", "Description[nl]": "Meldingen tonen van oproepen en SMSjes", "Description[nn]": "Vis varslingar for oppringingar og SMS", "Description[pl]": "Powiadamiaj o dzwonieniu i esemesach", "Description[pt]": "Mostrar notificações para as chamadas e SMS", "Description[ru]": "Показ уведомлений для звонков и SMS", "Description[sr@ijekavian]": "Приказује обавештења за позиве и СМС", "Description[sr@ijekavianlatin]": "Prikazuje obaveštenja za pozive i SMS", "Description[sr@latin]": "Prikazuje obaveštenja za pozive i SMS", "Description[sr]": "Приказује обавештења за позиве и СМС", "Description[sv]": "Visa underrättelser om samtal och SMS", "Description[tr]": "Çağrı ve SMS'ler için bildirim göster", "Description[uk]": "Показ сповіщень щодо дзвінків і SMS", "Description[x-test]": "xxShow notifications for calls and SMSxx", "Description[zh_CN]": "显示来电和短信通知", "Description[zh_TW]": "顯示來電與短訊通知", "EnabledByDefault": true, "Icon": "call-start", "Id": "kdeconnect_telephony", "License": "GPL", "Name": "Telephony integration", "Name[ar]": "تكامل الهاتف", "Name[ca@valencia]": "Integració amb la telefonia", "Name[ca]": "Integració amb la telefonia", "Name[cs]": "Integrace telefonu", "Name[da]": "Integration af telefoni", "Name[de]": "Telefon-Integration", "Name[el]": "Ενσωμάτωση τηλεφωνίας", "Name[es]": "Integración con el teléfono", "Name[et]": "Telefoniga lõimimine", - "Name[eu]": "Telefoniarekin integrazioa", "Name[fi]": "Puhelinintegrointi", "Name[fr]": "Intégration de la téléphonie", "Name[gl]": "Integración telefónica", "Name[hu]": "Telefonintegráció", "Name[it]": "Integrazione telefonica", "Name[ko]": "전화 통합", "Name[nl]": "Telefoonintegratie", "Name[nn]": "Telefonintegrering", "Name[pl]": "Integracja z telefonem", "Name[pt]": "Integração telefónica", "Name[pt_BR]": "Integração telefônica", "Name[ru]": "Интеграция телефонии", "Name[sk]": "Integrácia telefónie", "Name[sr@ijekavian]": "Интегрисана телефонија", "Name[sr@ijekavianlatin]": "Integrisana telefonija", "Name[sr@latin]": "Integrisana telefonija", "Name[sr]": "Интегрисана телефонија", "Name[sv]": "Integrering av telefoni", "Name[tr]": "Telefon tümleştirmesi", "Name[uk]": "Інтеграція з системою телефонії", "Name[x-test]": "xxTelephony integrationxx", "Name[zh_CN]": "Telephony 集成", "Name[zh_TW]": "集成電話", "ServiceTypes": [ "KdeConnect/Plugin" ], "Version": "0.1", "Website": "http://albertvaka.wordpress.com" }, "X-KdeConnect-OutgoingPackageType": [ "kdeconnect.telephony.request", "kdeconnect.sms.request" ], "X-KdeConnect-SupportedPackageType": [ "kdeconnect.telephony" ] } diff --git a/plugins/telephony/sendsmsdialog.cpp b/plugins/telephony/sendsmsdialog.cpp index da86a353..6d8498be 100644 --- a/plugins/telephony/sendsmsdialog.cpp +++ b/plugins/telephony/sendsmsdialog.cpp @@ -1,64 +1,64 @@ /** * Copyright 2015 Albert Vaca * * 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 "sendsmsdialog.h" #include #include #include #include #include SendSmsDialog::SendSmsDialog(const QString& originalMessage, const QString& phoneNumber, const QString& contactName, QWidget* parent) : QDialog(parent) - , mPhoneNumber(phoneNumber) + , m_phoneNumber(phoneNumber) { QVBoxLayout* layout = new QVBoxLayout; QTextEdit* textView = new QTextEdit(this); textView->setReadOnly(true); textView->setText(contactName + ": \n" + originalMessage); layout->addWidget(textView); - mTextEdit = new QTextEdit(this); - layout->addWidget(mTextEdit); + m_textEdit = new QTextEdit(this); + layout->addWidget(m_textEdit); QPushButton* sendButton = new QPushButton(i18n("Send"), this); connect(sendButton, &QAbstractButton::clicked, this, &SendSmsDialog::sendButtonClicked); layout->addWidget(sendButton); setLayout(layout); setWindowTitle(contactName); setWindowIcon(QIcon::fromTheme(QStringLiteral("kdeconnect"))); setAttribute(Qt::WA_DeleteOnClose); } void SendSmsDialog::sendButtonClicked() { - Q_EMIT sendSms(mPhoneNumber, mTextEdit->toPlainText()); + Q_EMIT sendSms(m_phoneNumber, m_textEdit->toPlainText()); close(); } QSize SendSmsDialog::sizeHint() const { return QSize(512, 64); } diff --git a/plugins/telephony/sendsmsdialog.h b/plugins/telephony/sendsmsdialog.h index b56bbc15..1ec8fffc 100644 --- a/plugins/telephony/sendsmsdialog.h +++ b/plugins/telephony/sendsmsdialog.h @@ -1,50 +1,50 @@ /** * Copyright 2015 Albert Vaca * * 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 SENDSMSDIALOG_H #define SENDSMSDIALOG_H #include #include class QTextEdit; class QLineEdit; class QPushButton; class SendSmsDialog : public QDialog { Q_OBJECT public: - explicit SendSmsDialog(const QString& originalMessage, const QString& phoneNumber, const QString& contactName, QWidget *parent = nullptr); + explicit SendSmsDialog(const QString& originalMessage, const QString& phoneNumber, const QString& contactName, QWidget* parent = nullptr); QSize sizeHint() const override; private Q_SLOTS: void sendButtonClicked(); Q_SIGNALS: void sendSms(const QString& phoneNumber, const QString& messageBody); private: - QString mPhoneNumber; - QTextEdit *mTextEdit; + QString m_phoneNumber; + QTextEdit* m_textEdit; }; #endif diff --git a/plugins/telephony/telephonyplugin.cpp b/plugins/telephony/telephonyplugin.cpp index 7b76f57a..e77e9726 100644 --- a/plugins/telephony/telephonyplugin.cpp +++ b/plugins/telephony/telephonyplugin.cpp @@ -1,169 +1,169 @@ /** * Copyright 2013 Albert Vaca * * 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 "telephonyplugin.h" #include "sendsmsdialog.h" #include #include #include #include #include K_PLUGIN_FACTORY_WITH_JSON( KdeConnectPluginFactory, "kdeconnect_telephony.json", registerPlugin< TelephonyPlugin >(); ) Q_LOGGING_CATEGORY(KDECONNECT_PLUGIN_TELEPHONY, "kdeconnect.plugin.telephony") -TelephonyPlugin::TelephonyPlugin(QObject *parent, const QVariantList &args) +TelephonyPlugin::TelephonyPlugin(QObject* parent, const QVariantList& args) : KdeConnectPlugin(parent, args) , m_telepathyInterface(QStringLiteral("org.freedesktop.Telepathy.ConnectionManager.kdeconnect"), QStringLiteral("/kdeconnect")) { } KNotification* TelephonyPlugin::createNotification(const NetworkPackage& np) { const QString event = np.get(QStringLiteral("event")); const QString phoneNumber = np.get(QStringLiteral("phoneNumber"), i18n("unknown number")); const QString contactName = np.get(QStringLiteral("contactName"), phoneNumber); const QByteArray phoneThumbnail = QByteArray::fromBase64(np.get(QStringLiteral("phoneThumbnail"), "")); // In case telepathy can handle the message, don't do anything else if (event == QLatin1String("sms") && m_telepathyInterface.isValid()) { qCDebug(KDECONNECT_PLUGIN_TELEPHONY) << "Passing a text message to the telepathy interface"; connect(&m_telepathyInterface, SIGNAL(messageReceived(QString,QString)), SLOT(sendSms(QString,QString)), Qt::UniqueConnection); const QString messageBody = np.get(QStringLiteral("messageBody"),QLatin1String("")); QDBusReply reply = m_telepathyInterface.call(QStringLiteral("sendMessage"), phoneNumber, contactName, messageBody); if (reply) { return nullptr; } else { qCDebug(KDECONNECT_PLUGIN_TELEPHONY) << "Telepathy failed, falling back to the default handling"; } } QString content, type, icon; KNotification::NotificationFlags flags = KNotification::CloseOnTimeout; const QString title = device()->name(); if (event == QLatin1String("ringing")) { type = QStringLiteral("callReceived"); icon = QStringLiteral("call-start"); content = i18n("Incoming call from %1", contactName); } else if (event == QLatin1String("missedCall")) { type = QStringLiteral("missedCall"); icon = QStringLiteral("call-start"); content = i18n("Missed call from %1", contactName); flags |= KNotification::Persistent; //Note that in Unity this generates a message box! } else if (event == QLatin1String("sms")) { type = QStringLiteral("smsReceived"); icon = QStringLiteral("mail-receive"); QString messageBody = np.get(QStringLiteral("messageBody"), QLatin1String("")); content = i18n("SMS from %1
%2", contactName, messageBody); flags |= KNotification::Persistent; //Note that in Unity this generates a message box! } else if (event == QLatin1String("talking")) { return nullptr; } else { #ifndef NDEBUG return nullptr; #else type = QStringLiteral("callReceived"); icon = QStringLiteral("phone"); content = i18n("Unknown telephony event: %1", event); #endif } qCDebug(KDECONNECT_PLUGIN_TELEPHONY) << "Creating notification with type:" << type; KNotification* notification = new KNotification(type, flags, this); if (!phoneThumbnail.isEmpty()) { QPixmap photo; photo.loadFromData(phoneThumbnail, "JPEG"); notification->setPixmap(photo); } else { notification->setIconName(icon); } notification->setComponentName(QStringLiteral("kdeconnect")); notification->setTitle(title); notification->setText(content); if (event == QLatin1String("ringing")) { notification->setActions( QStringList(i18n("Mute Call")) ); connect(notification, &KNotification::action1Activated, this, &TelephonyPlugin::sendMutePackage); } else if (event == QLatin1String("sms")) { const QString messageBody = np.get(QStringLiteral("messageBody"),QLatin1String("")); notification->setActions( QStringList(i18n("Reply")) ); notification->setProperty("phoneNumber", phoneNumber); notification->setProperty("contactName", contactName); notification->setProperty("originalMessage", messageBody); connect(notification, &KNotification::action1Activated, this, &TelephonyPlugin::showSendSmsDialog); } return notification; } bool TelephonyPlugin::receivePackage(const NetworkPackage& np) { if (np.get(QStringLiteral("isCancel"))) { //TODO: Clear the old notification return true; } KNotification* n = createNotification(np); if (n != nullptr) n->sendEvent(); return true; } void TelephonyPlugin::sendMutePackage() { NetworkPackage package(PACKAGE_TYPE_TELEPHONY_REQUEST, {{"action", "mute"}}); sendPackage(package); } void TelephonyPlugin::sendSms(const QString& phoneNumber, const QString& messageBody) { NetworkPackage np(PACKAGE_TYPE_SMS_REQUEST, { {"sendSms", true}, {"phoneNumber", phoneNumber}, {"messageBody", messageBody} }); sendPackage(np); } void TelephonyPlugin::showSendSmsDialog() { QString phoneNumber = sender()->property("phoneNumber").toString(); QString contactName = sender()->property("contactName").toString(); QString originalMessage = sender()->property("originalMessage").toString(); SendSmsDialog* dialog = new SendSmsDialog(originalMessage, phoneNumber, contactName); connect(dialog, &SendSmsDialog::sendSms, this, &TelephonyPlugin::sendSms); dialog->show(); } QString TelephonyPlugin::dbusPath() const { return "/modules/kdeconnect/devices/" + device()->id() + "/telephony"; } #include "telephonyplugin.moc" diff --git a/plugins/telephony/telephonyplugin.h b/plugins/telephony/telephonyplugin.h index ff4fe07c..a1f3c7bb 100644 --- a/plugins/telephony/telephonyplugin.h +++ b/plugins/telephony/telephonyplugin.h @@ -1,62 +1,62 @@ /** * Copyright 2013 Albert Vaca * * 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 TELEPHONYPLUGIN_H #define TELEPHONYPLUGIN_H #include #include #include #include #define PACKAGE_TYPE_TELEPHONY_REQUEST QStringLiteral("kdeconnect.telephony.request") #define PACKAGE_TYPE_SMS_REQUEST QStringLiteral("kdeconnect.sms.request") Q_DECLARE_LOGGING_CATEGORY(KDECONNECT_PLUGIN_TELEPHONY) class TelephonyPlugin : public KdeConnectPlugin { Q_OBJECT Q_CLASSINFO("D-Bus Interface", "org.kde.kdeconnect.device.telephony") public: - explicit TelephonyPlugin(QObject *parent, const QVariantList &args); + explicit TelephonyPlugin(QObject* parent, const QVariantList& args); bool receivePackage(const NetworkPackage& np) override; void connected() override {} QString dbusPath() const override; public Q_SLOTS: Q_SCRIPTABLE void sendSms(const QString& phoneNumber, const QString& messageBody); private Q_SLOTS: void sendMutePackage(); void showSendSmsDialog(); private: KNotification* createNotification(const NetworkPackage& np); QDBusInterface m_telepathyInterface; }; #endif diff --git a/tests/downloadjobtest.cpp b/tests/downloadjobtest.cpp index 30692271..d59e3f96 100644 --- a/tests/downloadjobtest.cpp +++ b/tests/downloadjobtest.cpp @@ -1,83 +1,83 @@ /************************************************************************************* * Copyright (C) 2014 by Albert Vaca Cintora * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Lesser General Public * * License as published by the Free Software Foundation; either * * version 2.1 of the License, or (at your option) any later version. * * * * 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 * * Lesser General Public License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with this library; if not, write to the Free Software * * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *************************************************************************************/ #include "../core/backends/lan/downloadjob.h" #include #include #include #include #include #include #include #include #include #include class DownloadJobTest : public QObject { Q_OBJECT private Q_SLOTS: void failToConnectShouldDestroyTheJob(); void closingTheConnectionShouldDestroyTheJob(); private: void initServer(); void initDownloadJob(); void awaitToBeDestroyedOrTimeOut(); void stopServer(); - QPointer test; - QPointer mServer; + QPointer m_test; + QPointer m_server; }; void DownloadJobTest::initServer() { - delete mServer; - mServer = new QTcpServer(this); - QVERIFY2(mServer->listen(QHostAddress::LocalHost, 8694), "Failed to create local tcp server"); + delete m_server; + m_server = new QTcpServer(this); + QVERIFY2(m_server->listen(QHostAddress::LocalHost, 8694), "Failed to create local tcp server"); } void DownloadJobTest::failToConnectShouldDestroyTheJob() { // no initServer - test = new DownloadJob(QHostAddress::LocalHost, {{"port", 8694}}); + m_test = new DownloadJob(QHostAddress::LocalHost, {{"port", 8694}}); - QSignalSpy spy(test.data(), &KJob::finished); - test->start(); + QSignalSpy spy(m_test.data(), &KJob::finished); + m_test->start(); QVERIFY(spy.count() || spy.wait()); - QCOMPARE(test->error(), 1); + QCOMPARE(m_test->error(), 1); } void DownloadJobTest::closingTheConnectionShouldDestroyTheJob() { initServer(); - test = new DownloadJob(QHostAddress::LocalHost, {{"port", 8694}}); - QSignalSpy spy(test.data(), &KJob::finished); - test->start(); - mServer->close(); + m_test = new DownloadJob(QHostAddress::LocalHost, {{"port", 8694}}); + QSignalSpy spy(m_test.data(), &KJob::finished); + m_test->start(); + m_server->close(); QVERIFY(spy.count() || spy.wait(2000)); } QTEST_GUILESS_MAIN(DownloadJobTest) #include "downloadjobtest.moc" diff --git a/tests/lanlinkprovidertest.cpp b/tests/lanlinkprovidertest.cpp index 14f7114d..926b8848 100644 --- a/tests/lanlinkprovidertest.cpp +++ b/tests/lanlinkprovidertest.cpp @@ -1,356 +1,356 @@ /** * Copyright 2015 Vineet Garg * * 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 . */ // This class tests the behaviour of the class LanLinkProvider, be sure to kill process kdeconnectd to avoid any port binding issues #include "../core/backends/lan/lanlinkprovider.h" #include "../core/backends/lan/server.h" #include "../core/backends/lan/socketlinereader.h" #include "../core/kdeconnectconfig.h" #include #include #include #include #include /* * This class tests the working of LanLinkProvider under different conditions that when identity package is received over TCP, over UDP and same when the device is paired. * It depends on KdeConnectConfig since LanLinkProvider internally uses it. */ class LanLinkProviderTest : public QObject { Q_OBJECT public: explicit LanLinkProviderTest() - : mLanLinkProvider(true) { + : m_lanLinkProvider(true) { QStandardPaths::setTestModeEnabled(true); } public Q_SLOTS: void initTestCase(); private Q_SLOTS: void pairedDeviceTcpPackageReceived(); void pairedDeviceUdpPackageReceived(); void unpairedDeviceTcpPackageReceived(); void unpairedDeviceUdpPackageReceived(); private: const int TEST_PORT = 8520; // Add some private fields here - LanLinkProvider mLanLinkProvider; - Server* mServer; - SocketLineReader* mReader; - QUdpSocket* mUdpSocket; - QString mIdentityPackage; + LanLinkProvider m_lanLinkProvider; + Server* m_server; + SocketLineReader* m_reader; + QUdpSocket* m_udpSocket; + QString m_identityPackage; // Attributes for test device - QString deviceId; - QString name; - QCA::PrivateKey privateKey; - QSslCertificate certificate; + QString m_deviceId; + QString m_name; + QCA::PrivateKey m_privateKey; + QSslCertificate m_certificate; QSslCertificate generateCertificate(QString&, QCA::PrivateKey&); void addTrustedDevice(); void removeTrustedDevice(); - void setSocketAttributes(QSslSocket *socket); + void setSocketAttributes(QSslSocket* socket); void testIdentityPackage(QByteArray& identityPackage); }; void LanLinkProviderTest::initTestCase() { removeTrustedDevice(); // Remove trusted device if left by chance by any test - deviceId = QStringLiteral("testdevice"); - name = QStringLiteral("Test Device"); - privateKey = QCA::KeyGenerator().createRSA(2048); - certificate = generateCertificate(deviceId, privateKey); + m_deviceId = QStringLiteral("testdevice"); + m_name = QStringLiteral("Test Device"); + m_privateKey = QCA::KeyGenerator().createRSA(2048); + m_certificate = generateCertificate(m_deviceId, m_privateKey); - mLanLinkProvider.onStart(); + m_lanLinkProvider.onStart(); - mIdentityPackage = QStringLiteral("{\"id\":1439365924847,\"type\":\"kdeconnect.identity\",\"body\":{\"deviceId\":\"testdevice\",\"deviceName\":\"Test Device\",\"protocolVersion\":6,\"deviceType\":\"phone\",\"tcpPort\":") + QString::number(TEST_PORT) + QStringLiteral("}}"); + m_identityPackage = QStringLiteral("{\"id\":1439365924847,\"type\":\"kdeconnect.identity\",\"body\":{\"deviceId\":\"testdevice\",\"deviceName\":\"Test Device\",\"protocolVersion\":6,\"deviceType\":\"phone\",\"tcpPort\":") + QString::number(TEST_PORT) + QStringLiteral("}}"); } void LanLinkProviderTest::pairedDeviceTcpPackageReceived() { KdeConnectConfig* kcc = KdeConnectConfig::instance(); addTrustedDevice(); QUdpSocket* mUdpServer = new QUdpSocket; bool b = mUdpServer->bind(QHostAddress::LocalHost, LanLinkProvider::UDP_PORT, QUdpSocket::ShareAddress); QVERIFY(b); QSignalSpy spy(mUdpServer, SIGNAL(readyRead())); - mLanLinkProvider.onNetworkChange(); + m_lanLinkProvider.onNetworkChange(); QVERIFY(!spy.isEmpty() || spy.wait()); QByteArray datagram; datagram.resize(mUdpServer->pendingDatagramSize()); QHostAddress sender; mUdpServer->readDatagram(datagram.data(), datagram.size(), &sender); testIdentityPackage(datagram); QJsonDocument jsonDocument = QJsonDocument::fromJson(datagram); QJsonObject body = jsonDocument.object().value(QStringLiteral("body")).toObject(); int tcpPort = body.value(QStringLiteral("tcpPort")).toInt(); QSslSocket socket; QSignalSpy spy2(&socket, SIGNAL(connected())); socket.connectToHost(sender, tcpPort); QVERIFY(spy2.wait()); QVERIFY2(socket.isOpen(), "Socket disconnected immediately"); - socket.write(mIdentityPackage.toLatin1()); + socket.write(m_identityPackage.toLatin1()); socket.waitForBytesWritten(2000); QSignalSpy spy3(&socket, SIGNAL(encrypted())); setSocketAttributes(&socket); socket.addCaCertificate(kcc->certificate()); socket.setPeerVerifyMode(QSslSocket::VerifyPeer); socket.setPeerVerifyName(kcc->name()); socket.startServerEncryption(); QVERIFY(spy3.wait()); QCOMPARE(socket.sslErrors().size(), 0); QVERIFY2(socket.isValid(), "Server socket disconnected"); QVERIFY2(socket.isEncrypted(), "Server socket not yet encrypted"); QVERIFY2(!socket.peerCertificate().isNull(), "Peer certificate is null"); removeTrustedDevice(); delete mUdpServer; } void LanLinkProviderTest::pairedDeviceUdpPackageReceived() { KdeConnectConfig* kcc = KdeConnectConfig::instance(); addTrustedDevice(); - mServer = new Server(this); - mUdpSocket = new QUdpSocket(this); + m_server = new Server(this); + m_udpSocket = new QUdpSocket(this); - mServer->listen(QHostAddress::LocalHost, TEST_PORT); + m_server->listen(QHostAddress::LocalHost, TEST_PORT); - QSignalSpy spy(mServer, SIGNAL(newConnection())); + QSignalSpy spy(m_server, SIGNAL(newConnection())); - qint64 bytesWritten = mUdpSocket->writeDatagram(mIdentityPackage.toLatin1(), QHostAddress::LocalHost, LanLinkProvider::UDP_PORT); // write an identity package to udp socket here, we do not broadcast it here - QCOMPARE(bytesWritten, mIdentityPackage.size()); + qint64 bytesWritten = m_udpSocket->writeDatagram(m_identityPackage.toLatin1(), QHostAddress::LocalHost, LanLinkProvider::UDP_PORT); // write an identity package to udp socket here, we do not broadcast it here + QCOMPARE(bytesWritten, m_identityPackage.size()); // We should have an incoming connection now, wait for incoming connection QVERIFY(!spy.isEmpty() || spy.wait()); - QSslSocket* serverSocket = mServer->nextPendingConnection(); + QSslSocket* serverSocket = m_server->nextPendingConnection(); QVERIFY2(serverSocket != 0, "Server socket is null"); QVERIFY2(serverSocket->isOpen(), "Server socket already closed"); - mReader = new SocketLineReader(serverSocket, this); - QSignalSpy spy2(mReader, SIGNAL(readyRead())); + m_reader = new SocketLineReader(serverSocket, this); + QSignalSpy spy2(m_reader, SIGNAL(readyRead())); QVERIFY(spy2.wait()); - QByteArray receivedPackage = mReader->readLine(); + QByteArray receivedPackage = m_reader->readLine(); testIdentityPackage(receivedPackage); // Received identiy package from LanLinkProvider now start ssl QSignalSpy spy3(serverSocket, SIGNAL(encrypted())); QVERIFY(connect(serverSocket, static_cast(&QSslSocket::error), this, [](QAbstractSocket::SocketError error){ qDebug() << "error:" << error; })); setSocketAttributes(serverSocket); serverSocket->addCaCertificate(kcc->certificate()); serverSocket->setPeerVerifyMode(QSslSocket::VerifyPeer); serverSocket->setPeerVerifyName(kcc->deviceId()); serverSocket->startClientEncryption(); // Its TCP server. but SSL client QVERIFY(!serverSocket->isEncrypted()); spy3.wait(2000); qDebug() << "xxxxxxxxx" << serverSocket->sslErrors(); QCOMPARE(serverSocket->sslErrors().size(), 0); QVERIFY2(serverSocket->isValid(), "Server socket disconnected"); QVERIFY2(serverSocket->isEncrypted(), "Server socket not yet encrypted"); QVERIFY2(!serverSocket->peerCertificate().isNull(), "Peer certificate is null"); removeTrustedDevice(); - delete mServer; - delete mUdpSocket; + delete m_server; + delete m_udpSocket; } void LanLinkProviderTest::unpairedDeviceTcpPackageReceived() { QUdpSocket* mUdpServer = new QUdpSocket; bool b = mUdpServer->bind(QHostAddress::LocalHost, LanLinkProvider::UDP_PORT, QUdpSocket::ShareAddress); QVERIFY(b); QSignalSpy spy(mUdpServer, SIGNAL(readyRead())); - mLanLinkProvider.onNetworkChange(); + m_lanLinkProvider.onNetworkChange(); QVERIFY(!spy.isEmpty() || spy.wait()); QByteArray datagram; datagram.resize(mUdpServer->pendingDatagramSize()); QHostAddress sender; mUdpServer->readDatagram(datagram.data(), datagram.size(), &sender); testIdentityPackage(datagram); QJsonDocument jsonDocument = QJsonDocument::fromJson(datagram); QJsonObject body = jsonDocument.object().value(QStringLiteral("body")).toObject(); int tcpPort = body.value(QStringLiteral("tcpPort")).toInt(); QSslSocket socket; QSignalSpy spy2(&socket, SIGNAL(connected())); socket.connectToHost(sender, tcpPort); QVERIFY(spy2.wait()); QVERIFY2(socket.isOpen(), "Socket disconnected immediately"); - socket.write(mIdentityPackage.toLatin1()); + socket.write(m_identityPackage.toLatin1()); socket.waitForBytesWritten(2000); QSignalSpy spy3(&socket, SIGNAL(encrypted())); // We don't take care for sslErrors signal here, but signal will emit still we will get successful connection setSocketAttributes(&socket); socket.setPeerVerifyMode(QSslSocket::QueryPeer); socket.startServerEncryption(); QVERIFY(spy3.wait()); QVERIFY2(socket.isValid(), "Server socket disconnected"); QVERIFY2(socket.isEncrypted(), "Server socket not yet encrypted"); QVERIFY2(!socket.peerCertificate().isNull(), "Peer certificate is null"); delete mUdpServer; } void LanLinkProviderTest::unpairedDeviceUdpPackageReceived() { - mServer = new Server(this); - mUdpSocket = new QUdpSocket(this); + m_server = new Server(this); + m_udpSocket = new QUdpSocket(this); - mServer->listen(QHostAddress::LocalHost, TEST_PORT); + m_server->listen(QHostAddress::LocalHost, TEST_PORT); - QSignalSpy spy(mServer, &Server::newConnection); - qint64 bytesWritten = mUdpSocket->writeDatagram(mIdentityPackage.toLatin1(), QHostAddress::LocalHost, LanLinkProvider::UDP_PORT); // write an identity package to udp socket here, we do not broadcast it here - QCOMPARE(bytesWritten, mIdentityPackage.size()); + QSignalSpy spy(m_server, &Server::newConnection); + qint64 bytesWritten = m_udpSocket->writeDatagram(m_identityPackage.toLatin1(), QHostAddress::LocalHost, LanLinkProvider::UDP_PORT); // write an identity package to udp socket here, we do not broadcast it here + QCOMPARE(bytesWritten, m_identityPackage.size()); QVERIFY(!spy.isEmpty() || spy.wait()); - QSslSocket* serverSocket = mServer->nextPendingConnection(); + QSslSocket* serverSocket = m_server->nextPendingConnection(); QVERIFY2(serverSocket != 0, "Server socket is null"); QVERIFY2(serverSocket->isOpen(), "Server socket already closed"); - mReader = new SocketLineReader(serverSocket, this); - QSignalSpy spy2(mReader, &SocketLineReader::readyRead); + m_reader = new SocketLineReader(serverSocket, this); + QSignalSpy spy2(m_reader, &SocketLineReader::readyRead); QVERIFY(spy2.wait()); - QByteArray receivedPackage = mReader->readLine(); + QByteArray receivedPackage = m_reader->readLine(); QVERIFY2(!receivedPackage.isEmpty(), "Empty package received"); testIdentityPackage(receivedPackage); // Received identity package from LanLinkProvider now start ssl QSignalSpy spy3(serverSocket, SIGNAL(encrypted())); setSocketAttributes(serverSocket); serverSocket->setPeerVerifyMode(QSslSocket::QueryPeer); serverSocket->startClientEncryption(); // Its TCP server. but SSL client QVERIFY(spy3.wait()); QVERIFY2(serverSocket->isValid(), "Server socket disconnected"); QVERIFY2(serverSocket->isEncrypted(), "Server socket not yet encrypted"); QVERIFY2(!serverSocket->peerCertificate().isNull(), "Peer certificate is null"); - delete mServer; - delete mUdpSocket; + delete m_server; + delete m_udpSocket; } -void LanLinkProviderTest::testIdentityPackage(QByteArray &identityPackage) +void LanLinkProviderTest::testIdentityPackage(QByteArray& identityPackage) { QJsonDocument jsonDocument = QJsonDocument::fromJson(identityPackage); QJsonObject jsonObject = jsonDocument.object(); QJsonObject body = jsonObject.value(QStringLiteral("body")).toObject(); QCOMPARE(jsonObject.value("type").toString(), QString("kdeconnect.identity")); QVERIFY2(body.contains("deviceName"), "Device name not found in identity package"); QVERIFY2(body.contains("deviceId"), "Device id not found in identity package"); QVERIFY2(body.contains("protocolVersion"), "Protocol version not found in identity package"); QVERIFY2(body.contains("deviceType"), "Device type not found in identity package"); } QSslCertificate LanLinkProviderTest::generateCertificate(QString& commonName, QCA::PrivateKey& privateKey) { QDateTime startTime = QDateTime::currentDateTime(); QDateTime endTime = startTime.addYears(10); QCA::CertificateInfo certificateInfo; certificateInfo.insert(QCA::CommonName,commonName); certificateInfo.insert(QCA::Organization,QStringLiteral("KDE")); certificateInfo.insert(QCA::OrganizationalUnit,QStringLiteral("Kde connect")); QCA::CertificateOptions certificateOptions(QCA::PKCS10); certificateOptions.setSerialNumber(10); certificateOptions.setInfo(certificateInfo); certificateOptions.setValidityPeriod(startTime, endTime); certificateOptions.setFormat(QCA::PKCS10); QSslCertificate certificate = QSslCertificate(QCA::Certificate(certificateOptions, privateKey).toPEM().toLatin1()); return certificate; } -void LanLinkProviderTest::setSocketAttributes(QSslSocket *socket) +void LanLinkProviderTest::setSocketAttributes(QSslSocket* socket) { - socket->setPrivateKey(QSslKey(privateKey.toPEM().toLatin1(), QSsl::Rsa)); - socket->setLocalCertificate(certificate); + socket->setPrivateKey(QSslKey(m_privateKey.toPEM().toLatin1(), QSsl::Rsa)); + socket->setLocalCertificate(m_certificate); } void LanLinkProviderTest::addTrustedDevice() { - KdeConnectConfig *kcc = KdeConnectConfig::instance(); - kcc->addTrustedDevice(deviceId, name, QStringLiteral("phone")); - kcc->setDeviceProperty(deviceId, QStringLiteral("certificate"), QString::fromLatin1(certificate.toPem())); + KdeConnectConfig* kcc = KdeConnectConfig::instance(); + kcc->addTrustedDevice(m_deviceId, m_name, QStringLiteral("phone")); + kcc->setDeviceProperty(m_deviceId, QStringLiteral("certificate"), QString::fromLatin1(m_certificate.toPem())); } void LanLinkProviderTest::removeTrustedDevice() { - KdeConnectConfig *kcc = KdeConnectConfig::instance(); - kcc->removeTrustedDevice(deviceId); + KdeConnectConfig* kcc = KdeConnectConfig::instance(); + kcc->removeTrustedDevice(m_deviceId); } QTEST_GUILESS_MAIN(LanLinkProviderTest) #include "lanlinkprovidertest.moc" diff --git a/tests/networkpackagetests.cpp b/tests/networkpackagetests.cpp index 004d0fc0..d0d11a69 100644 --- a/tests/networkpackagetests.cpp +++ b/tests/networkpackagetests.cpp @@ -1,96 +1,96 @@ /** * Copyright 2013 Albert Vaca * * 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 "networkpackagetests.h" #include "core/networkpackage.h" #include #include QTEST_GUILESS_MAIN(NetworkPackageTests); void NetworkPackageTests::initTestCase() { // Called before the first testfunction is executed } void NetworkPackageTests::networkPackageTest() { NetworkPackage np(QStringLiteral("com.test")); np.set(QStringLiteral("hello"),"hola"); QCOMPARE( (np.get("hello","bye")) , QString("hola") ); np.set(QStringLiteral("hello"),""); QCOMPARE( (np.get("hello","bye")) , QString("") ); np.body().remove(QStringLiteral("hello")); QCOMPARE( (np.get("hello","bye")) , QString("bye") ); np.set(QStringLiteral("foo"), "bar"); QByteArray ba = np.serialize(); //qDebug() << "Serialized package:" << ba; NetworkPackage np2(QLatin1String("")); NetworkPackage::unserialize(ba,&np2); QCOMPARE( np.id(), np2.id() ); QCOMPARE( np.type(), np2.type() ); QCOMPARE( np.body(), np2.body() ); QByteArray json("{\"id\":\"123\",\"type\":\"test\",\"body\":{\"testing\":true}}"); //qDebug() << json; NetworkPackage::unserialize(json,&np2); QCOMPARE( np2.id(), QString("123") ); QCOMPARE( (np2.get("testing")), true ); QCOMPARE( (np2.get("not_testing")), false ); QCOMPARE( (np2.get("not_testing",true)), true ); //NetworkPackage::unserialize("this is not json",&np2); //QtTest::ignoreMessage(QtSystemMsg, "json_parser - syntax error found, forcing abort, Line 1 Column 0"); //QtTest::ignoreMessage(QtDebugMsg, "Unserialization error: 1 \"syntax error, unexpected string\""); } void NetworkPackageTests::networkPackageIdentityTest() { NetworkPackage np(QLatin1String("")); NetworkPackage::createIdentityPackage(&np); - QCOMPARE( np.get("protocolVersion", -1) , NetworkPackage::ProtocolVersion ); + QCOMPARE( np.get("protocolVersion", -1) , NetworkPackage::s_protocolVersion ); QCOMPARE( np.type() , PACKAGE_TYPE_IDENTITY ); } void NetworkPackageTests::cleanupTestCase() { // Called after the last testfunction was executed } void NetworkPackageTests::init() { // Called before each testfunction is executed } void NetworkPackageTests::cleanup() { // Called after every testfunction } diff --git a/tests/pluginloadtest.cpp b/tests/pluginloadtest.cpp index 7e30bcff..4b735181 100644 --- a/tests/pluginloadtest.cpp +++ b/tests/pluginloadtest.cpp @@ -1,85 +1,85 @@ /** * Copyright 2015 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 "core/daemon.h" #include "core/device.h" #include "core/kdeconnectplugin.h" #include #include "kdeconnect-version.h" #include "testdaemon.h" class PluginLoadTest : public QObject { Q_OBJECT public: PluginLoadTest() { QStandardPaths::setTestModeEnabled(true); - mDaemon = new TestDaemon; + m_daemon = new TestDaemon; } private Q_SLOTS: void testPlugins() { Device* d = nullptr; - mDaemon->acquireDiscoveryMode(QStringLiteral("plugintest")); - const QList devicesList = mDaemon->devicesList(); + m_daemon->acquireDiscoveryMode(QStringLiteral("plugintest")); + const QList devicesList = m_daemon->devicesList(); for (Device* id : devicesList) { if (id->isReachable()) { if (!id->isTrusted()) id->requestPair(); d = id; break; } } - mDaemon->releaseDiscoveryMode(QStringLiteral("plugintest")); + m_daemon->releaseDiscoveryMode(QStringLiteral("plugintest")); if (!d->loadedPlugins().contains(QStringLiteral("kdeconnect_remotecontrol"))) { QSKIP("kdeconnect_remotecontrol is required for this test"); } QVERIFY(d); QVERIFY(d->isTrusted()); QVERIFY(d->isReachable()); d->setPluginEnabled(QStringLiteral("kdeconnect_mousepad"), false); QCOMPARE(d->isPluginEnabled("kdeconnect_mousepad"), false); QVERIFY(d->supportedPlugins().contains("kdeconnect_remotecontrol")); d->setPluginEnabled(QStringLiteral("kdeconnect_mousepad"), true); QCOMPARE(d->isPluginEnabled("kdeconnect_mousepad"), true); QVERIFY(d->supportedPlugins().contains("kdeconnect_remotecontrol")); } private: - TestDaemon* mDaemon; + TestDaemon* m_daemon; }; QTEST_MAIN(PluginLoadTest); #include "pluginloadtest.moc" diff --git a/tests/sendfiletest.cpp b/tests/sendfiletest.cpp index 4d5063e7..4b2abf8e 100644 --- a/tests/sendfiletest.cpp +++ b/tests/sendfiletest.cpp @@ -1,149 +1,149 @@ /** * Copyright 2015 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 #include #include #include "core/daemon.h" #include "core/device.h" #include "core/kdeconnectplugin.h" #include #include "kdeconnect-version.h" #include "testdaemon.h" class TestSendFile : public QObject { Q_OBJECT public: TestSendFile() { QStandardPaths::setTestModeEnabled(true); - mDaemon = new TestDaemon; + m_daemon = new TestDaemon; } private Q_SLOTS: void testSend() { - mDaemon->acquireDiscoveryMode(QStringLiteral("test")); + m_daemon->acquireDiscoveryMode(QStringLiteral("test")); Device* d = nullptr; - const QList devicesList = mDaemon->devicesList(); + const QList devicesList = m_daemon->devicesList(); for (Device* id : devicesList) { if (id->isReachable()) { if (!id->isTrusted()) id->requestPair(); d = id; } } - mDaemon->releaseDiscoveryMode(QStringLiteral("test")); + m_daemon->releaseDiscoveryMode(QStringLiteral("test")); QVERIFY(d); QCOMPARE(d->isReachable(), true); QCOMPARE(d->isTrusted(), true); QByteArray content("12312312312313213123213123"); QTemporaryFile temp; temp.open(); temp.write(content); temp.close(); KdeConnectPlugin* plugin = d->plugin(QStringLiteral("kdeconnect_share")); QVERIFY(plugin); plugin->metaObject()->invokeMethod(plugin, "shareUrl", Q_ARG(QString, QUrl::fromLocalFile(temp.fileName()).toString())); QSignalSpy spy(plugin, SIGNAL(shareReceived(QUrl))); QVERIFY(spy.wait(2000)); QVariantList args = spy.takeFirst(); QUrl sentFile(args.first().toUrl()); QFile file(sentFile.toLocalFile()); QCOMPARE(file.size(), content.size()); QVERIFY(file.open(QIODevice::ReadOnly)); QCOMPARE(file.readAll(), content); } void testSslJobs() { const QString aFile = QFINDTESTDATA("sendfiletest.cpp"); const QString destFile = QDir::tempPath() + "/kdeconnect-test-sentfile"; QFile(destFile).remove(); const QString deviceId = KdeConnectConfig::instance()->deviceId() , deviceName = QStringLiteral("testdevice") , deviceType = KdeConnectConfig::instance()->deviceType(); KdeConnectConfig* kcc = KdeConnectConfig::instance(); kcc->addTrustedDevice(deviceId, deviceName, deviceType); kcc->setDeviceProperty(deviceId, QStringLiteral("certificate"), QString::fromLatin1(kcc->certificate().toPem())); // Using same certificate from kcc, instead of generating QSharedPointer f(new QFile(aFile)); UploadJob* uj = new UploadJob(f, deviceId); QSignalSpy spyUpload(uj, &KJob::result); uj->start(); auto info = uj->transferInfo(); info.insert(QStringLiteral("deviceId"), deviceId); info.insert(QStringLiteral("size"), aFile.size()); DownloadJob* dj = new DownloadJob(QHostAddress::LocalHost, info); QVERIFY(dj->getPayload()->open(QIODevice::ReadOnly)); FileTransferJob* ft = new FileTransferJob(dj->getPayload(), uj->transferInfo()[QStringLiteral("size")].toInt(), QUrl::fromLocalFile(destFile)); QSignalSpy spyDownload(dj, &KJob::result); QSignalSpy spyTransfer(ft, &KJob::result); ft->start(); dj->start(); QVERIFY(spyTransfer.count() || spyTransfer.wait(1000000000)); if (ft->error()) qWarning() << "fterror" << ft->errorString(); QCOMPARE(ft->error(), 0); QCOMPARE(spyDownload.count(), 1); QCOMPARE(spyUpload.count(), 1); QFile resultFile(destFile), originFile(aFile); QVERIFY(resultFile.open(QIODevice::ReadOnly)); QVERIFY(originFile.open(QIODevice::ReadOnly)); const QByteArray resultContents = resultFile.readAll(), originContents = originFile.readAll(); QCOMPARE(resultContents.size(), originContents.size()); QCOMPARE(resultFile.readAll(), originFile.readAll()); } private: - TestDaemon* mDaemon; + TestDaemon* m_daemon; }; QTEST_MAIN(TestSendFile); #include "sendfiletest.moc" diff --git a/tests/testnotificationlistener.cpp b/tests/testnotificationlistener.cpp index 8fa6e547..ad7443b3 100644 --- a/tests/testnotificationlistener.cpp +++ b/tests/testnotificationlistener.cpp @@ -1,502 +1,502 @@ /** * Copyright 2015 Holger Kaelberer * * 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 "core/daemon.h" #include "core/device.h" #include "core/kdeconnectplugin.h" #include "kdeconnect-version.h" #include "plugins/sendnotifications/sendnotificationsplugin.h" #include "plugins/sendnotifications/notificationslistener.h" #include "plugins/sendnotifications/notifyingapplication.h" // Tweaked NotificationsPlugin for testing class TestNotificationsPlugin : public SendNotificationsPlugin { Q_OBJECT public: - explicit TestNotificationsPlugin(QObject *parent, const QVariantList &args) + explicit TestNotificationsPlugin(QObject* parent, const QVariantList& args) : SendNotificationsPlugin(parent, args) { } ~TestNotificationsPlugin() override = default; // allow to access notificationsListener for testing: NotificationsListener* getNotificationsListener() const { return notificationsListener; } void setNotificationsListener(NotificationsListener* value) { notificationsListener = value; } }; // Tweaked Device for testing: class TestDevice: public Device { Q_OBJECT private: int sentPackages; - NetworkPackage *lastPackage; + NetworkPackage* lastPackage; public: explicit TestDevice(QObject* parent, const QString& id) : Device (parent, id) , sentPackages(0) , lastPackage(nullptr) {} ~TestDevice() override { delete lastPackage; } int getSentPackages() const { return sentPackages; } NetworkPackage* getLastPackage() { return lastPackage; } void deleteLastPackage() { delete lastPackage; lastPackage = nullptr; } public Q_SLOTS: bool sendPackage(NetworkPackage& np) override { ++sentPackages; // copy package manually to allow for inspection (can't use copy-constructor) deleteLastPackage(); lastPackage = new NetworkPackage(np.type()); Q_ASSERT(lastPackage); for (QVariantMap::ConstIterator iter = np.body().constBegin(); iter != np.body().constEnd(); iter++) lastPackage->set(iter.key(), iter.value()); lastPackage->setPayload(np.payload(), np.payloadSize()); return true; } }; // Tweaked NotificationsListener for testing: class TestedNotificationsListener: public NotificationsListener { Q_OBJECT public: explicit TestedNotificationsListener(KdeConnectPlugin* aPlugin) : NotificationsListener(aPlugin) {} ~TestedNotificationsListener() override {} QHash& getApplications() { - return applications; + return m_applications; } void setApplications(const QHash& value) { - applications = value; + m_applications = value; } protected: bool parseImageDataArgument(const QVariant& argument, int& width, int& height, int& rowStride, int& bitsPerSample, int& channels, bool& hasAlpha, QByteArray& imageData) const override { width = argument.toMap().value(QStringLiteral("width")).toInt(); height = argument.toMap().value(QStringLiteral("height")).toInt(); rowStride = argument.toMap().value(QStringLiteral("rowStride")).toInt(); bitsPerSample = argument.toMap().value(QStringLiteral("bitsPerSample")).toInt(); channels = argument.toMap().value(QStringLiteral("channels")).toInt(); hasAlpha = argument.toMap().value(QStringLiteral("hasAlpha")).toBool(); imageData = argument.toMap().value(QStringLiteral("imageData")).toByteArray(); return true; } }; class TestNotificationListener : public QObject { Q_OBJECT public: TestNotificationListener() : plugin(nullptr) { QStandardPaths::setTestModeEnabled(true); } private Q_SLOTS: void testNotify(); private: TestNotificationsPlugin* plugin; }; void TestNotificationListener::testNotify() { // // set things up: // QString dId(QStringLiteral("testid")); - TestDevice *d = new TestDevice(nullptr, dId); + TestDevice* d = new TestDevice(nullptr, dId); int proxiedNotifications = 0; QCOMPARE(proxiedNotifications, d->getSentPackages()); plugin = new TestNotificationsPlugin(this, QVariantList({ QVariant::fromValue(d), "notifications_plugin", {"kdeconnect.notification"}})); QVERIFY(plugin->getNotificationsListener()); delete plugin->getNotificationsListener(); // inject our tweaked NotificationsListener: TestedNotificationsListener* listener = new TestedNotificationsListener(plugin); QVERIFY(listener); plugin->setNotificationsListener(listener); QCOMPARE(listener, plugin->getNotificationsListener()); // make sure config is default: plugin->config()->set(QStringLiteral("generalPersistent"), false); plugin->config()->set(QStringLiteral("generalIncludeBody"), true); plugin->config()->set(QStringLiteral("generalUrgency"), 0); QCOMPARE(plugin->config()->get("generalPersistent"), false); QCOMPARE(plugin->config()->get("generalIncludeBody"), true); QCOMPARE(plugin->config()->get("generalUrgency"), false); // applications are modified directly: listener->getApplications().clear(); QCOMPARE(listener->getApplications().count(), 0); // // Go !!! // uint replacesId = 99; uint retId; QString appName(QStringLiteral("some-appName")); QString body(QStringLiteral("some-body")); QString icon(QStringLiteral("some-icon")); QString summary(QStringLiteral("some-summary")); // regular Notify call that is synchronized ... retId = listener->Notify(appName, replacesId, icon, summary, body, {}, {{}}, 0); // ... should return replacesId, QCOMPARE(retId, replacesId); // ... have triggered sending a package QCOMPARE(++proxiedNotifications, d->getSentPackages()); // ... with our properties, QCOMPARE(d->getLastPackage()->get("id"), replacesId); QCOMPARE(d->getLastPackage()->get("appName"), appName); QCOMPARE(d->getLastPackage()->get("ticker"), summary + ": " + body); QCOMPARE(d->getLastPackage()->get("isClearable"), true); QCOMPARE(d->getLastPackage()->hasPayload(), false); // ... and create a new application internally that is initialized correctly: QCOMPARE(listener->getApplications().count(), 1); QVERIFY(listener->getApplications().contains(appName)); QVERIFY(listener->getApplications()[appName].active); QCOMPARE(listener->getApplications()[appName].name, appName); QVERIFY(listener->getApplications()[appName].blacklistExpression.pattern().isEmpty()); QCOMPARE(listener->getApplications()[appName].name, appName); QCOMPARE(listener->getApplications()[appName].icon, icon); // another one, with other timeout and urgency values: QString appName2(QStringLiteral("some-appName2")); QString body2(QStringLiteral("some-body2")); QString icon2(QStringLiteral("some-icon2")); QString summary2(QStringLiteral("some-summary2")); retId = listener->Notify(appName2, replacesId+1, icon2, summary2, body2, {}, {{"urgency", 2}}, 10); QCOMPARE(retId, replacesId+1); QCOMPARE(++proxiedNotifications, d->getSentPackages()); QCOMPARE(d->getLastPackage()->get("id"), replacesId+1); QCOMPARE(d->getLastPackage()->get("appName"), appName2); QCOMPARE(d->getLastPackage()->get("ticker"), summary2 + ": " + body2); QCOMPARE(d->getLastPackage()->get("isClearable"), false); // timeout != 0 QCOMPARE(d->getLastPackage()->hasPayload(), false); QCOMPARE(listener->getApplications().count(), 2); QVERIFY(listener->getApplications().contains(appName2)); QVERIFY(listener->getApplications().contains(appName)); // if persistent-only is set, timeouts > 0 are not synced: plugin->config()->set(QStringLiteral("generalPersistent"), true); retId = listener->Notify(appName, replacesId, icon, summary, body, {}, {{}}, 1); QCOMPARE(retId, 0U); QCOMPARE(proxiedNotifications, d->getSentPackages()); retId = listener->Notify(appName2, replacesId, icon2, summary2, body2, {}, {{}}, 3); QCOMPARE(retId, 0U); QCOMPARE(proxiedNotifications, d->getSentPackages()); // but timeout == 0 is retId = listener->Notify(appName, replacesId, icon, summary, body, {}, {{}}, 0); QCOMPARE(retId, replacesId); QCOMPARE(++proxiedNotifications, d->getSentPackages()); plugin->config()->set(QStringLiteral("generalPersistent"), false); // if min-urgency is set, lower urgency levels are not synced: plugin->config()->set(QStringLiteral("generalUrgency"), 1); retId = listener->Notify(appName, replacesId, icon, summary, body, {}, {{"urgency", 0}}, 0); QCOMPARE(retId, 0U); QCOMPARE(proxiedNotifications, d->getSentPackages()); // equal urgency is retId = listener->Notify(appName, replacesId, icon, summary, body, {}, {{"urgency", 1}}, 0); QCOMPARE(retId, replacesId); QCOMPARE(++proxiedNotifications, d->getSentPackages()); // higher urgency as well retId = listener->Notify(appName, replacesId, icon, summary, body, {}, {{"urgency", 2}}, 0); QCOMPARE(retId, replacesId); QCOMPARE(++proxiedNotifications, d->getSentPackages()); plugin->config()->set(QStringLiteral("generalUrgency"), 0); // notifications for a deactivated application are not synced: QVERIFY(listener->getApplications().contains(appName)); listener->getApplications()[appName].active = false; QVERIFY(!listener->getApplications()[appName].active); retId = listener->Notify(appName, replacesId, icon, summary, body, {}, {{"urgency", 0}}, 0); QCOMPARE(retId, 0U); QCOMPARE(proxiedNotifications, d->getSentPackages()); // others are still: retId = listener->Notify(appName2, replacesId+1, icon2, summary2, body2, {}, {{}}, 0); QCOMPARE(retId, replacesId+1); QCOMPARE(++proxiedNotifications, d->getSentPackages()); // back to normal: listener->getApplications()[appName].active = true; QVERIFY(listener->getApplications()[appName].active); retId = listener->Notify(appName, replacesId, icon, summary, body, {}, {{}}, 0); QCOMPARE(retId, replacesId); QCOMPARE(++proxiedNotifications, d->getSentPackages()); // notifications with blacklisted subjects are not synced: QVERIFY(listener->getApplications().contains(appName)); listener->getApplications()[appName].blacklistExpression.setPattern(QStringLiteral("black[12]|foo(bar|baz)")); retId = listener->Notify(appName, replacesId, icon, QStringLiteral("summary black1"), body, {}, {{}}, 0); QCOMPARE(retId, 0U); QCOMPARE(proxiedNotifications, d->getSentPackages()); retId = listener->Notify(appName, replacesId, icon, QStringLiteral("summary foobar"), body, {}, {{}}, 0); QCOMPARE(retId, 0U); QCOMPARE(proxiedNotifications, d->getSentPackages()); // other subjects are synced: retId = listener->Notify(appName, replacesId, icon, QStringLiteral("summary foo"), body, {}, {{}}, 0); QCOMPARE(retId, replacesId); QCOMPARE(++proxiedNotifications, d->getSentPackages()); retId = listener->Notify(appName, replacesId, icon, QStringLiteral("summary black3"), body, {}, {{}}, 0); QCOMPARE(retId, replacesId); QCOMPARE(++proxiedNotifications, d->getSentPackages()); // also body is checked by blacklist if requested: plugin->config()->set(QStringLiteral("generalIncludeBody"), true); retId = listener->Notify(appName, replacesId, icon, summary, QStringLiteral("body black1"), {}, {{}}, 0); QCOMPARE(retId, 0U); QCOMPARE(proxiedNotifications, d->getSentPackages()); retId = listener->Notify(appName, replacesId, icon, summary, QStringLiteral("body foobaz"), {}, {{}}, 0); QCOMPARE(retId, 0U); QCOMPARE(proxiedNotifications, d->getSentPackages()); // body does not matter if inclusion was not requested: plugin->config()->set(QStringLiteral("generalIncludeBody"), false); retId = listener->Notify(appName, replacesId, icon, summary, QStringLiteral("body black1"), {}, {{}}, 0); QCOMPARE(retId, replacesId); QCOMPARE(++proxiedNotifications, d->getSentPackages()); // without body, also ticker value is different: QCOMPARE(d->getLastPackage()->get("ticker"), summary); retId = listener->Notify(appName, replacesId, icon, summary, QStringLiteral("body foobaz"), {}, {{}}, 0); QCOMPARE(retId, replacesId); QCOMPARE(++proxiedNotifications, d->getSentPackages()); // back to normal: listener->getApplications()[appName].blacklistExpression.setPattern(QLatin1String("")); plugin->config()->set(QStringLiteral("generalIncludeBody"), true); retId = listener->Notify(appName, replacesId, icon, summary, body, {}, {{}}, 0); QCOMPARE(retId, replacesId); QCOMPARE(++proxiedNotifications, d->getSentPackages()); retId = listener->Notify(appName2, replacesId, icon2, summary2, body2, {}, {{}}, 0); QCOMPARE(retId, replacesId); QCOMPARE(++proxiedNotifications, d->getSentPackages()); // icon synchronization: QStringList iconPaths; // appIcon int count = 0; const QStringList icons = KIconLoader::global()->queryIcons(-KIconLoader::SizeEnormous, KIconLoader::Application); for (const auto& iconName : icons) { if (!iconName.endsWith(QLatin1String(".png"))) continue; if (count++ > 3) // max 3 iterations break; iconPaths.append(iconName); // memorize some paths for later // existing icons are sync-ed if requested plugin->config()->set(QStringLiteral("generalSynchronizeIcons"), true); QFileInfo fi(iconName); retId = listener->Notify(appName, replacesId, fi.baseName(), summary, body, {}, {{}}, 0); QCOMPARE(retId, replacesId); QCOMPARE(++proxiedNotifications, d->getSentPackages()); QVERIFY(d->getLastPackage()->hasPayload()); QCOMPARE(d->getLastPackage()->payloadSize(), fi.size()); // works also with abolute paths retId = listener->Notify(appName, replacesId, iconName, summary, body, {}, {{}}, 0); QCOMPARE(retId, replacesId); QCOMPARE(++proxiedNotifications, d->getSentPackages()); QVERIFY(d->getLastPackage()->hasPayload()); QCOMPARE(d->getLastPackage()->payloadSize(), fi.size()); // extensions other than png are not accepted: retId = listener->Notify(appName, replacesId, iconName + ".svg", summary, body, {}, {{}}, 0); QCOMPARE(retId, replacesId); QCOMPARE(++proxiedNotifications, d->getSentPackages()); QVERIFY(!d->getLastPackage()->hasPayload()); // if sync not requested no payload: plugin->config()->set(QStringLiteral("generalSynchronizeIcons"), false); retId = listener->Notify(appName, replacesId, fi.baseName(), summary, body, {}, {{}}, 0); QCOMPARE(retId, replacesId); QCOMPARE(++proxiedNotifications, d->getSentPackages()); QVERIFY(!d->getLastPackage()->hasPayload()); QCOMPARE(d->getLastPackage()->payloadSize(), 0); } plugin->config()->set(QStringLiteral("generalSynchronizeIcons"), true); // image-path in hints if (iconPaths.size() > 0) { retId = listener->Notify(appName, replacesId, iconPaths.size() > 1 ? iconPaths[1] : icon, summary, body, {}, {{"image-path", iconPaths[0]}}, 0); QCOMPARE(retId, replacesId); QCOMPARE(++proxiedNotifications, d->getSentPackages()); QVERIFY(d->getLastPackage()->hasPayload()); QFileInfo hintsFi(iconPaths[0]); // image-path has priority over appIcon parameter: QCOMPARE(d->getLastPackage()->payloadSize(), hintsFi.size()); } // image_path in hints if (iconPaths.size() > 0) { retId = listener->Notify(appName, replacesId, iconPaths.size() > 1 ? iconPaths[1] : icon, summary, body, {}, {{"image_path", iconPaths[0]}}, 0); QCOMPARE(retId, replacesId); QCOMPARE(++proxiedNotifications, d->getSentPackages()); QVERIFY(d->getLastPackage()->hasPayload()); QFileInfo hintsFi(iconPaths[0]); // image_path has priority over appIcon parameter: QCOMPARE(d->getLastPackage()->payloadSize(), hintsFi.size()); } // image-data in hints // set up: - QBuffer *buffer; + QBuffer* buffer; QImage image; int width = 2, height = 2, rowStride = 4*width, bitsPerSample = 8, channels = 4; bool hasAlpha = 1; char rawData[] = { 0x01, 0x02, 0x03, 0x04, // raw rgba data 0x11, 0x12, 0x13, 0x14, 0x21, 0x22, 0x23, 0x24, 0x31, 0x32, 0x33, 0x34 }; QVariantMap imageData = {{"width", width}, {"height", height}, {"rowStride", rowStride}, {"bitsPerSample", bitsPerSample}, {"channels", channels}, {"hasAlpha", hasAlpha}, {"imageData", QByteArray(rawData, sizeof(rawData))}}; QVariantMap hints; #define COMPARE_PIXEL(x, y) \ QCOMPARE(qRed(image.pixel(x,y)), (int)rawData[x*4 + y*rowStride + 0]); \ QCOMPARE(qGreen(image.pixel(x,y)), (int)rawData[x*4 + y*rowStride + 1]); \ QCOMPARE(qBlue(image.pixel(x,y)), (int)rawData[x*4 + y*rowStride + 2]); \ QCOMPARE(qAlpha(image.pixel(x,y)), (int)rawData[x*4 + y*rowStride + 3]); hints.insert(QStringLiteral("image-data"), imageData); if (iconPaths.size() > 0) hints.insert(QStringLiteral("image-path"), iconPaths[0]); retId = listener->Notify(appName, replacesId, icon, summary, body, {}, hints, 0); QCOMPARE(retId, replacesId); QCOMPARE(++proxiedNotifications, d->getSentPackages()); QVERIFY(d->getLastPackage()->hasPayload()); buffer = dynamic_cast(d->getLastPackage()->payload().data()); QCOMPARE(d->getLastPackage()->payloadSize(), buffer->size()); // image-data is attached as png data QVERIFY(image.loadFromData(reinterpret_cast(buffer->data().constData()), buffer->size(), "PNG")); // image-data has priority over image-path: QCOMPARE(image.byteCount(), rowStride*height); // rgba -> argb conversion was done correctly: COMPARE_PIXEL(0,0); COMPARE_PIXEL(1,0); COMPARE_PIXEL(0,1); COMPARE_PIXEL(1,1); // same for image_data in hints hints.clear(); hints.insert(QStringLiteral("image-data"), imageData); if (iconPaths.size() > 0) hints.insert(QStringLiteral("image_path"), iconPaths[0]); retId = listener->Notify(appName, replacesId, icon, summary, body, {}, hints, 0); QCOMPARE(retId, replacesId); QCOMPARE(++proxiedNotifications, d->getSentPackages()); QVERIFY(d->getLastPackage()->hasPayload()); buffer = dynamic_cast(d->getLastPackage()->payload().data()); QCOMPARE(d->getLastPackage()->payloadSize(), buffer->size()); // image-data is attached as png data QVERIFY(image.loadFromData(reinterpret_cast(buffer->data().constData()), buffer->size(), "PNG")); // image_data has priority over image_path/image-path: QCOMPARE(image.byteCount(), rowStride*height); // rgba -> argb conversion was done correctly: COMPARE_PIXEL(0,0); COMPARE_PIXEL(1,0); COMPARE_PIXEL(0,1); COMPARE_PIXEL(1,1); // same for icon_data, which has lowest priority hints.clear(); hints.insert(QStringLiteral("icon_data"), imageData); retId = listener->Notify(appName, replacesId, QLatin1String(""), summary, body, {}, hints, 0); QCOMPARE(retId, replacesId); QCOMPARE(++proxiedNotifications, d->getSentPackages()); QVERIFY(d->getLastPackage()); QVERIFY(d->getLastPackage()->hasPayload()); buffer = dynamic_cast(d->getLastPackage()->payload().data()); // image-data is attached as png data QVERIFY(image.loadFromData(reinterpret_cast(buffer->data().constData()), buffer->size(), "PNG")); QCOMPARE(image.byteCount(), rowStride*height); // rgba -> argb conversion was done correctly: COMPARE_PIXEL(0,0); COMPARE_PIXEL(1,0); COMPARE_PIXEL(0,1); COMPARE_PIXEL(1,1); #undef COMPARE_PIXEL } QTEST_GUILESS_MAIN(TestNotificationListener); #include "testnotificationlistener.moc" diff --git a/tests/testsocketlinereader.cpp b/tests/testsocketlinereader.cpp index 828e5691..f027dd03 100644 --- a/tests/testsocketlinereader.cpp +++ b/tests/testsocketlinereader.cpp @@ -1,122 +1,122 @@ /************************************************************************************* * Copyright (C) 2014 by Alejandro Fiestas Olivares * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Lesser General Public * * License as published by the Free Software Foundation; either * * version 2.1 of the License, or (at your option) any later version. * * * * 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 * * Lesser General Public License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with this library; if not, write to the Free Software * * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *************************************************************************************/ #include "../core/backends/lan/socketlinereader.h" #include "../core/backends/lan/server.h" #include #include #include #include #include class TestSocketLineReader : public QObject { Q_OBJECT public Q_SLOTS: void initTestCase(); void newPackage(); private Q_SLOTS: void socketLineReader(); private: - QTimer mTimer; - QEventLoop mLoop; - QList mPackages; - Server *mServer; - QSslSocket *mConn; - SocketLineReader *mReader; + QTimer m_timer; + QEventLoop m_loop; + QList m_packages; + Server* m_server; + QSslSocket* m_conn; + SocketLineReader* m_reader; }; void TestSocketLineReader::initTestCase() { - mServer = new Server(this); + m_server = new Server(this); - QVERIFY2(mServer->listen(QHostAddress::LocalHost, 8694), "Failed to create local tcp server"); + QVERIFY2(m_server->listen(QHostAddress::LocalHost, 8694), "Failed to create local tcp server"); - mTimer.setInterval(4000);//For second is more enough to send some data via local socket - mTimer.setSingleShot(true); - connect(&mTimer, &QTimer::timeout, &mLoop, &QEventLoop::quit); + m_timer.setInterval(4000);//For second is more enough to send some data via local socket + m_timer.setSingleShot(true); + connect(&m_timer, &QTimer::timeout, &m_loop, &QEventLoop::quit); - mConn = new QSslSocket(this); - mConn->connectToHost(QHostAddress::LocalHost, 8694); - connect(mConn, &QAbstractSocket::connected, &mLoop, &QEventLoop::quit); - mTimer.start(); - mLoop.exec(); + m_conn = new QSslSocket(this); + m_conn->connectToHost(QHostAddress::LocalHost, 8694); + connect(m_conn, &QAbstractSocket::connected, &m_loop, &QEventLoop::quit); + m_timer.start(); + m_loop.exec(); - QVERIFY2(mConn->isOpen(), "Could not connect to local tcp server"); + QVERIFY2(m_conn->isOpen(), "Could not connect to local tcp server"); } void TestSocketLineReader::socketLineReader() { QList dataToSend; dataToSend << "foobar\n" << "barfoo\n" << "foobar?\n" << "\n" << "barfoo!\n" << "panda\n"; for (const QByteArray& line : dataToSend) { - mConn->write(line); + m_conn->write(line); } - mConn->flush(); + m_conn->flush(); int maxAttemps = 5; - while(!mServer->hasPendingConnections() && maxAttemps > 0) { + while(!m_server->hasPendingConnections() && maxAttemps > 0) { --maxAttemps; QTest::qSleep(1000); } - QSslSocket *sock = mServer->nextPendingConnection(); + QSslSocket* sock = m_server->nextPendingConnection(); QVERIFY2(sock != nullptr, "Could not open a connection to the client"); - mReader = new SocketLineReader(sock, this); - connect(mReader, &SocketLineReader::readyRead, this, &TestSocketLineReader::newPackage); - mTimer.start(); - mLoop.exec(); + m_reader = new SocketLineReader(sock, this); + connect(m_reader, &SocketLineReader::readyRead, this, &TestSocketLineReader::newPackage); + m_timer.start(); + m_loop.exec(); /* remove the empty line before compare */ dataToSend.removeOne("\n"); - QCOMPARE(mPackages.count(), 5);//We expect 5 Packages + QCOMPARE(m_packages.count(), 5);//We expect 5 Packages for(int x = 0;x < 5; ++x) { - QCOMPARE(mPackages[x], dataToSend[x]); + QCOMPARE(m_packages[x], dataToSend[x]); } } void TestSocketLineReader::newPackage() { - if (!mReader->bytesAvailable()) { + if (!m_reader->bytesAvailable()) { return; } int maxLoops = 5; - while(mReader->bytesAvailable() > 0 && maxLoops > 0) { + while(m_reader->bytesAvailable() > 0 && maxLoops > 0) { --maxLoops; - const QByteArray package = mReader->readLine(); + const QByteArray package = m_reader->readLine(); if (!package.isEmpty()) { - mPackages.append(package); + m_packages.append(package); } - if (mPackages.count() == 5) { - mLoop.exit(); + if (m_packages.count() == 5) { + m_loop.exit(); } } } QTEST_GUILESS_MAIN(TestSocketLineReader) #include "testsocketlinereader.moc" diff --git a/tests/testsslsocketlinereader.cpp b/tests/testsslsocketlinereader.cpp index 24a912cb..485cbd29 100644 --- a/tests/testsslsocketlinereader.cpp +++ b/tests/testsslsocketlinereader.cpp @@ -1,310 +1,310 @@ /** * Copyright 2015 Vineet Garg * * 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 "../core/backends/lan/server.h" #include "../core/backends/lan/socketlinereader.h" #include #include #include #include /* * This class tests the behaviour of socket line reader when the connection if over ssl. Since SSL takes part below application layer, * working of SocketLineReader should be same. */ class TestSslSocketLineReader : public QObject { Q_OBJECT public Q_SLOTS: void newPackage(); private Q_SLOTS: void initTestCase(); void init(); void cleanup(); void cleanupTestCase(); void testTrustedDevice(); void testUntrustedDevice(); void testTrustedDeviceWithWrongCertificate(); private: const int PORT = 7894; - QTimer mTimer; - QCA::Initializer mQcaInitializer; - QEventLoop mLoop; - QList mPackages; - Server *mServer; - QSslSocket *mClientSocket; - SocketLineReader *mReader; + QTimer m_timer; + QCA::Initializer m_qcaInitializer; + QEventLoop m_loop; + QList m_packages; + Server* m_server; + QSslSocket* m_clientSocket; + SocketLineReader* m_reader; private: void setSocketAttributes(QSslSocket* socket, QString deviceName); }; void TestSslSocketLineReader::initTestCase() { - mServer = new Server(this); + m_server = new Server(this); - QVERIFY2(mServer->listen(QHostAddress::LocalHost, PORT), "Failed to create local tcp server"); + QVERIFY2(m_server->listen(QHostAddress::LocalHost, PORT), "Failed to create local tcp server"); - mTimer.setInterval(10 * 1000);//Ten second is more enough for this test, just used this so that to break mLoop if stuck - mTimer.setSingleShot(true); - connect(&mTimer, &QTimer::timeout, &mLoop, &QEventLoop::quit); + m_timer.setInterval(10 * 1000);//Ten second is more enough for this test, just used this so that to break mLoop if stuck + m_timer.setSingleShot(true); + connect(&m_timer, &QTimer::timeout, &m_loop, &QEventLoop::quit); - mTimer.start(); + m_timer.start(); } void TestSslSocketLineReader::init() { - mClientSocket = new QSslSocket(this); - mClientSocket->connectToHost(QHostAddress::LocalHost, PORT); - connect(mClientSocket, &QAbstractSocket::connected, &mLoop, &QEventLoop::quit); + m_clientSocket = new QSslSocket(this); + m_clientSocket->connectToHost(QHostAddress::LocalHost, PORT); + connect(m_clientSocket, &QAbstractSocket::connected, &m_loop, &QEventLoop::quit); - mLoop.exec(); + m_loop.exec(); - QVERIFY2(mClientSocket->isOpen(), "Could not connect to local tcp server"); + QVERIFY2(m_clientSocket->isOpen(), "Could not connect to local tcp server"); } void TestSslSocketLineReader::cleanup() { - mClientSocket->disconnectFromHost(); - delete mClientSocket; + m_clientSocket->disconnectFromHost(); + delete m_clientSocket; } void TestSslSocketLineReader::cleanupTestCase() { - delete mServer; + delete m_server; } void TestSslSocketLineReader::testTrustedDevice() { int maxAttemps = 5; - QCOMPARE(true, mServer->hasPendingConnections()); - while(!mServer->hasPendingConnections() && maxAttemps > 0) { + QCOMPARE(true, m_server->hasPendingConnections()); + while(!m_server->hasPendingConnections() && maxAttemps > 0) { --maxAttemps; QTest::qSleep(1000); } - QSslSocket *serverSocket = mServer->nextPendingConnection(); + QSslSocket* serverSocket = m_server->nextPendingConnection(); QVERIFY2(serverSocket != 0, "Null socket returned by server"); QVERIFY2(serverSocket->isOpen(), "Server socket already closed"); setSocketAttributes(serverSocket, QStringLiteral("Test Server")); - setSocketAttributes(mClientSocket, QStringLiteral("Test Client")); + setSocketAttributes(m_clientSocket, QStringLiteral("Test Client")); serverSocket->setPeerVerifyName(QStringLiteral("Test Client")); serverSocket->setPeerVerifyMode(QSslSocket::VerifyPeer); - serverSocket->addCaCertificate(mClientSocket->localCertificate()); + serverSocket->addCaCertificate(m_clientSocket->localCertificate()); - mClientSocket->setPeerVerifyName(QStringLiteral("Test Server")); - mClientSocket->setPeerVerifyMode(QSslSocket::VerifyPeer); - mClientSocket->addCaCertificate(serverSocket->localCertificate()); + m_clientSocket->setPeerVerifyName(QStringLiteral("Test Server")); + m_clientSocket->setPeerVerifyMode(QSslSocket::VerifyPeer); + m_clientSocket->addCaCertificate(serverSocket->localCertificate()); - connect(mClientSocket, &QSslSocket::encrypted, &mLoop, &QEventLoop::quit); + connect(m_clientSocket, &QSslSocket::encrypted, &m_loop, &QEventLoop::quit); serverSocket->startServerEncryption(); - mClientSocket->startClientEncryption(); - mLoop.exec(); + m_clientSocket->startClientEncryption(); + m_loop.exec(); // Both client and server socket should be encrypted here and should have remote certificate because VerifyPeer is used - QVERIFY2(mClientSocket->isOpen(), "Client socket already closed"); + QVERIFY2(m_clientSocket->isOpen(), "Client socket already closed"); QVERIFY2(serverSocket->isOpen(), "Server socket already closed"); - QVERIFY2(mClientSocket->isEncrypted(), "Client is not encrypted"); + QVERIFY2(m_clientSocket->isEncrypted(), "Client is not encrypted"); QVERIFY2(serverSocket->isEncrypted(), "Server is not encrypted"); - QVERIFY2(!mClientSocket->peerCertificate().isNull(), "Server certificate not received"); + QVERIFY2(!m_clientSocket->peerCertificate().isNull(), "Server certificate not received"); QVERIFY2(!serverSocket->peerCertificate().isNull(), "Client certificate not received"); QList dataToSend; dataToSend << "foobar\n" << "barfoo\n" << "foobar?\n" << "\n" << "barfoo!\n" << "panda\n"; - for (const QByteArray &line : dataToSend) { - mClientSocket->write(line); + for (const QByteArray& line : dataToSend) { + m_clientSocket->write(line); } - mClientSocket->flush(); + m_clientSocket->flush(); - mPackages.clear(); + m_packages.clear(); - mReader = new SocketLineReader(serverSocket, this); - connect(mReader, &SocketLineReader::readyRead, this,&TestSslSocketLineReader::newPackage); - mLoop.exec(); + m_reader = new SocketLineReader(serverSocket, this); + connect(m_reader, &SocketLineReader::readyRead, this,&TestSslSocketLineReader::newPackage); + m_loop.exec(); /* remove the empty line before compare */ dataToSend.removeOne("\n"); - QCOMPARE(mPackages.count(), 5);//We expect 5 Packages + QCOMPARE(m_packages.count(), 5);//We expect 5 Packages for(int x = 0;x < 5; ++x) { - QCOMPARE(mPackages[x], dataToSend[x]); + QCOMPARE(m_packages[x], dataToSend[x]); } - delete mReader; + delete m_reader; } void TestSslSocketLineReader::testUntrustedDevice() { int maxAttemps = 5; - QCOMPARE(true, mServer->hasPendingConnections()); - while(!mServer->hasPendingConnections() && maxAttemps > 0) { + QCOMPARE(true, m_server->hasPendingConnections()); + while(!m_server->hasPendingConnections() && maxAttemps > 0) { --maxAttemps; QTest::qSleep(1000); } - QSslSocket *serverSocket = mServer->nextPendingConnection(); + QSslSocket* serverSocket = m_server->nextPendingConnection(); QVERIFY2(serverSocket != 0, "Null socket returned by server"); QVERIFY2(serverSocket->isOpen(), "Server socket already closed"); setSocketAttributes(serverSocket, QStringLiteral("Test Server")); - setSocketAttributes(mClientSocket, QStringLiteral("Test Client")); + setSocketAttributes(m_clientSocket, QStringLiteral("Test Client")); serverSocket->setPeerVerifyName(QStringLiteral("Test Client")); serverSocket->setPeerVerifyMode(QSslSocket::QueryPeer); - mClientSocket->setPeerVerifyName(QStringLiteral("Test Server")); - mClientSocket->setPeerVerifyMode(QSslSocket::QueryPeer); + m_clientSocket->setPeerVerifyName(QStringLiteral("Test Server")); + m_clientSocket->setPeerVerifyMode(QSslSocket::QueryPeer); - connect(mClientSocket, &QSslSocket::encrypted, &mLoop, &QEventLoop::quit); + connect(m_clientSocket, &QSslSocket::encrypted, &m_loop, &QEventLoop::quit); serverSocket->startServerEncryption(); - mClientSocket->startClientEncryption(); - mLoop.exec(); + m_clientSocket->startClientEncryption(); + m_loop.exec(); - QVERIFY2(mClientSocket->isOpen(), "Client socket already closed"); + QVERIFY2(m_clientSocket->isOpen(), "Client socket already closed"); QVERIFY2(serverSocket->isOpen(), "Server socket already closed"); - QVERIFY2(mClientSocket->isEncrypted(), "Client is not encrypted"); + QVERIFY2(m_clientSocket->isEncrypted(), "Client is not encrypted"); QVERIFY2(serverSocket->isEncrypted(), "Server is not encrypted"); - QVERIFY2(!mClientSocket->peerCertificate().isNull(), "Server certificate not received"); + QVERIFY2(!m_clientSocket->peerCertificate().isNull(), "Server certificate not received"); QVERIFY2(!serverSocket->peerCertificate().isNull(), "Client certificate not received"); QList dataToSend; dataToSend << "foobar\n" << "barfoo\n" << "foobar?\n" << "\n" << "barfoo!\n" << "panda\n"; - for (const QByteArray &line : dataToSend) { - mClientSocket->write(line); + for (const QByteArray& line : dataToSend) { + m_clientSocket->write(line); } - mClientSocket->flush(); + m_clientSocket->flush(); - mPackages.clear(); + m_packages.clear(); - mReader = new SocketLineReader(serverSocket, this); - connect(mReader, &SocketLineReader::readyRead, this, &TestSslSocketLineReader::newPackage); - mLoop.exec(); + m_reader = new SocketLineReader(serverSocket, this); + connect(m_reader, &SocketLineReader::readyRead, this, &TestSslSocketLineReader::newPackage); + m_loop.exec(); /* remove the empty line before compare */ dataToSend.removeOne("\n"); - QCOMPARE(mPackages.count(), 5);//We expect 5 Packages + QCOMPARE(m_packages.count(), 5);//We expect 5 Packages for(int x = 0;x < 5; ++x) { - QCOMPARE(mPackages[x], dataToSend[x]); + QCOMPARE(m_packages[x], dataToSend[x]); } - delete mReader; + delete m_reader; } void TestSslSocketLineReader::testTrustedDeviceWithWrongCertificate() { int maxAttemps = 5; - while(!mServer->hasPendingConnections() && maxAttemps > 0) { + while(!m_server->hasPendingConnections() && maxAttemps > 0) { --maxAttemps; QTest::qSleep(1000); } - QSslSocket *serverSocket = mServer->nextPendingConnection(); + QSslSocket* serverSocket = m_server->nextPendingConnection(); QVERIFY2(serverSocket != 0, "Could not open a connection to the client"); setSocketAttributes(serverSocket, QStringLiteral("Test Server")); - setSocketAttributes(mClientSocket, QStringLiteral("Test Client")); + setSocketAttributes(m_clientSocket, QStringLiteral("Test Client")); // Not adding other device certificate to list of CA certificate, and using VerifyPeer. This should lead to handshake failure serverSocket->setPeerVerifyName(QStringLiteral("Test Client")); serverSocket->setPeerVerifyMode(QSslSocket::VerifyPeer); - mClientSocket->setPeerVerifyName(QStringLiteral("Test Server")); - mClientSocket->setPeerVerifyMode(QSslSocket::VerifyPeer); + m_clientSocket->setPeerVerifyName(QStringLiteral("Test Server")); + m_clientSocket->setPeerVerifyMode(QSslSocket::VerifyPeer); - connect(serverSocket, &QSslSocket::encrypted, &mLoop, &QEventLoop::quit); // Encrypted signal should never be emitted - connect(mClientSocket, &QSslSocket::encrypted, &mLoop, &QEventLoop::quit); // Encrypted signal should never be emitted - connect(serverSocket, &QAbstractSocket::disconnected, &mLoop, &QEventLoop::quit); - connect(mClientSocket, &QAbstractSocket::disconnected, &mLoop, &QEventLoop::quit); + connect(serverSocket, &QSslSocket::encrypted, &m_loop, &QEventLoop::quit); // Encrypted signal should never be emitted + connect(m_clientSocket, &QSslSocket::encrypted, &m_loop, &QEventLoop::quit); // Encrypted signal should never be emitted + connect(serverSocket, &QAbstractSocket::disconnected, &m_loop, &QEventLoop::quit); + connect(m_clientSocket, &QAbstractSocket::disconnected, &m_loop, &QEventLoop::quit); serverSocket->startServerEncryption(); - mClientSocket->startClientEncryption(); - mLoop.exec(); + m_clientSocket->startClientEncryption(); + m_loop.exec(); QVERIFY2(!serverSocket->isEncrypted(), "Server is encrypted, it should not"); - QVERIFY2(!mClientSocket->isEncrypted(), "lient is encrypted, it should now"); + QVERIFY2(!m_clientSocket->isEncrypted(), "lient is encrypted, it should now"); - if (serverSocket->state() != QAbstractSocket::UnconnectedState) mLoop.exec(); // Wait until serverSocket is disconnected, It should be in disconnected state - if (mClientSocket->state() != QAbstractSocket::UnconnectedState) mLoop.exec(); // Wait until mClientSocket is disconnected, It should be in disconnected state + if (serverSocket->state() != QAbstractSocket::UnconnectedState) m_loop.exec(); // Wait until serverSocket is disconnected, It should be in disconnected state + if (m_clientSocket->state() != QAbstractSocket::UnconnectedState) m_loop.exec(); // Wait until mClientSocket is disconnected, It should be in disconnected state - QCOMPARE((int)mClientSocket->state(), 0); + QCOMPARE((int)m_clientSocket->state(), 0); QCOMPARE((int)serverSocket->state(), 0); } void TestSslSocketLineReader::newPackage() { - if (!mReader->bytesAvailable()) { + if (!m_reader->bytesAvailable()) { return; } int maxLoops = 5; - while(mReader->bytesAvailable() > 0 && maxLoops > 0) { + while(m_reader->bytesAvailable() > 0 && maxLoops > 0) { --maxLoops; - const QByteArray package = mReader->readLine(); + const QByteArray package = m_reader->readLine(); if (!package.isEmpty()) { - mPackages.append(package); + m_packages.append(package); } - if (mPackages.count() == 5) { - mLoop.exit(); + if (m_packages.count() == 5) { + m_loop.exit(); } } } -void TestSslSocketLineReader::setSocketAttributes(QSslSocket *socket, QString deviceName) { +void TestSslSocketLineReader::setSocketAttributes(QSslSocket* socket, QString deviceName) { QDateTime startTime = QDateTime::currentDateTime(); QDateTime endTime = startTime.addYears(10); QCA::CertificateInfo certificateInfo; certificateInfo.insert(QCA::CommonName,deviceName); certificateInfo.insert(QCA::Organization,QStringLiteral("KDE")); certificateInfo.insert(QCA::OrganizationalUnit,QStringLiteral("Kde connect")); QCA::CertificateOptions certificateOptions(QCA::PKCS10); certificateOptions.setSerialNumber(10); certificateOptions.setInfo(certificateInfo); certificateOptions.setValidityPeriod(startTime, endTime); certificateOptions.setFormat(QCA::PKCS10); QCA::PrivateKey privKey = QCA::KeyGenerator().createRSA(2048); QSslCertificate certificate = QSslCertificate(QCA::Certificate(certificateOptions, privKey).toPEM().toLatin1()); socket->setPrivateKey(QSslKey(privKey.toPEM().toLatin1(), QSsl::Rsa)); socket->setLocalCertificate(certificate); } QTEST_GUILESS_MAIN(TestSslSocketLineReader) #include "testsslsocketlinereader.moc" diff --git a/urlhandler/org.kde.kdeconnect.telhandler.desktop b/urlhandler/org.kde.kdeconnect.telhandler.desktop index 6b09937f..880edb97 100644 --- a/urlhandler/org.kde.kdeconnect.telhandler.desktop +++ b/urlhandler/org.kde.kdeconnect.telhandler.desktop @@ -1,29 +1,28 @@ [Desktop Entry] Name=KDE Connect Phone URL Handler Name[ca]=Gestor d'URL de telèfons del KDE Connect Name[ca@valencia]=Gestor d'URL de telèfons del KDE Connect Name[cs]=Nástroj pro práci s URL telefonu v KDE Connect Name[da]=Telefon-URL-håndtering til KDE Connect Name[es]=Controlador de URL de teléfonos de KDE Connect -Name[eu]=KDE Connect-en URL-kudeatzailea Name[fr]=Gestionnaire d'URL téléphoniques de KDE Connect Name[gl]=Manexador de URL de teléfono de KDE Connect Name[it]=Gestore URL del telefono di KDE Connect Name[nl]=URL behandelaar van KDE-Connect-telefoon Name[nn]=Telefon-URL-handsamar for KDE Connect Name[pl]=KDE Connect - obsługa URL telefonu Name[pt]=Tratamento de URL's Telefónicos do KDE Connect Name[sr]=КДЕ‑конекцијин руковалац телефонским УРЛ‑овима Name[sr@ijekavian]=КДЕ‑конекцијин руковалац телефонским УРЛ‑овима Name[sr@ijekavianlatin]=KDE‑konekcijin rukovalac telefonskim URL‑ovima Name[sr@latin]=KDE‑konekcijin rukovalac telefonskim URL‑ovima Name[sv]=KDE-anslut hanterare av telefonwebbadress Name[tr]=KDE Connect Telefon URL İşleyici Name[uk]=Обробник телефонних адрес KDE Connect Name[x-test]=xxKDE Connect Phone URL Handlerxx Exec=kdeconnect-handler %U Icon=kdeconnect Type=Application NoDisplay=true MimeType=x-scheme-handler/tel