Skip to content

Commit

Permalink
fix: handle multiline selection starting at trailing space (#5691)
Browse files Browse the repository at this point in the history
  • Loading branch information
Nerixyz authored Nov 3, 2024
1 parent d3000ba commit 6830427
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 15 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
- Bugfix: Fixed emotes starting with ":" not tab-completing. (#5603)
- Bugfix: Fixed 7TV emotes messing with Qt's HTML. (#5677)
- 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 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)
Expand Down
38 changes: 24 additions & 14 deletions src/messages/layouts/MessageLayoutContainer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -854,6 +854,18 @@ std::optional<size_t> MessageLayoutContainer::paintSelectionStart(
{
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
for (size_t lineIndex = 0; lineIndex < this->lines_.size(); lineIndex++)
{
Expand All @@ -874,7 +886,17 @@ std::optional<size_t> MessageLayoutContainer::paintSelectionStart(
auto right = this->elements_[line.endIndex - 1]->getRect().right();
this->paintSelectionRect(painter, line, right, right, yOffset,
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();
Expand Down Expand Up @@ -923,21 +945,9 @@ std::optional<size_t> MessageLayoutContainer::paintSelectionStart(
if (selection.selectionMax.messageIndex != messageIndex)
{
// 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,
selectionColor);
paintRemainingLines(lineIndex + 1);

return std::nullopt;
}
Expand Down
7 changes: 6 additions & 1 deletion src/messages/layouts/MessageLayoutContainer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,12 @@ struct MessageLayoutContainer {
/**
* 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,
size_t messageIndex,
Expand Down

0 comments on commit 6830427

Please sign in to comment.