wxVariant list used to translate between list of property child values and composite value string now maps values by names instead of labels. Naturally this means properties can no longer have empty name (this change allows using identical labels under same parent property. Ported from wxpropgrid SVN trunk)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@55602 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Jaakko Salli
2008-09-14 13:14:32 +00:00
parent 1fb72f6116
commit d665918bd2
8 changed files with 45 additions and 42 deletions

View File

@@ -88,10 +88,9 @@ other wxWidgets controls:
Naturally, wxStringProperty is a property class. Only the first function argument (label) Naturally, wxStringProperty is a property class. Only the first function argument (label)
is mandatory. Second one, name, defaults to label and, third, the initial value, to is mandatory. Second one, name, defaults to label and, third, the initial value, to
default value. If constant wxPG_LABEL is used as the name argument, then the label is default value. If constant wxPG_LABEL is used as the name argument, then the label is
automatically used as a name as well (this is more efficient than manually automatically used as a name as well (this is more efficient than manually defining both
defining both as the same). Empty name is also allowed, but in this case the as the same). Use of empty name is discouraged and will sometimes result in run-time error.
property cannot be accessed by its name. Note that all property class constructors have Note that all property class constructors have quite similar constructor argument list.
quite similar constructor argument list.
To demonstrate other common property classes, here's another code snippet: To demonstrate other common property classes, here's another code snippet:

View File

@@ -1872,7 +1872,7 @@ protected:
*/ */
wxString GetColumnText( unsigned int col ) const; wxString GetColumnText( unsigned int col ) const;
/** Returns (direct) child property with given label (or NULL if not found), /** Returns (direct) child property with given name (or NULL if not found),
with hint index. with hint index.
@param hintIndex @param hintIndex
@@ -1881,8 +1881,8 @@ protected:
@remarks @remarks
Does not support scope (ie. Parent.Child notation). Does not support scope (ie. Parent.Child notation).
*/ */
wxPGProperty* GetPropertyByLabelWH( const wxString& label, wxPGProperty* GetPropertyByNameWH( const wxString& name,
unsigned int hintIndex ) const; unsigned int hintIndex ) const;
/** This is used by Insert etc. */ /** This is used by Insert etc. */
void AddChild2( wxPGProperty* prop, void AddChild2( wxPGProperty* prop,

View File

@@ -1615,9 +1615,9 @@ void FormMain::PopulateWithExamples ()
wxPGProperty* topId = pg->Append( new wxStringProperty(wxT("3D Object"), wxPG_LABEL, wxT("<composed>")) ); wxPGProperty* topId = pg->Append( new wxStringProperty(wxT("3D Object"), wxPG_LABEL, wxT("<composed>")) );
pid = pg->AppendIn( topId, new wxStringProperty(wxT("Triangle 1"), wxT("Triangle 1"), wxT("<composed>")) ); pid = pg->AppendIn( topId, new wxStringProperty(wxT("Triangle 1"), wxT("Triangle 1"), wxT("<composed>")) );
pg->AppendIn( pid, new wxVectorProperty( wxT("A"), wxEmptyString ) ); pg->AppendIn( pid, new wxVectorProperty( wxT("A"), wxPG_LABEL ) );
pg->AppendIn( pid, new wxVectorProperty( wxT("B"), wxEmptyString ) ); pg->AppendIn( pid, new wxVectorProperty( wxT("B"), wxPG_LABEL ) );
pg->AppendIn( pid, new wxVectorProperty( wxT("C"), wxEmptyString ) ); pg->AppendIn( pid, new wxVectorProperty( wxT("C"), wxPG_LABEL ) );
pg->AppendIn( topId, new wxTriangleProperty( wxT("Triangle 2"), wxT("Triangle 2") ) ); pg->AppendIn( topId, new wxTriangleProperty( wxT("Triangle 2"), wxT("Triangle 2") ) );
@@ -1626,9 +1626,9 @@ void FormMain::PopulateWithExamples ()
wxT("three wxVectorProperty children, and other two are custom wxTriangleProperties.") ); wxT("three wxVectorProperty children, and other two are custom wxTriangleProperties.") );
pid = pg->AppendIn( topId, new wxStringProperty(wxT("Triangle 3"), wxT("Triangle 3"), wxT("<composed>")) ); pid = pg->AppendIn( topId, new wxStringProperty(wxT("Triangle 3"), wxT("Triangle 3"), wxT("<composed>")) );
pg->AppendIn( pid, new wxVectorProperty( wxT("A"), wxEmptyString ) ); pg->AppendIn( pid, new wxVectorProperty( wxT("A"), wxPG_LABEL ) );
pg->AppendIn( pid, new wxVectorProperty( wxT("B"), wxEmptyString ) ); pg->AppendIn( pid, new wxVectorProperty( wxT("B"), wxPG_LABEL ) );
pg->AppendIn( pid, new wxVectorProperty( wxT("C"), wxEmptyString ) ); pg->AppendIn( pid, new wxVectorProperty( wxT("C"), wxPG_LABEL ) );
pg->AppendIn( topId, new wxTriangleProperty( wxT("Triangle 4"), wxT("Triangle 4") ) ); pg->AppendIn( topId, new wxTriangleProperty( wxT("Triangle 4"), wxT("Triangle 4") ) );

View File

@@ -469,9 +469,9 @@ wxFontProperty::wxFontProperty( const wxString& label, const wxString& name,
wxFont& font = wxFontFromVariant(m_value); wxFont& font = wxFontFromVariant(m_value);
AddChild( new wxIntProperty( _("Point Size"),emptyString,(long)font.GetPointSize() ) ); AddChild( new wxIntProperty( _("Point Size"), wxS("Point Size"),(long)font.GetPointSize() ) );
AddChild( new wxEnumProperty(_("Family"), emptyString, AddChild( new wxEnumProperty(_("Family"), wxS("PointSize"),
gs_fp_es_family_labels,gs_fp_es_family_values, gs_fp_es_family_labels,gs_fp_es_family_values,
font.GetFamily()) ); font.GetFamily()) );
@@ -481,20 +481,20 @@ wxFontProperty::wxFontProperty( const wxString& label, const wxString& name,
wxPGGlobalVars->m_fontFamilyChoices->Index(faceName) == wxNOT_FOUND ) wxPGGlobalVars->m_fontFamilyChoices->Index(faceName) == wxNOT_FOUND )
wxPGGlobalVars->m_fontFamilyChoices->AddAsSorted(faceName); wxPGGlobalVars->m_fontFamilyChoices->AddAsSorted(faceName);
wxPGProperty* p = new wxEnumProperty(_("Face Name"),emptyString, wxPGProperty* p = new wxEnumProperty(_("Face Name"), wxS("Face Name"),
*wxPGGlobalVars->m_fontFamilyChoices); *wxPGGlobalVars->m_fontFamilyChoices);
p->SetValueFromString(faceName, wxPG_FULL_VALUE); p->SetValueFromString(faceName, wxPG_FULL_VALUE);
AddChild( p ); AddChild( p );
AddChild( new wxEnumProperty(_("Style"),emptyString, AddChild( new wxEnumProperty(_("Style"), wxS("Style"),
gs_fp_es_style_labels,gs_fp_es_style_values,font.GetStyle()) ); gs_fp_es_style_labels,gs_fp_es_style_values,font.GetStyle()) );
AddChild( new wxEnumProperty(_("Weight"),emptyString, AddChild( new wxEnumProperty(_("Weight"), wxS("Weight"),
gs_fp_es_weight_labels,gs_fp_es_weight_values,font.GetWeight()) ); gs_fp_es_weight_labels,gs_fp_es_weight_values,font.GetWeight()) );
AddChild( new wxBoolProperty(_("Underlined"),emptyString, AddChild( new wxBoolProperty(_("Underlined"), wxS("Underlined"),
font.GetUnderlined()) ); font.GetUnderlined()) );
} }

View File

@@ -705,9 +705,7 @@ bool wxPGProperty::StringToValue( wxVariant& variant, const wxString& text, int
wxVariant variant(child->GetValueRef()); wxVariant variant(child->GetValueRef());
if ( child->StringToValue(variant, token, propagatedFlags|wxPG_COMPOSITE_FRAGMENT) ) if ( child->StringToValue(variant, token, propagatedFlags|wxPG_COMPOSITE_FRAGMENT) )
{ {
// Use label instead of name, as name can be empty string, but variant.SetName(child->GetBaseName());
// label in practice never is.
variant.SetName(child->GetLabel());
// Clear unspecified flag only if OnSetValue() didn't // Clear unspecified flag only if OnSetValue() didn't
// affect it. // affect it.
@@ -726,7 +724,7 @@ bool wxPGProperty::StringToValue( wxVariant& variant, const wxString& text, int
{ {
// Empty, becomes unspecified // Empty, becomes unspecified
wxVariant variant2; wxVariant variant2;
variant2.SetName(child->GetLabel()); variant2.SetName(child->GetBaseName());
list.Append(variant2); list.Append(variant2);
changed = true; changed = true;
} }
@@ -779,9 +777,7 @@ bool wxPGProperty::StringToValue( wxVariant& variant, const wxString& text, int
wxVariant variant(child->GetValueRef()); wxVariant variant(child->GetValueRef());
if ( child->StringToValue( variant, token, propagatedFlags ) ) if ( child->StringToValue( variant, token, propagatedFlags ) )
{ {
// Use label instead of name, as name can be empty string, but variant.SetName(child->GetBaseName());
// label in practice never is.
variant.SetName(child->GetLabel());
list.Append(variant); list.Append(variant);
changed = true; changed = true;
} }
@@ -789,7 +785,7 @@ bool wxPGProperty::StringToValue( wxVariant& variant, const wxString& text, int
{ {
// Failed, becomes unspecified // Failed, becomes unspecified
wxVariant variant2; wxVariant variant2;
variant2.SetName(child->GetLabel()); variant2.SetName(child->GetBaseName());
list.Append(variant2); list.Append(variant2);
changed = true; changed = true;
} }
@@ -924,14 +920,14 @@ void wxPGProperty::SetValue( wxVariant value, wxVariant* pList, int flags )
//wxLogDebug(wxT(">> %s.SetValue() pList parsing"),GetName().c_str()); //wxLogDebug(wxT(">> %s.SetValue() pList parsing"),GetName().c_str());
// Children in list can be in any order, but we will give hint to // Children in list can be in any order, but we will give hint to
// GetPropertyByLabelWH(). This optimizes for full list parsing. // GetPropertyByNameWH(). This optimizes for full list parsing.
for ( node = list.begin(); node != list.end(); node++ ) for ( node = list.begin(); node != list.end(); node++ )
{ {
wxVariant& childValue = *((wxVariant*)*node); wxVariant& childValue = *((wxVariant*)*node);
wxPGProperty* child = GetPropertyByLabelWH(childValue.GetName(), i); wxPGProperty* child = GetPropertyByNameWH(childValue.GetName(), i);
if ( child ) if ( child )
{ {
//wxLogDebug(wxT("%i: child = %s, childValue.GetType()=%s"),i,child->GetLabel().c_str(),childValue.GetType().c_str()); //wxLogDebug(wxT("%i: child = %s, childValue.GetType()=%s"),i,child->GetBaseName().c_str(),childValue.GetType().c_str());
if ( wxPGIsVariantType(childValue, list) ) if ( wxPGIsVariantType(childValue, list) )
{ {
if ( child->HasFlag(wxPG_PROP_AGGREGATE) && !(flags & wxPG_SETVAL_AGGREGATED) ) if ( child->HasFlag(wxPG_PROP_AGGREGATE) && !(flags & wxPG_SETVAL_AGGREGATED) )
@@ -1639,6 +1635,9 @@ void wxPGProperty::AddChild2( wxPGProperty* prop, int index, bool correct_mode )
// This is used by properties that have fixed sub-properties // This is used by properties that have fixed sub-properties
void wxPGProperty::AddChild( wxPGProperty* prop ) void wxPGProperty::AddChild( wxPGProperty* prop )
{ {
wxASSERT_MSG( prop->GetBaseName().length(),
"Property's children must have unique, non-empty names within their scope" );
prop->m_arrIndex = m_children.GetCount(); prop->m_arrIndex = m_children.GetCount();
m_children.Add( prop ); m_children.Add( prop );
@@ -1675,13 +1674,13 @@ void wxPGProperty::AdaptListToValue( wxVariant& list, wxVariant* value ) const
unsigned int i; unsigned int i;
unsigned int n = 0; unsigned int n = 0;
//wxLogDebug(wxT(">> %s.AdaptListToValue()"),GetLabel().c_str()); //wxLogDebug(wxT(">> %s.AdaptListToValue()"),GetBaseName().c_str());
for ( i=0; i<GetChildCount(); i++ ) for ( i=0; i<GetChildCount(); i++ )
{ {
const wxPGProperty* child = Item(i); const wxPGProperty* child = Item(i);
if ( childValue.GetName() == child->GetLabel() ) if ( childValue.GetName() == child->GetBaseName() )
{ {
//wxLogDebug(wxT(" %s(n=%i), %s"),childValue.GetName().c_str(),n,childValue.GetType().c_str()); //wxLogDebug(wxT(" %s(n=%i), %s"),childValue.GetName().c_str(),n,childValue.GetType().c_str());
@@ -1736,7 +1735,7 @@ wxPGProperty* wxPGProperty::GetPropertyByName( const wxString& name ) const
return p->GetPropertyByName(name.substr(pos+1,name.length()-pos-1)); return p->GetPropertyByName(name.substr(pos+1,name.length()-pos-1));
} }
wxPGProperty* wxPGProperty::GetPropertyByLabelWH( const wxString& label, unsigned int hintIndex ) const wxPGProperty* wxPGProperty::GetPropertyByNameWH( const wxString& name, unsigned int hintIndex ) const
{ {
unsigned int i = hintIndex; unsigned int i = hintIndex;
@@ -1751,7 +1750,7 @@ wxPGProperty* wxPGProperty::GetPropertyByLabelWH( const wxString& label, unsigne
for (;;) for (;;)
{ {
wxPGProperty* p = Item(i); wxPGProperty* p = Item(i);
if ( p->m_label == label ) if ( p->m_name == name )
return p; return p;
if ( i == lastIndex ) if ( i == lastIndex )
@@ -1896,8 +1895,6 @@ bool wxPGProperty::AreAllChildrenSpecified( wxVariant* pendingList ) const
node = pList->begin(); node = pList->begin();
} }
// Children in list can be in any order, but we will give hint to
// GetPropertyByLabelWH(). This optimizes for full list parsing.
for ( i=0; i<GetChildCount(); i++ ) for ( i=0; i<GetChildCount(); i++ )
{ {
wxPGProperty* child = Item(i); wxPGProperty* child = Item(i);
@@ -1906,12 +1903,12 @@ bool wxPGProperty::AreAllChildrenSpecified( wxVariant* pendingList ) const
if ( pendingList ) if ( pendingList )
{ {
const wxString& childLabel = child->GetLabel(); const wxString& childName = child->GetBaseName();
for ( ; node != pList->end(); node++ ) for ( ; node != pList->end(); node++ )
{ {
const wxVariant& item = *((const wxVariant*)*node); const wxVariant& item = *((const wxVariant*)*node);
if ( item.GetName() == childLabel ) if ( item.GetName() == childName )
{ {
listValue = &item; listValue = &item;
value = item; value = item;

View File

@@ -2849,13 +2849,13 @@ bool wxPropertyGrid::PerformValidation( wxPGProperty* p, wxVariant& pendingValue
wxVariant bcpPendingList; wxVariant bcpPendingList;
listValue = pendingValue; listValue = pendingValue;
listValue.SetName(p->GetLabel()); listValue.SetName(p->GetBaseName());
while ( pwc && while ( pwc &&
(pwc->HasFlag(wxPG_PROP_AGGREGATE) || pwc->HasFlag(wxPG_PROP_COMPOSED_VALUE)) ) (pwc->HasFlag(wxPG_PROP_AGGREGATE) || pwc->HasFlag(wxPG_PROP_COMPOSED_VALUE)) )
{ {
wxVariantList tempList; wxVariantList tempList;
wxVariant lv(tempList, pwc->GetLabel()); wxVariant lv(tempList, pwc->GetBaseName());
lv.Append(listValue); lv.Append(listValue);
listValue = lv; listValue = lv;
pPendingValue = &listValue; pPendingValue = &listValue;

View File

@@ -1503,6 +1503,12 @@ int wxPropertyGridPageState::PrepareToAddItem( wxPGProperty* property,
if ( scheduledParent == m_properties ) if ( scheduledParent == m_properties )
scheduledParent = (wxPGProperty*) NULL; scheduledParent = (wxPGProperty*) NULL;
if ( scheduledParent && !scheduledParent->IsCategory() )
{
wxASSERT_MSG( property->GetBaseName().length(),
"Property's children must have unique, non-empty names within their scope" );
}
property->m_parentState = this; property->m_parentState = this;
if ( property->IsCategory() ) if ( property->IsCategory() )

View File

@@ -1241,16 +1241,17 @@ void wxFlagsProperty::Init()
child_val = ( value & (1<<i) )?true:false; child_val = ( value & (1<<i) )?true:false;
wxPGProperty* boolProp; wxPGProperty* boolProp;
wxString label = GetLabel(i);
#if wxUSE_INTL #if wxUSE_INTL
if ( wxPGGlobalVars->m_autoGetTranslation ) if ( wxPGGlobalVars->m_autoGetTranslation )
{ {
boolProp = new wxBoolProperty( ::wxGetTranslation( GetLabel(i) ), wxEmptyString, child_val ); boolProp = new wxBoolProperty( ::wxGetTranslation(label), label, child_val );
} }
else else
#endif #endif
{ {
boolProp = new wxBoolProperty( GetLabel(i), wxEmptyString, child_val ); boolProp = new wxBoolProperty( label, label, child_val );
} }
AddChild(boolProp); AddChild(boolProp);
} }