Commit 62d36ac9 authored by Daniel Teske's avatar Daniel Teske
Browse files

ProjectTree: Improve save/load of expand data



So far the code only saved the path of the expanded nodes, which always
created problems for nodes that had the same path. This broke for the
virtual folders SOURCES, FORMS, HEADERS recently because they have
nowadys the same path. They used to have different paths.

This new code saves both the path and the displayname and compares that,
this fixes the expanding for those folders.

Obviously there is no sure way to indetify the right nodes to expand,
and this isn't backwards compatible.

Change-Id: I9854f90ca942f92420970765b0cc19138ad5d63d
Task-number: QTCREATORBUG-14304
Reviewed-by: default avatarTobias Hunger <tobias.hunger@theqtcompany.com>
parent 557bac13
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms and
** conditions see http://www.qt.io/terms-conditions. For further information
** use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#include "expanddata.h"
using namespace ProjectExplorer;
using namespace ProjectExplorer::Internal;
ExpandData::ExpandData(const QString &path_, const QString &displayName_)
: path(path_), displayName(displayName_)
{}
bool ExpandData::operator==(const ExpandData &other) const
{
return path == other.path && displayName == other.displayName;
}
QStringList ExpandData::toStringList() const
{
return { path, displayName };
}
int ProjectExplorer::Internal::qHash(const ExpandData &data)
{
return qHash(data.path) ^ qHash(data.displayName);
}
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms and
** conditions see http://www.qt.io/terms-conditions. For further information
** use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#ifndef EXPANDDATA_H
#define EXPANDDATA_H
#include <QString>
#include <QHash>
#include <QDebug>
namespace ProjectExplorer {
namespace Internal {
class ExpandData
{
public:
ExpandData() = default;
ExpandData(const QString &path_, const QString &displayName_);
bool operator==(const ExpandData &other) const;
QStringList toStringList() const;
QString path;
QString displayName;
};
int qHash(const ExpandData &data);
} // namespace Internal
} // namespace ProjectExplorer
#endif // EXPANDDATA_H
......@@ -153,7 +153,8 @@ HEADERS += projectexplorer.h \
panelswidget.h \
projectwelcomepage.h \
projectpanelfactory.h \
projecttree.h
projecttree.h \
expanddata.h
SOURCES += projectexplorer.cpp \
abi.cpp \
......@@ -292,7 +293,8 @@ SOURCES += projectexplorer.cpp \
panelswidget.cpp \
projectwelcomepage.cpp \
projectpanelfactory.cpp \
projecttree.cpp
projecttree.cpp \
expanddata.cpp
FORMS += processstep.ui \
editorsettingspropertiespage.ui \
......
......@@ -70,6 +70,7 @@ QtcPlugin {
"environmentaspectwidget.cpp", "environmentaspectwidget.h",
"environmentitemswidget.cpp", "environmentitemswidget.h",
"environmentwidget.cpp", "environmentwidget.h",
"expanddata.cpp", "expanddata.h",
"foldernavigationwidget.cpp", "foldernavigationwidget.h",
"gccparser.cpp", "gccparser.h",
"gcctoolchain.cpp", "gcctoolchain.h",
......
......@@ -218,10 +218,14 @@ int ProjectTreeWidget::expandedCount(Node *node)
void ProjectTreeWidget::rowsInserted(const QModelIndex &parent, int start, int end)
{
const QString path = m_model->nodeForIndex(parent)->path().toString();
if (m_toExpand.contains(path)) {
Node *node = m_model->nodeForIndex(parent);
const QString path = node->path().toString();
const QString displayName = node->displayName();
auto it = m_toExpand.find(ExpandData(path, displayName));
if (it != m_toExpand.end()) {
m_view->expand(parent);
m_toExpand.remove(path);
m_toExpand.erase(it);
}
int i = start;
while (i <= end) {
......@@ -272,19 +276,31 @@ void ProjectTreeWidget::disableAutoExpand()
void ProjectTreeWidget::loadExpandData()
{
m_autoExpand = true;
QSet<QString> data = SessionManager::value(QLatin1String("ProjectTree.ExpandData")).toStringList().toSet();
recursiveLoadExpandData(m_view->rootIndex(), data);
QList<QVariant> data = SessionManager::value(QLatin1String("ProjectTree.ExpandData")).value<QList<QVariant>>();
QSet<ExpandData> set = Utils::transform<QSet>(data, [](const QVariant &v) {
QStringList list = v.toStringList();
if (list.size() != 2)
return ExpandData();
return ExpandData(list.at(0), list.at(1));
});
set.remove(ExpandData());
recursiveLoadExpandData(m_view->rootIndex(), set);
// store remaning nodes to expand
m_toExpand = data;
m_toExpand = set;
}
void ProjectTreeWidget::recursiveLoadExpandData(const QModelIndex &index, QSet<QString> &data)
void ProjectTreeWidget::recursiveLoadExpandData(const QModelIndex &index, QSet<ExpandData> &data)
{
const QString path = m_model->nodeForIndex(index)->path().toString();
if (data.contains(path)) {
Node *node = m_model->nodeForIndex(index);
const QString path = node->path().toString();
const QString displayName = node->displayName();
auto it = data.find(ExpandData(path, displayName));
if (it != data.end()) {
m_view->expand(index);
data.remove(path);
data.erase(it);
int count = m_model->rowCount(index);
for (int i = 0; i < count; ++i)
recursiveLoadExpandData(index.child(i, 0), data);
......@@ -293,19 +309,21 @@ void ProjectTreeWidget::recursiveLoadExpandData(const QModelIndex &index, QSet<Q
void ProjectTreeWidget::saveExpandData()
{
QStringList data;
QList<QVariant> data;
recursiveSaveExpandData(m_view->rootIndex(), &data);
// TODO if there are multiple ProjectTreeWidgets, the last one saves the data
SessionManager::setValue(QLatin1String("ProjectTree.ExpandData"), data);
}
void ProjectTreeWidget::recursiveSaveExpandData(const QModelIndex &index, QStringList *data)
void ProjectTreeWidget::recursiveSaveExpandData(const QModelIndex &index, QList<QVariant> *data)
{
Q_ASSERT(data);
if (m_view->isExpanded(index) || index == m_view->rootIndex()) {
// Note: We store the path of the node, which isn't unique for e.g. .pri files
// Note: We store the path+displayname of the node, which isn't unique for e.g. .pri files
// but works for most nodes
data->append(m_model->nodeForIndex(index)->path().toString());
Node *node = m_model->nodeForIndex(index);
const QStringList &list = ExpandData(node->path().toString(), node->displayName()).toStringList();
data->append(QVariant::fromValue(list));
int count = m_model->rowCount(index);
for (int i = 0; i < count; ++i)
recursiveSaveExpandData(index.child(i, 0), data);
......
......@@ -31,6 +31,8 @@
#ifndef PROJECTTREEWIDGET_H
#define PROJECTTREEWIDGET_H
#include "expanddata.h"
#include <coreplugin/inavigationwidgetfactory.h>
#include <utils/fileutils.h>
......@@ -92,13 +94,13 @@ private slots:
private:
void setCurrentItem(ProjectExplorer::Node *node);
void recursiveLoadExpandData(const QModelIndex &index, QSet<QString> &data);
void recursiveSaveExpandData(const QModelIndex &index, QStringList *data);
void recursiveLoadExpandData(const QModelIndex &index, QSet<ExpandData> &data);
void recursiveSaveExpandData(const QModelIndex &index, QList<QVariant> *data);
static int expandedCount(Node *node);
void rowsInserted(const QModelIndex &parent, int start, int end);
void renamed(const Utils::FileName &oldPath, const Utils::FileName &newPath);
QSet<QString> m_toExpand;
QSet<ExpandData> m_toExpand;
QTreeView *m_view;
FlatModel *m_model;
QAction *m_filterProjectsAction;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment