Use Quotient qml module
This commit is contained in:
@@ -23,12 +23,10 @@ ecm_add_qml_module(Timeline GENERATE_PLUGIN_SOURCE
|
||||
TypingPane.qml
|
||||
DelegateContextMenu.qml
|
||||
SOURCES
|
||||
messageattached.cpp
|
||||
messagedelegate.cpp
|
||||
timelinedelegate.cpp
|
||||
enums/delegatetype.h
|
||||
models/mediamessagefiltermodel.cpp
|
||||
models/messagecontentfiltermodel.cpp
|
||||
models/messagefiltermodel.cpp
|
||||
models/messagemodel.cpp
|
||||
models/pinnedmessagemodel.cpp
|
||||
@@ -39,6 +37,8 @@ ecm_add_qml_module(Timeline GENERATE_PLUGIN_SOURCE
|
||||
models/webshortcutmodel.cpp
|
||||
DEPENDENCIES
|
||||
QtQuick
|
||||
org.kde.neochat.libneochat
|
||||
io.github.quotient_im.libquotient
|
||||
)
|
||||
|
||||
target_include_directories(Timeline PRIVATE ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/enums ${CMAKE_CURRENT_SOURCE_DIR}/models)
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
// SPDX-FileCopyrightText: 2020 Black Hat <bhat@encom.eu.org>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Controls as QQC2
|
||||
import QtQuick.Layouts
|
||||
import Qt.labs.qmlmodels
|
||||
|
||||
import org.kde.kirigami as Kirigami
|
||||
import org.kde.kirigamiaddons.components as KirigamiComponents
|
||||
|
||||
import org.kde.neochat
|
||||
import org.kde.neochat.libneochat as LibNeoChat
|
||||
|
||||
/**
|
||||
* @brief The base delegate for all messages in the timeline.
|
||||
|
||||
@@ -1,210 +0,0 @@
|
||||
// SPDX-FileCopyrightText: 2025 James Graham <james.h.graham@protonmail.com>
|
||||
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||
|
||||
#include "messageattached.h"
|
||||
|
||||
MessageAttached::MessageAttached(QObject *parent)
|
||||
: QQuickAttachedPropertyPropagator(parent)
|
||||
{
|
||||
if (parent == nullptr) {
|
||||
qWarning() << "Message must be attached to an Item" << parent;
|
||||
return;
|
||||
}
|
||||
initialize();
|
||||
}
|
||||
|
||||
MessageAttached *MessageAttached::qmlAttachedProperties(QObject *object)
|
||||
{
|
||||
return new MessageAttached(object);
|
||||
}
|
||||
|
||||
NeoChatRoom *MessageAttached::room() const
|
||||
{
|
||||
return m_room;
|
||||
}
|
||||
|
||||
void MessageAttached::setRoom(NeoChatRoom *room)
|
||||
{
|
||||
m_explicitRoom = true;
|
||||
if (m_room == room) {
|
||||
return;
|
||||
}
|
||||
m_room = room;
|
||||
propagateMessage(this);
|
||||
Q_EMIT roomChanged();
|
||||
}
|
||||
|
||||
QQuickItem *MessageAttached::timeline() const
|
||||
{
|
||||
return m_timeline;
|
||||
}
|
||||
|
||||
void MessageAttached::setTimeline(QQuickItem *timeline)
|
||||
{
|
||||
m_explicitTimeline = true;
|
||||
if (m_timeline == timeline) {
|
||||
return;
|
||||
}
|
||||
m_timeline = timeline;
|
||||
propagateMessage(this);
|
||||
Q_EMIT timelineChanged();
|
||||
}
|
||||
|
||||
MessageContentModel *MessageAttached::contentModel() const
|
||||
{
|
||||
return m_contentModel;
|
||||
}
|
||||
|
||||
void MessageAttached::setContentModel(MessageContentModel *contentModel)
|
||||
{
|
||||
m_explicitContentModel = true;
|
||||
if (m_contentModel == contentModel) {
|
||||
return;
|
||||
}
|
||||
m_contentModel = contentModel;
|
||||
propagateMessage(this);
|
||||
Q_EMIT contentModelChanged();
|
||||
}
|
||||
|
||||
MessageContentFilterModel *MessageAttached::contentFilterModel() const
|
||||
{
|
||||
return m_contentFilterModel;
|
||||
}
|
||||
|
||||
void MessageAttached::setContentFilterModel(MessageContentFilterModel *contentFilterModel)
|
||||
{
|
||||
m_explicitContentFilterModel = true;
|
||||
if (m_contentFilterModel == contentFilterModel) {
|
||||
return;
|
||||
}
|
||||
m_contentFilterModel = contentFilterModel;
|
||||
propagateMessage(this);
|
||||
Q_EMIT contentFilterModelChanged();
|
||||
}
|
||||
|
||||
int MessageAttached::index() const
|
||||
{
|
||||
return m_index;
|
||||
}
|
||||
|
||||
void MessageAttached::setIndex(int index)
|
||||
{
|
||||
m_explicitIndex = true;
|
||||
if (m_index == index) {
|
||||
return;
|
||||
}
|
||||
m_index = index;
|
||||
propagateMessage(this);
|
||||
Q_EMIT indexChanged();
|
||||
}
|
||||
|
||||
qreal MessageAttached::maxContentWidth() const
|
||||
{
|
||||
return m_maxContentWidth;
|
||||
}
|
||||
|
||||
void MessageAttached::setMaxContentWidth(qreal maxContentWidth)
|
||||
{
|
||||
m_explicitMaxContentWidth = true;
|
||||
if (m_maxContentWidth == maxContentWidth) {
|
||||
return;
|
||||
}
|
||||
m_maxContentWidth = maxContentWidth;
|
||||
propagateMessage(this);
|
||||
Q_EMIT maxContentWidthChanged();
|
||||
}
|
||||
|
||||
QString MessageAttached::selectedText() const
|
||||
{
|
||||
return m_selectedText;
|
||||
}
|
||||
|
||||
void MessageAttached::setSelectedText(const QString &selectedTest)
|
||||
{
|
||||
m_explicitSelectedText = true;
|
||||
if (m_selectedText == selectedTest) {
|
||||
return;
|
||||
}
|
||||
m_selectedText = selectedTest;
|
||||
propagateMessage(this);
|
||||
Q_EMIT selectedTextChanged();
|
||||
}
|
||||
|
||||
QString MessageAttached::hoveredLink() const
|
||||
{
|
||||
return m_hoveredLink;
|
||||
}
|
||||
|
||||
void MessageAttached::setHoveredLink(const QString &hoveredLink)
|
||||
{
|
||||
m_explicitHoveredLink = true;
|
||||
if (m_hoveredLink == hoveredLink) {
|
||||
return;
|
||||
}
|
||||
m_hoveredLink = hoveredLink;
|
||||
propagateMessage(this);
|
||||
Q_EMIT hoveredLinkChanged();
|
||||
}
|
||||
|
||||
void MessageAttached::propagateMessage(MessageAttached *message)
|
||||
{
|
||||
if (m_explicitRoom || m_room != message->room()) {
|
||||
m_room = message->room();
|
||||
Q_EMIT roomChanged();
|
||||
}
|
||||
|
||||
if (m_explicitTimeline || m_timeline != message->timeline()) {
|
||||
m_timeline = message->timeline();
|
||||
Q_EMIT timelineChanged();
|
||||
}
|
||||
|
||||
if (!m_explicitContentModel && m_contentModel != message->contentModel()) {
|
||||
m_contentModel = message->contentModel();
|
||||
Q_EMIT contentModelChanged();
|
||||
}
|
||||
|
||||
if (!m_explicitContentFilterModel && m_contentFilterModel != message->contentFilterModel()) {
|
||||
m_contentFilterModel = message->contentFilterModel();
|
||||
Q_EMIT contentFilterModelChanged();
|
||||
}
|
||||
|
||||
if (m_explicitIndex || m_index != message->index()) {
|
||||
m_index = message->index();
|
||||
Q_EMIT indexChanged();
|
||||
}
|
||||
|
||||
if (m_explicitMaxContentWidth || m_maxContentWidth != message->maxContentWidth()) {
|
||||
m_maxContentWidth = message->maxContentWidth();
|
||||
Q_EMIT maxContentWidthChanged();
|
||||
}
|
||||
|
||||
if (m_explicitSelectedText || m_selectedText != message->selectedText()) {
|
||||
m_selectedText = message->selectedText();
|
||||
Q_EMIT selectedTextChanged();
|
||||
}
|
||||
|
||||
if (m_explicitHoveredLink || m_hoveredLink != message->hoveredLink()) {
|
||||
m_hoveredLink = message->hoveredLink();
|
||||
Q_EMIT hoveredLinkChanged();
|
||||
}
|
||||
|
||||
const auto styles = attachedChildren();
|
||||
for (auto *child : attachedChildren()) {
|
||||
MessageAttached *message = qobject_cast<MessageAttached *>(child);
|
||||
if (message != nullptr) {
|
||||
message->propagateMessage(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MessageAttached::attachedParentChange(QQuickAttachedPropertyPropagator *newParent, QQuickAttachedPropertyPropagator *oldParent)
|
||||
{
|
||||
Q_UNUSED(oldParent);
|
||||
|
||||
MessageAttached *attachedParent = qobject_cast<MessageAttached *>(newParent);
|
||||
if (attachedParent) {
|
||||
propagateMessage(attachedParent);
|
||||
}
|
||||
}
|
||||
|
||||
#include "moc_messageattached.cpp"
|
||||
@@ -1,128 +0,0 @@
|
||||
// SPDX-FileCopyrightText: 2025 James Graham <james.h.graham@protonmail.com>
|
||||
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QQmlEngine>
|
||||
#include <QQuickAttachedPropertyPropagator>
|
||||
#include <QQuickItem>
|
||||
|
||||
#include "models/messagecontentfiltermodel.h"
|
||||
#include "models/messagecontentmodel.h"
|
||||
#include "neochatroom.h"
|
||||
|
||||
class MessageAttached : public QQuickAttachedPropertyPropagator
|
||||
{
|
||||
Q_OBJECT
|
||||
QML_NAMED_ELEMENT(Message)
|
||||
QML_ATTACHED(MessageAttached)
|
||||
QML_UNCREATABLE("")
|
||||
|
||||
/**
|
||||
* @brief The room that the message comes from.
|
||||
*/
|
||||
Q_PROPERTY(NeoChatRoom *room READ room WRITE setRoom NOTIFY roomChanged FINAL)
|
||||
|
||||
/**
|
||||
* @brief The timeline for the current message.
|
||||
*/
|
||||
Q_PROPERTY(QQuickItem *timeline READ timeline WRITE setTimeline NOTIFY timelineChanged FINAL)
|
||||
|
||||
/**
|
||||
* @brief The content model for the current message.
|
||||
*/
|
||||
Q_PROPERTY(MessageContentModel *contentModel READ contentModel WRITE setContentModel NOTIFY contentModelChanged FINAL)
|
||||
|
||||
/**
|
||||
* @brief The content model for the current message.
|
||||
*/
|
||||
Q_PROPERTY(MessageContentFilterModel *contentFilterModel READ contentFilterModel WRITE setContentFilterModel NOTIFY contentFilterModelChanged FINAL)
|
||||
|
||||
/**
|
||||
* @brief The index of the message in the timeline
|
||||
*/
|
||||
Q_PROPERTY(int index READ index WRITE setIndex NOTIFY indexChanged FINAL)
|
||||
|
||||
/**
|
||||
* @brief The width available to the message content.
|
||||
*/
|
||||
Q_PROPERTY(qreal maxContentWidth READ maxContentWidth WRITE setMaxContentWidth NOTIFY maxContentWidthChanged FINAL)
|
||||
|
||||
/**
|
||||
* @brief The current selected message text.
|
||||
*/
|
||||
Q_PROPERTY(QString selectedText READ selectedText WRITE setSelectedText NOTIFY selectedTextChanged FINAL)
|
||||
|
||||
/**
|
||||
* @brief The text of a hovered link if any.
|
||||
*/
|
||||
Q_PROPERTY(QString hoveredLink READ hoveredLink WRITE setHoveredLink NOTIFY hoveredLinkChanged FINAL)
|
||||
|
||||
public:
|
||||
explicit MessageAttached(QObject *parent = nullptr);
|
||||
|
||||
static MessageAttached *qmlAttachedProperties(QObject *object);
|
||||
|
||||
NeoChatRoom *room() const;
|
||||
void setRoom(NeoChatRoom *room);
|
||||
|
||||
QQuickItem *timeline() const;
|
||||
void setTimeline(QQuickItem *timeline);
|
||||
|
||||
MessageContentModel *contentModel() const;
|
||||
void setContentModel(MessageContentModel *contentModel);
|
||||
|
||||
MessageContentFilterModel *contentFilterModel() const;
|
||||
void setContentFilterModel(MessageContentFilterModel *contentFilterModel);
|
||||
|
||||
int index() const;
|
||||
void setIndex(int index);
|
||||
|
||||
qreal maxContentWidth() const;
|
||||
void setMaxContentWidth(qreal maxContentWidth);
|
||||
|
||||
QString selectedText() const;
|
||||
void setSelectedText(const QString &selectedTest);
|
||||
|
||||
QString hoveredLink() const;
|
||||
void setHoveredLink(const QString &hoveredLink);
|
||||
|
||||
Q_SIGNALS:
|
||||
void roomChanged();
|
||||
void timelineChanged();
|
||||
void contentModelChanged();
|
||||
void contentFilterModelChanged();
|
||||
void indexChanged();
|
||||
void maxContentWidthChanged();
|
||||
void selectedTextChanged();
|
||||
void hoveredLinkChanged();
|
||||
|
||||
protected:
|
||||
void propagateMessage(MessageAttached *message);
|
||||
void attachedParentChange(QQuickAttachedPropertyPropagator *newParent, QQuickAttachedPropertyPropagator *oldParent) override;
|
||||
|
||||
private:
|
||||
QPointer<NeoChatRoom> m_room;
|
||||
bool m_explicitRoom = false;
|
||||
|
||||
QPointer<QQuickItem> m_timeline;
|
||||
bool m_explicitTimeline = false;
|
||||
|
||||
QPointer<MessageContentModel> m_contentModel;
|
||||
bool m_explicitContentModel = false;
|
||||
|
||||
QPointer<MessageContentFilterModel> m_contentFilterModel;
|
||||
bool m_explicitContentFilterModel = false;
|
||||
|
||||
int m_index = -1;
|
||||
bool m_explicitIndex = false;
|
||||
|
||||
qreal m_maxContentWidth = -1;
|
||||
bool m_explicitMaxContentWidth = false;
|
||||
|
||||
QString m_selectedText = {};
|
||||
bool m_explicitSelectedText = false;
|
||||
|
||||
QString m_hoveredLink = {};
|
||||
bool m_explicitHoveredLink = false;
|
||||
};
|
||||
@@ -1,37 +0,0 @@
|
||||
// SPDX-FileCopyrightText: 2025 James Graham <james.h.graham@protonmail.com>
|
||||
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||
|
||||
#include "messagecontentfiltermodel.h"
|
||||
#include "enums/messagecomponenttype.h"
|
||||
#include "models/messagecontentmodel.h"
|
||||
|
||||
MessageContentFilterModel::MessageContentFilterModel(QObject *parent)
|
||||
: QSortFilterProxyModel(parent)
|
||||
{
|
||||
}
|
||||
|
||||
bool MessageContentFilterModel::showAuthor() const
|
||||
{
|
||||
return m_showAuthor;
|
||||
}
|
||||
|
||||
void MessageContentFilterModel::setShowAuthor(bool showAuthor)
|
||||
{
|
||||
if (showAuthor == m_showAuthor) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_showAuthor = showAuthor;
|
||||
Q_EMIT showAuthorChanged();
|
||||
}
|
||||
|
||||
bool MessageContentFilterModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
|
||||
{
|
||||
if (m_showAuthor) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const auto index = sourceModel()->index(source_row, 0, source_parent);
|
||||
auto contentType = static_cast<MessageComponentType::Type>(index.data(MessageContentModel::ComponentTypeRole).toInt());
|
||||
return contentType != MessageComponentType::Author;
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
// SPDX-FileCopyrightText: 2025 James Graham <james.h.graham@protonmail.com>
|
||||
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QQmlEngine>
|
||||
#include <QSortFilterProxyModel>
|
||||
|
||||
/**
|
||||
* @class MessageContentFilterModel
|
||||
*
|
||||
* This model filters a message's contents.
|
||||
*/
|
||||
class MessageContentFilterModel : public QSortFilterProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
QML_ELEMENT
|
||||
|
||||
/**
|
||||
* @brief Whether the author component should be shown.
|
||||
*/
|
||||
Q_PROPERTY(bool showAuthor READ showAuthor WRITE setShowAuthor NOTIFY showAuthorChanged)
|
||||
|
||||
public:
|
||||
explicit MessageContentFilterModel(QObject *parent = nullptr);
|
||||
|
||||
bool showAuthor() const;
|
||||
void setShowAuthor(bool showAuthor);
|
||||
|
||||
Q_SIGNALS:
|
||||
void showAuthorChanged();
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @brief Whether a row should be shown out or not.
|
||||
*
|
||||
* @sa QSortFilterProxyModel::filterAcceptsRow
|
||||
*/
|
||||
[[nodiscard]] bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override;
|
||||
|
||||
private:
|
||||
bool m_showAuthor = true;
|
||||
};
|
||||
Reference in New Issue
Block a user