fix: handle multiline selection starting at trailing space (#5691)

This commit is contained in:
nerix 2024-11-03 19:23:53 +01:00 committed by GitHub
parent d3000ba597
commit 68304272a2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 31 additions and 15 deletions

View file

@ -68,6 +68,7 @@
- Bugfix: Fixed emotes starting with ":" not tab-completing. (#5603) - Bugfix: Fixed emotes starting with ":" not tab-completing. (#5603)
- Bugfix: Fixed 7TV emotes messing with Qt's HTML. (#5677) - Bugfix: Fixed 7TV emotes messing with Qt's HTML. (#5677)
- Bugfix: Fixed incorrect messages getting replaced visually. (#5683) - Bugfix: Fixed incorrect messages getting replaced visually. (#5683)
- Bugfix: Fixed rendering of multi-line selection that starts at a trailing space. (#5691)
- Dev: Update Windows build from Qt 6.5.0 to Qt 6.7.1. (#5420) - Dev: Update Windows build from Qt 6.5.0 to Qt 6.7.1. (#5420)
- Dev: Update vcpkg build Qt from 6.5.0 to 6.7.0, boost from 1.83.0 to 1.85.0, openssl from 3.1.3 to 3.3.0. (#5422) - Dev: Update vcpkg build Qt from 6.5.0 to 6.7.0, boost from 1.83.0 to 1.85.0, openssl from 3.1.3 to 3.3.0. (#5422)
- Dev: Unsingletonize `ISoundController`. (#5462) - Dev: Unsingletonize `ISoundController`. (#5462)

View file

@ -854,6 +854,18 @@ std::optional<size_t> MessageLayoutContainer::paintSelectionStart(
{ {
const auto selectionColor = getTheme()->messages.selection; const auto selectionColor = getTheme()->messages.selection;
auto paintRemainingLines = [&](size_t startIndex) {
for (size_t i = startIndex; i < this->lines_.size(); i++)
{
const auto &line = this->lines_[i];
auto left = this->elements_[line.startIndex]->getRect().left();
auto right = this->elements_[line.endIndex - 1]->getRect().right();
this->paintSelectionRect(painter, line, left, right, yOffset,
selectionColor);
}
};
// The selection starts in this message // The selection starts in this message
for (size_t lineIndex = 0; lineIndex < this->lines_.size(); lineIndex++) for (size_t lineIndex = 0; lineIndex < this->lines_.size(); lineIndex++)
{ {
@ -874,7 +886,17 @@ std::optional<size_t> MessageLayoutContainer::paintSelectionStart(
auto right = this->elements_[line.endIndex - 1]->getRect().right(); auto right = this->elements_[line.endIndex - 1]->getRect().right();
this->paintSelectionRect(painter, line, right, right, yOffset, this->paintSelectionRect(painter, line, right, right, yOffset,
selectionColor); selectionColor);
return std::nullopt;
if (selection.selectionMax.messageIndex != messageIndex)
{
// The selection does not end in this message
paintRemainingLines(lineIndex + 1);
return std::nullopt;
}
// The selection starts in this line, but ends in some next line or message
return {lineIndex + 1};
} }
int x = this->elements_[line.startIndex]->getRect().left(); int x = this->elements_[line.startIndex]->getRect().left();
@ -923,21 +945,9 @@ std::optional<size_t> MessageLayoutContainer::paintSelectionStart(
if (selection.selectionMax.messageIndex != messageIndex) if (selection.selectionMax.messageIndex != messageIndex)
{ {
// The selection does not end in this message // The selection does not end in this message
for (size_t lineIndex2 = lineIndex + 1;
lineIndex2 < this->lines_.size(); lineIndex2++)
{
const auto &line2 = this->lines_[lineIndex2];
auto left =
this->elements_[line2.startIndex]->getRect().left();
auto right =
this->elements_[line2.endIndex - 1]->getRect().right();
this->paintSelectionRect(painter, line2, left, right,
yOffset, selectionColor);
}
this->paintSelectionRect(painter, line, x, r, yOffset, this->paintSelectionRect(painter, line, x, r, yOffset,
selectionColor); selectionColor);
paintRemainingLines(lineIndex + 1);
return std::nullopt; return std::nullopt;
} }

View file

@ -283,7 +283,12 @@ private:
/** /**
* Paint the selection start * Paint the selection start
* *
* Returns a line index if this message should also paint the selection end * @returns A line index if the selection ends within this message but start
* and end are on different lines. The returned index is the index
* of the first line where the selection starts at the beginning of
* the line. This index should be passed to paintSelectionEnd().
* If `std::nullopt` is returned, no further call to
* paintSelectionEnd() is necessary.
*/ */
std::optional<size_t> paintSelectionStart(QPainter &painter, std::optional<size_t> paintSelectionStart(QPainter &painter,
size_t messageIndex, size_t messageIndex,