Skip to content

Commit

Permalink
#6034: Offer SortModelFoldersFirst overloads to start at a given elem…
Browse files Browse the repository at this point in the history
…ent in the tree.

Reduce code duplication by forwarding calls to more specific overloads.
  • Loading branch information
codereader committed Aug 5, 2022
1 parent 3f43438 commit f971cf8
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 17 deletions.
40 changes: 24 additions & 16 deletions libs/wxutil/dataview/TreeModel.cpp
Expand Up @@ -350,12 +350,12 @@ void TreeModel::ForeachNodeRecursiveReverse(const TreeModel::NodePtr& node, cons

void TreeModel::SortModel(const TreeModel::SortFunction& sortFunction)
{
SortModelRecursive(_rootNode, sortFunction);
SortModelRecursively(_rootNode.get(), sortFunction);
}

void TreeModel::SortModelByColumn(const TreeModel::Column& column)
{
SortModelRecursive(_rootNode, [&] (const wxDataViewItem& a, const wxDataViewItem& b)->bool
SortModelRecursively(_rootNode.get(), [&](const wxDataViewItem& a, const wxDataViewItem& b)->bool
{
Row rowA(a, *this);
Row rowB(b, *this);
Expand Down Expand Up @@ -393,23 +393,31 @@ void TreeModel::SortModelByColumn(const TreeModel::Column& column)
});
}

void TreeModel::SortModelFoldersFirst(const TreeModel::Column& stringColumn,
const TreeModel::Column& isFolderColumn)
void TreeModel::SortModelFoldersFirst(const Column& stringColumn, const Column& isFolderColumn)
{
SortModelRecursive(_rootNode, std::bind(&TreeModel::CompareFoldersFirst,
this,
std::placeholders::_1,
std::placeholders::_2,
stringColumn,
stringColumn.type == Column::String ? CompareStringVariants : CompareIconTextVariants,
isFolderColumn,
FolderCompareFunction())); // custom folder comparer is empty
// Pass an empty item to start at the root element
SortModelFoldersFirst(wxDataViewItem(), stringColumn, isFolderColumn);
}

void TreeModel::SortModelFoldersFirst(const wxDataViewItem& startItem, const Column& stringColumn, const Column& isFolderColumn)
{
// Pass an empty custom folder comparer
SortModelFoldersFirst(startItem, stringColumn, isFolderColumn, FolderCompareFunction());
}

void TreeModel::SortModelFoldersFirst(const Column& stringColumn, const Column& isFolderColumn,
const FolderCompareFunction& customFolderSortFunc)
{
SortModelRecursive(_rootNode, std::bind(&TreeModel::CompareFoldersFirst,
// Pass an empty item to start at the root element
SortModelFoldersFirst(wxDataViewItem(), stringColumn, isFolderColumn, customFolderSortFunc);
}

void TreeModel::SortModelFoldersFirst(const wxDataViewItem& startItem, const Column& stringColumn,
const Column& isFolderColumn, const FolderCompareFunction& customFolderSortFunc)
{
auto startNode = !startItem.IsOk() ? _rootNode.get() : static_cast<Node*>(startItem.GetID());

SortModelRecursively(startNode, std::bind(&TreeModel::CompareFoldersFirst,
this,
std::placeholders::_1,
std::placeholders::_2,
Expand All @@ -419,18 +427,18 @@ void TreeModel::SortModelFoldersFirst(const Column& stringColumn, const Column&
customFolderSortFunc));
}

void TreeModel::SortModelRecursive(const TreeModel::NodePtr& node, const TreeModel::SortFunction& sortFunction)
void TreeModel::SortModelRecursively(Node* node, const TreeModel::SortFunction& sortFunction)
{
// Use std::sort algorithm and small lambda to only pass wxDataViewItems to the client sort function
std::sort(node->children.begin(), node->children.end(), [&] (const NodePtr& a, const NodePtr& b)->bool
{
return sortFunction(a->item, b->item);
return sortFunction(a->item, b->item);
});

// Enter recursion
std::for_each(node->children.begin(), node->children.end(), [&] (const NodePtr& child)
{
SortModelRecursive(child, sortFunction);
SortModelRecursively(child.get(), sortFunction);
});
}

Expand Down
11 changes: 10 additions & 1 deletion libs/wxutil/dataview/TreeModel.h
Expand Up @@ -445,6 +445,10 @@ class TreeModel :
// Pass a boolean-valued "is-a-folder" column to indicate which items are actual folders.
virtual void SortModelFoldersFirst(const Column& stringColumn, const Column& isFolderColumn);

// Sort the model by a string-valued column, sorting folders on top, starting at the given item.
// See also the other SortModelFoldersFirst overload.
virtual void SortModelFoldersFirst(const wxDataViewItem& startItem, const Column& stringColumn, const Column& isFolderColumn);

using FolderCompareFunction = std::function<int(const wxDataViewItem&, const wxDataViewItem&)>;

// Sort the model by a string-valued column, sorting folders on top.
Expand All @@ -454,6 +458,11 @@ class TreeModel :
virtual void SortModelFoldersFirst(const Column& stringColumn, const Column& isFolderColumn,
const FolderCompareFunction& customFolderSortFunc);

// Sort the model by a string-valued column, sorting folders on top, starting at the given item.
// See also the other SortModelFoldersFirst overload.
virtual void SortModelFoldersFirst(const wxDataViewItem& startItem, const Column& stringColumn,
const Column& isFolderColumn, const FolderCompareFunction& customFolderSortFunc);

// Find the given string needle in the given column (searches the entire tree)
virtual wxDataViewItem FindString(const std::string& needle, const Column& column);

Expand Down Expand Up @@ -523,7 +532,7 @@ class TreeModel :
protected:
void ForeachNodeRecursive(const TreeModel::NodePtr& node, const VisitFunction& visitFunction);
void ForeachNodeRecursiveReverse(const TreeModel::NodePtr& node, const TreeModel::VisitFunction& visitFunction);
void SortModelRecursive(const TreeModel::NodePtr& node, const TreeModel::SortFunction& sortFunction);
void SortModelRecursively(Node* node, const TreeModel::SortFunction& sortFunction);

// Sort functor for the SortModelFoldersFirst() method, uses the stringCompare method to compare the actual text values
// Pass CompareStringVariants or CompareIconTextVariants as stringCompare.
Expand Down

0 comments on commit f971cf8

Please sign in to comment.