diff options
| author | Peter Penz <[email protected]> | 2008-03-23 01:56:18 +0000 |
|---|---|---|
| committer | Peter Penz <[email protected]> | 2008-03-23 01:56:18 +0000 |
| commit | 8c6e717eadc966196f72b7552012c12f46c720ce (patch) | |
| tree | f3f686feef0e43923ed8ba778e3504ed70574f4f /src/iconmanager.cpp | |
| parent | 4d1a74b7459e7ede2d20e8d6ea3e4555e36b90a9 (diff) | |
Performance boost for previews that are already available in the cache: apply the previews in larger blocks instead of applying them immediately after getting the signal 'gotPreview' from the PreviewJob. Now the previews in Konqueror and Dolphin are as fast as in the good old KDE 3 days :-)
svn path=/trunk/KDE/kdebase/apps/; revision=789009
Diffstat (limited to 'src/iconmanager.cpp')
| -rw-r--r-- | src/iconmanager.cpp | 133 |
1 files changed, 89 insertions, 44 deletions
diff --git a/src/iconmanager.cpp b/src/iconmanager.cpp index dcfa9befe..cde15b00b 100644 --- a/src/iconmanager.cpp +++ b/src/iconmanager.cpp @@ -38,10 +38,12 @@ IconManager::IconManager(QAbstractItemView* parent, DolphinSortFilterProxyModel* QObject(parent), m_showPreview(false), m_view(parent), + m_previewTimer(0), m_previewJobs(), m_dolphinModel(0), m_proxyModel(model), - m_cutItemsCache() + m_cutItemsCache(), + m_previews() { Q_ASSERT(m_view->iconSize().isValid()); // each view must provide its current icon size @@ -52,6 +54,9 @@ IconManager::IconManager(QAbstractItemView* parent, DolphinSortFilterProxyModel* QClipboard* clipboard = QApplication::clipboard(); connect(clipboard, SIGNAL(dataChanged()), this, SLOT(updateCutItems())); + + m_previewTimer = new QTimer(this); + connect(m_previewTimer, SIGNAL(timeout()), this, SLOT(dispatchPreviewQueue())); } IconManager::~IconManager() @@ -98,49 +103,12 @@ void IconManager::updateIcons(const KFileItemList& items) } } -void IconManager::replaceIcon(const KFileItem& item, const QPixmap& pixmap) +void IconManager::addToPreviewQueue(const KFileItem& item, const QPixmap& pixmap) { - Q_ASSERT(!item.isNull()); - 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 = item.url().directory(); - foreach (KUrl url, dirs) { - if (url.path() == itemDir) { - isOldPreview = false; - break; - } - } - if (isOldPreview) { - return; - } - - const QModelIndex idx = m_dolphinModel->indexForItem(item); - if (idx.isValid() && (idx.column() == 0)) { - 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)) { - 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); - } - } + Preview preview; + preview.item = item; + preview.pixmap = pixmap; + m_previews.append(preview); } void IconManager::slotPreviewJobFinished(KJob* job) @@ -165,6 +133,37 @@ void IconManager::updateCutItems() applyCutItemEffect(); } +void IconManager::dispatchPreviewQueue() +{ + const int previewsCount = m_previews.count(); + if (previewsCount == 0) { + return; + } + + // Applying the previews to the model must be done step by step + // in larger blocks: Applying a preview immediately when getting the signal + // 'gotPreview()' from the PreviewJob is too expensive, as a relayout + // of the view would be triggered for each single preview. + + int dispatchCount = 30; + if (dispatchCount > previewsCount) { + dispatchCount = previewsCount; + } + + for (int i = 0; i < dispatchCount; ++i) { + const Preview& preview = m_previews.first(); + replaceIcon(preview.item, preview.pixmap); + m_previews.pop_front(); + } + + if (m_previews.count() > 0) { + // there are still pending previews; if no preview job is + // working, poll more aggressively: + const int timeout = (m_previewJobs.count() > 0) ? 200 : 10; + m_previewTimer->start(timeout); + } +} + void IconManager::generatePreviews(const KFileItemList &items) { Q_ASSERT(m_showPreview); @@ -187,11 +186,57 @@ void IconManager::generatePreviews(const KFileItemList &items) const QSize size = m_view->iconSize(); KIO::PreviewJob* job = KIO::filePreview(orderedItems, 128, 128); connect(job, SIGNAL(gotPreview(const KFileItem&, const QPixmap&)), - this, SLOT(replaceIcon(const KFileItem&, const QPixmap&))); + this, SLOT(addToPreviewQueue(const KFileItem&, const QPixmap&))); connect(job, SIGNAL(finished(KJob*)), this, SLOT(slotPreviewJobFinished(KJob*))); m_previewJobs.append(job); + m_previewTimer->start(200); +} + +void IconManager::replaceIcon(const KFileItem& item, const QPixmap& pixmap) +{ + Q_ASSERT(!item.isNull()); + 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 = item.url().directory(); + foreach (KUrl url, dirs) { + if (url.path() == itemDir) { + isOldPreview = false; + break; + } + } + if (isOldPreview) { + return; + } + + const QModelIndex idx = m_dolphinModel->indexForItem(item); + if (idx.isValid() && (idx.column() == 0)) { + 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)) { + 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 |
