Compare commits
1 commit
master
...
fix_copy_a
Author | SHA1 | Date | |
---|---|---|---|
|
caaac80ca5 |
5 changed files with 136 additions and 1 deletions
|
@ -5,8 +5,9 @@ target_link_libraries(kdeconnect_notifications
|
||||||
kdeconnectcore
|
kdeconnectcore
|
||||||
Qt::DBus
|
Qt::DBus
|
||||||
Qt::Widgets
|
Qt::Widgets
|
||||||
KF6::Notifications
|
KF6::GuiAddons
|
||||||
KF6::I18n
|
KF6::I18n
|
||||||
|
KF6::Notifications
|
||||||
KF6::WindowSystem
|
KF6::WindowSystem
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -11,11 +11,15 @@
|
||||||
#include <dbushelper.h>
|
#include <dbushelper.h>
|
||||||
|
|
||||||
#include <KPluginFactory>
|
#include <KPluginFactory>
|
||||||
|
#include <KSystemClipboard>
|
||||||
|
|
||||||
#if !defined(Q_OS_WIN) && !defined(Q_OS_MAC)
|
#if !defined(Q_OS_WIN) && !defined(Q_OS_MAC)
|
||||||
#include <KStartupInfo>
|
#include <KStartupInfo>
|
||||||
#include <private/qtx11extras_p.h>
|
#include <private/qtx11extras_p.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <QMimeData>
|
||||||
|
|
||||||
K_PLUGIN_CLASS_WITH_JSON(NotificationsPlugin, "kdeconnect_notifications.json")
|
K_PLUGIN_CLASS_WITH_JSON(NotificationsPlugin, "kdeconnect_notifications.json")
|
||||||
|
|
||||||
void NotificationsPlugin::connected()
|
void NotificationsPlugin::connected()
|
||||||
|
@ -175,6 +179,32 @@ void NotificationsPlugin::sendAction(const QString &key, const QString &action)
|
||||||
np.set<QString>(QStringLiteral("key"), key);
|
np.set<QString>(QStringLiteral("key"), key);
|
||||||
np.set<QString>(QStringLiteral("action"), action);
|
np.set<QString>(QStringLiteral("action"), action);
|
||||||
sendPacket(np);
|
sendPacket(np);
|
||||||
|
|
||||||
|
copyAuthCodeIfPresent(action);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationsPlugin::copyAuthCodeIfPresent(const QString &action)
|
||||||
|
{
|
||||||
|
// The auth code we receive has invisible characters in it for some reason.
|
||||||
|
// (U+2063 INVISIBLE SEPARATOR between each digit).
|
||||||
|
// Remove them if present before continuing.
|
||||||
|
QString sanitizedAction = action;
|
||||||
|
sanitizedAction.remove(QChar(0x2063));
|
||||||
|
|
||||||
|
// Match blocks of digits, 4-10 digits long. This should match auth codes
|
||||||
|
// in any language without relying on the action text having a specific
|
||||||
|
// keyword in it such as "Copy" in English.
|
||||||
|
QRegularExpression authCodeRegex(QStringLiteral("\\b(\\d{4,10})\\b"));
|
||||||
|
QRegularExpressionMatch match = authCodeRegex.match(sanitizedAction);
|
||||||
|
|
||||||
|
if (!match.hasMatch()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString text = match.captured(1);
|
||||||
|
auto mimeData = new QMimeData;
|
||||||
|
mimeData->setText(text);
|
||||||
|
KSystemClipboard::instance()->setMimeData(mimeData, QClipboard::Clipboard);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString NotificationsPlugin::newId()
|
QString NotificationsPlugin::newId()
|
||||||
|
|
|
@ -43,6 +43,14 @@ Q_SIGNALS:
|
||||||
Q_SCRIPTABLE void allNotificationsRemoved();
|
Q_SCRIPTABLE void allNotificationsRemoved();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
/**
|
||||||
|
* Check if the action is to copy an auth code, if so add the code to the desktop clipboard.
|
||||||
|
*
|
||||||
|
* This is necessary since access to the Android clipboard has become more restricted for apps
|
||||||
|
* that are not the foreground app since Android 10.
|
||||||
|
*/
|
||||||
|
void copyAuthCodeIfPresent(const QString &action);
|
||||||
|
|
||||||
void removeNotification(const QString &internalId);
|
void removeNotification(const QString &internalId);
|
||||||
QString newId(); // Generates successive identifiers to use as public ids
|
QString newId(); // Generates successive identifiers to use as public ids
|
||||||
void notificationReady();
|
void notificationReady();
|
||||||
|
|
|
@ -5,8 +5,10 @@ set(kdeconnect_libraries
|
||||||
kdeconnectinterfaces
|
kdeconnectinterfaces
|
||||||
kdeconnectsmshelper
|
kdeconnectsmshelper
|
||||||
kdeconnectversion
|
kdeconnectversion
|
||||||
|
KF6::GuiAddons
|
||||||
KF6::I18n
|
KF6::I18n
|
||||||
KF6::KIOWidgets
|
KF6::KIOWidgets
|
||||||
|
KF6::Notifications
|
||||||
Qt::DBus
|
Qt::DBus
|
||||||
Qt::Network
|
Qt::Network
|
||||||
KF6::People
|
KF6::People
|
||||||
|
@ -14,6 +16,7 @@ set(kdeconnect_libraries
|
||||||
Qt::Test
|
Qt::Test
|
||||||
)
|
)
|
||||||
|
|
||||||
|
ecm_add_test(notificationstest.cpp LINK_LIBRARIES ${kdeconnect_libraries})
|
||||||
ecm_add_test(pluginloadtest.cpp LINK_LIBRARIES ${kdeconnect_libraries})
|
ecm_add_test(pluginloadtest.cpp LINK_LIBRARIES ${kdeconnect_libraries})
|
||||||
ecm_add_test(sendfiletest.cpp LINK_LIBRARIES ${kdeconnect_libraries})
|
ecm_add_test(sendfiletest.cpp LINK_LIBRARIES ${kdeconnect_libraries})
|
||||||
ecm_add_test(smshelpertest.cpp LINK_LIBRARIES ${kdeconnect_libraries})
|
ecm_add_test(smshelpertest.cpp LINK_LIBRARIES ${kdeconnect_libraries})
|
||||||
|
|
93
tests/notificationstest.cpp
Normal file
93
tests/notificationstest.cpp
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
/**
|
||||||
|
* SPDX-FileCopyrightText: 2024 Kristen McWilliam <kmcwilliampublic@gmail.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "kdeconnectplugin.h"
|
||||||
|
#include "testdaemon.h"
|
||||||
|
|
||||||
|
#include <KSystemClipboard>
|
||||||
|
|
||||||
|
#include <QtTest>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test the NotificationsPlugin class
|
||||||
|
*/
|
||||||
|
class NotificationsPluginTest : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
NotificationsPluginTest()
|
||||||
|
{
|
||||||
|
QStandardPaths::setTestModeEnabled(true);
|
||||||
|
m_daemon = new TestDaemon;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
TestDaemon *m_daemon;
|
||||||
|
|
||||||
|
private Q_SLOTS:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the user selects the action to copy an auth code, the auth code should
|
||||||
|
* be copied to the desktop clipboard.
|
||||||
|
*/
|
||||||
|
void testAuthCodeIsCopied()
|
||||||
|
{
|
||||||
|
Device *device = nullptr;
|
||||||
|
const QList<Device *> devicesList = m_daemon->devicesList();
|
||||||
|
|
||||||
|
for (Device *id : devicesList) {
|
||||||
|
if (id->isReachable()) {
|
||||||
|
if (!id->isPaired())
|
||||||
|
id->requestPairing();
|
||||||
|
device = id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (device == nullptr) {
|
||||||
|
QFAIL("Unable to determine device");
|
||||||
|
}
|
||||||
|
|
||||||
|
QCOMPARE(device->isReachable(), true);
|
||||||
|
QCOMPARE(device->isPaired(), true);
|
||||||
|
|
||||||
|
KdeConnectPlugin *plugin = device->plugin(QStringLiteral("kdeconnect_notifications"));
|
||||||
|
QVERIFY(plugin);
|
||||||
|
|
||||||
|
const QString key = QStringLiteral("0|com.google.android.apps.messaging|2|com.google.android.apps.messaging:incoming_message:23|10129");
|
||||||
|
|
||||||
|
// Note that the auth code we receive to work with has invisible
|
||||||
|
// characters in it for some reason. (U+2063 INVISIBLE SEPARATOR between
|
||||||
|
// each digit)
|
||||||
|
//
|
||||||
|
// `action` here is equal to `Copy \"671733\"`, but with the invisible
|
||||||
|
// characters written out explicitly to make it easier to read, and to
|
||||||
|
// prevent confusion when reading the test code.
|
||||||
|
const QString action = QStringLiteral("Copy \"6\u20637\u20631\u20637\u20633\u20633\"");
|
||||||
|
|
||||||
|
const QString expectedClipboardContents = QStringLiteral("671733");
|
||||||
|
|
||||||
|
// Verify that the clipboard does not contain the auth code already
|
||||||
|
const QString originalClipboardContents = KSystemClipboard::instance()->text(QClipboard::Clipboard);
|
||||||
|
QVERIFY(originalClipboardContents != expectedClipboardContents);
|
||||||
|
|
||||||
|
// Send the action
|
||||||
|
plugin->metaObject()->invokeMethod(plugin, "sendAction", Q_ARG(QString, key), Q_ARG(QString, action));
|
||||||
|
|
||||||
|
// Verify that the clipboard now contains the auth code
|
||||||
|
const QString updatedClipboardContents = KSystemClipboard::instance()->text(QClipboard::Clipboard);
|
||||||
|
QCOMPARE(updatedClipboardContents, expectedClipboardContents);
|
||||||
|
|
||||||
|
// Set the clipboard back to its original state
|
||||||
|
auto mimeData = new QMimeData;
|
||||||
|
mimeData->setText(originalClipboardContents);
|
||||||
|
KSystemClipboard::instance()->setMimeData(mimeData, QClipboard::Clipboard);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
QTEST_MAIN(NotificationsPluginTest);
|
||||||
|
|
||||||
|
#include "notificationstest.moc"
|
Loading…
Reference in a new issue