From 8c8a9976a5c87008691b02db823ce7c4e270cf0c Mon Sep 17 00:00:00 2001 From: Carl Schwan Date: Sat, 7 Nov 2020 11:30:15 +0100 Subject: [PATCH] Transform Clipboard to singleton and add rich text copying feature --- qml/ChatTextInput.qml | 2 +- qml/RoomPage.qml | 9 +++----- src/CMakeLists.txt | 2 +- src/{imageclipboard.cpp => clipboard.cpp} | 26 +++++++++++++++++------ src/{imageclipboard.h => clipboard.h} | 19 ++++++++++------- src/main.cpp | 6 ++++-- 6 files changed, 39 insertions(+), 25 deletions(-) rename src/{imageclipboard.cpp => clipboard.cpp} (51%) rename src/{imageclipboard.h => clipboard.h} (68%) diff --git a/qml/ChatTextInput.qml b/qml/ChatTextInput.qml index b50a49a42..8fe756670 100644 --- a/qml/ChatTextInput.qml +++ b/qml/ChatTextInput.qml @@ -209,7 +209,7 @@ Control { icon.name: "mail-attachment" onClicked: { - if (imageClipboard.hasImage) { + if (Clipboard.hasImage) { attachDialog.open() } else { var fileDialog = openFileDialog.createObject(ApplicationWindow.overlay) diff --git a/qml/RoomPage.qml b/qml/RoomPage.qml index 36d0b3d14..d1c48e3f7 100644 --- a/qml/RoomPage.qml +++ b/qml/RoomPage.qml @@ -5,13 +5,14 @@ import Qt.labs.qmlmodels 1.0 import QtQuick.Controls.Material 2.12 import org.kde.kirigami 2.4 as Kirigami - import org.kde.kitemmodels 1.0 +import org.kde.neochat 1.0 import Spectral.Component 2.0 import Spectral.Component.Timeline 2.0 import Spectral.Dialog 2.0 import Spectral.Effect 2.0 +import Spectral.Menu.Timeline 2.0 import Spectral 0.1 Kirigami.ScrollablePage { @@ -27,10 +28,6 @@ Kirigami.ScrollablePage { room: currentRoom } - ImageClipboard { - id: imageClipboard - } - QQC2.Popup { anchors.centerIn: parent @@ -74,7 +71,7 @@ Kirigami.ScrollablePage { text: i18n("Clipboard image") onClicked: { var localPath = StandardPaths.writableLocation(StandardPaths.CacheLocation) + "/screenshots/" + (new Date()).getTime() + ".png" - if (!imageClipboard.saveImage(localPath)) return + if (!Clipboard.saveImage(localPath)) return chatTextInput.attach(localPath) attachDialog.close() } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index eb693b5de..69b2fc7e3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -2,7 +2,7 @@ add_executable(neochat accountlistmodel.cpp controller.cpp emojimodel.cpp - imageclipboard.cpp + clipboard.cpp matriximageprovider.cpp messageeventmodel.cpp roomlistmodel.cpp diff --git a/src/imageclipboard.cpp b/src/clipboard.cpp similarity index 51% rename from src/imageclipboard.cpp rename to src/clipboard.cpp index 75a7e35c3..a4f0c09e0 100644 --- a/src/imageclipboard.cpp +++ b/src/clipboard.cpp @@ -3,32 +3,35 @@ * * SPDX-LicenseIdentifier: GPL-3.0-only */ -#include "imageclipboard.h" +#include "clipboard.h" -#include +#include +#include +#include +#include #include #include #include #include -ImageClipboard::ImageClipboard(QObject *parent) +Clipboard::Clipboard(QObject *parent) : QObject(parent) , m_clipboard(QGuiApplication::clipboard()) { - connect(m_clipboard, &QClipboard::changed, this, &ImageClipboard::imageChanged); + connect(m_clipboard, &QClipboard::changed, this, &Clipboard::imageChanged); } -bool ImageClipboard::hasImage() const +bool Clipboard::hasImage() const { return !image().isNull(); } -QImage ImageClipboard::image() const +QImage Clipboard::image() const { return m_clipboard->image(); } -bool ImageClipboard::saveImage(const QUrl &localPath) +bool Clipboard::saveImage(const QUrl &localPath) { if (!localPath.isLocalFile()) return false; @@ -48,3 +51,12 @@ bool ImageClipboard::saveImage(const QUrl &localPath) return true; } + +void Clipboard::saveText(QString message) +{ + QRegularExpression re("<[^>]*>"); + auto *mineData = new QMimeData; // ownership is transfered to clipboard + mineData->setHtml(message); + mineData->setText(message.replace(re, "")); + m_clipboard->setMimeData(mineData); +} diff --git a/src/imageclipboard.h b/src/clipboard.h similarity index 68% rename from src/imageclipboard.h rename to src/clipboard.h index 87f8532d0..f11f2492d 100644 --- a/src/imageclipboard.h +++ b/src/clipboard.h @@ -3,32 +3,35 @@ * * SPDX-LicenseIdentifier: GPL-3.0-only */ -#ifndef IMAGECLIPBOARD_H -#define IMAGECLIPBOARD_H +#pragma once -#include -#include #include -class ImageClipboard : public QObject +class QClipboard; +class QImage; + +/** + * Clipboard proxy + */ +class Clipboard : public QObject { Q_OBJECT Q_PROPERTY(bool hasImage READ hasImage NOTIFY imageChanged) Q_PROPERTY(QImage image READ image NOTIFY imageChanged) public: - explicit ImageClipboard(QObject *parent = nullptr); + explicit Clipboard(QObject *parent = nullptr); bool hasImage() const; QImage image() const; Q_INVOKABLE bool saveImage(const QUrl &localPath); + Q_INVOKABLE void saveText(QString message); + private: QClipboard *m_clipboard; Q_SIGNALS: void imageChanged(); }; - -#endif // IMAGECLIPBOARD_H diff --git a/src/main.cpp b/src/main.cpp index 57665b97f..2c37e234b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -23,7 +23,7 @@ #include "csapi/joining.h" #include "csapi/leaving.h" #include "emojimodel.h" -#include "imageclipboard.h" +#include "clipboard.h" #include "matriximageprovider.h" #include "messageeventmodel.h" #include "notificationsmanager.h" @@ -57,7 +57,10 @@ int main(int argc, char *argv[]) app.setOrganizationName("KDE"); app.setWindowIcon(QIcon(":/assets/img/icon.png")); + Clipboard clipboard; + qmlRegisterSingletonInstance("Spectral", 0, 1, "Controller", &Controller::instance()); + qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "Clipboard", &clipboard); qmlRegisterType("Spectral", 0, 1, "AccountListModel"); qmlRegisterType("Spectral", 0, 1, "RoomListModel"); qmlRegisterType("Spectral", 0, 1, "UserListModel"); @@ -67,7 +70,6 @@ int main(int argc, char *argv[]) qmlRegisterType("Spectral", 0, 1, "EmojiModel"); qmlRegisterType("Spectral", 0, 1, "NotificationsManager"); qmlRegisterType("Spectral", 0, 1, "TrayIcon"); - qmlRegisterType("Spectral", 0, 1, "ImageClipboard"); qmlRegisterUncreatableType("Spectral", 0, 1, "RoomMessageEvent", "ENUM"); qmlRegisterUncreatableType("Spectral", 0, 1, "RoomType", "ENUM"); qmlRegisterUncreatableType("Spectral", 0, 1, "UserType", "ENUM");