diff --git a/libs/wxutil/dataview/ResourceTreeView.cpp b/libs/wxutil/dataview/ResourceTreeView.cpp index 5bbe2a7898..1fc47b4615 100644 --- a/libs/wxutil/dataview/ResourceTreeView.cpp +++ b/libs/wxutil/dataview/ResourceTreeView.cpp @@ -5,6 +5,7 @@ #include "ifavourites.h" #include "../menu/IconTextMenuItem.h" #include "TreeViewItemStyle.h" +#include "string/case_conv.h" #include namespace wxutil @@ -199,6 +200,17 @@ void ResourceTreeView::PopulateContextMenu(wxutil::PopupMenu& popupMenu) ); } +void ResourceTreeView::SetFilterText(const std::string& filterText) +{ + // We use the lower-case copy of the given filter text + _filterText = string::to_lower_copy(filterText); +} + +void ResourceTreeView::ClearFilterText() +{ + _filterText.clear(); +} + std::string ResourceTreeView::GetSelectedFullname() { // Get the selected value @@ -429,6 +441,28 @@ bool ResourceTreeView::IsFavouriteSelected() } 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 + } + + wxDataViewIconText iconAndName = row[_columns.iconAndName]; + + auto displayString = iconAndName.GetText().ToStdString(); + string::to_lower(displayString); + rMessage() << "displayString: " << displayString << ": " << displayString.find(_filterText) << std::endl; + + return displayString.find(_filterText) != std::string::npos; +} + +bool ResourceTreeView::IsTreeModelRowVisibleByViewMode(wxutil::TreeModel::Row& row) { if (_mode == TreeMode::ShowAll) return true; // everything is visible @@ -446,7 +480,7 @@ bool ResourceTreeView::IsTreeModelRowVisible(wxutil::TreeModel::Row& row) { wxutil::TreeModel::Row childRow(child, *_treeStore); - if (IsTreeModelRowVisible(childRow)) + if (IsTreeModelRowVisibleByViewMode(childRow)) { return true; } diff --git a/libs/wxutil/dataview/ResourceTreeView.h b/libs/wxutil/dataview/ResourceTreeView.h index a928de4800..8fc642cd06 100644 --- a/libs/wxutil/dataview/ResourceTreeView.h +++ b/libs/wxutil/dataview/ResourceTreeView.h @@ -88,6 +88,8 @@ class ResourceTreeView : decl::Type _declType; + std::string _filterText; + public: ResourceTreeView(wxWindow* parent, const Columns& columns, long style = wxDV_SINGLE); ResourceTreeView(wxWindow* parent, const TreeModel::Ptr& model, const Columns& columns, long style = wxDV_SINGLE); @@ -101,6 +103,15 @@ class ResourceTreeView : virtual TreeMode GetTreeMode() const; virtual void SetTreeMode(TreeMode mode); + // Sets the string filter to apply to the currently visible tree + // this string will match against the default iconAndName column, + // all rows not containing the string will be hidden. + // Filtering happens case-insensitively. + virtual void SetFilterText(const std::string& filterText); + + // Removes the string filter + virtual void ClearFilterText(); + // Returns the full name of the selection (or an empty string) virtual std::string GetSelectedFullname(); virtual void SetSelectedFullname(const std::string& fullName); @@ -135,6 +146,10 @@ class ResourceTreeView : virtual bool IsTreeModelRowVisible(TreeModel::Row& row); private: + // Returns true if the given row is visible according + // to the current view mode (show favourites vs. show all) + bool IsTreeModelRowVisibleByViewMode(TreeModel::Row& row); + void _onContextMenu(wxDataViewEvent& ev); void _onTreeStorePopulationProgress(TreeModel::PopulationProgressEvent& ev); void _onTreeStorePopulationFinished(TreeModel::PopulationFinishedEvent& ev); diff --git a/libs/wxutil/dataview/ResourceTreeViewToolbar.h b/libs/wxutil/dataview/ResourceTreeViewToolbar.h index 9dfe4fdb75..7bdd0fc112 100644 --- a/libs/wxutil/dataview/ResourceTreeViewToolbar.h +++ b/libs/wxutil/dataview/ResourceTreeViewToolbar.h @@ -4,6 +4,7 @@ #include #include #include +#include #include "ResourceTreeView.h" namespace wxutil @@ -40,6 +41,18 @@ class ResourceTreeViewToolbar : GetSizer()->Add(_showAll, 0, wxRIGHT, 0); GetSizer()->Add(_showFavourites, 0, wxLEFT, 6); + // Filter text entry box + auto* filterBox = new wxTextCtrl(this, wxID_ANY); + filterBox->SetMinSize(wxSize(60, -1)); + filterBox->Bind(wxEVT_TEXT, [this](wxCommandEvent& ev) + { + if (_treeView != nullptr) + { + _treeView->SetFilterText(ev.GetString().ToStdString()); + } + }); + GetSizer()->Add(filterBox, 1, wxLEFT, 6); + AssociateToTreeView(treeView); }