mirror of
https://invent.kde.org/system/dolphin
synced 2024-11-05 18:47:12 +00:00
Make the handling of the "maximum text lines" setting more robust
If the user sets a maximum number of text lines in the settings, this number was translated into a maximum height in pixels using QFontMetrics::lineSpacing() before this commit. In KStandardItemListWidgetInformant::itemSizeHint(), this maximum height limited the size that is reserved for the item. However, in KStandardItemListWidget::updateIconsLayoutTextCache(), the maximum height was translated back into a maximum number of lines, which limits the number of lines that are created using the QTextLayout. This approach could lead to problems if the real height of the layouted text is 1 pixel more or less than QFontMetrics::lineSpacing() times "number of lines". Now we do not store a "maximum height" inside the "maximum size" explicitly, but store a maximum number of lines and a maximum with (for Compact View) separately, and then use the number of lines also to calculate the required size in KStandardItemListWidgetInformant::itemSizeHint(). This should make sure that the correct height is reserved for each item. Thanks to Christoph Feck and Emmanuel Pescosta for helping to debug this problem and testing the patch. BUG: 323841 FIXED-IN: 4.13 REVIEW: 113871
This commit is contained in:
parent
0d37038b40
commit
342822e83d
5 changed files with 23 additions and 25 deletions
|
@ -31,7 +31,8 @@ KItemListStyleOption::KItemListStyleOption() :
|
||||||
verticalMargin(-1),
|
verticalMargin(-1),
|
||||||
iconSize(-1),
|
iconSize(-1),
|
||||||
extendedSelectionRegion(false),
|
extendedSelectionRegion(false),
|
||||||
maxTextSize()
|
maxTextLines(0),
|
||||||
|
maxTextWidth(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +46,8 @@ KItemListStyleOption::KItemListStyleOption(const KItemListStyleOption& other) :
|
||||||
verticalMargin(other.verticalMargin),
|
verticalMargin(other.verticalMargin),
|
||||||
iconSize(other.iconSize),
|
iconSize(other.iconSize),
|
||||||
extendedSelectionRegion(other.extendedSelectionRegion),
|
extendedSelectionRegion(other.extendedSelectionRegion),
|
||||||
maxTextSize(other.maxTextSize)
|
maxTextLines(other.maxTextLines),
|
||||||
|
maxTextWidth(other.maxTextWidth)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,8 @@ public:
|
||||||
int verticalMargin;
|
int verticalMargin;
|
||||||
int iconSize;
|
int iconSize;
|
||||||
bool extendedSelectionRegion;
|
bool extendedSelectionRegion;
|
||||||
QSize maxTextSize;
|
int maxTextLines;
|
||||||
|
int maxTextWidth;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -760,7 +760,8 @@ void KItemListView::setStyleOption(const KItemListStyleOption& option)
|
||||||
updateGroupHeaderHeight();
|
updateGroupHeaderHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (animate && previousOption.maxTextSize != option.maxTextSize) {
|
if (animate &&
|
||||||
|
(previousOption.maxTextLines != option.maxTextLines || previousOption.maxTextWidth != option.maxTextWidth)) {
|
||||||
// Animating a change of the maximum text size just results in expensive
|
// Animating a change of the maximum text size just results in expensive
|
||||||
// temporary eliding and clipping operations and does not look good visually.
|
// temporary eliding and clipping operations and does not look good visually.
|
||||||
animate = false;
|
animate = false;
|
||||||
|
|
|
@ -130,7 +130,6 @@ void KStandardItemListWidgetInformant::calculateIconsLayoutItemSizeHints(QVector
|
||||||
|
|
||||||
const qreal itemWidth = view->itemSize().width();
|
const qreal itemWidth = view->itemSize().width();
|
||||||
const qreal maxWidth = itemWidth - 2 * option.padding;
|
const qreal maxWidth = itemWidth - 2 * option.padding;
|
||||||
const qreal maxTextHeight = option.maxTextSize.height();
|
|
||||||
const qreal additionalRolesSpacing = additionalRolesCount * option.fontMetrics.lineSpacing();
|
const qreal additionalRolesSpacing = additionalRolesCount * option.fontMetrics.lineSpacing();
|
||||||
const qreal spacingAndIconHeight = option.iconSize + option.padding * 3;
|
const qreal spacingAndIconHeight = option.iconSize + option.padding * 3;
|
||||||
|
|
||||||
|
@ -150,20 +149,22 @@ void KStandardItemListWidgetInformant::calculateIconsLayoutItemSizeHints(QVector
|
||||||
layout.setTextOption(textOption);
|
layout.setTextOption(textOption);
|
||||||
layout.beginLayout();
|
layout.beginLayout();
|
||||||
QTextLine line;
|
QTextLine line;
|
||||||
|
int lineCount = 0;
|
||||||
while ((line = layout.createLine()).isValid()) {
|
while ((line = layout.createLine()).isValid()) {
|
||||||
line.setLineWidth(maxWidth);
|
line.setLineWidth(maxWidth);
|
||||||
line.naturalTextWidth();
|
line.naturalTextWidth();
|
||||||
textHeight += line.height();
|
textHeight += line.height();
|
||||||
|
|
||||||
|
++lineCount;
|
||||||
|
if (lineCount == option.maxTextLines) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
layout.endLayout();
|
layout.endLayout();
|
||||||
|
|
||||||
// Add one line for each additional information
|
// Add one line for each additional information
|
||||||
textHeight += additionalRolesSpacing;
|
textHeight += additionalRolesSpacing;
|
||||||
|
|
||||||
if (maxTextHeight > 0 && textHeight > maxTextHeight) {
|
|
||||||
textHeight = maxTextHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
sizeHints[index] = QSizeF(itemWidth, textHeight + spacingAndIconHeight);
|
sizeHints[index] = QSizeF(itemWidth, textHeight + spacingAndIconHeight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -176,7 +177,7 @@ void KStandardItemListWidgetInformant::calculateCompactLayoutItemSizeHints(QVect
|
||||||
|
|
||||||
const QList<QByteArray>& visibleRoles = view->visibleRoles();
|
const QList<QByteArray>& visibleRoles = view->visibleRoles();
|
||||||
const bool showOnlyTextRole = (visibleRoles.count() == 1) && (visibleRoles.first() == "text");
|
const bool showOnlyTextRole = (visibleRoles.count() == 1) && (visibleRoles.first() == "text");
|
||||||
const qreal maxWidth = option.maxTextSize.width();
|
const qreal maxWidth = option.maxTextWidth;
|
||||||
const qreal paddingAndIconWidth = option.padding * 4 + option.iconSize;
|
const qreal paddingAndIconWidth = option.padding * 4 + option.iconSize;
|
||||||
const qreal height = option.padding * 2 + qMax(option.iconSize, (1 + additionalRolesCount) * option.fontMetrics.lineSpacing());
|
const qreal height = option.padding * 2 + qMax(option.iconSize, (1 + additionalRolesCount) * option.fontMetrics.lineSpacing());
|
||||||
|
|
||||||
|
@ -1066,9 +1067,6 @@ void KStandardItemListWidget::updateIconsLayoutTextCache()
|
||||||
qreal nameHeight = 0;
|
qreal nameHeight = 0;
|
||||||
QTextLine line;
|
QTextLine line;
|
||||||
|
|
||||||
const int additionalRolesCount = qMax(visibleRoles().count() - 1, 0);
|
|
||||||
const int maxNameLines = (option.maxTextSize.height() / int(lineSpacing)) - additionalRolesCount;
|
|
||||||
|
|
||||||
QTextLayout layout(nameTextInfo->staticText.text(), m_customizedFont);
|
QTextLayout layout(nameTextInfo->staticText.text(), m_customizedFont);
|
||||||
layout.setTextOption(nameTextInfo->staticText.textOption());
|
layout.setTextOption(nameTextInfo->staticText.textOption());
|
||||||
layout.beginLayout();
|
layout.beginLayout();
|
||||||
|
@ -1079,7 +1077,7 @@ void KStandardItemListWidget::updateIconsLayoutTextCache()
|
||||||
nameHeight += line.height();
|
nameHeight += line.height();
|
||||||
|
|
||||||
++nameLineIndex;
|
++nameLineIndex;
|
||||||
if (nameLineIndex == maxNameLines) {
|
if (nameLineIndex == option.maxTextLines) {
|
||||||
// The maximum number of textlines has been reached. If this is
|
// The maximum number of textlines has been reached. If this is
|
||||||
// the case provide an elided text if necessary.
|
// the case provide an elided text if necessary.
|
||||||
const int textLength = line.textStart() + line.textLength();
|
const int textLength = line.textStart() + line.textLength();
|
||||||
|
@ -1101,6 +1099,7 @@ void KStandardItemListWidget::updateIconsLayoutTextCache()
|
||||||
layout.endLayout();
|
layout.endLayout();
|
||||||
|
|
||||||
// Use one line for each additional information
|
// Use one line for each additional information
|
||||||
|
const int additionalRolesCount = qMax(visibleRoles().count() - 1, 0);
|
||||||
nameTextInfo->staticText.setTextWidth(maxWidth);
|
nameTextInfo->staticText.setTextWidth(maxWidth);
|
||||||
nameTextInfo->pos = QPointF(padding, widgetHeight -
|
nameTextInfo->pos = QPointF(padding, widgetHeight -
|
||||||
nameHeight -
|
nameHeight -
|
||||||
|
|
|
@ -180,7 +180,8 @@ void DolphinItemListView::updateGridSize()
|
||||||
// Calculate the item-width and item-height
|
// Calculate the item-width and item-height
|
||||||
int itemWidth;
|
int itemWidth;
|
||||||
int itemHeight;
|
int itemHeight;
|
||||||
QSize maxTextSize;
|
int maxTextLines = 0;
|
||||||
|
int maxTextWidth = 0;
|
||||||
|
|
||||||
switch (itemLayout()) {
|
switch (itemLayout()) {
|
||||||
case KFileItemListView::IconsLayout: {
|
case KFileItemListView::IconsLayout: {
|
||||||
|
@ -200,16 +201,10 @@ void DolphinItemListView::updateGridSize()
|
||||||
}
|
}
|
||||||
|
|
||||||
itemHeight = padding * 3 + iconSize + option.fontMetrics.lineSpacing();
|
itemHeight = padding * 3 + iconSize + option.fontMetrics.lineSpacing();
|
||||||
if (IconsModeSettings::maximumTextLines() > 0) {
|
|
||||||
// A restriction is given for the maximum number of textlines (0 means
|
|
||||||
// having no restriction)
|
|
||||||
const int additionalInfoCount = visibleRoles().count() - 1;
|
|
||||||
const int maxAdditionalLines = additionalInfoCount + IconsModeSettings::maximumTextLines();
|
|
||||||
maxTextSize.rheight() = option.fontMetrics.lineSpacing() * maxAdditionalLines;
|
|
||||||
}
|
|
||||||
|
|
||||||
horizontalMargin = 4;
|
horizontalMargin = 4;
|
||||||
verticalMargin = 8;
|
verticalMargin = 8;
|
||||||
|
maxTextLines = IconsModeSettings::maximumTextLines();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case KFileItemListView::CompactLayout: {
|
case KFileItemListView::CompactLayout: {
|
||||||
|
@ -220,8 +215,7 @@ void DolphinItemListView::updateGridSize()
|
||||||
if (CompactModeSettings::maximumTextWidthIndex() > 0) {
|
if (CompactModeSettings::maximumTextWidthIndex() > 0) {
|
||||||
// A restriction is given for the maximum width of the text (0 means
|
// A restriction is given for the maximum width of the text (0 means
|
||||||
// having no restriction)
|
// having no restriction)
|
||||||
maxTextSize.rwidth() = option.fontMetrics.height() * 10 *
|
maxTextWidth = option.fontMetrics.height() * 10 * CompactModeSettings::maximumTextWidthIndex();
|
||||||
CompactModeSettings::maximumTextWidthIndex();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
horizontalMargin = 8;
|
horizontalMargin = 8;
|
||||||
|
@ -244,7 +238,8 @@ void DolphinItemListView::updateGridSize()
|
||||||
option.horizontalMargin = horizontalMargin;
|
option.horizontalMargin = horizontalMargin;
|
||||||
option.verticalMargin = verticalMargin;
|
option.verticalMargin = verticalMargin;
|
||||||
option.iconSize = iconSize;
|
option.iconSize = iconSize;
|
||||||
option.maxTextSize = maxTextSize;
|
option.maxTextLines = maxTextLines;
|
||||||
|
option.maxTextWidth = maxTextWidth;
|
||||||
beginTransaction();
|
beginTransaction();
|
||||||
setStyleOption(option);
|
setStyleOption(option);
|
||||||
setItemSize(QSizeF(itemWidth, itemHeight));
|
setItemSize(QSizeF(itemWidth, itemHeight));
|
||||||
|
|
Loading…
Reference in a new issue