Added wxPropertyGrid::SetSortFunction(); moved Sort() and SortChildren() to wxPropertyGridInterface; default sorting is now case-insensitive
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@57894 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -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)?
|
||||
|
@@ -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;
|
||||
|
||||
/** @}
|
||||
|
@@ -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):
|
||||
|
@@ -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; }
|
||||
|
||||
|
@@ -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 );
|
||||
};
|
||||
|
||||
|
||||
|
@@ -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;
|
||||
*/
|
||||
|
@@ -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;
|
||||
|
@@ -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 )
|
||||
|
@@ -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()
|
||||
|
@@ -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 *pp1 = *p1;
|
||||
wxPGProperty *pp2 = *p2;
|
||||
return pp1->GetLabel().compare( pp2->GetLabel() );
|
||||
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 *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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user