Move the block for resizing the preview, applying an item effect + border to the slot where the preview has been received. This reduces the blocking of the GUI for the following usecase:

- folder with 1000 items
- ~30 items are visible

Old approach:
- Show the 30 items as soon as possible.
- Receive preview and add it to the queue. This is done asynchronously 970 times (no UI blocking).
- Iterate through 970 items, resize, apply item effect + border and apply the preview to the model (-> blocking of UI thread for more than 3 seconds).

New approach:
- Show the 30 items as soon as possible.
- Receive preview, resize it, apply item effect + border and add it to the queue. This is done asynchronously 970 times (no UI blocking).
- Iterate through 970 items and apply the preview to the model (-> UI thread is blocked only very short).

svn path=/trunk/KDE/kdebase/apps/; revision=826109
This commit is contained in:
Peter Penz 2008-06-29 21:04:43 +00:00
parent fdd06835fc
commit 1f3607bdc1
2 changed files with 60 additions and 69 deletions

View file

@ -212,9 +212,61 @@ void IconManager::generatePreviews(const KFileItemList& items)
void IconManager::addToPreviewQueue(const KFileItem& item, const QPixmap& pixmap) void IconManager::addToPreviewQueue(const KFileItem& item, const QPixmap& pixmap)
{ {
if (!m_showPreview) {
// the preview has been canceled in the meantime
return;
}
const KUrl url = item.url();
// check whether the item is part of the directory lister (it is possible
// that a preview from an old directory lister is received)
KDirLister* dirLister = m_dolphinModel->dirLister();
bool isOldPreview = true;
const KUrl::List dirs = dirLister->directories();
const QString itemDir = url.directory();
foreach (const KUrl& url, dirs) {
if (url.path() == itemDir) {
isOldPreview = false;
break;
}
}
if (isOldPreview) {
return;
}
QPixmap icon = pixmap;
const QString mimeType = item.mimetype();
const QString mimeTypeGroup = mimeType.left(mimeType.indexOf('/'));
if ((mimeTypeGroup != "image") || !applyImageFrame(icon)) {
limitToSize(icon, m_view->iconSize());
}
const QMimeData* mimeData = QApplication::clipboard()->mimeData();
if (KonqMimeData::decodeIsCutSelection(mimeData) && isCutItem(item)) {
// Remember the current icon in the cache for cut items before
// the disabled effect is applied. This makes it possible restoring
// the uncut version again when cutting other items.
QList<ItemInfo>::iterator begin = m_cutItemsCache.begin();
QList<ItemInfo>::iterator end = m_cutItemsCache.end();
for (QList<ItemInfo>::iterator it = begin; it != end; ++it) {
if ((*it).url == item.url()) {
(*it).pixmap = icon;
break;
}
}
// apply the disabled effect to the icon for marking it as "cut item"
// and apply the icon to the item
KIconEffect iconEffect;
icon = iconEffect.apply(icon, KIconLoader::Desktop, KIconLoader::DisabledState);
}
// remember the preview and URL, so that it can be applied to the model
// in IconManager::dispatchPreviewQueue()
ItemInfo preview; ItemInfo preview;
preview.url = item.url(); preview.url = url;
preview.pixmap = pixmap; preview.pixmap = icon;
m_previews.append(preview); m_previews.append(preview);
m_dispatchedItems.append(item); m_dispatchedItems.append(item);
@ -260,7 +312,12 @@ void IconManager::dispatchPreviewQueue()
LayoutBlocker blocker(m_view); LayoutBlocker blocker(m_view);
for (int i = 0; i < previewsCount; ++i) { for (int i = 0; i < previewsCount; ++i) {
const ItemInfo& preview = m_previews.first(); const ItemInfo& preview = m_previews.first();
replaceIcon(preview.url, preview.pixmap);
const QModelIndex idx = m_dolphinModel->indexForUrl(preview.url);
if (idx.isValid() && (idx.column() == 0)) {
m_dolphinModel->setData(idx, QIcon(preview.pixmap), Qt::DecorationRole);
}
m_previews.pop_front(); m_previews.pop_front();
if (m_pendingVisiblePreviews > 0) { if (m_pendingVisiblePreviews > 0) {
--m_pendingVisiblePreviews; --m_pendingVisiblePreviews;
@ -319,66 +376,6 @@ void IconManager::resumePreviews()
startPreviewJob(orderedItems); startPreviewJob(orderedItems);
} }
void IconManager::replaceIcon(const KUrl& url, const QPixmap& pixmap)
{
Q_ASSERT(url.isValid());
if (!m_showPreview) {
// the preview has been canceled in the meantime
return;
}
// check whether the item is part of the directory lister (it is possible
// that a preview from an old directory lister is received)
KDirLister* dirLister = m_dolphinModel->dirLister();
bool isOldPreview = true;
const KUrl::List dirs = dirLister->directories();
const QString itemDir = url.directory();
foreach (const KUrl& url, dirs) {
if (url.path() == itemDir) {
isOldPreview = false;
break;
}
}
if (isOldPreview) {
return;
}
const QModelIndex idx = m_dolphinModel->indexForUrl(url);
if (idx.isValid() && (idx.column() == 0)) {
QPixmap icon = pixmap;
const KFileItem item = m_dolphinModel->itemForIndex(idx);
const QString mimeType = item.mimetype();
const QString mimeTypeGroup = mimeType.left(mimeType.indexOf('/'));
if ((mimeTypeGroup != "image") || !applyImageFrame(icon)) {
limitToSize(icon, m_view->iconSize());
}
const QMimeData* mimeData = QApplication::clipboard()->mimeData();
if (KonqMimeData::decodeIsCutSelection(mimeData) && isCutItem(item)) {
// Remember the current icon in the cache for cut items before
// the disabled effect is applied. This makes it possible restoring
// the uncut version again when cutting other items.
QList<ItemInfo>::iterator begin = m_cutItemsCache.begin();
QList<ItemInfo>::iterator end = m_cutItemsCache.end();
for (QList<ItemInfo>::iterator it = begin; it != end; ++it) {
if ((*it).url == item.url()) {
(*it).pixmap = icon;
break;
}
}
// apply the disabled effect to the icon for marking it as "cut item"
// and apply the icon to the item
KIconEffect iconEffect;
icon = iconEffect.apply(icon, KIconLoader::Desktop, KIconLoader::DisabledState);
m_dolphinModel->setData(idx, QIcon(icon), Qt::DecorationRole);
} else {
m_dolphinModel->setData(idx, QIcon(icon), Qt::DecorationRole);
}
}
}
bool IconManager::isCutItem(const KFileItem& item) const bool IconManager::isCutItem(const KFileItem& item) const
{ {
const QMimeData* mimeData = QApplication::clipboard()->mimeData(); const QMimeData* mimeData = QApplication::clipboard()->mimeData();

View file

@ -115,12 +115,6 @@ private slots:
void resumePreviews(); void resumePreviews();
private: private:
/**
* Replaces the icon of the item with the \a url by the preview pixmap
* \a pixmap.
*/
void replaceIcon(const KUrl& url, const QPixmap& pixmap);
/** /**
* Returns true, if the item \a item has been cut into * Returns true, if the item \a item has been cut into
* the clipboard. * the clipboard.