Skip to content

Commit

Permalink
#5568: Streamline the resource tree view filter functions a bit.
Browse files Browse the repository at this point in the history
This way the code to hide empty folders can also take effect when overriding the IsTreeModelRowVisible method.
  • Loading branch information
codereader committed Mar 23, 2021
1 parent 211f30c commit 0a534f7
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 49 deletions.
75 changes: 28 additions & 47 deletions libs/wxutil/dataview/ResourceTreeView.cpp
Expand Up @@ -102,10 +102,8 @@ void ResourceTreeView::SetupTreeModelFilter()
// Set up the filter
_treeModelFilter.reset(new TreeModelFilter(_treeStore));

_treeModelFilter->SetVisibleFunc([this](TreeModel::Row& row)
{
return IsTreeModelRowVisible(row);
});
_treeModelFilter->SetVisibleFunc(
std::bind(&ResourceTreeView::IsTreeModelRowOrAnyChildVisible, this, std::placeholders::_1));

AssociateModel(_treeModelFilter.get());

Expand Down Expand Up @@ -596,73 +594,56 @@ bool ResourceTreeView::IsFavouriteSelected()
return row[_columns.isFavourite].getBool();
}

bool ResourceTreeView::IsTreeModelRowVisible(wxutil::TreeModel::Row& row)
{
if (!IsTreeModelRowVisibleByViewMode(row))
{
return false; // done here
}

// Check for a text filter we might need to apply
if (_filterText.empty())
{
return true; // done here
}

return !IsTreeModelRowFilteredRecursively(row);
}

bool ResourceTreeView::IsTreeModelRowFilteredRecursively(wxutil::TreeModel::Row& row)
bool ResourceTreeView::IsTreeModelRowOrAnyChildVisible(TreeModel::Row& row)
{
if (TreeModel::RowContainsString(row, _filterText, _colsToSearch, true))
// Test the node itself
if (IsTreeModelRowVisible(row))
{
return false;
return true; // node is visible
}

// This node might also be visible if a single child node is visible, dive into it
// The node itself is invisible, but it might still be visible
// if any of the child nodes is visible, dive into it
wxDataViewItemArray children;
_treeStore->GetChildren(row.getItem(), children);

for (const wxDataViewItem& child : children)
{
wxutil::TreeModel::Row childRow(child, *_treeStore);

if (!IsTreeModelRowFilteredRecursively(childRow))
// Check the child node (recursively)
if (IsTreeModelRowOrAnyChildVisible(childRow))
{
return false; // unfiltered node, break the loop
return true; // found a visible child, this is enough
}
}

// Either we don't have any children, or
// all child nodes are filtered, so this node is filtered too
return true;
// all child nodes are invisible, so this node is invisible too
return false;
}

bool ResourceTreeView::IsTreeModelRowVisibleByViewMode(wxutil::TreeModel::Row& row)
bool ResourceTreeView::IsTreeModelRowVisible(wxutil::TreeModel::Row& row)
{
if (_mode == TreeMode::ShowAll) return true; // everything is visible

// Favourites mode, check if this item or any descendant is visible
if (row[_columns.isFavourite].getBool())
// Check view mode
if (!IsTreeModelRowVisibleByViewMode(row))
{
return true;
return false; // done here
}

wxDataViewItemArray children;
_treeStore->GetChildren(row.getItem(), children);

// Enter the recursion for each of the children and bail out on the first visible one
for (const wxDataViewItem& child : children)
{
wxutil::TreeModel::Row childRow(child, *_treeStore);
// Check filter, otherwise the node is visible
return !IsTreeModelRowFiltered(row);
}

if (IsTreeModelRowVisibleByViewMode(childRow))
{
return true;
}
}
bool ResourceTreeView::IsTreeModelRowFiltered(wxutil::TreeModel::Row& row)
{
return !_filterText.empty() && !TreeModel::RowContainsString(row, _filterText, _colsToSearch, true);
}

return false;
bool ResourceTreeView::IsTreeModelRowVisibleByViewMode(wxutil::TreeModel::Row& row)
{
// In favourites mode, check if this item is marked as favourite
return _mode == TreeMode::ShowAll || row[_columns.isFavourite].getBool();
}

}
7 changes: 5 additions & 2 deletions libs/wxutil/dataview/ResourceTreeView.h
Expand Up @@ -173,12 +173,15 @@ class ResourceTreeView :
virtual std::string GetResourcePathOfSelection();

private:
// Recursive visibility test used by the TreeModelFilterFunction
bool IsTreeModelRowOrAnyChildVisible(TreeModel::Row& row);

// Returns true if the given row is visible according
// to the current view mode (show favourites vs. show all)
bool IsTreeModelRowVisibleByViewMode(TreeModel::Row& row);

// Returns true if the given row is filtered (i.e. node and all child nodes are invisible)
bool IsTreeModelRowFilteredRecursively(wxutil::TreeModel::Row& row);
// Returns true if the given row is filtered by an active filter text
bool IsTreeModelRowFiltered(wxutil::TreeModel::Row& row);

void _onContextMenu(wxDataViewEvent& ev);
void _onTreeStorePopulationProgress(TreeModel::PopulationProgressEvent& ev);
Expand Down

0 comments on commit 0a534f7

Please sign in to comment.