]> git.saurik.com Git - wxWidgets.git/blobdiff - include/wx/propgrid/property.h
move virtual GetPath() implementation out of line to work around an apparent Fedora...
[wxWidgets.git] / include / wx / propgrid / property.h
index 593de4b4678d21abe91a3057afc30350dc881940..d8dcf5363f1fe2f62d95bb34e6649ed10c855fe2 100644 (file)
@@ -4,7 +4,7 @@
 // Author:      Jaakko Salli
 // Modified by:
 // Created:     2008-08-23
 // Author:      Jaakko Salli
 // Modified by:
 // Created:     2008-08-23
-// RCS-ID:      $Id:
+// RCS-ID:      $Id$
 // Copyright:   (c) Jaakko Salli
 // Licence:     wxWindows license
 /////////////////////////////////////////////////////////////////////////////
 // Copyright:   (c) Jaakko Salli
 // Licence:     wxWindows license
 /////////////////////////////////////////////////////////////////////////////
@@ -47,13 +47,6 @@ struct wxPGPaintData
 };
 
 
 };
 
 
-// Structure for relaying choice/list info.
-struct wxPGChoiceInfo
-{
-    wxPGChoices*    m_choices;
-};
-
-
 #ifndef SWIG
 
 
 #ifndef SWIG
 
 
@@ -82,8 +75,27 @@ public:
     // Render flags
     enum
     {
     // Render flags
     enum
     {
+        // We are painting selected item
         Selected        = 0x00010000,
         Selected        = 0x00010000,
-        Control         = 0x00020000
+
+        // We are painting item in choice popup
+        ChoicePopup     = 0x00020000,
+
+        // We are rendering wxOwnerDrawnComboBox control
+        // (or other owner drawn control, but that is only
+        // officially supported one ATM).
+        Control         = 0x00040000,
+
+        // We are painting a disable property
+        Disabled        = 0x00080000,
+
+        // We are painting selected, disabled, or similar
+        // item that dictates fore- and background colours,
+        // overriding any cell values.
+        DontUseCellFgCol    = 0x00100000,
+        DontUseCellBgCol    = 0x00200000,
+        DontUseCellColours  = DontUseCellFgCol |
+                              DontUseCellBgCol
     };
 
     virtual void Render( wxDC& dc,
     };
 
     virtual void Render( wxDC& dc,
@@ -152,14 +164,46 @@ private:
 };
 
 
 };
 
 
+class WXDLLIMPEXP_PROPGRID wxPGCellData : public wxObjectRefData
+{
+    friend class wxPGCell;
+public:
+    wxPGCellData();
+
+    void SetText( const wxString& text )
+    {
+        m_text = text;
+        m_hasValidText = true;
+    }
+    void SetBitmap( const wxBitmap& bitmap ) { m_bitmap = bitmap; }
+    void SetFgCol( const wxColour& col ) { m_fgCol = col; }
+    void SetBgCol( const wxColour& col ) { m_bgCol = col; }
+
+protected:
+    virtual ~wxPGCellData() { }
+
+    wxString    m_text;
+    wxBitmap    m_bitmap;
+    wxColour    m_fgCol;
+    wxColour    m_bgCol;
+
+    // True if m_text is valid and specified
+    bool        m_hasValidText;
+};
+
 /** @class wxPGCell
 
     Base class for simple wxPropertyGrid cell information.
 */
 /** @class wxPGCell
 
     Base class for simple wxPropertyGrid cell information.
 */
-class WXDLLIMPEXP_PROPGRID wxPGCell
+class WXDLLIMPEXP_PROPGRID wxPGCell : public wxObject
 {
 public:
     wxPGCell();
 {
 public:
     wxPGCell();
+    wxPGCell(const wxPGCell& other)
+        : wxObject(other)
+    {
+    }
+
     wxPGCell( const wxString& text,
               const wxBitmap& bitmap = wxNullBitmap,
               const wxColour& fgCol = wxNullColour,
     wxPGCell( const wxString& text,
               const wxBitmap& bitmap = wxNullBitmap,
               const wxColour& fgCol = wxNullColour,
@@ -167,21 +211,50 @@ public:
 
     virtual ~wxPGCell() { }
 
 
     virtual ~wxPGCell() { }
 
-    void SetText( const wxString& text ) { m_text = text; }
-    void SetBitmap( const wxBitmap& bitmap ) { m_bitmap = bitmap; }
-    void SetFgCol( const wxColour& col ) { m_fgCol = col; }
-    void SetBgCol( const wxColour& col ) { m_bgCol = col; }
+    wxPGCellData* GetData()
+    {
+        return (wxPGCellData*) m_refData;
+    }
+
+    const wxPGCellData* GetData() const
+    {
+        return (const wxPGCellData*) m_refData;
+    }
+
+    bool HasText() const
+    {
+        return (m_refData && GetData()->m_hasValidText);
+    }
 
 
-    const wxString& GetText() const { return m_text; }
-    const wxBitmap& GetBitmap() const { return m_bitmap; }
-    const wxColour& GetFgCol() const { return m_fgCol; }
-    const wxColour& GetBgCol() const { return m_bgCol; }
+    /**
+        Merges valid data from srcCell into this.
+    */
+    void MergeFrom( const wxPGCell& srcCell );
+
+    void SetText( const wxString& text );
+    void SetBitmap( const wxBitmap& bitmap );
+    void SetFgCol( const wxColour& col );
+    void SetBgCol( const wxColour& col );
+
+    const wxString& GetText() const { return GetData()->m_text; }
+    const wxBitmap& GetBitmap() const { return GetData()->m_bitmap; }
+    const wxColour& GetFgCol() const { return GetData()->m_fgCol; }
+    const wxColour& GetBgCol() const { return GetData()->m_bgCol; }
+
+    wxPGCell& operator=( const wxPGCell& other )
+    {
+        if ( this != &other )
+        {
+            Ref(other);
+        }
+        return *this;
+    }
 
 protected:
 
 protected:
-    wxString    m_text;
-    wxBitmap    m_bitmap;
-    wxColour    m_fgCol;
-    wxColour    m_bgCol;
+    virtual wxObjectRefData *CreateRefData() const
+        { return new wxPGCellData(); }
+
+    virtual wxObjectRefData *CloneRefData(const wxObjectRefData *data) const;
 };
 
 
 };
 
 
@@ -222,7 +295,7 @@ public:
     ~wxPGAttributeStorage();
 
     void Set( const wxString& name, const wxVariant& value );
     ~wxPGAttributeStorage();
 
     void Set( const wxString& name, const wxVariant& value );
-    size_t GetCount() const { return m_map.size(); }
+    unsigned int GetCount() const { return (unsigned int) m_map.size(); }
     wxVariant FindValue( const wxString& name ) const
     {
         wxPGHashMapS2P::const_iterator it = m_map.find(name);
     wxVariant FindValue( const wxString& name ) const
     {
         wxPGHashMapS2P::const_iterator it = m_map.find(name);
@@ -249,7 +322,7 @@ public:
         data->IncRef();
         variant.SetData(data);
         variant.SetName(it->first);
         data->IncRef();
         variant.SetData(data);
         variant.SetName(it->first);
-        it++;
+        ++it;
         return true;
     }
 
         return true;
     }
 
@@ -396,9 +469,6 @@ wxPG_PROP_CLASS_SPECIFIC_2          = 0x00100000
 /** @}
 */
 
 /** @}
 */
 
-// Amalgam of flags that should be inherited by sub-properties
-#define wxPG_INHERITED_PROPFLAGS        (wxPG_PROP_HIDDEN|wxPG_PROP_NOEDITOR)
-
 // Combination of flags that can be stored by GetFlagsAsString
 #define wxPG_STRING_STORED_FLAGS \
     (wxPG_PROP_DISABLED|wxPG_PROP_HIDDEN|wxPG_PROP_NOEDITOR|wxPG_PROP_COLLAPSED)
 // Combination of flags that can be stored by GetFlagsAsString
 #define wxPG_STRING_STORED_FLAGS \
     (wxPG_PROP_DISABLED|wxPG_PROP_HIDDEN|wxPG_PROP_NOEDITOR|wxPG_PROP_COLLAPSED)
@@ -445,13 +515,28 @@ wxPG_PROP_CLASS_SPECIFIC_2          = 0x00100000
 */
 #define wxPG_ATTR_INLINE_HELP               wxS("InlineHelp")
 
 */
 #define wxPG_ATTR_INLINE_HELP               wxS("InlineHelp")
 
-/** wxBoolProperty specific, int, default 0. When 1 sets bool property to
-    use checkbox instead of choice.
+/** Universal, wxArrayString. Set to enable auto-completion in any
+    wxTextCtrl-based property editor.
+*/
+#define wxPG_ATTR_AUTOCOMPLETE              wxS("AutoComplete")
+
+/** wxBoolProperty and wxFlagsProperty specific. Value type is bool.
+    Default value is False.
+
+    When set to True, bool property will use check box instead of a
+    combo box as its editor control. If you set this attribute
+    for a wxFlagsProperty, it is automatically applied to child
+    bool properties.
 */
 #define wxPG_BOOL_USE_CHECKBOX              wxS("UseCheckbox")
 
 */
 #define wxPG_BOOL_USE_CHECKBOX              wxS("UseCheckbox")
 
-/** wxBoolProperty specific, int, default 0. When 1 sets bool property value
-    to cycle on double click (instead of showing the popup listbox).
+/** wxBoolProperty and wxFlagsProperty specific. Value type is bool.
+    Default value is False.
+
+    Set to True for the bool property to cycle value on double click
+    (instead of showing the popup listbox). If you set this attribute
+    for a wxFlagsProperty, it is automatically applied to child
+    bool properties.
 */
 #define wxPG_BOOL_USE_DOUBLE_CLICK_CYCLING  wxS("UseDClickCycling")
 
 */
 #define wxPG_BOOL_USE_DOUBLE_CLICK_CYCLING  wxS("UseDClickCycling")
 
@@ -567,189 +652,602 @@ wxPG_PROP_CLASS_SPECIFIC_2          = 0x00100000
 
 // -----------------------------------------------------------------------
 
 
 // -----------------------------------------------------------------------
 
-/** @class wxPGProperty
-
-    wxPGProperty is base class for all wxPropertyGrid properties.
-
-    NB: Full class overview is now only present in
-        interface/wx/propgrid/property.h.
+#ifndef SWIG
 
 
-    @library{wxpropgrid}
-    @category{propgrid}
+/** @class wxPGChoiceEntry
+    Data of a single wxPGChoices choice.
 */
 */
-class WXDLLIMPEXP_PROPGRID wxPGProperty : public wxObject
+class WXDLLIMPEXP_PROPGRID wxPGChoiceEntry : public wxPGCell
 {
 {
-    friend class wxPropertyGrid;
-    friend class wxPropertyGridInterface;
-    friend class wxPropertyGridPageState;
-    friend class wxPropertyGridPopulator;
-    friend class wxStringProperty;  // Proper "<composed>" support requires this
-#ifndef SWIG
-    DECLARE_ABSTRACT_CLASS(wxPGProperty)
-#endif
 public:
 public:
-    typedef wxUint32 FlagType;
-
-    /** Basic constructor.
-    */
-    wxPGProperty();
+    wxPGChoiceEntry();
+    wxPGChoiceEntry(const wxPGChoiceEntry& other)
+        : wxPGCell(other)
+    {
+        m_value = other.m_value;
+    }
+    wxPGChoiceEntry( const wxString& label,
+                     int value = wxPG_INVALID_VALUE )
+        : wxPGCell(), m_value(value)
+    {
+        SetText(label);
+    }
 
 
-    /** Constructor.
-        Non-abstract property classes should have constructor of this style:
+    virtual ~wxPGChoiceEntry() { }
 
 
-        @code
+    void SetValue( int value ) { m_value = value; }
+    int GetValue() const { return m_value; }
 
 
-        // If T is a class, then it should be a constant reference
-        // (e.g. const T& ) instead.
-        MyProperty( const wxString& label, const wxString& name, T value )
-            : wxPGProperty()
+    wxPGChoiceEntry& operator=( const wxPGChoiceEntry& other )
+    {
+        if ( this != &other )
         {
         {
-            // Generally recommended way to set the initial value
-            // (as it should work in pretty much 100% of cases).
-            wxVariant variant;
-            variant << value;
-            SetValue(variant);
-
-            // If has private child properties then create them here, e.g.:
-            //     AddChild( new wxStringProperty( "Subprop 1",
-            //                                     wxPG_LABEL,
-            //                                     value.GetSubProp1() ) );
+            Ref(other);
         }
         }
+        m_value = other.m_value;
+        return *this;
+    }
 
 
-        @endcode
-    */
-    wxPGProperty( const wxString& label, const wxString& name );
+protected:
+    int m_value;
+};
 
 
-    /**
-        Virtual destructor.
-        It is customary for derived properties to implement this.
-    */
-    virtual ~wxPGProperty();
 
 
-    /** This virtual function is called after m_value has been set.
+typedef void* wxPGChoicesId;
 
 
-        @remarks
-        - If m_value was set to Null variant (ie. unspecified value),
-          OnSetValue() will not be called.
-        - m_value may be of any variant type. Typically properties internally
-          support only one variant type, and as such OnSetValue() provides a
-          good opportunity to convert
-          supported values into internal type.
-        - Default implementation does nothing.
-    */
-    virtual void OnSetValue();
+class WXDLLIMPEXP_PROPGRID wxPGChoicesData
+{
+    friend class wxPGChoices;
+public:
+    // Constructor sets m_refCount to 1.
+    wxPGChoicesData();
 
 
-    /** Override this to return something else than m_value as the value.
-    */
-    virtual wxVariant DoGetValue() const { return m_value; }
+    void CopyDataFrom( wxPGChoicesData* data );
 
 
-#if !defined(SWIG) || defined(CREATE_VCW)
-    /** Implement this function in derived class to check the value.
-        Return true if it is ok. Returning false prevents property change events
-        from occurring.
+    wxPGChoiceEntry& Insert( int index, const wxPGChoiceEntry& item );
 
 
-        @remarks
-        - Default implementation always returns true.
-    */
-    virtual bool ValidateValue( wxVariant& value,
-                                wxPGValidationInfo& validationInfo ) const;
+    // Delete all entries
+    void Clear();
 
 
-    /**
-        Converts 'text' into proper value 'variant'.
-        Returns true if new (different than m_value) value could be interpreted
-        from the text.
-        @param argFlags
-            If wxPG_FULL_VALUE is set, returns complete, storable value instead
-            of displayable one (they may be different).
-            If wxPG_COMPOSITE_FRAGMENT is set, text is interpreted as a part of
-            composite property string value (as generated by GetValueAsString()
-            called with this same flag).
+    unsigned int GetCount() const
+    {
+        return (unsigned int) m_items.size();
+    }
 
 
-        @remarks
-        Default implementation converts semicolon delimited tokens into child
-        values. Only works for properties with children.
-    */
-    virtual bool StringToValue( wxVariant& variant,
-                                const wxString& text,
-                                int argFlags = 0 ) const;
+    const wxPGChoiceEntry& Item( unsigned int i ) const
+    {
+        wxASSERT_MSG( i < GetCount(), "invalid index" );
+        return m_items[i];
+    }
 
 
-    /**
-        Converts 'number' (including choice selection) into proper value
-        'variant'.
+    wxPGChoiceEntry& Item( unsigned int i )
+    {
+        wxASSERT_MSG( i < GetCount(), "invalid index" );
+        return m_items[i];
+    }
 
 
-        Returns true if new (different than m_value) value could be interpreted
-        from the integer.
+    void DecRef()
+    {
+        m_refCount--;
+        wxASSERT( m_refCount >= 0 );
+        if ( m_refCount == 0 )
+            delete this;
+    }
 
 
-        @param argFlags
-            If wxPG_FULL_VALUE is set, returns complete, storable value instead
-            of displayable one.
+private:
+    wxVector<wxPGChoiceEntry>   m_items;
 
 
-        @remarks
-        - If property is not supposed to use choice or spinctrl or other editor
-          with int-based value, it is not necessary to implement this method.
-        - Default implementation simply assign given int to m_value.
-        - If property uses choice control, and displays a dialog on some choice
-          items, then it is preferred to display that dialog in IntToValue
-          instead of OnEvent.
-    */
-    virtual bool IntToValue( wxVariant& value,
-                             int number,
-                             int argFlags = 0 ) const;
-#endif  // !defined(SWIG) || defined(CREATE_VCW)
+    // So that multiple properties can use the same set
+    int             m_refCount;
 
 
-public:
-    /** Returns text representation of property's value.
+    virtual ~wxPGChoicesData();
+};
 
 
-        @param argFlags
-            If wxPG_FULL_VALUE is set, returns complete, storable string value
-            instead of displayable. If wxPG_EDITABLE_VALUE is set, returns
-            string value that must be editable in textctrl. If
-            wxPG_COMPOSITE_FRAGMENT is set, returns text that is appropriate to
-            display as a part of composite property string value.
+#define wxPGChoicesEmptyData    ((wxPGChoicesData*)NULL)
 
 
-        @remarks
-        Default implementation returns string composed from text
-        representations of child properties.
-    */
-    virtual wxString GetValueAsString( int argFlags = 0 ) const;
+#endif // SWIG
 
 
-    /** Converts string to a value, and if successful, calls SetValue() on it.
-        Default behavior is to do nothing.
-        @param text
-        String to get the value from.
-        @return
-        true if value was changed.
-    */
-    bool SetValueFromString( const wxString& text, int flags = 0 );
+/** @class wxPGChoices
 
 
-    /** Converts integer to a value, and if succesful, calls SetValue() on it.
-        Default behavior is to do nothing.
-        @param value
-            Int to get the value from.
-        @param flags
-            If has wxPG_FULL_VALUE, then the value given is a actual value and
-            not an index.
-        @return
-            True if value was changed.
-    */
-    bool SetValueFromInt( long value, int flags = 0 );
+    Helper class for managing choices of wxPropertyGrid properties.
+    Each entry can have label, value, bitmap, text colour, and background
+    colour.
+    wxPGChoices uses reference counting, similar to other wxWidgets classes.
+    This means that assignment operator and copy constructor only copy the
+    reference and not the actual data. Use Copy() member function to create a
+    real copy.
 
 
-    /**
-        Returns size of the custom painted image in front of property.
+    @remarks If you do not specify value for entry, index is used.
 
 
-        This method must be overridden to return non-default value if
-        OnCustomPaint is to be called.
-        @param item
-            Normally -1, but can be an index to the property's list of items.
-        @remarks
-        - Default behavior is to return wxSize(0,0), which means no image.
-        - Default image width or height is indicated with dimension -1.
-        - You can also return wxPG_DEFAULT_IMAGE_SIZE, i.e. wxSize(-1, -1).
-    */
-    virtual wxSize OnMeasureImage( int item = -1 ) const;
+    @library{wxpropgrid}
+    @category{propgrid}
+*/
+class WXDLLIMPEXP_PROPGRID wxPGChoices
+{
+public:
+    typedef long ValArrItem;
 
 
-    /**
-        Events received by editor widgets are processed here.
+    /** Default constructor. */
+    wxPGChoices()
+    {
+        Init();
+    }
+
+    /**
+        Copy constructor, uses reference counting. To create a real copy,
+        use Copy() member function instead.
+    */
+    wxPGChoices( const wxPGChoices& a )
+    {
+        if ( a.m_data != wxPGChoicesEmptyData )
+        {
+            m_data = a.m_data;
+            m_data->m_refCount++;
+        }
+    }
+
+    /**
+        Constructor.
+
+        @param labels
+            Labels for choices
+
+        @param values
+            Values for choices. If NULL, indexes are used.
+    */
+    wxPGChoices( const wxChar** labels, const long* values = NULL )
+    {
+        Init();
+        Set(labels,values);
+    }
+
+    /**
+        Constructor.
+
+        @param labels
+            Labels for choices
+
+        @param values
+            Values for choices. If empty, indexes are used.
+    */
+    wxPGChoices( const wxArrayString& labels,
+                 const wxArrayInt& values = wxArrayInt() )
+    {
+        Init();
+        Set(labels,values);
+    }
+
+    /** Simple interface constructor. */
+    wxPGChoices( wxPGChoicesData* data )
+    {
+        wxASSERT(data);
+        m_data = data;
+        data->m_refCount++;
+    }
+
+    /** Destructor. */
+    ~wxPGChoices()
+    {
+        Free();
+    }
+
+    /**
+        Adds to current.
+
+        If did not have own copies, creates them now. If was empty, identical
+        to set except that creates copies.
+
+        @param labels
+            Labels for added choices.
+
+        @param values
+            Values for added choices. If empty, relevant entry indexes are used.
+    */
+    void Add( const wxChar** labels, const ValArrItem* values = NULL );
+
+    /** Version that works with wxArrayString and wxArrayInt. */
+    void Add( const wxArrayString& arr, const wxArrayInt& arrint = wxArrayInt() );
+
+    /**
+        Adds a single choice.
+
+        @param label
+            Label for added choice.
+
+        @param value
+            Value for added choice. If unspecified, index is used.
+    */
+    wxPGChoiceEntry& Add( const wxString& label,
+                          int value = wxPG_INVALID_VALUE );
+
+    /** Adds a single item, with bitmap. */
+    wxPGChoiceEntry& Add( const wxString& label,
+                          const wxBitmap& bitmap,
+                          int value = wxPG_INVALID_VALUE );
+
+    /** Adds a single item with full entry information. */
+    wxPGChoiceEntry& Add( const wxPGChoiceEntry& entry )
+    {
+        return Insert(entry, -1);
+    }
+
+    /** Adds single item. */
+    wxPGChoiceEntry& AddAsSorted( const wxString& label,
+                                  int value = wxPG_INVALID_VALUE );
+
+    /**
+        Assigns choices data, using reference counting. To create a real copy,
+        use Copy() member function instead.
+    */
+    void Assign( const wxPGChoices& a )
+    {
+        AssignData(a.m_data);
+    }
+
+    void AssignData( wxPGChoicesData* data );
+
+    /** Delete all choices. */
+    void Clear();
+
+    /**
+        Returns a real copy of the choices.
+    */
+    wxPGChoices Copy() const
+    {
+        wxPGChoices dst;
+        dst.EnsureData();
+        dst.m_data->CopyDataFrom(m_data);
+        return dst;
+    }
+
+    void EnsureData()
+    {
+        if ( m_data == wxPGChoicesEmptyData )
+            m_data = new wxPGChoicesData();
+    }
+
+    /** Gets a unsigned number identifying this list. */
+    wxPGChoicesId GetId() const { return (wxPGChoicesId) m_data; };
+
+    const wxString& GetLabel( unsigned int ind ) const
+    {
+        return Item(ind).GetText();
+    }
+
+    unsigned int GetCount () const
+    {
+        if ( !m_data )
+            return 0;
+
+        return m_data->GetCount();
+    }
+
+    int GetValue( unsigned int ind ) const { return Item(ind).GetValue(); }
+
+    /** Returns array of values matching the given strings. Unmatching strings
+        result in wxPG_INVALID_VALUE entry in array.
+    */
+    wxArrayInt GetValuesForStrings( const wxArrayString& strings ) const;
+
+    /** Returns array of indices matching given strings. Unmatching strings
+        are added to 'unmatched', if not NULL.
+    */
+    wxArrayInt GetIndicesForStrings( const wxArrayString& strings,
+                                     wxArrayString* unmatched = NULL ) const;
+
+    int Index( const wxString& str ) const;
+    int Index( int val ) const;
+
+    /** Inserts single item. */
+    wxPGChoiceEntry& Insert( const wxString& label,
+                             int index,
+                             int value = wxPG_INVALID_VALUE );
+
+    /** Inserts a single item with full entry information. */
+    wxPGChoiceEntry& Insert( const wxPGChoiceEntry& entry, int index );
+
+    /** Returns false if this is a constant empty set of choices,
+        which should not be modified.
+    */
+    bool IsOk() const
+    {
+        return ( m_data != wxPGChoicesEmptyData );
+    }
+
+    const wxPGChoiceEntry& Item( unsigned int i ) const
+    {
+        wxASSERT( IsOk() );
+        return m_data->Item(i);
+    }
+
+    wxPGChoiceEntry& Item( unsigned int i )
+    {
+        wxASSERT( IsOk() );
+        return m_data->Item(i);
+    }
+
+    /** Removes count items starting at position nIndex. */
+    void RemoveAt(size_t nIndex, size_t count = 1);
+
+#ifndef SWIG
+    /** Does not create copies for itself. */
+    void Set( const wxChar** labels, const long* values = NULL )
+    {
+        Free();
+        Add(labels,values);
+    }
+#endif // SWIG
+
+    /** Version that works with wxArrayString and wxArrayInt. */
+    void Set( const wxArrayString& labels,
+              const wxArrayInt& values = wxArrayInt() )
+    {
+        Free();
+        if ( &values )
+            Add(labels,values);
+        else
+            Add(labels);
+    }
+
+    // Creates exclusive copy of current choices
+    void AllocExclusive();
+
+    // Returns data, increases refcount.
+    wxPGChoicesData* GetData()
+    {
+        wxASSERT( m_data->m_refCount != 0xFFFFFFF );
+        m_data->m_refCount++;
+        return m_data;
+    }
+
+    // Returns plain data ptr - no refcounting stuff is done.
+    wxPGChoicesData* GetDataPtr() const { return m_data; }
+
+    // Changes ownership of data to you.
+    wxPGChoicesData* ExtractData()
+    {
+        wxPGChoicesData* data = m_data;
+        m_data = wxPGChoicesEmptyData;
+        return data;
+    }
+
+    wxArrayString GetLabels() const;
+
+#ifndef SWIG
+    void operator= (const wxPGChoices& a)
+    {
+        if (this != &a)
+            AssignData(a.m_data);
+    }
+
+    wxPGChoiceEntry& operator[](unsigned int i)
+    {
+        return Item(i);
+    }
+
+    const wxPGChoiceEntry& operator[](unsigned int i) const
+    {
+        return Item(i);
+    }
+
+protected:
+    wxPGChoicesData*    m_data;
+
+    void Init();
+    void Free();
+#endif  // !SWIG
+};
+
+// -----------------------------------------------------------------------
+
+/** @class wxPGProperty
+
+    wxPGProperty is base class for all wxPropertyGrid properties.
+
+    NB: Full class overview is now only present in
+        interface/wx/propgrid/property.h.
+
+    @library{wxpropgrid}
+    @category{propgrid}
+*/
+class WXDLLIMPEXP_PROPGRID wxPGProperty : public wxObject
+{
+    friend class wxPropertyGrid;
+    friend class wxPropertyGridInterface;
+    friend class wxPropertyGridPageState;
+    friend class wxPropertyGridPopulator;
+    friend class wxStringProperty;  // Proper "<composed>" support requires this
+#ifndef SWIG
+    DECLARE_ABSTRACT_CLASS(wxPGProperty)
+#endif
+public:
+    typedef wxUint32 FlagType;
+
+    /** Basic constructor.
+    */
+    wxPGProperty();
+
+    /** Constructor.
+        Non-abstract property classes should have constructor of this style:
+
+        @code
+
+        // If T is a class, then it should be a constant reference
+        // (e.g. const T& ) instead.
+        MyProperty( const wxString& label, const wxString& name, T value )
+            : wxPGProperty()
+        {
+            // Generally recommended way to set the initial value
+            // (as it should work in pretty much 100% of cases).
+            wxVariant variant;
+            variant << value;
+            SetValue(variant);
+
+            // If has private child properties then create them here. Also
+            // set flag that indicates presence of private children. E.g.:
+            //
+            //     AddPrivateChild( new wxStringProperty("Subprop 1",
+            //                                           wxPG_LABEL,
+            //                                           value.GetSubProp1() ) );
+        }
+
+        @endcode
+    */
+    wxPGProperty( const wxString& label, const wxString& name );
+
+    /**
+        Virtual destructor.
+        It is customary for derived properties to implement this.
+    */
+    virtual ~wxPGProperty();
+
+    /** This virtual function is called after m_value has been set.
+
+        @remarks
+        - If m_value was set to Null variant (ie. unspecified value),
+          OnSetValue() will not be called.
+        - m_value may be of any variant type. Typically properties internally
+          support only one variant type, and as such OnSetValue() provides a
+          good opportunity to convert
+          supported values into internal type.
+        - Default implementation does nothing.
+    */
+    virtual void OnSetValue();
+
+    /** Override this to return something else than m_value as the value.
+    */
+    virtual wxVariant DoGetValue() const { return m_value; }
+
+#if !defined(SWIG) || defined(CREATE_VCW)
+    /** Implement this function in derived class to check the value.
+        Return true if it is ok. Returning false prevents property change events
+        from occurring.
+
+        @remarks
+        - Default implementation always returns true.
+    */
+    virtual bool ValidateValue( wxVariant& value,
+                                wxPGValidationInfo& validationInfo ) const;
+
+    /**
+        Converts text into wxVariant value appropriate for this property.
+
+        @param variant
+            On function entry this is the old value (should not be wxNullVariant
+            in normal cases). Translated value must be assigned back to it.
+
+        @param text
+            Text to be translated into variant.
+
+        @param argFlags
+            If wxPG_FULL_VALUE is set, returns complete, storable value instead
+            of displayable one (they may be different).
+            If wxPG_COMPOSITE_FRAGMENT is set, text is interpreted as a part of
+            composite property string value (as generated by ValueToString()
+            called with this same flag).
+
+        @return Returns @true if resulting wxVariant value was different.
+
+        @remarks Default implementation converts semicolon delimited tokens into
+                child values. Only works for properties with children.
+
+                You might want to take into account that m_value is Null variant
+                if property value is unspecified (which is usually only case if
+                you explicitly enabled that sort behavior).
+    */
+    virtual bool StringToValue( wxVariant& variant,
+                                const wxString& text,
+                                int argFlags = 0 ) const;
+
+    /**
+        Converts integer (possibly a choice selection) into wxVariant value
+        appropriate for this property.
+
+        @param variant
+            On function entry this is the old value (should not be wxNullVariant
+            in normal cases). Translated value must be assigned back to it.
+
+        @param number
+            Integer to be translated into variant.
+
+        @param argFlags
+            If wxPG_FULL_VALUE is set, returns complete, storable value instead
+            of displayable one.
+
+        @return Returns @true if resulting wxVariant value was different.
+
+        @remarks
+        - If property is not supposed to use choice or spinctrl or other editor
+          with int-based value, it is not necessary to implement this method.
+        - Default implementation simply assign given int to m_value.
+        - If property uses choice control, and displays a dialog on some choice
+          items, then it is preferred to display that dialog in IntToValue
+          instead of OnEvent.
+        - You might want to take into account that m_value is Null variant if
+          property value is unspecified (which is usually only case if you
+          explicitly enabled that sort behavior).
+    */
+    virtual bool IntToValue( wxVariant& value,
+                             int number,
+                             int argFlags = 0 ) const;
+#endif  // !defined(SWIG) || defined(CREATE_VCW)
+    /**
+        Converts property value into a text representation.
+
+        @param value
+            Value to be converted.
+
+        @param argFlags
+            If 0 (default value), then displayed string is returned.
+            If wxPG_FULL_VALUE is set, returns complete, storable string value
+            instead of displayable. If wxPG_EDITABLE_VALUE is set, returns
+            string value that must be editable in textctrl. If
+            wxPG_COMPOSITE_FRAGMENT is set, returns text that is appropriate to
+            display as a part of string property's composite text
+            representation.
+
+        @remarks Default implementation calls GenerateComposedValue().
+    */
+    virtual wxString ValueToString( wxVariant& value, int argFlags = 0 ) const;
+
+    /** Converts string to a value, and if successful, calls SetValue() on it.
+        Default behavior is to do nothing.
+        @param text
+        String to get the value from.
+        @return
+        true if value was changed.
+    */
+    bool SetValueFromString( const wxString& text, int flags = wxPG_PROGRAMMATIC_VALUE );
+
+    /** Converts integer to a value, and if succesful, calls SetValue() on it.
+        Default behavior is to do nothing.
+        @param value
+            Int to get the value from.
+        @param flags
+            If has wxPG_FULL_VALUE, then the value given is a actual value and
+            not an index.
+        @return
+            True if value was changed.
+    */
+    bool SetValueFromInt( long value, int flags = 0 );
+
+    /**
+        Returns size of the custom painted image in front of property.
+
+        This method must be overridden to return non-default value if
+        OnCustomPaint is to be called.
+        @param item
+            Normally -1, but can be an index to the property's list of items.
+        @remarks
+        - Default behavior is to return wxSize(0,0), which means no image.
+        - Default image width or height is indicated with dimension -1.
+        - You can also return wxPG_DEFAULT_IMAGE_SIZE, i.e. wxSize(-1, -1).
+    */
+    virtual wxSize OnMeasureImage( int item = -1 ) const;
+
+    /**
+        Events received by editor widgets are processed here.
 
         Note that editor class usually processes most events. Some, such as
         button press events of TextCtrlAndButton class, can be handled here.
 
         Note that editor class usually processes most events. Some, such as
         button press events of TextCtrlAndButton class, can be handled here.
@@ -853,21 +1351,6 @@ public:
     */
     virtual wxValidator* DoGetValidator () const;
 
     */
     virtual wxValidator* DoGetValidator () const;
 
-    /**
-        Returns current value's index to the choice control.
-
-        May also return, through pointer arguments, strings that should be
-        inserted to that control. Irrelevant to classes which do not employ
-        wxPGEditor_Choice or similar.
-
-        @remarks
-        - If returns NULL in choiceinfo.m_choices, then this class must be
-          derived from wxBaseEnumProperty.
-        - Must be able to cope situation where property's set of choices is
-          uninitialized.
-    */
-    virtual int GetChoiceInfo( wxPGChoiceInfo* choiceinfo );
-
     /**
         Override to paint an image in front of the property value text or
         drop-down list item (but only if wxPGProperty::OnMeasureImage is
     /**
         Override to paint an image in front of the property value text or
         drop-down list item (but only if wxPGProperty::OnMeasureImage is
@@ -909,7 +1392,7 @@ public:
               colour) pen for drawing framing rectangle. It can be changed as
               well.
 
               colour) pen for drawing framing rectangle. It can be changed as
               well.
 
-        @see GetValueAsString()
+        @see ValueToString()
     */
     virtual void OnCustomPaint( wxDC& dc,
                                 const wxRect& rect,
     */
     virtual void OnCustomPaint( wxDC& dc,
                                 const wxRect& rect,
@@ -923,6 +1406,14 @@ public:
     */
     virtual wxPGCellRenderer* GetCellRenderer( int column ) const;
 
     */
     virtual wxPGCellRenderer* GetCellRenderer( int column ) const;
 
+    /** Returns which choice is currently selected. Only applies to properties
+        which have choices.
+
+        Needs to reimplemented in derived class if property value does not
+        map directly to a choice. Integer as index, bool, and string usually do.
+    */
+    virtual int GetChoiceSelection() const;
+
     /**
         Refresh values of child properties.
 
     /**
         Refresh values of child properties.
 
@@ -956,27 +1447,19 @@ public:
     virtual wxPGEditorDialogAdapter* GetEditorDialog() const;
 
     /**
     virtual wxPGEditorDialogAdapter* GetEditorDialog() const;
 
     /**
-        Adds entry to property's wxPGChoices and editor control (if it is
-        active).
+        Called whenever validation has failed with given pending value.
 
 
-        Returns index of item added.
+        @remarks If you implement this in your custom property class, please
+                 remember to call the baser implementation as well, since they
+                 may use it to revert property into pre-change state.
     */
     */
-    int AppendChoice( const wxString& label, int value = wxPG_INVALID_VALUE )
-    {
-        return InsertChoice(label,-1,value);
-    }
+    virtual void OnValidationFailure( wxVariant& pendingValue );
 
 
-    /** Returns wxPGCell of given column, NULL if none. If valid
-        object is returned, caller will gain its ownership.
+    /** Append a new choice to property's list of choices.
     */
     */
-    wxPGCell* AcquireCell( unsigned int column )
+    int AddChoice( const wxString& label, int value = wxPG_INVALID_VALUE )
     {
     {
-        if ( column >= m_cells.size() )
-            return NULL;
-
-        wxPGCell* cell = (wxPGCell*) m_cells[column];
-        m_cells[column] = NULL;
-        return cell;
+        return InsertChoice(label, wxNOT_FOUND, value);
     }
 
     /**
     }
 
     /**
@@ -992,6 +1475,11 @@ public:
         return false;
     }
 
         return false;
     }
 
+    /**
+        Deletes children of the property.
+    */
+    void DeleteChildren();
+
     /**
         Removes entry from property's wxPGChoices and editor control (if it is
         active).
     /**
         Removes entry from property's wxPGChoices and editor control (if it is
         active).
@@ -1013,8 +1501,15 @@ public:
         else ClearFlag( wxPG_PROP_USES_COMMON_VALUE );
     }
 
         else ClearFlag( wxPG_PROP_USES_COMMON_VALUE );
     }
 
-    /** Composes text from values of child properties. */
-    void GenerateComposedValue( wxString& text, int argFlags = 0 ) const;
+    /**
+        Composes text from values of child properties.
+    */
+    wxString GenerateComposedValue() const
+    {
+        wxString s;
+        DoGenerateComposedValue(s);
+        return s;
+    }
 
     /** Returns property's label. */
     const wxString& GetLabel() const { return m_label; }
 
     /** Returns property's label. */
     const wxString& GetLabel() const { return m_label; }
@@ -1028,11 +1523,12 @@ public:
      */
     const wxString& GetBaseName() const { return m_name; }
 
      */
     const wxString& GetBaseName() const { return m_name; }
 
-    wxPGChoices& GetChoices();
-
-    const wxPGChoices& GetChoices() const;
-
-    const wxPGChoiceEntry* GetCurrentChoice() const;
+    /** Returns read-only reference to property's list of choices.
+    */
+    const wxPGChoices& GetChoices() const
+    {
+        return m_choices;
+    }
 
     /** Returns coordinate to the top y of the property. Note that the
         position of scrollbars is not taken into account.
 
     /** Returns coordinate to the top y of the property. Note that the
         position of scrollbars is not taken into account.
@@ -1060,26 +1556,38 @@ public:
     }
 #endif
 
     }
 #endif
 
-    /** Same as GetValueAsString, except takes common value into account.
-    */
-    wxString GetValueString( int argFlags = 0 ) const;
+    /** Returns text representation of property's value.
 
 
-    void UpdateControl( wxWindow* primary );
+        @param argFlags
+            If 0 (default value), then displayed string is returned.
+            If wxPG_FULL_VALUE is set, returns complete, storable string value
+            instead of displayable. If wxPG_EDITABLE_VALUE is set, returns
+            string value that must be editable in textctrl. If
+            wxPG_COMPOSITE_FRAGMENT is set, returns text that is appropriate to
+            display as a part of string property's composite text
+            representation.
 
 
-    /** Returns wxPGCell of given column, NULL if none. wxPGProperty
-        will retain ownership of the cell object.
+        @remarks In older versions, this function used to be overridden to convert
+                 property's value into a string representation. This function is
+                 now handled by ValueToString(), and overriding this function now
+                 will result in run-time assertion failure.
     */
     */
-    wxPGCell* GetCell( unsigned int column ) const
-    {
-        if ( column >= m_cells.size() )
-            return NULL;
+    virtual wxString GetValueAsString( int argFlags = 0 ) const;
 
 
-        return (wxPGCell*) m_cells[column];
-    }
+    /** Synonymous to GetValueAsString().
+
+        @deprecated Use GetValueAsString() instead.
+
+        @see GetValueAsString()
+    */
+    wxDEPRECATED( wxString GetValueString( int argFlags = 0 ) const );
 
 
-    unsigned int GetChoiceCount() const;
+    /**
+        Returns wxPGCell of given column.
+    */
+    const wxPGCell& GetCell( unsigned int column ) const;
 
 
-    wxString GetChoiceString( unsigned int index );
+    wxPGCell& GetCell( unsigned int column );
 
     /** Return number of displayed common values for this property.
     */
 
     /** Return number of displayed common values for this property.
     */
@@ -1087,7 +1595,7 @@ public:
 
     wxString GetDisplayedString() const
     {
 
     wxString GetDisplayedString() const
     {
-        return GetValueString(0);
+        return GetValueAsString(0);
     }
 
     /** Returns property grid where property lies. */
     }
 
     /** Returns property grid where property lies. */
@@ -1172,14 +1680,21 @@ public:
     bool HasVisibleChildren() const;
 
     /**
     bool HasVisibleChildren() const;
 
     /**
-        Adds entry to property's wxPGChoices and editor control (if it is
-        active).
+        Use this member function to add independent (ie. regular) children to
+        a property.
+
+        @return Inserted childProperty.
+
+        @remarks wxPropertyGrid is not automatically refreshed by this
+                 function.
+
+        @see AddPrivateChild()
+    */
+    wxPGProperty* InsertChild( int index, wxPGProperty* childProperty );
 
 
-        Returns index of item added.
+    /** Inserts a new choice to property's list of choices.
     */
     */
-    int InsertChoice( const wxString& label,
-                      int index,
-                      int value = wxPG_INVALID_VALUE );
+    int InsertChoice( const wxString& label, int index, int value = wxPG_INVALID_VALUE );
 
     /**
         Returns true if this property is actually a wxPropertyCategory.
 
     /**
         Returns true if this property is actually a wxPropertyCategory.
@@ -1213,7 +1728,9 @@ public:
     /**
         Determines, recursively, if all children are not unspecified.
 
     /**
         Determines, recursively, if all children are not unspecified.
 
-        Takes values in given list into account.
+        @param pendingList
+            Assumes members in this wxVariant list as pending
+            replacement values.
     */
     bool AreAllChildrenSpecified( wxVariant* pendingList = NULL ) const;
 
     */
     bool AreAllChildrenSpecified( wxVariant* pendingList = NULL ) const;
 
@@ -1227,9 +1744,9 @@ public:
 
     /** Returns true if containing grid uses wxPG_EX_AUTO_UNSPECIFIED_VALUES.
     */
 
     /** Returns true if containing grid uses wxPG_EX_AUTO_UNSPECIFIED_VALUES.
     */
-    FlagType UsesAutoUnspecified() const
+    bool UsesAutoUnspecified() const
     {
     {
-        return HasFlag(wxPG_PROP_AUTO_UNSPECIFIED);
+        return HasFlag(wxPG_PROP_AUTO_UNSPECIFIED)?true:false;
     }
 
     wxBitmap* GetValueImage() const
     }
 
     wxBitmap* GetValueImage() const
@@ -1260,8 +1777,6 @@ public:
     */
     double GetAttributeAsDouble( const wxString& name, double defVal ) const;
 
     */
     double GetAttributeAsDouble( const wxString& name, double defVal ) const;
 
-    unsigned int GetArrIndex() const { return m_arrIndex; }
-
     unsigned int GetDepth() const { return (unsigned int)m_depth; }
 
     /** Gets flags as a'|' delimited string. Note that flag names are not
     unsigned int GetDepth() const { return (unsigned int)m_depth; }
 
     /** Gets flags as a'|' delimited string. Note that flag names are not
@@ -1312,888 +1827,622 @@ public:
     */
     void SetAttribute( const wxString& name, wxVariant value );
 
     */
     void SetAttribute( const wxString& name, wxVariant value );
 
-    void SetAttributes( const wxPGAttributeStorage& attributes );
-
-#ifndef SWIG
-    /** Sets editor for a property.
-
-        @param editor
-            For builtin editors, use wxPGEditor_X, where X is builtin editor's
-            name (TextCtrl, Choice, etc. see wxPGEditor documentation for full
-            list).
-
-        For custom editors, use pointer you received from
-        wxPropertyGrid::RegisterEditorClass().
-    */
-    void SetEditor( const wxPGEditor* editor )
-    {
-        m_customEditor = editor;
-    }
-#endif
-
-    /** Sets editor for a property.
-    */
-    inline void SetEditor( const wxString& editorName );
-
-    /** Sets cell information for given column.
-
-        Note that the property takes ownership of given wxPGCell instance.
-    */
-    void SetCell( int column, wxPGCell* cellObj );
-
-    /** Changes value of a property with choices, but only
-        works if the value type is long or string. */
-    void SetChoiceSelection( int newValue, const wxPGChoiceInfo& choiceInfo );
-
-    /** Sets common value selected for this property. -1 for none.
-    */
-    void SetCommonValue( int commonValue )
-    {
-        m_commonValue = commonValue;
-    }
-
-    /** Sets flags from a '|' delimited string. Note that flag names are not
-        prepended with 'wxPG_PROP_'.
-    */
-    void SetFlagsFromString( const wxString& str );
-
-    /** Sets property's "is it modified?" flag. Affects children recursively.
-    */
-    void SetModifiedStatus( bool modified )
-    {
-        SetFlagRecursively(wxPG_PROP_MODIFIED, modified);
-    }
-
-    /** Call in OnEvent(), OnButtonClick() etc. to change the property value
-        based on user input.
-
-        @remarks
-        This method is const since it doesn't actually modify value, but posts
-        given variant as pending value, stored in wxPropertyGrid.
-    */
-    void SetValueInEvent( wxVariant value ) const;
-
-    /**
-        Call this to set value of the property.
-
-        Unlike methods in wxPropertyGrid, this does not automatically update
-        the display.
-
-        @remarks
-        Use wxPropertyGrid::ChangePropertyValue() instead if you need to run
-        through validation process and send property change event.
-
-        If you need to change property value in event, based on user input, use
-        SetValueInEvent() instead.
-
-        @param pList
-        Pointer to list variant that contains child values. Used to indicate
-        which children should be marked as modified.
-        @param flags
-        Various flags (for instance, wxPG_SETVAL_REFRESH_EDITOR).
-    */
-    void SetValue( wxVariant value, wxVariant* pList = NULL, int flags = 0 );
-
-    /** Set wxBitmap in front of the value. This bitmap may be ignored
-        by custom cell renderers.
-    */
-    void SetValueImage( wxBitmap& bmp );
-
-    /** If property has choices and they are not yet exclusive, new such copy
-        of them will be created.
-    */
-    void SetChoicesExclusive();
-
-    void SetExpanded( bool expanded )
-    {
-        if ( !expanded ) m_flags |= wxPG_PROP_COLLAPSED;
-        else m_flags &= ~wxPG_PROP_COLLAPSED;
-    }
-
-    void SetFlag( FlagType flag ) { m_flags |= flag; }
-
-    void SetFlagRecursively( FlagType flag, bool set );
-
-    void SetHelpString( const wxString& helpString )
-    {
-        m_helpString = helpString;
-    }
-
-    void SetLabel( const wxString& label ) { m_label = label; }
-
-    inline void SetName( const wxString& newName );
-
-    void SetValueToUnspecified()
-    {
-        wxVariant val;  // Create NULL variant
-        SetValue(val);
-    }
-
-#if wxUSE_VALIDATORS
-    /** Sets wxValidator for a property*/
-    void SetValidator( const wxValidator& validator )
-    {
-        m_validator = wxDynamicCast(validator.Clone(),wxValidator);
-    }
-
-    /** Gets assignable version of property's validator. */
-    wxValidator* GetValidator() const
-    {
-        if ( m_validator )
-            return m_validator;
-        return DoGetValidator();
-    }
-#endif // #if wxUSE_VALIDATORS
-
-    /** Updates property value in case there were last minute
-        changes. If value was unspecified, it will be set to default.
-        Use only for properties that have TextCtrl-based editor.
-        @remarks
-        If you have code similar to
-        @code
-            // Update the value in case of last minute changes
-            if ( primary && propgrid->IsEditorsValueModified() )
-                 GetEditorClass()->CopyValueFromControl( this, primary );
-        @endcode
-        in wxPGProperty::OnEvent wxEVT_COMMAND_BUTTON_CLICKED handler,
-        then replace it with call to this method.
-        @return
-        True if value changed.
-    */
-    bool PrepareValueForDialogEditing( wxPropertyGrid* propgrid );
-
-#ifndef SWIG
-    /** Returns client data (void*) of a property.
-    */
-    void* GetClientData() const
-    {
-        return m_clientData;
-    }
-
-    /** Sets client data (void*) of a property.
-        @remarks
-        This untyped client data has to be deleted manually.
-    */
-    void SetClientData( void* clientData )
-    {
-        m_clientData = clientData;
-    }
-
-    /** Returns client object of a property.
-    */
-    void SetClientObject(wxClientData* clientObject)
-    {
-        delete m_clientObject;
-        m_clientObject = clientObject;
-    }
-
-    /** Sets managed client object of a property.
-    */
-    wxClientData *GetClientObject() const { return m_clientObject; }
-#endif
-
-    /** Sets new set of choices for property.
-
-        @remarks
-        This operation clears the property value.
-    */
-    bool SetChoices( wxPGChoices& choices );
-
-    /** Sets new set of choices for property.
-    */
-    inline bool SetChoices( const wxArrayString& labels,
-                            const wxArrayInt& values = wxArrayInt() );
-
-    /** Set max length of text in text editor.
-    */
-    inline bool SetMaxLength( int maxLen );
-
-    /** Call with 'false' in OnSetValue to cancel value changes after all
-        (ie. cancel 'true' returned by StringToValue() or IntToValue()).
-    */
-    void SetWasModified( bool set = true )
-    {
-        if ( set ) m_flags |= wxPG_PROP_WAS_MODIFIED;
-        else m_flags &= ~wxPG_PROP_WAS_MODIFIED;
-    }
-
-    const wxString& GetHelpString() const
-    {
-        return m_helpString;
-    }
-
-    void ClearFlag( FlagType flag ) { m_flags &= ~(flag); }
-
-    // Use, for example, to detect if item is inside collapsed section.
-    bool IsSomeParent( wxPGProperty* candidate_parent ) const;
-
-    /**
-        Adapts list variant into proper value using consecutive
-        ChildChanged-calls.
-    */
-    void AdaptListToValue( wxVariant& list, wxVariant* value ) const;
-
-    /** This is used by properties that have fixed sub-properties. */
-    void AddChild( wxPGProperty* prop );
-
-    /** Returns height of children, recursively, and
-        by taking expanded/collapsed status into account.
-
-        iMax is used when finding property y-positions.
-    */
-    int GetChildrenHeight( int lh, int iMax = -1 ) const;
+    void SetAttributes( const wxPGAttributeStorage& attributes );
 
 
-    /** Returns number of child properties */
-    unsigned int GetChildCount() const { return m_children.GetCount(); }
+    /**
+        Sets property's background colour.
 
 
-    /** Returns sub-property at index i. */
-    wxPGProperty* Item( size_t i ) const
-        { return (wxPGProperty*)m_children.Item(i); }
+        @param colour
+            Background colour to use.
 
 
-    /** Returns last sub-property.
+        @param recursively
+            If @true, children are affected recursively, and any categories
+            are not.
     */
     */
-    wxPGProperty* Last() const { return (wxPGProperty*)m_children.Last(); }
+    void SetBackgroundColour( const wxColour& colour,
+                              bool recursively = false );
 
 
-    /** Returns index of given sub-property. */
-    int Index( const wxPGProperty* p ) const
-        { return m_children.Index((wxPGProperty*)p); }
+    /**
+        Sets property's text colour.
 
 
-    /** Deletes all sub-properties. */
-    void Empty();
+        @param colour
+            Text colour to use.
 
 
-    // Puts correct indexes to children
-    void FixIndexesOfChildren( size_t starthere = 0 );
+        @param recursively
+            If @true, children are affected recursively, and any categories
+            are not.
+    */
+    void SetTextColour( const wxColour& colour,
+                        bool recursively = false );
 
 #ifndef SWIG
 
 #ifndef SWIG
-    // Returns wxPropertyGridPageState in which this property resides.
-    wxPropertyGridPageState* GetParentState() const { return m_parentState; }
-#endif
+    /** Sets editor for a property.
 
 
-    wxPGProperty* GetItemAtY( unsigned int y,
-                              unsigned int lh,
-                              unsigned int* nextItemY ) const;
+        @param editor
+            For builtin editors, use wxPGEditor_X, where X is builtin editor's
+            name (TextCtrl, Choice, etc. see wxPGEditor documentation for full
+            list).
 
 
-    /** Returns (direct) child property with given name (or NULL if not found).
+        For custom editors, use pointer you received from
+        wxPropertyGrid::RegisterEditorClass().
     */
     */
-    wxPGProperty* GetPropertyByName( const wxString& name ) const;
-
-#ifdef SWIG
-     %extend {
-        DocStr(GetClientData,
-               "Returns the client data object for a property", "");
-        PyObject* GetClientData() {
-            wxPyClientData* data = (wxPyClientData*)self->GetClientObject();
-            if (data) {
-                Py_INCREF(data->m_obj);
-                return data->m_obj;
-            } else {
-                Py_INCREF(Py_None);
-                return Py_None;
-            }
-        }
-
-        DocStr(SetClientData,
-               "Associate the given client data.", "");
-        void SetClientData(PyObject* clientData) {
-            wxPyClientData* data = new wxPyClientData(clientData);
-            self->SetClientObject(data);
-        }
-    }
-    %pythoncode {
-         GetClientObject = GetClientData
-         SetClientObject = SetClientData
+    void SetEditor( const wxPGEditor* editor )
+    {
+        m_customEditor = editor;
     }
 #endif
 
     }
 #endif
 
-#ifndef SWIG
-
-    static wxString*            sm_wxPG_LABEL;
-
-    /** This member is public so scripting language bindings
-        wrapper code can access it freely.
+    /** Sets editor for a property.
     */
     */
-    void*                       m_clientData;
+    inline void SetEditor( const wxString& editorName );
 
 
-protected:
-    /** Returns text for given column.
+    /**
+        Sets cell information for given column.
     */
     */
-    wxString GetColumnText( unsigned int col ) const;
-
-    /** Returns (direct) child property with given name (or NULL if not found),
-        with hint index.
+    void SetCell( int column, const wxPGCell& cell );
 
 
-        @param hintIndex
-        Start looking for the child at this index.
-
-        @remarks
-        Does not support scope (ie. Parent.Child notation).
+    /** Sets common value selected for this property. -1 for none.
     */
     */
-    wxPGProperty* GetPropertyByNameWH( const wxString& name,
-                                       unsigned int hintIndex ) const;
-
-    /** This is used by Insert etc. */
-    void AddChild2( wxPGProperty* prop,
-                    int index = -1,
-                    bool correct_mode = true );
-
-    void DoSetName(const wxString& str) { m_name = str; }
+    void SetCommonValue( int commonValue )
+    {
+        m_commonValue = commonValue;
+    }
 
 
-    // Call for after sub-properties added with AddChild
-    void PrepareSubProperties();
+    /** Sets flags from a '|' delimited string. Note that flag names are not
+        prepended with 'wxPG_PROP_'.
+    */
+    void SetFlagsFromString( const wxString& str );
 
 
-    void SetParentalType( int flag )
+    /** Sets property's "is it modified?" flag. Affects children recursively.
+    */
+    void SetModifiedStatus( bool modified )
     {
     {
-        m_flags &= ~(wxPG_PROP_PROPERTY|wxPG_PROP_PARENTAL_FLAGS);
-        m_flags |= flag;
+        SetFlagRecursively(wxPG_PROP_MODIFIED, modified);
     }
 
     }
 
-    void SetParentState( wxPropertyGridPageState* pstate )
-        { m_parentState = pstate; }
-
-    // Call after fixed sub-properties added/removed after creation.
-    // if oldSelInd >= 0 and < new max items, then selection is
-    // moved to it.
-    void SubPropsChanged( int oldSelInd = -1 );
+    /** Call in OnEvent(), OnButtonClick() etc. to change the property value
+        based on user input.
 
 
-    int GetY2( int lh ) const;
+        @remarks
+        This method is const since it doesn't actually modify value, but posts
+        given variant as pending value, stored in wxPropertyGrid.
+    */
+    void SetValueInEvent( wxVariant value ) const;
 
 
-    wxString                    m_label;
-    wxString                    m_name;
-    wxPGProperty*               m_parent;
-    wxPropertyGridPageState*        m_parentState;
+    /**
+        Call this to set value of the property.
 
 
-    wxClientData*               m_clientObject;
+        Unlike methods in wxPropertyGrid, this does not automatically update
+        the display.
 
 
-    // Overrides editor returned by property class
-    const wxPGEditor*           m_customEditor;
-#if wxUSE_VALIDATORS
-    // Editor is going to get this validator
-    wxValidator*                m_validator;
-#endif
-    // Show this in front of the value
-    //
-    // TODO: Can bitmap be implemented with wxPGCell?
-    wxBitmap*                   m_valueBitmap;
+        @remarks
+        Use wxPropertyGrid::ChangePropertyValue() instead if you need to run
+        through validation process and send property change event.
 
 
-    wxVariant                   m_value;
-    wxPGAttributeStorage        m_attributes;
-    wxArrayPtrVoid              m_children;
+        If you need to change property value in event, based on user input, use
+        SetValueInEvent() instead.
 
 
-    // Extended cell information
-    wxArrayPtrVoid              m_cells;
+        @param pList
+            Pointer to list variant that contains child values. Used to
+            indicate which children should be marked as modified.
 
 
-    // Help shown in statusbar or help box.
-    wxString                    m_helpString;
+        @param flags
+            Various flags (for instance, wxPG_SETVAL_REFRESH_EDITOR, which is
+            enabled by default).
+    */
+    void SetValue( wxVariant value, wxVariant* pList = NULL,
+                   int flags = wxPG_SETVAL_REFRESH_EDITOR );
 
 
-    // Index in parent's property array.
-    unsigned int                m_arrIndex;
+    /** Set wxBitmap in front of the value. This bitmap may be ignored
+        by custom cell renderers.
+    */
+    void SetValueImage( wxBitmap& bmp );
 
 
-    // If not -1, then overrides m_value
-    int                         m_commonValue;
+    /** Sets selected choice and changes property value.
 
 
-    FlagType                    m_flags;
+        Tries to retain value type, although currently if it is not string,
+        then it is forced to integer.
+    */
+    void SetChoiceSelection( int newValue );
 
 
-    // Maximum length (mainly for string properties). Could be in some sort of
-    // wxBaseStringProperty, but currently, for maximum flexibility and
-    // compatibility, we'll stick it here. Anyway, we had 3 excess bytes to use
-    // so short int will fit in just fine.
-    short                       m_maxLen;
+    void SetExpanded( bool expanded )
+    {
+        if ( !expanded ) m_flags |= wxPG_PROP_COLLAPSED;
+        else m_flags &= ~wxPG_PROP_COLLAPSED;
+    }
 
 
-    // Root has 0, categories etc. at that level 1, etc.
-    unsigned char               m_depth;
+    /**
+        Sets given property flag(s).
+    */
+    void SetFlag( FlagType flag ) { m_flags |= flag; }
 
 
-    // m_depthBgCol indicates width of background colour between margin and item
-    // (essentially this is category's depth, if none then equals m_depth).
-    unsigned char               m_depthBgCol;
+    /**
+        Sets or clears given property flag(s).
+    */
+    void ChangeFlag( FlagType flag, bool set )
+    {
+        if ( set )
+            m_flags |= flag;
+        else
+            m_flags &= ~flag;
+    }
 
 
-    unsigned char               m_bgColIndex; // Background brush index.
-    unsigned char               m_fgColIndex; // Foreground colour index.
+    void SetFlagRecursively( FlagType flag, bool set );
 
 
-private:
-    // Called in constructors.
-    void Init();
-    void Init( const wxString& label, const wxString& name );
-#endif // #ifndef SWIG
-};
+    void SetHelpString( const wxString& helpString )
+    {
+        m_helpString = helpString;
+    }
 
 
-// -----------------------------------------------------------------------
+    void SetLabel( const wxString& label ) { m_label = label; }
 
 
-//
-// Property class declaration helper macros
-// (wxPGRootPropertyClass and wxPropertyCategory require this).
-//
+    inline void SetName( const wxString& newName );
 
 
-#define WX_PG_DECLARE_DOGETEDITORCLASS \
-    virtual const wxPGEditor* DoGetEditorClass() const;
+    /**
+        Changes what sort of parent this property is for its children.
 
 
-#ifndef SWIG
-    #define WX_PG_DECLARE_PROPERTY_CLASS(CLASSNAME) \
-        public: \
-            DECLARE_DYNAMIC_CLASS(CLASSNAME) \
-            WX_PG_DECLARE_DOGETEDITORCLASS \
-        private:
-#else
-    #define WX_PG_DECLARE_PROPERTY_CLASS(CLASSNAME)
-#endif
+        @param flag
+            Use one of the following values: wxPG_PROP_MISC_PARENT (for
+            generic parents), wxPG_PROP_CATEGORY (for categories), or
+            wxPG_PROP_AGGREGATE (for derived property classes with private
+            children).
 
 
-// Implements sans constructor function. Also, first arg is class name, not
-// property name.
-#define WX_PG_IMPLEMENT_PROPERTY_CLASS_PLAIN(PROPNAME,T,EDITOR) \
-const wxPGEditor* PROPNAME::DoGetEditorClass() const \
-{ \
-    return wxPGEditor_##EDITOR; \
-}
+        @remarks You generally do not need to call this function.
+    */
+    void SetParentalType( int flag )
+    {
+        m_flags &= ~(wxPG_PROP_PROPERTY|wxPG_PROP_PARENTAL_FLAGS);
+        m_flags |= flag;
+    }
 
 
-// -----------------------------------------------------------------------
+    void SetValueToUnspecified()
+    {
+        wxVariant val;  // Create NULL variant
+        SetValue(val);
+    }
 
 
-#ifndef SWIG
+#if wxUSE_VALIDATORS
+    /** Sets wxValidator for a property*/
+    void SetValidator( const wxValidator& validator )
+    {
+        m_validator = wxDynamicCast(validator.Clone(),wxValidator);
+    }
 
 
-/** @class wxPGRootProperty
-    @ingroup classes
-    Root parent property.
-*/
-class WXDLLIMPEXP_PROPGRID wxPGRootProperty : public wxPGProperty
-{
-public:
-    WX_PG_DECLARE_PROPERTY_CLASS(wxPGRootProperty)
-public:
+    /** Gets assignable version of property's validator. */
+    wxValidator* GetValidator() const
+    {
+        if ( m_validator )
+            return m_validator;
+        return DoGetValidator();
+    }
+#endif // #if wxUSE_VALIDATORS
 
 
-    /** Constructor. */
-    wxPGRootProperty();
-    virtual ~wxPGRootProperty();
+#ifndef SWIG
+    /** Returns client data (void*) of a property.
+    */
+    void* GetClientData() const
+    {
+        return m_clientData;
+    }
 
 
-    virtual bool StringToValue( wxVariant&, const wxString&, int ) const
+    /** Sets client data (void*) of a property.
+        @remarks
+        This untyped client data has to be deleted manually.
+    */
+    void SetClientData( void* clientData )
     {
     {
-        return false;
+        m_clientData = clientData;
     }
 
     }
 
-protected:
-};
+    /** Returns client object of a property.
+    */
+    void SetClientObject(wxClientData* clientObject)
+    {
+        delete m_clientObject;
+        m_clientObject = clientObject;
+    }
 
 
-// -----------------------------------------------------------------------
+    /** Sets managed client object of a property.
+    */
+    wxClientData *GetClientObject() const { return m_clientObject; }
+#endif
 
 
-/** @class wxPropertyCategory
-    @ingroup classes
-    Category (caption) property.
-*/
-class WXDLLIMPEXP_PROPGRID wxPropertyCategory : public wxPGProperty
-{
-    friend class wxPropertyGrid;
-    friend class wxPropertyGridPageState;
-    WX_PG_DECLARE_PROPERTY_CLASS(wxPropertyCategory)
-public:
+    /** Sets new set of choices for property.
 
 
-    /** Default constructor is only used in special cases. */
-    wxPropertyCategory();
+        @remarks
+        This operation clears the property value.
+    */
+    bool SetChoices( wxPGChoices& choices );
 
 
-    wxPropertyCategory( const wxString& label,
-                        const wxString& name = wxPG_LABEL );
-    ~wxPropertyCategory();
+    /** Set max length of text in text editor.
+    */
+    inline bool SetMaxLength( int maxLen );
 
 
-    int GetTextExtent( const wxWindow* wnd, const wxFont& font ) const;
+    /** Call with 'false' in OnSetValue to cancel value changes after all
+        (ie. cancel 'true' returned by StringToValue() or IntToValue()).
+    */
+    void SetWasModified( bool set = true )
+    {
+        if ( set ) m_flags |= wxPG_PROP_WAS_MODIFIED;
+        else m_flags &= ~wxPG_PROP_WAS_MODIFIED;
+    }
 
 
-protected:
-    virtual wxString GetValueAsString( int argFlags ) const;
+    const wxString& GetHelpString() const
+    {
+        return m_helpString;
+    }
 
 
-    void SetTextColIndex( unsigned int colInd )
-        { m_capFgColIndex = (wxByte) colInd; }
-    unsigned int GetTextColIndex() const
-        { return (unsigned int) m_capFgColIndex; }
+    void ClearFlag( FlagType flag ) { m_flags &= ~(flag); }
 
 
-    void CalculateTextExtent( wxWindow* wnd, const wxFont& font );
+    // Use, for example, to detect if item is inside collapsed section.
+    bool IsSomeParent( wxPGProperty* candidate_parent ) const;
 
 
-    int     m_textExtent;  // pre-calculated length of text
-    wxByte  m_capFgColIndex;  // caption text colour index
+    /**
+        Adapts list variant into proper value using consecutive
+        ChildChanged-calls.
+    */
+    void AdaptListToValue( wxVariant& list, wxVariant* value ) const;
 
 
-private:
-    void Init();
-};
+#if wxPG_COMPATIBILITY_1_4
+    /**
+        Adds a private child property.
 
 
-#endif  // !SWIG
+        @deprecated Use AddPrivateChild() instead.
 
 
-// -----------------------------------------------------------------------
+        @see AddPrivateChild()
+    */
+    wxDEPRECATED( void AddChild( wxPGProperty* prop ) );
+#endif
 
 
-#ifndef SWIG
+    /**
+        Adds a private child property. If you use this instead of
+        wxPropertyGridInterface::Insert() or
+        wxPropertyGridInterface::AppendIn(), then property's parental
+        type will automatically be set up to wxPG_PROP_AGGREGATE. In other
+        words, all properties of this property will become private.
+    */
+    void AddPrivateChild( wxPGProperty* prop );
 
 
-/** @class wxPGChoiceEntry
-    Data of a single wxPGChoices choice.
-*/
-class WXDLLIMPEXP_PROPGRID wxPGChoiceEntry : public wxPGCell
-{
-public:
-    wxPGChoiceEntry();
-    wxPGChoiceEntry( const wxPGChoiceEntry& entry );
-    wxPGChoiceEntry( const wxString& label,
-                     int value = wxPG_INVALID_VALUE )
-        : wxPGCell(), m_value(value)
+    /**
+        Appends a new child property.
+    */
+    wxPGProperty* AppendChild( wxPGProperty* prop )
     {
     {
-        m_text = label;
+        return InsertChild(-1, prop);
     }
 
     }
 
-    wxPGChoiceEntry( const wxString& label,
-                     int value,
-                     const wxBitmap& bitmap,
-                     const wxColour& fgCol = wxNullColour,
-                     const wxColour& bgCol = wxNullColour )
-        : wxPGCell(label, bitmap, fgCol, bgCol), m_value(value)
-    {
-    }
+    /** Returns height of children, recursively, and
+        by taking expanded/collapsed status into account.
+
+        iMax is used when finding property y-positions.
+    */
+    int GetChildrenHeight( int lh, int iMax = -1 ) const;
 
 
-    virtual ~wxPGChoiceEntry()
+    /** Returns number of child properties */
+    unsigned int GetChildCount() const
     {
     {
+        return (unsigned int) m_children.size();
     }
 
     }
 
-    void SetValue( int value ) { m_value = value; }
+    /** Returns sub-property at index i. */
+    wxPGProperty* Item( unsigned int i ) const
+        { return m_children[i]; }
 
 
-    int GetValue() const { return m_value; }
+    /** Returns last sub-property.
+    */
+    wxPGProperty* Last() const { return m_children.back(); }
 
 
-    bool HasValue() const { return (m_value != wxPG_INVALID_VALUE); }
+    /** Returns index of given child property. */
+    int Index( const wxPGProperty* p ) const;
 
 
-protected:
-    int m_value;
-};
+    // Puts correct indexes to children
+    void FixIndicesOfChildren( unsigned int starthere = 0 );
 
 
+    /**
+        Converts image width into full image offset, with margins.
+    */
+    int GetImageOffset( int imageWidth ) const;
 
 
-typedef void* wxPGChoicesId;
+#ifndef SWIG
+    // Returns wxPropertyGridPageState in which this property resides.
+    wxPropertyGridPageState* GetParentState() const { return m_parentState; }
+#endif
 
 
-class WXDLLIMPEXP_PROPGRID wxPGChoicesData
-{
-    friend class wxPGChoices;
-public:
-    // Constructor sets m_refCount to 1.
-    wxPGChoicesData();
+    wxPGProperty* GetItemAtY( unsigned int y,
+                              unsigned int lh,
+                              unsigned int* nextItemY ) const;
 
 
-    void CopyDataFrom( wxPGChoicesData* data );
+    /** Returns (direct) child property with given name (or NULL if not found).
+    */
+    wxPGProperty* GetPropertyByName( const wxString& name ) const;
 
 
-    // Takes ownership of 'item'
-    void Insert( int index, wxPGChoiceEntry* item )
-    {
-        wxArrayPtrVoid::iterator it;
-        if ( index == -1 )
-        {
-            it = m_items.end();
-            index = m_items.size();
-        }
-        else
-        {
-            it = m_items.begin() + index;
+#ifdef SWIG
+     %extend {
+        DocStr(GetClientData,
+               "Returns the client data object for a property", "");
+        PyObject* GetClientData() {
+            wxPyClientData* data = (wxPyClientData*)self->GetClientObject();
+            if (data) {
+                Py_INCREF(data->m_obj);
+                return data->m_obj;
+            } else {
+                Py_INCREF(Py_None);
+                return Py_None;
+            }
         }
 
         }
 
-        // Need to fix value?
-        if ( item->GetValue() == wxPG_INVALID_VALUE )
-            item->SetValue(index);
-
-        m_items.insert(it, item);
+        DocStr(SetClientData,
+               "Associate the given client data.", "");
+        void SetClientData(PyObject* clientData) {
+            wxPyClientData* data = new wxPyClientData(clientData);
+            self->SetClientObject(data);
+        }
     }
     }
+    %pythoncode {
+         GetClientObject = GetClientData
+         SetClientObject = SetClientData
+    }
+#endif
 
 
-    // Delete all entries
-    void Clear();
-
-    size_t GetCount() const { return m_items.size(); }
-
-    wxPGChoiceEntry* Item( unsigned int i ) const
-    {
-        wxCHECK_MSG( i < GetCount(), NULL, "invalid index" );
+#ifndef SWIG
 
 
-        return (wxPGChoiceEntry*) m_items[i];
-    }
+    // Returns various display-related information for given column
+    void GetDisplayInfo( unsigned int column,
+                         int choiceIndex,
+                         int flags,
+                         wxString* pString,
+                         const wxPGCell** pCell );
 
 
-    void DecRef()
-    {
-        m_refCount--;
-        wxASSERT( m_refCount >= 0 );
-        if ( m_refCount == 0 )
-            delete this;
-    }
+    static wxString*            sm_wxPG_LABEL;
 
 
-private:
-    wxArrayPtrVoid  m_items;
+    /** This member is public so scripting language bindings
+        wrapper code can access it freely.
+    */
+    void*                       m_clientData;
 
 
-    // So that multiple properties can use the same set
-    int             m_refCount;
+protected:
 
 
-    virtual ~wxPGChoicesData();
-};
+    /**
+        Sets property cell in fashion that reduces number of exclusive
+        copies of cell data. Used when setting, for instance, same
+        background colour for a number of properties.
 
 
-#define wxPGChoicesEmptyData    ((wxPGChoicesData*)NULL)
+        @param firstCol
+            First column to affect.
 
 
-#endif // SWIG
+        @param lastCol
+            Last column to affect.
 
 
+        @param preparedCell
+            Pre-prepared cell that is used for those which cell data
+            before this matched unmodCellData.
 
 
-/** @class wxPGChoices
+        @param srcData
+            If unmodCellData did not match, valid cell data from this
+            is merged into cell (usually generating new exclusive copy
+            of cell's data).
 
 
-    Helper class for managing choices of wxPropertyGrid properties.
-    Each entry can have label, value, bitmap, text colour, and background
-    colour.
+        @param unmodCellData
+            If cell's cell data matches this, its cell is now set to
+            preparedCell.
 
 
-    @library{wxpropgrid}
-    @category{propgrid}
-*/
-class WXDLLIMPEXP_PROPGRID wxPGChoices
-{
-public:
-    typedef long ValArrItem;
+        @param ignoreWithFlags
+            Properties with any one of these flags are skipped.
 
 
-    /** Default constructor. */
-    wxPGChoices()
-    {
-        Init();
-    }
+        @param recursively
+            If @true, apply this operation recursively in child properties.
+    */
+    void AdaptiveSetCell( unsigned int firstCol,
+                          unsigned int lastCol,
+                          const wxPGCell& preparedCell,
+                          const wxPGCell& srcData,
+                          wxPGCellData* unmodCellData,
+                          FlagType ignoreWithFlags,
+                          bool recursively );
 
 
-    /** Copy constructor. */
-    wxPGChoices( const wxPGChoices& a )
-    {
-        if ( a.m_data != wxPGChoicesEmptyData )
-        {
-            m_data = a.m_data;
-            m_data->m_refCount++;
-        }
-    }
+    /**
+        Makes sure m_cells has size of column+1 (or more).
+    */
+    void EnsureCells( unsigned int column );
 
 
-    /** Constructor. */
-    wxPGChoices( const wxChar** labels, const long* values = NULL )
-    {
-        Init();
-        Set(labels,values);
-    }
+    /** Returns (direct) child property with given name (or NULL if not found),
+        with hint index.
 
 
-    /** Constructor. */
-    wxPGChoices( const wxArrayString& labels,
-                 const wxArrayInt& values = wxArrayInt() )
-    {
-        Init();
-        Set(labels,values);
-    }
+        @param hintIndex
+        Start looking for the child at this index.
 
 
-    /** Simple interface constructor. */
-    wxPGChoices( wxPGChoicesData* data )
-    {
-        wxASSERT(data);
-        m_data = data;
-        data->m_refCount++;
-    }
+        @remarks
+        Does not support scope (ie. Parent.Child notation).
+    */
+    wxPGProperty* GetPropertyByNameWH( const wxString& name,
+                                       unsigned int hintIndex ) const;
 
 
-    /** Destructor. */
-    ~wxPGChoices()
-    {
-        Free();
-    }
+    /** This is used by Insert etc. */
+    void DoAddChild( wxPGProperty* prop,
+                     int index = -1,
+                     bool correct_mode = true );
 
 
-    /**
-        Adds to current.
+    void DoGenerateComposedValue( wxString& text,
+                                  int argFlags = wxPG_VALUE_IS_CURRENT,
+                                  const wxVariantList* valueOverrides = NULL,
+                                  wxPGHashMapS2S* childResults = NULL ) const;
 
 
-        If did not have own copies, creates them now. If was empty, identical
-        to set except that creates copies.
-    */
-    void Add( const wxChar** labels, const ValArrItem* values = NULL );
+    void DoSetName(const wxString& str) { m_name = str; }
 
 
-    /** Version that works with wxArrayString. */
-    void Add( const wxArrayString& arr, const ValArrItem* values = NULL );
+    /** Deletes all sub-properties. */
+    void Empty();
 
 
-    /** Version that works with wxArrayString and wxArrayInt. */
-    void Add( const wxArrayString& arr, const wxArrayInt& arrint );
+    void InitAfterAdded( wxPropertyGridPageState* pageState,
+                         wxPropertyGrid* propgrid );
 
 
-    /** Adds single item. */
-    wxPGChoiceEntry& Add( const wxString& label,
-                          int value = wxPG_INVALID_VALUE );
+    // Removes child property with given pointer. Does not delete it.
+    void RemoveChild( wxPGProperty* p );
 
 
-    /** Adds a single item, with bitmap. */
-    wxPGChoiceEntry& Add( const wxString& label,
-                          const wxBitmap& bitmap,
-                          int value = wxPG_INVALID_VALUE );
+    void DoPreAddChild( int index, wxPGProperty* prop );
 
 
-    /** Adds a single item with full entry information. */
-    wxPGChoiceEntry& Add( const wxPGChoiceEntry& entry )
-    {
-        return Insert(entry, -1);
-    }
+    void SetParentState( wxPropertyGridPageState* pstate )
+        { m_parentState = pstate; }
 
 
-    /** Adds single item. */
-    wxPGChoiceEntry& AddAsSorted( const wxString& label,
-                                  int value = wxPG_INVALID_VALUE );
+    // Call after fixed sub-properties added/removed after creation.
+    // if oldSelInd >= 0 and < new max items, then selection is
+    // moved to it.
+    void SubPropsChanged( int oldSelInd = -1 );
 
 
-    void Assign( const wxPGChoices& a )
-    {
-        AssignData(a.m_data);
-    }
+    int GetY2( int lh ) const;
 
 
-    void AssignData( wxPGChoicesData* data );
+    wxString                    m_label;
+    wxString                    m_name;
+    wxPGProperty*               m_parent;
+    wxPropertyGridPageState*    m_parentState;
 
 
-    /** Delete all choices. */
-    void Clear()
-    {
-        if ( m_data != wxPGChoicesEmptyData )
-            m_data->Clear();
-    }
+    wxClientData*               m_clientObject;
 
 
-    void EnsureData()
-    {
-        if ( m_data == wxPGChoicesEmptyData )
-            m_data = new wxPGChoicesData();
-    }
+    // Overrides editor returned by property class
+    const wxPGEditor*           m_customEditor;
+#if wxUSE_VALIDATORS
+    // Editor is going to get this validator
+    wxValidator*                m_validator;
+#endif
+    // Show this in front of the value
+    //
+    // TODO: Can bitmap be implemented with wxPGCell?
+    wxBitmap*                   m_valueBitmap;
 
 
-    /** Gets a unsigned number identifying this list. */
-    wxPGChoicesId GetId() const { return (wxPGChoicesId) m_data; };
+    wxVariant                   m_value;
+    wxPGAttributeStorage        m_attributes;
+    wxArrayPGProperty           m_children;
 
 
-    const wxString& GetLabel( size_t ind ) const
-    {
-        return Item(ind).GetText();
-    }
+    // Extended cell information
+    wxVector<wxPGCell>          m_cells;
 
 
-    size_t GetCount () const
-    {
-        wxASSERT_MSG( m_data, "When checking if wxPGChoices is valid, "
-                              "use IsOk() instead of GetCount()" );
-        return m_data->GetCount();
-    }
+    // Choices shown in drop-down list of editor control.
+    wxPGChoices                 m_choices;
 
 
-    int GetValue( size_t ind ) const { return Item(ind).GetValue(); }
+    // Help shown in statusbar or help box.
+    wxString                    m_helpString;
 
 
-    /** Returns array of values matching the given strings. Unmatching strings
-        result in wxPG_INVALID_VALUE entry in array.
-    */
-    wxArrayInt GetValuesForStrings( const wxArrayString& strings ) const;
+    // Index in parent's property array.
+    unsigned int                m_arrIndex;
 
 
-    /** Returns array of indices matching given strings. Unmatching strings
-        are added to 'unmatched', if not NULL.
-    */
-    wxArrayInt GetIndicesForStrings( const wxArrayString& strings,
-                                     wxArrayString* unmatched = NULL ) const;
+    // If not -1, then overrides m_value
+    int                         m_commonValue;
 
 
-    /** Returns true if choices in general are likely to have values
-        (depens on that all entries have values or none has)
-    */
-    bool HasValues() const;
+    FlagType                    m_flags;
 
 
-    bool HasValue( unsigned int i ) const
-        { return (i < m_data->GetCount()) && m_data->Item(i)->HasValue(); }
+    // Maximum length (mainly for string properties). Could be in some sort of
+    // wxBaseStringProperty, but currently, for maximum flexibility and
+    // compatibility, we'll stick it here. Anyway, we had 3 excess bytes to use
+    // so short int will fit in just fine.
+    short                       m_maxLen;
 
 
-    int Index( const wxString& str ) const;
-    int Index( int val ) const;
+    // Root has 0, categories etc. at that level 1, etc.
+    unsigned char               m_depth;
 
 
-    /** Inserts single item. */
-    wxPGChoiceEntry& Insert( const wxString& label,
-                             int index,
-                             int value = wxPG_INVALID_VALUE );
+    // m_depthBgCol indicates width of background colour between margin and item
+    // (essentially this is category's depth, if none then equals m_depth).
+    unsigned char               m_depthBgCol;
 
 
-    /** Inserts a single item with full entry information. */
-    wxPGChoiceEntry& Insert( const wxPGChoiceEntry& entry, int index );
+private:
+    // Called in constructors.
+    void Init();
+    void Init( const wxString& label, const wxString& name );
+#endif // #ifndef SWIG
+};
 
 
-    /** Returns false if this is a constant empty set of choices,
-        which should not be modified.
-    */
-    bool IsOk() const
-    {
-        return ( m_data != wxPGChoicesEmptyData );
-    }
+// -----------------------------------------------------------------------
 
 
-    const wxPGChoiceEntry& Item( unsigned int i ) const
-    {
-        wxASSERT( IsOk() );
-        return *m_data->Item(i);
-    }
+//
+// Property class declaration helper macros
+// (wxPGRootPropertyClass and wxPropertyCategory require this).
+//
 
 
-    wxPGChoiceEntry& Item( unsigned int i )
-    {
-        wxASSERT( IsOk() );
-        return *m_data->Item(i);
-    }
+#define WX_PG_DECLARE_DOGETEDITORCLASS \
+    virtual const wxPGEditor* DoGetEditorClass() const;
 
 
-    /** Removes count items starting at position nIndex. */
-    void RemoveAt(size_t nIndex, size_t count = 1);
+#ifndef SWIG
+    #define WX_PG_DECLARE_PROPERTY_CLASS(CLASSNAME) \
+        public: \
+            DECLARE_DYNAMIC_CLASS(CLASSNAME) \
+            WX_PG_DECLARE_DOGETEDITORCLASS \
+        private:
+#else
+    #define WX_PG_DECLARE_PROPERTY_CLASS(CLASSNAME)
+#endif
+
+// Implements sans constructor function. Also, first arg is class name, not
+// property name.
+#define WX_PG_IMPLEMENT_PROPERTY_CLASS_PLAIN(PROPNAME,T,EDITOR) \
+const wxPGEditor* PROPNAME::DoGetEditorClass() const \
+{ \
+    return wxPGEditor_##EDITOR; \
+}
+
+// -----------------------------------------------------------------------
 
 #ifndef SWIG
 
 #ifndef SWIG
-    /** Does not create copies for itself. */
-    void Set( const wxChar** labels, const long* values = NULL )
-    {
-        Free();
-        Add(labels,values);
-    }
 
 
-    /** Version that works with wxArrayString.
-        TODO: Deprecate this.
-    */
-    void Set( wxArrayString& arr, const long* values = (const long*) NULL )
-    {
-        Free();
-        Add(arr,values);
-    }
-#endif // SWIG
+/** @class wxPGRootProperty
+    @ingroup classes
+    Root parent property.
+*/
+class WXDLLIMPEXP_PROPGRID wxPGRootProperty : public wxPGProperty
+{
+public:
+    WX_PG_DECLARE_PROPERTY_CLASS(wxPGRootProperty)
+public:
 
 
-    /** Version that works with wxArrayString and wxArrayInt. */
-    void Set( const wxArrayString& labels,
-              const wxArrayInt& values = wxArrayInt() )
-    {
-        Free();
-        if ( &values )
-            Add(labels,values);
-        else
-            Add(labels);
-    }
+    /** Constructor. */
+    wxPGRootProperty( const wxString& name = wxS("<Root>") );
+    virtual ~wxPGRootProperty();
 
 
-    // Creates exclusive copy of current choices
-    void SetExclusive()
+    virtual bool StringToValue( wxVariant&, const wxString&, int ) const
     {
     {
-        if ( m_data->m_refCount != 1 )
-        {
-            wxPGChoicesData* data = new wxPGChoicesData();
-            data->CopyDataFrom(m_data);
-            Free();
-            m_data = data;
-        }
+        return false;
     }
 
     }
 
-    // Returns data, increases refcount.
-    wxPGChoicesData* GetData()
-    {
-        wxASSERT( m_data->m_refCount != 0xFFFFFFF );
-        m_data->m_refCount++;
-        return m_data;
-    }
+protected:
+};
 
 
-    // Returns plain data ptr - no refcounting stuff is done.
-    wxPGChoicesData* GetDataPtr() const { return m_data; }
+// -----------------------------------------------------------------------
 
 
-    // Changes ownership of data to you.
-    wxPGChoicesData* ExtractData()
-    {
-        wxPGChoicesData* data = m_data;
-        m_data = wxPGChoicesEmptyData;
-        return data;
-    }
+/** @class wxPropertyCategory
+    @ingroup classes
+    Category (caption) property.
+*/
+class WXDLLIMPEXP_PROPGRID wxPropertyCategory : public wxPGProperty
+{
+    friend class wxPropertyGrid;
+    friend class wxPropertyGridPageState;
+    WX_PG_DECLARE_PROPERTY_CLASS(wxPropertyCategory)
+public:
 
 
-    wxArrayString GetLabels() const;
+    /** Default constructor is only used in special cases. */
+    wxPropertyCategory();
 
 
-#ifndef SWIG
-    void operator= (const wxPGChoices& a)
-    {
-        AssignData(a.m_data);
-    }
+    wxPropertyCategory( const wxString& label,
+                        const wxString& name = wxPG_LABEL );
+    ~wxPropertyCategory();
 
 
-    wxPGChoiceEntry& operator[](unsigned int i)
-    {
-        return Item(i);
-    }
+    int GetTextExtent( const wxWindow* wnd, const wxFont& font ) const;
 
 
-    const wxPGChoiceEntry& operator[](unsigned int i) const
-    {
-        return Item(i);
-    }
+    virtual wxString ValueToString( wxVariant& value, int argFlags ) const;
 
 protected:
 
 protected:
-    wxPGChoicesData*    m_data;
+    void SetTextColIndex( unsigned int colInd )
+        { m_capFgColIndex = (wxByte) colInd; }
+    unsigned int GetTextColIndex() const
+        { return (unsigned int) m_capFgColIndex; }
+
+    void CalculateTextExtent( wxWindow* wnd, const wxFont& font );
+
+    int     m_textExtent;  // pre-calculated length of text
+    wxByte  m_capFgColIndex;  // caption text colour index
 
 
+private:
     void Init();
     void Init();
-    void Free();
-#endif  // !SWIG
 };
 
 };
 
-inline bool wxPGProperty::SetChoices( const wxArrayString& labels,
-                                      const wxArrayInt& values )
-{
-    wxPGChoices chs(labels, values);
-    return SetChoices(chs);
-}
+#endif  // !SWIG
 
 // -----------------------------------------------------------------------
 
 
 // -----------------------------------------------------------------------