diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6b5bffd7..d8e048fb 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -252,6 +252,7 @@ set(SRC_FILES
# Timeline
src/timeline/EventStore.cpp
+ src/timeline/InputBar.cpp
src/timeline/Reaction.cpp
src/timeline/TimelineViewManager.cpp
src/timeline/TimelineModel.cpp
@@ -463,6 +464,7 @@ qt5_wrap_cpp(MOC_HEADERS
# Timeline
src/timeline/EventStore.h
+ src/timeline/InputBar.h
src/timeline/Reaction.h
src/timeline/TimelineViewManager.h
src/timeline/TimelineModel.h
diff --git a/resources/qml/MessageInput.qml b/resources/qml/MessageInput.qml
index 71da9cae..3b424bb3 100644
--- a/resources/qml/MessageInput.qml
+++ b/resources/qml/MessageInput.qml
@@ -3,6 +3,8 @@ import QtQuick.Controls 2.3
import QtQuick.Layouts 1.2
import QtQuick.Window 2.2
+import im.nheko 1.0
+
Rectangle {
color: colors.window
Layout.fillWidth: true
@@ -44,16 +46,36 @@ Rectangle {
Layout.fillWidth: true
TextArea {
+ id: textArea
+
placeholderText: qsTr("Write a message...")
placeholderTextColor: colors.buttonText
color: colors.text
wrapMode: TextEdit.Wrap
+ onTextChanged: TimelineManager.timeline.input.updateState(selectionStart, selectionEnd, cursorPosition, text)
+ onCursorPositionChanged: TimelineManager.timeline.input.updateState(selectionStart, selectionEnd, cursorPosition, text)
+ onSelectionStartChanged: TimelineManager.timeline.input.updateState(selectionStart, selectionEnd, cursorPosition, text)
+ onSelectionEndChanged: TimelineManager.timeline.input.updateState(selectionStart, selectionEnd, cursorPosition, text)
+
+ Keys.onPressed: {
+ if (event.matches(StandardKey.Paste)) {
+ TimelineManager.timeline.input.paste(false) || textArea.paste()
+ event.accepted = true
+ }
+ else if (event.matches(StandardKey.InsertParagraphSeparator)) {
+ TimelineManager.timeline.input.send()
+ textArea.clear()
+ event.accepted = true
+ }
+ }
+
MouseArea {
// workaround for wrong cursor shape on some platforms
anchors.fill: parent
- acceptedButtons: Qt.NoButton
+ acceptedButtons: Qt.MiddleButton
cursorShape: Qt.IBeamCursor
+ onClicked: TimelineManager.timeline.input.paste(true) || textArea.paste()
}
background: Rectangle {
diff --git a/resources/qml/TimelineView.qml b/resources/qml/TimelineView.qml
index 95143b18..d85167af 100644
--- a/resources/qml/TimelineView.qml
+++ b/resources/qml/TimelineView.qml
@@ -234,8 +234,8 @@ Page {
ReplyPopup {
}
- //MessageInput {
- //}
+ MessageInput {
+ }
}
diff --git a/src/timeline/InputBar.cpp b/src/timeline/InputBar.cpp
new file mode 100644
index 00000000..d128631d
--- /dev/null
+++ b/src/timeline/InputBar.cpp
@@ -0,0 +1,46 @@
+#include "InputBar.h"
+
+#include <QClipboard>
+#include <QGuiApplication>
+#include <QMimeData>
+
+#include "Logging.h"
+
+bool
+InputBar::paste(bool fromMouse)
+{
+ const QMimeData *md = nullptr;
+
+ if (fromMouse) {
+ if (QGuiApplication::clipboard()->supportsSelection()) {
+ md = QGuiApplication::clipboard()->mimeData(QClipboard::Selection);
+ }
+ } else {
+ md = QGuiApplication::clipboard()->mimeData(QClipboard::Clipboard);
+ }
+
+ if (!md)
+ return false;
+
+ if (md->hasImage()) {
+ return true;
+ } else {
+ nhlog::ui()->debug("formats: {}", md->formats().join(", ").toStdString());
+ return false;
+ }
+}
+
+void
+InputBar::updateState(int selectionStart_, int selectionEnd_, int cursorPosition_, QString text_)
+{
+ selectionStart = selectionStart_;
+ selectionEnd = selectionEnd_;
+ cursorPosition = cursorPosition_;
+ text = text_;
+}
+
+void
+InputBar::send()
+{
+ nhlog::ui()->debug("Send: {}", text.toStdString());
+}
diff --git a/src/timeline/InputBar.h b/src/timeline/InputBar.h
new file mode 100644
index 00000000..78b06960
--- /dev/null
+++ b/src/timeline/InputBar.h
@@ -0,0 +1,25 @@
+#pragma once
+
+#include <QObject>
+
+class TimelineModel;
+
+class InputBar : public QObject {
+ Q_OBJECT
+
+public:
+ InputBar(TimelineModel *parent)
+ : QObject()
+ , room(parent)
+ {}
+
+public slots:
+ void send();
+ bool paste(bool fromMouse);
+ void updateState(int selectionStart, int selectionEnd, int cursorPosition, QString text);
+
+private:
+ TimelineModel *room;
+ QString text;
+ int selectionStart = 0, selectionEnd = 0, cursorPosition = 0;
+};
diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp
index 8b80ea51..aeb4e8f5 100644
--- a/src/timeline/TimelineModel.cpp
+++ b/src/timeline/TimelineModel.cpp
@@ -1567,3 +1567,4 @@ TimelineModel::roomTopic() const
return utils::replaceEmoji(utils::linkifyMessage(
utils::escapeBlacklistedHtml(QString::fromStdString(info[room_id_].topic))));
}
+
diff --git a/src/timeline/TimelineModel.h b/src/timeline/TimelineModel.h
index e1fb9196..58a1496c 100644
--- a/src/timeline/TimelineModel.h
+++ b/src/timeline/TimelineModel.h
@@ -10,6 +10,7 @@
#include "CacheCryptoStructs.h"
#include "EventStore.h"
+#include "InputBar.h"
#include "ui/UserProfile.h"
namespace mtx::http {
@@ -149,6 +150,7 @@ class TimelineModel : public QAbstractListModel
Q_PROPERTY(QString roomName READ roomName NOTIFY roomNameChanged)
Q_PROPERTY(QString roomAvatarUrl READ roomAvatarUrl NOTIFY roomAvatarUrlChanged)
Q_PROPERTY(QString roomTopic READ roomTopic NOTIFY roomTopicChanged)
+ Q_PROPERTY(InputBar *input READ input)
public:
explicit TimelineModel(TimelineViewManager *manager,
@@ -271,6 +273,7 @@ public slots:
QString roomName() const;
QString roomTopic() const;
+ InputBar *input() { return &input_; }
QString roomAvatarUrl() const;
QString roomId() const { return room_id_; }
@@ -320,6 +323,8 @@ private:
TimelineViewManager *manager_;
+ InputBar input_{this};
+
friend struct SendMessageVisitor;
};
|