]> git.saurik.com Git - wxWidgets.git/blobdiff - include/wx/propgrid/propgriddefs.h
Fix wxPropertyGrid::GetPropertyRect when the last item is collapsed.
[wxWidgets.git] / include / wx / propgrid / propgriddefs.h
index 1d3d12e68cd33c9e2b2d7908a042fd970fb76aad..ae2e462bf44219a56b3a21cd4c21a2183d70c1ea 100644 (file)
@@ -4,17 +4,22 @@
 // Author:      Jaakko Salli
 // Modified by:
 // Created:     2008-08-31
-// RCS-ID:      $Id:
 // Copyright:   (c) Jaakko Salli
-// Licence:     wxWindows license
+// Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
 #ifndef _WX_PROPGRID_PROPGRIDDEFS_H_
 #define _WX_PROPGRID_PROPGRIDDEFS_H_
 
+#include "wx/defs.h"
+
+#if wxUSE_PROPGRID
+
 #include "wx/dynarray.h"
+#include "wx/vector.h"
 #include "wx/hashmap.h"
 #include "wx/variant.h"
+#include "wx/any.h"
 #include "wx/longlong.h"
 #include "wx/clntdata.h"
 
@@ -25,8 +30,6 @@
 // NOTE: More in propertygrid.cpp
 //
 
-#ifndef SWIG
-
 #if defined(__WXMSW__)
 
     // space between vertical line and value text
     // space between vertical line and value editor control
     #define wxPG_XBEFOREWIDGET          1
 
-    // x position adjustment for wxTextCtrl (and like)
-    #define wxPG_TEXTCTRLXADJUST        3
-
     // comment to use bitmap buttons
     #define wxPG_ICON_WIDTH             9
     // 1 if wxRendererNative should be employed
     #define wxPG_USE_RENDERER_NATIVE    0
 
-    // 1 to use double-buffer that guarantees flicker-free painting
-    #define wxPG_DOUBLE_BUFFER          1
-
     // Enable tooltips
     #define wxPG_SUPPORT_TOOLTIPS       1
 
     // width of optional bitmap/image in front of property
     #define wxPG_CUSTOM_IMAGE_WIDTH     20
 
-    // 1 to create controls out of sight, hide them, and then move them into
-    // correct position
-    #define wxPG_CREATE_CONTROLS_HIDDEN 0
-
     // 1 if splitter drag detect margin and control cannot overlap
     #define wxPG_NO_CHILD_EVT_MOTION    0
 
-    // If 1, then setting empty tooltip actually hides it
-    #define wxPG_ALLOW_EMPTY_TOOLTIPS   1
-
     #define wxPG_NAT_BUTTON_BORDER_ANY          1
     #define wxPG_NAT_BUTTON_BORDER_X            1
     #define wxPG_NAT_BUTTON_BORDER_Y            1
 
-    // If 1 then controls are refreshed after selected was drawn.
-    #define wxPG_REFRESH_CONTROLS_AFTER_REPAINT 0
+    // If 1 then controls are refreshed explicitly in a few places
+    #define wxPG_REFRESH_CONTROLS 0
 
 #elif defined(__WXGTK__)
 
     #define wxPG_XBEFOREWIDGET          1
 
     // x position adjustment for wxTextCtrl (and like)
-    #define wxPG_TEXTCTRLXADJUST        3
+    // NB: Only define wxPG_TEXTCTRLXADJUST for platforms that do not
+    //     (yet) support wxTextEntry::SetMargins() for the left margin.
+    //#define wxPG_TEXTCTRLXADJUST        3
 
     // comment to use bitmap buttons
     #define wxPG_ICON_WIDTH             9
     // 1 if wxRendererNative should be employed
-    #define wxPG_USE_RENDERER_NATIVE    0
-
-    // 1 to use double-buffer that guarantees flicker-free painting
-    #define wxPG_DOUBLE_BUFFER          1
+    #define wxPG_USE_RENDERER_NATIVE    1
 
     // Enable tooltips
     #define wxPG_SUPPORT_TOOLTIPS       1
     // width of optional bitmap/image in front of property
     #define wxPG_CUSTOM_IMAGE_WIDTH     20
 
-    // 1 to create controls out of sight, hide them, and then move them into
-    // correct position
-    #define wxPG_CREATE_CONTROLS_HIDDEN 0
-
     // 1 if splitter drag detect margin and control cannot overlap
     #define wxPG_NO_CHILD_EVT_MOTION    1
 
-    // If 1, then setting empty tooltip actually hides it
-    #define wxPG_ALLOW_EMPTY_TOOLTIPS   0
-
     #define wxPG_NAT_BUTTON_BORDER_ANY      1
     #define wxPG_NAT_BUTTON_BORDER_X        1
     #define wxPG_NAT_BUTTON_BORDER_Y        1
 
     // If 1 then controls are refreshed after selected was drawn.
-    #define wxPG_REFRESH_CONTROLS_AFTER_REPAINT 1
+    #define wxPG_REFRESH_CONTROLS 1
 
 #elif defined(__WXMAC__)
 
     #define wxPG_XBEFOREWIDGET          1
 
     // x position adjustment for wxTextCtrl (and like)
-    #define wxPG_TEXTCTRLXADJUST        3
+    #define wxPG_TEXTCTRLXADJUST        0
 
     // comment to use bitmap buttons
     #define wxPG_ICON_WIDTH             11
     // 1 if wxRendererNative should be employed
     #define wxPG_USE_RENDERER_NATIVE    1
 
-    // 1 to use double-buffer that guarantees flicker-free painting
-    #define wxPG_DOUBLE_BUFFER          0
-
     // Enable tooltips
     #define wxPG_SUPPORT_TOOLTIPS       1
 
     // width of optional bitmap/image in front of property
     #define wxPG_CUSTOM_IMAGE_WIDTH     20
 
-    // 1 to create controls out of sight, hide them, and then move them into
-    // correct position
-    #define wxPG_CREATE_CONTROLS_HIDDEN 0
-
     // 1 if splitter drag detect margin and control cannot overlap
     #define wxPG_NO_CHILD_EVT_MOTION    0
 
-    // If 1, then setting empty tooltip actually hides it
-    #define wxPG_ALLOW_EMPTY_TOOLTIPS   1
-
     #define wxPG_NAT_BUTTON_BORDER_ANY      0
     #define wxPG_NAT_BUTTON_BORDER_X        0
     #define wxPG_NAT_BUTTON_BORDER_Y        0
 
     // If 1 then controls are refreshed after selected was drawn.
-    #define wxPG_REFRESH_CONTROLS_AFTER_REPAINT 0
+    #define wxPG_REFRESH_CONTROLS 0
 
 #else // defaults
 
     // 1 if wxRendererNative should be employed
     #define wxPG_USE_RENDERER_NATIVE    0
 
-    // 1 to use double-buffer that guarantees flicker-free painting
-    #define wxPG_DOUBLE_BUFFER          0
-
     // Enable tooltips
     #define wxPG_SUPPORT_TOOLTIPS       0
 
     // width of optional bitmap/image in front of property
     #define wxPG_CUSTOM_IMAGE_WIDTH     20
 
-    // 1 to create controls out of sight, hide them, and then move them into
-    // correct position
-    #define wxPG_CREATE_CONTROLS_HIDDEN 0
-
     // 1 if splitter drag detect margin and control cannot overlap
     #define wxPG_NO_CHILD_EVT_MOTION    1
 
-    // If 1, then setting empty tooltip actually hides it
-    #define wxPG_ALLOW_EMPTY_TOOLTIPS   0
-
     #define wxPG_NAT_BUTTON_BORDER_ANY      0
     #define wxPG_NAT_BUTTON_BORDER_X        0
     #define wxPG_NAT_BUTTON_BORDER_Y        0
 
     // If 1 then controls are refreshed after selected was drawn.
-    #define wxPG_REFRESH_CONTROLS_AFTER_REPAINT 1
+    #define wxPG_REFRESH_CONTROLS 0
 #endif // platform
 
 
 #define wxCC_CUSTOM_IMAGE_MARGIN1       4  // before image
 #define wxCC_CUSTOM_IMAGE_MARGIN2       5  // after image
 
+#define DEFAULT_IMAGE_OFFSET_INCREMENT \
+    (wxCC_CUSTOM_IMAGE_MARGIN1 + wxCC_CUSTOM_IMAGE_MARGIN2)
+
 #define wxPG_DRAG_MARGIN                30
 
 #if wxPG_NO_CHILD_EVT_MOTION
 
 #if defined(__WXWINCE__)
     #define wxPG_SMALL_SCREEN       1
-    #undef wxPG_DOUBLE_BUFFER
-    #define wxPG_DOUBLE_BUFFER      0
 #else
     #define wxPG_SMALL_SCREEN       0
 #endif
 
-#endif // #ifndef SWIG
 
 // Undefine wxPG_ICON_WIDTH to use supplied xpm bitmaps instead
 // (for tree buttons)
 //#undef wxPG_ICON_WIDTH
 
+#if WXWIN_COMPATIBILITY_2_6 || WXWIN_COMPATIBILITY_2_8
+    #define wxPG_COMPATIBILITY_1_4      1
+#else
+    #define wxPG_COMPATIBILITY_1_4      0
+#endif
+
 // Need to force disable tooltips?
 #if !wxUSE_TOOLTIPS
     #undef wxPG_SUPPORT_TOOLTIPS
 // -----------------------------------------------------------------------
 
 
-// wxPG_CHECK_FOO_DBG - debug check with message that does not
-//                      interrupt program flow.
-#define wxPG_CHECK_RET_DBG(A,B) \
-    if ( !(A) ) { wxLogWarning(B); return; }
-#define wxPG_CHECK_MSG_DBG(A,B,C) \
-    if ( !(A) ) { wxLogWarning(C); return B; }
-
-
 class wxPGEditor;
 class wxPGProperty;
 class wxPropertyCategory;
@@ -265,9 +225,8 @@ class wxPropertyGrid;
 class wxPropertyGridEvent;
 class wxPropertyGridManager;
 class wxPGOwnerDrawnComboBox;
-class wxPGCustomComboControl;
 class wxPGEditorDialogAdapter;
-struct wxPGValidationInfo;
+class wxPGValidationInfo;
 
 
 // -----------------------------------------------------------------------
@@ -278,17 +237,13 @@ struct wxPGValidationInfo;
     @{
 */
 
-#ifndef SWIG
-    // Used to tell wxPGProperty to use label as name as well
-    #define wxPG_LABEL              (*wxPGProperty::sm_wxPG_LABEL)
-    // This is the value placed in wxPGProperty::sm_wxPG_LABEL
-    #define wxPG_LABEL_STRING       wxS("@!")
-    #define wxPG_NULL_BITMAP        wxNullBitmap
-    #define wxPG_COLOUR_BLACK       (*wxBLACK)
-#else
-    #define wxPG_NULL_BITMAP        wxBitmap_NULL
-    #define wxPG_COLOUR_BLACK       wxColour_BLACK
-#endif // #ifndef SWIG
+// Used to tell wxPGProperty to use label as name as well
+#define wxPG_LABEL              (*wxPGProperty::sm_wxPG_LABEL)
+
+// This is the value placed in wxPGProperty::sm_wxPG_LABEL
+#define wxPG_LABEL_STRING       wxS("@!")
+#define wxPG_NULL_BITMAP        wxNullBitmap
+#define wxPG_COLOUR_BLACK       (*wxBLACK)
 
 /** Convert Red, Green and Blue to a single 32-bit value.
 */
@@ -301,6 +256,29 @@ struct 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;
 
 /** @}
@@ -314,21 +292,17 @@ typedef wxString wxPGCachedString;
 
 // -----------------------------------------------------------------------
 
-#ifndef SWIG
-
-#if wxUSE_STL
-typedef std::vector<wxPGProperty*> wxArrayPGProperty;
-#else
 WX_DEFINE_TYPEARRAY_WITH_DECL_PTR(wxPGProperty*, wxArrayPGProperty,
                                   wxBaseArrayPtrVoid,
                                   class WXDLLIMPEXP_PROPGRID);
-#endif
 
-// Always use wxString based hashmap with unicode, stl, swig and GCC 4.0+
 WX_DECLARE_STRING_HASH_MAP_WITH_DECL(void*,
                                      wxPGHashMapS2P,
                                      class WXDLLIMPEXP_PROPGRID);
 
+WX_DECLARE_STRING_HASH_MAP_WITH_DECL(wxString,
+                                     wxPGHashMapS2S,
+                                     class WXDLLIMPEXP_PROPGRID);
 
 WX_DECLARE_VOIDPTR_HASH_MAP_WITH_DECL(void*,
                                       wxPGHashMapP2P,
@@ -341,7 +315,18 @@ WX_DECLARE_HASH_MAP_WITH_DECL(wxInt32,
                               wxPGHashMapI2I,
                               class WXDLLIMPEXP_PROPGRID);
 
-#endif // #ifndef SWIG
+// Utility to find if specific item is in a vector. Returns index to
+// the item, or wxNOT_FOUND if not present.
+template<typename CONTAINER, typename T>
+int wxPGFindInVector( CONTAINER vector, const T& item )
+{
+    for ( unsigned int i=0; i<vector.size(); i++ )
+    {
+        if ( vector[i] == item )
+            return (int) i;
+    }
+    return wxNOT_FOUND;
+}
 
 // -----------------------------------------------------------------------
 
@@ -361,7 +346,12 @@ wxPG_INC_ATTRIBUTES               = 0x00000040,
 wxPG_RECURSE_STARTS               = 0x00000080,
 
 /** Force value change. */
-wxPG_FORCE                        = 0x00000100
+wxPG_FORCE                        = 0x00000100,
+
+/** Only sort categories and their immediate children.
+    Sorting done by wxPG_AUTO_SORT option uses this.
+*/
+wxPG_SORT_TOP_LEVEL_ONLY          = 0x00000200
 
 };
 
@@ -387,9 +377,16 @@ enum wxPG_MISC_ARG_FLAGS
     // Used when dealing with fragments of composite string value
     wxPG_COMPOSITE_FRAGMENT             = 0x00000010,
 
-    // Means property for which final string value is for can not really be
+    // Means property for which final string value is for cannot really be
     // edited.
-    wxPG_UNEDITABLE_COMPOSITE_FRAGMENT  = 0x00000020
+    wxPG_UNEDITABLE_COMPOSITE_FRAGMENT  = 0x00000020,
+
+    // ValueToString() called from GetValueAsString()
+    // (guarantees that input wxVariant value is current own value)
+    wxPG_VALUE_IS_CURRENT               = 0x00000040,
+
+    // Value is being set programmatically (ie. not by user)
+    wxPG_PROGRAMMATIC_VALUE             = 0x00000080
 };
 
 // -----------------------------------------------------------------------
@@ -399,7 +396,8 @@ enum wxPG_SETVALUE_FLAGS
 {
     wxPG_SETVAL_REFRESH_EDITOR      = 0x0001,
     wxPG_SETVAL_AGGREGATED          = 0x0002,
-    wxPG_SETVAL_FROM_PARENT         = 0x0004
+    wxPG_SETVAL_FROM_PARENT         = 0x0004,
+    wxPG_SETVAL_BY_USER             = 0x0008  // Set if value changed by user
 };
 
 // -----------------------------------------------------------------------
@@ -421,15 +419,17 @@ enum wxPG_SETVALUE_FLAGS
 // -----------------------------------------------------------------------
 // Editor class.
 
-#ifndef SWIG
-
-// Editor accessor.
+// Editor accessor (for backwards compatiblity use only).
 #define wxPG_EDITOR(T)          wxPGEditor_##T
 
-// Declare editor class, with optional part.
-#define WX_PG_DECLARE_EDITOR_WITH_DECL(EDITOR,DECL) \
-extern DECL wxPGEditor* wxPGEditor_##EDITOR; \
-extern DECL wxPGEditor* wxPGConstruct##EDITOR##EditorClass();
+// Macro for declaring editor class, with optional impexpdecl part.
+#ifndef WX_PG_DECLARE_EDITOR_WITH_DECL
+
+    #define WX_PG_DECLARE_EDITOR_WITH_DECL(EDITOR,DECL) \
+    extern DECL wxPGEditor* wxPGEditor_##EDITOR; \
+    extern DECL wxPGEditor* wxPGConstruct##EDITOR##EditorClass();
+
+#endif
 
 // Declare editor class.
 #define WX_PG_DECLARE_EDITOR(EDITOR) \
@@ -446,99 +446,19 @@ WX_PG_DECLARE_EDITOR_WITH_DECL(CheckBox,WXDLLIMPEXP_PROPGRID)
 #endif
 WX_PG_DECLARE_EDITOR_WITH_DECL(ChoiceAndButton,WXDLLIMPEXP_PROPGRID)
 
-#endif  // !SWIG
-
 // -----------------------------------------------------------------------
 
 #ifndef SWIG
 
-/** @class wxPGVariantData
-    @ingroup classes
-    wxVariantData with additional functionality.
-
-    It is usually enough to use supplied to macros to automatically generate
-    variant data class. Like so:
-
-    @code
-
-    // In header
-    WX_PG_DECLARE_VARIANT_DATA(wxPGVariantDataMyClass,  // Name of the class
-                               MyClass,  // Name of the data type
-                               wxEMPTY_PARAMETER_VALUE)  // Declaration
-
-    // In source
-    WX_PG_IMPLEMENT_VARIANT_DATA(wxPGVariantDataMyClass, MyClass)
-
-    @endcode
-
-    If your class is derived from wxObject, it is recommended that you use
-    wxObject-versions of the macros (WX_PG_DECLARE_WXOBJECT_VARIANT_DATA and
-    WX_PG_IMPLEMENT_WXOBJECT_VARIANT_DATA).
-
-*/
-class WXDLLIMPEXP_PROPGRID wxPGVariantData : public wxVariantData
-{
-public:
-    virtual void* GetValuePtr() = 0;
-    virtual wxVariant GetDefaultValue() const = 0;
-protected:
-};
-
-
-//
-// With wxWidgets 2.9 and later we demand native C++ RTTI support
-#ifdef wxNO_RTTI
-    #error "You need to enable compiler RTTI support for wxPropertyGrid"
-#endif
-#define WX_PG_DECLARE_DYNAMIC_CLASS_VARIANTDATA(A)
-#define WX_PG_IMPLEMENT_DYNAMIC_CLASS_VARIANTDATA(A, B)
-typedef const std::type_info* wxPGVariantDataClassInfo;
-#define wxPGVariantDataGetClassInfo(A) (&typeid(*A))
-#define wxPG_VARIANT_EQ(A, B) \
-    ( ((A).GetData() && \
-       (B).GetData() && typeid(*(A).GetData()) == typeid(*(B).GetData()) && \
-       (A == B)) || !((A).GetData() && (B).GetData()) )
-
-#ifndef wxDynamicCastVariantData
-    #define wxDynamicCastVariantData wxDynamicCast
-#endif
-
-
-inline void wxPGDoesNothing() {}
-
-
-#define _WX_PG_IMPLEMENT_VARIANT_DATA_CLASS(CLASSNAME, \
-                                            DATATYPE, \
-                                            AS_ARG, \
-                                            AS_ARG_CONST, \
-                                            CTOR_CODE, \
-                                            DEFAULT_VALUE, \
-                                            SET_CODE) \
-    WX_PG_DECLARE_DYNAMIC_CLASS_VARIANTDATA(CLASSNAME) \
-protected: \
-    DATATYPE m_value; \
-public: \
-    CLASSNAME() { CTOR_CODE; } \
-    CLASSNAME(AS_ARG_CONST value) { CTOR_CODE; SET_CODE; m_value = value; } \
-    DATATYPE GetValue() const { return m_value; } \
-    AS_ARG_CONST GetValueRef() const { return m_value; } \
-    AS_ARG GetValueRef() { return m_value; } \
-    void SetValue(AS_ARG_CONST value) { SET_CODE; m_value = value; } \
-    virtual bool Eq(wxVariantData&) const { return false; } \
-    virtual wxString GetType() const { return wxS(#DATATYPE); } \
-    virtual wxVariantData* Clone() { return new CLASSNAME; } \
-    virtual bool Read(wxString &) { return false; } \
-    virtual bool Write(wxString &) const { return true; } \
-    virtual wxVariant GetDefaultValue() const { return DEFAULT_VALUE; }
-
 //
 // Macro WXVARIANT allows creation of wxVariant from any type supported by
 // wxWidgets internally, and of all types created using
 // WX_PG_DECLARE_VARIANT_DATA.
 template<class T>
-wxVariant WXVARIANT( const T& value )
+wxVariant WXVARIANT( const T& WXUNUSED(value) )
 {
-    return wxVariant((void*)&value);
+    wxFAIL_MSG("Code should always call specializations of this template");
+    return wxVariant();
 }
 
 template<> inline wxVariant WXVARIANT( const int& value )
@@ -553,188 +473,185 @@ template<> inline wxVariant WXVARIANT( const wxArrayString& value )
     { return wxVariant(value); }
 template<> inline wxVariant WXVARIANT( const wxString& value )
     { return wxVariant(value); }
+#if wxUSE_LONGLONG
+template<> inline wxVariant WXVARIANT( const wxLongLong& value )
+    { return wxVariant(value); }
+template<> inline wxVariant WXVARIANT( const wxULongLong& value )
+    { return wxVariant(value); }
+#endif
 #if wxUSE_DATETIME
 template<> inline wxVariant WXVARIANT( const wxDateTime& value )
     { return wxVariant(value); }
 #endif
 
-#define _WX_PG_VARIANT_DATA_CLASSINFO_CONTAINER_DECL(CLASSNAME) \
-    extern int CLASSNAME##_d_;
-#define _WX_PG_VARIANT_DATA_CLASSINFO_CONTAINER(CLASSNAME) \
-    int CLASSNAME##_d_;
-
-#define _WX_PG_IMPLEMENT_VARIANT_DATA(CLASSNAME, \
-                                      DATATYPE, \
-                                      AS_ARG, \
-                                      AS_CONST_ARG, \
-                                      NULLVAL, \
-                                      BASECLASS) \
-_WX_PG_VARIANT_DATA_CLASSINFO_CONTAINER(CLASSNAME) \
-WX_PG_IMPLEMENT_DYNAMIC_CLASS_VARIANTDATA(CLASSNAME, BASECLASS) \
-AS_ARG operator <<( AS_ARG value, const wxVariant &variant ) \
+
+//
+// These are modified versions of DECLARE/WX_PG_IMPLEMENT_VARIANT_DATA
+// macros found in variant.h. Difference are as follows:
+//   * These support non-wxObject data
+//   * These implement classname##RefFromVariant function which returns
+//     reference to data within.
+//   * const char* classname##_VariantType which equals classname.
+//   * WXVARIANT
+//
+#define WX_PG_DECLARE_VARIANT_DATA(classname) \
+    WX_PG_DECLARE_VARIANT_DATA_EXPORTED(classname, wxEMPTY_PARAMETER_VALUE)
+
+#define WX_PG_DECLARE_VARIANT_DATA_EXPORTED(classname,expdecl) \
+expdecl classname& operator << ( classname &object, const wxVariant &variant ); \
+expdecl wxVariant& operator << ( wxVariant &variant, const classname &object ); \
+expdecl const classname& classname##RefFromVariant( const wxVariant& variant ); \
+expdecl classname& classname##RefFromVariant( wxVariant& variant ); \
+template<> inline wxVariant WXVARIANT( const classname& value ) \
 { \
-    CLASSNAME *data = wxDynamicCastVariantData( variant.GetData(), CLASSNAME ); \
-    wxASSERT( data ); \
-    value = data->GetValue(); \
-    return value; \
+    wxVariant variant; \
+    variant << value; \
+    return variant; \
 } \
-wxVariant& operator <<( wxVariant &variant, AS_CONST_ARG value ) \
+extern expdecl const char* classname##_VariantType;
+
+
+#define WX_PG_IMPLEMENT_VARIANT_DATA(classname) \
+    WX_PG_IMPLEMENT_VARIANT_DATA_EXPORTED(classname, wxEMPTY_PARAMETER_VALUE)
+
+// 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 \
 { \
-    CLASSNAME *data = new CLASSNAME( value ); \
-    variant.SetData( data ); \
-    return variant; \
+public:\
+    classname##VariantData() {} \
+    classname##VariantData( const classname &value ) { m_value = value; } \
+\
+    classname &GetValue() { return m_value; } \
+\
+    const classname &GetValue() const { return m_value; } \
+\
+    virtual bool Eq(wxVariantData& data) const; \
+\
+    virtual wxString GetType() const; \
+\
+    virtual wxVariantData* Clone() const { return new classname##VariantData(m_value); } \
+\
+    DECLARE_WXANY_CONVERSION() \
+protected:\
+    classname m_value; \
+};\
+\
+IMPLEMENT_TRIVIAL_WXANY_CONVERSION(classname, classname##VariantData) \
+\
+wxString classname##VariantData::GetType() const\
+{\
+    return wxS(#classname);\
+}\
+\
+expdecl wxVariant& operator << ( wxVariant &variant, const classname &value )\
+{\
+    classname##VariantData *data = new classname##VariantData( value );\
+    variant.SetData( data );\
+    return variant;\
 } \
-AS_ARG DATATYPE##FromVariant( const wxVariant& v ) \
+expdecl classname& classname##RefFromVariant( wxVariant& variant ) \
 { \
-    CLASSNAME *data = wxDynamicCastVariantData( v.GetData(), CLASSNAME ); \
-    if ( !data ) \
-        return NULLVAL; \
-    return data->GetValueRef(); \
+    wxASSERT_MSG( variant.GetType() == wxS(#classname), \
+                  wxString::Format("Variant type should have been '%s'" \
+                                   "instead of '%s'", \
+                                   wxS(#classname), \
+                                   variant.GetType().c_str())); \
+    classname##VariantData *data = \
+        (classname##VariantData*) variant.GetData(); \
+    return data->GetValue();\
 } \
-wxVariant DATATYPE##ToVariant( AS_CONST_ARG value ) \
+expdecl const classname& classname##RefFromVariant( const wxVariant& variant ) \
 { \
-    wxVariant variant( new CLASSNAME( value ) ); \
-    return variant; \
+    wxASSERT_MSG( variant.GetType() == wxS(#classname), \
+                  wxString::Format("Variant type should have been '%s'" \
+                                   "instead of '%s'", \
+                                   wxS(#classname), \
+                                   variant.GetType().c_str())); \
+    classname##VariantData *data = \
+        (classname##VariantData*) variant.GetData(); \
+    return data->GetValue();\
 }
 
-#define WX_PG_IMPLEMENT_VARIANT_DATA(CLASSNAME, DATATYPE) \
-class CLASSNAME : public wxPGVariantData \
-{ \
-_WX_PG_IMPLEMENT_VARIANT_DATA_CLASS(CLASSNAME, DATATYPE, DATATYPE&, \
-                                    const DATATYPE&, wxPGDoesNothing(), \
-                                    wxVariant(new CLASSNAME(DATATYPE())), \
-                                    wxPGDoesNothing()) \
-public: \
-    virtual void* GetValuePtr() { return (void*)&m_value; } \
-}; \
-_WX_PG_IMPLEMENT_VARIANT_DATA(CLASSNAME, \
-                              DATATYPE, \
-                              DATATYPE&, \
-                              const DATATYPE&, \
-                              (DATATYPE&)*((DATATYPE*)NULL), \
-                              wxPGVariantData)
-
-#define WX_PG_IMPLEMENT_WXOBJECT_VARIANT_DATA(CLASSNAME, DATATYPE) \
-class CLASSNAME : public wxPGVariantData \
-{ \
-_WX_PG_IMPLEMENT_VARIANT_DATA_CLASS(CLASSNAME, DATATYPE, DATATYPE&, \
-                                    const DATATYPE&, wxPGDoesNothing(), \
-                                    wxVariant(new CLASSNAME(DATATYPE())), \
-                                    wxPGDoesNothing()) \
-public: \
-    virtual void* GetValuePtr() { return (void*)&m_value; } \
-    virtual wxClassInfo* GetValueClassInfo() \
-        { return m_value.GetClassInfo(); } \
-}; \
-_WX_PG_IMPLEMENT_VARIANT_DATA(CLASSNAME, DATATYPE, DATATYPE&, \
-                              const DATATYPE&, \
-                              (DATATYPE&)*((DATATYPE*)NULL), \
-                              wxPGVariantData)
-
-
-#define WX_PG_DECLARE_VARIANT_DATA(CLASSNAME, DATATYPE, DECL) \
-DECL DATATYPE& operator <<( DATATYPE& value, const wxVariant &variant ); \
-DECL wxVariant& operator <<( wxVariant &variant, const DATATYPE& value ); \
-DECL DATATYPE& DATATYPE##FromVariant( const wxVariant& variant ); \
-DECL wxVariant DATATYPE##ToVariant( const DATATYPE& value ); \
-template<> inline wxVariant WXVARIANT( const DATATYPE& value ) \
-    { return DATATYPE##ToVariant(value); } \
-DECL _WX_PG_VARIANT_DATA_CLASSINFO_CONTAINER_DECL(CLASSNAME);
-
-#define WX_PG_DECLARE_WXOBJECT_VARIANT_DATA WX_PG_DECLARE_VARIANT_DATA
-
-#define WX_PG_DECLARE_PTR_VARIANT_DATA(CLASSNAME, DATATYPE, DECL) \
-DECL DATATYPE* operator <<( DATATYPE* value, const wxVariant &variant ); \
-DECL wxVariant& operator <<( wxVariant &variant, DATATYPE* value ); \
-DECL DATATYPE* DATATYPE##FromVariant( const wxVariant& variant ); \
-DECL wxVariant DATATYPE##ToVariant( DATATYPE* value ); \
-DECL _WX_PG_VARIANT_DATA_CLASSINFO_CONTAINER_DECL(CLASSNAME);
-
-
-#define WX_PG_IMPLEMENT_PTR_VARIANT_DATA(CLASSNAME, DATATYPE, DEFAULT) \
-class CLASSNAME : public wxPGVariantData \
-{ \
-_WX_PG_IMPLEMENT_VARIANT_DATA_CLASS(CLASSNAME, DATATYPE*, DATATYPE*, \
-                                    DATATYPE*, m_value = NULL, \
-                                    DEFAULT, \
-                                    if (m_value) Py_DECREF(m_value); \
-                                    if (!value) value = Py_None; \
-                                    Py_INCREF(value) ) \
-    ~CLASSNAME() { if (m_value) Py_DECREF(m_value); } \
-public: \
-    virtual void* GetValuePtr() { return (void*)m_value; } \
-}; \
-_WX_PG_IMPLEMENT_VARIANT_DATA(CLASSNAME, DATATYPE, DATATYPE*, DATATYPE*, \
-                              NULL, wxPGVariantData)
-
-
-WX_PG_DECLARE_VARIANT_DATA(wxPGVariantDataPoint, wxPoint, WXDLLIMPEXP_PROPGRID)
-WX_PG_DECLARE_VARIANT_DATA(wxPGVariantDataSize, wxSize, WXDLLIMPEXP_PROPGRID)
-WX_PG_DECLARE_VARIANT_DATA(wxPGVariantDataArrayInt,
-                           wxArrayInt, WXDLLIMPEXP_PROPGRID)
-WX_PG_DECLARE_VARIANT_DATA(wxPGVariantDataLongLong,
-                           wxLongLong, WXDLLIMPEXP_PROPGRID)
-WX_PG_DECLARE_VARIANT_DATA(wxPGVariantDataULongLong,
-                           wxULongLong, WXDLLIMPEXP_PROPGRID)
-
-WX_PG_DECLARE_WXOBJECT_VARIANT_DATA(wxPGVariantDataFont,
-                                    wxFont, WXDLLIMPEXP_PROPGRID)
-template<> inline wxVariant WXVARIANT( const wxColour& value )
-{
-    wxVariant variant;
-    variant << value;
-    return variant;
+#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_VARIANT_GETVALUEREF(P, T) \
-    (*((T*)((wxPGVariantData*)(P.GetData()))->GetValuePtr()))
-
-// Safely converts a wxVariant to (long) int. Supports converting from string
-// and boolean as well.
-WXDLLIMPEXP_PROPGRID
-long wxPGVariantToInt( const wxVariant& variant, long defVal = 1 );
-
-// Safely converts a wxVariant to wxLongLong_t. Returns true on success.
-WXDLLIMPEXP_PROPGRID
-bool wxPGVariantToLongLong( const wxVariant& variant, wxLongLong_t* pResult );
-
-// Safely converts a wxVariant to wxULongLong_t. Returns true on success.
-WXDLLIMPEXP_PROPGRID
-bool wxPGVariantToULongLong( const wxVariant& variant, wxULongLong_t* pResult );
-
-// Safely converts a wxVariant to double. Supports converting from string and
-// wxLongLong as well.
-WXDLLIMPEXP_PROPGRID
-bool wxPGVariantToDouble( const wxVariant& variant, double* pResult );
+#define WX_PG_IMPLEMENT_VARIANT_DATA_EQ(classname, expdecl) \
+bool classname##VariantData::Eq(wxVariantData& data) const \
+{\
+    wxASSERT( GetType() == data.GetType() );\
+\
+    classname##VariantData & otherData = (classname##VariantData &) data;\
+\
+    return otherData.m_value == m_value;\
+}
 
-#endif // !SWIG
+// 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_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 false; \
+}
 
-// -----------------------------------------------------------------------
+#define WX_PG_IMPLEMENT_VARIANT_DATA_DUMMY_EQ(classname) \
+WX_PG_IMPLEMENT_VARIANT_DATA_EXPORTED_DUMMY_EQ(classname, wxEMPTY_PARAMETER_VALUE)
 
-#ifndef SWIG
+WX_PG_DECLARE_VARIANT_DATA_EXPORTED(wxPoint, WXDLLIMPEXP_PROPGRID)
+WX_PG_DECLARE_VARIANT_DATA_EXPORTED(wxSize, WXDLLIMPEXP_PROPGRID)
+WX_PG_DECLARE_VARIANT_DATA_EXPORTED(wxArrayInt, WXDLLIMPEXP_PROPGRID)
+DECLARE_VARIANT_OBJECT_EXPORTED(wxFont, WXDLLIMPEXP_PROPGRID)
+template<> inline wxVariant WXVARIANT( const wxFont& value )
+{
+    wxVariant variant;
+    variant << value;
+    return variant;
+}
 
-WXDLLIMPEXP_PROPGRID
-wxObject*
-wxPG_VariantToWxObject( const wxVariant& variant, wxClassInfo* classInfo );
+template<> inline wxVariant WXVARIANT( const wxColour& value )
+{
+    wxVariant variant;
+    variant << value;
+    return variant;
+}
 
-//
-// Redefine wxGetVariantCast to also take propertygrid variantdata
-// classes into account.
-//
-#undef wxGetVariantCast
-#define wxGetVariantCast(var,classname) \
-    (classname*)wxPG_VariantToWxObject(var,&classname::ms_classInfo)
+// Define constants for common wxVariant type strings
 
-// TODO: After a while, remove this.
-#define WX_PG_VARIANT_TO_WXOBJECT(VARIANT,CLASSNAME) \
-    (CLASSNAME*)wxPG_VariantToWxObject(VARIANT,&CLASSNAME::ms_classInfo)
+#define wxPG_VARIANT_TYPE_STRING        wxPGGlobalVars->m_strstring
+#define wxPG_VARIANT_TYPE_LONG          wxPGGlobalVars->m_strlong
+#define wxPG_VARIANT_TYPE_BOOL          wxPGGlobalVars->m_strbool
+#define wxPG_VARIANT_TYPE_LIST          wxPGGlobalVars->m_strlist
+#define wxPG_VARIANT_TYPE_DOUBLE        wxS("double")
+#define wxPG_VARIANT_TYPE_ARRSTRING     wxS("arrstring")
+#define wxPG_VARIANT_TYPE_DATETIME      wxS("datetime")
+#define wxPG_VARIANT_TYPE_LONGLONG      wxS("longlong")
+#define wxPG_VARIANT_TYPE_ULONGLONG     wxS("ulonglong")
 
 #endif // !SWIG
 
 // -----------------------------------------------------------------------
 
-#ifndef SWIG
-
 //
 // Tokenizer macros.
 // NOTE: I have made two versions - worse ones (performance and consistency
@@ -790,8 +707,8 @@ protected:
 #define WX_PG_TOKENIZER2_END() \
     }
 
-#endif
-
 // -----------------------------------------------------------------------
 
+#endif // wxUSE_PROPGRID
+
 #endif // _WX_PROPGRID_PROPGRIDDEFS_H_