Merge PR #5619: FIX(client): resolve list tags, etc. polluting log

As reported in #4491, #4986 and #5430, since the changes to the chat in
the 1.4.x release, some tags would "pollute" the rest of the log, i.e.
cause future log entries to be contained within them.

The source of the issue seems to be that the insertBlock method of
QTextCursor appears to correspond to the <p> HTML tag. The <p> tag
may only contain inline elements, but QTextEdit will not fail outright
when inserting block-level elements and will instead attempt to correct
the invalid input which results in the behaviour reported in the above
issues (as far as I can tell).

The proposed solution is to use the insertFrame method for all
messages.

Fixes #4491
This commit is contained in:
Robert Adam 2022-04-09 19:10:54 +02:00 committed by GitHub
commit 0e321ebc15
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -642,9 +642,7 @@ QString Log::validHtml(const QString &html, QTextCursor *tc) {
}
if (tc) {
QTextCursor tcNew(&qtd);
tcNew.movePosition(QTextCursor::End, QTextCursor::KeepAnchor);
tc->insertFragment(tcNew.selection());
tc->insertHtml(qtd.toHtml());
return QString();
} else {
return qtd.toHtml();
@ -675,11 +673,6 @@ void Log::log(MsgType mt, const QString &console, const QString &terse, bool own
// the setting might change in that time).
const int msgMargin = Global::get().s.iChatMessageMargins;
QTextBlockFormat format = tc.blockFormat();
format.setTopMargin(msgMargin);
format.setBottomMargin(msgMargin);
tc.setBlockFormat(format);
LogTextBrowser *tlog = Global::get().mw->qteLog;
const int oldscrollvalue = tlog->getLogScroll();
const bool scroll = (oldscrollvalue == tlog->getLogScrollMaximum());
@ -698,24 +691,25 @@ void Log::log(MsgType mt, const QString &console, const QString &terse, bool own
QString fixedNLPlain =
plain.replace(QLatin1String("\r\n"), QLatin1String("\n")).replace(QLatin1String("\r"), QLatin1String("\n"));
QTextFrameFormat qttf;
// `insertFrame` causes a blank line to precede the inserted frame.
// This is remedied by setting a negative top margin of equal height.
static int lineSpacing = QFontMetrics(tc.currentFrame()->format().toCharFormat().font()).lineSpacing();
qttf.setTopMargin(-lineSpacing);
qttf.setBottomMargin(msgMargin);
if (fixedNLPlain.contains(QRegExp(QLatin1String("\\n[ \\t]*$")))) {
// If the message ends with one or more blank lines (or lines only containing whitespace)
// paint a border around the message to make clear that it contains invisible parts.
// The beginning of the message is clear anyway (the date and potentially the "To XY" part)
// so we don't have to care about that.
QTextFrameFormat qttf;
qttf.setBorder(1);
qttf.setPadding(2);
qttf.setMargin(msgMargin);
qttf.setBorderStyle(QTextFrameFormat::BorderStyle_Dashed);
tc.insertFrame(qttf);
} else if (!tc.block().text().isEmpty()) {
// Only insert a block if the current block is not empty. It may be empty because
// it is the default block of an empty document. Another cause might be that apparently
// a new empty block is automatically inserted after a frame.
tc.insertBlock();
}
tc.insertFrame(qttf);
const QString timeString =
dt.time().toString(QLatin1String(Global::get().s.bLog24HourClock ? "HH:mm:ss" : "hh:mm:ss AP"));
tc.insertHtml(Log::msgColor(QString::fromLatin1("[%1] ").arg(timeString.toHtmlEscaped()), Log::Time));