]> cloud.milkyroute.net Git - dolphin.git/commitdiff
Up to now DolphinView and ColumnWidget contained a lot of code duplication regarding...
authorPeter Penz <peter.penz19@gmail.com>
Fri, 11 Jan 2008 11:37:28 +0000 (11:37 +0000)
committerPeter Penz <peter.penz19@gmail.com>
Fri, 11 Jan 2008 11:37:28 +0000 (11:37 +0000)
svn path=/trunk/KDE/kdebase/apps/; revision=759864

src/CMakeLists.txt
src/dolphincolumnwidget.cpp
src/dolphincolumnwidget.h
src/dolphinview.cpp
src/dolphinview.h
src/iconmanager.cpp [new file with mode: 0644]
src/iconmanager.h [new file with mode: 0644]

index fe9fd5c2fc7806322aaadeddac6af2a5d3e396b6..18b3a2283785ed0d68c384cbc64fba613e1828c0 100644 (file)
@@ -17,18 +17,19 @@ set(dolphinprivate_LIB_SRCS
     dolphiniconsview.cpp
     dolphincolumnview.cpp
     dolphincolumnwidget.cpp
+    dolphindropcontroller.cpp
+    dolphinsortfilterproxymodel.cpp
     draganddrophelper.cpp
-    kcategorizedview.cpp
-    kcategorydrawer.cpp
     dolphinmodel.cpp
     dolphinsettings.cpp
     dolphincategorydrawer.cpp
-    viewproperties.cpp
-    dolphinsortfilterproxymodel.cpp
-    renamedialog.cpp
     dolphinview.cpp
+    iconmanager.cpp
+    kcategorizedview.cpp
+    kcategorydrawer.cpp
     ratingpainter.cpp
-    dolphindropcontroller.cpp
+    renamedialog.cpp
+    viewproperties.cpp
     )
 
 kde4_add_kcfg_files(dolphinprivate_LIB_SRCS
index 002c2cf28dd64cc06e919f3193eac3156f5daa27..a51e3ef9fc6f334f167d04011e8f276e98c3aefe 100644 (file)
@@ -37,6 +37,8 @@
 #include <kmimetyperesolver.h>
 #include <konqmimedata.h>
 
+#include "iconmanager.h"
+
 #include <QApplication>
 #include <QClipboard>
 #include <QPainter>
@@ -47,7 +49,6 @@ DolphinColumnWidget::DolphinColumnWidget(QWidget* parent,
                                          const KUrl& url) :
     QListView(parent),
     m_active(true),
-    m_showPreview(false),
     m_view(columnView),
     m_url(url),
     m_childUrl(),
@@ -56,7 +57,7 @@ DolphinColumnWidget::DolphinColumnWidget(QWidget* parent,
     m_dirLister(0),
     m_dolphinModel(0),
     m_proxyModel(0),
-    m_previewJob(0),
+    m_iconManager(0),
     m_dragging(false),
     m_dropRect()
 {
@@ -107,8 +108,6 @@ DolphinColumnWidget::DolphinColumnWidget(QWidget* parent,
     m_dirLister->setDelayedMimeTypes(true);
     const bool showHiddenFiles = m_view->m_controller->dolphinView()->showHiddenFiles();
     m_dirLister->setShowingDotFiles(showHiddenFiles);
-    connect(m_dirLister, SIGNAL(newItems(const KFileItemList&)),
-            this, SLOT(generatePreviews(const KFileItemList&)));
 
     m_dolphinModel = new DolphinModel(this);
     m_dolphinModel->setDirLister(m_dirLister);
@@ -120,6 +119,8 @@ DolphinColumnWidget::DolphinColumnWidget(QWidget* parent,
 
     setModel(m_proxyModel);
     new KMimeTypeResolver(this, m_dolphinModel);
+    m_iconManager = new IconManager(this, m_dolphinModel);
+    m_iconManager->setShowPreview(m_view->m_controller->dolphinView()->showPreview());
 
     m_dirLister->openUrl(url, KDirLister::NoFlags);
 }
@@ -131,11 +132,6 @@ DolphinColumnWidget::~DolphinColumnWidget()
     delete m_dolphinModel;
     m_dolphinModel = 0;
     m_dirLister = 0; // deleted by m_dolphinModel
-
-    if (m_previewJob != 0) {
-        m_previewJob->kill();
-        m_previewJob = 0;
-    }
 }
 
 void DolphinColumnWidget::setDecorationSize(const QSize& size)
@@ -176,10 +172,11 @@ void DolphinColumnWidget::setShowHiddenFiles(bool show)
 
 void DolphinColumnWidget::setShowPreview(bool show)
 {
-    if (show != m_showPreview) {
-        m_dirLister->stop();
-        m_dirLister->openUrl(m_url, KDirLister::Reload);
-    }
+    kDebug() << "-------------- column widget: show" << show;
+    m_iconManager->setShowPreview(show);
+
+    m_dirLister->stop();
+    m_dirLister->openUrl(m_url, KDirLister::Reload);
 }
 
 void DolphinColumnWidget::updateBackground()
@@ -363,51 +360,6 @@ void DolphinColumnWidget::triggerItem(const QModelIndex& index)
     m_view->m_controller->triggerItem(item);
 }
 
-void DolphinColumnWidget::generatePreviews(const KFileItemList& items)
-{
-    // TODO: same implementation as in DolphinView; create helper class
-    // for generatePreviews(), showPreview() and isCutItem()
-
-    if (m_view->m_controller->dolphinView()->showPreview()) {
-        if (m_previewJob != 0) {
-            m_previewJob->kill();
-            m_previewJob = 0;
-        }
-
-        m_previewJob = KIO::filePreview(items, 128);
-        connect(m_previewJob, SIGNAL(gotPreview(const KFileItem&, const QPixmap&)),
-                this, SLOT(replaceIcon(const KFileItem&, const QPixmap&)));
-        connect(m_previewJob, SIGNAL(finished(KJob*)),
-                this, SLOT(slotPreviewJobFinished(KJob*)));
-    }
-}
-
-void DolphinColumnWidget::replaceIcon(const KFileItem& item, const QPixmap& pixmap)
-{
-    // TODO: same implementation as in DolphinView; create helper class
-    // for generatePreviews(), showPreview() and isCutItem()
-
-    Q_ASSERT(!item.isNull());
-    const bool showPreview = m_view->m_controller->dolphinView()->showPreview();
-    if (!showPreview || (item.url().directory() != m_dirLister->url().path())) {
-        // the preview job is still working on items of an older URL, hence
-        // the item is not part of the directory model anymore
-        return;
-    }
-
-    const QModelIndex idx = m_dolphinModel->indexForItem(item);
-    if (idx.isValid() && (idx.column() == 0)) {
-        const QMimeData* mimeData = QApplication::clipboard()->mimeData();
-        if (KonqMimeData::decodeIsCutSelection(mimeData) && isCutItem(item)) {
-            KIconEffect iconEffect;
-            const QPixmap cutPixmap = iconEffect.apply(pixmap, KIconLoader::Desktop, KIconLoader::DisabledState);
-            m_dolphinModel->setData(idx, QIcon(cutPixmap), Qt::DecorationRole);
-        } else {
-            m_dolphinModel->setData(idx, QIcon(pixmap), Qt::DecorationRole);
-        }
-    }
-}
-
 void DolphinColumnWidget::slotEntered(const QModelIndex& index)
 {
     const QModelIndex dirIndex = m_proxyModel->mapToSource(index);
@@ -415,12 +367,6 @@ void DolphinColumnWidget::slotEntered(const QModelIndex& index)
     m_view->m_controller->emitItemEntered(item);
 }
 
-void DolphinColumnWidget::slotPreviewJobFinished(KJob* job)
-{
-    Q_ASSERT(job == m_previewJob);
-    m_previewJob = 0;
-}
-
 void DolphinColumnWidget::activate()
 {
     setFocus(Qt::OtherFocusReason);
@@ -466,27 +412,6 @@ void DolphinColumnWidget::deactivate()
     updateBackground();
 }
 
-bool DolphinColumnWidget::isCutItem(const KFileItem& item) const
-{
-    // TODO: same implementation as in DolphinView; create helper class
-    // for generatePreviews(), showPreview() and isCutItem()
-
-    const QMimeData* mimeData = QApplication::clipboard()->mimeData();
-    const KUrl::List cutUrls = KUrl::List::fromMimeData(mimeData);
-
-    const KUrl& itemUrl = item.url();
-    KUrl::List::const_iterator it = cutUrls.begin();
-    const KUrl::List::const_iterator end = cutUrls.end();
-    while (it != end) {
-        if (*it == itemUrl) {
-            return true;
-        }
-        ++it;
-    }
-
-    return false;
-}
-
 KFileItem DolphinColumnWidget::itemForIndex(const QModelIndex& index) const
 {
     const QModelIndex dirIndex = m_proxyModel->mapToSource(index);
index 87024626942b034fe637e0831c50b28f586ca884..de14576e7bb98c7369ca69110e188525b1d1814f 100644 (file)
 class DolphinColumnView;
 class DolphinModel;
 class DolphinSortFilterProxyModel;
+class IconManager;
 class KDirLister;
 class KJob;
 class KFileItem;
 class KFileItemList;
 class QPixmap;
-namespace KIO
-{
-    class PreviewJob;
-}
 
 /**
  * Represents one column inside the DolphinColumnView and has been
@@ -118,27 +115,8 @@ private slots:
      */
     void triggerItem(const QModelIndex& index);
 
-    /**
-     * Generates a preview image for each file item in \a items.
-     * The current preview settings (maximum size, 'Show Preview' menu)
-     * are respected.
-     */
-    void generatePreviews(const KFileItemList& items);
-
-    /**
-     * Replaces the icon of the item \a item by the preview pixmap
-     * \a pixmap.
-     */
-    void replaceIcon(const KFileItem& item, const QPixmap& pixmap);
-
     void slotEntered(const QModelIndex& index);
 
-    /**
-     * Is invoked when the preview job has been finished and
-     * set m_previewJob to 0.
-     */
-    void slotPreviewJobFinished(KJob* job);
-
 private:
     /** Used by DolphinColumnWidget::setActive(). */
     void activate();
@@ -146,17 +124,10 @@ private:
     /** Used by DolphinColumnWidget::setActive(). */
     void deactivate();
 
-    /**
-     * Returns true, if the item \a item has been cut into
-     * the clipboard.
-     */
-    bool isCutItem(const KFileItem& item) const;
-
     KFileItem itemForIndex(const QModelIndex& index) const;
 
 private:
     bool m_active;
-    bool m_showPreview;
     DolphinColumnView* m_view;
     KUrl m_url;      // URL of the directory that is shown
     KUrl m_childUrl; // URL of the next column that is shown
@@ -168,7 +139,7 @@ private:
     DolphinModel* m_dolphinModel;
     DolphinSortFilterProxyModel* m_proxyModel;
 
-    KIO::PreviewJob* m_previewJob;
+    IconManager* m_iconManager;
 
     bool m_dragging;   // TODO: remove this property when the issue #160611 is solved in Qt 4.4
     QRect m_dropRect;  // TODO: remove this property when the issue #160611 is solved in Qt 4.4
index 44fbf4b6bd0a4464a52abc880a5caa1f7c7c56a0..56a3d54de7c9be217e94bf6eef07d3107aec1a05 100644 (file)
 #include <kcolorscheme.h>
 #include <kdirlister.h>
 #include <kfileitemdelegate.h>
-#include <klocale.h>
 #include <kiconeffect.h>
+#include <klocale.h>
 #include <kio/deletejob.h>
 #include <kio/netaccess.h>
 #include <kio/previewjob.h>
 #include <kjob.h>
 #include <kmenu.h>
 #include <kmimetyperesolver.h>
-#include <konqmimedata.h>
 #include <konq_operations.h>
+#include <konqmimedata.h>
 #include <kurl.h>
 
 #include "dolphindropcontroller.h"
 #include "dolphinsortfilterproxymodel.h"
 #include "dolphindetailsview.h"
 #include "dolphiniconsview.h"
-#include "renamedialog.h"
-#include "viewproperties.h"
 #include "dolphinsettings.h"
 #include "dolphin_generalsettings.h"
+#include "iconmanager.h"
+#include "renamedialog.h"
+#include "viewproperties.h"
 
 DolphinView::DolphinView(QWidget* parent,
                          const KUrl& url,
@@ -78,21 +79,15 @@ DolphinView::DolphinView(QWidget* parent,
     m_dolphinModel(dolphinModel),
     m_dirLister(dirLister),
     m_proxyModel(proxyModel),
-    m_previewJob(0)
+    m_iconManager(0)
 {
     setFocusPolicy(Qt::StrongFocus);
     m_topLayout = new QVBoxLayout(this);
     m_topLayout->setSpacing(0);
     m_topLayout->setMargin(0);
 
-    QClipboard* clipboard = QApplication::clipboard();
-    connect(clipboard, SIGNAL(dataChanged()),
-            this, SLOT(updateCutItems()));
-
     connect(m_dirLister, SIGNAL(completed()),
             this, SLOT(updateCutItems()));
-    connect(m_dirLister, SIGNAL(newItems(const KFileItemList&)),
-            this, SLOT(generatePreviews(const KFileItemList&)));
 
     m_controller = new DolphinController(this);
     m_controller->setUrl(url);
@@ -125,16 +120,14 @@ DolphinView::DolphinView(QWidget* parent,
     connect(m_controller, SIGNAL(viewportEntered()),
             this, SLOT(clearHoverInformation()));
 
+    m_iconManager = new IconManager(this, m_dolphinModel);
+
     applyViewProperties(url);
     m_topLayout->addWidget(itemView());
 }
 
 DolphinView::~DolphinView()
 {
-    if (m_previewJob != 0) {
-        m_previewJob->kill();
-        m_previewJob = 0;
-    }
 }
 
 const KUrl& DolphinView::url() const
@@ -246,7 +239,7 @@ void DolphinView::setShowPreview(bool show)
     props.setShowPreview(show);
 
     m_showPreview = show;
-
+    m_iconManager->setShowPreview(show);
     emit showPreviewChanged();
 
     loadDirectory(viewPropsUrl, true);
@@ -575,45 +568,6 @@ void DolphinView::triggerItem(const KFileItem& item)
     emit itemTriggered(item); // caught by DolphinViewContainer or DolphinPart
 }
 
-void DolphinView::generatePreviews(const KFileItemList& items)
-{
-    if (m_controller->dolphinView()->showPreview()) {
-        if (m_previewJob != 0) {
-            m_previewJob->kill();
-            m_previewJob = 0;
-        }
-
-        m_previewJob = KIO::filePreview(items, 128);
-        connect(m_previewJob, SIGNAL(gotPreview(const KFileItem&, const QPixmap&)),
-                this, SLOT(replaceIcon(const KFileItem&, const QPixmap&)));
-        connect(m_previewJob, SIGNAL(finished(KJob*)),
-                this, SLOT(slotPreviewJobFinished(KJob*)));
-    }
-}
-
-void DolphinView::replaceIcon(const KFileItem& item, const QPixmap& pixmap)
-{
-    Q_ASSERT(!item.isNull());
-    if (!m_showPreview || (item.url().directory() != m_dirLister->url().path())) {
-        // the preview has been deactivated in the meanwhile or the preview
-        // job is still working on items of an older URL, hence
-        // the item is not part of the directory model anymore
-        return;
-    }
-
-    const QModelIndex idx = m_dolphinModel->indexForItem(item);
-    if (idx.isValid() && (idx.column() == 0)) {
-        const QMimeData* mimeData = QApplication::clipboard()->mimeData();
-        if (KonqMimeData::decodeIsCutSelection(mimeData) && isCutItem(item)) {
-            KIconEffect iconEffect;
-            const QPixmap cutPixmap = iconEffect.apply(pixmap, KIconLoader::Desktop, KIconLoader::DisabledState);
-            m_dolphinModel->setData(idx, QIcon(cutPixmap), Qt::DecorationRole);
-        } else {
-            m_dolphinModel->setData(idx, QIcon(pixmap), Qt::DecorationRole);
-        }
-    }
-}
-
 void DolphinView::emitSelectionChangedSignal()
 {
     emit selectionChanged(DolphinView::selectedItems());
@@ -631,7 +585,6 @@ void DolphinView::loadDirectory(const KUrl& url, bool reload)
         return;
     }
 
-    m_cutItemsCache.clear();
     m_loadingDirectory = true;
 
     m_dirLister->stop();
@@ -714,6 +667,7 @@ void DolphinView::applyViewProperties(const KUrl& url)
     const bool showPreview = props.showPreview();
     if (showPreview != m_showPreview) {
         m_showPreview = showPreview;
+        m_iconManager->setShowPreview(showPreview);
         emit showPreviewChanged();
     }
 }
@@ -819,25 +773,6 @@ void DolphinView::emitContentsMoved()
     }
 }
 
-void DolphinView::updateCutItems()
-{
-    // restore the icons of all previously selected items to the
-    // original state...
-    QList<CutItem>::const_iterator it = m_cutItemsCache.begin();
-    QList<CutItem>::const_iterator end = m_cutItemsCache.end();
-    while (it != end) {
-        const QModelIndex index = m_dolphinModel->indexForUrl((*it).url);
-        if (index.isValid()) {
-            m_dolphinModel->setData(index, QIcon((*it).pixmap), Qt::DecorationRole);
-        }
-        ++it;
-    }
-    m_cutItemsCache.clear();
-
-    // ... and apply an item effect to all currently cut items
-    applyCutItemEffect();
-}
-
 void DolphinView::showHoverInformation(const KFileItem& item)
 {
     if (hasSelection() || !m_active) {
@@ -854,7 +789,6 @@ void DolphinView::clearHoverInformation()
     }
 }
 
-
 void DolphinView::createView()
 {
     deleteView();
@@ -954,42 +888,6 @@ bool DolphinView::isCutItem(const KFileItem& item) const
     return false;
 }
 
-void DolphinView::applyCutItemEffect()
-{
-    const QMimeData* mimeData = QApplication::clipboard()->mimeData();
-    if (!KonqMimeData::decodeIsCutSelection(mimeData)) {
-        return;
-    }
-
-    KFileItemList items(m_dirLister->items());
-    KFileItemList::const_iterator it = items.begin();
-    const KFileItemList::const_iterator end = items.end();
-    while (it != end) {
-        const KFileItem item = *it;
-        if (isCutItem(item)) {
-            const QModelIndex index = m_dolphinModel->indexForItem(item);
-            const QVariant value = m_dolphinModel->data(index, Qt::DecorationRole);
-            if (value.type() == QVariant::Icon) {
-                const QIcon icon(qvariant_cast<QIcon>(value));
-                QPixmap pixmap = icon.pixmap(128, 128);
-
-                // remember current pixmap for the item to be able
-                // to restore it when other items get cut
-                CutItem cutItem;
-                cutItem.url = item.url();
-                cutItem.pixmap = pixmap;
-                m_cutItemsCache.append(cutItem);
-
-                // apply icon effect to the cut item
-                KIconEffect iconEffect;
-                pixmap = iconEffect.apply(pixmap, KIconLoader::Desktop, KIconLoader::DisabledState);
-                m_dolphinModel->setData(index, QIcon(pixmap), Qt::DecorationRole);
-            }
-        }
-        ++it;
-    }
-}
-
 KToggleAction* DolphinView::iconsModeAction(KActionCollection* actionCollection)
 {
     KToggleAction* iconsView = actionCollection->add<KToggleAction>("icons");
@@ -1126,12 +1024,6 @@ void DolphinView::slotDeleteFileFinished(KJob* job)
     }
 }
 
-void DolphinView::slotPreviewJobFinished(KJob* job)
-{
-    Q_ASSERT(job == m_previewJob);
-    m_previewJob = 0;
-}
-
 void DolphinView::cutSelectedItems()
 {
     QMimeData* mimeData = new QMimeData();
index 60e29b4d5a8d702bdef99da8f75e5cb90b3e7136..fa5b18471b4edd6831774d4a00c1eb322f53ff65 100644 (file)
 #include <QListView>
 #include <QWidget>
 
-class KAction;
-class KToggleAction;
 class DolphinController;
-class KDirLister;
-class KFileItemDelegate;
-class KUrl;
-class DolphinModel;
 class DolphinColumnView;
 class DolphinDetailsView;
 class DolphinIconsView;
 class DolphinMainWindow;
+class DolphinModel;
 class DolphinSortFilterProxyModel;
+class IconManager;
+class KAction;
+class KDirLister;
+class KFileItemDelegate;
+class KUrl;
+class KToggleAction;
 class QModelIndex;
 class ViewProperties;
-namespace KIO
-{
-    class PreviewJob;
-}
 
 /**
  * @short Represents a view for the directory content.
@@ -526,19 +523,6 @@ private slots:
      */
     void triggerItem(const KFileItem& index);
 
-    /**
-     * Generates a preview image for each file item in \a items.
-     * The current preview settings (maximum size, 'Show Preview' menu)
-     * are respected.
-     */
-    void generatePreviews(const KFileItemList& items);
-
-    /**
-     * Replaces the icon of the item \a item by the preview pixmap
-     * \a pixmap.
-     */
-    void replaceIcon(const KFileItem& item, const QPixmap& pixmap);
-
     void emitSelectionChangedSignal();
 
     /**
@@ -587,9 +571,6 @@ private slots:
      */
     void emitContentsMoved();
 
-    /** Applies an item effect to all cut items of the clipboard. */
-    void updateCutItems();
-
     /**
      * Updates the status bar to show hover information for the
      * item \a item. If currently other items are selected,
@@ -610,12 +591,6 @@ private slots:
      */
     void slotDeleteFileFinished(KJob* job);
 
-    /**
-     * Is invoked when the preview job has been finished and
-     * set m_previewJob to 0.
-     */
-    void slotPreviewJobFinished(KJob* job);
-
 private:
     void loadDirectory(const KUrl& url, bool reload = false);
 
@@ -654,9 +629,6 @@ private:
      */
     bool isCutItem(const KFileItem& item) const;
 
-    /** Applies an item effect to all cut items. */
-    void applyCutItemEffect();
-
     /**
      * Returns true, if the ColumnView is activated. As the column view
      * requires some special handling for iterating through directories,
@@ -668,16 +640,6 @@ private:
     }
 
 private:
-    /**
-     * Remembers the original pixmap for an item before
-     * the cut effect is applied.
-     */
-    struct CutItem
-    {
-        KUrl url;
-        QPixmap pixmap;
-    };
-
     bool m_active;
     bool m_showPreview;
     bool m_loadingDirectory;
@@ -698,9 +660,7 @@ private:
     KDirLister* m_dirLister;
     DolphinSortFilterProxyModel* m_proxyModel;
 
-    KIO::PreviewJob* m_previewJob;
-
-    QList<CutItem> m_cutItemsCache;
+    IconManager* m_iconManager;
 
     KUrl m_rootUrl;
 };
diff --git a/src/iconmanager.cpp b/src/iconmanager.cpp
new file mode 100644 (file)
index 0000000..77e7731
--- /dev/null
@@ -0,0 +1,177 @@
+/***************************************************************************
+ *   Copyright (C) 2008 by Peter Penz <peter.penz@gmx.at>                  *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA            *
+ ***************************************************************************/
+
+#include "iconmanager.h"
+
+#include "dolphinmodel.h"
+
+#include <kiconeffect.h>
+#include <kio/previewjob.h>
+#include <kdebug.h>
+#include <kdirlister.h>
+#include <konqmimedata.h>
+
+#include <QApplication>
+#include <QClipboard>
+#include <QIcon>
+
+IconManager::IconManager(QObject* parent, DolphinModel* model) :
+    QObject(parent),
+    m_showPreview(false),
+    m_previewJobs(),
+    m_dolphinModel(model),
+    m_cutItemsCache()
+{
+    connect(model->dirLister(), SIGNAL(newItems(const KFileItemList&)),
+            this, SLOT(generatePreviews(const KFileItemList&)));
+
+    QClipboard* clipboard = QApplication::clipboard();
+    connect(clipboard, SIGNAL(dataChanged()),
+            this, SLOT(updateCutItems()));
+}
+
+IconManager::~IconManager()
+{
+    foreach (KJob* job, m_previewJobs) {
+        Q_ASSERT(job != 0);
+        job->kill();
+    }
+    m_previewJobs.clear();
+}
+
+
+void IconManager::setShowPreview(bool show)
+{
+    if (m_showPreview != show) {
+        m_showPreview = show;
+        m_cutItemsCache.clear();
+        updateCutItems();
+    }
+}
+
+void IconManager::generatePreviews(const KFileItemList& items)
+{
+    if (!m_showPreview) {
+        return;
+    }
+
+    KIO::PreviewJob* job = KIO::filePreview(items, 128);
+    connect(job, SIGNAL(gotPreview(const KFileItem&, const QPixmap&)),
+            this, SLOT(replaceIcon(const KFileItem&, const QPixmap&)));
+    connect(job, SIGNAL(finished(KJob*)),
+            this, SLOT(slotPreviewJobFinished(KJob*)));
+
+    m_previewJobs.append(job);
+}
+
+void IconManager::replaceIcon(const KFileItem& item, const QPixmap& pixmap)
+{
+    Q_ASSERT(!item.isNull());
+    KDirLister* dirLister = m_dolphinModel->dirLister();
+    if (!m_showPreview || (item.url().directory() != dirLister->url().path())) {
+        // the preview has been canceled in the meanwhile or the preview
+        // job is still working on items of an older URL, hence
+        // the item is not part of the directory model anymore
+        return;
+    }
+
+    const QModelIndex idx = m_dolphinModel->indexForItem(item);
+    if (idx.isValid() && (idx.column() == 0)) {
+        const QMimeData* mimeData = QApplication::clipboard()->mimeData();
+        if (KonqMimeData::decodeIsCutSelection(mimeData) && isCutItem(item)) {
+            KIconEffect iconEffect;
+            const QPixmap cutPixmap = iconEffect.apply(pixmap, KIconLoader::Desktop, KIconLoader::DisabledState);
+            m_dolphinModel->setData(idx, QIcon(cutPixmap), Qt::DecorationRole);
+        } else {
+            m_dolphinModel->setData(idx, QIcon(pixmap), Qt::DecorationRole);
+        }
+    }
+}
+
+
+void IconManager::slotPreviewJobFinished(KJob* job)
+{
+    const int index = m_previewJobs.indexOf(job);
+    m_previewJobs.removeAt(index);
+}
+
+void IconManager::updateCutItems()
+{
+    // restore the icons of all previously selected items to the
+    // original state...
+    foreach (CutItem cutItem, m_cutItemsCache) {
+        const QModelIndex index = m_dolphinModel->indexForUrl(cutItem.url);
+        if (index.isValid()) {
+            m_dolphinModel->setData(index, QIcon(cutItem.pixmap), Qt::DecorationRole);
+        }
+    }
+    m_cutItemsCache.clear();
+
+    // ... and apply an item effect to all currently cut items
+    applyCutItemEffect();
+}
+
+bool IconManager::isCutItem(const KFileItem& item) const
+{
+    const QMimeData* mimeData = QApplication::clipboard()->mimeData();
+    const KUrl::List cutUrls = KUrl::List::fromMimeData(mimeData);
+
+    const KUrl& itemUrl = item.url();
+    foreach (KUrl url, cutUrls) {
+        if (url == itemUrl) {
+            return true;
+        }
+    }
+
+    return false;
+}
+
+void IconManager::applyCutItemEffect()
+{
+    const QMimeData* mimeData = QApplication::clipboard()->mimeData();
+    if (!KonqMimeData::decodeIsCutSelection(mimeData)) {
+        return;
+    }
+
+    const KFileItemList items(m_dolphinModel->dirLister()->items());
+    foreach (KFileItem item, items) {
+        if (isCutItem(item)) {
+            const QModelIndex index = m_dolphinModel->indexForItem(item);
+            const QVariant value = m_dolphinModel->data(index, Qt::DecorationRole);
+            if (value.type() == QVariant::Icon) {
+                const QIcon icon(qvariant_cast<QIcon>(value));
+                QPixmap pixmap = icon.pixmap(128, 128);
+
+                // remember current pixmap for the item to be able
+                // to restore it when other items get cut
+                CutItem cutItem;
+                cutItem.url = item.url();
+                cutItem.pixmap = pixmap;
+                m_cutItemsCache.append(cutItem);
+
+                // apply icon effect to the cut item
+                KIconEffect iconEffect;
+                pixmap = iconEffect.apply(pixmap, KIconLoader::Desktop, KIconLoader::DisabledState);
+                m_dolphinModel->setData(index, QIcon(pixmap), Qt::DecorationRole);
+            }
+        }
+    }
+}
+
+#include "iconmanager.moc"
diff --git a/src/iconmanager.h b/src/iconmanager.h
new file mode 100644 (file)
index 0000000..175e4a0
--- /dev/null
@@ -0,0 +1,107 @@
+/***************************************************************************
+ *   Copyright (C) 2008 by Peter Penz <peter.penz@gmx.at>                  *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA            *
+ ***************************************************************************/
+
+#ifndef ICONMANAGER_H
+#define ICONMANAGER_H
+
+#include <kurl.h>
+
+#include <QList>
+#include <QObject>
+#include <QPixmap>
+
+class DolphinModel;
+class KFileItem;
+class KFileItemList;
+class KJob;
+
+/**
+ * @brief Manages the icon state of a directory model.
+ *
+ * Per default a preview is generated for each item.
+ * Additionally the clipboard is checked for cut items.
+ * The icon state for cut items gets dimmed automatically.
+ */
+class IconManager : public QObject
+{
+    Q_OBJECT
+
+public:
+    IconManager(QObject* parent, DolphinModel* model);
+    virtual ~IconManager();
+    void setShowPreview(bool show);
+    bool showPreview() const;
+
+private slots:
+    /**
+     * Generates a preview image for each file item in \a items.
+     * The current preview settings (maximum size, 'Show Preview' menu)
+     * are respected.
+     */
+    void generatePreviews(const KFileItemList& items);
+
+    /**
+     * Replaces the icon of the item \a item by the preview pixmap
+     * \a pixmap.
+     */
+    void replaceIcon(const KFileItem& item, const QPixmap& pixmap);
+
+    /**
+     * Is invoked when the preview job has been finished and
+     * set m_previewJob to 0.
+     */
+    void slotPreviewJobFinished(KJob* job);
+
+    /** Synchronizes the item icon with the clipboard of cut items. */
+    void updateCutItems();
+
+private:
+    /**
+     * Returns true, if the item \a item has been cut into
+     * the clipboard.
+     */
+    bool isCutItem(const KFileItem& item) const;
+
+    /** Applies an item effect to all cut items. */
+    void applyCutItemEffect();
+
+private:
+    /**
+     * Remembers the original pixmap for an item before
+     * the cut effect is applied.
+     */
+    struct CutItem
+    {
+        KUrl url;
+        QPixmap pixmap;
+    };
+
+   bool m_showPreview;
+   QList<KJob*> m_previewJobs;
+   DolphinModel* m_dolphinModel;
+
+   QList<CutItem> m_cutItemsCache;
+};
+
+inline bool IconManager::showPreview() const
+{
+    return m_showPreview;
+}
+
+#endif