Skip to content

Commit

Permalink
project directory filter expands directories, hides filtered out dire…
Browse files Browse the repository at this point in the history
…ctories
  • Loading branch information
kusharami committed Jan 18, 2021
1 parent d08c8f9 commit 018023d
Show file tree
Hide file tree
Showing 5 changed files with 146 additions and 56 deletions.
166 changes: 112 additions & 54 deletions BananaUI/ProjectDirectoryFilterModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -251,69 +251,57 @@ bool ProjectDirectoryFilterModel::filterAcceptsColumn(
return (0 == source_column);
}

bool ProjectDirectoryFilterModel::filterAcceptsRow(
int source_row, const QModelIndex &source_parent) const
static QList<QFileInfo> splitDirs(QFileInfo fileInfo)
{
if (project_tree_model != nullptr)
{
auto project_dir = project_tree_model->getProjectDirectory();
if (nullptr == project_dir)
return false;

auto index = project_tree_model->index(source_row, 0, source_parent);

if (index.isValid())
{
auto fileinfo = project_tree_model->fileInfo(index);

if (fileinfo.isRoot())
return true;
QList<QFileInfo> dirs;

auto filePath = QDir::cleanPath(fileinfo.filePath());

if (fileinfo.isDir() &&
!filePath.startsWith(
QDir::cleanPath(project_dir->getFilePath()) + "/",
Qt::CaseInsensitive))
return true;

filePath = project_dir->getRelativeFilePathFor(filePath);

if (hideIgnored && ignore.isValid() && !ignore.isEmpty())
{
if (ignore.exactMatch(filePath))
return false;
}

if (fileinfo.isDir())
return true;
fileInfo = QFileInfo(QDir::cleanPath(fileInfo.filePath()));
do
{
fileInfo = QFileInfo(fileInfo.path());
dirs.prepend(fileInfo);
} while (!QDir(fileInfo.filePath()).isRoot());

auto re = filterRegExp();
return dirs;
}

if (!re.isEmpty() && re.isValid())
{
if (!re.exactMatch(filePath))
return false;
}
bool ProjectDirectoryFilterModel::filterAcceptsRow(
int source_row, const QModelIndex &source_parent) const
{
if (project_tree_model == nullptr)
{
return false;
}
auto re = filterRegExp();
if (re.isEmpty() || !re.isValid())
{
return QSortFilterProxyModel::filterAcceptsRow(
source_row, source_parent);
}

if (showDirsOnly)
{
if (!fileinfo.isDir())
return false;
}
auto project_dir = project_tree_model->getProjectDirectory();
if (nullptr == project_dir)
return false;

if (show_extensions.empty())
return true;
auto index = project_tree_model->index(source_row, 0, source_parent);
if (!index.isValid())
{
return false;
}
auto fileinfo = project_tree_model->fileInfo(index);
if (fileinfo.isRoot())
return true;

for (auto extension : show_extensions)
{
if (filePath.endsWith(extension, Qt::CaseInsensitive))
return true;
}
}
if (fileinfo.isDir())
{
auto rootPath = QDir::cleanPath(project_dir->getFilePath()) + "/";
auto filePath = QDir::cleanPath(fileinfo.filePath());
if (!filePath.startsWith(rootPath, Qt::CaseInsensitive))
return true;
}

return false;
return filterAcceptsRowInternal(
source_row, source_parent, splitDirs(fileinfo));
}

bool ProjectDirectoryFilterModel::lessThan(
Expand Down Expand Up @@ -448,4 +436,74 @@ void ProjectDirectoryFilterModel::disconnectProjectFile()
project_file = nullptr;
}
}

bool ProjectDirectoryFilterModel::filterAcceptsRowInternal(int source_row,
const QModelIndex &source_parent, const QList<QFileInfo> &parentDirs) const
{
auto index = project_tree_model->index(source_row, 0, source_parent);
Q_ASSERT(index.isValid());
auto fileInfo = project_tree_model->fileInfo(index);

auto project_dir = project_tree_model->getProjectDirectory();
Q_ASSERT(project_dir);

if (showDirsOnly)
{
if (!fileInfo.isDir())
return false;
}

if (fileInfo.isDir())
{
bool recurse = true;
for (auto &inf : parentDirs)
{
if (inf.canonicalFilePath().compare(fileInfo.canonicalFilePath(),
Qt::CaseInsensitive) == 0) // check cyclic symlink
{
recurse = false;
break;
}
}
if (recurse)
{
auto currentDirs = parentDirs;
currentDirs.append(fileInfo);
int rows = project_tree_model->rowCount(index);
if (project_tree_model->canFetchMore(index))
{
project_tree_model->fetchMore(index);
rows = project_tree_model->rowCount(index);
}
for (int i = 0; i < rows; i++)
{
if (filterAcceptsRowInternal(i, index, currentDirs))
return true;
}
}
}

auto filePath = QDir::cleanPath(fileInfo.filePath());
filePath = project_dir->getRelativeFilePathFor(filePath);

if (hideIgnored && ignore.isValid() && !ignore.isEmpty())
{
if (ignore.exactMatch(filePath))
return false;
}

if (!filterRegExp().exactMatch(filePath))
return false;

if (show_extensions.empty())
return true;

for (auto extension : show_extensions)
{
if (filePath.endsWith(extension, Qt::CaseInsensitive))
return true;
}

return false;
}
}
6 changes: 6 additions & 0 deletions BananaUI/ProjectDirectoryFilterModel.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ SOFTWARE.

#include <QSortFilterProxyModel>

#include <QDir>

#include <vector>

namespace Banana
Expand Down Expand Up @@ -78,6 +80,10 @@ private slots:
void connectProjectFile();
void disconnectProjectFile();

bool filterAcceptsRowInternal(int source_row,
const QModelIndex &source_parent,
const QList<QFileInfo> &parentDirs) const;

std::vector<const char *> show_extensions;
ProjectDirectoryModel *project_tree_model;
AbstractProjectFile *project_file;
Expand Down
22 changes: 21 additions & 1 deletion BananaUI/ProjectTreeView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ ProjectTreeView::ProjectTreeView(QWidget *parent)
this, &ProjectTreeView::onFilterModelAboutToBeReset);
QObject::connect(filterModel, &QAbstractItemModel::modelReset, this,
&ProjectTreeView::onFilterModelReset);
QObject::connect(filterModel, &QAbstractItemModel::layoutChanged, this,
&ProjectTreeView::expandIfFilter);
QObject::connect(filterModel, &QAbstractItemModel::rowsInserted, this,
&ProjectTreeView::expandIfFilter);
}

void ProjectTreeView::select(AbstractFileSystemObject *file, bool expand)
Expand Down Expand Up @@ -508,6 +512,11 @@ void ProjectTreeView::onFilterModelReset()

setProjectDirectory(project_dir);

if (expandIfFilter())
{
expanded.clear();
return;
}
if (nullptr != projectDirModel)
{
for (auto &path : expanded)
Expand All @@ -525,14 +534,25 @@ void ProjectTreeView::onFilterModelReset()
}

expanded.clear();

if (!savedCurrent.isEmpty())
{
select(savedCurrent, false);
savedCurrent.clear();
}
}

bool ProjectTreeView::expandIfFilter()
{
auto re = filterModel->filterRegExp();
if (!re.isEmpty() && re.isValid())
{
expandAll();
return true;
}

return false;
}

void ProjectTreeView::saveExpandedDirs(const QModelIndex &parent_index)
{
int count = filterModel->rowCount(parent_index);
Expand Down
3 changes: 2 additions & 1 deletion BananaUI/ProjectTreeView.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,10 @@ class ProjectTreeView
signals:
void modelSelectionChanged();

private slots:
private:
void onFilterModelAboutToBeReset();
void onFilterModelReset();
bool expandIfFilter();

protected:
virtual void dragEnterEvent(QDragEnterEvent *event) override;
Expand Down
5 changes: 5 additions & 0 deletions BananaUI/ProjectTreeWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,11 @@ void ProjectTreeWidget::updateFilter(bool force)

model->setFilterRegExp(
QRegExp(text, Qt::CaseInsensitive, pattern_syntax));

if (!text.isEmpty())
{
ui->projectTreeView->expandAll();
}
}
}

Expand Down

0 comments on commit 018023d

Please sign in to comment.