File indexing completed on 2024-09-15 04:28:26
0001 // SPDX-FileCopyrightText: 2020 Carl Schwan <carl@carlschwan.eu> 0002 // SPDX-License-Identifier: GPL-2.0-or-later 0003 0004 #pragma once 0005 0006 #include <QObject> 0007 #include <QQmlEngine> 0008 #include <QQuickTextDocument> 0009 #include <QTextCursor> 0010 0011 #include "chatbarcache.h" 0012 #include "models/completionmodel.h" 0013 #include "neochatroom.h" 0014 0015 class NeoChatRoom; 0016 class SyntaxHighlighter; 0017 0018 /** 0019 * @class ChatDocumentHandler 0020 * 0021 * Handle the QQuickTextDocument of a qml text item. 0022 * 0023 * The class provides functionality to highlight text in the text document as well 0024 * as providing completion functionality via a CompletionModel. 0025 * 0026 * The ChatDocumentHandler is also linked to a NeoChatRoom to provide functionality 0027 * to save the chat document text when switching between rooms. 0028 * 0029 * To get the full functionality the cursor position and text selection information 0030 * need to be passed in. For example: 0031 * 0032 * @code{.qml} 0033 * import QtQuick 2.0 0034 * import QtQuick.Controls 2.15 as QQC2 0035 * 0036 * import org.kde.kirigami 2.12 as Kirigami 0037 * import org.kde.neochat 1.0 0038 * 0039 * QQC2.TextArea { 0040 * id: textField 0041 * 0042 * // Set this to a NeoChatRoom object. 0043 * property var room 0044 * 0045 * ChatDocumentHandler { 0046 * id: documentHandler 0047 * document: textField.textDocument 0048 * cursorPosition: textField.cursorPosition 0049 * selectionStart: textField.selectionStart 0050 * selectionEnd: textField.selectionEnd 0051 * mentionColor: Kirigami.Theme.linkColor 0052 * errorColor: Kirigami.Theme.negativeTextColor 0053 * room: textField.room 0054 * } 0055 * } 0056 * @endcode 0057 * 0058 * @sa QQuickTextDocument, CompletionModel, NeoChatRoom 0059 */ 0060 class ChatDocumentHandler : public QObject 0061 { 0062 Q_OBJECT 0063 QML_ELEMENT 0064 0065 /** 0066 * @brief The QQuickTextDocument that is being handled. 0067 */ 0068 Q_PROPERTY(QQuickTextDocument *document READ document WRITE setDocument NOTIFY documentChanged) 0069 0070 /** 0071 * @brief The current saved cursor position. 0072 */ 0073 Q_PROPERTY(int cursorPosition READ cursorPosition WRITE setCursorPosition NOTIFY cursorPositionChanged) 0074 0075 /** 0076 * @brief The start position of any currently selected text. 0077 */ 0078 Q_PROPERTY(int selectionStart READ selectionStart WRITE setSelectionStart NOTIFY selectionStartChanged) 0079 0080 /** 0081 * @brief The end position of any currently selected text. 0082 */ 0083 Q_PROPERTY(int selectionEnd READ selectionEnd WRITE setSelectionEnd NOTIFY selectionEndChanged) 0084 0085 /** 0086 * @brief The current CompletionModel. 0087 * 0088 * This is typically provided to a qml component to visualise the current 0089 * completion results. 0090 */ 0091 Q_PROPERTY(CompletionModel *completionModel READ completionModel CONSTANT) 0092 0093 /** 0094 * @brief The current room that the the text document is being handled for. 0095 */ 0096 Q_PROPERTY(NeoChatRoom *room READ room WRITE setRoom NOTIFY roomChanged) 0097 0098 /** 0099 * @brief The cache for the chat bar the text document is being handled for. 0100 */ 0101 Q_PROPERTY(ChatBarCache *chatBarCache READ chatBarCache WRITE setChatBarCache NOTIFY chatBarCacheChanged) 0102 0103 /** 0104 * @brief The color to highlight user mentions. 0105 */ 0106 Q_PROPERTY(QColor mentionColor READ mentionColor WRITE setMentionColor NOTIFY mentionColorChanged) 0107 0108 /** 0109 * @brief The color to highlight spelling errors. 0110 */ 0111 Q_PROPERTY(QColor errorColor READ errorColor WRITE setErrorColor NOTIFY errorColorChanged) 0112 0113 public: 0114 explicit ChatDocumentHandler(QObject *parent = nullptr); 0115 0116 [[nodiscard]] QQuickTextDocument *document() const; 0117 void setDocument(QQuickTextDocument *document); 0118 0119 [[nodiscard]] int cursorPosition() const; 0120 void setCursorPosition(int position); 0121 0122 [[nodiscard]] int selectionStart() const; 0123 void setSelectionStart(int position); 0124 0125 [[nodiscard]] int selectionEnd() const; 0126 void setSelectionEnd(int position); 0127 0128 [[nodiscard]] NeoChatRoom *room() const; 0129 void setRoom(NeoChatRoom *room); 0130 0131 [[nodiscard]] ChatBarCache *chatBarCache() const; 0132 void setChatBarCache(ChatBarCache *chatBarCache); 0133 0134 Q_INVOKABLE void complete(int index); 0135 0136 CompletionModel *completionModel() const; 0137 0138 [[nodiscard]] QColor mentionColor() const; 0139 void setMentionColor(const QColor &color); 0140 0141 [[nodiscard]] QColor errorColor() const; 0142 void setErrorColor(const QColor &color); 0143 0144 Q_SIGNALS: 0145 void documentChanged(); 0146 void cursorPositionChanged(); 0147 void roomChanged(); 0148 void chatBarCacheChanged(); 0149 void selectionStartChanged(); 0150 void selectionEndChanged(); 0151 void errorColorChanged(); 0152 void mentionColorChanged(); 0153 0154 private: 0155 int completionStartIndex() const; 0156 0157 QPointer<QQuickTextDocument> m_document; 0158 0159 QPointer<NeoChatRoom> m_room; 0160 QPointer<ChatBarCache> m_chatBarCache; 0161 0162 QColor m_mentionColor; 0163 QColor m_errorColor; 0164 0165 int m_cursorPosition; 0166 int m_selectionStart; 0167 int m_selectionEnd; 0168 0169 QString getText() const; 0170 void pushMention(const Mention mention) const; 0171 0172 SyntaxHighlighter *m_highlighter = nullptr; 0173 0174 CompletionModel *m_completionModel = nullptr; 0175 };