|
|
|
@ -7,6 +7,7 @@
|
|
|
|
|
#include <QTextTableCell>
|
|
|
|
|
#include <QGuiApplication>
|
|
|
|
|
#include <QClipboard>
|
|
|
|
|
#include <QPainter>
|
|
|
|
|
|
|
|
|
|
enum Language {
|
|
|
|
|
None,
|
|
|
|
@ -845,11 +846,36 @@ void SyntaxHighlighter::highlightBlock(const QString &text)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const int ContextLinkFormat = QTextFormat::UserObject + 1;
|
|
|
|
|
const int ContextLinkHref = QTextFormat::UserProperty + 1;
|
|
|
|
|
const int ContextLinkText = QTextFormat::UserProperty + 2;
|
|
|
|
|
|
|
|
|
|
void ContextLinkInterface::drawObject(QPainter *painter, const QRectF &rect, QTextDocument *doc,
|
|
|
|
|
int posInDocument, const QTextFormat &format)
|
|
|
|
|
{
|
|
|
|
|
const QString &href = format.property(ContextLinkHref).toString();
|
|
|
|
|
const QString &text = format.property(ContextLinkText).toString();
|
|
|
|
|
painter->setFont(doc->defaultFont());
|
|
|
|
|
painter->setPen(format.foreground().color());
|
|
|
|
|
painter->drawText(rect.bottomLeft(), text);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QSizeF ContextLinkInterface::intrinsicSize(QTextDocument *doc, int posInDocument,
|
|
|
|
|
const QTextFormat &format)
|
|
|
|
|
{
|
|
|
|
|
const QString &href = format.property(ContextLinkHref).toString();
|
|
|
|
|
const QString &text = format.property(ContextLinkText).toString();
|
|
|
|
|
const QFontMetricsF metrics(doc->defaultFont());
|
|
|
|
|
const QSizeF textSize = metrics.size(Qt::TextSingleLine, text);
|
|
|
|
|
return textSize;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ResponseText::ResponseText(QObject *parent)
|
|
|
|
|
: QObject{parent}
|
|
|
|
|
, m_textDocument(nullptr)
|
|
|
|
|
, m_syntaxHighlighter(new SyntaxHighlighter(this))
|
|
|
|
|
, m_isProcessingText(false)
|
|
|
|
|
, m_contextLink(new ContextLinkInterface(this))
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -864,6 +890,7 @@ void ResponseText::setTextDocument(QQuickTextDocument* textDocument)
|
|
|
|
|
disconnect(m_textDocument->textDocument(), &QTextDocument::contentsChanged, this, &ResponseText::handleTextChanged);
|
|
|
|
|
|
|
|
|
|
m_textDocument = textDocument;
|
|
|
|
|
m_textDocument->textDocument()->documentLayout()->registerHandler(ContextLinkFormat, m_contextLink);
|
|
|
|
|
m_syntaxHighlighter->setDocument(m_textDocument->textDocument());
|
|
|
|
|
connect(m_textDocument->textDocument(), &QTextDocument::contentsChanged, this, &ResponseText::handleTextChanged);
|
|
|
|
|
handleTextChanged();
|
|
|
|
@ -871,10 +898,20 @@ void ResponseText::setTextDocument(QQuickTextDocument* textDocument)
|
|
|
|
|
|
|
|
|
|
QString ResponseText::getLinkAtPosition(int position) const
|
|
|
|
|
{
|
|
|
|
|
int i = 0;
|
|
|
|
|
for (const auto &link : m_links) {
|
|
|
|
|
if (position >= link.startPos && position < link.endPos)
|
|
|
|
|
return link.href;
|
|
|
|
|
QTextCursor cursor(m_textDocument->textDocument());
|
|
|
|
|
cursor.setPosition(position);
|
|
|
|
|
QTextCharFormat format = cursor.charFormat();
|
|
|
|
|
if (format.objectType() == ContextLinkFormat) {
|
|
|
|
|
QString href = format.property(ContextLinkHref).toString();
|
|
|
|
|
if (!href.isEmpty())
|
|
|
|
|
return href;
|
|
|
|
|
}
|
|
|
|
|
cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor);
|
|
|
|
|
format = cursor.charFormat();
|
|
|
|
|
if (format.objectType() == ContextLinkFormat) {
|
|
|
|
|
QString href = format.property(ContextLinkHref).toString();
|
|
|
|
|
if (!href.isEmpty())
|
|
|
|
|
return href;
|
|
|
|
|
}
|
|
|
|
|
return QString();
|
|
|
|
|
}
|
|
|
|
@ -912,9 +949,6 @@ void ResponseText::handleContextLinks()
|
|
|
|
|
{
|
|
|
|
|
QTextDocument* doc = m_textDocument->textDocument();
|
|
|
|
|
QTextCursor cursor(doc);
|
|
|
|
|
QTextCharFormat linkFormat;
|
|
|
|
|
linkFormat.setForeground(m_linkColor);
|
|
|
|
|
linkFormat.setFontUnderline(true);
|
|
|
|
|
|
|
|
|
|
// Regex for context links
|
|
|
|
|
static const QRegularExpression reLink("\\[Context\\]\\((context://\\d+)\\)");
|
|
|
|
@ -943,8 +977,13 @@ void ResponseText::handleContextLinks()
|
|
|
|
|
cursor.setPosition(matchesLink.at(index).capturedStart());
|
|
|
|
|
cursor.setPosition(matchesLink.at(index).capturedEnd(), QTextCursor::KeepAnchor);
|
|
|
|
|
cursor.removeSelectedText();
|
|
|
|
|
cursor.setCharFormat(linkFormat);
|
|
|
|
|
cursor.insertText(newLinks.at(index).text);
|
|
|
|
|
QTextCharFormat objectFormat;
|
|
|
|
|
objectFormat.setForeground(m_linkColor);
|
|
|
|
|
objectFormat.setFontUnderline(true);
|
|
|
|
|
objectFormat.setProperty(ContextLinkHref, newLinks.at(index).href);
|
|
|
|
|
objectFormat.setProperty(ContextLinkText, newLinks.at(index).text);
|
|
|
|
|
objectFormat.setObjectType(ContextLinkFormat);
|
|
|
|
|
cursor.insertText(QString(QChar::ObjectReplacementCharacter), objectFormat);
|
|
|
|
|
cursor.setCharFormat(QTextCharFormat());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|