forked from qt-creator/qt-creator
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:
@@ -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()
|
void TreeItem::removeChildren()
|
||||||
{
|
{
|
||||||
if (childCount() == 0)
|
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()
|
void TreeItem::expand()
|
||||||
{
|
{
|
||||||
QTC_ASSERT(m_model, return);
|
QTC_ASSERT(m_model, return);
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ public:
|
|||||||
void prependChild(TreeItem *item);
|
void prependChild(TreeItem *item);
|
||||||
void appendChild(TreeItem *item);
|
void appendChild(TreeItem *item);
|
||||||
void insertChild(int pos, TreeItem *item);
|
void insertChild(int pos, TreeItem *item);
|
||||||
|
void removeChildAt(int pos);
|
||||||
void removeChildren();
|
void removeChildren();
|
||||||
void sortChildren(const std::function<bool(const TreeItem *, const TreeItem *)> &cmp);
|
void sortChildren(const std::function<bool(const TreeItem *, const TreeItem *)> &cmp);
|
||||||
void update();
|
void update();
|
||||||
@@ -90,6 +91,7 @@ private:
|
|||||||
void operator=(const TreeItem &) = delete;
|
void operator=(const TreeItem &) = delete;
|
||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
|
void removeItemAt(int pos);
|
||||||
void propagateModel(BaseTreeModel *m);
|
void propagateModel(BaseTreeModel *m);
|
||||||
|
|
||||||
TreeItem *m_parent; // Not owned.
|
TreeItem *m_parent; // Not owned.
|
||||||
|
|||||||
@@ -189,7 +189,10 @@ void FlatModel::addOrRebuildProjectModel(Project *project)
|
|||||||
|
|
||||||
if (ProjectNode *projectNode = project->rootProjectNode()) {
|
if (ProjectNode *projectNode = project->rootProjectNode()) {
|
||||||
addFolderNode(container, projectNode, &seen);
|
addFolderNode(container, projectNode, &seen);
|
||||||
} else {
|
if (m_trimEmptyDirectories)
|
||||||
|
trimEmptyDirectories(container);
|
||||||
|
}
|
||||||
|
if (container->childCount() == 0) {
|
||||||
FileNode *projectFileNode = new FileNode(project->projectFilePath(), FileType::Project, false);
|
FileNode *projectFileNode = new FileNode(project->projectFilePath(), FileType::Project, false);
|
||||||
seen.insert(projectFileNode);
|
seen.insert(projectFileNode);
|
||||||
container->appendChild(new WrapperNode(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
|
Qt::DropActions FlatModel::supportedDragActions() const
|
||||||
{
|
{
|
||||||
return Qt::MoveAction;
|
return Qt::MoveAction;
|
||||||
@@ -363,10 +378,20 @@ void FlatModel::setProjectFilterEnabled(bool filter)
|
|||||||
|
|
||||||
void FlatModel::setGeneratedFilesFilterEnabled(bool filter)
|
void FlatModel::setGeneratedFilesFilterEnabled(bool filter)
|
||||||
{
|
{
|
||||||
|
if (filter == m_filterGeneratedFiles)
|
||||||
|
return;
|
||||||
m_filterGeneratedFiles = filter;
|
m_filterGeneratedFiles = filter;
|
||||||
rebuildModel();
|
rebuildModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FlatModel::setTrimEmptyDirectories(bool filter)
|
||||||
|
{
|
||||||
|
if (filter == m_trimEmptyDirectories)
|
||||||
|
return;
|
||||||
|
m_trimEmptyDirectories = filter;
|
||||||
|
rebuildModel();
|
||||||
|
}
|
||||||
|
|
||||||
bool FlatModel::projectFilterEnabled()
|
bool FlatModel::projectFilterEnabled()
|
||||||
{
|
{
|
||||||
return m_filterProjects;
|
return m_filterProjects;
|
||||||
|
|||||||
@@ -76,6 +76,7 @@ public:
|
|||||||
bool generatedFilesFilterEnabled();
|
bool generatedFilesFilterEnabled();
|
||||||
void setProjectFilterEnabled(bool filter);
|
void setProjectFilterEnabled(bool filter);
|
||||||
void setGeneratedFilesFilterEnabled(bool filter);
|
void setGeneratedFilesFilterEnabled(bool filter);
|
||||||
|
void setTrimEmptyDirectories(bool filter);
|
||||||
|
|
||||||
void onExpanded(const QModelIndex &idx);
|
void onExpanded(const QModelIndex &idx);
|
||||||
void onCollapsed(const QModelIndex &idx);
|
void onCollapsed(const QModelIndex &idx);
|
||||||
@@ -87,12 +88,14 @@ signals:
|
|||||||
private:
|
private:
|
||||||
bool m_filterProjects = false;
|
bool m_filterProjects = false;
|
||||||
bool m_filterGeneratedFiles = true;
|
bool m_filterGeneratedFiles = true;
|
||||||
|
bool m_trimEmptyDirectories = true;
|
||||||
|
|
||||||
static const QLoggingCategory &logger();
|
static const QLoggingCategory &logger();
|
||||||
|
|
||||||
void updateSubtree(FolderNode *node);
|
void updateSubtree(FolderNode *node);
|
||||||
void rebuildModel();
|
void rebuildModel();
|
||||||
void addFolderNode(WrapperNode *parent, FolderNode *folderNode, QSet<Node *> *seen);
|
void addFolderNode(WrapperNode *parent, FolderNode *folderNode, QSet<Node *> *seen);
|
||||||
|
bool trimEmptyDirectories(WrapperNode *parent);
|
||||||
|
|
||||||
ExpandData expandDataForNode(const Node *node) const;
|
ExpandData expandDataForNode(const Node *node) const;
|
||||||
void loadExpandData();
|
void loadExpandData();
|
||||||
|
|||||||
@@ -194,6 +194,12 @@ ProjectTreeWidget::ProjectTreeWidget(QWidget *parent) : QWidget(parent)
|
|||||||
connect(m_filterGeneratedFilesAction, &QAction::toggled,
|
connect(m_filterGeneratedFilesAction, &QAction::toggled,
|
||||||
this, &ProjectTreeWidget::setGeneratedFilesFilter);
|
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
|
// connections
|
||||||
connect(m_model, &FlatModel::renamed,
|
connect(m_model, &FlatModel::renamed,
|
||||||
this, &ProjectTreeWidget::renamed);
|
this, &ProjectTreeWidget::renamed);
|
||||||
@@ -433,6 +439,12 @@ void ProjectTreeWidget::setGeneratedFilesFilter(bool filter)
|
|||||||
m_filterGeneratedFilesAction->setChecked(filter);
|
m_filterGeneratedFilesAction->setChecked(filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ProjectTreeWidget::setTrimEmptyDirectories(bool filter)
|
||||||
|
{
|
||||||
|
m_model->setTrimEmptyDirectories(filter);
|
||||||
|
m_trimEmptyDirectoriesAction->setChecked(filter);
|
||||||
|
}
|
||||||
|
|
||||||
bool ProjectTreeWidget::generatedFilesFilter()
|
bool ProjectTreeWidget::generatedFilesFilter()
|
||||||
{
|
{
|
||||||
return m_model->generatedFilesFilterEnabled();
|
return m_model->generatedFilesFilterEnabled();
|
||||||
@@ -466,6 +478,7 @@ NavigationView ProjectTreeWidgetFactory::createWidget()
|
|||||||
auto filterMenu = new QMenu(filter);
|
auto filterMenu = new QMenu(filter);
|
||||||
filterMenu->addAction(ptw->m_filterProjectsAction);
|
filterMenu->addAction(ptw->m_filterProjectsAction);
|
||||||
filterMenu->addAction(ptw->m_filterGeneratedFilesAction);
|
filterMenu->addAction(ptw->m_filterGeneratedFilesAction);
|
||||||
|
filterMenu->addAction(ptw->m_trimEmptyDirectoriesAction);
|
||||||
filter->setMenu(filterMenu);
|
filter->setMenu(filterMenu);
|
||||||
|
|
||||||
n.dockToolBarWidgets << filter << ptw->toggleSync();
|
n.dockToolBarWidgets << filter << ptw->toggleSync();
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
void setProjectFilter(bool filter);
|
void setProjectFilter(bool filter);
|
||||||
void setGeneratedFilesFilter(bool filter);
|
void setGeneratedFilesFilter(bool filter);
|
||||||
|
void setTrimEmptyDirectories(bool filter);
|
||||||
|
|
||||||
void handleCurrentItemChange(const QModelIndex ¤t);
|
void handleCurrentItemChange(const QModelIndex ¤t);
|
||||||
void showContextMenu(const QPoint &pos);
|
void showContextMenu(const QPoint &pos);
|
||||||
@@ -83,8 +84,9 @@ private:
|
|||||||
QTreeView *m_view = nullptr;
|
QTreeView *m_view = nullptr;
|
||||||
FlatModel *m_model = nullptr;
|
FlatModel *m_model = nullptr;
|
||||||
QAction *m_filterProjectsAction = nullptr;
|
QAction *m_filterProjectsAction = nullptr;
|
||||||
QAction *m_filterGeneratedFilesAction;
|
QAction *m_filterGeneratedFilesAction = nullptr;
|
||||||
QToolButton *m_toggleSync;
|
QAction *m_trimEmptyDirectoriesAction = nullptr;
|
||||||
|
QToolButton *m_toggleSync = nullptr;
|
||||||
|
|
||||||
QString m_modelId;
|
QString m_modelId;
|
||||||
bool m_autoSync = true;
|
bool m_autoSync = true;
|
||||||
|
|||||||
Reference in New Issue
Block a user