#include <KRatingPainter>
#include <KStringHandler>
+#include <QApplication>
#include <QGraphicsScene>
#include <QGraphicsSceneResizeEvent>
#include <QGraphicsView>
{
}
-void KStandardItemListWidgetInformant::calculateItemSizeHints(QVector<qreal>& logicalHeightHints, qreal& logicalWidthHint, const KItemListView* view) const
+void KStandardItemListWidgetInformant::calculateItemSizeHints(QVector<std::pair<qreal, bool>>& logicalHeightHints, qreal& logicalWidthHint, const KItemListView* view) const
{
switch (static_cast<const KStandardItemListView*>(view)->itemLayout()) {
case KStandardItemListView::IconsLayout:
return baseFont;
}
-void KStandardItemListWidgetInformant::calculateIconsLayoutItemSizeHints(QVector<qreal>& logicalHeightHints, qreal& logicalWidthHint, const KItemListView* view) const
+void KStandardItemListWidgetInformant::calculateIconsLayoutItemSizeHints(QVector<std::pair<qreal, bool>>& logicalHeightHints, qreal& logicalWidthHint, const KItemListView* view) const
{
const KItemListStyleOption& option = view->styleOption();
const QFont& normalFont = option.font;
textOption.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
for (int index = 0; index < logicalHeightHints.count(); ++index) {
- if (logicalHeightHints.at(index) > 0.0) {
+ if (logicalHeightHints.at(index).first > 0.0) {
continue;
}
const QFont& font = itemIsLink(index, view) ? linkFont : normalFont;
const QString& text = KStringHandler::preProcessWrap(itemText(index, view));
-
+
// Calculate the number of lines required for wrapping the name
qreal textHeight = 0;
QTextLayout layout(text, font);
layout.beginLayout();
QTextLine line;
int lineCount = 0;
+ bool isElided = false;
while ((line = layout.createLine()).isValid()) {
line.setLineWidth(maxWidth);
line.naturalTextWidth();
++lineCount;
if (lineCount == option.maxTextLines) {
+ isElided = layout.createLine().isValid();
break;
}
}
// Add one line for each additional information
textHeight += additionalRolesSpacing;
- logicalHeightHints[index] = textHeight + spacingAndIconHeight;
+ logicalHeightHints[index].first = textHeight + spacingAndIconHeight;
+ logicalHeightHints[index].second = isElided;
}
logicalWidthHint = itemWidth;
}
-void KStandardItemListWidgetInformant::calculateCompactLayoutItemSizeHints(QVector<qreal>& logicalHeightHints, qreal& logicalWidthHint, const KItemListView* view) const
+void KStandardItemListWidgetInformant::calculateCompactLayoutItemSizeHints(QVector<std::pair<qreal, bool>>& logicalHeightHints, qreal& logicalWidthHint, const KItemListView* view) const
{
const KItemListStyleOption& option = view->styleOption();
const QFontMetrics& normalFontMetrics = option.fontMetrics;
const QFontMetrics linkFontMetrics(customizedFontForLinks(option.font));
for (int index = 0; index < logicalHeightHints.count(); ++index) {
- if (logicalHeightHints.at(index) > 0.0) {
+ if (logicalHeightHints.at(index).first > 0.0) {
continue;
}
width = maxWidth;
}
- logicalHeightHints[index] = width;
+ logicalHeightHints[index].first = width;
}
logicalWidthHint = height;
}
-void KStandardItemListWidgetInformant::calculateDetailsLayoutItemSizeHints(QVector<qreal>& logicalHeightHints, qreal& logicalWidthHint, const KItemListView* view) const
+void KStandardItemListWidgetInformant::calculateDetailsLayoutItemSizeHints(QVector<std::pair<qreal, bool>>& logicalHeightHints, qreal& logicalWidthHint, const KItemListView* view) const
{
const KItemListStyleOption& option = view->styleOption();
- const qreal height = option.padding * 2 + qMax(option.iconSize, option.fontMetrics.height());
- logicalHeightHints.fill(height);
+
+ float zoomLevel = 1;
+ if (option.iconSize >= KIconLoader::SizeEnormous) {
+ zoomLevel = 2;
+ } else if (option.iconSize >= KIconLoader::SizeHuge) {
+ zoomLevel = 1.8;
+ } else if (option.iconSize >= KIconLoader::SizeLarge) {
+ zoomLevel = 1.6;
+ } else if (option.iconSize >= KIconLoader::SizeMedium) {
+ zoomLevel = 1.4;
+ } else if (option.iconSize >= KIconLoader::SizeSmallMedium) {
+ zoomLevel = 1.2;
+ }
+
+ const qreal contentHeight = qMax<qreal>(option.iconSize, zoomLevel * option.fontMetrics.height());
+ logicalHeightHints.fill(std::make_pair(contentHeight + 2 * option.padding, false));
logicalWidthHint = -1.0;
}
KStandardItemListWidget::KStandardItemListWidget(KItemListWidgetInformant* informant, QGraphicsItem* parent) :
KItemListWidget(informant, parent),
+ m_textInfo(),
m_isCut(false),
m_isHidden(false),
m_customizedFont(),
m_scaledPixmapSize(),
m_iconRect(),
m_hoverPixmap(),
- m_textInfo(),
m_textRect(),
m_sortedVisibleRoles(),
m_expansionArea(),
}
const KItemListStyleOption& itemListStyleOption = styleOption();
- if (isHovered()) {
+ if (isHovered() && !m_pixmap.isNull()) {
if (hoverOpacity() < 1.0) {
/*
* Linear interpolation between m_pixmap and m_hoverPixmap.
} else {
drawPixmap(painter, m_hoverPixmap);
}
- } else {
+ } else if (!m_pixmap.isNull()) {
drawPixmap(painter, m_pixmap);
}
m_dirtyContent = true;
}
+void KStandardItemListWidget::invalidateIconCache()
+{
+ m_dirtyContent = true;
+ m_dirtyContentRoles.insert("iconPixmap");
+ m_dirtyContentRoles.insert("iconOverlays");
+}
+
void KStandardItemListWidget::refreshCache()
{
}
m_roleEditor = new KItemListRoleEditor(parent);
m_roleEditor->setRole(current);
+ m_roleEditor->setAllowUpDownKeyChainEdit(m_layout != IconsLayout);
m_roleEditor->setFont(styleOption().font);
const QString text = data().value(current).toString();
}
if (updatePixmap) {
- m_pixmap = values["iconPixmap"].value<QPixmap>();
+ m_pixmap = QPixmap();
+
+ int sequenceIndex = hoverSequenceIndex();
+
+ if (values.contains("hoverSequencePixmaps")) {
+ // Use one of the hover sequence pixmaps instead of the default
+ // icon pixmap.
+
+ const QVector<QPixmap> pixmaps = values["hoverSequencePixmaps"].value<QVector<QPixmap>>();
+
+ if (values.contains("hoverSequenceWraparoundPoint")) {
+ const float wap = values["hoverSequenceWraparoundPoint"].toFloat();
+ if (wap >= 1.0f) {
+ sequenceIndex %= static_cast<int>(wap);
+ }
+ }
+
+ const int loadedIndex = qMax(qMin(sequenceIndex, pixmaps.size()-1), 0);
+
+ if (loadedIndex != 0) {
+ m_pixmap = pixmaps[loadedIndex];
+ }
+ }
+
+ if (m_pixmap.isNull()) {
+ m_pixmap = values["iconPixmap"].value<QPixmap>();
+ }
+
if (m_pixmap.isNull()) {
// Use the icon that fits to the MIME-type
QString iconName = values["iconName"].toString();
KPixmapModifier::scale(m_pixmap, QSize(maxIconWidth, maxIconHeight) * qApp->devicePixelRatio());
}
+ if (m_pixmap.isNull()) {
+ m_hoverPixmap = QPixmap();
+ return;
+ }
+
if (m_isCut) {
KIconEffect* effect = KIconLoader::global()->iconEffect();
m_pixmap = effect->apply(m_pixmap, KIconLoader::Desktop, KIconLoader::DisabledState);
if (m_layout == IconsLayout && isSelected()) {
const QColor color = palette().brush(QPalette::Normal, QPalette::Highlight).color();
QImage image = m_pixmap.toImage();
+ if (image.isNull()) {
+ m_hoverPixmap = QPixmap();
+ return;
+ }
KIconEffect::colorize(image, color, 0.8f);
m_pixmap = QPixmap::fromImage(image);
}
QString ret = m_customizedFontMetrics.elidedText(text.chopped(extensionLength),
Qt::ElideRight,
elidingWidth - extensionWidth);
- ret.append(text.right(extensionLength));
+ ret.append(text.rightRef(extensionLength));
return ret;
}
}
if (icon.isNull()) {
icon = QIcon(name);
}
- if (icon.isNull()) {
+ if (icon.isNull()
+ || icon.pixmap(size / qApp->devicePixelRatio(), size / qApp->devicePixelRatio(), mode).isNull()) {
icon = fallbackIcon;
}