[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    KDE/kdelibs/kfile
From:       Peter Penz <peter.penz () gmx ! at>
Date:       2009-01-09 22:38:01
Message-ID: 1231540681.113966.6166.nullmailer () svn ! kde ! org
[Download RAW message or body]

SVN commit 908572 by ppenz:

Assure that the previews get recreated when a data change is done outside the scope \
of KFilePreviewGenerator.

CCMAIL: faure@kde.org

 M  +60 -8     kfilepreviewgenerator.cpp  
 M  +6 -5      kfilepreviewgenerator.h  


--- trunk/KDE/kdelibs/kfile/kfilepreviewgenerator.cpp #908571:908572
@@ -154,13 +154,19 @@
             KAbstractViewAdapter* viewAdapter,
             QAbstractItemModel* model);
     ~Private();
-    
+
     /**
      * Generates previews for the items \a items asynchronously.
      */
     void generatePreviews(const KFileItemList& items);
 
     /**
+     * Generates previews for the indices within \a topLeft
+     * and \a bottomRight asynchronously.
+     */
+    void generatePreviews(const QModelIndex& topLeft, const QModelIndex& \
bottomRight); +
+    /**
      * Adds the preview \a pixmap for the item \a item to the preview
      * queue and starts a timer which will dispatch the preview queue
      * later.
@@ -195,7 +201,7 @@
      * generated first.
      */
     void resumePreviews();
-    
+
     /**
      * Returns true, if the item \a item has been cut into
      * the clipboard.
@@ -240,7 +246,7 @@
      * been cut.
      */
     bool decodeIsCutSelection(const QMimeData* mimeData);
-    
+
     /** Remembers the pixmap for an item specified by an URL. */
     struct ItemInfo
     {
@@ -248,6 +254,20 @@
         QPixmap pixmap;
     };
 
+    /**
+     * During the lifetime of a DataChangeObtainer instance changing
+     * the data of the model won't trigger generating a preview.
+     */
+    class DataChangeObtainer
+    {
+    public:
+        DataChangeObtainer(KFilePreviewGenerator::Private* generator) :
+            m_gen(generator)  { ++m_gen->m_internalDataChange; }
+        ~DataChangeObtainer() { --m_gen->m_internalDataChange; }
+    private:
+        KFilePreviewGenerator::Private* m_gen;
+    };
+
     bool m_previewShown;
 
     /**
@@ -261,6 +281,13 @@
      */
     bool m_hasCutSelection;
 
+    /**
+     * If the value is 0, the slot
+     * generatePreviews(const QModelIndex&, const QModelIndex&) has
+     * been triggered by an external data change.
+     */
+    int m_internalDataChange;
+
     int m_pendingVisiblePreviews;
 
     KAbstractViewAdapter* m_viewAdapter;
@@ -303,6 +330,7 @@
     m_previewShown(true),
     m_clearItemQueues(true),
     m_hasCutSelection(false),
+    m_internalDataChange(0),
     m_pendingVisiblePreviews(0),
     m_viewAdapter(viewAdapter),
     m_itemView(0),
@@ -322,7 +350,7 @@
     if (!m_viewAdapter->iconSize().isValid()) {
         m_previewShown = false;
     }
-    
+
     m_proxyModel = qobject_cast<QAbstractProxyModel*>(model);
     m_dirModel = (m_proxyModel == 0) ?
                  qobject_cast<KDirModel*>(model) :
@@ -333,6 +361,8 @@
     } else {
         connect(m_dirModel->dirLister(), SIGNAL(newItems(const KFileItemList&)),
                 q, SLOT(generatePreviews(const KFileItemList&)));
+        connect(m_dirModel, SIGNAL(dataChanged(const QModelIndex&, const \
QModelIndex&)), +                q, SLOT(generatePreviews(const QModelIndex&, const \
QModelIndex&)));  }
 
     QClipboard* clipboard = QApplication::clipboard();
@@ -357,7 +387,7 @@
 }
 
 KFilePreviewGenerator::Private::~Private()
-{        
+{
     killPreviewJobs();
     m_pendingItems.clear();
     m_dispatchedItems.clear();
@@ -386,6 +416,25 @@
     startPreviewJob(orderedItems);
 }
 
+void KFilePreviewGenerator::Private::generatePreviews(const QModelIndex& topLeft,
+                                                      const QModelIndex& \
bottomRight) +{
+    if (m_internalDataChange > 0) {
+        // QAbstractItemModel::setData() has been invoked internally by the \
KFilePreviewGenerator. +        // The signal dataChanged() is connected with this \
method, but previews only need +        // to be generated when an external data \
change has occured. +        return;
+    }
+
+    KFileItemList itemList;
+    for (int row = topLeft.row(); row <= bottomRight.row(); ++row) {
+        const QModelIndex index = m_dirModel->index(row, 0);
+        const KFileItem item = m_dirModel->itemForIndex(index);
+        itemList.append(item);
+    }
+    generatePreviews(itemList);
+}
+
 void KFilePreviewGenerator::Private::addToPreviewQueue(const KFileItem& item, const \
QPixmap& pixmap)  {
     if (!m_previewShown) {
@@ -462,6 +511,8 @@
 
 void KFilePreviewGenerator::Private::updateCutItems()
 {
+    DataChangeObtainer obt(this);
+
     // restore the icons of all previously selected items to the
     // original state...
     foreach (const ItemInfo& cutItem, m_cutItemsCache) {
@@ -485,6 +536,7 @@
         // 'gotPreview()' from the PreviewJob is too expensive, as a relayout
         // of the view would be triggered for each single preview.
         LayoutBlocker blocker(m_itemView);
+        DataChangeObtainer obt(this);
         for (int i = 0; i < previewsCount; ++i) {
             const ItemInfo& preview = m_previews.first();
 
@@ -584,6 +636,7 @@
         items << dirLister->itemsForDir(url);
     }
 
+    DataChangeObtainer obt(this);
     foreach (const KFileItem& item, items) {
         if (isCutItem(item)) {
             const QModelIndex index = m_dirModel->indexForItem(item);
@@ -694,7 +747,7 @@
     const QSize size = m_viewAdapter->iconSize();
 
     // PreviewJob internally caches items always with the size of
-    // 128 x 128 pixels or 256 x 256 pixels. A downscaling is done 
+    // 128 x 128 pixels or 256 x 256 pixels. A downscaling is done
     // by PreviewJob if a smaller size is requested. As the KFilePreviewGenerator \
must  // do a downscaling anyhow because of the frame, only the provided
     // cache sizes are requested.
@@ -730,7 +783,6 @@
     // the model. Choosing the right algorithm is important when having directories
     // with several hundreds or thousands of items.
 
-
     const bool hasProxy = (m_proxyModel != 0);
     const int itemCount = items.count();
     const int rowCount = hasProxy ? m_proxyModel->rowCount() : \
m_dirModel->rowCount(); @@ -834,7 +886,7 @@
         // otherwise the showing the previews will get ignored
         return;
     }
-    
+
     if (d->m_previewShown != show) {
         d->m_previewShown = show;
         d->m_cutItemsCache.clear();
--- trunk/KDE/kdelibs/kfile/kfilepreviewgenerator.h #908571:908572
@@ -55,17 +55,17 @@
     /**
      * @param parent  Item view containing the file items where previews should
      *                be generated. It is mandatory that the item view specifies
-     *                an icon size by QAbstractItemView::setIconSize() and that 
+     *                an icon size by QAbstractItemView::setIconSize() and that
      *                the model of the view (or the source model of the proxy model)
      *                is an instance of KDirModel. Otherwise no previews will be \
                generated.
      */
     KFilePreviewGenerator(QAbstractItemView* parent);
-    
+
     /** @internal */
     KFilePreviewGenerator(KAbstractViewAdapter* parent, QAbstractProxyModel* model);
-    
+
     virtual ~KFilePreviewGenerator();
-    
+
     /**
      * If \a show is set to true, a preview is generated for each item. If \a show
      * is false, the MIME type icon of the item is shown instead. Per default \
showing @@ -112,8 +112,9 @@
     class Private;
     Private* const d; /// @internal
     Q_DISABLE_COPY(KFilePreviewGenerator)
-    
+
     Q_PRIVATE_SLOT(d, void generatePreviews(const KFileItemList&))
+    Q_PRIVATE_SLOT(d, void generatePreviews(const QModelIndex&, const QModelIndex&))
     Q_PRIVATE_SLOT(d, void addToPreviewQueue(const KFileItem&, const QPixmap&))
     Q_PRIVATE_SLOT(d, void slotPreviewJobFinished(KJob*))
     Q_PRIVATE_SLOT(d, void updateCutItems())


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic