aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEike Ziller <eike.ziller@qt.io>2018-10-19 14:00:28 +0200
committerEike Ziller <eike.ziller@qt.io>2018-10-23 05:46:25 +0000
commite3021b7178fd557de5e10c55db5875e0eff73b2e (patch)
tree232a2b6083d455767d0f3030c77e03506e3d732b
parent496ecfc88a8b539a5a5ddbcbd7d0e88609824099 (diff)
Fix crash in folder navigation widget
We want to delay updating the crumble path, but we may not keep and pass around the QModelIndex, since that can become invalid. Change-Id: Id0c1ffb046dda1fb3bc09801fd1952787f9919fa Reviewed-by: Eike Ziller <eike.ziller@qt.io>
-rw-r--r--src/plugins/projectexplorer/foldernavigationwidget.cpp28
-rw-r--r--src/plugins/projectexplorer/foldernavigationwidget.h4
2 files changed, 23 insertions, 9 deletions
diff --git a/src/plugins/projectexplorer/foldernavigationwidget.cpp b/src/plugins/projectexplorer/foldernavigationwidget.cpp
index b0df620375..f6853ef9a2 100644
--- a/src/plugins/projectexplorer/foldernavigationwidget.cpp
+++ b/src/plugins/projectexplorer/foldernavigationwidget.cpp
@@ -373,13 +373,25 @@ FolderNavigationWidget::FolderNavigationWidget(QWidget *parent) : QWidget(parent
connect(m_listView, &QAbstractItemView::activated, this, [this](const QModelIndex &index) {
openItem(m_sortProxyModel->mapToSource(index));
});
- // use QueuedConnection for updating crumble path, because that can scroll, which doesn't
- // work well when done directly in currentChanged (the wrong item can get highlighted)
+ // Delay updating crumble path by event loop cylce, because that can scroll, which doesn't
+ // work well when done directly in currentChanged (the wrong item can get highlighted).
+ // We cannot use Qt::QueuedConnection directly, because the QModelIndex could get invalidated
+ // in the meantime, so use a queued invokeMethod instead.
connect(m_listView->selectionModel(),
&QItemSelectionModel::currentChanged,
this,
- &FolderNavigationWidget::setCrumblePath,
- Qt::QueuedConnection);
+ [this](const QModelIndex &index) {
+ const QModelIndex sourceIndex = m_sortProxyModel->mapToSource(index);
+ const auto filePath = Utils::FileName::fromString(
+ m_fileSystemModel->filePath(sourceIndex));
+ // QTimer::singleShot only posts directly onto the event loop if you use the SLOT("...")
+ // notation, so using a singleShot with a lambda would flicker
+ // QTimer::singleShot(0, this, [this, filePath]() { setCrumblePath(filePath); });
+ QMetaObject::invokeMethod(this,
+ "setCrumblePath",
+ Qt::QueuedConnection,
+ Q_ARG(Utils::FileName, filePath));
+ });
connect(m_crumbLabel, &Utils::FileCrumbLabel::pathClicked, [this](const Utils::FileName &path) {
const QModelIndex rootIndex = m_sortProxyModel->mapToSource(m_listView->rootIndex());
const QModelIndex fileIndex = m_fileSystemModel->index(path.toString());
@@ -623,7 +635,7 @@ void FolderNavigationWidget::selectFile(const Utils::FileName &filePath)
} else {
m_listView->scrollTo(fileIndex);
}
- setCrumblePath(fileIndex);
+ setCrumblePath(filePath);
});
}
}
@@ -699,12 +711,12 @@ void FolderNavigationWidget::createNewFolder(const QModelIndex &parent)
m_listView->edit(index);
}
-void FolderNavigationWidget::setCrumblePath(const QModelIndex &index)
+void FolderNavigationWidget::setCrumblePath(const Utils::FileName &filePath)
{
- const QModelIndex sourceIndex = m_sortProxyModel->mapToSource(index);
+ const QModelIndex index = m_fileSystemModel->index(filePath.toString());
const int width = m_crumbLabel->width();
const int previousHeight = m_crumbLabel->immediateHeightForWidth(width);
- m_crumbLabel->setPath(Utils::FileName::fromString(m_fileSystemModel->filePath(sourceIndex)));
+ m_crumbLabel->setPath(filePath);
const int currentHeight = m_crumbLabel->immediateHeightForWidth(width);
const int diff = currentHeight - previousHeight;
if (diff != 0 && m_crumbLabel->isVisible()) {
diff --git a/src/plugins/projectexplorer/foldernavigationwidget.h b/src/plugins/projectexplorer/foldernavigationwidget.h
index f10f69d595..5c8a2e24f6 100644
--- a/src/plugins/projectexplorer/foldernavigationwidget.h
+++ b/src/plugins/projectexplorer/foldernavigationwidget.h
@@ -118,6 +118,9 @@ public:
protected:
void contextMenuEvent(QContextMenuEvent *ev) override;
+private slots:
+ void setCrumblePath(const Utils::FileName &filePath);
+
private:
bool rootAutoSynchronization() const;
void setRootAutoSynchronization(bool sync);
@@ -131,7 +134,6 @@ private:
QStringList projectsInDirectory(const QModelIndex &index) const;
void openProjectsInDirectory(const QModelIndex &index);
void createNewFolder(const QModelIndex &parent);
- void setCrumblePath(const QModelIndex &index);
Core::IContext *m_context = nullptr;
Utils::NavigationTreeView *m_listView = nullptr;