From f971cf8d73f86a70a748ca38008f67f0a9b59970 Mon Sep 17 00:00:00 2001 From: codereader Date: Fri, 5 Aug 2022 07:51:47 +0200 Subject: [PATCH] #6034: Offer SortModelFoldersFirst overloads to start at a given element in the tree. Reduce code duplication by forwarding calls to more specific overloads. --- libs/wxutil/dataview/TreeModel.cpp | 40 ++++++++++++++++++------------ libs/wxutil/dataview/TreeModel.h | 11 +++++++- 2 files changed, 34 insertions(+), 17 deletions(-) diff --git a/libs/wxutil/dataview/TreeModel.cpp b/libs/wxutil/dataview/TreeModel.cpp index fa8612bf37..7a3662745b 100644 --- a/libs/wxutil/dataview/TreeModel.cpp +++ b/libs/wxutil/dataview/TreeModel.cpp @@ -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); @@ -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(startItem.GetID()); + + SortModelRecursively(startNode, std::bind(&TreeModel::CompareFoldersFirst, this, std::placeholders::_1, std::placeholders::_2, @@ -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); }); } diff --git a/libs/wxutil/dataview/TreeModel.h b/libs/wxutil/dataview/TreeModel.h index 66a1d68275..5ddf59ea65 100644 --- a/libs/wxutil/dataview/TreeModel.h +++ b/libs/wxutil/dataview/TreeModel.h @@ -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; // Sort the model by a string-valued column, sorting folders on top. @@ -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); @@ -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.