Fix bugs with the context link text for localdocs to make the context links

persistently work across application loads and fix scrolling bug with context
links.

Signed-off-by: Adam Treat <treat.adam@gmail.com>
This commit is contained in:
Adam Treat 2023-12-21 13:59:33 -05:00 committed by AT
parent ac498f79ac
commit e27653219b
2 changed files with 64 additions and 9 deletions

View File

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

View File

@ -6,6 +6,7 @@
#include <QQuickTextDocument>
#include <QSyntaxHighlighter>
#include <QRegularExpression>
#include <QTextObjectInterface>
class SyntaxHighlighter : public QSyntaxHighlighter {
Q_OBJECT
@ -28,6 +29,20 @@ struct CodeCopy {
QString text;
};
class ContextLinkInterface : public QObject, public QTextObjectInterface
{
Q_OBJECT
Q_INTERFACES(QTextObjectInterface)
public:
explicit ContextLinkInterface(QObject *parent) : QObject(parent) {}
void drawObject(QPainter *painter, const QRectF &rect, QTextDocument *doc, int posInDocument,
const QTextFormat &format) override;
QSizeF intrinsicSize(QTextDocument *doc, int posInDocument, const QTextFormat &format) override;
};
class ResponseText : public QObject
{
Q_OBJECT
@ -61,6 +76,7 @@ private:
QColor m_linkColor;
QColor m_headerColor;
bool m_isProcessingText = false;
ContextLinkInterface *m_contextLink;
};
#endif // RESPONSETEXT_H