From a59d9f85fa770a00d10e66025e102c736e18fa70 Mon Sep 17 00:00:00 2001 From: Amol Godbole Date: Fri, 13 Oct 2023 21:08:35 -0500 Subject: KItemListView: add view position in scrollToItem() An item, on being scrolled to, is always located at the nearest edge of the view. This is not always convenient. Allow specifying where the item should be positioned with respect to the view in scrollToItem(). BUG: 423884 --- src/kitemviews/kitemlistcontroller.cpp | 2 +- src/kitemviews/kitemlistview.cpp | 60 +++++++++++++++++++++++++++------- src/kitemviews/kitemlistview.h | 8 +++-- 3 files changed, 55 insertions(+), 15 deletions(-) (limited to 'src/kitemviews') diff --git a/src/kitemviews/kitemlistcontroller.cpp b/src/kitemviews/kitemlistcontroller.cpp index be7a63e09..0016bb22a 100644 --- a/src/kitemviews/kitemlistcontroller.cpp +++ b/src/kitemviews/kitemlistcontroller.cpp @@ -539,7 +539,7 @@ void KItemListController::slotChangeCurrentItem(const QString &text, bool search m_selectionManager->beginAnchoredSelection(index); } - m_view->scrollToItem(index); + m_view->scrollToItem(index, KItemListView::ViewItemPosition::Beginning); } } diff --git a/src/kitemviews/kitemlistview.cpp b/src/kitemviews/kitemlistview.cpp index 457c02ec5..be22b91cc 100644 --- a/src/kitemviews/kitemlistview.cpp +++ b/src/kitemviews/kitemlistview.cpp @@ -537,7 +537,7 @@ bool KItemListView::isElided(int index) const return m_sizeHintResolver->isElided(index); } -void KItemListView::scrollToItem(int index) +void KItemListView::scrollToItem(int index, ViewItemPosition viewItemPosition) { QRectF viewGeometry = geometry(); if (m_headerWidget->isVisible()) { @@ -546,29 +546,65 @@ void KItemListView::scrollToItem(int index) } QRectF currentRect = itemRect(index); - // Fix for Bug 311099 - View the underscore when using Ctrl + PagDown + // Fix for Bug 311099 - View the underscore when using Ctrl + PageDown currentRect.adjust(-m_styleOption.horizontalMargin, -m_styleOption.verticalMargin, m_styleOption.horizontalMargin, m_styleOption.verticalMargin); - if (!viewGeometry.contains(currentRect)) { - qreal newOffset = scrollOffset(); - if (scrollOrientation() == Qt::Vertical) { + qreal newOffset = scrollOffset(); + if (scrollOrientation() == Qt::Vertical && (currentRect.top() < viewGeometry.top() || currentRect.bottom() > viewGeometry.bottom())) { + switch (viewItemPosition) { + case Beginning: + newOffset += currentRect.top() - viewGeometry.top(); + break; + case Middle: + newOffset += 0.5 * (currentRect.top() + currentRect.bottom() - (viewGeometry.top() + viewGeometry.bottom())); + break; + case End: + newOffset += currentRect.bottom() - viewGeometry.bottom(); + break; + case Nearest: if (currentRect.top() < viewGeometry.top()) { newOffset += currentRect.top() - viewGeometry.top(); - } else if (currentRect.bottom() > viewGeometry.bottom()) { + } else { newOffset += currentRect.bottom() - viewGeometry.bottom(); } - } else { + break; + default: + Q_UNREACHABLE(); + } + } else if (scrollOrientation() == Qt::Horizontal && (currentRect.left() < viewGeometry.left() || currentRect.right() > viewGeometry.right())) { + switch (viewItemPosition) { + case Beginning: + if (layoutDirection() == Qt::RightToLeft) { + newOffset += currentRect.right() - viewGeometry.right(); + } else { + newOffset += currentRect.left() - viewGeometry.left(); + } + break; + case Middle: + newOffset += 0.5 * (currentRect.left() + currentRect.right() - (viewGeometry.left() + viewGeometry.right())); + break; + case End: + if (layoutDirection() == Qt::RightToLeft) { + newOffset += currentRect.left() - viewGeometry.left(); + } else { + newOffset += currentRect.right() - viewGeometry.right(); + } + break; + case Nearest: if (currentRect.left() < viewGeometry.left()) { newOffset += currentRect.left() - viewGeometry.left(); - } else if (currentRect.right() > viewGeometry.right()) { + } else { newOffset += currentRect.right() - viewGeometry.right(); } + break; + default: + Q_UNREACHABLE(); } + } - if (newOffset != scrollOffset()) { - Q_EMIT scrollTo(newOffset); - return; - } + if (newOffset != scrollOffset()) { + Q_EMIT scrollTo(newOffset); + return; } Q_EMIT scrollingStopped(); diff --git a/src/kitemviews/kitemlistview.h b/src/kitemviews/kitemlistview.h index 7bcaec704..8812eb8cc 100644 --- a/src/kitemviews/kitemlistview.h +++ b/src/kitemviews/kitemlistview.h @@ -59,6 +59,9 @@ class DOLPHIN_EXPORT KItemListView : public QGraphicsWidget Q_PROPERTY(qreal itemOffset READ itemOffset WRITE setItemOffset NOTIFY itemOffsetChanged) public: + /** The position in the view to which an item should be scrolled to. */ + enum ViewItemPosition { Beginning, Middle, End, Nearest }; + explicit KItemListView(QGraphicsWidget *parent = nullptr); ~KItemListView() override; @@ -251,9 +254,10 @@ public: /** * Scrolls to the item with the index \a index so that the item - * will be fully visible. + * will be fully visible. The item is positioned within the view + * as specified by \a viewItemPosition. */ - void scrollToItem(int index); + void scrollToItem(int index, ViewItemPosition viewItemPosition = ViewItemPosition::Nearest); /** * If several properties of KItemListView are changed synchronously, it is -- cgit v1.3 From 5c7887a763ea1a58ebcf93c047ab39b00eb6a8eb Mon Sep 17 00:00:00 2001 From: Felix Ernst Date: Mon, 23 Oct 2023 14:26:52 +0000 Subject: Fix rubberband selection on icon in icon view mode As an unintended side-effect of d9a18b04ea0b1b4e427f45083fdc0cdec87cbbfd items would no longer be selected in icon view mode when the selection rectangle intersected with the item's icon. This commit fixes this. --- src/kitemviews/kitemlistcontroller.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/kitemviews') diff --git a/src/kitemviews/kitemlistcontroller.cpp b/src/kitemviews/kitemlistcontroller.cpp index 0016bb22a..5abf1830b 100644 --- a/src/kitemviews/kitemlistcontroller.cpp +++ b/src/kitemviews/kitemlistcontroller.cpp @@ -1299,7 +1299,8 @@ void KItemListController::slotRubberBandChanged() if (widgetRect.intersects(rubberBandRect)) { // Select the full row intersecting with the rubberband rectangle const QRectF selectionRect = widget->selectionRect().translated(widgetRect.topLeft()); - if (selectionRect.intersects(rubberBandRect)) { + const QRectF iconRect = widget->iconRect().translated(widgetRect.topLeft()); + if (selectionRect.intersects(rubberBandRect) || iconRect.intersects(rubberBandRect)) { selectedItems.insert(index); } } -- cgit v1.3 From 8ef3c7bc42bad4397bed0711f4317ebad9c0f8f1 Mon Sep 17 00:00:00 2001 From: Yifan Zhu Date: Sun, 22 Oct 2023 11:54:51 -0700 Subject: Display newline in filename as Unicode line break BUG: 422998 CCBUG: 444747 --- src/kitemviews/kstandarditemlistwidget.cpp | 15 +++++++++++++-- src/kitemviews/kstandarditemlistwidget.h | 7 +++++++ 2 files changed, 20 insertions(+), 2 deletions(-) (limited to 'src/kitemviews') diff --git a/src/kitemviews/kstandarditemlistwidget.cpp b/src/kitemviews/kstandarditemlistwidget.cpp index 01b135038..0088e4116 100644 --- a/src/kitemviews/kstandarditemlistwidget.cpp +++ b/src/kitemviews/kstandarditemlistwidget.cpp @@ -1205,6 +1205,16 @@ QString KStandardItemListWidget::elideRightKeepExtension(const QString &text, in return m_customizedFontMetrics.elidedText(text, Qt::ElideRight, elidingWidth); } +QString KStandardItemListWidget::escapeString(const QString &text) const +{ + QString escaped(text); + + const QChar returnSymbol(0x21b5); + escaped.replace('\n', returnSymbol); + + return escaped; +} + void KStandardItemListWidget::updateIconsLayoutTextCache() { // +------+ @@ -1227,7 +1237,7 @@ void KStandardItemListWidget::updateIconsLayoutTextCache() // Initialize properties for the "text" role. It will be used as anchor // for initializing the position of the other roles. TextInfo *nameTextInfo = m_textInfo.value("text"); - const QString nameText = KStringHandler::preProcessWrap(values["text"].toString()); + const QString nameText = KStringHandler::preProcessWrap(escapeString(values["text"].toString())); nameTextInfo->staticText.setText(nameText); // Calculate the number of lines required for the name and the required width @@ -1348,7 +1358,7 @@ void KStandardItemListWidget::updateCompactLayoutTextCache() qreal y = qRound((widgetHeight - textLinesHeight) / 2); const qreal maxWidth = size().width() - x - option.padding; for (const QByteArray &role : qAsConst(m_sortedVisibleRoles)) { - const QString text = roleText(role, values); + const QString text = escapeString(roleText(role, values)); TextInfo *textInfo = m_textInfo.value(role); textInfo->staticText.setText(text); @@ -1407,6 +1417,7 @@ void KStandardItemListWidget::updateDetailsLayoutTextCache() const bool isTextRole = (role == "text"); if (isTextRole) { + text = escapeString(text); availableTextWidth -= firstColumnInc - sidePadding(); } diff --git a/src/kitemviews/kstandarditemlistwidget.h b/src/kitemviews/kstandarditemlistwidget.h index c4f80af1d..52cde1423 100644 --- a/src/kitemviews/kstandarditemlistwidget.h +++ b/src/kitemviews/kstandarditemlistwidget.h @@ -208,6 +208,13 @@ private: QString elideRightKeepExtension(const QString &text, int elidingWidth) const; + /** + * Escapes text for display purposes. + * + * Replaces '\n' with Unicode line break (U+21B5). + */ + QString escapeString(const QString &text) const; + /** * Closes the role editor and returns the focus back * to the KItemListContainer. -- cgit v1.3