case IconsLayout: {
const QString text = KStringHandler::preProcessWrap(values["name"].toString());
- const qreal maxWidth = view->itemSize().width() - 2 * option.padding;
+ const qreal itemWidth = view->itemSize().width();
+ const qreal maxWidth = itemWidth - 2 * option.padding;
QTextLine line;
// Calculate the number of lines required for wrapping the name
layout.endLayout();
// Add one line for each additional information
- const qreal height = textHeight +
- additionalRolesCount * option.fontMetrics.lineSpacing() +
- option.iconSize +
- option.padding * 3;
- return QSizeF(view->itemSize().width(), height);
+ textHeight += additionalRolesCount * option.fontMetrics.lineSpacing();
+
+ const qreal maxTextHeight = option.maxTextSize.height();
+ if (maxTextHeight > 0 && textHeight > maxTextHeight) {
+ textHeight = maxTextHeight;
+ }
+
+ return QSizeF(itemWidth, textHeight + option.iconSize + option.padding * 3);
}
case CompactLayout: {
maximumRequiredWidth = qMax(maximumRequiredWidth, requiredWidth);
}
- const qreal width = option.padding * 4 + option.iconSize + maximumRequiredWidth;
+ qreal width = option.padding * 4 + option.iconSize + maximumRequiredWidth;
+ const qreal maxWidth = option.maxTextSize.width();
+ if (maxWidth > 0 && width > maxWidth) {
+ width = maxWidth;
+ }
const qreal height = option.padding * 2 + qMax(option.iconSize, (1 + additionalRolesCount) * option.fontMetrics.lineSpacing());
return QSizeF(width, height);
}
// Initialize properties for the "name" role. It will be used as anchor
// for initializing the position of the other roles.
TextInfo* nameTextInfo = m_textInfo.value("name");
- nameTextInfo->staticText.setText(KStringHandler::preProcessWrap(values["name"].toString()));
+ const QString nameText = KStringHandler::preProcessWrap(values["name"].toString());
+ nameTextInfo->staticText.setText(nameText);
// Calculate the number of lines required for the name and the required width
qreal nameWidth = 0;
qreal nameHeight = 0;
QTextLine line;
+ const int additionalRolesCount = qMax(visibleRoles().count() - 1, 0);
+ const int maxNameLines = (option.maxTextSize.height() / int(lineSpacing)) - additionalRolesCount;
+
QTextLayout layout(nameTextInfo->staticText.text(), option.font);
layout.setTextOption(nameTextInfo->staticText.textOption());
layout.beginLayout();
+ int nameLineIndex = 0;
while ((line = layout.createLine()).isValid()) {
line.setLineWidth(maxWidth);
nameWidth = qMax(nameWidth, line.naturalTextWidth());
nameHeight += line.height();
+
+ ++nameLineIndex;
+ if (nameLineIndex == maxNameLines) {
+ // The maximum number of textlines has been reached. If this is
+ // the case provide an elided text if necessary.
+ const int textLength = line.textStart() + line.textLength();
+ if (textLength < nameText.length()) {
+ // Elide the last line of the text
+ QString lastTextLine = nameText.mid(line.textStart(), line.textLength());
+ lastTextLine = option.fontMetrics.elidedText(lastTextLine,
+ Qt::ElideRight,
+ line.naturalTextWidth() - 1);
+ const QString elidedText = nameText.left(line.textStart()) + lastTextLine;
+ nameTextInfo->staticText.setText(elidedText);
+ }
+ break;
+ }
}
layout.endLayout();
// Use one line for each additional information
- const int additionalRolesCount = qMax(visibleRoles().count() - 1, 0);
nameTextInfo->staticText.setTextWidth(maxWidth);
nameTextInfo->pos = QPointF(padding, widgetHeight -
nameHeight -
horizontalMargin(0),
verticalMargin(0),
iconSize(KIconLoader::SizeMedium),
- extendedSelectionRegion(false)
+ extendedSelectionRegion(false),
+ maxTextSize()
{
}
horizontalMargin(other.horizontalMargin),
verticalMargin(other.verticalMargin),
iconSize(other.iconSize),
- extendedSelectionRegion(other.extendedSelectionRegion)
+ extendedSelectionRegion(other.extendedSelectionRegion),
+ maxTextSize(other.maxTextSize)
{
}
int verticalMargin;
int iconSize;
bool extendedSelectionRegion;
+ QSize maxTextSize;
};
#endif
return m_layouter->scrollOrientation();
}
-void KItemListView::setItemSize(const QSizeF& itemSize)
+void KItemListView::setItemSize(const QSizeF& size)
{
const QSizeF previousSize = m_itemSize;
- if (itemSize == previousSize) {
+ if (size == previousSize) {
return;
}
// are changed in the grid layout. Although the animation
// engine can handle this usecase, it looks obtrusive.
const bool animate = !changesItemGridLayout(m_layouter->size(),
- itemSize,
+ size,
m_layouter->itemMargin());
const bool alternateBackgroundsChanged = (m_visibleRoles.count() > 1) &&
- (( m_itemSize.isEmpty() && !itemSize.isEmpty()) ||
- (!m_itemSize.isEmpty() && itemSize.isEmpty()));
+ (( m_itemSize.isEmpty() && !size.isEmpty()) ||
+ (!m_itemSize.isEmpty() && size.isEmpty()));
- m_itemSize = itemSize;
+ m_itemSize = size;
if (alternateBackgroundsChanged) {
// For an empty item size alternate backgrounds are drawn if more than
updateAlternateBackgrounds();
}
- if (itemSize.isEmpty()) {
+ if (size.isEmpty()) {
if (m_headerWidget->automaticColumnResizing()) {
updatePreferredColumnWidths();
} else {
// Only apply the changed height and respect the header widths
// set by the user
const qreal currentWidth = m_layouter->itemSize().width();
- const QSizeF newSize(currentWidth, itemSize.height());
+ const QSizeF newSize(currentWidth, size.height());
m_layouter->setItemSize(newSize);
}
} else {
- m_layouter->setItemSize(itemSize);
+ m_layouter->setItemSize(size);
}
m_sizeHintResolver->clearCache();
doLayout(animate ? Animation : NoAnimation);
- onItemSizeChanged(itemSize, previousSize);
+ onItemSizeChanged(size, previousSize);
}
QSizeF KItemListView::itemSize() const
updateGroupHeaderHeight();
}
+ if (animate && previousOption.maxTextSize != option.maxTextSize) {
+ // Animating a change of the maximum text size just results in expensive
+ // temporary eliding and clipping operations and does not look good visually.
+ animate = false;
+ }
+
QHashIterator<int, KItemListWidget*> it(m_visibleItems);
while (it.hasNext()) {
it.next();
}
m_sizeHintResolver->clearCache();
+ m_layouter->markAsDirty();
doLayout(animate ? Animation : NoAnimation);
onStyleOptionChanged(option, previousOption);
<label>Preview size</label>
<default code="true">KIconLoader::SizeLarge</default>
</entry>
+ <entry name="MaximumTextWidthIndex" type="Int">
+ <label>Maximum text width index (0 means unlimited)</label>
+ <default>0</default>
+ </entry>
</group>
</kcfg>
<label>Text width index</label>
<default>1</default>
</entry>
+ <entry name="MaximumTextLines" type="Int">
+ <label>Maximum textlines (0 means unlimited)</label>
+ <default>0</default>
+ </entry>
</group>
</kcfg>
m_defaultSizeSlider(0),
m_previewSizeSlider(0),
m_fontRequester(0),
- m_textWidthBox(0),
+ m_widthBox(0),
+ m_maxLinesBox(0),
m_expandableFolders(0)
{
QVBoxLayout* topLayout = new QVBoxLayout(this);
switch (m_mode) {
case IconsMode: {
- QLabel* textWidthLabel = new QLabel(i18nc("@label:listbox", "Text width:"), textGroup);
- m_textWidthBox = new KComboBox(textGroup);
- m_textWidthBox->addItem(i18nc("@item:inlistbox Text width", "Small"));
- m_textWidthBox->addItem(i18nc("@item:inlistbox Text width", "Medium"));
- m_textWidthBox->addItem(i18nc("@item:inlistbox Text width", "Large"));
- m_textWidthBox->addItem(i18nc("@item:inlistbox Text width", "Huge"));
-
- textGroupLayout->addWidget(textWidthLabel, 2, 0, Qt::AlignRight);
- textGroupLayout->addWidget(m_textWidthBox, 2, 1);
+ QLabel* widthLabel = new QLabel(i18nc("@label:listbox", "Width:"), textGroup);
+ m_widthBox = new KComboBox(textGroup);
+ m_widthBox->addItem(i18nc("@item:inlistbox Text width", "Small"));
+ m_widthBox->addItem(i18nc("@item:inlistbox Text width", "Medium"));
+ m_widthBox->addItem(i18nc("@item:inlistbox Text width", "Large"));
+ m_widthBox->addItem(i18nc("@item:inlistbox Text width", "Huge"));
+
+ QLabel* maxLinesLabel = new QLabel(i18nc("@label:listbox", "Maximum lines:"), textGroup);
+ m_maxLinesBox = new KComboBox(textGroup);
+ m_maxLinesBox->addItem(i18nc("@item:inlistbox Maximum lines", "Unlimited"));
+ m_maxLinesBox->addItem(i18nc("@item:inlistbox Maximum lines", "1"));
+ m_maxLinesBox->addItem(i18nc("@item:inlistbox Maximum lines", "2"));
+ m_maxLinesBox->addItem(i18nc("@item:inlistbox Maximum lines", "3"));
+ m_maxLinesBox->addItem(i18nc("@item:inlistbox Maximum lines", "4"));
+ m_maxLinesBox->addItem(i18nc("@item:inlistbox Maximum lines", "5"));
+
+ textGroupLayout->addWidget(widthLabel, 2, 0, Qt::AlignRight);
+ textGroupLayout->addWidget(m_widthBox, 2, 1);
+ textGroupLayout->addWidget(maxLinesLabel, 3, 0, Qt::AlignRight);
+ textGroupLayout->addWidget(m_maxLinesBox, 3, 1);
+ break;
+ }
+ case CompactMode: {
+ QLabel* maxWidthLabel = new QLabel(i18nc("@label:listbox", "Maximum width:"), textGroup);
+ m_widthBox = new KComboBox(textGroup);
+ m_widthBox->addItem(i18nc("@item:inlistbox Maximum width", "Unlimited"));
+ m_widthBox->addItem(i18nc("@item:inlistbox Maximum width", "Small"));
+ m_widthBox->addItem(i18nc("@item:inlistbox Maximum width", "Medium"));
+ m_widthBox->addItem(i18nc("@item:inlistbox Maximum width", "Large"));
+
+ textGroupLayout->addWidget(maxWidthLabel, 2, 0, Qt::AlignRight);
+ textGroupLayout->addWidget(m_widthBox, 2, 1);
break;
}
case DetailsMode:
switch (m_mode) {
case IconsMode:
- connect(m_textWidthBox, SIGNAL(currentIndexChanged(int)), this, SIGNAL(changed()));
+ connect(m_widthBox, SIGNAL(currentIndexChanged(int)), this, SIGNAL(changed()));
+ connect(m_maxLinesBox, SIGNAL(currentIndexChanged(int)), this, SIGNAL(changed()));
+ break;
+ case CompactMode:
+ connect(m_widthBox, SIGNAL(currentIndexChanged(int)), this, SIGNAL(changed()));
break;
case DetailsMode:
connect(m_expandableFolders, SIGNAL(toggled(bool)), this, SIGNAL(changed()));
switch (m_mode) {
case IconsMode:
- IconsModeSettings::setTextWidthIndex(m_textWidthBox->currentIndex());
+ IconsModeSettings::setTextWidthIndex(m_widthBox->currentIndex());
+ IconsModeSettings::setMaximumTextLines(m_maxLinesBox->currentIndex());
+ break;
+ case CompactMode:
+ CompactModeSettings::setMaximumTextWidthIndex(m_widthBox->currentIndex());
break;
case DetailsMode:
DetailsModeSettings::setExpandableFolders(m_expandableFolders->isChecked());
{
switch (m_mode) {
case IconsMode:
- m_textWidthBox->setCurrentIndex(IconsModeSettings::textWidthIndex());
+ m_widthBox->setCurrentIndex(IconsModeSettings::textWidthIndex());
+ m_maxLinesBox->setCurrentIndex(IconsModeSettings::maximumTextLines());
+ break;
+ case CompactMode:
+ m_widthBox->setCurrentIndex(CompactModeSettings::maximumTextWidthIndex());
break;
case DetailsMode:
m_expandableFolders->setChecked(DetailsModeSettings::expandableFolders());
QSlider* m_previewSizeSlider;
DolphinFontRequester* m_fontRequester;
- KComboBox* m_textWidthBox;
+ KComboBox* m_widthBox;
+ KComboBox* m_maxLinesBox;
QCheckBox* m_expandableFolders;
};
// Calculate the item-width and item-height
int itemWidth;
int itemHeight;
+ QSize maxTextSize;
+
switch (itemLayout()) {
case KFileItemListView::IconsLayout: {
const int minItemWidth = 48;
if (itemWidth < iconSize + padding * 2) {
itemWidth = iconSize + padding * 2;
}
- itemHeight = padding * 3 + iconSize + styleOption.fontMetrics.height();
+
+ itemHeight = padding * 3 + iconSize + styleOption.fontMetrics.lineSpacing();
+ if (IconsModeSettings::maximumTextLines() > 0) {
+ // A restriction is given for the maximum number of textlines (0 means
+ // having no restriction)
+ const int additionalInfoCount = m_fileItemListView->visibleRoles().count() - 1;
+ const int maxAdditionalLines = additionalInfoCount + IconsModeSettings::maximumTextLines();
+ maxTextSize.rheight() = styleOption.fontMetrics.lineSpacing() * maxAdditionalLines;
+ }
horizontalMargin = 4;
verticalMargin = 8;
case KFileItemListView::CompactLayout: {
itemWidth = padding * 4 + iconSize + styleOption.fontMetrics.height() * 5;
const int textLinesCount = m_fileItemListView->visibleRoles().count();
- itemHeight = padding * 2 + qMax(iconSize, textLinesCount * styleOption.fontMetrics.height());
+ itemHeight = padding * 2 + qMax(iconSize, textLinesCount * styleOption.fontMetrics.lineSpacing());
+
+ if (CompactModeSettings::maximumTextWidthIndex() > 0) {
+ // A restriction is given for the maximum width of the text (0 means
+ // having no restriction)
+ maxTextSize.rwidth() = styleOption.fontMetrics.height() * 10 *
+ CompactModeSettings::maximumTextWidthIndex();
+ }
horizontalMargin = 8;
break;
}
case KFileItemListView::DetailsLayout: {
itemWidth = -1;
- itemHeight = padding * 2 + qMax(iconSize, styleOption.fontMetrics.height());
+ itemHeight = padding * 2 + qMax(iconSize, styleOption.fontMetrics.lineSpacing());
break;
}
default:
styleOption.horizontalMargin = horizontalMargin;
styleOption.verticalMargin = verticalMargin;
styleOption.iconSize = iconSize;
+ styleOption.maxTextSize = maxTextSize;
m_fileItemListView->beginTransaction();
m_fileItemListView->setStyleOption(styleOption);
m_fileItemListView->setItemSize(QSizeF(itemWidth, itemHeight));