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
#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 \
{ \
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 );\
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() );\
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 \
{\
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
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
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
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);
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 )
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));
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();
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"
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"));
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)
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;
}
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;
}