From 0490d12e0945060c7f3ea0b2415b9626682f3b6a Mon Sep 17 00:00:00 2001 From: Peter Penz Date: Thu, 19 Aug 2010 15:01:52 +0000 Subject: [PATCH] Fix crash in column view because of a dangling pointer to a selection model. Thanks a lot to Frank Reininghaus for finding a way how to reproduce the issue and analyzing the root cause. Keeping the selection model as part of the DolphinView is not required anymore at all, as the restoring of selected items is done by m_selectedItems in the meantime. CCBUG: 247618 svn path=/trunk/KDE/kdebase/apps/; revision=1165532 --- src/views/dolphinview.cpp | 63 +++++++++++++++++++-------------------- src/views/dolphinview.h | 1 - 2 files changed, 31 insertions(+), 33 deletions(-) diff --git a/src/views/dolphinview.cpp b/src/views/dolphinview.cpp index 919805790..1da3dc42b 100644 --- a/src/views/dolphinview.cpp +++ b/src/views/dolphinview.cpp @@ -93,7 +93,6 @@ DolphinView::DolphinView(QWidget* parent, m_dolphinViewController(0), m_viewModeController(0), m_viewAccessor(proxyModel), - m_selectionModel(0), m_selectionChangedTimer(0), m_rootUrl(), m_activeItemUrl(), @@ -540,30 +539,33 @@ QList DolphinView::versionControlActions(const KFileItemList& items) c void DolphinView::setUrl(const KUrl& url) { - if (m_viewModeController->url() != url) { - m_newFileNames.clear(); + if (m_viewModeController->url() == url) { + return; + } - m_viewModeController->setUrl(url); // emits urlChanged, which we forward - m_viewAccessor.prepareUrlChange(url); - applyViewProperties(); - loadDirectory(url); + // The selection model might change in the case of the column view. Disconnect + // from the current selection model and reconnect later after the URL switch. + QAbstractItemView* view = m_viewAccessor.itemView(); + disconnect(view->selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)), + this, SLOT(slotSelectionChanged(QItemSelection, QItemSelection))); - // When changing the URL there is no need to keep the version - // data of the previous URL. - m_viewAccessor.dirModel()->clearVersionData(); + m_newFileNames.clear(); - emit startedPathLoading(url); - } + m_viewModeController->setUrl(url); // emits urlChanged, which we forward + m_viewAccessor.prepareUrlChange(url); + applyViewProperties(); + loadDirectory(url); - // the selection model might have changed in the case of a column view - QItemSelectionModel* selectionModel = m_viewAccessor.itemView()->selectionModel(); - if (m_selectionModel != selectionModel) { - disconnect(m_selectionModel, SIGNAL(selectionChanged(QItemSelection, QItemSelection)), - this, SLOT(slotSelectionChanged(QItemSelection, QItemSelection))); - m_selectionModel = selectionModel; - connect(m_selectionModel, SIGNAL(selectionChanged(QItemSelection, QItemSelection)), - this, SLOT(slotSelectionChanged(QItemSelection, QItemSelection))); - } + // When changing the URL there is no need to keep the version + // data of the previous URL. + m_viewAccessor.dirModel()->clearVersionData(); + + emit startedPathLoading(url); + + // Reconnect to the (probably) new selection model + view = m_viewAccessor.itemView(); + connect(view->selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)), + this, SLOT(slotSelectionChanged(QItemSelection, QItemSelection))); } void DolphinView::selectAll() @@ -1271,28 +1273,25 @@ void DolphinView::applyViewProperties() void DolphinView::createView() { + QAbstractItemView* view = m_viewAccessor.itemView(); + if ((view != 0) && (view->selectionModel() != 0)) { + disconnect(view->selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)), + this, SLOT(slotSelectionChanged(QItemSelection, QItemSelection))); + } + deleteView(); Q_ASSERT(m_viewAccessor.itemView() == 0); m_viewAccessor.createView(this, m_dolphinViewController, m_viewModeController, m_mode); - QAbstractItemView* view = m_viewAccessor.itemView(); + view = m_viewAccessor.itemView(); Q_ASSERT(view != 0); view->installEventFilter(this); view->viewport()->installEventFilter(this); m_dolphinViewController->setItemView(view); - // When changing the view mode, the selection is lost due to reinstantiating - // a new item view with a custom selection model. Pass the ownership of the - // selection model to DolphinView, so that it can be shared by all item views. - if (m_selectionModel != 0) { - view->setSelectionModel(m_selectionModel); - } else { - m_selectionModel = view->selectionModel(); - } - m_selectionModel->setParent(this); - connect(m_selectionModel, SIGNAL(selectionChanged(QItemSelection, QItemSelection)), + connect(view->selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)), this, SLOT(slotSelectionChanged(QItemSelection, QItemSelection))); setFocusProxy(m_viewAccessor.layoutTarget()); diff --git a/src/views/dolphinview.h b/src/views/dolphinview.h index dbef511bf..4877b0cd2 100644 --- a/src/views/dolphinview.h +++ b/src/views/dolphinview.h @@ -795,7 +795,6 @@ private: ViewModeController* m_viewModeController; ViewAccessor m_viewAccessor; - QItemSelectionModel* m_selectionModel; // allow to switch views without losing the selection QTimer* m_selectionChangedTimer; KUrl m_rootUrl; -- 2.47.3