Fix slow scrolling when hidden files or symbolic links are shown

The problem was that we drawed the overlays using KIconLoader, which can
be very slow, every time an item appeared on the screen. This commit
makes sure that not only the icon, but the icon including overlays is
cached in QPixmapCache. Therefore, the overlay drawing is done just once
for each icon+overlays combination.

For previews, the overlay drawing is done in KFileItemModelRolesUpdater
just after the preview is received.

BUG: 310662
BUG: 314339
FIXED-IN: 4.11.1
REVIEW: 111956
This commit is contained in:
Frank Reininghaus 2013-08-14 23:44:57 +02:00
parent 7e5b7d5626
commit fd5ba3b4b2
3 changed files with 35 additions and 20 deletions

View file

@ -570,6 +570,22 @@ void KFileItemModelRolesUpdater::slotGotPreview(const KFileItem& item, const QPi
}
QHash<QByteArray, QVariant> data = rolesData(item);
const QStringList overlays = data["iconOverlays"].toStringList();
// Strangely KFileItem::overlays() returns empty string-values, so
// we need to check first whether an overlay must be drawn at all.
// It is more efficient to do it here, as KIconLoader::drawOverlays()
// assumes that an overlay will be drawn and has some additional
// setup time.
foreach (const QString& overlay, overlays) {
if (!overlay.isEmpty()) {
// There is at least one overlay, draw all overlays above m_pixmap
// and cancel the check
KIconLoader::global()->drawOverlays(overlays, scaledPixmap, KIconLoader::Desktop);
break;
}
}
data.insert("iconPixmap", scaledPixmap);
disconnect(m_model, SIGNAL(itemsChanged(KItemRangeList,QSet<QByteArray>)),

View file

@ -839,29 +839,14 @@ void KStandardItemListWidget::updatePixmapCache()
// use a generic icon as fallback
iconName = QLatin1String("unknown");
}
m_pixmap = pixmapForIcon(iconName, maxIconHeight);
const QStringList overlays = values["iconOverlays"].toStringList();
m_pixmap = pixmapForIcon(iconName, overlays, maxIconHeight);
} else if (m_pixmap.width() != maxIconWidth || m_pixmap.height() != maxIconHeight) {
// A custom pixmap has been applied. Assure that the pixmap
// is scaled to the maximum available size.
KPixmapModifier::scale(m_pixmap, QSize(maxIconWidth, maxIconHeight));
}
const QStringList overlays = values["iconOverlays"].toStringList();
// Strangely KFileItem::overlays() returns empty string-values, so
// we need to check first whether an overlay must be drawn at all.
// It is more efficient to do it here, as KIconLoader::drawOverlays()
// assumes that an overlay will be drawn and has some additional
// setup time.
foreach (const QString& overlay, overlays) {
if (!overlay.isEmpty()) {
// There is at least one overlay, draw all overlays above m_pixmap
// and cancel the check
KIconLoader::global()->drawOverlays(overlays, m_pixmap, KIconLoader::Desktop);
break;
}
}
if (m_isCut) {
KIconEffect* effect = KIconLoader::global()->iconEffect();
m_pixmap = effect->apply(m_pixmap, KIconLoader::Desktop, KIconLoader::DisabledState);
@ -1323,9 +1308,9 @@ void KStandardItemListWidget::closeRoleEditor()
m_roleEditor = 0;
}
QPixmap KStandardItemListWidget::pixmapForIcon(const QString& name, int size)
QPixmap KStandardItemListWidget::pixmapForIcon(const QString& name, const QStringList& overlays, int size)
{
const QString key = "KStandardItemListWidget:" % name % ":" % QString::number(size);
const QString key = "KStandardItemListWidget:" % name % ":" % overlays.join(":") % ":" % QString::number(size);
QPixmap pixmap;
if (!QPixmapCache::find(key, pixmap)) {
@ -1355,6 +1340,20 @@ QPixmap KStandardItemListWidget::pixmapForIcon(const QString& name, int size)
KPixmapModifier::scale(pixmap, QSize(size, size));
}
// Strangely KFileItem::overlays() returns empty string-values, so
// we need to check first whether an overlay must be drawn at all.
// It is more efficient to do it here, as KIconLoader::drawOverlays()
// assumes that an overlay will be drawn and has some additional
// setup time.
foreach (const QString& overlay, overlays) {
if (!overlay.isEmpty()) {
// There is at least one overlay, draw all overlays above m_pixmap
// and cancel the check
KIconLoader::global()->drawOverlays(overlays, pixmap, KIconLoader::Desktop);
break;
}
}
QPixmapCache::insert(key, pixmap);
}

View file

@ -186,7 +186,7 @@ private:
*/
void closeRoleEditor();
static QPixmap pixmapForIcon(const QString& name, int size);
static QPixmap pixmapForIcon(const QString& name, const QStringList& overlays, int size);
/**
* @return Preferred size of the rating-image based on the given