From 05dd9e5bfb58f5968f5abc0ba02b71f628e51ed1 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sat, 15 Aug 2020 13:59:47 +0200 Subject: [PATCH] LibGUI: Virtualize SortingProxyModel comparator This patch adds SortingProxyModel::less_than(ModelIndex, ModelIndex) which is now used to implement the sort order. This allows you to subclass SortingProxyModel if you want to tweak how sorting works. Get rid of the awkward case sensitivity logic in SortingProxyModel since that can now be done outside. Turns out nobody was actually using it anyway, but it seems like something we will want to do in the future someday. --- Libraries/LibGUI/SortingProxyModel.cpp | 19 ++++++++++--------- Libraries/LibGUI/SortingProxyModel.h | 8 +++----- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/Libraries/LibGUI/SortingProxyModel.cpp b/Libraries/LibGUI/SortingProxyModel.cpp index 0510478a6e..4a5be37c72 100644 --- a/Libraries/LibGUI/SortingProxyModel.cpp +++ b/Libraries/LibGUI/SortingProxyModel.cpp @@ -109,6 +109,15 @@ void SortingProxyModel::set_key_column_and_sort_order(int column, SortOrder sort resort(); } +bool SortingProxyModel::less_than(const ModelIndex& index1, const ModelIndex& index2) const +{ + auto data1 = data(index1, Role::Sort); + auto data2 = data(index2, Role::Sort); + if (data1.is_string() && data2.is_string()) + return data1.as_string().to_lowercase() < data2.as_string().to_lowercase(); + return data1 < data2; +} + void SortingProxyModel::resort(unsigned flags) { auto old_row_mappings = m_row_mappings; @@ -121,15 +130,7 @@ void SortingProxyModel::resort(unsigned flags) return; } quick_sort(m_row_mappings, [&](auto row1, auto row2) -> bool { - auto data1 = source().data(source().index(row1, m_key_column), m_sort_role); - auto data2 = source().data(source().index(row2, m_key_column), m_sort_role); - if (data1 == data2) - return 0; - bool is_less_than; - if (data1.is_string() && data2.is_string() && !m_sorting_case_sensitive) - is_less_than = data1.as_string().to_lowercase() < data2.as_string().to_lowercase(); - else - is_less_than = data1 < data2; + bool is_less_than = less_than(source().index(row1, m_key_column), source().index(row2, m_key_column)); return m_sort_order == SortOrder::Ascending ? is_less_than : !is_less_than; }); for_each_view([&](AbstractView& view) { diff --git a/Libraries/LibGUI/SortingProxyModel.h b/Libraries/LibGUI/SortingProxyModel.h index e3b83025b2..9e2323a03c 100644 --- a/Libraries/LibGUI/SortingProxyModel.h +++ b/Libraries/LibGUI/SortingProxyModel.h @@ -30,7 +30,7 @@ namespace GUI { -class SortingProxyModel final +class SortingProxyModel : public Model , private ModelClient { public: @@ -49,6 +49,8 @@ public: virtual void set_key_column_and_sort_order(int, SortOrder) override; virtual bool is_column_sortable(int column_index) const override; + virtual bool less_than(const ModelIndex&, const ModelIndex&) const; + ModelIndex map_to_source(const ModelIndex&) const; Role sort_role() const { return m_sort_role; } @@ -65,15 +67,11 @@ private: void resort(unsigned flags = Model::UpdateFlag::DontInvalidateIndexes); - void set_sorting_case_sensitive(bool b) { m_sorting_case_sensitive = b; } - bool is_sorting_case_sensitive() { return m_sorting_case_sensitive; } - NonnullRefPtr m_source; Vector m_row_mappings; int m_key_column { -1 }; SortOrder m_sort_order { SortOrder::Ascending }; Role m_sort_role { Role::Sort }; - bool m_sorting_case_sensitive { false }; }; }