Use Quotient qml module

This commit is contained in:
Tobias Fella
2025-09-15 16:48:44 +02:00
parent cc2daa2021
commit 604c652821
9 changed files with 11 additions and 5 deletions

View File

@@ -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)

View File

@@ -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.

View File

@@ -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"

View File

@@ -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;
};

View File

@@ -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;
}

View File

@@ -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;
};