From c74077a41f5e89c0331d682b481408ad22d7ec78 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Wed, 25 Nov 2020 17:02:23 +0100 Subject: [PATCH] Implement Qml drag and drop --- CMakeLists.txt | 12 +++++---- resources/qml/MessageInput.qml | 5 ++++ src/ChatPage.h | 1 + src/timeline/InputBar.cpp | 8 ++++++ src/timeline/InputBar.h | 2 ++ src/timeline/TimelineViewManager.cpp | 3 +++ src/timeline/TimelineViewManager.h | 9 +++++++ src/ui/NhekoDropArea.cpp | 39 ++++++++++++++++++++++++++++ src/ui/NhekoDropArea.h | 30 +++++++++++++++++++++ 9 files changed, 104 insertions(+), 5 deletions(-) create mode 100644 src/ui/NhekoDropArea.cpp create mode 100644 src/ui/NhekoDropArea.h diff --git a/CMakeLists.txt b/CMakeLists.txt index bd42938a..e8570c77 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -257,22 +257,23 @@ set(SRC_FILES src/ui/Avatar.cpp src/ui/Badge.cpp src/ui/DropShadow.cpp - src/ui/LoadingIndicator.cpp - src/ui/InfoMessage.cpp src/ui/FlatButton.cpp src/ui/FloatingButton.cpp + src/ui/InfoMessage.cpp src/ui/Label.cpp + src/ui/LoadingIndicator.cpp + src/ui/NhekoDropArea.cpp src/ui/OverlayModal.cpp - src/ui/SnackBar.cpp + src/ui/OverlayWidget.cpp src/ui/RaisedButton.cpp src/ui/Ripple.cpp src/ui/RippleOverlay.cpp - src/ui/OverlayWidget.cpp + src/ui/SnackBar.cpp src/ui/TextField.cpp src/ui/TextLabel.cpp - src/ui/ToggleButton.cpp src/ui/Theme.cpp src/ui/ThemeManager.cpp + src/ui/ToggleButton.cpp src/ui/UserProfile.cpp src/AvatarProvider.cpp @@ -471,6 +472,7 @@ qt5_wrap_cpp(MOC_HEADERS src/ui/Label.h src/ui/FloatingButton.h src/ui/Menu.h + src/ui/NhekoDropArea.h src/ui/OverlayWidget.h src/ui/SnackBar.h src/ui/RaisedButton.h diff --git a/resources/qml/MessageInput.qml b/resources/qml/MessageInput.qml index 76eac5b3..812c450e 100644 --- a/resources/qml/MessageInput.qml +++ b/resources/qml/MessageInput.qml @@ -178,6 +178,11 @@ Rectangle { onClicked: TimelineManager.timeline.input.paste(true) } + NhekoDropArea { + anchors.fill: parent + roomid: TimelineManager.timeline.roomId() + } + background: Rectangle { color: colors.window } diff --git a/src/ChatPage.h b/src/ChatPage.h index 273ba4af..5b336cbb 100644 --- a/src/ChatPage.h +++ b/src/ChatPage.h @@ -88,6 +88,7 @@ public: QSharedPointer userSettings() { return userSettings_; } CallManager *callManager() { return callManager_; } + TimelineViewManager *timelineManager() { return view_manager_; } void deleteConfigs(); CommunitiesList *communitiesList() { return communitiesList_; } diff --git a/src/timeline/InputBar.cpp b/src/timeline/InputBar.cpp index b0d555b7..46bbd9a2 100644 --- a/src/timeline/InputBar.cpp +++ b/src/timeline/InputBar.cpp @@ -1,6 +1,7 @@ #include "InputBar.h" #include +#include #include #include #include @@ -44,6 +45,13 @@ InputBar::paste(bool fromMouse) md = QGuiApplication::clipboard()->mimeData(QClipboard::Clipboard); } + if (md) + insertMimeData(md); +} + +void +InputBar::insertMimeData(const QMimeData *md) +{ if (!md) return; diff --git a/src/timeline/InputBar.h b/src/timeline/InputBar.h index 939e8dad..27aa4bc3 100644 --- a/src/timeline/InputBar.h +++ b/src/timeline/InputBar.h @@ -9,6 +9,7 @@ class TimelineModel; class QMimeData; +class QDropEvent; class QStringList; class InputBar : public QObject @@ -36,6 +37,7 @@ public slots: void send(); void paste(bool fromMouse); + void insertMimeData(const QMimeData *data); void updateState(int selectionStart, int selectionEnd, int cursorPosition, QString text); void openFileSelection(); bool uploading() const { return uploading_; } diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp index 1392c505..866e7c51 100644 --- a/src/timeline/TimelineViewManager.cpp +++ b/src/timeline/TimelineViewManager.cpp @@ -1,6 +1,7 @@ #include "TimelineViewManager.h" #include +#include #include #include #include @@ -20,6 +21,7 @@ #include "dialogs/ImageOverlay.h" #include "emoji/EmojiModel.h" #include "emoji/Provider.h" +#include "ui/NhekoDropArea.h" #include //only for debugging @@ -115,6 +117,7 @@ TimelineViewManager::TimelineViewManager(CallManager *callManager, ChatPage *par qmlRegisterType("im.nheko", 1, 0, "DelegateChoice"); qmlRegisterType("im.nheko", 1, 0, "DelegateChooser"); + qmlRegisterType("im.nheko", 1, 0, "NhekoDropArea"); qmlRegisterUncreatableType( "im.nheko", 1, 0, "DeviceVerificationFlow", "Can't create verification flow from QML!"); qmlRegisterUncreatableType( diff --git a/src/timeline/TimelineViewManager.h b/src/timeline/TimelineViewManager.h index 371e9af2..b9febf75 100644 --- a/src/timeline/TimelineViewManager.h +++ b/src/timeline/TimelineViewManager.h @@ -105,6 +105,15 @@ public slots: void initWithMessages(const std::vector &roomIds); void setHistoryView(const QString &room_id); + TimelineModel *getHistoryView(const QString &room_id) + { + auto room = models.find(room_id); + if (room != models.end()) + return room.value().data(); + else + return nullptr; + } + void updateColorPalette(); void queueReactionMessage(const QString &reactedEvent, const QString &reactionKey); void queueCallMessage(const QString &roomid, const mtx::events::msg::CallInvite &); diff --git a/src/ui/NhekoDropArea.cpp b/src/ui/NhekoDropArea.cpp new file mode 100644 index 00000000..14b71524 --- /dev/null +++ b/src/ui/NhekoDropArea.cpp @@ -0,0 +1,39 @@ +#include "NhekoDropArea.h" + +#include + +#include "ChatPage.h" +#include "timeline/InputBar.h" +#include "timeline/TimelineModel.h" +#include "timeline/TimelineViewManager.h" + +#include "Logging.h" + +NhekoDropArea::NhekoDropArea(QQuickItem *parent) + : QQuickItem(parent) +{ + setFlags(ItemAcceptsDrops); +} + +void +NhekoDropArea::dragEnterEvent(QDragEnterEvent *event) +{ + event->acceptProposedAction(); +} + +void +NhekoDropArea::dragMoveEvent(QDragMoveEvent *event) +{ + event->acceptProposedAction(); +} + +void +NhekoDropArea::dropEvent(QDropEvent *event) +{ + if (event) { + auto model = ChatPage::instance()->timelineManager()->getHistoryView(roomid_); + if (model) { + model->input()->insertMimeData(event->mimeData()); + } + } +} diff --git a/src/ui/NhekoDropArea.h b/src/ui/NhekoDropArea.h new file mode 100644 index 00000000..b03620f2 --- /dev/null +++ b/src/ui/NhekoDropArea.h @@ -0,0 +1,30 @@ +#include + +class NhekoDropArea : public QQuickItem +{ + Q_OBJECT + Q_PROPERTY(QString roomid READ roomid WRITE setRoomid NOTIFY roomidChanged) +public: + NhekoDropArea(QQuickItem *parent = nullptr); + +signals: + void roomidChanged(QString roomid); + +public slots: + void setRoomid(QString roomid) + { + if (roomid_ != roomid) { + roomid_ = roomid; + emit roomidChanged(roomid); + } + } + QString roomid() const { return roomid_; } + +protected: + void dragEnterEvent(QDragEnterEvent *event) override; + void dragMoveEvent(QDragMoveEvent *event) override; + void dropEvent(QDropEvent *event) override; + +private: + QString roomid_; +};