From 10e77252469b6406cd76f758c253bda5d37a7afa Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 25 Sep 2017 14:44:24 +0200 Subject: [PATCH 1/2] Add wxDataViewModel::DoCompareValues() useful virtual hook This new method, called from the default Compare() implementation, is simpler to override in the derived classes than Compare() itself. --- include/wx/dataview.h | 10 ++++++++++ interface/wx/dataview.h | 33 +++++++++++++++++++++++++++++++-- src/common/datavcmn.cpp | 6 ++++++ 3 files changed, 47 insertions(+), 2 deletions(-) diff --git a/include/wx/dataview.h b/include/wx/dataview.h index 4b78de8a43..687312cbfd 100644 --- a/include/wx/dataview.h +++ b/include/wx/dataview.h @@ -276,6 +276,16 @@ protected: // the user should not delete this class directly: he should use DecRef() instead! virtual ~wxDataViewModel() { } + // Helper function used by the default Compare() implementation to compare + // values of types it is not aware about. Can be overridden in the derived + // classes that use columns of custom types. + virtual int DoCompareValues(const wxVariant& WXUNUSED(value1), + const wxVariant& WXUNUSED(value2)) const + { + return 0; + } + + wxDataViewModelNotifiers m_notifiers; }; diff --git a/interface/wx/dataview.h b/interface/wx/dataview.h index 90805b3853..30e6c2d41d 100644 --- a/interface/wx/dataview.h +++ b/interface/wx/dataview.h @@ -138,7 +138,9 @@ public: The compare function to be used by the control. The default compare function sorts most data types implemented by wxVariant (i.e. bool, int, long, double, string) as well as datetime and wxDataViewIconText. - Override this for a different sorting behaviour. + Override this method to implement a different sorting behaviour or + override just DoCompareValues() to extend it to support other wxVariant + types. The function should return negative, null or positive for an ascending comparison, depending on whether the first item is less than, equal to @@ -171,7 +173,8 @@ public: return (ascending == (id1 > id2)) ? : 1 : -1; @endcode - @see HasDefaultCompare(). + + @see HasDefaultCompare(), DoCompareValues() */ virtual int Compare(const wxDataViewItem& item1, const wxDataViewItem& item2, @@ -377,6 +380,32 @@ protected: Destructor. This should not be called directly. Use DecRef() instead. */ virtual ~wxDataViewModel(); + + /** + Virtual method that can be overridden to define comparison for values + of non-standard types. + + This function is called from the default Compare() implementation to + compare values of types it is not aware about (i.e. not any of the + standard ones). As Compare() itself, this method should return a + negative value if @a value1 is less than (i.e. should appear above) @a + value2 and a positive value if @a value2 is less than @a value1. + + Unlike Compare(), if the values are equal, this method should just + return 0 to indicate it and let Compare() order them by their items + values. It also doesn't have to care about the sort order direction, + making it simpler to override than Compare() itself. + + The default implementation just returns 0, so the derived class version + can simply forward to it if it doesn't know how to compare the given + values. + + @see Compare() + + @since 3.1.1 + */ + virtual int DoCompareValues(const wxVariant& value1, + const wxVariant& value2) const; }; diff --git a/src/common/datavcmn.cpp b/src/common/datavcmn.cpp index 011c02245f..fff1ca3fcd 100644 --- a/src/common/datavcmn.cpp +++ b/src/common/datavcmn.cpp @@ -378,6 +378,12 @@ int wxDataViewModel::Compare( const wxDataViewItem &item1, const wxDataViewItem if (res != 0) return res; } + else + { + int res = DoCompareValues(value1, value2); + if (res != 0) + return res; + } // items must be different From 812224488f853d318d3c18a974e053373a729ad8 Mon Sep 17 00:00:00 2001 From: Fabian Cenedese Date: Mon, 25 Sep 2017 14:45:51 +0200 Subject: [PATCH 2/2] Fix wxTreeListCtrl items comparison when using checkboxes Override DoCompareValues() to handle values of "wxDataViewCheckIconText" type which is not handled by wxDataViewModel::Compare() itself. This ensures that the items with checkboxes are sorted by their (text) contents instead of by the order of their addresses in memory as was done for them, as for any unknown values type, previously. --- src/generic/treelist.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/generic/treelist.cpp b/src/generic/treelist.cpp index 665a979190..c05cb346b4 100644 --- a/src/generic/treelist.cpp +++ b/src/generic/treelist.cpp @@ -387,6 +387,10 @@ public: unsigned col, bool ascending) const wxOVERRIDE; +protected: + virtual int DoCompareValues(const wxVariant& value1, + const wxVariant& value2) const wxOVERRIDE; + private: // The control we're associated with. wxTreeListCtrl* const m_treelist; @@ -1007,6 +1011,22 @@ wxTreeListModel::Compare(const wxDataViewItem& item1, return result; } +int wxTreeListModel::DoCompareValues(const wxVariant& value1, + const wxVariant& value2) const +{ + if ( value1.GetType() == wxS("wxDataViewCheckIconText") ) + { + wxDataViewCheckIconText iconText1, iconText2; + + iconText1 << value1; + iconText2 << value2; + + return iconText1.GetText().Cmp(iconText2.GetText()); + } + + return wxDataViewModel::DoCompareValues(value1, value2); +} + // ============================================================================ // wxTreeListCtrl implementation // ============================================================================