[network/ruqola] src/widgets/room/delegate: Fix layout
Laurent Montel <[email protected]>
| Newsgroups | gmane.comp.kde.cvs |
|---|---|
| Message-ID | <[email protected]> |
Git commit 818c71118bc25d9977f8cd56ff91d4e1b42e4c5b by Laurent Montel.
Committed on 14/08/2026 at 17:39.
Pushed by mlaurent into branch 'master'.
Fix layout
M +5 -3 src/widgets/room/delegate/messageattachmentdelegatehelperbase.cpp
M +10 -3 src/widgets/room/delegate/messageattachmentdelegatehelperimage.cpp
M +23 -11 src/widgets/room/delegate/messageattachmentdelegatehelpertext.cpp
M +1 -0 src/widgets/room/delegate/messageattachmentdelegatehelpertext.h
https://invent.kde.org/network/ruqola/-/commit/818c71118bc25d9977f8cd56ff91d4e1b42e4c5b
diff --git a/src/widgets/room/delegate/messageattachmentdelegatehelperbase.cpp b/src/widgets/room/delegate/messageattachmentdelegatehelperbase.cpp
index 7789b13eeb..cccb391d1a 100644
--- a/src/widgets/room/delegate/messageattachmentdelegatehelperbase.cpp
+++ b/src/widgets/room/delegate/messageattachmentdelegatehelperbase.cpp
@@ -101,14 +101,16 @@ bool MessageAttachmentDelegateHelperBase::handleMouseEvent(const MessageAttachme
mTextSelectionImpl->setMightStartDrag(false);
mCurrentIndex = QModelIndex();
if (const auto *doc = documentFromAttachment(msgAttach, attachmentsRect.width())) {
- const QPoint pos = mouseEvent->pos();
- const int charPos = charPosition(doc, msgAttach, attachmentsRect, pos, option);
+ // The document is laid out below the attachment header, so hit testing needs the adapted
+ // position, not the raw viewport one.
+ const QPoint relativePos = adaptMousePosition(mouseEvent->pos(), msgAttach, attachmentsRect, option);
+ const int charPos = doc->documentLayout()->hitTest(relativePos, Qt::FuzzyHit);
qCDebug(RUQOLAWIDGETS_SELECTION_LOG) << "pressed at pos" << charPos;
if (charPos == -1) {
return false;
}
// TODO fix mTextSelectionImpl->contains with attachment
- if (mTextSelectionImpl->textSelection()->contains(index, charPos) && doc->documentLayout()->hitTest(pos, Qt::ExactHit) != -1) {
+ if (mTextSelectionImpl->textSelection()->contains(index, charPos) && doc->documentLayout()->hitTest(relativePos, Qt::ExactHit) != -1) {
mTextSelectionImpl->setMightStartDrag(true);
mCurrentIndex = index;
return true;
diff --git a/src/widgets/room/delegate/messageattachmentdelegatehelperimage.cpp b/src/widgets/room/delegate/messageattachmentdelegatehelperimage.cpp
index dc9ad39b48..2dbfc936dd 100644
--- a/src/widgets/room/delegate/messageattachmentdelegatehelperimage.cpp
+++ b/src/widgets/room/delegate/messageattachmentdelegatehelperimage.cpp
@@ -158,9 +158,11 @@ bool MessageAttachmentDelegateHelperImage::handleMouseEvent(const MessageAttachm
job->setInfo(info);
job->start();
return true;
- } else if (!layout.pixmap.isNull()) {
+ } else if (layout.isShown && !layout.pixmap.isNull()) {
+ // imageSize is in device pixels (as the cached pixmap is), draw() paints it scaled down by the dpr.
+ const qreal dpr = layout.pixmap.devicePixelRatioF();
const int imageY = attachmentsRect.y() + layout.titleSize.height() + DelegatePaintUtil::margin();
- const QRect imageRect(attachmentsRect.x(), imageY, layout.imageSize.width(), layout.imageSize.height());
+ const QRect imageRect(attachmentsRect.x(), imageY, layout.imageSize.width() / dpr, layout.imageSize.height() / dpr);
if (imageRect.contains(pos)) {
auto parentWidget = const_cast<QWidget *>(option.widget);
auto dlg = new ShowImageDialog(mRocketChatAccount, parentWidget);
@@ -259,7 +261,12 @@ QPoint MessageAttachmentDelegateHelperImage::adaptMousePosition(const QPoint &po
const QStyleOptionViewItem &option)
{
const ImageLayout layout = layoutImage(msgAttach, option, attachmentsRect.width(), attachmentsRect.height());
- const QPoint relativePos = pos - attachmentsRect.topLeft() - QPoint(0, layout.imageSize.height() + layout.titleSize.height() + DelegatePaintUtil::margin());
+ // Same vertical layout as draw(): title | margin [| image | margin] | description
+ int descriptionY = layout.titleSize.height() + DelegatePaintUtil::margin();
+ if (layout.isShown && !layout.pixmap.isNull()) {
+ descriptionY += layout.imageSize.height() / layout.pixmap.devicePixelRatioF() + DelegatePaintUtil::margin();
+ }
+ const QPoint relativePos = pos - attachmentsRect.topLeft() - QPoint(0, descriptionY);
return relativePos;
}
diff --git a/src/widgets/room/delegate/messageattachmentdelegatehelpertext.cpp b/src/widgets/room/delegate/messageattachmentdelegatehelpertext.cpp
index 119e07cd1f..fe081814f6 100644
--- a/src/widgets/room/delegate/messageattachmentdelegatehelpertext.cpp
+++ b/src/widgets/room/delegate/messageattachmentdelegatehelpertext.cpp
@@ -85,7 +85,15 @@ QPoint MessageAttachmentDelegateHelperText::adaptMousePosition(const QPoint &pos
QPoint MessageAttachmentDelegateHelperText::relativePos(const QPoint &pos, const TextLayout &layout, QRect attachmentsRect) const
{
- return pos - attachmentsRect.topLeft() - QPoint(0, layout.titleRect.height() + DelegatePaintUtil::margin());
+ // draw() only pushes the document below a title row when there is a title.
+ const int documentY = layout.title.isEmpty() ? 0 : qRound(layout.titleRect.height()) + DelegatePaintUtil::margin();
+ return pos - attachmentsRect.topLeft() - QPoint(0, documentY);
+}
+
+bool MessageAttachmentDelegateHelperText::documentIsShown(const TextLayout &layout)
+{
+ // Same condition as draw(): a collapsed attachment paints its title only, so there is nothing to hit test.
+ return layout.isShown || layout.title.isEmpty();
}
bool MessageAttachmentDelegateHelperText::handleMouseEvent(const MessageAttachment &msgAttach,
@@ -114,15 +122,16 @@ bool MessageAttachmentDelegateHelperText::handleMouseEvent(const MessageAttachme
return true;
}
}
- // Clicks on links
- auto *doc = documentAttachmentForIndex(msgAttach, attachmentsRect.width());
- if (doc) {
- // Fix mouse position (we have layout.titleSize.height() + DelegatePaintUtil::margin() too)
- const QPoint mouseClickPos = relativePos(pos, layout, attachmentsRect);
- const QString link = doc->documentLayout()->anchorAt(mouseClickPos);
- if (!link.isEmpty()) {
- Q_EMIT mRocketChatAccount->openLinkRequested(link);
- return true;
+ // Clicks on links (only when the text is actually painted, see documentIsShown())
+ if (documentIsShown(layout)) {
+ if (auto *doc = documentAttachmentForIndex(msgAttach, attachmentsRect.width())) {
+ // Fix mouse position (we have layout.titleSize.height() + DelegatePaintUtil::margin() too)
+ const QPoint mouseClickPos = relativePos(pos, layout, attachmentsRect);
+ const QString link = doc->documentLayout()->anchorAt(mouseClickPos);
+ if (!link.isEmpty()) {
+ Q_EMIT mRocketChatAccount->openLinkRequested(link);
+ return true;
+ }
}
}
// don't return true here, we need to send mouse release events to other helpers (ex: click on image)
@@ -245,12 +254,15 @@ bool MessageAttachmentDelegateHelperText::handleHelpEvent(QHelpEvent *helpEvent,
}
}
+ if (!documentIsShown(layout)) {
+ return false;
+ }
const auto *doc = documentAttachmentForIndex(msgAttach, messageRect.width());
if (!doc) {
return false;
}
- const QPoint pos = helpEvent->pos() - messageRect.topLeft() - QPoint(0, layout.titleRect.height() + DelegatePaintUtil::margin());
+ const QPoint pos = relativePos(helpEvent->pos(), layout, messageRect);
QString formattedTooltip;
if (MessageDelegateUtils::generateToolTip(doc, pos, formattedTooltip)) {
QToolTip::showText(helpEvent->globalPos(), formattedTooltip);
diff --git a/src/widgets/room/delegate/messageattachmentdelegatehelpertext.h b/src/widgets/room/delegate/messageattachmentdelegatehelpertext.h
index 3ab30b9197..ecaf6515ba 100644
--- a/src/widgets/room/delegate/messageattachmentdelegatehelpertext.h
+++ b/src/widgets/room/delegate/messageattachmentdelegatehelpertext.h
@@ -48,4 +48,5 @@ private:
QRect attachmentsRect,
const QStyleOptionViewItem &option) override;
[[nodiscard]] LIBRUQOLAWIDGETS_NO_EXPORT QPoint relativePos(const QPoint &pos, const TextLayout &layout, QRect attachmentsRect) const;
+ [[nodiscard]] LIBRUQOLAWIDGETS_NO_EXPORT static bool documentIsShown(const TextLayout &layout);
};