Patch to fix crash in kdirmodel

Andreas Pakulat apaku at gmx.de
Mon Feb 19 22:42:56 GMT 2007


Hi,

the attached patch fixes a crash in kdirmodel if a view calls fetchMore
more than once with the same index. This happens if one puts a simple
QListView on top of a kdirmodel and then navigates into a directory with
many items so that scrollbars appear. When you navigate to the same dir
the second time you can crash the app by scrolling. The reason is that
QAbstractItemView's implementations of *ScrollBarValueChanged() call
fetchMore() without first running canFetchMore.

The downside of the patch is the memory added by 1 bool for each item
in the model. So I'm not sure if we should do that or just depend on
sane view implementations that first check with canFetchMore before
fetching more.

Andreas

-- 
You will be surrounded by luxury.
-------------- next part --------------
Index: kio/kio/kdirmodel.cpp
===================================================================
--- kio/kio/kdirmodel.cpp	(Revision 634794)
+++ kio/kio/kdirmodel.cpp	(Arbeitskopie)
@@ -42,7 +42,8 @@ public:
     KDirModelNode( KDirModelDirNode* parent, KFileItem* item ) :
         m_item(item),
         m_parent(parent),
-        m_preview()
+        m_preview(),
+        m_populated(false)
     {
     }
     //KUrl url() const { return m_item->url(); }
@@ -54,11 +55,14 @@ public:
     QIcon preview() const { return m_preview; }
     void addPreview( const QPixmap& pix ) { m_preview.addPixmap(pix); }
     void setPreview( const QIcon& icn ) { m_preview = icn; }
+    bool isPopulated() const { return m_populated; }
+    void setPopulated( bool populated ) { m_populated = populated; }
 
 private:
     KFileItem* m_item;
     KDirModelDirNode* const m_parent;
     QIcon m_preview;
+    bool m_populated;
 };
 
 // Specialization for directory nodes
@@ -614,7 +618,7 @@ bool KDirModel::canFetchMore( const QMod
 
     KDirModelNode* node = static_cast<KDirModelNode*>(parent.internalPointer());
     KFileItem* item = node->item();
-    return item->isDir() /*&& !node->m_populated*/
+    return item->isDir() && !node->isPopulated()
         && static_cast<KDirModelDirNode *>(node)->m_childNodes.isEmpty();
 }
 
@@ -627,7 +631,10 @@ void KDirModel::fetchMore( const QModelI
     //kDebug() << k_funcinfo << url << endl;
 
     KDirModelNode* parentNode = static_cast<KDirModelNode*>(parent.internalPointer());
-    //parentNode->m_populated = true;
+    if( parentNode->isPopulated() )
+        return;
+
+    parentNode->setPopulated( true );
     KFileItem* parentItem = parentNode->item();
     Q_ASSERT(parentItem->isDir());
 


More information about the kde-core-devel mailing list