Files
utun2/tools/chatgui/src/message_text.h
T

41 lines
3.3 KiB
C

/* Разметка текста сообщений: **жирный**, __курсив__, ~~зачёркнутый~~ и отдельные строки ```[язык]/```.
* Исходник модели не меняется. GUI-поток получает кешированный видимый текст, ссылки и цвета синтаксиса.
* Один QTextLayout используется для размеров, рисования и выделения; clipboard берёт MessageText::text. */
#pragma once
#include "message_links.h"
#include <QModelIndex>
#include <QSharedPointer>
#include <QTextLayout>
struct MessageCodeBlock {
int start; // Начало кода в видимом тексте, UTF-16.
int length; // Длина без строк-ограждений; ноль означает пустой блок.
QString language; // Имя из ограждения: пустое включает автоопределение, неизвестное/text/plain отключает раскраску.
QString languageName; // Имя для шапки после подготовки подсветки; пусто означает обычный text.
};
struct MessageText {
QString text; // Видимый текст без распознанных маркеров; настоящие переводы строк сохранены.
QVector<QTextLayout::FormatRange> styles; // Жирный, курсив и зачёркивание; диапазоны UTF-16.
QVector<MessageCodeBlock> code; // Непересекающиеся блоки в порядке текста.
QVector<MessageLink> links; // Адреса вне кода, в координатах видимого текста.
QVector<QTextLayout::FormatRange> lightSyntax, darkSyntax; // Только цвета токенов, без изменения метрик шрифта.
bool changed = false; // Хотя бы один маркер/escape обработан; иначе применяется прежняя отрисовка.
// Принадлежность позиции UTF-16 к коду, включая пустые строки/блоки. Для исключения ссылок и emoji.
bool isCode(int position) const;
};
// Чистый разбор без загрузки библиотеки синтаксиса. Незакрытые маркеры остаются буквально; вложенности нет.
MessageText parseMessageText(const QString& source);
// GUI-поток: кеш разметки/цветов с ограничением памяти. nullptr для обычного текста, медиа, опросов и compact invite.
QSharedPointer<const MessageText> formattedMessageText(const QModelIndex& index);
// Настроить layout с уже заданным базовым font; width > 0, dark выбирает цвета. Возвращает высоту строк.
qreal layoutFormattedMessage(QTextLayout& layout, const MessageText& message, int width, bool dark);
// Прямоугольник Copy в координатах готового layout; пустой, если у блока нет строки.
QRectF messageCodeCopyRect(const QTextLayout& layout, const MessageCodeBlock& block, int width);