]> git.saurik.com Git - wxWidgets.git/commitdiff
'wx(U)LongLong << variant' type safety improved (now works even if variant has plain...
authorJaakko Salli <jaakko.salli@dnainternet.net>
Sun, 21 Sep 2008 16:54:22 +0000 (16:54 +0000)
committerJaakko Salli <jaakko.salli@dnainternet.net>
Sun, 21 Sep 2008 16:54:22 +0000 (16:54 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@55771 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

docs/doxygen/overviews/propgrid.h
include/wx/propgrid/propgriddefs.h
interface/wx/propgrid/property.h
samples/propgrid/tests.cpp
src/propgrid/propgridiface.cpp

index 79e65b1087382614aa39b3b3288a1dab17b3d20b..4da34e5ba70d3aefc4573056e1d6634774cb8d09 100644 (file)
@@ -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
index f6608cef06b09828b6ae6c84d25f1bac1aaa4ffc..0cafff69341fba86dead815fe86d9e990de772db 100644 (file)
@@ -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
index 59f37bdc1b5b092442743acd94a845e021466c1f..766c51ec6364482c90bc74e5d4c035554fb0e220 100644 (file)
 
     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
 
index 217229f64061a0b59e2a89e583ae70c2f61d796a..7685b2978d71f67ce2fc91f098afeadfff01da27 100644 (file)
@@ -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"));
index dcb84e73868b4e052992546b748ae5f0edd871b2..8e20e67d0dca4eda6ede53a8bdf0d6167b5d4a23 100644 (file)
@@ -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;
     }