ProjectExplorer: Add option to hide empty directories from project tree

Together with the earlier fix for hiding generated files, this change makes
for a very clean CMake server-mode project tree:-)

Change-Id: Ib70fd66699eddf5d6e602f3f8848b31fd6d85b57
Reviewed-by: André Hartmann <aha_1980@gmx.de>
Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
This commit is contained in:
Tobias Hunger
2017-08-02 17:02:02 +02:00
parent e50f882f0f
commit ea867cd49a
6 changed files with 71 additions and 3 deletions

View File

@@ -689,6 +689,20 @@ void TreeItem::insertChild(int pos, TreeItem *item)
}
}
void TreeItem::removeChildAt(int pos)
{
QTC_ASSERT(0 <= pos && pos < m_children.count(), return);
if (m_model) {
QModelIndex idx = index();
m_model->beginRemoveRows(idx, pos, pos);
removeItemAt(pos);
m_model->endRemoveRows();
} else {
removeItemAt(pos);
}
}
void TreeItem::removeChildren()
{
if (childCount() == 0)
@@ -863,6 +877,15 @@ void TreeItem::clear()
}
}
void TreeItem::removeItemAt(int pos)
{
TreeItem *item = m_children.at(pos);
item->m_model = nullptr;
item->m_parent = nullptr;
delete item;
m_children.removeAt(pos);
}
void TreeItem::expand()
{
QTC_ASSERT(m_model, return);

View File

@@ -54,6 +54,7 @@ public:
void prependChild(TreeItem *item);
void appendChild(TreeItem *item);
void insertChild(int pos, TreeItem *item);
void removeChildAt(int pos);
void removeChildren();
void sortChildren(const std::function<bool(const TreeItem *, const TreeItem *)> &cmp);
void update();
@@ -90,6 +91,7 @@ private:
void operator=(const TreeItem &) = delete;
void clear();
void removeItemAt(int pos);
void propagateModel(BaseTreeModel *m);
TreeItem *m_parent; // Not owned.

View File

@@ -189,7 +189,10 @@ void FlatModel::addOrRebuildProjectModel(Project *project)
if (ProjectNode *projectNode = project->rootProjectNode()) {
addFolderNode(container, projectNode, &seen);
} else {
if (m_trimEmptyDirectories)
trimEmptyDirectories(container);
}
if (container->childCount() == 0) {
FileNode *projectFileNode = new FileNode(project->projectFilePath(), FileType::Project, false);
seen.insert(projectFileNode);
container->appendChild(new WrapperNode(projectFileNode));
@@ -317,6 +320,18 @@ void FlatModel::addFolderNode(WrapperNode *parent, FolderNode *folderNode, QSet<
}
}
bool FlatModel::trimEmptyDirectories(WrapperNode *parent)
{
if (!parent->m_node->asFolderNode())
return false;
for (int i = parent->childCount() - 1; i >= 0; --i) {
if (trimEmptyDirectories(parent->childAt(i)))
parent->removeChildAt(i);
}
return parent->childCount() == 0;
}
Qt::DropActions FlatModel::supportedDragActions() const
{
return Qt::MoveAction;
@@ -363,10 +378,20 @@ void FlatModel::setProjectFilterEnabled(bool filter)
void FlatModel::setGeneratedFilesFilterEnabled(bool filter)
{
if (filter == m_filterGeneratedFiles)
return;
m_filterGeneratedFiles = filter;
rebuildModel();
}
void FlatModel::setTrimEmptyDirectories(bool filter)
{
if (filter == m_trimEmptyDirectories)
return;
m_trimEmptyDirectories = filter;
rebuildModel();
}
bool FlatModel::projectFilterEnabled()
{
return m_filterProjects;

View File

@@ -76,6 +76,7 @@ public:
bool generatedFilesFilterEnabled();
void setProjectFilterEnabled(bool filter);
void setGeneratedFilesFilterEnabled(bool filter);
void setTrimEmptyDirectories(bool filter);
void onExpanded(const QModelIndex &idx);
void onCollapsed(const QModelIndex &idx);
@@ -87,12 +88,14 @@ signals:
private:
bool m_filterProjects = false;
bool m_filterGeneratedFiles = true;
bool m_trimEmptyDirectories = true;
static const QLoggingCategory &logger();
void updateSubtree(FolderNode *node);
void rebuildModel();
void addFolderNode(WrapperNode *parent, FolderNode *folderNode, QSet<Node *> *seen);
bool trimEmptyDirectories(WrapperNode *parent);
ExpandData expandDataForNode(const Node *node) const;
void loadExpandData();

View File

@@ -194,6 +194,12 @@ ProjectTreeWidget::ProjectTreeWidget(QWidget *parent) : QWidget(parent)
connect(m_filterGeneratedFilesAction, &QAction::toggled,
this, &ProjectTreeWidget::setGeneratedFilesFilter);
m_trimEmptyDirectoriesAction = new QAction(tr("Hide Empty Directories"), this);
m_trimEmptyDirectoriesAction->setCheckable(true);
m_trimEmptyDirectoriesAction->setChecked(true);
connect(m_trimEmptyDirectoriesAction, &QAction::toggled,
this, &ProjectTreeWidget::setTrimEmptyDirectories);
// connections
connect(m_model, &FlatModel::renamed,
this, &ProjectTreeWidget::renamed);
@@ -433,6 +439,12 @@ void ProjectTreeWidget::setGeneratedFilesFilter(bool filter)
m_filterGeneratedFilesAction->setChecked(filter);
}
void ProjectTreeWidget::setTrimEmptyDirectories(bool filter)
{
m_model->setTrimEmptyDirectories(filter);
m_trimEmptyDirectoriesAction->setChecked(filter);
}
bool ProjectTreeWidget::generatedFilesFilter()
{
return m_model->generatedFilesFilterEnabled();
@@ -466,6 +478,7 @@ NavigationView ProjectTreeWidgetFactory::createWidget()
auto filterMenu = new QMenu(filter);
filterMenu->addAction(ptw->m_filterProjectsAction);
filterMenu->addAction(ptw->m_filterGeneratedFilesAction);
filterMenu->addAction(ptw->m_trimEmptyDirectoriesAction);
filter->setMenu(filterMenu);
n.dockToolBarWidgets << filter << ptw->toggleSync();

View File

@@ -70,6 +70,7 @@ public:
private:
void setProjectFilter(bool filter);
void setGeneratedFilesFilter(bool filter);
void setTrimEmptyDirectories(bool filter);
void handleCurrentItemChange(const QModelIndex &current);
void showContextMenu(const QPoint &pos);
@@ -83,8 +84,9 @@ private:
QTreeView *m_view = nullptr;
FlatModel *m_model = nullptr;
QAction *m_filterProjectsAction = nullptr;
QAction *m_filterGeneratedFilesAction;
QToolButton *m_toggleSync;
QAction *m_filterGeneratedFilesAction = nullptr;
QAction *m_trimEmptyDirectoriesAction = nullptr;
QToolButton *m_toggleSync = nullptr;
QString m_modelId;
bool m_autoSync = true;