'wx(U)LongLong << variant' type safety improved (now works even if variant has plain long value). Added << operator and WXVARIANT template specialization for wx(U)LongLong_t as well. Changed WX_PG_DECLARE/IMPLEMENT_VARIANT_DATA so that classname << variant can be customized.
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@55771 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -455,7 +455,8 @@ supports wxArrayString and nothing else.
|
||||
In any case, you will need to take extra care when dealing with
|
||||
raw wxVariant values. For instance, wxIntProperty and wxUIntProperty,
|
||||
store value internally as wx(U)LongLong when number doesn't fit into
|
||||
standard long type.
|
||||
standard long type. Using << operator to get wx(U)LongLong from wxVariant
|
||||
is customized to work quite safely with various types of variant data.
|
||||
|
||||
You may have noticed that properties store, in wxVariant, values of many
|
||||
types which are not natively supported by it. Custom wxVariantDatas
|
||||
|
@@ -513,7 +513,9 @@ extern expdecl const char* classname##_VariantType;
|
||||
#define WX_PG_IMPLEMENT_VARIANT_DATA(classname) \
|
||||
WX_PG_IMPLEMENT_VARIANT_DATA_EXPORTED(classname, wxEMPTY_PARAMETER_VALUE)
|
||||
|
||||
#define WX_PG_IMPLEMENT_VARIANT_DATA_EXPORTED_NO_EQ(classname,expdecl) \
|
||||
// Add getter (ie. classname << variant) separately to allow
|
||||
// custom implementations.
|
||||
#define WX_PG_IMPLEMENT_VARIANT_DATA_EXPORTED_NO_EQ_NO_GETTER(classname,expdecl) \
|
||||
const char* classname##_VariantType = #classname; \
|
||||
class classname##VariantData: public wxVariantData \
|
||||
{ \
|
||||
@@ -540,15 +542,6 @@ wxString classname##VariantData::GetType() const\
|
||||
return wxS(#classname);\
|
||||
}\
|
||||
\
|
||||
expdecl classname& operator << ( classname &value, const wxVariant &variant )\
|
||||
{\
|
||||
wxASSERT( variant.GetType() == #classname );\
|
||||
\
|
||||
classname##VariantData *data = (classname##VariantData*) variant.GetData();\
|
||||
value = data->GetValue();\
|
||||
return value;\
|
||||
}\
|
||||
\
|
||||
expdecl wxVariant& operator << ( wxVariant &variant, const classname &value )\
|
||||
{\
|
||||
classname##VariantData *data = new classname##VariantData( value );\
|
||||
@@ -568,11 +561,17 @@ expdecl const classname& classname##RefFromVariant( const wxVariant& variant ) \
|
||||
return data->GetValue();\
|
||||
}
|
||||
|
||||
// implements a wxVariantData-derived class using for the Eq() method the
|
||||
// operator== which must have been provided by "classname"
|
||||
#define WX_PG_IMPLEMENT_VARIANT_DATA_EXPORTED(classname,expdecl) \
|
||||
WX_PG_IMPLEMENT_VARIANT_DATA_EXPORTED_NO_EQ(classname,wxEMPTY_PARAMETER_VALUE expdecl) \
|
||||
\
|
||||
#define WX_PG_IMPLEMENT_VARIANT_DATA_GETTER(classname, expdecl) \
|
||||
expdecl classname& operator << ( classname &value, const wxVariant &variant )\
|
||||
{\
|
||||
wxASSERT( variant.GetType() == #classname );\
|
||||
\
|
||||
classname##VariantData *data = (classname##VariantData*) variant.GetData();\
|
||||
value = data->GetValue();\
|
||||
return value;\
|
||||
}
|
||||
|
||||
#define WX_PG_IMPLEMENT_VARIANT_DATA_EQ(classname, expdecl) \
|
||||
bool classname##VariantData::Eq(wxVariantData& data) const \
|
||||
{\
|
||||
wxASSERT( GetType() == data.GetType() );\
|
||||
@@ -582,12 +581,20 @@ bool classname##VariantData::Eq(wxVariantData& data) const \
|
||||
return otherData.m_value == m_value;\
|
||||
}
|
||||
|
||||
// implements a wxVariantData-derived class using for the Eq() method the
|
||||
// operator== which must have been provided by "classname"
|
||||
#define WX_PG_IMPLEMENT_VARIANT_DATA_EXPORTED(classname,expdecl) \
|
||||
WX_PG_IMPLEMENT_VARIANT_DATA_EXPORTED_NO_EQ_NO_GETTER(classname,wxEMPTY_PARAMETER_VALUE expdecl) \
|
||||
WX_PG_IMPLEMENT_VARIANT_DATA_GETTER(classname,wxEMPTY_PARAMETER_VALUE expdecl) \
|
||||
WX_PG_IMPLEMENT_VARIANT_DATA_EQ(classname,wxEMPTY_PARAMETER_VALUE expdecl)
|
||||
|
||||
#define WX_PG_IMPLEMENT_VARIANT_DATA(classname) \
|
||||
WX_PG_IMPLEMENT_VARIANT_DATA_EXPORTED(classname, wxEMPTY_PARAMETER_VALUE)
|
||||
|
||||
// with Eq() implementation that always returns false
|
||||
#define WX_PG_IMPLEMENT_VARIANT_DATA_EXPORTED_DUMMY_EQ(classname,expdecl) \
|
||||
WX_PG_IMPLEMENT_VARIANT_DATA_EXPORTED_NO_EQ(classname,wxEMPTY_PARAMETER_VALUE expdecl) \
|
||||
WX_PG_IMPLEMENT_VARIANT_DATA_EXPORTED_NO_EQ_NO_GETTER(classname,wxEMPTY_PARAMETER_VALUE expdecl) \
|
||||
WX_PG_IMPLEMENT_VARIANT_DATA_GETTER(classname,wxEMPTY_PARAMETER_VALUE expdecl) \
|
||||
\
|
||||
bool classname##VariantData::Eq(wxVariantData& WXUNUSED(data)) const \
|
||||
{\
|
||||
@@ -617,6 +624,27 @@ template<> inline wxVariant WXVARIANT( const wxColour& value )
|
||||
return variant;
|
||||
}
|
||||
|
||||
#if wxUSE_LONGLONG_NATIVE
|
||||
|
||||
template<> inline wxVariant WXVARIANT( const wxLongLong_t& value )
|
||||
{
|
||||
wxVariant variant;
|
||||
variant << wxLongLong(value);
|
||||
return variant;
|
||||
}
|
||||
|
||||
template<> inline wxVariant WXVARIANT( const wxULongLong_t& value )
|
||||
{
|
||||
wxVariant variant;
|
||||
variant << wxULongLong(value);
|
||||
return variant;
|
||||
}
|
||||
|
||||
WXDLLIMPEXP_PROPGRID wxLongLong_t& operator << ( wxLongLong_t &value, const wxVariant &variant );
|
||||
WXDLLIMPEXP_PROPGRID wxULongLong_t& operator << ( wxULongLong_t &value, const wxVariant &variant );
|
||||
|
||||
#endif // wxUSE_LONGLONG_NATIVE
|
||||
|
||||
// Define constants for common wxVariant type strings
|
||||
|
||||
#define wxPG_VARIANT_TYPE_STRING wxPGGlobalVars->m_strstring
|
||||
|
@@ -197,6 +197,15 @@
|
||||
|
||||
Like wxStringProperty, but converts text to a signed long integer.
|
||||
wxIntProperty seamlessly supports 64-bit integers (ie. wxLongLong).
|
||||
To safely convert variant to integer, use code like this:
|
||||
|
||||
@code
|
||||
wxLongLong ll;
|
||||
ll << property->GetValue();
|
||||
|
||||
// or
|
||||
wxLongLong ll = propertyGrid->GetPropertyValueAsLong(property);
|
||||
@endcode
|
||||
|
||||
@subsection wxUIntProperty
|
||||
|
||||
@@ -205,7 +214,8 @@
|
||||
To set the globally used base, manipulate wxPG_UINT_BASE int
|
||||
attribute. Regardless of current prefix, understands (hex) values starting
|
||||
with both "0x" and "$".
|
||||
wxUIntProperty seamlessly supports 64-bit unsigned integers (ie. wxULongLong).
|
||||
Like wxIntProperty, wxUIntProperty seamlessly supports 64-bit unsigned
|
||||
integers (ie. wxULongLong). Same wxVariant safety rules apply.
|
||||
|
||||
@subsection wxFloatProperty
|
||||
|
||||
|
@@ -755,7 +755,6 @@ bool FormMain::RunTests( bool fullTest, bool interactive )
|
||||
pgman->SetPropertyValue(wxT("FloatProperty"),1024.0000000001);
|
||||
pgman->SetPropertyValue(wxT("BoolProperty"),FALSE);
|
||||
pgman->SetPropertyValue(wxT("EnumProperty"),120);
|
||||
pgman->SetPropertyValue(wxT("Custom FlagsProperty"),FLAG_TEST_SET1);
|
||||
pgman->SetPropertyValue(wxT("ArrayStringProperty"),test_arrstr_1);
|
||||
wxColour emptyCol;
|
||||
pgman->SetPropertyValue(wxT("ColourProperty"),emptyCol);
|
||||
@@ -782,8 +781,6 @@ bool FormMain::RunTests( bool fullTest, bool interactive )
|
||||
RT_FAILURE();
|
||||
if ( pg->GetPropertyValueAsArrayString(wxT("ArrayStringProperty")) != test_arrstr_1 )
|
||||
RT_FAILURE();
|
||||
if ( pg->GetPropertyValueAsLong(wxT("Custom FlagsProperty")) != FLAG_TEST_SET1 )
|
||||
RT_FAILURE();
|
||||
wxColour col;
|
||||
col << pgman->GetPropertyValue(wxT("ColourProperty"));
|
||||
if ( col != *wxBLACK )
|
||||
@@ -809,7 +806,6 @@ bool FormMain::RunTests( bool fullTest, bool interactive )
|
||||
pg->SetPropertyValue(wxT("BoolProperty"),TRUE);
|
||||
pg->SetPropertyValue(wxT("EnumProperty"),80);
|
||||
pg->SetPropertyValue(wxT("ArrayStringProperty"),test_arrstr_2);
|
||||
pg->SetPropertyValue(wxT("Custom FlagsProperty"),FLAG_TEST_SET2);
|
||||
pg->SetPropertyValue(wxT("ColourProperty"),(wxObject*)wxWHITE);
|
||||
pg->SetPropertyValue(wxT("Size"),wxSize(300,300));
|
||||
pg->SetPropertyValue(wxT("Position"),wxPoint(300,300));
|
||||
@@ -834,8 +830,6 @@ bool FormMain::RunTests( bool fullTest, bool interactive )
|
||||
RT_FAILURE();
|
||||
if ( pgman->GetPropertyValueAsArrayString(wxT("ArrayStringProperty")) != test_arrstr_2 )
|
||||
RT_FAILURE();
|
||||
if ( pgman->GetPropertyValueAsLong(wxT("Custom FlagsProperty")) != FLAG_TEST_SET2 )
|
||||
RT_FAILURE();
|
||||
col << pgman->GetPropertyValue(wxT("ColourProperty"));
|
||||
if ( col != *wxWHITE )
|
||||
RT_FAILURE();
|
||||
@@ -854,6 +848,58 @@ bool FormMain::RunTests( bool fullTest, bool interactive )
|
||||
if ( pgman->GetPropertyValueAsLongLong(wxT("IntProperty")) != wxLL(-80000000000) )
|
||||
RT_FAILURE();
|
||||
|
||||
//
|
||||
// Flexible wx(U)LongLong << operator safety conformance tests
|
||||
wxPGProperty* prop;
|
||||
wxLongLong ll;
|
||||
wxULongLong ull;
|
||||
|
||||
prop = pgman->GetProperty(wxT("IntProperty"));
|
||||
prop->SetValue(128);
|
||||
ll << prop->GetValue();
|
||||
if ( ll != 128 )
|
||||
RT_FAILURE();
|
||||
|
||||
prop->SetValue(WXVARIANT(wxLL(68719476736)));
|
||||
ll << prop->GetValue();
|
||||
if ( ll.GetValue() != wxLL(68719476736) )
|
||||
RT_FAILURE();
|
||||
|
||||
#if wxUSE_LONGLONG_NATIVE
|
||||
wxLongLong_t ll_t;
|
||||
ll_t << prop->GetValue();
|
||||
if ( ll_t != wxLL(68719476736) )
|
||||
RT_FAILURE();
|
||||
#endif
|
||||
|
||||
prop->SetValue(256);
|
||||
ll << prop->GetValue();
|
||||
if ( ll != 256 )
|
||||
RT_FAILURE();
|
||||
|
||||
prop = pgman->GetProperty(wxT("UIntProperty"));
|
||||
prop->SetValue(128);
|
||||
ull << prop->GetValue();
|
||||
if ( ull != 128 )
|
||||
RT_FAILURE();
|
||||
|
||||
prop->SetValue(WXVARIANT(wxULL(68719476739)));
|
||||
ull << prop->GetValue();
|
||||
if ( ull.GetValue() != wxULL(68719476739) )
|
||||
RT_FAILURE();
|
||||
|
||||
#if wxUSE_LONGLONG_NATIVE
|
||||
wxULongLong_t ull_t;
|
||||
ull_t << prop->GetValue();
|
||||
if ( ull_t != wxLL(68719476739) )
|
||||
RT_FAILURE();
|
||||
#endif
|
||||
|
||||
prop->SetValue(256);
|
||||
ull << prop->GetValue();
|
||||
if ( ull != 256 )
|
||||
RT_FAILURE();
|
||||
|
||||
// Make sure children of composite parent get updated as well
|
||||
// Original string value: "Lamborghini Diablo SV; 5707; [300; 3.9; 8.6] 300000"
|
||||
|
||||
@@ -891,7 +937,6 @@ bool FormMain::RunTests( bool fullTest, bool interactive )
|
||||
pgman->SetPropertyValueUnspecified(wxT("BoolProperty"));
|
||||
pgman->SetPropertyValueUnspecified(wxT("EnumProperty"));
|
||||
pgman->SetPropertyValueUnspecified(wxT("ArrayStringProperty"));
|
||||
pgman->SetPropertyValueUnspecified(wxT("Custom FlagsProperty"));
|
||||
pgman->SetPropertyValueUnspecified(wxT("ColourProperty"));
|
||||
pgman->SetPropertyValueUnspecified(wxT("Size"));
|
||||
pgman->SetPropertyValueUnspecified(wxT("Position"));
|
||||
|
@@ -68,8 +68,50 @@ const wxChar *wxPGTypeName_wxArrayString = wxT("arrstring");
|
||||
WX_PG_IMPLEMENT_VARIANT_DATA_EXPORTED(wxPoint, WXDLLIMPEXP_PROPGRID)
|
||||
WX_PG_IMPLEMENT_VARIANT_DATA_EXPORTED(wxSize, WXDLLIMPEXP_PROPGRID)
|
||||
WX_PG_IMPLEMENT_VARIANT_DATA_EXPORTED_DUMMY_EQ(wxArrayInt, WXDLLIMPEXP_PROPGRID)
|
||||
WX_PG_IMPLEMENT_VARIANT_DATA_EXPORTED(wxLongLong, WXDLLIMPEXP_PROPGRID)
|
||||
WX_PG_IMPLEMENT_VARIANT_DATA_EXPORTED(wxULongLong, WXDLLIMPEXP_PROPGRID)
|
||||
|
||||
// For wxLongLong and wxULongLong have custom classname << variant
|
||||
// implementation for improved flexibility.
|
||||
WX_PG_IMPLEMENT_VARIANT_DATA_EXPORTED_NO_EQ_NO_GETTER(wxLongLong, WXDLLIMPEXP_PROPGRID)
|
||||
WX_PG_IMPLEMENT_VARIANT_DATA_EQ(wxLongLong, WXDLLIMPEXP_PROPGRID)
|
||||
WXDLLIMPEXP_PROPGRID wxLongLong& operator << ( wxLongLong &value, const wxVariant &variant )
|
||||
{
|
||||
wxLongLong_t ll;
|
||||
if ( !wxPGVariantToLongLong(variant, &ll) )
|
||||
{
|
||||
wxFAIL_MSG("Cannot convert to wxLongLong");
|
||||
}
|
||||
value = ll;
|
||||
return value;
|
||||
}
|
||||
WXDLLIMPEXP_PROPGRID wxLongLong_t& operator << ( wxLongLong_t &value, const wxVariant &variant )
|
||||
{
|
||||
if ( !wxPGVariantToLongLong(variant, &value) )
|
||||
{
|
||||
wxFAIL_MSG("Cannot convert to wxLongLong");
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
WX_PG_IMPLEMENT_VARIANT_DATA_EXPORTED_NO_EQ_NO_GETTER(wxULongLong, WXDLLIMPEXP_PROPGRID)
|
||||
WX_PG_IMPLEMENT_VARIANT_DATA_EQ(wxULongLong, WXDLLIMPEXP_PROPGRID)
|
||||
WXDLLIMPEXP_PROPGRID wxULongLong& operator << ( wxULongLong &value, const wxVariant &variant )
|
||||
{
|
||||
wxULongLong_t ull;
|
||||
if ( !wxPGVariantToULongLong(variant, &ull) )
|
||||
{
|
||||
wxFAIL_MSG("Cannot convert to wxULongLong");
|
||||
}
|
||||
value = ull;
|
||||
return value;
|
||||
}
|
||||
WXDLLIMPEXP_PROPGRID wxULongLong_t& operator << ( wxULongLong_t &value, const wxVariant &variant )
|
||||
{
|
||||
if ( !wxPGVariantToULongLong(variant, &value) )
|
||||
{
|
||||
wxFAIL_MSG("Cannot convert to wxULongLong");
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
IMPLEMENT_VARIANT_OBJECT_EXPORTED(wxFont, WXDLLIMPEXP_PROPGRID)
|
||||
|
||||
@@ -124,9 +166,8 @@ bool wxPGVariantToLongLong( const wxVariant& variant, wxLongLong_t* pResult )
|
||||
|
||||
if ( variantType == wxLongLong_VariantType )
|
||||
{
|
||||
wxLongLong ll;
|
||||
ll << variant;
|
||||
*pResult = ll.GetValue();
|
||||
// NOTE: << operator uses this functions, so we can't use it here
|
||||
*pResult = wxLongLongRefFromVariant(variant).GetValue();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -150,9 +191,8 @@ bool wxPGVariantToULongLong( const wxVariant& variant, wxULongLong_t* pResult )
|
||||
|
||||
if ( variantType == wxULongLong_VariantType )
|
||||
{
|
||||
wxULongLong ull;
|
||||
ull << variant;
|
||||
*pResult = ull.GetValue();
|
||||
// NOTE: << operator uses this functions, so we can't use it here
|
||||
*pResult = wxULongLongRefFromVariant(variant).GetValue();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user