]> git.saurik.com Git - wxWidgets.git/commitdiff
Moved wxPGChoices m_choices member from various property classes to base wxPGProperty...
authorJaakko Salli <jaakko.salli@dnainternet.net>
Fri, 19 Sep 2008 16:57:33 +0000 (16:57 +0000)
committerJaakko Salli <jaakko.salli@dnainternet.net>
Fri, 19 Sep 2008 16:57:33 +0000 (16:57 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@55740 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

15 files changed:
docs/doxygen/overviews/propgrid.h
include/wx/propgrid/advprops.h
include/wx/propgrid/property.h
include/wx/propgrid/propgridiface.h
include/wx/propgrid/props.h
interface/wx/propgrid/property.h
interface/wx/propgrid/propgridiface.h
samples/propgrid/propgrid.cpp
samples/propgrid/tests.cpp
src/propgrid/advprops.cpp
src/propgrid/editors.cpp
src/propgrid/property.cpp
src/propgrid/propgrid.cpp
src/propgrid/propgridiface.cpp
src/propgrid/props.cpp

index ba37bc48aa1c4302925a7249a9254312ffbcd10e..c24203017bdbab110dd3bd69f48bc390f138fce8 100644 (file)
@@ -296,8 +296,8 @@ You have to provide list of constant labels, and optionally relevant values
 
 @remarks
 
-- Value wxPG_INVALID_VALUE (equals 2147483647 which usually equals INT_MAX) is not
-  allowed as value.
+- Value wxPG_INVALID_VALUE (equals INT_MAX) is not allowed as list
+  item value.
 
 A very simple example:
 
@@ -365,7 +365,6 @@ Here's extended example using values as well:
     long array_diet_ids[] =
     { 40, 45, 50 };
 
-    // Value can be set from string as well
     pg->Append( new wxEnumProperty(wxT("Diet"),
                                    wxPG_LABEL,
                                    array_diet,
@@ -394,45 +393,26 @@ Here's extended example using values as well:
 
     // Note: you can add even whole arrays to wxPGChoices
 
-    pg->Append( new wxEnumProperty(wxT("Diet"),
+    pg->Append( new wxEnumProperty(wxT("Primary Diet"),
                                    wxPG_LABEL,
                                    chs) );
 
     // Add same choices to another property as well - this is efficient due
     // to reference counting
-    pg->Append( new wxEnumProperty(wxT("Diet 2"),
+    pg->Append( new wxEnumProperty(wxT("Secondary Diet"),
                                    wxPG_LABEL,
                                    chs) );
 
- @endcode
-
-If you later need to change choices used by a property, there is function
-for that as well.
-
-@code
-
-    //
-    // Example 1: Add one extra item
-    wxPGChoices& choices = pg->GetPropertyChoices(wxT("Diet"));
-    choices.Add(wxT("Custom"),55);
-
-    //
-    // Example 2: Replace all the choices
-    wxPGChoices chs;
-    chs.Add(wxT("<No valid items yet>"),0);
-    pg->SetPropertyChoices(wxT("Diet"),chs);
-
 @endcode
 
-If you want to create your enum properties with simple (label,name,value)
-constructor, then you need to create a new property class using one of the
-supplied macro pairs. See @ref pgproperty_creating for details.
+You can later change choices of property by using wxPGProperty::InsertChoice(),
+wxPGProperty::DeleteChoice(), and wxPGProperty::SetChoices().
 
 <b>wxEditEnumProperty</b> is works exactly like wxEnumProperty, except
 is uses non-readonly combobox as default editor, and value is stored as
 string when it is not any of the choices.
 
-wxFlagsProperty is similar:
+wxFlagsProperty has similar construction:
 
 @code
 
@@ -454,8 +434,8 @@ wxFlagsProperty is similar:
 wxFlagsProperty can use wxPGChoices just the same way as wxEnumProperty
 (and also custom property classes can be created with similar macro pairs).
 <b>Note: </b> When changing "choices" (ie. flag labels) of wxFlagsProperty,
-you will need to use SetPropertyChoices - otherwise they will not get updated
-properly.
+you will need to use wxPGProperty::SetChoices() to replace all choices
+at once - otherwise they will not get updated properly.
 
 @section propgrid_advprops Specialized Properties
 
@@ -839,7 +819,7 @@ each cell in the property grid. Use wxPropertyGridInterface::SetPropertyCell() o
 wxPGProperty::SetCell() for this purpose.
 
 In addition, it is possible to control these characteristics for
-wxPGChoices list items. See wxPGChoices::Item() and wxPGChoiceEntry class
+wxPGChoices list items. See wxPGChoices class
 reference for more info.
 
 
@@ -1049,8 +1029,8 @@ unique (base) name.
         pg->SetPropertyAttribute(wxT("MyFlagsProperty"),wxPG_BOOL_USE_CHECKBOX,true,wxPG_RECURSE);
     @endcode
 
-  - Default item names for wxBoolProperty are [wxT("False"),wxT("True")]. This can be
-    changed using wxPropertyGrid::SetBoolChoices(trueChoice,falseChoice).
+  - Default item names for wxBoolProperty are ["False", "True"]. This can be
+    changed using wxPropertyGrid::SetBoolChoices(trueChoice, falseChoice).
 
 @subsection propgrid_textctrlupdates Updates from wxTextCtrl Based Editor
 
index a3fb60dd83226e850b9c8376f4e9243adfcd536f..a73c0d3c7656b36d5dabef32019970b3f8342f21 100644 (file)
@@ -372,8 +372,6 @@ public:
                                int argFlags = 0) const;
     WX_PG_DECLARE_EVENT_METHODS()
 
-    virtual int GetChoiceInfo( wxPGChoiceInfo* choiceinfo );
-
     wxArrayInt GetValueAsArrayInt() const
     {
         return m_choices.GetValuesForStrings(m_value.GetArrayString());
@@ -388,8 +386,6 @@ protected:
 
     wxArrayString       m_valueAsStrings;  // Value as array of strings
 
-    wxPGChoices         m_choices;
-
     // Cache displayed text since generating it is relatively complicated.
     wxString            m_display;
 };
index 593de4b4678d21abe91a3057afc30350dc881940..cd4ec9f2afdb2d888e4f445852b834da7fe6b4e9 100644 (file)
@@ -47,13 +47,6 @@ struct wxPGPaintData
 };
 
 
-// Structure for relaying choice/list info.
-struct wxPGChoiceInfo
-{
-    wxPGChoices*    m_choices;
-};
-
-
 #ifndef SWIG
 
 
@@ -567,1633 +560,1619 @@ 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:
-    typedef wxUint32 FlagType;
-
-    /** Basic constructor.
-    */
-    wxPGProperty();
-
-    /** Constructor.
-        Non-abstract property classes should have constructor of this style:
+    wxPGChoiceEntry();
+    wxPGChoiceEntry( const wxPGChoiceEntry& entry );
+    wxPGChoiceEntry( const wxString& label,
+                     int value = wxPG_INVALID_VALUE )
+        : wxPGCell(), m_value(value)
+    {
+        m_text = label;
+    }
 
-        @code
+    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)
+    {
+    }
 
-        // 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);
+    virtual ~wxPGChoiceEntry()
+    {
+    }
 
-            // If has private child properties then create them here, e.g.:
-            //     AddChild( new wxStringProperty( "Subprop 1",
-            //                                     wxPG_LABEL,
-            //                                     value.GetSubProp1() ) );
-        }
+    void SetValue( int value ) { m_value = value; }
 
-        @endcode
-    */
-    wxPGProperty( const wxString& label, const wxString& name );
+    int GetValue() const { return m_value; }
 
-    /**
-        Virtual destructor.
-        It is customary for derived properties to implement this.
-    */
-    virtual ~wxPGProperty();
+    bool HasValue() const { return (m_value != wxPG_INVALID_VALUE); }
 
-    /** This virtual function is called after m_value has been set.
+protected:
+    int m_value;
+};
 
-        @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; }
+typedef void* wxPGChoicesId;
 
-#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.
+class WXDLLIMPEXP_PROPGRID wxPGChoicesData
+{
+    friend class wxPGChoices;
+public:
+    // Constructor sets m_refCount to 1.
+    wxPGChoicesData();
 
-        @remarks
-        - Default implementation always returns true.
-    */
-    virtual bool ValidateValue( wxVariant& value,
-                                wxPGValidationInfo& validationInfo ) const;
+    void CopyDataFrom( wxPGChoicesData* data );
 
-    /**
-        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).
+    // 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;
+        }
 
-        @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;
+        // Need to fix value?
+        if ( item->GetValue() == wxPG_INVALID_VALUE )
+            item->SetValue(index);
 
-    /**
-        Converts 'number' (including choice selection) into proper value
-        'variant'.
+        m_items.insert(it, item);
+    }
 
-        Returns true if new (different than m_value) value could be interpreted
-        from the integer.
+    // Delete all entries
+    void Clear();
 
-        @param argFlags
-            If wxPG_FULL_VALUE is set, returns complete, storable value instead
-            of displayable one.
+    size_t GetCount() const { return m_items.size(); }
 
-        @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)
+    wxPGChoiceEntry* Item( unsigned int i ) const
+    {
+        wxCHECK_MSG( i < GetCount(), NULL, "invalid index" );
 
-public:
-    /** Returns text representation of property's value.
+        return (wxPGChoiceEntry*) m_items[i];
+    }
 
-        @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.
+    void DecRef()
+    {
+        m_refCount--;
+        wxASSERT( m_refCount >= 0 );
+        if ( m_refCount == 0 )
+            delete this;
+    }
 
-        @remarks
-        Default implementation returns string composed from text
-        representations of child properties.
-    */
-    virtual wxString GetValueAsString( int argFlags = 0 ) const;
+private:
+    wxArrayPtrVoid  m_items;
 
-    /** 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 );
+    // So that multiple properties can use the same set
+    int             m_refCount;
 
-    /** 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 );
+    virtual ~wxPGChoicesData();
+};
 
-    /**
-        Returns size of the custom painted image in front of property.
+#define wxPGChoicesEmptyData    ((wxPGChoicesData*)NULL)
 
-        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;
+#endif // SWIG
 
-    /**
-        Events received by editor widgets are processed here.
+/** @class wxPGChoices
 
-        Note that editor class usually processes most events. Some, such as
-        button press events of TextCtrlAndButton class, can be handled here.
-        Also, if custom handling for regular events is desired, then that can
-        also be done (for example, wxSystemColourProperty custom handles
-        wxEVT_COMMAND_CHOICE_SELECTED to display colour picker dialog when
-        'custom' selection is made).
+    Helper class for managing choices of wxPropertyGrid properties.
+    Each entry can have label, value, bitmap, text colour, and background
+    colour.
 
-        If the event causes value to be changed, SetValueInEvent()
-        should be called to set the new value.
+    @library{wxpropgrid}
+    @category{propgrid}
+*/
+class WXDLLIMPEXP_PROPGRID wxPGChoices
+{
+public:
+    typedef long ValArrItem;
 
-        @param event
-        Associated wxEvent.
-        @return
-        Should return true if any changes in value should be reported.
-        @remarks
-        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 OnEvent( wxPropertyGrid* propgrid,
-                          wxWindow* wnd_primary,
-                          wxEvent& event );
+    /** Default constructor. */
+    wxPGChoices()
+    {
+        Init();
+    }
 
-    /**
-        Called after value of a child property has been altered.
+    /** Copy constructor. */
+    wxPGChoices( const wxPGChoices& a )
+    {
+        if ( a.m_data != wxPGChoicesEmptyData )
+        {
+            m_data = a.m_data;
+            m_data->m_refCount++;
+        }
+    }
 
-        Note that this function is usually called at the time that value of
-        this property, or given child property, is still pending for change.
+    /** Constructor. */
+    wxPGChoices( const wxChar** labels, const long* values = NULL )
+    {
+        Init();
+        Set(labels,values);
+    }
 
-        Sample pseudo-code implementation:
+    /** Constructor. */
+    wxPGChoices( const wxArrayString& labels,
+                 const wxArrayInt& values = wxArrayInt() )
+    {
+        Init();
+        Set(labels,values);
+    }
 
-        @code
-        void MyProperty::ChildChanged( wxVariant& thisValue,
-                                       int childIndex,
-                                       wxVariant& childValue ) const
-        {
-            // Acquire reference to actual type of data stored in variant
-            // (TFromVariant only exists if wxPropertyGrid's wxVariant-macros
-            // were used to create the variant class).
-            T& data = TFromVariant(thisValue);
+    /** Simple interface constructor. */
+    wxPGChoices( wxPGChoicesData* data )
+    {
+        wxASSERT(data);
+        m_data = data;
+        data->m_refCount++;
+    }
 
-            // Copy childValue into data.
-            switch ( childIndex )
-            {
-                case 0:
-                    data.SetSubProp1( childvalue.GetLong() );
-                    break;
-                case 1:
-                    data.SetSubProp2( childvalue.GetString() );
-                    break;
-                ...
-            }
-        }
-        @endcode
+    /** Destructor. */
+    ~wxPGChoices()
+    {
+        Free();
+    }
 
-        @param thisValue
-            Value of this property, that should be altered.
-        @param childIndex
-            Index of child changed (you can use Item(childIndex) to get).
-        @param childValue
-            Value of the child property.
-    */
-    virtual void ChildChanged( wxVariant& thisValue,
-                               int childIndex,
-                               wxVariant& childValue ) const;
+    /**
+        Adds to current.
 
-    /** Returns pointer to an instance of used editor.
+        If did not have own copies, creates them now. If was empty, identical
+        to set except that creates copies.
     */
-    virtual const wxPGEditor* DoGetEditorClass() const;
-
-    /** Returns pointer to the wxValidator that should be used
-        with the editor of this property (NULL for no validator).
-        Setting validator explicitly via SetPropertyValidator
-        will override this.
-
-        In most situations, code like this should work well
-        (macros are used to maintain one actual validator instance,
-        so on the second call the function exits within the first
-        macro):
+    void Add( const wxChar** labels, const ValArrItem* values = NULL );
 
-        @code
+    /** Version that works with wxArrayString. */
+    void Add( const wxArrayString& arr, const ValArrItem* values = NULL );
 
-        wxValidator* wxMyPropertyClass::DoGetValidator () const
-        {
-            WX_PG_DOGETVALIDATOR_ENTRY()
+    /** Version that works with wxArrayString and wxArrayInt. */
+    void Add( const wxArrayString& arr, const wxArrayInt& arrint );
 
-            wxMyValidator* validator = new wxMyValidator(...);
+    /** Adds single item. */
+    wxPGChoiceEntry& Add( const wxString& label,
+                          int value = wxPG_INVALID_VALUE );
 
-            ... prepare validator...
+    /** Adds a single item, with bitmap. */
+    wxPGChoiceEntry& Add( const wxString& label,
+                          const wxBitmap& bitmap,
+                          int value = wxPG_INVALID_VALUE );
 
-            WX_PG_DOGETVALIDATOR_EXIT(validator)
-        }
+    /** Adds a single item with full entry information. */
+    wxPGChoiceEntry& Add( const wxPGChoiceEntry& entry )
+    {
+        return Insert(entry, -1);
+    }
 
-        @endcode
+    /** Adds single item. */
+    wxPGChoiceEntry& AddAsSorted( const wxString& label,
+                                  int value = wxPG_INVALID_VALUE );
 
-        @remarks
-        You can get common filename validator by returning
-        wxFileProperty::GetClassValidator(). wxDirProperty,
-        for example, uses it.
-    */
-    virtual wxValidator* DoGetValidator () const;
+    void Assign( const wxPGChoices& a )
+    {
+        AssignData(a.m_data);
+    }
 
-    /**
-        Returns current value's index to the choice control.
+    void AssignData( wxPGChoicesData* data );
 
-        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.
+    /** Delete all choices. */
+    void Clear()
+    {
+        if ( m_data != wxPGChoicesEmptyData )
+            m_data->Clear();
+    }
 
-        @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 );
+    void EnsureData()
+    {
+        if ( m_data == wxPGChoicesEmptyData )
+            m_data = new wxPGChoicesData();
+    }
 
-    /**
-        Override to paint an image in front of the property value text or
-        drop-down list item (but only if wxPGProperty::OnMeasureImage is
-        overridden as well).
+    /** Gets a unsigned number identifying this list. */
+    wxPGChoicesId GetId() const { return (wxPGChoicesId) m_data; };
 
-        If property's OnMeasureImage() returns size that has height != 0 but
-        less than row height ( < 0 has special meanings), wxPropertyGrid calls
-        this method to draw a custom image in a limited area in front of the
-        editor control or value text/graphics, and if control has drop-down
-        list, then the image is drawn there as well (even in the case
-        OnMeasureImage() returned higher height than row height).
+    const wxString& GetLabel( size_t ind ) const
+    {
+        return Item(ind).GetText();
+    }
 
-        NOTE: Following applies when OnMeasureImage() returns a "flexible"
-        height ( using wxPG_FLEXIBLE_SIZE(W,H) macro), which implies variable
-        height items: If rect.x is < 0, then this is a measure item call, which
-        means that dc is invalid and only thing that should be done is to set
-        paintdata.m_drawnHeight to the height of the image of item at index
-        paintdata.m_choiceItem. This call may be done even as often as once
-        every drop-down popup show.
+    size_t GetCount () const
+    {
+        if ( !m_data )
+            return 0;
 
-        @param dc
-            wxDC to paint on.
-        @param rect
-            Box reserved for custom graphics. Includes surrounding rectangle,
-            if any. If x is < 0, then this is a measure item call (see above).
-        @param paintdata
-            wxPGPaintData structure with much useful data.
+        return m_data->GetCount();
+    }
 
-        @remarks
-            - You can actually exceed rect width, but if you do so then
-              paintdata.m_drawnWidth must be set to the full width drawn in
-              pixels.
-            - Due to technical reasons, rect's height will be default even if
-              custom height was reported during measure call.
-            - Brush is guaranteed to be default background colour. It has been
-              already used to clear the background of area being painted. It
-              can be modified.
-            - Pen is guaranteed to be 1-wide 'black' (or whatever is the proper
-              colour) pen for drawing framing rectangle. It can be changed as
-              well.
+    int GetValue( size_t ind ) const { return Item(ind).GetValue(); }
 
-        @see GetValueAsString()
+    /** Returns array of values matching the given strings. Unmatching strings
+        result in wxPG_INVALID_VALUE entry in array.
     */
-    virtual void OnCustomPaint( wxDC& dc,
-                                const wxRect& rect,
-                                wxPGPaintData& paintdata );
+    wxArrayInt GetValuesForStrings( const wxArrayString& strings ) const;
 
-    /**
-        Returns used wxPGCellRenderer instance for given property column
-        (label=0, value=1).
+    /** 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;
 
-        Default implementation returns editor's renderer for all columns.
+    /** Returns true if choices in general are likely to have values
+        (depens on that all entries have values or none has)
     */
-    virtual wxPGCellRenderer* GetCellRenderer( int column ) const;
+    bool HasValues() const;
 
-    /**
-        Refresh values of child properties.
+    bool HasValue( unsigned int i ) const
+        { return (i < m_data->GetCount()) && m_data->Item(i)->HasValue(); }
 
-        Automatically called after value is set.
-    */
-    virtual void RefreshChildren();
+    int Index( const wxString& str ) const;
+    int Index( int val ) const;
 
-    /** Special handling for attributes of this property.
+    /** Inserts single item. */
+    wxPGChoiceEntry& Insert( const wxString& label,
+                             int index,
+                             int value = wxPG_INVALID_VALUE );
 
-        If returns false, then the attribute will be automatically stored in
-        m_attributes.
+    /** Inserts a single item with full entry information. */
+    wxPGChoiceEntry& Insert( const wxPGChoiceEntry& entry, int index );
 
-        Default implementation simply returns false.
+    /** Returns false if this is a constant empty set of choices,
+        which should not be modified.
     */
-    virtual bool DoSetAttribute( const wxString& name, wxVariant& value );
+    bool IsOk() const
+    {
+        return ( m_data != wxPGChoicesEmptyData );
+    }
 
-    /** Returns value of an attribute.
+    const wxPGChoiceEntry& Item( unsigned int i ) const
+    {
+        wxASSERT( IsOk() );
+        return *m_data->Item(i);
+    }
 
-        Override if custom handling of attributes is needed.
+    wxPGChoiceEntry& Item( unsigned int i )
+    {
+        wxASSERT( IsOk() );
+        return *m_data->Item(i);
+    }
 
-        Default implementation simply return NULL variant.
-    */
-    virtual wxVariant DoGetAttribute( const wxString& name ) const;
+    /** Removes count items starting at position nIndex. */
+    void RemoveAt(size_t nIndex, size_t count = 1);
 
-    /** Returns instance of a new wxPGEditorDialogAdapter instance, which is
-        used when user presses the (optional) button next to the editor control;
+#ifndef SWIG
+    /** Does not create copies for itself. */
+    void Set( const wxChar** labels, const long* values = NULL )
+    {
+        Free();
+        Add(labels,values);
+    }
 
-        Default implementation returns NULL (ie. no action is generated when
-        button is pressed).
+    /** Version that works with wxArrayString.
+        TODO: Deprecate this.
     */
-    virtual wxPGEditorDialogAdapter* GetEditorDialog() const;
+    void Set( wxArrayString& arr, const long* values = (const long*) NULL )
+    {
+        Free();
+        Add(arr,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 SetExclusive()
+    {
+        if ( m_data->m_refCount != 1 )
+        {
+            wxPGChoicesData* data = new wxPGChoicesData();
+            data->CopyDataFrom(m_data);
+            Free();
+            m_data = data;
+        }
+    }
+
+    // Returns data, increases refcount.
+    wxPGChoicesData* GetData()
+    {
+        wxASSERT( m_data->m_refCount != 0xFFFFFFF );
+        m_data->m_refCount++;
+        return m_data;
+    }
 
-    /**
-        Adds entry to property's wxPGChoices and editor control (if it is
-        active).
+    // Returns plain data ptr - no refcounting stuff is done.
+    wxPGChoicesData* GetDataPtr() const { return m_data; }
 
-        Returns index of item added.
-    */
-    int AppendChoice( const wxString& label, int value = wxPG_INVALID_VALUE )
+    // Changes ownership of data to you.
+    wxPGChoicesData* ExtractData()
     {
-        return InsertChoice(label,-1,value);
+        wxPGChoicesData* data = m_data;
+        m_data = wxPGChoicesEmptyData;
+        return data;
     }
 
-    /** Returns wxPGCell of given column, NULL if none. If valid
-        object is returned, caller will gain its ownership.
-    */
-    wxPGCell* AcquireCell( unsigned int column )
-    {
-        if ( column >= m_cells.size() )
-            return NULL;
+    wxArrayString GetLabels() const;
 
-        wxPGCell* cell = (wxPGCell*) m_cells[column];
-        m_cells[column] = NULL;
-        return cell;
+#ifndef SWIG
+    void operator= (const wxPGChoices& a)
+    {
+        AssignData(a.m_data);
     }
 
-    /**
-        Returns true if children of this property are component values (for
-        instance, points size, face name, and is_underlined are component
-        values of a font).
-    */
-    bool AreChildrenComponents() const
+    wxPGChoiceEntry& operator[](unsigned int i)
     {
-        if ( m_flags & (wxPG_PROP_COMPOSED_VALUE|wxPG_PROP_AGGREGATE) )
-            return true;
-
-        return false;
+        return Item(i);
     }
 
-    /**
-        Removes entry from property's wxPGChoices and editor control (if it is
-        active).
-
-        If selected item is deleted, then the value is set to unspecified.
-    */
-    void DeleteChoice( int index );
-
-    /**
-        Call to enable or disable usage of common value (integer value that can
-        be selected for properties instead of their normal values) for this
-        property.
-
-        Common values are disabled by the default for all properties.
-    */
-    void EnableCommonValue( bool enable = true )
+    const wxPGChoiceEntry& operator[](unsigned int i) const
     {
-        if ( enable ) SetFlag( wxPG_PROP_USES_COMMON_VALUE );
-        else ClearFlag( wxPG_PROP_USES_COMMON_VALUE );
+        return Item(i);
     }
 
-    /** Composes text from values of child properties. */
-    void GenerateComposedValue( wxString& text, int argFlags = 0 ) const;
-
-    /** Returns property's label. */
-    const wxString& GetLabel() const { return m_label; }
-
-    /** Returns property's name with all (non-category, non-root) parents. */
-    wxString GetName() const;
-
-    /**
-        Returns property's base name (ie parent's name is not added in any
-        case)
-     */
-    const wxString& GetBaseName() const { return m_name; }
+protected:
+    wxPGChoicesData*    m_data;
 
-    wxPGChoices& GetChoices();
+    void Init();
+    void Free();
+#endif  // !SWIG
+};
 
-    const wxPGChoices& GetChoices() const;
+// -----------------------------------------------------------------------
 
-    const wxPGChoiceEntry* GetCurrentChoice() const;
+/** @class wxPGProperty
 
-    /** Returns coordinate to the top y of the property. Note that the
-        position of scrollbars is not taken into account.
-    */
-    int GetY() const;
+    wxPGProperty is base class for all wxPropertyGrid properties.
 
-    wxVariant GetValue() const
-    {
-        return DoGetValue();
-    }
+    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
-    /** Returns reference to the internal stored value. GetValue is preferred
-        way to get the actual value, since GetValueRef ignores DoGetValue,
-        which may override stored value.
-    */
-    wxVariant& GetValueRef()
-    {
-        return m_value;
-    }
-
-    const wxVariant& GetValueRef() const
-    {
-        return m_value;
-    }
+    DECLARE_ABSTRACT_CLASS(wxPGProperty)
 #endif
+public:
+    typedef wxUint32 FlagType;
 
-    /** Same as GetValueAsString, except takes common value into account.
+    /** Basic constructor.
     */
-    wxString GetValueString( int argFlags = 0 ) const;
+    wxPGProperty();
 
-    void UpdateControl( wxWindow* primary );
+    /** Constructor.
+        Non-abstract property classes should have constructor of this style:
 
-    /** Returns wxPGCell of given column, NULL if none. wxPGProperty
-        will retain ownership of the cell object.
-    */
-    wxPGCell* GetCell( unsigned int column ) const
-    {
-        if ( column >= m_cells.size() )
-            return NULL;
+        @code
 
-        return (wxPGCell*) m_cells[column];
-    }
+        // 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);
 
-    unsigned int GetChoiceCount() const;
+            // If has private child properties then create them here, e.g.:
+            //     AddChild( new wxStringProperty( "Subprop 1",
+            //                                     wxPG_LABEL,
+            //                                     value.GetSubProp1() ) );
+        }
 
-    wxString GetChoiceString( unsigned int index );
+        @endcode
+    */
+    wxPGProperty( const wxString& label, const wxString& name );
 
-    /** Return number of displayed common values for this property.
+    /**
+        Virtual destructor.
+        It is customary for derived properties to implement this.
     */
-    int GetDisplayedCommonValueCount() const;
+    virtual ~wxPGProperty();
 
-    wxString GetDisplayedString() const
-    {
-        return GetValueString(0);
-    }
+    /** This virtual function is called after m_value has been set.
 
-    /** Returns property grid where property lies. */
-    wxPropertyGrid* GetGrid() const;
+        @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();
 
-    /** Returns owner wxPropertyGrid, but only if one is currently on a page
-        displaying this property. */
-    wxPropertyGrid* GetGridIfDisplayed() const;
+    /** 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.
 
-    /** Returns highest level non-category, non-root parent. Useful when you
-        have nested wxCustomProperties/wxParentProperties.
         @remarks
-        Thus, if immediate parent is root or category, this will return the
-        property itself.
+        - Default implementation always returns true.
     */
-    wxPGProperty* GetMainParent() const;
-
-    /** Return parent of property */
-    wxPGProperty* GetParent() const { return m_parent; }
+    virtual bool ValidateValue( wxVariant& value,
+                                wxPGValidationInfo& validationInfo ) const;
 
-    /** Returns true if property has editable wxTextCtrl when selected.
+    /**
+        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).
 
         @remarks
-        Altough disabled properties do not displayed editor, they still
-        return True here as being disabled is considered a temporary
-        condition (unlike being read-only or having limited editing enabled).
+        Default implementation converts semicolon delimited tokens into child
+        values. Only works for properties with children.
     */
-    bool IsTextEditable() const;
+    virtual bool StringToValue( wxVariant& variant,
+                                const wxString& text,
+                                int argFlags = 0 ) const;
 
-    bool IsValueUnspecified() const
-    {
-        return m_value.IsNull();
-    }
+    /**
+        Converts 'number' (including choice selection) into proper value
+        'variant'.
 
-    FlagType HasFlag( FlagType flag ) const
-    {
-        return ( m_flags & flag );
-    }
+        Returns true if new (different than m_value) value could be interpreted
+        from the integer.
 
-    /** Returns comma-delimited string of property attributes.
-    */
-    const wxPGAttributeStorage& GetAttributes() const
-    {
-        return m_attributes;
-    }
+        @param argFlags
+            If wxPG_FULL_VALUE is set, returns complete, storable value instead
+            of displayable one.
 
-    /** Returns m_attributes as list wxVariant.
+        @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.
     */
-    wxVariant GetAttributesAsList() const;
-
-    FlagType GetFlags() const
-    {
-        return m_flags;
-    }
+    virtual bool IntToValue( wxVariant& value,
+                             int number,
+                             int argFlags = 0 ) const;
+#endif  // !defined(SWIG) || defined(CREATE_VCW)
 
-    const wxPGEditor* GetEditorClass() const;
+public:
+    /** Returns text representation of property's value.
 
-    wxString GetValueType() const
-    {
-        return m_value.GetType();
-    }
+        @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.
 
-    /** Returns editor used for given column. NULL for no editor.
+        @remarks
+        Default implementation returns string composed from text
+        representations of child properties.
     */
-    const wxPGEditor* GetColumnEditor( int column ) const
-    {
-        if ( column == 1 )
-            return GetEditorClass();
-
-        return NULL;
-    }
+    virtual wxString GetValueAsString( int argFlags = 0 ) const;
 
-    /** Returns common value selected for this property. -1 for none.
+    /** 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.
     */
-    int GetCommonValue() const
-    {
-        return m_commonValue;
-    }
+    bool SetValueFromString( const wxString& text, int flags = 0 );
 
-    /** Returns true if property has even one visible child.
+    /** 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 HasVisibleChildren() const;
+    bool SetValueFromInt( long value, int flags = 0 );
 
     /**
-        Adds entry to property's wxPGChoices and editor control (if it is
-        active).
+        Returns size of the custom painted image in front of property.
 
-        Returns index of item added.
+        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).
     */
-    int InsertChoice( const wxString& label,
-                      int index,
-                      int value = wxPG_INVALID_VALUE );
+    virtual wxSize OnMeasureImage( int item = -1 ) const;
 
     /**
-        Returns true if this property is actually a wxPropertyCategory.
-    */
-    bool IsCategory() const { return HasFlag(wxPG_PROP_CATEGORY)?true:false; }
+        Events received by editor widgets are processed here.
 
-    /** Returns true if this property is actually a wxRootProperty.
-    */
-    bool IsRoot() const { return (m_parent == NULL); }
+        Note that editor class usually processes most events. Some, such as
+        button press events of TextCtrlAndButton class, can be handled here.
+        Also, if custom handling for regular events is desired, then that can
+        also be done (for example, wxSystemColourProperty custom handles
+        wxEVT_COMMAND_CHOICE_SELECTED to display colour picker dialog when
+        'custom' selection is made).
 
-    /** Returns true if this is a sub-property. */
-    bool IsSubProperty() const
-    {
-        wxPGProperty* parent = (wxPGProperty*)m_parent;
-        if ( parent && !parent->IsCategory() )
-            return true;
-        return false;
-    }
+        If the event causes value to be changed, SetValueInEvent()
+        should be called to set the new value.
 
-    /** Returns last visible sub-property, recursively.
+        @param event
+        Associated wxEvent.
+        @return
+        Should return true if any changes in value should be reported.
+        @remarks
+        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.
     */
-    const wxPGProperty* GetLastVisibleSubItem() const;
+    virtual bool OnEvent( wxPropertyGrid* propgrid,
+                          wxWindow* wnd_primary,
+                          wxEvent& event );
 
-    wxVariant GetDefaultValue() const;
+    /**
+        Called after value of a child property has been altered.
 
-    int GetMaxLength() const
-    {
-        return (int) m_maxLen;
-    }
+        Note that this function is usually called at the time that value of
+        this property, or given child property, is still pending for change.
 
-    /**
-        Determines, recursively, if all children are not unspecified.
+        Sample pseudo-code implementation:
 
-        Takes values in given list into account.
-    */
-    bool AreAllChildrenSpecified( wxVariant* pendingList = NULL ) const;
+        @code
+        void MyProperty::ChildChanged( wxVariant& thisValue,
+                                       int childIndex,
+                                       wxVariant& childValue ) const
+        {
+            // Acquire reference to actual type of data stored in variant
+            // (TFromVariant only exists if wxPropertyGrid's wxVariant-macros
+            // were used to create the variant class).
+            T& data = TFromVariant(thisValue);
 
-    /** Updates composed values of parent non-category properties, recursively.
-        Returns topmost property updated.
+            // Copy childValue into data.
+            switch ( childIndex )
+            {
+                case 0:
+                    data.SetSubProp1( childvalue.GetLong() );
+                    break;
+                case 1:
+                    data.SetSubProp2( childvalue.GetString() );
+                    break;
+                ...
+            }
+        }
+        @endcode
 
-        @remarks
-        - Must not call SetValue() (as can be called in it).
+        @param thisValue
+            Value of this property, that should be altered.
+        @param childIndex
+            Index of child changed (you can use Item(childIndex) to get).
+        @param childValue
+            Value of the child property.
     */
-    wxPGProperty* UpdateParentValues();
+    virtual void ChildChanged( wxVariant& thisValue,
+                               int childIndex,
+                               wxVariant& childValue ) const;
 
-    /** Returns true if containing grid uses wxPG_EX_AUTO_UNSPECIFIED_VALUES.
+    /** Returns pointer to an instance of used editor.
     */
-    FlagType UsesAutoUnspecified() const
-    {
-        return HasFlag(wxPG_PROP_AUTO_UNSPECIFIED);
-    }
+    virtual const wxPGEditor* DoGetEditorClass() const;
 
-    wxBitmap* GetValueImage() const
-    {
-        return m_valueBitmap;
-    }
+    /** Returns pointer to the wxValidator that should be used
+        with the editor of this property (NULL for no validator).
+        Setting validator explicitly via SetPropertyValidator
+        will override this.
 
-    wxVariant GetAttribute( const wxString& name ) const;
+        In most situations, code like this should work well
+        (macros are used to maintain one actual validator instance,
+        so on the second call the function exits within the first
+        macro):
 
-    /**
-        Returns named attribute, as string, if found.
+        @code
 
-        Otherwise defVal is returned.
-    */
-    wxString GetAttribute( const wxString& name, const wxString& defVal ) const;
+        wxValidator* wxMyPropertyClass::DoGetValidator () const
+        {
+            WX_PG_DOGETVALIDATOR_ENTRY()
 
-    /**
-        Returns named attribute, as long, if found.
+            wxMyValidator* validator = new wxMyValidator(...);
 
-        Otherwise defVal is returned.
-    */
-    long GetAttributeAsLong( const wxString& name, long defVal ) const;
+            ... prepare validator...
 
-    /**
-        Returns named attribute, as double, if found.
+            WX_PG_DOGETVALIDATOR_EXIT(validator)
+        }
 
-        Otherwise defVal is returned.
+        @endcode
+
+        @remarks
+        You can get common filename validator by returning
+        wxFileProperty::GetClassValidator(). wxDirProperty,
+        for example, uses it.
     */
-    double GetAttributeAsDouble( const wxString& name, double defVal ) const;
+    virtual wxValidator* DoGetValidator () const;
 
-    unsigned int GetArrIndex() const { return m_arrIndex; }
+    /**
+        Override to paint an image in front of the property value text or
+        drop-down list item (but only if wxPGProperty::OnMeasureImage is
+        overridden as well).
 
-    unsigned int GetDepth() const { return (unsigned int)m_depth; }
+        If property's OnMeasureImage() returns size that has height != 0 but
+        less than row height ( < 0 has special meanings), wxPropertyGrid calls
+        this method to draw a custom image in a limited area in front of the
+        editor control or value text/graphics, and if control has drop-down
+        list, then the image is drawn there as well (even in the case
+        OnMeasureImage() returned higher height than row height).
 
-    /** Gets flags as a'|' delimited string. Note that flag names are not
-        prepended with 'wxPG_PROP_'.
-        @param flagsMask
-        String will only be made to include flags combined by this parameter.
-    */
-    wxString GetFlagsAsString( FlagType flagsMask ) const;
+        NOTE: Following applies when OnMeasureImage() returns a "flexible"
+        height ( using wxPG_FLEXIBLE_SIZE(W,H) macro), which implies variable
+        height items: If rect.x is < 0, then this is a measure item call, which
+        means that dc is invalid and only thing that should be done is to set
+        paintdata.m_drawnHeight to the height of the image of item at index
+        paintdata.m_choiceItem. This call may be done even as often as once
+        every drop-down popup show.
 
-    /** Returns position in parent's array. */
-    unsigned int GetIndexInParent() const
-    {
-        return (unsigned int)m_arrIndex;
-    }
+        @param dc
+            wxDC to paint on.
+        @param rect
+            Box reserved for custom graphics. Includes surrounding rectangle,
+            if any. If x is < 0, then this is a measure item call (see above).
+        @param paintdata
+            wxPGPaintData structure with much useful data.
 
-    /** Hides or reveals the property.
-        @param hide
-            true for hide, false for reveal.
-        @param flags
-            By default changes are applied recursively. Set this paramter
-            wxPG_DONT_RECURSE to prevent this.
+        @remarks
+            - You can actually exceed rect width, but if you do so then
+              paintdata.m_drawnWidth must be set to the full width drawn in
+              pixels.
+            - Due to technical reasons, rect's height will be default even if
+              custom height was reported during measure call.
+            - Brush is guaranteed to be default background colour. It has been
+              already used to clear the background of area being painted. It
+              can be modified.
+            - Pen is guaranteed to be 1-wide 'black' (or whatever is the proper
+              colour) pen for drawing framing rectangle. It can be changed as
+              well.
+
+        @see GetValueAsString()
     */
-    inline bool Hide( bool hide, int flags = wxPG_RECURSE );
+    virtual void OnCustomPaint( wxDC& dc,
+                                const wxRect& rect,
+                                wxPGPaintData& paintdata );
 
-    bool IsExpanded() const
-        { return (!(m_flags & wxPG_PROP_COLLAPSED) && GetChildCount()); }
+    /**
+        Returns used wxPGCellRenderer instance for given property column
+        (label=0, value=1).
 
-    /** Returns true if all parents expanded.
+        Default implementation returns editor's renderer for all columns.
     */
-    bool IsVisible() const;
+    virtual wxPGCellRenderer* GetCellRenderer( int column ) const;
 
-    bool IsEnabled() const { return !(m_flags & wxPG_PROP_DISABLED); }
+    /** Returns which choice is currently selected. Only applies to properties
+        which have choices.
 
-    /** If property's editor is created this forces its recreation.
-        Useful in SetAttribute etc. Returns true if actually did anything.
+        Needs to reimplemented in derived class if property value does not
+        map directly to a choice. Integer as index, bool, and string usually do.
     */
-    bool RecreateEditor();
+    virtual int GetChoiceSelection() const;
 
-    /** If property's editor is active, then update it's value.
-    */
-    void RefreshEditor();
+    /**
+        Refresh values of child properties.
 
-    /** Sets an attribute for this property.
-        @param name
-        Text identifier of attribute. See @ref propgrid_property_attributes.
-        @param value
-        Value of attribute.
+        Automatically called after value is set.
     */
-    void SetAttribute( const wxString& name, wxVariant value );
-
-    void SetAttributes( const wxPGAttributeStorage& attributes );
+    virtual void RefreshChildren();
 
-#ifndef SWIG
-    /** Sets editor for a property.
+    /** Special handling for attributes of this 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).
+        If returns false, then the attribute will be automatically stored in
+        m_attributes.
 
-        For custom editors, use pointer you received from
-        wxPropertyGrid::RegisterEditorClass().
+        Default implementation simply returns false.
     */
-    void SetEditor( const wxPGEditor* editor )
-    {
-        m_customEditor = editor;
-    }
-#endif
+    virtual bool DoSetAttribute( const wxString& name, wxVariant& value );
 
-    /** Sets editor for a property.
-    */
-    inline void SetEditor( const wxString& editorName );
+    /** Returns value of an attribute.
 
-    /** Sets cell information for given column.
+        Override if custom handling of attributes is needed.
 
-        Note that the property takes ownership of given wxPGCell instance.
+        Default implementation simply return NULL variant.
     */
-    void SetCell( int column, wxPGCell* cellObj );
+    virtual wxVariant DoGetAttribute( const wxString& name ) const;
 
-    /** 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 );
+    /** Returns instance of a new wxPGEditorDialogAdapter instance, which is
+        used when user presses the (optional) button next to the editor control;
 
-    /** Sets common value selected for this property. -1 for none.
+        Default implementation returns NULL (ie. no action is generated when
+        button is pressed).
     */
-    void SetCommonValue( int commonValue )
+    virtual wxPGEditorDialogAdapter* GetEditorDialog() const;
+
+    /** Returns wxPGCell of given column, NULL if none. If valid
+        object is returned, caller will gain its ownership.
+    */
+    wxPGCell* AcquireCell( unsigned int column )
     {
-        m_commonValue = commonValue;
+        if ( column >= m_cells.size() )
+            return NULL;
+
+        wxPGCell* cell = (wxPGCell*) m_cells[column];
+        m_cells[column] = NULL;
+        return cell;
     }
 
-    /** Sets flags from a '|' delimited string. Note that flag names are not
-        prepended with 'wxPG_PROP_'.
+    /** Append a new choice to property's list of choices.
     */
-    void SetFlagsFromString( const wxString& str );
+    int AddChoice( const wxString& label, int value = wxPG_INVALID_VALUE )
+    {
+        return InsertChoice(label, wxNOT_FOUND, value);
+    }
 
-    /** Sets property's "is it modified?" flag. Affects children recursively.
+    /**
+        Returns true if children of this property are component values (for
+        instance, points size, face name, and is_underlined are component
+        values of a font).
     */
-    void SetModifiedStatus( bool modified )
+    bool AreChildrenComponents() const
     {
-        SetFlagRecursively(wxPG_PROP_MODIFIED, modified);
+        if ( m_flags & (wxPG_PROP_COMPOSED_VALUE|wxPG_PROP_AGGREGATE) )
+            return true;
+
+        return false;
     }
 
-    /** Call in OnEvent(), OnButtonClick() etc. to change the property value
-        based on user input.
+    /**
+        Removes entry from property's wxPGChoices and editor control (if it is
+        active).
 
-        @remarks
-        This method is const since it doesn't actually modify value, but posts
-        given variant as pending value, stored in wxPropertyGrid.
+        If selected item is deleted, then the value is set to unspecified.
     */
-    void SetValueInEvent( wxVariant value ) const;
+    void DeleteChoice( int index );
 
     /**
-        Call this to set value of the property.
+        Call to enable or disable usage of common value (integer value that can
+        be selected for properties instead of their normal values) for this
+        property.
 
-        Unlike methods in wxPropertyGrid, this does not automatically update
-        the display.
+        Common values are disabled by the default for all properties.
+    */
+    void EnableCommonValue( bool enable = true )
+    {
+        if ( enable ) SetFlag( wxPG_PROP_USES_COMMON_VALUE );
+        else ClearFlag( wxPG_PROP_USES_COMMON_VALUE );
+    }
 
-        @remarks
-        Use wxPropertyGrid::ChangePropertyValue() instead if you need to run
-        through validation process and send property change event.
+    /** Composes text from values of child properties. */
+    void GenerateComposedValue( wxString& text, int argFlags = 0 ) const;
 
-        If you need to change property value in event, based on user input, use
-        SetValueInEvent() instead.
+    /** Returns property's label. */
+    const wxString& GetLabel() const { return m_label; }
 
-        @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 );
+    /** Returns property's name with all (non-category, non-root) parents. */
+    wxString GetName() const;
 
-    /** Set wxBitmap in front of the value. This bitmap may be ignored
-        by custom cell renderers.
+    /**
+        Returns property's base name (ie parent's name is not added in any
+        case)
+     */
+    const wxString& GetBaseName() const { return m_name; }
+
+    /** Returns read-only reference to property's list of choices.
     */
-    void SetValueImage( wxBitmap& bmp );
+    const wxPGChoices& GetChoices() const
+    {
+        return m_choices;
+    }
 
-    /** If property has choices and they are not yet exclusive, new such copy
-        of them will be created.
+    /** Returns coordinate to the top y of the property. Note that the
+        position of scrollbars is not taken into account.
     */
-    void SetChoicesExclusive();
+    int GetY() const;
 
-    void SetExpanded( bool expanded )
+    wxVariant GetValue() const
     {
-        if ( !expanded ) m_flags |= wxPG_PROP_COLLAPSED;
-        else m_flags &= ~wxPG_PROP_COLLAPSED;
+        return DoGetValue();
     }
 
-    void SetFlag( FlagType flag ) { m_flags |= flag; }
-
-    void SetFlagRecursively( FlagType flag, bool set );
+#ifndef SWIG
+    /** Returns reference to the internal stored value. GetValue is preferred
+        way to get the actual value, since GetValueRef ignores DoGetValue,
+        which may override stored value.
+    */
+    wxVariant& GetValueRef()
+    {
+        return m_value;
+    }
 
-    void SetHelpString( const wxString& helpString )
+    const wxVariant& GetValueRef() const
     {
-        m_helpString = helpString;
+        return m_value;
     }
+#endif
 
-    void SetLabel( const wxString& label ) { m_label = label; }
+    /** Same as GetValueAsString, except takes common value into account.
+    */
+    wxString GetValueString( int argFlags = 0 ) const;
 
-    inline void SetName( const wxString& newName );
+    void UpdateControl( wxWindow* primary );
 
-    void SetValueToUnspecified()
+    /** Returns wxPGCell of given column, NULL if none. wxPGProperty
+        will retain ownership of the cell object.
+    */
+    wxPGCell* GetCell( unsigned int column ) const
     {
-        wxVariant val;  // Create NULL variant
-        SetValue(val);
-    }
+        if ( column >= m_cells.size() )
+            return NULL;
 
-#if wxUSE_VALIDATORS
-    /** Sets wxValidator for a property*/
-    void SetValidator( const wxValidator& validator )
-    {
-        m_validator = wxDynamicCast(validator.Clone(),wxValidator);
+        return (wxPGCell*) m_cells[column];
     }
 
-    /** Gets assignable version of property's validator. */
-    wxValidator* GetValidator() const
+    /** Return number of displayed common values for this property.
+    */
+    int GetDisplayedCommonValueCount() const;
+
+    wxString GetDisplayedString() const
     {
-        if ( m_validator )
-            return m_validator;
-        return DoGetValidator();
+        return GetValueString(0);
     }
-#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.
+    /** Returns property grid where property lies. */
+    wxPropertyGrid* GetGrid() const;
+
+    /** Returns owner wxPropertyGrid, but only if one is currently on a page
+        displaying this property. */
+    wxPropertyGrid* GetGridIfDisplayed() const;
+
+    /** Returns highest level non-category, non-root parent. Useful when you
+        have nested wxCustomProperties/wxParentProperties.
         @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.
+        Thus, if immediate parent is root or category, this will return the
+        property itself.
     */
-    bool PrepareValueForDialogEditing( wxPropertyGrid* propgrid );
+    wxPGProperty* GetMainParent() const;
 
-#ifndef SWIG
-    /** Returns client data (void*) of a property.
+    /** Return parent of property */
+    wxPGProperty* GetParent() const { return m_parent; }
+
+    /** Returns true if property has editable wxTextCtrl when selected.
+
+        @remarks
+        Altough disabled properties do not displayed editor, they still
+        return True here as being disabled is considered a temporary
+        condition (unlike being read-only or having limited editing enabled).
     */
-    void* GetClientData() const
+    bool IsTextEditable() const;
+
+    bool IsValueUnspecified() const
     {
-        return m_clientData;
+        return m_value.IsNull();
     }
 
-    /** Sets client data (void*) of a property.
-        @remarks
-        This untyped client data has to be deleted manually.
-    */
-    void SetClientData( void* clientData )
+    FlagType HasFlag( FlagType flag ) const
     {
-        m_clientData = clientData;
+        return ( m_flags & flag );
     }
 
-    /** Returns client object of a property.
+    /** Returns comma-delimited string of property attributes.
     */
-    void SetClientObject(wxClientData* clientObject)
+    const wxPGAttributeStorage& GetAttributes() const
     {
-        delete m_clientObject;
-        m_clientObject = clientObject;
+        return m_attributes;
     }
 
-    /** Sets managed client object of a property.
+    /** Returns m_attributes as list wxVariant.
     */
-    wxClientData *GetClientObject() const { return m_clientObject; }
-#endif
-
-    /** Sets new set of choices for property.
+    wxVariant GetAttributesAsList() const;
 
-        @remarks
-        This operation clears the property value.
-    */
-    bool SetChoices( wxPGChoices& choices );
+    FlagType GetFlags() const
+    {
+        return m_flags;
+    }
 
-    /** Sets new set of choices for property.
-    */
-    inline bool SetChoices( const wxArrayString& labels,
-                            const wxArrayInt& values = wxArrayInt() );
+    const wxPGEditor* GetEditorClass() const;
 
-    /** Set max length of text in text editor.
-    */
-    inline bool SetMaxLength( int maxLen );
+    wxString GetValueType() const
+    {
+        return m_value.GetType();
+    }
 
-    /** Call with 'false' in OnSetValue to cancel value changes after all
-        (ie. cancel 'true' returned by StringToValue() or IntToValue()).
+    /** Returns editor used for given column. NULL for no editor.
     */
-    void SetWasModified( bool set = true )
+    const wxPGEditor* GetColumnEditor( int column ) const
     {
-        if ( set ) m_flags |= wxPG_PROP_WAS_MODIFIED;
-        else m_flags &= ~wxPG_PROP_WAS_MODIFIED;
+        if ( column == 1 )
+            return GetEditorClass();
+
+        return NULL;
     }
 
-    const wxString& GetHelpString() const
+    /** Returns common value selected for this property. -1 for none.
+    */
+    int GetCommonValue() const
     {
-        return m_helpString;
+        return m_commonValue;
     }
 
-    void ClearFlag( FlagType flag ) { m_flags &= ~(flag); }
+    /** Returns true if property has even one visible child.
+    */
+    bool HasVisibleChildren() const;
 
-    // Use, for example, to detect if item is inside collapsed section.
-    bool IsSomeParent( wxPGProperty* candidate_parent ) const;
+    /** Inserts a new choice to property's list of choices.
+    */
+    int InsertChoice( const wxString& label, int index, int value = wxPG_INVALID_VALUE );
 
     /**
-        Adapts list variant into proper value using consecutive
-        ChildChanged-calls.
+        Returns true if this property is actually a wxPropertyCategory.
     */
-    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.
+    bool IsCategory() const { return HasFlag(wxPG_PROP_CATEGORY)?true:false; }
 
-        iMax is used when finding property y-positions.
+    /** Returns true if this property is actually a wxRootProperty.
     */
-    int GetChildrenHeight( int lh, int iMax = -1 ) const;
-
-    /** Returns number of child properties */
-    unsigned int GetChildCount() const { return m_children.GetCount(); }
+    bool IsRoot() const { return (m_parent == NULL); }
 
-    /** Returns sub-property at index i. */
-    wxPGProperty* Item( size_t i ) const
-        { return (wxPGProperty*)m_children.Item(i); }
+    /** Returns true if this is a sub-property. */
+    bool IsSubProperty() const
+    {
+        wxPGProperty* parent = (wxPGProperty*)m_parent;
+        if ( parent && !parent->IsCategory() )
+            return true;
+        return false;
+    }
 
-    /** Returns last sub-property.
+    /** Returns last visible sub-property, recursively.
     */
-    wxPGProperty* Last() const { return (wxPGProperty*)m_children.Last(); }
+    const wxPGProperty* GetLastVisibleSubItem() const;
 
-    /** Returns index of given sub-property. */
-    int Index( const wxPGProperty* p ) const
-        { return m_children.Index((wxPGProperty*)p); }
+    wxVariant GetDefaultValue() const;
 
-    /** Deletes all sub-properties. */
-    void Empty();
+    int GetMaxLength() const
+    {
+        return (int) m_maxLen;
+    }
 
-    // Puts correct indexes to children
-    void FixIndexesOfChildren( size_t starthere = 0 );
+    /**
+        Determines, recursively, if all children are not unspecified.
 
-#ifndef SWIG
-    // Returns wxPropertyGridPageState in which this property resides.
-    wxPropertyGridPageState* GetParentState() const { return m_parentState; }
-#endif
+        Takes values in given list into account.
+    */
+    bool AreAllChildrenSpecified( wxVariant* pendingList = NULL ) const;
 
-    wxPGProperty* GetItemAtY( unsigned int y,
-                              unsigned int lh,
-                              unsigned int* nextItemY ) const;
+    /** Updates composed values of parent non-category properties, recursively.
+        Returns topmost property updated.
 
-    /** Returns (direct) child property with given name (or NULL if not found).
+        @remarks
+        - Must not call SetValue() (as can be called in it).
     */
-    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;
-            }
-        }
+    wxPGProperty* UpdateParentValues();
 
-        DocStr(SetClientData,
-               "Associate the given client data.", "");
-        void SetClientData(PyObject* clientData) {
-            wxPyClientData* data = new wxPyClientData(clientData);
-            self->SetClientObject(data);
-        }
+    /** Returns true if containing grid uses wxPG_EX_AUTO_UNSPECIFIED_VALUES.
+    */
+    FlagType UsesAutoUnspecified() const
+    {
+        return HasFlag(wxPG_PROP_AUTO_UNSPECIFIED);
     }
-    %pythoncode {
-         GetClientObject = GetClientData
-         SetClientObject = SetClientData
+
+    wxBitmap* GetValueImage() const
+    {
+        return m_valueBitmap;
     }
-#endif
 
-#ifndef SWIG
+    wxVariant GetAttribute( const wxString& name ) const;
 
-    static wxString*            sm_wxPG_LABEL;
+    /**
+        Returns named attribute, as string, if found.
 
-    /** This member is public so scripting language bindings
-        wrapper code can access it freely.
+        Otherwise defVal is returned.
     */
-    void*                       m_clientData;
+    wxString GetAttribute( const wxString& name, const wxString& defVal ) const;
 
-protected:
-    /** Returns text for given column.
-    */
-    wxString GetColumnText( unsigned int col ) const;
+    /**
+        Returns named attribute, as long, if found.
 
-    /** Returns (direct) child property with given name (or NULL if not found),
-        with hint index.
+        Otherwise defVal is returned.
+    */
+    long GetAttributeAsLong( const wxString& name, long defVal ) const;
 
-        @param hintIndex
-        Start looking for the child at this index.
+    /**
+        Returns named attribute, as double, if found.
 
-        @remarks
-        Does not support scope (ie. Parent.Child notation).
+        Otherwise defVal is returned.
     */
-    wxPGProperty* GetPropertyByNameWH( const wxString& name,
-                                       unsigned int hintIndex ) const;
+    double GetAttributeAsDouble( const wxString& name, double defVal ) const;
 
-    /** This is used by Insert etc. */
-    void AddChild2( wxPGProperty* prop,
-                    int index = -1,
-                    bool correct_mode = true );
+    unsigned int GetArrIndex() const { return m_arrIndex; }
 
-    void DoSetName(const wxString& str) { m_name = str; }
+    unsigned int GetDepth() const { return (unsigned int)m_depth; }
 
-    // Call for after sub-properties added with AddChild
-    void PrepareSubProperties();
+    /** Gets flags as a'|' delimited string. Note that flag names are not
+        prepended with 'wxPG_PROP_'.
+        @param flagsMask
+        String will only be made to include flags combined by this parameter.
+    */
+    wxString GetFlagsAsString( FlagType flagsMask ) const;
 
-    void SetParentalType( int flag )
+    /** Returns position in parent's array. */
+    unsigned int GetIndexInParent() const
     {
-        m_flags &= ~(wxPG_PROP_PROPERTY|wxPG_PROP_PARENTAL_FLAGS);
-        m_flags |= flag;
+        return (unsigned int)m_arrIndex;
     }
 
-    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 );
+    /** Hides or reveals the property.
+        @param hide
+            true for hide, false for reveal.
+        @param flags
+            By default changes are applied recursively. Set this paramter
+            wxPG_DONT_RECURSE to prevent this.
+    */
+    inline bool Hide( bool hide, int flags = wxPG_RECURSE );
 
-    int GetY2( int lh ) const;
+    bool IsExpanded() const
+        { return (!(m_flags & wxPG_PROP_COLLAPSED) && GetChildCount()); }
 
-    wxString                    m_label;
-    wxString                    m_name;
-    wxPGProperty*               m_parent;
-    wxPropertyGridPageState*        m_parentState;
+    /** Returns true if all parents expanded.
+    */
+    bool IsVisible() const;
 
-    wxClientData*               m_clientObject;
+    bool IsEnabled() const { return !(m_flags & wxPG_PROP_DISABLED); }
 
-    // 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;
+    /** If property's editor is created this forces its recreation.
+        Useful in SetAttribute etc. Returns true if actually did anything.
+    */
+    bool RecreateEditor();
 
-    wxVariant                   m_value;
-    wxPGAttributeStorage        m_attributes;
-    wxArrayPtrVoid              m_children;
+    /** If property's editor is active, then update it's value.
+    */
+    void RefreshEditor();
 
-    // Extended cell information
-    wxArrayPtrVoid              m_cells;
+    /** Sets an attribute for this property.
+        @param name
+        Text identifier of attribute. See @ref propgrid_property_attributes.
+        @param value
+        Value of attribute.
+    */
+    void SetAttribute( const wxString& name, wxVariant value );
 
-    // Help shown in statusbar or help box.
-    wxString                    m_helpString;
+    void SetAttributes( const wxPGAttributeStorage& attributes );
 
-    // Index in parent's property array.
-    unsigned int                m_arrIndex;
+#ifndef SWIG
+    /** Sets editor for a property.
 
-    // If not -1, then overrides m_value
-    int                         m_commonValue;
+        @param editor
+            For builtin editors, use wxPGEditor_X, where X is builtin editor's
+            name (TextCtrl, Choice, etc. see wxPGEditor documentation for full
+            list).
 
-    FlagType                    m_flags;
+        For custom editors, use pointer you received from
+        wxPropertyGrid::RegisterEditorClass().
+    */
+    void SetEditor( const wxPGEditor* editor )
+    {
+        m_customEditor = editor;
+    }
+#endif
 
-    // 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;
+    /** Sets editor for a property.
+    */
+    inline void SetEditor( const wxString& editorName );
 
-    // Root has 0, categories etc. at that level 1, etc.
-    unsigned char               m_depth;
+    /** Sets cell information for given column.
 
-    // 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;
+        Note that the property takes ownership of given wxPGCell instance.
+    */
+    void SetCell( int column, wxPGCell* cellObj );
 
-    unsigned char               m_bgColIndex; // Background brush index.
-    unsigned char               m_fgColIndex; // Foreground colour index.
+    /** Sets common value selected for this property. -1 for none.
+    */
+    void SetCommonValue( int commonValue )
+    {
+        m_commonValue = commonValue;
+    }
 
-private:
-    // Called in constructors.
-    void Init();
-    void Init( const wxString& label, const wxString& name );
-#endif // #ifndef SWIG
-};
+    /** 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);
+    }
 
-//
-// Property class declaration helper macros
-// (wxPGRootPropertyClass and wxPropertyCategory require this).
-//
+    /** Call in OnEvent(), OnButtonClick() etc. to change the property value
+        based on user input.
 
-#define WX_PG_DECLARE_DOGETEDITORCLASS \
-    virtual const wxPGEditor* DoGetEditorClass() 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;
 
-#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
+    /**
+        Call this to set value of the property.
 
-// 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; \
-}
+        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.
 
-#ifndef SWIG
+        If you need to change property value in event, based on user input, use
+        SetValueInEvent() instead.
 
-/** @class wxPGRootProperty
-    @ingroup classes
-    Root parent property.
-*/
-class WXDLLIMPEXP_PROPGRID wxPGRootProperty : public wxPGProperty
-{
-public:
-    WX_PG_DECLARE_PROPERTY_CLASS(wxPGRootProperty)
-public:
+        @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 );
 
-    /** Constructor. */
-    wxPGRootProperty();
-    virtual ~wxPGRootProperty();
+    /** Set wxBitmap in front of the value. This bitmap may be ignored
+        by custom cell renderers.
+    */
+    void SetValueImage( wxBitmap& bmp );
 
-    virtual bool StringToValue( wxVariant&, const wxString&, int ) const
+    /** If property has choices and they are not yet exclusive, new such copy
+        of them will be created.
+    */
+    void SetChoicesExclusive()
     {
-        return false;
+        m_choices.SetExclusive();
     }
 
-protected:
-};
-
-// -----------------------------------------------------------------------
+    /** Sets selected choice and changes property value.
 
-/** @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:
+        Tries to retain value type, although currently if it is not string,
+        then it is forced to integer.
+    */
+    void SetChoiceSelection( int newValue );
 
-    /** Default constructor is only used in special cases. */
-    wxPropertyCategory();
+    void SetExpanded( bool expanded )
+    {
+        if ( !expanded ) m_flags |= wxPG_PROP_COLLAPSED;
+        else m_flags &= ~wxPG_PROP_COLLAPSED;
+    }
 
-    wxPropertyCategory( const wxString& label,
-                        const wxString& name = wxPG_LABEL );
-    ~wxPropertyCategory();
+    void SetFlag( FlagType flag ) { m_flags |= flag; }
 
-    int GetTextExtent( const wxWindow* wnd, const wxFont& font ) const;
+    void SetFlagRecursively( FlagType flag, bool set );
 
-protected:
-    virtual wxString GetValueAsString( int argFlags ) const;
+    void SetHelpString( const wxString& helpString )
+    {
+        m_helpString = helpString;
+    }
 
-    void SetTextColIndex( unsigned int colInd )
-        { m_capFgColIndex = (wxByte) colInd; }
-    unsigned int GetTextColIndex() const
-        { return (unsigned int) m_capFgColIndex; }
+    void SetLabel( const wxString& label ) { m_label = label; }
 
-    void CalculateTextExtent( wxWindow* wnd, const wxFont& font );
+    inline void SetName( const wxString& newName );
 
-    int     m_textExtent;  // pre-calculated length of text
-    wxByte  m_capFgColIndex;  // caption text colour index
+    void SetValueToUnspecified()
+    {
+        wxVariant val;  // Create NULL variant
+        SetValue(val);
+    }
 
-private:
-    void Init();
-};
+#if wxUSE_VALIDATORS
+    /** Sets wxValidator for a property*/
+    void SetValidator( const wxValidator& validator )
+    {
+        m_validator = wxDynamicCast(validator.Clone(),wxValidator);
+    }
 
-#endif  // !SWIG
+    /** 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
-
-/** @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)
+    /** Returns client data (void*) of a property.
+    */
+    void* GetClientData() const
     {
-        m_text = label;
+        return m_clientData;
     }
 
-    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)
+    /** Sets client data (void*) of a property.
+        @remarks
+        This untyped client data has to be deleted manually.
+    */
+    void SetClientData( void* clientData )
     {
+        m_clientData = clientData;
     }
 
-    virtual ~wxPGChoiceEntry()
+    /** Returns client object of a property.
+    */
+    void SetClientObject(wxClientData* clientObject)
     {
+        delete m_clientObject;
+        m_clientObject = clientObject;
     }
 
-    void SetValue( int value ) { m_value = value; }
-
-    int GetValue() const { return m_value; }
-
-    bool HasValue() const { return (m_value != wxPG_INVALID_VALUE); }
-
-protected:
-    int m_value;
-};
+    /** Sets managed client object of a property.
+    */
+    wxClientData *GetClientObject() const { return m_clientObject; }
+#endif
 
+    /** Sets new set of choices for property.
 
-typedef void* wxPGChoicesId;
+        @remarks
+        This operation clears the property value.
+    */
+    bool SetChoices( wxPGChoices& choices );
 
-class WXDLLIMPEXP_PROPGRID wxPGChoicesData
-{
-    friend class wxPGChoices;
-public:
-    // Constructor sets m_refCount to 1.
-    wxPGChoicesData();
+    /** Sets new set of choices for property.
+    */
+    bool SetChoices( const wxArrayString& labels,
+                     const wxArrayInt& values = wxArrayInt() )
+    {
+        wxPGChoices chs(labels, values);
+        return SetChoices(chs);
+    }
 
-    void CopyDataFrom( wxPGChoicesData* data );
+    /** Set max length of text in text editor.
+    */
+    inline bool SetMaxLength( int maxLen );
 
-    // Takes ownership of 'item'
-    void Insert( int index, wxPGChoiceEntry* item )
+    /** Call with 'false' in OnSetValue to cancel value changes after all
+        (ie. cancel 'true' returned by StringToValue() or IntToValue()).
+    */
+    void SetWasModified( bool set = true )
     {
-        wxArrayPtrVoid::iterator it;
-        if ( index == -1 )
-        {
-            it = m_items.end();
-            index = m_items.size();
-        }
-        else
-        {
-            it = m_items.begin() + index;
-        }
-
-        // Need to fix value?
-        if ( item->GetValue() == wxPG_INVALID_VALUE )
-            item->SetValue(index);
+        if ( set ) m_flags |= wxPG_PROP_WAS_MODIFIED;
+        else m_flags &= ~wxPG_PROP_WAS_MODIFIED;
+    }
 
-        m_items.insert(it, item);
+    const wxString& GetHelpString() const
+    {
+        return m_helpString;
     }
 
-    // Delete all entries
-    void Clear();
+    void ClearFlag( FlagType flag ) { m_flags &= ~(flag); }
 
-    size_t GetCount() const { return m_items.size(); }
+    // Use, for example, to detect if item is inside collapsed section.
+    bool IsSomeParent( wxPGProperty* candidate_parent ) const;
 
-    wxPGChoiceEntry* Item( unsigned int i ) const
-    {
-        wxCHECK_MSG( i < GetCount(), NULL, "invalid index" );
+    /**
+        Adapts list variant into proper value using consecutive
+        ChildChanged-calls.
+    */
+    void AdaptListToValue( wxVariant& list, wxVariant* value ) const;
 
-        return (wxPGChoiceEntry*) m_items[i];
-    }
+    /** This is used by properties that have fixed sub-properties. */
+    void AddChild( wxPGProperty* prop );
 
-    void DecRef()
-    {
-        m_refCount--;
-        wxASSERT( m_refCount >= 0 );
-        if ( m_refCount == 0 )
-            delete this;
-    }
+    /** Returns height of children, recursively, and
+        by taking expanded/collapsed status into account.
 
-private:
-    wxArrayPtrVoid  m_items;
+        iMax is used when finding property y-positions.
+    */
+    int GetChildrenHeight( int lh, int iMax = -1 ) const;
 
-    // So that multiple properties can use the same set
-    int             m_refCount;
+    /** Returns number of child properties */
+    unsigned int GetChildCount() const { return m_children.GetCount(); }
 
-    virtual ~wxPGChoicesData();
-};
+    /** Returns sub-property at index i. */
+    wxPGProperty* Item( size_t i ) const
+        { return (wxPGProperty*)m_children.Item(i); }
 
-#define wxPGChoicesEmptyData    ((wxPGChoicesData*)NULL)
+    /** Returns last sub-property.
+    */
+    wxPGProperty* Last() const { return (wxPGProperty*)m_children.Last(); }
 
-#endif // SWIG
+    /** Returns index of given sub-property. */
+    int Index( const wxPGProperty* p ) const
+        { return m_children.Index((wxPGProperty*)p); }
 
+    /** Deletes all sub-properties. */
+    void Empty();
 
-/** @class wxPGChoices
+    // Puts correct indexes to children
+    void FixIndexesOfChildren( size_t starthere = 0 );
 
-    Helper class for managing choices of wxPropertyGrid properties.
-    Each entry can have label, value, bitmap, text colour, and background
-    colour.
+#ifndef SWIG
+    // Returns wxPropertyGridPageState in which this property resides.
+    wxPropertyGridPageState* GetParentState() const { return m_parentState; }
+#endif
 
-    @library{wxpropgrid}
-    @category{propgrid}
-*/
-class WXDLLIMPEXP_PROPGRID wxPGChoices
-{
-public:
-    typedef long ValArrItem;
+    wxPGProperty* GetItemAtY( unsigned int y,
+                              unsigned int lh,
+                              unsigned int* nextItemY ) const;
 
-    /** Default constructor. */
-    wxPGChoices()
-    {
-        Init();
-    }
+    /** Returns (direct) child property with given name (or NULL if not found).
+    */
+    wxPGProperty* GetPropertyByName( const wxString& name ) const;
 
-    /** Copy constructor. */
-    wxPGChoices( const wxPGChoices& a )
-    {
-        if ( a.m_data != wxPGChoicesEmptyData )
-        {
-            m_data = a.m_data;
-            m_data->m_refCount++;
+#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;
+            }
         }
-    }
 
-    /** Constructor. */
-    wxPGChoices( const wxChar** labels, const long* values = NULL )
-    {
-        Init();
-        Set(labels,values);
+        DocStr(SetClientData,
+               "Associate the given client data.", "");
+        void SetClientData(PyObject* clientData) {
+            wxPyClientData* data = new wxPyClientData(clientData);
+            self->SetClientObject(data);
+        }
     }
-
-    /** Constructor. */
-    wxPGChoices( const wxArrayString& labels,
-                 const wxArrayInt& values = wxArrayInt() )
-    {
-        Init();
-        Set(labels,values);
+    %pythoncode {
+         GetClientObject = GetClientData
+         SetClientObject = SetClientData
     }
+#endif
 
-    /** Simple interface constructor. */
-    wxPGChoices( wxPGChoicesData* data )
-    {
-        wxASSERT(data);
-        m_data = data;
-        data->m_refCount++;
-    }
+#ifndef SWIG
 
-    /** Destructor. */
-    ~wxPGChoices()
-    {
-        Free();
-    }
+    static wxString*            sm_wxPG_LABEL;
 
-    /**
-        Adds to current.
+    /** This member is public so scripting language bindings
+        wrapper code can access it freely.
+    */
+    void*                       m_clientData;
 
-        If did not have own copies, creates them now. If was empty, identical
-        to set except that creates copies.
+protected:
+    /** Returns text for given column.
     */
-    void Add( const wxChar** labels, const ValArrItem* values = NULL );
+    wxString GetColumnText( unsigned int col ) const;
 
-    /** Version that works with wxArrayString. */
-    void Add( const wxArrayString& arr, const ValArrItem* values = NULL );
+    /** Returns (direct) child property with given name (or NULL if not found),
+        with hint index.
 
-    /** Version that works with wxArrayString and wxArrayInt. */
-    void Add( const wxArrayString& arr, const wxArrayInt& arrint );
+        @param hintIndex
+        Start looking for the child at this index.
 
-    /** Adds single item. */
-    wxPGChoiceEntry& Add( const wxString& label,
-                          int value = wxPG_INVALID_VALUE );
+        @remarks
+        Does not support scope (ie. Parent.Child notation).
+    */
+    wxPGProperty* GetPropertyByNameWH( const wxString& name,
+                                       unsigned int hintIndex ) const;
 
-    /** Adds a single item, with bitmap. */
-    wxPGChoiceEntry& Add( const wxString& label,
-                          const wxBitmap& bitmap,
-                          int value = wxPG_INVALID_VALUE );
+    /** This is used by Insert etc. */
+    void AddChild2( wxPGProperty* prop,
+                    int index = -1,
+                    bool correct_mode = true );
 
-    /** Adds a single item with full entry information. */
-    wxPGChoiceEntry& Add( const wxPGChoiceEntry& entry )
+    void DoSetName(const wxString& str) { m_name = str; }
+
+    // Call for after sub-properties added with AddChild
+    void PrepareSubProperties();
+
+    void SetParentalType( int flag )
     {
-        return Insert(entry, -1);
+        m_flags &= ~(wxPG_PROP_PROPERTY|wxPG_PROP_PARENTAL_FLAGS);
+        m_flags |= flag;
     }
 
-    /** Adds single item. */
-    wxPGChoiceEntry& AddAsSorted( const wxString& label,
-                                  int value = wxPG_INVALID_VALUE );
+    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 );
 
-    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;
+    wxArrayPtrVoid              m_children;
 
-    const wxString& GetLabel( size_t ind ) const
-    {
-        return Item(ind).GetText();
-    }
+    // Extended cell information
+    wxArrayPtrVoid              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 );
+    unsigned char               m_bgColIndex; // Background brush index.
+    unsigned char               m_fgColIndex; // Foreground colour index.
 
-    /** Returns false if this is a constant empty set of choices,
-        which should not be modified.
-    */
-    bool IsOk() const
-    {
-        return ( m_data != wxPGChoicesEmptyData );
-    }
+private:
+    // Called in constructors.
+    void Init();
+    void Init( const wxString& label, const wxString& name );
+#endif // #ifndef SWIG
+};
 
-    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);
-    }
+//
+// Property class declaration helper macros
+// (wxPGRootPropertyClass and wxPropertyCategory require this).
+//
 
-    /** Removes count items starting at position nIndex. */
-    void RemoveAt(size_t nIndex, size_t count = 1);
+#define WX_PG_DECLARE_DOGETEDITORCLASS \
+    virtual const wxPGEditor* DoGetEditorClass() const;
 
 #ifndef SWIG
-    /** Does not create copies for itself. */
-    void Set( const wxChar** labels, const long* values = NULL )
-    {
-        Free();
-        Add(labels,values);
-    }
+    #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
 
-    /** Version that works with wxArrayString.
-        TODO: Deprecate this.
-    */
-    void Set( wxArrayString& arr, const long* values = (const long*) NULL )
-    {
-        Free();
-        Add(arr,values);
-    }
-#endif // SWIG
+// 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; \
+}
 
-    /** 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 SetExclusive()
-    {
-        if ( m_data->m_refCount != 1 )
-        {
-            wxPGChoicesData* data = new wxPGChoicesData();
-            data->CopyDataFrom(m_data);
-            Free();
-            m_data = data;
-        }
-    }
+#ifndef SWIG
 
-    // Returns data, increases refcount.
-    wxPGChoicesData* GetData()
-    {
-        wxASSERT( m_data->m_refCount != 0xFFFFFFF );
-        m_data->m_refCount++;
-        return m_data;
-    }
+/** @class wxPGRootProperty
+    @ingroup classes
+    Root parent property.
+*/
+class WXDLLIMPEXP_PROPGRID wxPGRootProperty : public wxPGProperty
+{
+public:
+    WX_PG_DECLARE_PROPERTY_CLASS(wxPGRootProperty)
+public:
 
-    // Returns plain data ptr - no refcounting stuff is done.
-    wxPGChoicesData* GetDataPtr() const { return m_data; }
+    /** Constructor. */
+    wxPGRootProperty();
+    virtual ~wxPGRootProperty();
 
-    // Changes ownership of data to you.
-    wxPGChoicesData* ExtractData()
+    virtual bool StringToValue( wxVariant&, const wxString&, int ) const
     {
-        wxPGChoicesData* data = m_data;
-        m_data = wxPGChoicesEmptyData;
-        return data;
+        return false;
     }
 
-    wxArrayString GetLabels() const;
+protected:
+};
 
-#ifndef SWIG
-    void operator= (const wxPGChoices& a)
-    {
-        AssignData(a.m_data);
-    }
+// -----------------------------------------------------------------------
 
-    wxPGChoiceEntry& operator[](unsigned int i)
-    {
-        return Item(i);
-    }
+/** @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:
 
-    const wxPGChoiceEntry& operator[](unsigned int i) const
-    {
-        return Item(i);
-    }
+    /** Default constructor is only used in special cases. */
+    wxPropertyCategory();
+
+    wxPropertyCategory( const wxString& label,
+                        const wxString& name = wxPG_LABEL );
+    ~wxPropertyCategory();
+
+    int GetTextExtent( const wxWindow* wnd, const wxFont& font ) const;
 
 protected:
-    wxPGChoicesData*    m_data;
+    virtual wxString GetValueAsString( int argFlags ) const;
 
+    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 Free();
-#endif  // !SWIG
 };
 
-inline bool wxPGProperty::SetChoices( const wxArrayString& labels,
-                                      const wxArrayInt& values )
-{
-    wxPGChoices chs(labels, values);
-    return SetChoices(chs);
-}
+#endif  // !SWIG
 
 // -----------------------------------------------------------------------
 
index 60aeb2d72a02e414ee375c6ad358d6f572d7b409..76aa1afa765135a78f3faee2825ec1836f17a30a 100644 (file)
@@ -169,20 +169,6 @@ public:
     /** Destructor */
     virtual ~wxPropertyGridInterface() { }
 
-    /** Adds choice to a property that can accept one.
-        @remarks
-        - If you need to make sure that you modify only the set of choices of
-          a single property (and not also choices of other properties with
-          initially identical set), call
-          wxPropertyGrid::SetPropertyChoicesPrivate.
-        - This usually only works for wxEnumProperty and derivatives
-          (wxFlagsProperty can get accept new items but its items may not get
-          updated).
-    */
-    void AddPropertyChoice( wxPGPropArg id,
-                            const wxString& label,
-                            int value = wxPG_INVALID_VALUE );
-
     /**
         Appends property to the list.
 
@@ -263,14 +249,6 @@ public:
      */
     void DeleteProperty( wxPGPropArg id );
 
-    /** Deletes choice from a property.
-
-        If selected item is deleted, then the value is set to unspecified.
-
-        See AddPropertyChoice for more details.
-    */
-    void DeletePropertyChoice( wxPGPropArg id, int index );
-
     /** Disables property. */
     bool DisableProperty( wxPGPropArg id ) { return EnableProperty(id,false); }
 
@@ -463,12 +441,6 @@ public:
     wxPGProperty* GetPropertyByName( const wxString& name,
                                      const wxString& subname ) const;
 
-    /** Returns writable reference to property's list of choices (and relevant
-        values). If property does not have any choices, will return reference
-        to an invalid set of choices that will return false on IsOk call.
-    */
-    wxPGChoices& GetPropertyChoices( wxPGPropArg id );
-
     /** Returns property's editor. */
     const wxPGEditor* GetPropertyEditor( wxPGPropArg id ) const
     {
@@ -762,15 +734,6 @@ public:
         return p->IsCategory();
     }
 
-    /** Inserts choice to a property that can accept one.
-
-        See AddPropertyChoice for more details.
-    */
-    void InsertPropertyChoice( wxPGPropArg id,
-                               const wxString& label,
-                               int index,
-                               int value = wxPG_INVALID_VALUE );
-
     /** Returns true if property is enabled. */
     bool IsPropertyEnabled( wxPGPropArg id ) const
     {
@@ -971,28 +934,6 @@ public:
         p->SetCell( column, new wxPGCell(text, bitmap, fgCol, bgCol) );
     }
 
-    /** Set choices of a property to specified set of labels and values.
-
-        @remarks
-        This operation clears the property value.
-    */
-    void SetPropertyChoices( wxPGPropArg id, wxPGChoices& choices)
-    {
-        wxPG_PROP_ARG_CALL_PROLOG()
-        p->SetChoices(choices);
-    }
-
-
-    /**
-        If property's set of choices is shared, then calling this method
-        converts it to private.
-    */
-    void SetPropertyChoicesExclusive( wxPGPropArg id )
-    {
-        wxPG_PROP_ARG_CALL_PROLOG()
-        p->SetChoicesExclusive();
-    }
-
 #ifndef SWIG
     /** Sets client data (void*) of a property.
         @remarks
index 7e4dcb9dd09be89730b016dbf4f9f76d6a1196c0..6e42c2813a473cb84a5519e2ee87a5bd5347d270 100644 (file)
@@ -39,7 +39,6 @@ class wxArrayEditorDialog;
 #define WX_PG_DECLARE_CHOICE_METHODS() \
     virtual bool IntToValue( wxVariant& variant, \
                              int number, int argFlags = 0 ) const; \
-    virtual int GetChoiceInfo( wxPGChoiceInfo* choiceinfo );
 
 #define WX_PG_DECLARE_EVENT_METHODS() \
     virtual bool OnEvent( wxPropertyGrid* propgrid, \
@@ -640,6 +639,11 @@ public:
     // pvalue is never NULL - always set it.
     virtual const wxString* GetEntry( size_t index, int* pvalue ) const = 0;
 
+    // GetChoiceSelection needs to overridden since m_index is
+    // the true index, and various property classes derived from
+    // this take advantage of it.
+    virtual int GetChoiceSelection() const { return m_index; }
+
     int GetValueForIndex( size_t index ) const
     {
         int v;
@@ -718,15 +722,11 @@ public:
 
     virtual ~wxEnumProperty();
 
-    virtual int GetChoiceInfo( wxPGChoiceInfo* choiceinfo );
     virtual int GetIndexForValue( int value ) const;
     virtual const wxString* GetEntry( size_t index, int* pvalue ) const;
 
     size_t GetItemCount() const { return m_choices.GetCount(); }
     const wxPGChoices& GetChoices() const { return m_choices; }
-
-protected:
-    wxPGChoices             m_choices;
 };
 
 // -----------------------------------------------------------------------
@@ -817,8 +817,9 @@ public:
                                wxVariant& childValue ) const;
     virtual void RefreshChildren();
 
-    // this is necessary for conveying m_choices
-    virtual int GetChoiceInfo( wxPGChoiceInfo* choiceinfo );
+    // GetChoiceSelection needs to overridden since m_choices is
+    // used and value is integer, but it is not index.
+    virtual int GetChoiceSelection() const { return wxNOT_FOUND; }
 
     // helpers
     size_t GetItemCount() const { return m_choices.GetCount(); }
@@ -826,8 +827,6 @@ public:
         { return m_choices.GetLabel(ind); }
 
 protected:
-    wxPGChoices             m_choices;
-
     // Used to detect if choices have been changed
     wxPGChoicesData*        m_oldChoicesData;
 
index 593e0f62c811687c82c8ad70d91bde1ad11dd9bd..59f37bdc1b5b092442743acd94a845e021466c1f 100644 (file)
 #define wxNullProperty  ((wxPGProperty*)NULL)
 
 
-// Structure for relaying choice/list info.
-struct wxPGChoiceInfo
-{
-    wxPGChoices*    m_choices;
-};
-
-
 /** @section propgrid_property_attributes wxPropertyGrid Property Attribute Identifiers
 
     wxPGProperty::SetAttribute() and
@@ -257,7 +250,8 @@ struct wxPGChoiceInfo
     the flags as a text; a continous sequence of spaces, commas and semicolons
     is considered as a flag id separator.
     <b>Note: </b> When changing "choices" (ie. flag labels) of wxFlagsProperty, you
-    will need to use SetPropertyChoices - otherwise they will not get updated properly.
+    will need to use wxPGProperty::SetChoices() - otherwise they will not get updated
+    properly.
 
     @subsection wxArrayStringProperty
 
@@ -634,17 +628,6 @@ public:
     */
     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 overridden as well).
 
@@ -682,7 +665,7 @@ public:
             int                     m_drawnWidth;
 
             // In a measure item call, set this to the height of item at m_choiceItem index
-            int                     m_drawnHeight;   
+            int                     m_drawnHeight;
         };
         @endcode
 
@@ -706,6 +689,14 @@ public:
     */
     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. Automatically called after value is set.
     */
     virtual void RefreshChildren();
@@ -735,14 +726,6 @@ public:
     */
     virtual wxPGEditorDialogAdapter* GetEditorDialog() const;
 
-    /** Adds entry to property's wxPGChoices and editor control (if it is active).
-        Returns index of item added.
-    */
-    int AppendChoice( const wxString& label, int value = wxPG_INVALID_VALUE )
-    {
-        return InsertChoice(label,-1,value);
-    }
-
     /** Returns wxPGCell of given column, NULL if none. If valid
         object is returned, caller will gain its ownership.
     */
@@ -756,6 +739,20 @@ public:
         return cell;
     }
 
+    /** Append a new choice to property's list of choices.
+
+        @param label
+            Label for added choice.
+
+        @param value
+            Value for new choice. Do not specify if you wish this
+            to equal choice index.
+
+        @return
+            Index to added choice.
+    */
+    int AddChoice( const wxString& label, int value = wxPG_INVALID_VALUE );
+
     /** Returns true if children of this property are component values (for instance,
         points size, face name, and is_underlined are component values of a font).
     */
@@ -796,12 +793,10 @@ public:
     /** Returns property's base name (ie. parent's name is not added in any case) */
     const wxString& GetBaseName() const { return m_name; }
 
-    wxPGChoices& GetChoices();
-
+    /** Returns read-only reference to property's list of choices.
+    */
     const wxPGChoices& GetChoices() const;
 
-    const wxPGChoiceEntry* GetCurrentChoice() const;
-
     /** Returns coordinate to the top y of the property. Note that the
         position of scrollbars is not taken into account.
     */
@@ -843,10 +838,6 @@ public:
         return (wxPGCell*) m_cells[column];
     }
 
-    unsigned int GetChoiceCount() const;
-
-    wxString GetChoiceString( unsigned int index );
-
     /** Return number of displayed common values for this property.
     */
     int GetDisplayedCommonValueCount() const;
@@ -937,8 +928,17 @@ public:
     */
     bool HasVisibleChildren() const;
 
-    /** Adds entry to property's wxPGChoices and editor control (if it is active).
-        Returns index of item added.
+    /** Inserts a new choice to property's list of choices.
+
+        @param label
+            Text for new choice
+
+        @param index
+            Insertion position. Use wxNOT_FOUND to append.
+
+        @param value
+            Value for new choice. Do not specify if you wish this
+            to equal choice index.
     */
     int InsertChoice( const wxString& label, int index, int value = wxPG_INVALID_VALUE );
 
@@ -1086,9 +1086,17 @@ public:
     */
     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 );
+    /** If property has choices and they are not yet exclusive, new such copy
+        of them will be created.
+    */
+    void SetChoicesExclusive();
+
+    /** Sets selected choice and changes property value.
+
+        Tries to retain value type, although currently if it is not string,
+        then it is forced to integer.
+    */
+    void SetChoiceSelection( int newValue );
 
     /** Sets common value selected for this property. -1 for none.
     */
@@ -1141,11 +1149,6 @@ public:
     */
     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;
@@ -1280,7 +1283,7 @@ public:
 
     /** 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;
index 8bc8442175d4a422825555424b345121b817b1e8..d5aabb60e835f2f05346e04b331ae73ff32c5c88 100644 (file)
@@ -26,16 +26,6 @@ public:
     /** Destructor */
     virtual ~wxPropertyGridInterface() { }
 
-    /** Adds choice to a property that can accept one.
-        @remarks
-        - If you need to make sure that you modify only the set of choices of
-          a single property (and not also choices of other properties with initially
-          identical set), call wxPropertyGrid::SetPropertyChoicesPrivate.
-        - This usually only works for wxEnumProperty and derivatives (wxFlagsProperty
-          can get accept new items but its items may not get updated).
-    */
-    void AddPropertyChoice( wxPGPropArg id, const wxString& label, int value = wxPG_INVALID_VALUE );
-
     /** Appends property to the list. wxPropertyGrid assumes ownership of the object.
         Becomes child of most recently added category.
         @remarks
@@ -106,14 +96,6 @@ public:
     /** Deletes a property by id. If category is deleted, all children are automatically deleted as well. */
     void DeleteProperty( wxPGPropArg id );
 
-    /** Deletes choice from a property.
-
-        If selected item is deleted, then the value is set to unspecified.
-
-        See AddPropertyChoice for more details.
-    */
-    void DeletePropertyChoice( wxPGPropArg id, int index );
-
     /** Disables property. */
     bool DisableProperty( wxPGPropArg id ) { return EnableProperty(id,false); }
 
@@ -286,12 +268,6 @@ public:
     */
     wxPGProperty* GetPropertyByName( const wxString& name, const wxString& subname ) const;
 
-    /** Returns writable reference to property's list of choices (and relevant
-        values). If property does not have any choices, will return reference
-        to an invalid set of choices that will return false on IsOk call.
-    */
-    wxPGChoices& GetPropertyChoices( wxPGPropArg id );
-
     /** Returns property's editor. */
     const wxPGEditor* GetPropertyEditor( wxPGPropArg id ) const
     {
@@ -534,12 +510,6 @@ public:
         return p->IsCategory();
     }
 
-    /** Inserts choice to a property that can accept one.
-
-        See AddPropertyChoice for more details.
-    */
-    void InsertPropertyChoice( wxPGPropArg id, const wxString& label, int index, int value = wxPG_INVALID_VALUE );
-
     /** Returns true if property is enabled. */
     bool IsPropertyEnabled( wxPGPropArg id ) const
     {
@@ -707,27 +677,6 @@ public:
         p->SetCell( column, new wxPGCell(text, bitmap, fgCol, bgCol) );
     }
 
-    /** Set choices of a property to specified set of labels and values.
-
-        @remarks
-        This operation clears the property value.
-    */
-    void SetPropertyChoices( wxPGPropArg id, wxPGChoices& choices)
-    {
-        wxPG_PROP_ARG_CALL_PROLOG()
-        p->SetChoices(choices);
-    }
-
-
-    /** If property's set of choices is shared, then calling this method converts
-        it to private.
-    */
-    void SetPropertyChoicesExclusive( wxPGPropArg id )
-    {
-        wxPG_PROP_ARG_CALL_PROLOG()
-        p->SetChoicesExclusive();
-    }
-
     /** Sets client data (void*) of a property.
         @remarks
         This untyped client data has to be deleted manually.
index f44d23dab8ec32303a72d0b0194313f9d009080a..d6ab769b8439670bf1e1210ded4ab846e5b30d4a 100644 (file)
@@ -326,14 +326,6 @@ void wxAdvImageFileProperty::OnSetValue()
         m_index = -1;
 }
 
-int wxAdvImageFileProperty::GetChoiceInfo( wxPGChoiceInfo* choiceinfo )
-{
-    if ( choiceinfo )
-        choiceinfo->m_choices = &ms_choices;
-
-    return m_index;
-}
-
 bool wxAdvImageFileProperty::IntToValue( wxVariant& variant, int number, int WXUNUSED(argFlags) ) const
 {
     wxASSERT( number >= 0 );
@@ -1488,7 +1480,7 @@ void FormMain::PopulateWithExamples ()
                                    wxPG_LABEL,
                                    soc,
                                   240) );
-    pg->AddPropertyChoice(wxT("EnumProperty 2"),wxT("Testing Extra"),360);
+    pg->GetProperty(wxT("EnumProperty 2"))->AddChoice(wxT("Testing Extra"), 360);
 
     // Add a second time to test that the caching works
     pg->Append( new wxEnumProperty(wxT("EnumProperty 3"),wxPG_LABEL,
@@ -1503,8 +1495,9 @@ void FormMain::PopulateWithExamples ()
 
     pg->Append( new wxEnumProperty(wxT("EnumProperty 5"),wxPG_LABEL,
         soc, 240 ) );
-    pg->SetPropertyChoicesExclusive(wxT("EnumProperty 5"));
-    pg->AddPropertyChoice(wxT("EnumProperty 5"),wxT("5th only"),360);
+    pg->GetProperty(wxT("EnumProperty 5"))->SetChoicesExclusive();
+    pg->GetProperty(wxT("EnumProperty 5"))->AddChoice(wxT("5th only"), 360);
+
     pg->SetPropertyHelpString(wxT("EnumProperty 5"),
         wxT("Should have one extra item when compared to EnumProperty 4"));
 
@@ -2495,8 +2488,7 @@ void FormMain::OnFitColumnsClick( wxCommandEvent& WXUNUSED(event) )
 
 void FormMain::OnChangeFlagsPropItemsClick( wxCommandEvent& WXUNUSED(event) )
 {
-
-    wxPGProperty* id = m_pPropGridManager->GetPropertyByName(wxT("Window Styles"));
+    wxPGProperty* p = m_pPropGridManager->GetPropertyByName(wxT("Window Styles"));
 
     wxPGChoices newChoices;
 
@@ -2505,9 +2497,7 @@ void FormMain::OnChangeFlagsPropItemsClick( wxCommandEvent& WXUNUSED(event) )
     newChoices.Add(wxT("Safe"),0x4);
     newChoices.Add(wxT("Sleek"),0x8);
 
-    m_pPropGridManager->SetPropertyChoices(id,newChoices);
-    //m_pPropGridManager->ReplaceProperty(wxT("Window Styles"),
-    //    wxFlagsProperty(wxT("Window Styles"),wxPG_LABEL,newChoices));
+    p->SetChoices(newChoices);
 }
 
 // -----------------------------------------------------------------------
@@ -2892,14 +2882,14 @@ void FormMain::OnInsertChoice( wxCommandEvent& WXUNUSED(event) )
     wxPropertyGrid* pg = m_pPropGridManager->GetGrid();
 
     wxPGProperty* selected = pg->GetSelection();
-    wxPGChoices& choices = pg->GetPropertyChoices(selected);
+    const wxPGChoices& choices = selected->GetChoices();
 
     // Insert new choice to the center of list
 
     if ( choices.IsOk() )
     {
         int pos = choices.GetCount() / 2;
-        pg->InsertPropertyChoice(selected,wxT("New Choice"),pos);
+        selected->InsertChoice(wxT("New Choice"), pos);
     }
     else
     {
@@ -2914,14 +2904,14 @@ void FormMain::OnDeleteChoice( wxCommandEvent& WXUNUSED(event) )
     wxPropertyGrid* pg = m_pPropGridManager->GetGrid();
 
     wxPGProperty* selected = pg->GetSelection();
-    wxPGChoices& choices = pg->GetPropertyChoices(selected);
+    const wxPGChoices& choices = selected->GetChoices();
 
     // Deletes choice from the center of list
 
     if ( choices.IsOk() )
     {
         int pos = choices.GetCount() / 2;
-        pg->DeletePropertyChoice(selected,pos);
+        selected->DeleteChoice(pos);
     }
     else
     {
index 17dfbae98c54397a26a37fc474df38575b757325..0c8085141fb24a564962e044729fcd5d3d7d37a6 100644 (file)
@@ -1023,6 +1023,24 @@ bool FormMain::RunTests( bool fullTest, bool interactive )
         }
     }
 
+    {
+        RT_START_TEST(Choice_Manipulation)
+
+        wxPGProperty* enumProp = pgman->GetProperty(wxT("EnumProperty"));
+
+        pgman->SelectPage(2);
+        pgman->SelectProperty(enumProp);
+        wxASSERT(pgman->GetGrid()->GetSelection() == enumProp);
+
+        const wxPGChoices& choices = enumProp->GetChoices();
+        int ind = enumProp->InsertChoice(wxT("New Choice"), choices.GetCount()/2);
+        enumProp->DeleteChoice(ind);
+
+        // Recreate the original grid
+        CreateGrid( -1, -1 );
+        pgman = m_pPropGridManager;
+    }
+
     //if ( !(pgman->GetWindowStyleFlag()&wxPG_HIDE_CATEGORIES) )
     {
         RT_START_TEST(RandomCollapse)
index dcc6b982076037441e0f6a80e41c74205789effb..da269ea3f435ef2999ec3fca485dc204031a4b14 100644 (file)
@@ -1808,13 +1808,6 @@ bool wxMultiChoiceProperty::OnEvent( wxPropertyGrid* propgrid,
     return false;
 }
 
-int wxMultiChoiceProperty::GetChoiceInfo( wxPGChoiceInfo* choiceinfo )
-{
-    if ( choiceinfo )
-        choiceinfo->m_choices = &m_choices;
-    return -1;
-}
-
 bool wxMultiChoiceProperty::StringToValue( wxVariant& variant, const wxString& text, int ) const
 {
     wxArrayString arr;
index fd0a8c663ca4b9ab05dbe9cb0824f7139b864121..0cf23e0faad5341f66b8a13e0fe050fc50a6de04 100644 (file)
@@ -794,11 +794,15 @@ void wxPropertyGrid::OnComboItemPaint( wxPGCustomComboControl* pCc,
     wxPGProperty* p = m_selected;
     wxString text;
 
-    const wxPGChoices* pChoices = &p->GetChoices();
+    const wxPGChoices& choices = p->GetChoices();
     const wxPGCommonValue* comVal = NULL;
-    int choiceCount = p->GetChoiceCount();
     int comVals = p->GetDisplayedCommonValueCount();
     int comValIndex = -1;
+
+    int choiceCount = 0;
+    if ( choices.IsOk() )
+        choiceCount = choices.GetCount();
+
     if ( item >= choiceCount && comVals > 0 )
     {
         comValIndex = item - choiceCount;
@@ -826,8 +830,8 @@ void wxPropertyGrid::OnComboItemPaint( wxPGCustomComboControl* pCc,
 
     const wxBitmap* itemBitmap = NULL;
 
-    if ( item >= 0 && pChoices && pChoices->Item(item).GetBitmap().Ok() && comValIndex == -1 )
-        itemBitmap = &pChoices->Item(item).GetBitmap();
+    if ( item >= 0 && choices.IsOk() && choices.Item(item).GetBitmap().Ok() && comValIndex == -1 )
+        itemBitmap = &choices.Item(item).GetBitmap();
 
     //
     // Decide what custom image size to use
@@ -929,9 +933,9 @@ void wxPropertyGrid::OnComboItemPaint( wxPGCustomComboControl* pCc,
             if ( item < 0 && (flags & wxODCB_PAINTING_CONTROL) )
                 item = pCb->GetSelection();
 
-            if ( pChoices && item >= 0 && comValIndex < 0 )
+            if ( choices.IsOk() && item >= 0 && comValIndex < 0 )
             {
-                const wxPGChoiceEntry& cell = pChoices->Item(item);
+                const wxPGChoiceEntry& cell = choices.Item(item);
                 wxPGCellRenderer* renderer = wxPGGlobalVars->m_defaultRenderer;
                 int imageOffset = renderer->PreDrawCell( dc, rect, cell, renderFlags );
                 if ( imageOffset )
@@ -992,20 +996,15 @@ wxWindow* wxPGChoiceEditor::CreateControlsBase( wxPropertyGrid* propGrid,
                                                 const wxSize& sz,
                                                 long extraStyle ) const
 {
-    wxString        defString;
-
-    // Get choices.
-    int index = property->GetChoiceInfo( NULL );
+    const wxPGChoices& choices = property->GetChoices();
+    wxString defString;
+    int index = property->GetChoiceSelection();
 
     bool isUnspecified = property->IsValueUnspecified();
 
-    if ( isUnspecified )
-        index = -1;
-    else
+    if ( !isUnspecified )
         defString = property->GetDisplayedString();
 
-    const wxPGChoices& choices = property->GetChoices();
-
     wxArrayString labels = choices.GetLabels();
 
     wxPGComboBox* cb;
@@ -1052,20 +1051,10 @@ wxWindow* wxPGChoiceEditor::CreateControlsBase( wxPropertyGrid* propGrid,
                labels,
                odcbFlags);
 
-    //int extRight = propGrid->GetClientSize().x - (po.x+si.x);
-    //int extRight =  - (po.x+si.x);
-
     cb->SetButtonPosition(si.y,0,wxRIGHT);
-    //cb->SetPopupExtents( 1, extRight );
     cb->SetTextIndent(wxPG_XBEFORETEXT-1);
 
     wxPGChoiceEditor_SetCustomPaintWidth( propGrid, cb, property->GetCommonValue() );
-    /*if ( property->GetFlags() & wxPG_PROP_CUSTOMIMAGE )
-    {
-        wxSize imageSize = propGrid->GetImageSize(property, index);
-        if ( imageSize.x ) imageSize.x += ODCB_CUST_PAINT_MARGIN;
-        cb->SetCustomPaintWidth( imageSize.x );
-    }*/
 
     if ( index >= 0 && index < (int)cb->GetCount() )
     {
@@ -1091,7 +1080,7 @@ void wxPGChoiceEditor::UpdateControl( wxPGProperty* property, wxWindow* ctrl ) c
     wxASSERT( ctrl );
     wxOwnerDrawnComboBox* cb = (wxOwnerDrawnComboBox*)ctrl;
     wxASSERT( cb->IsKindOf(CLASSINFO(wxOwnerDrawnComboBox)));
-    int ind = property->GetChoiceInfo( (wxPGChoiceInfo*)NULL );
+    int ind = property->GetChoiceSelection();
     cb->SetSelection(ind);
 }
 
@@ -1164,7 +1153,7 @@ bool wxPGChoiceEditor::GetValueFromControl( wxVariant& variant, wxPGProperty* pr
 
     int index = cb->GetSelection();
 
-    if ( index != property->GetChoiceInfo( (wxPGChoiceInfo*) NULL ) ||
+    if ( index != property->GetChoiceSelection() ||
         // Changing unspecified always causes event (returning
         // true here should be enough to trigger it).
          property->IsValueUnspecified()
@@ -1610,7 +1599,7 @@ wxPGWindowList wxPGCheckBoxEditor::CreateControls( wxPropertyGrid* propGrid,
             (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction)
             &wxPropertyGrid::OnCustomEditorEvent, NULL, propGrid );
 
-    if ( property->GetChoiceInfo((wxPGChoiceInfo*)NULL) &&
+    if ( property->GetChoiceSelection() > 0 &&
          !property->IsValueUnspecified() )
         cb->m_state = 1;
 
@@ -1669,7 +1658,7 @@ void wxPGCheckBoxEditor::DrawValue( wxDC& dc, const wxRect& rect, wxPGProperty*
     int state = 0;
     if ( !property->IsValueUnspecified() )
     {
-        state = property->GetChoiceInfo((wxPGChoiceInfo*)NULL);
+        state = property->GetChoiceSelection();
         if ( dc.GetFont().GetWeight() == wxBOLD ) state |= 2;
     }
     DrawSimpleCheckBox(dc,rect,dc.GetCharHeight(),state,dc.GetTextForeground());
@@ -1678,7 +1667,7 @@ void wxPGCheckBoxEditor::DrawValue( wxDC& dc, const wxRect& rect, wxPGProperty*
 void wxPGCheckBoxEditor::UpdateControl( wxPGProperty* property, wxWindow* ctrl ) const
 {
     wxASSERT( ctrl );
-    ((wxSimpleCheckBox*)ctrl)->m_state = property->GetChoiceInfo((wxPGChoiceInfo*)NULL);
+    ((wxSimpleCheckBox*)ctrl)->m_state = property->GetChoiceSelection();
     ctrl->Refresh();
 }
 
@@ -1700,7 +1689,7 @@ bool wxPGCheckBoxEditor::GetValueFromControl( wxVariant& variant, wxPGProperty*
 
     int index = cb->m_state;
 
-    if ( index != property->GetChoiceInfo( (wxPGChoiceInfo*) NULL ) ||
+    if ( index != property->GetChoiceSelection() ||
          // Changing unspecified always causes event (returning
          // true here should be enough to trigger it).
          property->IsValueUnspecified()
index abaa782c13ad239b571fd650b7c2a8d3137c5913..262d4648c26341ad56453be9d4cfb078337c968f 100644 (file)
@@ -210,11 +210,16 @@ void wxPGDefaultRenderer::Render( wxDC& dc, const wxRect& rect,
     // Use choice cell?
     if ( column == 1 && (flags & Control) )
     {
-        const wxPGCell* ccell = property->GetCurrentChoice();
-        if ( ccell &&
-             ( ccell->GetBitmap().IsOk() || ccell->GetFgCol().IsOk() || ccell->GetBgCol().IsOk() )
-           )
-            cell = ccell;
+        int selectedIndex = property->GetChoiceSelection();
+        if ( selectedIndex != wxNOT_FOUND )
+        {
+            const wxPGChoices& choices = property->GetChoices();
+            const wxPGCell* ccell = &choices[selectedIndex];
+            if ( ccell &&
+                 ( ccell->GetBitmap().IsOk() || ccell->GetFgCol().IsOk() || ccell->GetBgCol().IsOk() )
+               )
+                cell = ccell;
+        }
     }
 
     if ( cell )
@@ -1099,104 +1104,6 @@ void wxPGProperty::SetCell( int column, wxPGCell* cellObj )
     m_cells[column] = cellObj;
 }
 
-void wxPGProperty::SetChoiceSelection( int newValue, const wxPGChoiceInfo& choiceInfo )
-{
-    // Changes value of a property with choices, but only
-    // works if the value type is long or string.
-    wxString ts = GetValue().GetType();
-
-    wxCHECK_RET( choiceInfo.m_choices, wxT("invalid choiceinfo") );
-
-    if ( ts == wxS("long") )
-    {
-        SetValue( (long) newValue );
-    }
-    else if ( ts == wxS("string") )
-    {
-        SetValue( choiceInfo.m_choices->GetLabel(newValue) );
-    }
-}
-
-
-wxString wxPGProperty::GetChoiceString( unsigned int index )
-{
-    wxPGChoiceInfo ci;
-    GetChoiceInfo(&ci);
-    wxASSERT(ci.m_choices);
-    return ci.m_choices->GetLabel(index);
-}
-
-int wxPGProperty::InsertChoice( const wxString& label, int index, int value )
-{
-    wxPropertyGrid* pg = GetGrid();
-
-    wxPGChoiceInfo ci;
-    ci.m_choices = (wxPGChoices*) NULL;
-    int sel = GetChoiceInfo(&ci);
-
-    if ( ci.m_choices )
-    {
-        int newSel = sel;
-
-        if ( index < 0 )
-            index = ci.m_choices->GetCount();
-
-        if ( index <= sel )
-            newSel++;
-
-        ci.m_choices->Insert(label, index, value);
-
-        if ( sel != newSel )
-            SetChoiceSelection(newSel, ci);
-
-        if ( this == pg->GetSelection() )
-            GetEditorClass()->InsertItem(pg->GetEditorControl(),label,index);
-
-        return index;
-    }
-
-    return -1;
-}
-
-
-void wxPGProperty::DeleteChoice( int index )
-{
-    wxPropertyGrid* pg = GetGrid();
-
-    wxPGChoiceInfo ci;
-    ci.m_choices = (wxPGChoices*) NULL;
-    int sel = GetChoiceInfo(&ci);
-
-    if ( ci.m_choices )
-    {
-        int newSel = sel;
-
-        // Adjust current value
-        if ( sel == index )
-        {
-            SetValueToUnspecified();
-            newSel = 0;
-        }
-        else if ( index < sel )
-        {
-            newSel--;
-        }
-
-        ci.m_choices->RemoveAt(index);
-
-        if ( sel != newSel )
-            SetChoiceSelection(newSel, ci);
-
-        if ( this == pg->GetSelection() )
-            GetEditorClass()->DeleteItem(pg->GetEditorControl(), index);
-    }
-}
-
-int wxPGProperty::GetChoiceInfo( wxPGChoiceInfo* WXUNUSED(info) )
-{
-    return -1;
-}
-
 wxPGEditorDialogAdapter* wxPGProperty::GetEditorDialog() const
 {
     return NULL;
@@ -1349,63 +1256,116 @@ wxValidator* wxPGProperty::DoGetValidator() const
     return (wxValidator*) NULL;
 }
 
-wxPGChoices& wxPGProperty::GetChoices()
+int wxPGProperty::InsertChoice( const wxString& label, int index, int value )
 {
-    wxPGChoiceInfo choiceInfo;
-    choiceInfo.m_choices = NULL;
-    GetChoiceInfo(&choiceInfo);
-    return *choiceInfo.m_choices;
+    wxPropertyGrid* pg = GetGrid();
+    int sel = GetChoiceSelection();
+
+    int newSel = sel;
+
+    if ( index == wxNOT_FOUND )
+        index = m_choices.GetCount();
+
+    if ( index <= sel )
+        newSel++;
+
+    m_choices.Insert(label, index, value);
+
+    if ( sel != newSel )
+        SetChoiceSelection(newSel);
+
+    if ( this == pg->GetSelection() )
+        GetEditorClass()->InsertItem(pg->GetEditorControl(),label,index);
+
+    return index;
 }
 
-const wxPGChoices& wxPGProperty::GetChoices() const
+
+void wxPGProperty::DeleteChoice( int index )
 {
-    return (const wxPGChoices&) ((wxPGProperty*)this)->GetChoices();
+    wxPropertyGrid* pg = GetGrid();
+
+    int sel = GetChoiceSelection();
+    int newSel = sel;
+
+    // Adjust current value
+    if ( sel == index )
+    {
+        SetValueToUnspecified();
+        newSel = 0;
+    }
+    else if ( index < sel )
+    {
+        newSel--;
+    }
+
+    m_choices.RemoveAt(index);
+
+    if ( sel != newSel )
+        SetChoiceSelection(newSel);
+
+    if ( this == pg->GetSelection() )
+        GetEditorClass()->DeleteItem(pg->GetEditorControl(), index);
 }
 
-unsigned int wxPGProperty::GetChoiceCount() const
+int wxPGProperty::GetChoiceSelection() const
 {
-    const wxPGChoices& choices = GetChoices();
-    if ( &choices && choices.IsOk() )
-        return choices.GetCount();
-    return 0;
+    wxVariant value = GetValue();
+    wxString valueType = value.GetType();
+    int index = wxNOT_FOUND;
+
+    if ( IsValueUnspecified() || !m_choices.GetCount() )
+        return wxNOT_FOUND;
+
+    if ( valueType == wxPG_VARIANT_TYPE_LONG )
+    {
+        index = value.GetLong();
+    }
+    else if ( valueType == wxPG_VARIANT_TYPE_STRING )
+    {
+        index = m_choices.Index(value.GetString());
+    }
+    else if ( valueType == wxPG_VARIANT_TYPE_BOOL )
+    {
+        index = value.GetBool()? 1 : 0;
+    }
+
+    return index;
 }
 
-const wxPGChoiceEntry* wxPGProperty::GetCurrentChoice() const
+void wxPGProperty::SetChoiceSelection( int newValue )
 {
-    wxPGChoiceInfo ci;
-    ci.m_choices = (wxPGChoices*) NULL;
-    int index = ((wxPGProperty*)this)->GetChoiceInfo(&ci);
-    if ( index == -1 || !ci.m_choices || index >= (int)ci.m_choices->GetCount() )
-        return NULL;
+    // Changes value of a property with choices, but only
+    // works if the value type is long or string.
+    wxString valueType = GetValue().GetType();
+
+    wxCHECK_RET( m_choices.IsOk(), wxT("invalid choiceinfo") );
 
-    return &(*ci.m_choices)[index];
+    if ( valueType == wxPG_VARIANT_TYPE_STRING )
+    {
+        SetValue( m_choices.GetLabel(newValue) );
+    }
+    else  // if ( valueType == wxPG_VARIANT_TYPE_LONG )
+    {
+        SetValue( (long) newValue );
+    }
 }
 
 bool wxPGProperty::SetChoices( wxPGChoices& choices )
 {
-    wxPGChoiceInfo ci;
-    ci.m_choices = (wxPGChoices*) NULL;
+    m_choices.Assign(choices);
 
-    // Unref existing
-    GetChoiceInfo(&ci);
-    if ( ci.m_choices )
     {
-        ci.m_choices->Assign(choices);
-
-        //if ( m_parent )
-        {
-            // This may be needed to trigger some initialization
-            // (but don't do it if property is somewhat uninitialized)
-            wxVariant defVal = GetDefaultValue();
-            if ( defVal.IsNull() )
-                return false;
-
-            SetValue(defVal);
+        // This may be needed to trigger some initialization
+        // (but don't do it if property is somewhat uninitialized)
+        wxVariant defVal = GetDefaultValue();
+        if ( defVal.IsNull() )
+            return false;
 
-            return true;
-        }
+        SetValue(defVal);
     }
-    return false;
+
+    return true;
 }
 
 
@@ -1436,18 +1396,6 @@ const wxPGEditor* wxPGProperty::GetEditorClass() const
     return editor;
 }
 
-
-// Privatizes set of choices
-void wxPGProperty::SetChoicesExclusive()
-{
-    wxPGChoiceInfo ci;
-    ci.m_choices = (wxPGChoices*) NULL;
-
-    GetChoiceInfo(&ci);
-    if ( ci.m_choices )
-        ci.m_choices->SetExclusive();
-}
-
 bool wxPGProperty::HasVisibleChildren() const
 {
     unsigned int i;
index 11ef4ae1b9769edb4949ab67fbfdecb0c8bfeaec..fc40bcf90b45c9ac200577d573b116d19a4a5d75 100644 (file)
@@ -3397,7 +3397,7 @@ wxSize wxPropertyGrid::GetImageSize( wxPGProperty* p, int item ) const
 
     wxSize cis = p->OnMeasureImage(item);
 
-    int choiceCount = p->GetChoiceCount();
+    int choiceCount = p->m_choices.GetCount();
     int comVals = p->GetDisplayedCommonValueCount();
     if ( item >= choiceCount && comVals > 0 )
     {
index 8ee1c101dcbd587d0224c8ead58934fff3f42440..74b071871db006ec16b0b1141cfd4327649acd53 100644 (file)
@@ -221,38 +221,7 @@ wxPGProperty* wxPGPropArgCls::GetPtr( wxPropertyGridInterface* iface ) const
 }
 
 // -----------------------------------------------------------------------
-// Choice related methods
-// -----------------------------------------------------------------------
-
-void wxPropertyGridInterface::AddPropertyChoice( wxPGPropArg id,
-                                                 const wxString& label,
-                                                 int value )
-{
-    wxPG_PROP_ARG_CALL_PROLOG()
-
-    p->InsertChoice(label,-1,value);
-}
-
-
-void wxPropertyGridInterface::InsertPropertyChoice( wxPGPropArg id,
-                                                    const wxString& label,
-                                                    int index,
-                                                    int value )
-{
-    wxPG_PROP_ARG_CALL_PROLOG()
-
-    p->InsertChoice(label,index,value);
-}
-
-
-void wxPropertyGridInterface::DeletePropertyChoice( wxPGPropArg id,
-                                                    int index )
-{
-    wxPG_PROP_ARG_CALL_PROLOG()
-
-    p->DeleteChoice(index);
-}
-
+// wxPropertyGridInterface
 // -----------------------------------------------------------------------
 
 void wxPropertyGridInterface::RefreshGrid( wxPropertyGridPageState* state )
@@ -646,25 +615,6 @@ void wxPropertyGridInterface::SetBoolChoices( const wxString& trueChoice,
 
 // -----------------------------------------------------------------------
 
-wxPGChoices gs_emptyChoices;
-
-wxPGChoices& wxPropertyGridInterface::GetPropertyChoices( wxPGPropArg id )
-{
-    wxPG_PROP_ARG_CALL_PROLOG_RETVAL(gs_emptyChoices)
-
-    wxPGChoiceInfo ci;
-    ci.m_choices = (wxPGChoices*) NULL;
-
-    p->GetChoiceInfo(&ci);
-
-    if ( !ci.m_choices )
-        return gs_emptyChoices;
-
-    return *ci.m_choices;
-}
-
-// -----------------------------------------------------------------------
-
 wxPGProperty* wxPropertyGridInterface::DoGetPropertyByName( const wxString& name ) const
 {
     return m_pState->BaseGetPropertyByName(name);
index b161d8c10ddede65a70b60e3a2ebc5850bb21385..9c5433f1d07b10a3392d0899b9ae186f364a26be 100644 (file)
@@ -748,6 +748,8 @@ const wxPGEditor* wxBoolProperty::DoGetEditorClass() const
 wxBoolProperty::wxBoolProperty( const wxString& label, const wxString& name, bool value ) :
     wxPGProperty(label,name)
 {
+    m_choices.Assign(wxPGGlobalVars->m_boolChoices);
+
     SetValue(wxPGVariant_Bool(value));
 
     m_flags |= wxPG_PROP_USE_DCC;
@@ -795,16 +797,6 @@ wxString wxBoolProperty::GetValueAsString( int argFlags ) const
     return text;
 }
 
-int wxBoolProperty::GetChoiceInfo( wxPGChoiceInfo* choiceinfo )
-{
-    if ( IsValueUnspecified() )
-        return -1;
-
-    if ( choiceinfo )
-        choiceinfo->m_choices = &wxPGGlobalVars->m_boolChoices;
-    return m_value.GetBool()?1:0;
-}
-
 bool wxBoolProperty::StringToValue( wxVariant& variant, const wxString& text, int WXUNUSED(argFlags) ) const
 {
     int value = 0;
@@ -1161,17 +1153,6 @@ const wxString* wxEnumProperty::GetEntry( size_t index, int* pvalue ) const
     return (const wxString*) NULL;
 }
 
-int wxEnumProperty::GetChoiceInfo( wxPGChoiceInfo* choiceinfo )
-{
-    if ( choiceinfo )
-        choiceinfo->m_choices = &m_choices;
-
-    if ( !m_choices.IsOk() )
-        return -1;
-
-    return GetIndex();
-}
-
 // -----------------------------------------------------------------------
 // wxEditEnumProperty
 // -----------------------------------------------------------------------
@@ -1549,13 +1530,6 @@ void wxFlagsProperty::ChildChanged( wxVariant& thisValue, int childIndex, wxVari
         thisValue = (long)(oldValue & ~(vi));
 }
 
-int wxFlagsProperty::GetChoiceInfo( wxPGChoiceInfo* choiceinfo )
-{
-    if ( choiceinfo )
-        choiceinfo->m_choices = &m_choices;
-    return -1;
-}
-
 // -----------------------------------------------------------------------
 // wxDirProperty
 // -----------------------------------------------------------------------