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 );
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
// 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)?
#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;
/** @}
*/
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):
/** 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; }
/** @}
*/
+/** 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);
+
// -----------------------------------------------------------------------
/**
*/
wxColour GetSelectionForegroundColour() const;
+ /**
+ Returns the property sort function (default is @NULL).
+
+ @see SetSortFunction
+ */
+ wxPGSortCallback GetSortFunction() const;
+
/**
Returns current splitter x position.
*/
*/
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.
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 );
};
*/
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;
*/
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;
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;
m_eventObject = this;
m_curFocused = (wxWindow*) NULL;
m_tlwHandler = NULL;
+ m_sortFunction = NULL;
m_inDoPropertyChanged = 0;
m_inCommitChangesFromEditor = 0;
m_inDoSelectProperty = 0;
// -----------------------------------------------------------------------
-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 )
// -----------------------------------------------------------------------
+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()
#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;
{
wxPGProperty* p = m_properties->Item(i);
if ( p->IsCategory() )
- SortChildren( p );
+ DoSortChildren( p );
}
}
}