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

List:       kde-commits
Subject:    KDE/kdelibs/kfile
From:       Aaron J. Seigo <aseigo () kde ! org>
Date:       2010-09-17 16:54:00
Message-ID: 20100917165400.38F96AC888 () svn ! kde ! org
[Download RAW message or body]

SVN commit 1176424 by aseigo:

use a QWeakPointer, as it is more performant than a QPointer, and check it everywhere \
it is used. may end up being more paranoid than strictly necessary, but follows the \
semenatics of a smart pointer and prevents future new and inventive ways of crashing \
KFilePreviewGenerator ;) CCMAIL:peter.penz19@gmail.com


 M  +88 -36    kfilepreviewgenerator.cpp  


--- trunk/KDE/kdelibs/kfile/kfilepreviewgenerator.cpp #1176423:1176424
@@ -358,7 +358,7 @@
     QTimer* m_iconUpdateTimer;
     QTimer* m_scrollAreaTimer;
     QList<KJob*> m_previewJobs;
-    QPointer<KDirModel> m_dirModel;
+    QWeakPointer<KDirModel> m_dirModel;
     QAbstractProxyModel* m_proxyModel;
 
     /**
@@ -418,7 +418,6 @@
     m_iconUpdateTimer(0),
     m_scrollAreaTimer(0),
     m_previewJobs(),
-    m_dirModel(0),
     m_proxyModel(0),
     m_cutItemsCache(),
     m_previews(),
@@ -439,17 +438,18 @@
     m_dirModel = (m_proxyModel == 0) ?
                  qobject_cast<KDirModel*>(model) :
                  qobject_cast<KDirModel*>(m_proxyModel->sourceModel());
-    if (m_dirModel == 0) {
+    if (!m_dirModel) {
         // previews can only get generated for directory models
         m_previewShown = false;
     } else {
-        connect(m_dirModel->dirLister(), SIGNAL(newItems(const KFileItemList&)),
+        KDirModel *dirModel = m_dirModel.data();
+        connect(dirModel->dirLister(), SIGNAL(newItems(const KFileItemList&)),
                 q, SLOT(updateIcons(const KFileItemList&)));
-        connect(m_dirModel, SIGNAL(dataChanged(const QModelIndex&, const \
QModelIndex&)), +        connect(dirModel, SIGNAL(dataChanged(const QModelIndex&, \
                const QModelIndex&)),
                 q, SLOT(updateIcons(const QModelIndex&, const QModelIndex&)));
-        connect(m_dirModel, SIGNAL(needSequenceIcon(const QModelIndex&,int)),
+        connect(dirModel, SIGNAL(needSequenceIcon(const QModelIndex&,int)),
                q, SLOT(requestSequenceIcon(const QModelIndex&, int)));
-        connect(m_dirModel, SIGNAL(rowsAboutToBeRemoved(const QModelIndex&, int, \
int)), +        connect(dirModel, SIGNAL(rowsAboutToBeRemoved(const QModelIndex&, \
                int, int)),
                 q, SLOT(rowsAboutToBeRemoved(const QModelIndex&, int, int)));
     }
 
@@ -492,7 +492,12 @@
                                                          int sequenceIndex)
 {
     if (m_pendingItems.isEmpty() || (sequenceIndex == 0)) {
-        KFileItem item = m_dirModel->itemForIndex(index);
+        KDirModel *dirModel = m_dirModel.data();
+        if (!dirModel) {
+            return;
+        }
+
+        KFileItem item = dirModel->itemForIndex(index);
         if (sequenceIndex == 0) {
            m_sequenceIndices.remove(item.url());
         } else {
@@ -540,13 +545,18 @@
         return;
     }
 
+    KDirModel *dirModel = m_dirModel.data();
+    if (!dirModel) {
+        return;
+    }
+
     KFileItemList itemList;
     for (int row = topLeft.row(); row <= bottomRight.row(); ++row) {
-        const QModelIndex index = m_dirModel->index(row, 0);
+        const QModelIndex index = dirModel->index(row, 0);
         if (!index.isValid()) {
             continue;
         }
-        const KFileItem item = m_dirModel->itemForIndex(index);
+        const KFileItem item = dirModel->itemForIndex(index);
         Q_ASSERT(!item.isNull());
 
         if (m_previewShown) {
@@ -589,10 +599,15 @@
         return;
     }
 
+    KDirModel *dirModel = m_dirModel.data();
+    if (!dirModel) {
+        return;
+    }
+
     // check whether the item is part of the directory lister (it is possible
     // that a preview from an old directory lister is received)
     const KUrl url = item.url();
-    KDirLister* dirLister = m_dirModel->dirLister();
+    KDirLister* dirLister = dirModel->dirLister();
     bool isOldPreview = true;
     const KUrl::List dirs = dirLister->directories();
     const QString itemDir = url.directory();
@@ -649,7 +664,8 @@
 
 void KFilePreviewGenerator::Private::updateCutItems()
 {
-    if (m_dirModel == 0) {
+    KDirModel *dirModel = m_dirModel.data();
+    if (!dirModel == 0) {
         // see bug #196681
         kWarning() << "KDirModel has been deleted before deleting \
KFilePreviewGenerator.";  return;
@@ -659,7 +675,7 @@
     clearCutItemsCache();
 
     KFileItemList items;
-    KDirLister* dirLister = m_dirModel->dirLister();
+    KDirLister* dirLister = dirModel->dirLister();
     const KUrl::List dirs = dirLister->directories();
     foreach (const KUrl& url, dirs) {
         items << dirLister->itemsForDir(url);
@@ -669,16 +685,21 @@
 
 void KFilePreviewGenerator::Private::clearCutItemsCache()
 {
+    KDirModel *dirModel = m_dirModel.data();
+    if (!dirModel == 0) {
+        return;
+    }
+
     DataChangeObtainer obt(this);
     KFileItemList previews;
     // Reset the icons of all items that are stored in the cache
     // to use their default MIME type icon.
     foreach (const KUrl& url, m_cutItemsCache.keys()) {
-        const QModelIndex index = m_dirModel->indexForUrl(url);
+        const QModelIndex index = dirModel->indexForUrl(url);
         if (index.isValid()) {
-            m_dirModel->setData(index, QIcon(), Qt::DecorationRole);
+            dirModel->setData(index, QIcon(), Qt::DecorationRole);
             if (m_previewShown) {
-                previews.append(m_dirModel->itemForIndex(index));
+                previews.append(dirModel->itemForIndex(index));
             }
         }
     }
@@ -694,6 +715,11 @@
 
 void KFilePreviewGenerator::Private::dispatchIconUpdateQueue()
 {
+    KDirModel *dirModel = m_dirModel.data();
+    if (!dirModel == 0) {
+        return;
+    }
+
     const int count = m_previewShown ? m_previews.count()
                                      : m_resolvedMimeTypes.count();
     if (count > 0) {
@@ -703,17 +729,17 @@
         if (m_previewShown) {
             // dispatch preview queue
             foreach (const ItemInfo& preview, m_previews) {
-                const QModelIndex idx = m_dirModel->indexForUrl(preview.url);
+                const QModelIndex idx = dirModel->indexForUrl(preview.url);
                 if (idx.isValid() && (idx.column() == 0)) {
-                    m_dirModel->setData(idx, QIcon(preview.pixmap), \
Qt::DecorationRole); +                    dirModel->setData(idx, \
QIcon(preview.pixmap), Qt::DecorationRole);  }
             }
             m_previews.clear();
         } else {
             // dispatch mime type queue
             foreach (const KFileItem& item, m_resolvedMimeTypes) {
-                const QModelIndex idx = m_dirModel->indexForItem(item);
-                m_dirModel->itemChanged(idx);
+                const QModelIndex idx = dirModel->indexForItem(item);
+                dirModel->itemChanged(idx);
             }
             m_resolvedMimeTypes.clear();
         }
@@ -848,14 +874,19 @@
         return;
     }
 
+    KDirModel *dirModel = m_dirModel.data();
+    if (!dirModel == 0) {
+        return;
+    }
+
     const QSet<KUrl> cutUrls = KUrl::List::fromMimeData(mimeData).toSet();
 
     DataChangeObtainer obt(this);
     KIconEffect *iconEffect = KIconLoader::global()->iconEffect();
     foreach (const KFileItem& item, items) {
         if (cutUrls.contains(item.url())) {
-            const QModelIndex index = m_dirModel->indexForItem(item);
-            const QVariant value = m_dirModel->data(index, Qt::DecorationRole);
+            const QModelIndex index = dirModel->indexForItem(item);
+            const QVariant value = dirModel->data(index, Qt::DecorationRole);
             if (value.type() == QVariant::Icon) {
                 const QIcon icon(qvariant_cast<QIcon>(value));
                 const QSize actualSize = icon.actualSize(m_viewAdapter->iconSize());
@@ -864,7 +895,7 @@
                 const QHash<KUrl, QPixmap>::const_iterator cacheIt = \
                m_cutItemsCache.constFind(item.url());
                 if ((cacheIt == m_cutItemsCache.constEnd()) || (cacheIt->cacheKey() \
                != pixmap.cacheKey())) {
                     pixmap = iconEffect->apply(pixmap, KIconLoader::Desktop, \
                KIconLoader::DisabledState);
-                    m_dirModel->setData(index, QIcon(pixmap), Qt::DecorationRole);
+                    dirModel->setData(index, QIcon(pixmap), Qt::DecorationRole);
                     
                     m_cutItemsCache.insert(item.url(), pixmap);
                 }
@@ -1033,6 +1064,11 @@
 
 void KFilePreviewGenerator::Private::orderItems(KFileItemList& items)
 {
+    KDirModel *dirModel = m_dirModel.data();
+    if (!dirModel == 0) {
+        return;
+    }
+
     // Order the items in a way that the preview for the visible items
     // is generated first, as this improves the feeled performance a lot.
     const bool hasProxy = (m_proxyModel != 0);
@@ -1043,7 +1079,7 @@
     QRect itemRect;
     int insertPos = 0;
     for (int i = 0; i < itemCount; ++i) {
-        dirIndex = m_dirModel->indexForItem(items.at(i)); // O(n) (n = number of \
rows) +        dirIndex = dirModel->indexForItem(items.at(i)); // O(n) (n = number of \
rows)  if (hasProxy) {
             const QModelIndex proxyIndex = m_proxyModel->mapFromSource(dirIndex);
             itemRect = m_viewAdapter->visualRect(proxyIndex);
@@ -1075,13 +1111,18 @@
 
 void KFilePreviewGenerator::Private::addItemsToList(const QModelIndex& index, \
KFileItemList& list)  {
-    const int rowCount = m_dirModel->rowCount(index);
+    KDirModel *dirModel = m_dirModel.data();
+    if (!dirModel == 0) {
+        return;
+    }
+
+    const int rowCount = dirModel->rowCount(index);
     for (int row = 0; row < rowCount; ++row) {
-        const QModelIndex subIndex = m_dirModel->index(row, 0, index);
-        KFileItem item = m_dirModel->itemForIndex(subIndex);
+        const QModelIndex subIndex = dirModel->index(row, 0, index);
+        KFileItem item = dirModel->itemForIndex(subIndex);
         list.append(item);
 
-        if (m_dirModel->rowCount(subIndex) > 0) {
+        if (dirModel->rowCount(subIndex) > 0) {
             // the model is hierarchical (treeview)
             addItemsToList(subIndex, list);
         }
@@ -1090,6 +1131,11 @@
 
 void KFilePreviewGenerator::Private::delayedIconUpdate()
 {
+    KDirModel *dirModel = m_dirModel.data();
+    if (!dirModel == 0) {
+        return;
+    }
+
     // Precondition: No items have been changed within the last
     // 5 seconds. This means that items that have been changed constantly
     // due to a copy operation should be updated now.
@@ -1100,8 +1146,8 @@
     while (it != m_changedItems.constEnd()) {
         const bool hasChanged = it.value();
         if (hasChanged) {
-            const QModelIndex index = m_dirModel->indexForUrl(it.key());
-            const KFileItem item = m_dirModel->itemForIndex(index);
+            const QModelIndex index = dirModel->indexForUrl(it.key());
+            const KFileItem item = dirModel->itemForIndex(index);
             itemList.append(item);
         }
         ++it;
@@ -1117,16 +1163,21 @@
         return;
     }
 
+    KDirModel *dirModel = m_dirModel.data();
+    if (!dirModel == 0) {
+        return;
+    }
+
     for (int row = start; row <= end; row++) {
-        const QModelIndex index = m_dirModel->index(row, 0, parent);
+        const QModelIndex index = dirModel->index(row, 0, parent);
 
-        const KFileItem item = m_dirModel->itemForIndex(index);
+        const KFileItem item = dirModel->itemForIndex(index);
         if (!item.isNull()) {
             m_changedItems.remove(item.url());
         }
 
-        if (m_dirModel->hasChildren(index)) {
-            rowsAboutToBeRemoved(index, 0, m_dirModel->rowCount(index) - 1);
+        if (dirModel->hasChildren(index)) {
+            rowsAboutToBeRemoved(index, 0, dirModel->rowCount(index) - 1);
         }
     }
 }
@@ -1151,7 +1202,8 @@
 
 void KFilePreviewGenerator::setPreviewShown(bool show)
 {
-    if (show && (!d->m_viewAdapter->iconSize().isValid() || (d->m_dirModel == 0))) {
+    KDirModel *dirModel = d->m_dirModel.data();
+    if (show && (!d->m_viewAdapter->iconSize().isValid() || !dirModel)) {
         // the view must provide an icon size and a directory model,
         // otherwise the showing the previews will get ignored
         return;
@@ -1162,7 +1214,7 @@
         if (!show) {
             // When turning off the previews, the directory must be refreshed
             // so that the previews get be replaced again by the MIME type icons.
-            KDirLister* dirLister = d->m_dirModel->dirLister();
+            KDirLister* dirLister = dirModel->dirLister();
             const KUrl url = dirLister->url();
             if (url.isValid()) {
                 dirLister->openUrl(url, KDirLister::NoFlags);


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

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