]> git.saurik.com Git - wxWidgets.git/commitdiff
Added wxPropertyGrid::SetSortFunction(); moved Sort() and SortChildren() to wxPropert...
authorJaakko Salli <jaakko.salli@dnainternet.net>
Wed, 7 Jan 2009 18:53:09 +0000 (18:53 +0000)
committerJaakko Salli <jaakko.salli@dnainternet.net>
Wed, 7 Jan 2009 18:53:09 +0000 (18:53 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@57894 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/propgrid/propgrid.h
include/wx/propgrid/propgriddefs.h
include/wx/propgrid/propgridiface.h
include/wx/propgrid/propgridpagestate.h
interface/wx/propgrid/propgrid.h
interface/wx/propgrid/propgridiface.h
samples/propgrid/tests.cpp
src/propgrid/propgrid.cpp
src/propgrid/propgridiface.cpp
src/propgrid/propgridpagestate.cpp

index 4456641a4ad35b0ad7b714825c1b085f13aeed45..2146da9de111251ffe7ada4196139f0ca9778477 100644 (file)
@@ -1008,6 +1008,45 @@ public:
         m_iFlags |= wxPG_FL_SPLITTER_PRE_SET;
     }
 
+    /**
+        Sets the property sorting function.
+
+        @param sortFunction
+            The sorting function to be used. It should return a value greater
+            than 0 if position of p1 is after p2. So, for instance, when
+            comparing property names, you can use following implementation:
+
+            @code
+                int MyPropertySortFunction(wxPropertyGrid* propGrid,
+                                           wxPGProperty* p1,
+                                           wxPGProperty* p2)
+                {
+                    return p1->GetBaseName().compare( p2->GetBaseName() );
+                }
+            @endcode
+
+        @remarks
+            Default property sort function sorts properties by their labels
+            (case-insensitively).
+
+        @see GetSortFunction, wxPropertyGridInterface::Sort,
+             wxPropertyGridInterface::SortChildren
+    */
+    void SetSortFunction( wxPGSortCallback sortFunction )
+    {
+        m_sortFunction = sortFunction;
+    }
+
+    /**
+        Returns the property sort function (default is @NULL).
+
+        @see SetSortFunction
+    */
+    wxPGSortCallback GetSortFunction() const
+    {
+        return m_sortFunction;
+    }
+
     /** Set virtual width for this particular page. Width -1 indicates that the
         virtual width should be disabled. */
     void SetVirtualWidth( int width );
@@ -1041,13 +1080,6 @@ public:
         DoShowPropertyError(p, msg);
     }
 
-    /** Sorts all items at all levels (except sub-properties). */
-    void Sort();
-
-    /** Sorts children of a category.
-    */
-    void SortChildren( wxPGPropArg id );
-
     /////////////////////////////////////////////////////////////////
     //
     // Following methods do not need to be (currently) documented
@@ -1577,6 +1609,9 @@ protected:
     // Top level parent
     wxWindow*           m_tlp;
 
+    // Sort function
+    wxPGSortCallback    m_sortFunction;
+
     // y coordinate of property that mouse hovering
     int                 m_propHoverY;
     // Which column's editor is selected (usually 1)?
index 02e4fc0f2d26ffd1c4caec9c35f316e39b017cf8..996823d03b4829ae67c39e59e2d9d05d5082bc7a 100644 (file)
@@ -301,6 +301,29 @@ class wxPGValidationInfo;
 #define wxPG_DEFAULT_IMAGE_SIZE             wxSize(-1, -1)
 
 
+/** This callback function is used for sorting properties.
+
+    Call wxPropertyGrid::SetSortFunction() to set it.
+
+    Sort function should return a value greater than 0 if position of p1 is
+    after p2. So, for instance, when comparing property names, you can use
+    following implementation:
+
+        @code
+            int MyPropertySortFunction(wxPropertyGrid* propGrid,
+                                       wxPGProperty* p1,
+                                       wxPGProperty* p2)
+            {
+                return p1->GetBaseName().compare( p2->GetBaseName() );
+            }
+        @endcode
+*/
+typedef int (*wxPGSortCallback)(wxPropertyGrid* propGrid,
+                                wxPGProperty* p1,
+                                wxPGProperty* p2);
+
+
+
 typedef wxString wxPGCachedString;
 
 /** @}
index 8d8c010f4106da64a5b9f121d47ae4504808b079..8c8b39d47d8b02ae2f7564148010bbe5e788db0d 100644 (file)
@@ -1226,6 +1226,30 @@ public:
     */
     void SetValidationFailureBehavior( int vfbFlags );
 
+    /**
+        Sorts all properties.
+
+        @see SortChildren, wxPropertyGrid::SetSortFunction
+    */
+    void Sort();
+
+    /**
+        Sorts children of a property.
+
+        @param id
+            Name or pointer to a property.
+
+        @param recursively
+            If @true, then children are sorted recursively.
+
+        @see Sort, wxPropertyGrid::SetSortFunction
+    */
+    void SortChildren( wxPGPropArg id, bool recursively = false )
+    {
+        wxPG_PROP_ARG_CALL_PROLOG()
+        m_pState->DoSortChildren(p, recursively);
+    }
+
 #ifdef SWIG
     %pythoncode {
         def MapType(class_,factory):
index 65c45f2d29e732c19bf0e9609a7f36f5f1af1aa3..4c9172de829b8d184d7b9743c393a89b46cfbf65 100644 (file)
@@ -613,8 +613,8 @@ public:
     /** Set virtual width for this particular page. */
     void SetVirtualWidth( int width );
 
-    void SortChildren( wxPGProperty* p );
-    void Sort();
+    void DoSortChildren( wxPGProperty* p, bool recursively = false );
+    void DoSort();
 
     void SetSelection( wxPGProperty* p ) { m_selected = p; }
 
index aa3379626676f76db5d113a33e47189fdd912f12..16c785c43d6780767deacf6a21e6876dccc04891 100644 (file)
@@ -271,6 +271,27 @@ enum wxPG_KEYBOARD_ACTIONS
 /** @}
 */
 
+/** This callback function is used for sorting properties.
+
+    Call wxPropertyGrid::SetSortFunction() to set it.
+
+    Sort function should return a value greater than 0 if position of p1 is
+    after p2. So, for instance, when comparing property names, you can use
+    following implementation:
+
+        @code
+            int MyPropertySortFunction(wxPropertyGrid* propGrid,
+                                       wxPGProperty* p1,
+                                       wxPGProperty* p2)
+            {
+                return p1->GetBaseName().compare( p2->GetBaseName() );
+            }
+        @endcode
+*/
+typedef int (*wxPGSortCallback)(wxPropertyGrid* propGrid,
+                                wxPGProperty* p1,
+                                wxPGProperty* p2);
+
 // -----------------------------------------------------------------------
 
 /**
@@ -621,6 +642,13 @@ public:
     */
     wxColour GetSelectionForegroundColour() const;
 
+    /**
+        Returns the property sort function (default is @NULL).
+
+        @see SetSortFunction
+    */
+    wxPGSortCallback GetSortFunction() const;
+
     /**
         Returns current splitter x position.
     */
@@ -772,6 +800,33 @@ public:
     */
     void SetSelectionTextColour(const wxColour& col);
 
+
+    /**
+        Sets the property sorting function.
+
+        @param sortFunction
+            The sorting function to be used. It should return a value greater
+            than 0 if position of p1 is after p2. So, for instance, when
+            comparing property names, you can use following implementation:
+
+            @code
+                int MyPropertySortFunction(wxPropertyGrid* propGrid,
+                                           wxPGProperty* p1,
+                                           wxPGProperty* p2)
+                {
+                    return p1->GetBaseName().compare( p2->GetBaseName() );
+                }
+            @endcode
+
+        @remarks
+            Default property sort function sorts properties by their labels
+            (case-insensitively).
+
+        @see GetSortFunction, wxPropertyGridInterface::Sort,
+             wxPropertyGridInterface::SortChildren
+    */
+    void SetSortFunction( wxPGSortCallback sortFunction );
+
     /**
         Sets x coordinate of the splitter.
 
@@ -801,24 +856,6 @@ public:
         Shows an brief error message that is related to a property.
     */
     void ShowPropertyError( wxPGPropArg id, const wxString& msg );
-
-    /**
-        Sorts all items at all levels (except private children).
-
-        @remarks This functions deselects selected property, if any. Validation
-                failure option wxPG_VFB_STAY_IN_PROPERTY is not respected, ie.
-                selection is cleared even if editor had invalid value.
-    */
-    void Sort();
-
-    /**
-        Sorts children of a property.
-
-        @remarks This functions deselects selected property, if any. Validation
-                failure option wxPG_VFB_STAY_IN_PROPERTY is not respected, ie.
-                selection is cleared even if editor had invalid value.
-    */
-    void SortChildren( wxPGPropArg id );
 };
 
 
index 021954c63d600028c6cad3eb87bed4184bb0398a..97725fad6cad1fa513b9cbac6b6294d5e08f4a96 100644 (file)
@@ -901,6 +901,26 @@ public:
     */
     void SetValidationFailureBehavior( int vfbFlags );
 
+    /**
+        Sorts all properties.
+
+        @see SortChildren, wxPropertyGrid::SetSortFunction
+    */
+    void Sort();
+
+    /**
+        Sorts children of a property.
+
+        @param id
+            Name or pointer to a property.
+
+        @param recursively
+            If @true, then children are sorted recursively.
+
+        @see Sort, wxPropertyGrid::SetSortFunction
+    */
+    void SortChildren( wxPGPropArg id, bool recursively = false );
+
     /**
         Returns editor pointer of editor with given name;
     */
index 1c066ca0d9431561d16ba99af2e1a643fe02204c..c4c7de94b3ef8599bd74b4319a4366bbad629da3 100644 (file)
@@ -306,6 +306,15 @@ wxArrayPGProperty GetPropertiesInRandomOrder( wxPropertyGridInterface* props, in
     return arr;
 }
 
+// Callback for testing property sorting
+int MyPropertySortFunction(wxPropertyGrid* WXUNUSED(propGrid),
+                           wxPGProperty* p1,
+                           wxPGProperty* p2)
+{
+    // Reverse alphabetical order
+    return p2->GetLabel().CmpNoCase( p1->GetBaseName() );
+}
+
 bool FormMain::RunTests( bool fullTest, bool interactive )
 {
     wxString t;
@@ -935,6 +944,51 @@ bool FormMain::RunTests( bool fullTest, bool interactive )
         pgman->Update();
     }
 
+    {
+        RT_START_TEST(SortFunction)
+
+        wxPGProperty* p;
+
+        // Make sure indexes are as supposed
+
+        p = pgman->GetProperty(wxT("User Name"));
+        if ( p->GetIndexInParent() != 3 )
+            RT_FAILURE();
+
+        p = pgman->GetProperty(wxT("User Id"));
+        if ( p->GetIndexInParent() != 2 )
+            RT_FAILURE();
+
+        p = pgman->GetProperty(wxT("User Home"));
+        if ( p->GetIndexInParent() != 1 )
+            RT_FAILURE();
+
+        p = pgman->GetProperty(wxT("Operating System"));
+        if ( p->GetIndexInParent() != 0 )
+            RT_FAILURE();
+
+        pgman->GetGrid()->SetSortFunction(MyPropertySortFunction);
+
+        pgman->GetGrid()->SortChildren(wxT("Environment"));
+
+        // Make sure indexes have been reversed
+        p = pgman->GetProperty(wxT("User Name"));
+        if ( p->GetIndexInParent() != 0 )
+            RT_FAILURE();
+
+        p = pgman->GetProperty(wxT("User Id"));
+        if ( p->GetIndexInParent() != 1 )
+            RT_FAILURE();
+
+        p = pgman->GetProperty(wxT("User Home"));
+        if ( p->GetIndexInParent() != 2 )
+            RT_FAILURE();
+
+        p = pgman->GetProperty(wxT("Operating System"));
+        if ( p->GetIndexInParent() != 3 )
+            RT_FAILURE();
+    }
+
     {
         RT_START_TEST(SetPropertyBackgroundColour)
         wxCommandEvent evt;
index a424df5033ef38b2aaf728d92a2f5161e0b82b0e..4eaae9aedda2933c5dd66d51ca274ed5c2452f0f 100644 (file)
@@ -462,6 +462,7 @@ void wxPropertyGrid::Init1()
     m_eventObject = this;
     m_curFocused = (wxWindow*) NULL;
     m_tlwHandler = NULL;
+    m_sortFunction = NULL;
     m_inDoPropertyChanged = 0;
     m_inCommitChangesFromEditor = 0;
     m_inDoSelectProperty = 0;
@@ -2292,24 +2293,6 @@ void wxPropertyGrid::SwitchState( wxPropertyGridPageState* pNewState )
 
 // -----------------------------------------------------------------------
 
-void wxPropertyGrid::SortChildren( wxPGPropArg id )
-{
-    wxPG_PROP_ARG_CALL_PROLOG()
-
-    m_pState->SortChildren( p );
-}
-
-// -----------------------------------------------------------------------
-
-void wxPropertyGrid::Sort()
-{
-    ClearSelection(false);  // This must be before state clear
-
-    m_pState->Sort();
-}
-
-// -----------------------------------------------------------------------
-
 // Call to SetSplitterPosition will always disable splitter auto-centering
 // if parent window is shown.
 void wxPropertyGrid::DoSetSplitterPosition_( int newxpos, bool refresh, int splitterIndex, bool allPages )
index 603fc34ec06676083bbe9c9c3639c2053056d21c..033f06121379de33117279e8a112e258ba655555 100644 (file)
@@ -762,6 +762,25 @@ bool wxPropertyGridInterface::Expand( wxPGPropArg id )
 
 // -----------------------------------------------------------------------
 
+void wxPropertyGridInterface::Sort()
+{
+    wxPropertyGrid* pg = GetPropertyGrid();
+
+    pg->ClearSelection(false);
+
+    unsigned int pageIndex = 0;
+
+    for (;;)
+    {
+        wxPropertyGridPageState* page = GetPageState(pageIndex);
+        if ( !page ) break;
+        page->DoSort();
+        pageIndex++;
+    }
+}
+
+// -----------------------------------------------------------------------
+
 void wxPropertyGridInterface::SetPropertyLabel( wxPGPropArg id, const wxString& newproplabel )
 {
     wxPG_PROP_ARG_CALL_PROLOG()
index 802f05ee772d794fe4990146c41706aecb0035e7..db836d605d9b9e5a8b6366594e10607ab93f11f1 100644 (file)
@@ -602,54 +602,82 @@ bool wxPropertyGridPageState::EnableCategories( bool enable )
 #if wxUSE_STL
 #include <algorithm>
 
-static bool wxPG_SortFunc(wxPGProperty *p1, wxPGProperty *p2)
+static bool wxPG_SortFunc_ByFunction(wxPGProperty *p1, wxPGProperty *p2)
 {
-    return p1->GetLabel() < p2->GetLabel();
+    wxPropertyGrid* pg = p1->GetGrid();
+    wxPGSortCallback sortFunction = pg->GetSortFunction();
+    return sortFunction(pg, p1, p2) < 0;
+}
+
+static bool wxPG_SortFunc_ByLabel(wxPGProperty *p1, wxPGProperty *p2)
+{
+    return p1->GetLabel().CmpNoCase( p2->GetLabel() ) < 0;
 }
 
 #else
 
-static int wxPG_SortFunc(wxPGProperty **p1, wxPGProperty **p2)
+static int wxPG_SortFunc_ByFunction(wxPGProperty **pp1, wxPGProperty **pp2)
+{
+    wxPGProperty *p1 = *pp1;
+    wxPGProperty *p2 = *pp2;
+    wxPropertyGrid* pg = p1->GetGrid();
+    wxPGSortCallback sortFunction = pg->GetSortFunction();
+    return sortFunction(pg, p1, p2);
+}
+
+static int wxPG_SortFunc_ByLabel(wxPGProperty **pp1, wxPGProperty **pp2)
 {
-    wxPGProperty *pp1 = *p1;
-    wxPGProperty *pp2 = *p2;
-    return pp1->GetLabel().compare( pp2->GetLabel() );
+    wxPGProperty *p1 = *pp1;
+    wxPGProperty *p2 = *pp2;
+    return p1->GetLabel().CmpNoCase( p2->GetLabel() );
 }
 
 #endif
 
-void wxPropertyGridPageState::SortChildren( wxPGProperty* p )
+void wxPropertyGridPageState::DoSortChildren( wxPGProperty* p,
+                                              bool recursively )
 {
     if ( !p )
-        p = (wxPGProperty*)m_properties;
+        p = m_properties;
 
     if ( !p->GetChildCount() )
         return;
 
-    wxPGProperty* pwc = (wxPGProperty*)p;
-
     // Can only sort items with children
-    if ( pwc->GetChildCount() < 1 )
+    if ( p->GetChildCount() < 1 )
         return;
 
 #if wxUSE_STL
-    std::sort(pwc->m_children.begin(), pwc->m_children.end(), wxPG_SortFunc);
+    if ( GetGrid()->GetSortFunction() )
+        std::sort(p->m_children.begin(), p->m_children.end(),
+                  wxPG_SortFunc_ByFunction);
+    else
+        std::sort(p->m_children.begin(), p->m_children.end(),
+                  wxPG_SortFunc_ByLabel);
 #else
-    pwc->m_children.Sort( wxPG_SortFunc );
+    if ( GetGrid()->GetSortFunction() )
+        p->m_children.Sort( wxPG_SortFunc_ByFunction );
+    else
+        p->m_children.Sort( wxPG_SortFunc_ByLabel );
 #endif
 
     // Fix indexes
-    pwc->FixIndicesOfChildren();
+    p->FixIndicesOfChildren();
 
+    if ( recursively && !p->HasFlag(wxPG_PROP_AGGREGATE) )
+    {
+        for ( unsigned int i=0; i<p->GetChildCount(); i++ )
+            DoSortChildren(p->Item(i));
+    }
 }
 
 // -----------------------------------------------------------------------
 
-void wxPropertyGridPageState::Sort()
+void wxPropertyGridPageState::DoSort()
 {
-    SortChildren( m_properties );
+    DoSortChildren( m_properties, true );
 
-    // Sort categories as well
+    // Sort categories as well (but we need not do it recursively)
     if ( !IsInNonCatMode() )
     {
         size_t i;
@@ -657,7 +685,7 @@ void wxPropertyGridPageState::Sort()
         {
             wxPGProperty* p = m_properties->Item(i);
             if ( p->IsCategory() )
-                SortChildren( p );
+                DoSortChildren( p );
         }
     }
 }