]> git.saurik.com Git - wxWidgets.git/blobdiff - src/propgrid/propgrid.cpp
no real change: rename wxPendingEvents to wxHandlersWithPendingEvents since its curre...
[wxWidgets.git] / src / propgrid / propgrid.cpp
index 37cb0846fbae14112cb313dc255071885853f220..a2ba810891633d8a6be1a048304d8121f114be0f 100644 (file)
 
 
 //#define wxPG_TEXT_INDENT                4 // For the wxComboControl
-#define wxPG_ALLOW_CLIPPING             1 // If 1, GetUpdateRegion() in OnPaint event handler is not ignored
+//#define wxPG_ALLOW_CLIPPING             1 // If 1, GetUpdateRegion() in OnPaint event handler is not ignored
 #define wxPG_GUTTER_DIV                 3 // gutter is max(iconwidth/gutter_div,gutter_min)
 #define wxPG_GUTTER_MIN                 3 // gutter before and after image of [+] or [-]
 #define wxPG_YSPACING_MIN               1
 #define wxPG_DEFAULT_VSPACING           2 // This matches .NET propertygrid's value,
                                           // but causes normal combobox to spill out under MSW
 
-#define wxPG_OPTIMAL_WIDTH              200 // Arbitrary
+//#define wxPG_OPTIMAL_WIDTH              200 // Arbitrary
 
-#define wxPG_MIN_SCROLLBAR_WIDTH        10 // Smallest scrollbar width on any platform
+//#define wxPG_MIN_SCROLLBAR_WIDTH        10 // Smallest scrollbar width on any platform
                                            // Must be larger than largest control border
                                            // width * 2.
 
 
 //#define wxPG_NAT_CHOICE_BORDER_ANY   0
 
-#define wxPG_HIDER_BUTTON_HEIGHT        25
+//#define wxPG_HIDER_BUTTON_HEIGHT        25
 
 #define wxPG_PIXELS_PER_UNIT            m_lineHeight
 
   #define m_iconHeight m_iconWidth
 #endif
 
-#define wxPG_TOOLTIP_DELAY              1000
+//#define wxPG_TOOLTIP_DELAY              1000
 
 // -----------------------------------------------------------------------
 
@@ -134,7 +134,7 @@ void wxPropertyGrid::AutoGetTranslation ( bool ) { }
 
 // -----------------------------------------------------------------------
 
-const wxChar *wxPropertyGridNameStr = wxT("wxPropertyGrid");
+const char wxPropertyGridNameStr[] = "wxPropertyGrid";
 
 // -----------------------------------------------------------------------
 // Statics in one class for easy destruction.
@@ -231,90 +231,6 @@ void wxPropertyGridInitGlobalsIfNeeded()
 {
 }
 
-// -----------------------------------------------------------------------
-// wxPGBrush
-// -----------------------------------------------------------------------
-
-//
-// This class is a wxBrush derivative used in the background colour
-// brush cache. It adds wxPG-type colour-in-long to the class.
-// JMS: Yes I know wxBrush doesn't actually hold the value (refcounted
-//   object does), but this is simpler implementation and equally
-//   effective.
-//
-
-class wxPGBrush : public wxBrush
-{
-public:
-    wxPGBrush( const wxColour& colour );
-    wxPGBrush();
-    virtual ~wxPGBrush() { }
-    void SetColour2( const wxColour& colour );
-    inline long GetColourAsLong() const { return m_colAsLong; }
-private:
-    long    m_colAsLong;
-};
-
-
-void wxPGBrush::SetColour2( const wxColour& colour )
-{
-    wxBrush::SetColour(colour);
-    m_colAsLong = wxPG_COLOUR(colour.Red(),colour.Green(),colour.Blue());
-}
-
-
-wxPGBrush::wxPGBrush() : wxBrush()
-{
-    m_colAsLong = 0;
-}
-
-
-wxPGBrush::wxPGBrush( const wxColour& colour ) : wxBrush(colour)
-{
-    m_colAsLong = wxPG_COLOUR(colour.Red(),colour.Green(),colour.Blue());
-}
-
-
-// -----------------------------------------------------------------------
-// wxPGColour
-// -----------------------------------------------------------------------
-
-//
-// Same as wxPGBrush, but for wxColour instead.
-//
-
-class wxPGColour : public wxColour
-{
-public:
-    wxPGColour( const wxColour& colour );
-    wxPGColour();
-    virtual ~wxPGColour() { }
-    void SetColour2( const wxColour& colour );
-    inline long GetColourAsLong() const { return m_colAsLong; }
-private:
-    long    m_colAsLong;
-};
-
-
-void wxPGColour::SetColour2( const wxColour& colour )
-{
-    *this = colour;
-    m_colAsLong = wxPG_COLOUR(colour.Red(),colour.Green(),colour.Blue());
-}
-
-
-wxPGColour::wxPGColour() : wxColour()
-{
-    m_colAsLong = 0;
-}
-
-
-wxPGColour::wxPGColour( const wxColour& colour ) : wxColour(colour)
-{
-    m_colAsLong = wxPG_COLOUR(colour.Red(),colour.Green(),colour.Blue());
-}
-
-
 // -----------------------------------------------------------------------
 // wxPGTLWHandler
 //   Intercepts Close-events sent to wxPropertyGrid's top-level parent,
@@ -409,11 +325,11 @@ protected:
     }
 
     void OnPaint( wxPaintEvent& event );
-    
+
     // Always be focussable, even with child windows
     virtual void SetCanFocus(bool WXUNUSED(canFocus))
     {  wxPanel::SetCanFocus(true); }
-    
+
 
 private:
     DECLARE_EVENT_TABLE()
@@ -493,7 +409,7 @@ wxPropertyGrid::wxPropertyGrid( wxWindow *parent,
                                 const wxPoint& pos,
                                 const wxSize& size,
                                 long style,
-                                const wxChar* name )
+                                const wxString& name )
     : wxScrolledWindow()
 {
     Init1();
@@ -507,7 +423,7 @@ bool wxPropertyGrid::Create( wxWindow *parent,
                              const wxPoint& pos,
                              const wxSize& size,
                              long style,
-                             const wxChar* name )
+                             const wxString& name )
 {
 
     if ( !(style&wxBORDER_MASK) )
@@ -610,7 +526,7 @@ void wxPropertyGrid::Init2()
 #ifdef __WXMAC__
    // Smaller controls on Mac
    SetWindowVariant(wxWINDOW_VARIANT_SMALL);
-#endif 
+#endif
 
     // Now create state, if one didn't exist already
     // (wxPropertyGridManager might have created it for us).
@@ -656,15 +572,14 @@ void wxPropertyGrid::Init2()
         wxScrolledWindow::SetOwnFont( useFont );
     }
     else
+    {
         // This should be otherwise called by SetOwnFont
            CalculateFontAndBitmapStuff( wxPG_DEFAULT_VSPACING );
+    }
 
-    // Add base brush item
-    m_arrBgBrushes.Add((void*)new wxPGBrush());
-
-    // Add base colour items
-    m_arrFgCols.Add((void*)new wxPGColour());
-    m_arrFgCols.Add((void*)new wxPGColour());
+    // Allocate cell datas indirectly by calling setter
+    m_propertyDefaultCell.SetBgCol(*wxBLACK);
+    m_categoryDefaultCell.SetBgCol(*wxBLACK);
 
     RegainColours();
 
@@ -739,18 +654,6 @@ wxPropertyGrid::~wxPropertyGrid()
        delete m_collbmp;
 #endif
 
-    // Delete cached text colours.
-    for ( i=0; i<m_arrFgCols.size(); i++ )
-    {
-        delete (wxPGColour*)m_arrFgCols.Item(i);
-    }
-
-    // Delete cached brushes.
-    for ( i=0; i<m_arrBgBrushes.size(); i++ )
-    {
-        delete (wxPGBrush*)m_arrBgBrushes.Item(i);
-    }
-
     // Delete common value records
     for ( i=0; i<m_commonValues.size(); i++ )
     {
@@ -1056,8 +959,6 @@ static int wxPGGetColAvg( const wxColour& col )
 
 void wxPropertyGrid::RegainColours()
 {
-    wxColour def_bgcol = wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW );
-
     if ( !(m_coloursCustomized & 0x0002) )
     {
         wxColour col = wxSystemSettings::GetColour( wxSYS_COLOUR_BTNFACE );
@@ -1072,6 +973,7 @@ void wxPropertyGrid::RegainColours()
             m_colCapBack = wxPGAdjustColour(col,-colDec);
         else
             m_colCapBack = col;
+        m_categoryDefaultCell.GetData()->SetBgCol(m_colCapBack);
     }
 
     if ( !(m_coloursCustomized & 0x0001) )
@@ -1086,27 +988,21 @@ void wxPropertyGrid::RegainColours()
     #endif
         wxColour capForeCol = wxPGAdjustColour(m_colCapBack,colDec,5000,5000,true);
         m_colCapFore = capForeCol;
-
-        // Set the cached colour as well.
-        ((wxPGColour*)m_arrFgCols.Item(1))->SetColour2(capForeCol);
+        m_categoryDefaultCell.GetData()->SetFgCol(capForeCol);
     }
 
     if ( !(m_coloursCustomized & 0x0008) )
     {
         wxColour bgCol = wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW );
         m_colPropBack = bgCol;
-
-        // Set the cached brush as well.
-        ((wxPGBrush*)m_arrBgBrushes.Item(0))->SetColour2(bgCol);
+        m_propertyDefaultCell.GetData()->SetBgCol(bgCol);
     }
 
     if ( !(m_coloursCustomized & 0x0010) )
     {
         wxColour fgCol = wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWTEXT );
         m_colPropFore = fgCol;
-
-        // Set the cached colour as well.
-        ((wxPGColour*)m_arrFgCols.Item(0))->SetColour2(fgCol);
+        m_propertyDefaultCell.GetData()->SetFgCol(fgCol);
     }
 
     if ( !(m_coloursCustomized & 0x0020) )
@@ -1140,13 +1036,7 @@ void wxPropertyGrid::ResetColours()
 bool wxPropertyGrid::SetFont( const wxFont& font )
 {
     // Must disable active editor.
-    if ( m_selected )
-    {
-        bool selRes = ClearSelection();
-        wxPG_CHECK_MSG_DBG( selRes,
-                            false,
-                            wxT("failed to deselect a property (editor probably had invalid value)") );
-    }
+    ClearSelection(false);
 
     // TODO: Following code is disabled with wxMac because
     //   it is reported to fail. I (JMS) cannot debug it
@@ -1201,8 +1091,7 @@ void wxPropertyGrid::SetCellBackgroundColour( const wxColour& col )
     m_colPropBack = col;
     m_coloursCustomized |= 0x08;
 
-    // Set the cached brush as well.
-    ((wxPGBrush*)m_arrBgBrushes.Item(0))->SetColour2(col);
+    m_propertyDefaultCell.GetData()->SetBgCol(col);
 
     Refresh();
 }
@@ -1214,8 +1103,7 @@ void wxPropertyGrid::SetCellTextColour( const wxColour& col )
     m_colPropFore = col;
     m_coloursCustomized |= 0x10;
 
-    // Set the cached colour as well.
-    ((wxPGColour*)m_arrFgCols.Item(0))->SetColour2(col);
+    m_propertyDefaultCell.GetData()->SetFgCol(col);
 
     Refresh();
 }
@@ -1262,6 +1150,9 @@ void wxPropertyGrid::SetCaptionBackgroundColour( const wxColour& col )
 {
     m_colCapBack = col;
     m_coloursCustomized |= 0x02;
+
+    m_categoryDefaultCell.GetData()->SetBgCol(col);
+
     Refresh();
 }
 
@@ -1272,161 +1163,11 @@ void wxPropertyGrid::SetCaptionTextColour( const wxColour& col )
     m_colCapFore = col;
     m_coloursCustomized |= 0x04;
 
-    // Set the cached colour as well.
-    ((wxPGColour*)m_arrFgCols.Item(1))->SetColour2(col);
+    m_categoryDefaultCell.GetData()->SetFgCol(col);
 
     Refresh();
 }
 
-// -----------------------------------------------------------------------
-
-void wxPropertyGrid::SetBackgroundColourIndex( wxPGProperty* p, int index )
-{
-    unsigned char ind = index;
-
-    p->m_bgColIndex = ind;
-
-    unsigned int i;
-    for ( i=0; i<p->GetChildCount(); i++ )
-        SetBackgroundColourIndex(p->Item(i),index);
-}
-
-// -----------------------------------------------------------------------
-
-void wxPropertyGrid::SetPropertyBackgroundColour( wxPGPropArg id, const wxColour& colour )
-{
-    wxPG_PROP_ARG_CALL_PROLOG()
-
-    size_t i;
-    int colInd = -1;
-
-    long colAsLong = wxPG_COLOUR(colour.Red(),colour.Green(),colour.Blue());
-
-    // As it is most likely that the previous colour is used, start comparison
-    // from the end.
-    for ( i=(m_arrBgBrushes.size()-1); i>0; i-- )
-    {
-        if ( ((wxPGBrush*)m_arrBgBrushes.Item(i))->GetColourAsLong() == colAsLong )
-        {
-            colInd = i;
-            break;
-        }
-    }
-
-    if ( colInd < 0 )
-    {
-        colInd = m_arrBgBrushes.size();
-        wxCHECK_RET( colInd < 256, wxT("wxPropertyGrid: Warning - Only 255 different property background colours allowed.") );
-        m_arrBgBrushes.Add( (void*)new wxPGBrush(colour) );
-    }
-
-    // Set indexes
-    SetBackgroundColourIndex(p,colInd);
-
-    // If this was on a visible grid, then draw it.
-    DrawItemAndChildren(p);
-}
-
-// -----------------------------------------------------------------------
-
-wxColour wxPropertyGrid::GetPropertyBackgroundColour( wxPGPropArg id ) const
-{
-    wxPG_PROP_ARG_CALL_PROLOG_RETVAL(wxColour())
-
-    return ((wxPGBrush*)m_arrBgBrushes.Item(p->m_bgColIndex))->GetColour();
-}
-
-// -----------------------------------------------------------------------
-
-void wxPropertyGrid::SetTextColourIndex( wxPGProperty* p, int index, int flags )
-{
-    unsigned char ind = index;
-
-    p->m_fgColIndex = ind;
-
-    if ( p->GetChildCount() && (flags & wxPG_RECURSE) )
-    {
-        unsigned int i;
-        for ( i=0; i<p->GetChildCount(); i++ )
-            SetTextColourIndex( p->Item(i), index, flags );
-    }
-}
-
-// -----------------------------------------------------------------------
-
-int wxPropertyGrid::CacheColour( const wxColour& colour )
-{
-    unsigned int i;
-    int colInd = -1;
-
-    long colAsLong = wxPG_COLOUR(colour.Red(),colour.Green(),colour.Blue());
-
-    // As it is most likely that the previous colour is used, start comparison
-    // from the end.
-    for ( i=(m_arrFgCols.size()-1); i>0; i-- )
-    {
-        if ( ((wxPGColour*)m_arrFgCols.Item(i))->GetColourAsLong() == colAsLong )
-        {
-            colInd = i;
-            break;
-        }
-    }
-
-    if ( colInd < 0 )
-    {
-        colInd = m_arrFgCols.size();
-        wxCHECK_MSG( colInd < 256, 0, wxT("wxPropertyGrid: Warning - Only 255 different property foreground colours allowed.") );
-        m_arrFgCols.Add( (void*)new wxPGColour(colour) );
-    }
-
-    return colInd;
-}
-
-// -----------------------------------------------------------------------
-
-void wxPropertyGrid::SetPropertyTextColour( wxPGPropArg id, const wxColour& colour,
-                                            bool recursively )
-{
-    wxPG_PROP_ARG_CALL_PROLOG()
-
-    if ( p->IsCategory() )
-    {
-        wxPropertyCategory* cat = (wxPropertyCategory*) p;
-        cat->SetTextColIndex(CacheColour(colour));
-    }
-
-    // Set indexes
-    int flags = 0;
-    if ( recursively )
-        flags |= wxPG_RECURSE;
-    SetTextColourIndex(p, CacheColour(colour), flags);
-
-    DrawItemAndChildren(p);
-}
-
-// -----------------------------------------------------------------------
-
-wxColour wxPropertyGrid::GetPropertyTextColour( wxPGPropArg id ) const
-{
-    wxPG_PROP_ARG_CALL_PROLOG_RETVAL(wxColour())
-
-    return wxColour(*((wxPGColour*)m_arrFgCols.Item(p->m_fgColIndex)));
-}
-
-void wxPropertyGrid::SetPropertyColoursToDefault( wxPGPropArg id )
-{
-    wxPG_PROP_ARG_CALL_PROLOG()
-
-    SetBackgroundColourIndex( p, 0 );
-    SetTextColourIndex( p, 0, wxPG_RECURSE );
-
-    if ( p->IsCategory() )
-    {
-        wxPropertyCategory* cat = (wxPropertyCategory*) p;
-        cat->SetTextColIndex(1);
-    }
-}
-
 // -----------------------------------------------------------------------
 // wxPropertyGrid property adding and removal
 // -----------------------------------------------------------------------
@@ -1581,7 +1322,7 @@ wxString& wxPropertyGrid::ExpandEscapeSequences( wxString& dst_str, wxString& sr
 
     dst_str.clear();
 
-    for ( ; i != src_str.end(); i++ )
+    for ( ; i != src_str.end(); ++i )
     {
         wxUniChar a = *i;
 
@@ -1639,7 +1380,7 @@ wxString& wxPropertyGrid::CreateEscapeSequences( wxString& dst_str, wxString& sr
 
     dst_str.clear();
 
-    for ( ; i != src_str.end(); i++ )
+    for ( ; i != src_str.end(); ++i )
     {
         wxChar a = *i;
 
@@ -1940,13 +1681,10 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc,
 
         //
         // clipRect conversion
-        if ( clipRect )
-        {
-            cr2 = *clipRect;
-            cr2.x -= xRelMod;
-            cr2.y -= yRelMod;
-            clipRect = &cr2;
-        }
+        cr2 = *clipRect;
+        cr2.x -= xRelMod;
+        cr2.y -= yRelMod;
+        clipRect = &cr2;
         firstItemTopY -= yRelMod;
         lastItemBottomY -= yRelMod;
     }
@@ -1958,7 +1696,7 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc,
 
     const wxFont& normalfont = m_font;
 
-    bool reallyFocused = (m_iFlags & wxPG_FL_FOCUSED) ? true : false;
+    bool reallyFocused = (m_iFlags & wxPG_FL_FOCUSED) != 0;
 
     bool isEnabled = IsEnabled();
 
@@ -2035,7 +1773,7 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc,
 
         int rowHeight = m_fontHeight+(m_spacingy*2)+1;
         int textMarginHere = x;
-        int renderFlags = wxPGCellRenderer::Control;
+        int renderFlags = 0;
 
         int greyDepth = m_marginWidth;
         if ( !(windowStyle & wxPG_HIDE_CATEGORIES) )
@@ -2079,58 +1817,80 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc,
 
         dc.DrawLine( greyDepthX, y2-1, gridWidth-xRelMod, y2-1 );
 
-        if ( p == selected )
-        {
-            renderFlags |= wxPGCellRenderer::Selected;
-#if wxPG_REFRESH_CONTROLS_AFTER_REPAINT
-            wasSelectedPainted = true;
-#endif
-        }
-
-        wxColour rowBgCol;
+        //
+        // Need to override row colours?
         wxColour rowFgCol;
-        wxBrush rowBgBrush;
+        wxColour rowBgCol;
 
-        if ( p->IsCategory() )
-        {
-            if ( p->m_fgColIndex == 0 )
-                rowFgCol = m_colCapFore;
-            else
-                rowFgCol = *(wxPGColour*)m_arrFgCols[p->m_fgColIndex];
-            rowBgBrush = wxBrush(m_colCapBack);
-        }
-        else if ( p != selected )
+        if ( p != selected )
         {
             // Disabled may get different colour.
             if ( !p->IsEnabled() )
+            {
+                renderFlags |= wxPGCellRenderer::Disabled |
+                               wxPGCellRenderer::DontUseCellFgCol;
                 rowFgCol = m_colDisPropFore;
-            else
-                rowFgCol = *(wxPGColour*)m_arrFgCols[p->m_fgColIndex];
-
-            rowBgBrush = *(wxPGBrush*)m_arrBgBrushes[p->m_bgColIndex];
+            }
         }
         else
         {
-            // Selected gets different colour.
-            if ( reallyFocused )
-            {
-                rowFgCol = m_colSelFore;
-                rowBgBrush = wxBrush(m_colSelBack);
-            }
-            else if ( isEnabled )
+            renderFlags |= wxPGCellRenderer::Selected;
+
+            if ( !p->IsCategory() )
             {
-                rowFgCol = *(wxPGColour*)m_arrFgCols[p->m_fgColIndex];
-                rowBgBrush = marginBrush;
+                renderFlags |= wxPGCellRenderer::DontUseCellFgCol |
+                               wxPGCellRenderer::DontUseCellBgCol;
+
+#if wxPG_REFRESH_CONTROLS_AFTER_REPAINT
+                wasSelectedPainted = true;
+#endif
+
+                // Selected gets different colour.
+                if ( reallyFocused )
+                {
+                    rowFgCol = m_colSelFore;
+                    rowBgCol = m_colSelBack;
+                }
+                else if ( isEnabled )
+                {
+                    rowFgCol = m_colPropFore;
+                    rowBgCol = m_colMargin;
+                }
+                else
+                {
+                    rowFgCol = m_colDisPropFore;
+                    rowBgCol = m_colSelBack;
+                }
             }
-            else
+        }
+
+        wxBrush rowBgBrush;
+
+        if ( rowBgCol.IsOk() )
+            rowBgBrush = wxBrush(rowBgCol);
+
+        if ( HasInternalFlag(wxPG_FL_CELL_OVERRIDES_SEL) )
+            renderFlags = renderFlags & ~wxPGCellRenderer::DontUseCellColours;
+
+        //
+        // Fill additional margin area with background colour of first cell
+        if ( greyDepthX < textMarginHere )
+        {
+            if ( !(renderFlags & wxPGCellRenderer::DontUseCellBgCol) )
             {
-                rowFgCol = m_colDisPropFore;
-                rowBgBrush = wxBrush(m_colSelBack);
+                wxPGCell& cell = p->GetCell(0);
+                rowBgCol = cell.GetBgCol();
+                rowBgBrush = wxBrush(rowBgCol);
             }
+            dc.SetBrush(rowBgBrush);
+            dc.SetPen(rowBgCol);
+            dc.DrawRectangle(greyDepthX+1, y,
+                             textMarginHere-greyDepthX, lh-1);
         }
 
         bool fontChanged = false;
 
+        // Expander button rectangle
         wxRect butRect( ((p->m_depth - 1) * m_subgroup_extramargin) - xRelMod,
                         y,
                         m_marginWidth,
@@ -2138,18 +1898,22 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc,
 
         if ( p->IsCategory() )
         {
-            // Captions are all cells merged as one
+            // Captions have their cell areas merged as one
             dc.SetFont(m_captionFont);
             fontChanged = true;
             wxRect cellRect(greyDepthX, y, gridWidth - greyDepth + 2, rowHeight-1 );
 
-            dc.SetBrush(rowBgBrush);
-            dc.SetPen(rowBgBrush.GetColour());
-            dc.SetTextForeground(rowFgCol);
+            if ( renderFlags & wxPGCellRenderer::DontUseCellBgCol )
+            {
+                dc.SetBrush(rowBgBrush);
+                dc.SetPen(rowBgCol);
+            }
 
-            dc.DrawRectangle(cellRect);
+            if ( renderFlags & wxPGCellRenderer::DontUseCellFgCol )
+            {
+                dc.SetTextForeground(rowFgCol);
+            }
 
-            // Foreground
             wxPGCellRenderer* renderer = p->GetCellRenderer(0);
             renderer->Render( dc, cellRect, this, p, 0, -1, renderFlags );
 
@@ -2176,6 +1940,11 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc,
                 cellRect.width = nextCellWidth - 1;
 
                 bool ctrlCell = false;
+                int cellRenderFlags = renderFlags;
+
+                // Tree Item Button
+                if ( ci == 0 && !HasFlag(wxPG_HIDE_MARGIN) && p->HasVisibleChildren() )
+                    DrawExpanderButton( dc, butRect, p );
 
                 // Background
                 if ( p == selected && m_wndEditor && ci == 1 )
@@ -2184,22 +1953,24 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc,
                     dc.SetBrush(editorBgCol);
                     dc.SetPen(editorBgCol);
                     dc.SetTextForeground(m_colPropFore);
+                    dc.DrawRectangle(cellRect);
 
                     if ( m_dragStatus == 0 && !(m_iFlags & wxPG_FL_CUR_USES_CUSTOM_IMAGE) )
                         ctrlCell = true;
                 }
                 else
                 {
-                    dc.SetBrush(rowBgBrush);
-                    dc.SetPen(rowBgBrush.GetColour());
-                    dc.SetTextForeground(rowFgCol);
-                }
-
-                dc.DrawRectangle(cellRect);
+                    if ( renderFlags & wxPGCellRenderer::DontUseCellBgCol )
+                    {
+                        dc.SetBrush(rowBgBrush);
+                        dc.SetPen(rowBgCol);
+                    }
 
-                // Tree Item Button
-                if ( ci == 0 && !HasFlag(wxPG_HIDE_MARGIN) && p->HasVisibleChildren() )
-                    DrawExpanderButton( dc, butRect, p );
+                    if ( renderFlags & wxPGCellRenderer::DontUseCellFgCol )
+                    {
+                        dc.SetTextForeground(rowFgCol);
+                    }
+                }
 
                 dc.SetClippingRegion(cellRect);
 
@@ -2214,19 +1985,21 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc,
                     if ( cmnVal == -1 || ci != 1 )
                     {
                         renderer = p->GetCellRenderer(ci);
-                        renderer->Render( dc, cellRect, this, p, ci, -1, renderFlags );
+                        renderer->Render( dc, cellRect, this, p, ci, -1,
+                                          cellRenderFlags );
                     }
                     else
                     {
                         renderer = GetCommonValue(cmnVal)->GetRenderer();
-                        renderer->Render( dc, cellRect, this, p, ci, -1, renderFlags );
+                        renderer->Render( dc, cellRect, this, p, ci, -1,
+                                          cellRenderFlags );
                     }
                 }
 
                 cellX += state->m_colWidths[ci];
                 if ( ci < (state->m_colWidths.size()-1) )
                     nextCellWidth = state->m_colWidths[ci+1];
-                cellRect.x = cellX; 
+                cellRect.x = cellX;
                 dc.DestroyClippingRegion(); // Is this really necessary?
                 textXAdd = 0;
             }
@@ -2393,12 +2166,7 @@ void wxPropertyGrid::Refresh( bool WXUNUSED(eraseBackground),
 
 void wxPropertyGrid::Clear()
 {
-    if ( m_selected )
-    {
-        bool selRes = DoSelectProperty(NULL, wxPG_SEL_DELETING);  // This must be before state clear
-        wxPG_CHECK_RET_DBG( selRes,
-                            wxT("failed to deselect a property (editor probably had invalid value)") );
-    }
+    ClearSelection(false);
 
     m_pState->DoClear();
 
@@ -2417,8 +2185,7 @@ void wxPropertyGrid::Clear()
 
 bool wxPropertyGrid::EnableCategories( bool enable )
 {
-    if ( !ClearSelection() )
-        return false;
+    ClearSelection(false);
 
     if ( enable )
     {
@@ -2470,13 +2237,7 @@ void wxPropertyGrid::SwitchState( wxPropertyGridPageState* pNewState )
 
     wxPGProperty* oldSelection = m_selected;
 
-    // Deselect
-    if ( m_selected )
-    {
-        bool selRes = ClearSelection();
-        wxPG_CHECK_RET_DBG( selRes,
-                            wxT("failed to deselect a property (editor probably had invalid value)") );
-    }
+    ClearSelection(false);
 
     m_pState->m_selected = oldSelection;
 
@@ -2544,9 +2305,7 @@ void wxPropertyGrid::SortChildren( wxPGPropArg id )
 
 void wxPropertyGrid::Sort()
 {
-    bool selRes = ClearSelection();  // This must be before state clear
-    wxPG_CHECK_RET_DBG( selRes,
-                        wxT("failed to deselect a property (editor probably had invalid value)") );
+    ClearSelection(false);  // This must be before state clear
 
     m_pState->Sort();
 }
@@ -2629,7 +2388,7 @@ bool wxPropertyGrid::CommitChangesFromEditor( wxUint32 flags )
 
     // Don't do this if already processing editor event. It might
     // induce recursive dialogs and crap like that.
-    if ( m_iFlags & wxPG_FL_IN_ONCUSTOMEDITOREVENT )
+    if ( m_iFlags & wxPG_FL_IN_HANDLECUSTOMEDITOREVENT )
     {
         if ( m_inDoPropertyChanged )
             return true;
@@ -2891,28 +2650,34 @@ bool wxPropertyGrid::DoOnValidationFailure( wxPGProperty* property, wxVariant& W
     if ( (vfb & wxPG_VFB_MARK_CELL) &&
          !property->HasFlag(wxPG_PROP_INVALID_VALUE) )
     {
-        wxASSERT_MSG( !property->GetCell(0) && !property->GetCell(1),
-                      wxT("Currently wxPG_VFB_MARK_CELL only works with properties with standard first two cells") );
+        unsigned int colCount = m_pState->GetColumnCount();
+
+        // We need backup marked property's cells
+        m_propCellsBackup = property->m_cells;
 
-        if ( !property->GetCell(0) && !property->GetCell(1) )
+        wxColour vfbFg = *wxWHITE;
+        wxColour vfbBg = *wxRED;
+
+        property->EnsureCells(colCount);
+
+        for ( unsigned int i=0; i<colCount; i++ )
         {
-            wxColour vfbFg = *wxWHITE;
-            wxColour vfbBg = *wxRED;
-            property->SetCell(0, new wxPGCell(property->GetLabel(), wxNullBitmap, vfbFg, vfbBg));
-            property->SetCell(1, new wxPGCell(property->GetDisplayedString(), wxNullBitmap, vfbFg, vfbBg));
+            wxPGCell& cell = property->m_cells[i];
+            cell.SetFgCol(vfbFg);
+            cell.SetBgCol(vfbBg);
+        }
 
-            DrawItemAndChildren(property);
+        DrawItemAndChildren(property);
 
-            if ( property == m_selected )
-            {
-                SetInternalFlag(wxPG_FL_CELL_OVERRIDES_SEL);
+        if ( property == m_selected )
+        {
+            SetInternalFlag(wxPG_FL_CELL_OVERRIDES_SEL);
 
-                wxWindow* editor = GetEditorControl();
-                if ( editor )
-                {
-                    editor->SetForegroundColour(vfbFg);
-                    editor->SetBackgroundColour(vfbBg);
-                }
+            wxWindow* editor = GetEditorControl();
+            if ( editor )
+            {
+                editor->SetForegroundColour(vfbFg);
+                editor->SetBackgroundColour(vfbBg);
             }
         }
     }
@@ -2938,8 +2703,8 @@ void wxPropertyGrid::DoOnValidationFailureReset( wxPGProperty* property )
 
     if ( vfb & wxPG_VFB_MARK_CELL )
     {
-        property->SetCell(0, NULL);
-        property->SetCell(1, NULL);
+        // Revert cells
+        property->m_cells = m_propCellsBackup;
 
         ClearInternalFlag(wxPG_FL_CELL_OVERRIDES_SEL);
 
@@ -3114,29 +2879,7 @@ bool wxPropertyGrid::DoEditorValidate()
 
 // -----------------------------------------------------------------------
 
-bool wxPropertyGrid::ProcessEvent(wxEvent& event)
-{
-    wxWindow* wnd = (wxWindow*) event.GetEventObject();
-    if ( wnd && wnd->IsKindOf(CLASSINFO(wxWindow)) )
-    {
-        wxWindow* parent = wnd->GetParent();
-
-        if ( parent &&
-             (parent == m_canvas ||
-              parent->GetParent() == m_canvas) )
-        {
-            OnCustomEditorEvent((wxCommandEvent&)event);
-            return true;
-        }
-    }
-    return wxPanel::ProcessEvent(event);
-}
-
-// -----------------------------------------------------------------------
-
-// NB: It may really not be wxCommandEvent - must check if necessary
-//     (usually not).
-void wxPropertyGrid::OnCustomEditorEvent( wxCommandEvent &event )
+void wxPropertyGrid::HandleCustomEditorEvent( wxEvent &event )
 {
     wxPGProperty* selected = m_selected;
 
@@ -3145,7 +2888,7 @@ void wxPropertyGrid::OnCustomEditorEvent( wxCommandEvent &event )
     if ( !selected )
         return;
 
-    if ( m_iFlags & wxPG_FL_IN_ONCUSTOMEDITOREVENT )
+    if ( m_iFlags & wxPG_FL_IN_HANDLECUSTOMEDITOREVENT )
         return;
 
     wxVariant pendingValue(selected->GetValueRef());
@@ -3175,7 +2918,7 @@ void wxPropertyGrid::OnCustomEditorEvent( wxCommandEvent &event )
         m_prevTcValue = newTcValue;
     }
 
-    SetInternalFlag(wxPG_FL_IN_ONCUSTOMEDITOREVENT);
+    SetInternalFlag(wxPG_FL_IN_HANDLECUSTOMEDITOREVENT);
 
     bool validationFailure = false;
     bool buttonWasHandled = false;
@@ -3259,7 +3002,7 @@ void wxPropertyGrid::OnCustomEditorEvent( wxCommandEvent &event )
     else
     {
         // No value after all
-        
+
         // Regardless of editor type, unfocus editor on
         // text-editing related enter press.
         if ( event.GetEventType() == wxEVT_COMMAND_TEXT_ENTER )
@@ -3275,7 +3018,7 @@ void wxPropertyGrid::OnCustomEditorEvent( wxCommandEvent &event )
         }
     }
 
-    ClearInternalFlag(wxPG_FL_IN_ONCUSTOMEDITOREVENT);
+    ClearInternalFlag(wxPG_FL_IN_HANDLECUSTOMEDITOREVENT);
 }
 
 // -----------------------------------------------------------------------
@@ -3400,9 +3143,37 @@ void wxPropertyGrid::CustomSetCursor( int type, bool override )
 }
 
 // -----------------------------------------------------------------------
-// wxPropertyGrid property selection
+// wxPropertyGrid property selection, editor creation
 // -----------------------------------------------------------------------
 
+//
+// This class forwards events from property editor controls to wxPropertyGrid.
+class wxPropertyGridEditorEventForwarder : public wxEvtHandler
+{
+public:
+    wxPropertyGridEditorEventForwarder( wxPropertyGrid* propGrid )
+        : wxEvtHandler(), m_propGrid(propGrid)
+    {
+    }
+
+    virtual ~wxPropertyGridEditorEventForwarder()
+    {
+    }
+
+private:
+    bool ProcessEvent( wxEvent& event )
+    {
+        // Always skip
+        event.Skip();
+
+        m_propGrid->HandleCustomEditorEvent(event);
+
+        return wxEvtHandler::ProcessEvent(event);
+    }
+
+    wxPropertyGrid*         m_propGrid;
+};
+
 // Setups event handling for child control
 void wxPropertyGrid::SetupChildEventHandling( wxWindow* argWnd )
 {
@@ -3428,10 +3199,15 @@ void wxPropertyGrid::SetupChildEventHandling( wxWindow* argWnd )
         argWnd->Connect(id, wxEVT_LEAVE_WINDOW,
             wxMouseEventHandler(wxPropertyGrid::OnMouseEntry),
             NULL, this);
-        argWnd->Connect(id, wxEVT_KEY_DOWN,
-            wxCharEventHandler(wxPropertyGrid::OnChildKeyDown),
-            NULL, this);
     }
+
+    wxPropertyGridEditorEventForwarder* forwarder;
+    forwarder = new wxPropertyGridEditorEventForwarder(this);
+    argWnd->PushEventHandler(forwarder);
+
+    argWnd->Connect(id, wxEVT_KEY_DOWN,
+        wxCharEventHandler(wxPropertyGrid::OnChildKeyDown),
+        NULL, this);
 }
 
 void wxPropertyGrid::FreeEditors()
@@ -3458,6 +3234,7 @@ void wxPropertyGrid::FreeEditors()
     // Do not free editors immediately if processing events
     if ( m_wndEditor2 )
     {
+        m_wndEditor2->PopEventHandler(true);
         m_wndEditor2->Hide();
         wxPendingDelete.Append( m_wndEditor2 );
         m_wndEditor2 = (wxWindow*) NULL;
@@ -3465,6 +3242,7 @@ void wxPropertyGrid::FreeEditors()
 
     if ( m_wndEditor )
     {
+        m_wndEditor->PopEventHandler(true);
         m_wndEditor->Hide();
         wxPendingDelete.Append( m_wndEditor );
         m_wndEditor = (wxWindow*) NULL;
@@ -3474,8 +3252,6 @@ void wxPropertyGrid::FreeEditors()
 // Call with NULL to de-select property
 bool wxPropertyGrid::DoSelectProperty( wxPGProperty* p, unsigned int flags )
 {
-    wxPanel* canvas = GetPanel();
-
     /*
     if (p)
         wxLogDebug(wxT("SelectProperty( %s (%s[%i]) )"),p->m_label.c_str(),
@@ -3502,13 +3278,13 @@ bool wxPropertyGrid::DoSelectProperty( wxPGProperty* p, unsigned int flags )
         wxPrintf( "Selected %s\n", m_selected->GetClassInfo()->GetClassName() );
     else
         wxPrintf( "None selected\n" );
-    
+
     if (p)
         wxPrintf( "P =  %s\n", p->GetClassInfo()->GetClassName() );
     else
         wxPrintf( "P = NULL\n" );
 */
-  
+
     // If we are frozen, then just set the values.
     if ( m_frozen )
     {
@@ -3602,9 +3378,6 @@ bool wxPropertyGrid::DoSelectProperty( wxPGProperty* p, unsigned int flags )
 
             wxASSERT( m_wndEditor == (wxWindow*) NULL );
 
-            // Do we need OnMeasureCalls?
-            wxSize imsz = p->OnMeasureImage();
-
             //
             // Only create editor for non-disabled non-caption
             if ( !p->IsCategory() && !(p->m_flags & wxPG_PROP_DISABLED) )
@@ -3653,7 +3426,7 @@ bool wxPropertyGrid::DoSelectProperty( wxPGProperty* p, unsigned int flags )
 
                 if ( m_wndEditor )
                 {
-                    wxASSERT_MSG( m_wndEditor->GetParent() == canvas,
+                    wxASSERT_MSG( m_wndEditor->GetParent() == GetPanel(),
                                   wxT("CreateControls must use result of wxPropertyGrid::GetPanel() as parent of controls.") );
 
                     // Set validator, if any
@@ -3717,7 +3490,7 @@ bool wxPropertyGrid::DoSelectProperty( wxPGProperty* p, unsigned int flags )
 
                 if ( m_wndEditor2 )
                 {
-                    wxASSERT_MSG( m_wndEditor2->GetParent() == canvas,
+                    wxASSERT_MSG( m_wndEditor2->GetParent() == GetPanel(),
                                   wxT("CreateControls must use result of wxPropertyGrid::GetPanel() as parent of controls.") );
 
                     // Get proper id for wndSecondary
@@ -3863,6 +3636,15 @@ bool wxPropertyGrid::UnfocusEditor()
 
 // -----------------------------------------------------------------------
 
+void wxPropertyGrid::RefreshEditor()
+{
+    if ( !m_selected || !m_wndEditor || m_frozen )
+        return;
+    m_selected->UpdateControl(m_wndEditor);
+}
+
+// -----------------------------------------------------------------------
+
 // This method is not inline because it called dozens of times
 // (i.e. two-arg function calls create smaller code size).
 bool wxPropertyGrid::DoClearSelection()
@@ -3879,10 +3661,9 @@ bool wxPropertyGrid::DoCollapse( wxPGProperty* p, bool sendEvents )
     wxPGProperty* pwc = wxStaticCast(p, wxPGProperty);
 
     // If active editor was inside collapsed section, then disable it
-    if ( m_selected && m_selected->IsSomeParent (p) )
+    if ( m_selected && m_selected->IsSomeParent(p) )
     {
-        if ( !ClearSelection() )
-            return false;
+        ClearSelection(false);
     }
 
     // Store dont-center-splitter flag 'cause we need to temporarily set it
@@ -3951,7 +3732,7 @@ bool wxPropertyGrid::DoExpand( wxPGProperty* p, bool sendEvents )
     }
 
     // Clear dont-center-splitter flag if it wasn't set
-    m_iFlags = m_iFlags & ~(wxPG_FL_DONT_CENTER_SPLITTER) | old_flag;
+    m_iFlags = (m_iFlags & ~wxPG_FL_DONT_CENTER_SPLITTER) | old_flag;
 
     return res;
 }
@@ -3967,8 +3748,7 @@ bool wxPropertyGrid::DoHideProperty( wxPGProperty* p, bool hide, int flags )
          ( m_selected == p || m_selected->IsSomeParent(p) )
        )
         {
-            if ( !ClearSelection() )
-                return false;
+            ClearSelection(false);
         }
 
     m_pState->DoHideProperty(p, hide, flags);
@@ -4002,8 +3782,7 @@ void wxPropertyGrid::RecalculateVirtualSize( int forceXPos )
     if ( by1 != by2 )
     {
         wxString s = wxString::Format(wxT("VirtualHeight=%i, ActualVirtualHeight=%i, should match!"), by1, by2);
-        wxASSERT_MSG( false,
-                      s.c_str() );
+        wxFAIL_MSG(s.c_str());
         wxLogDebug(s);
     }
 #endif
@@ -4449,9 +4228,9 @@ bool wxPropertyGrid::HandleMouseMove( int x, unsigned int y, wxMouseEvent &event
         int curPropHoverY = y - (y % ih);
 
         // On which item it hovers
-        if ( ( !m_propHover )
+        if ( !m_propHover
              ||
-             ( m_propHover && ( sy < m_propHoverY || sy >= (m_propHoverY+ih) ) )
+             ( sy < m_propHoverY || sy >= (m_propHoverY+ih) )
            )
         {
             // Mouse moves on another property
@@ -4563,8 +4342,7 @@ bool wxPropertyGrid::HandleMouseMove( int x, unsigned int y, wxMouseEvent &event
             // (also not if we were dragging and its started
             // outside the splitter region)
 
-            if ( m_propHover &&
-                 !m_propHover->IsCategory() &&
+            if ( !m_propHover->IsCategory() &&
                  !event.Dragging() )
             {
 
@@ -4939,7 +4717,7 @@ void wxPropertyGrid::ClearActionTriggers( int action )
 {
     wxPGHashMapI2I::iterator it;
 
-    for ( it = m_actionTriggers.begin(); it != m_actionTriggers.end(); it++ )
+    for ( it = m_actionTriggers.begin(); it != m_actionTriggers.end(); ++it )
     {
         if ( it->second == action )
         {
@@ -4954,9 +4732,7 @@ void wxPropertyGrid::HandleKeyEvent( wxKeyEvent &event, bool fromChild )
     // Handles key event when editor control is not focused.
     //
 
-    wxASSERT( !m_frozen );
-    if ( m_frozen )
-        return;
+    wxCHECK2(!m_frozen, return);
 
     // Travelsal between items, collapsing/expanding, etc.
     int keycode = event.GetKeyCode();
@@ -4964,19 +4740,51 @@ void wxPropertyGrid::HandleKeyEvent( wxKeyEvent &event, bool fromChild )
 
     if ( keycode == WXK_TAB )
     {
+        wxWindow* mainControl;
+
+        if ( HasInternalFlag(wxPG_FL_IN_MANAGER) )
+            mainControl = GetParent();
+        else
+            mainControl = this;
+
         if ( !event.ShiftDown() )
         {
             if ( !editorFocused && m_wndEditor )
+            {
                 DoSelectProperty( m_selected, wxPG_SEL_FOCUS );
+            }
             else
+            {
+                // Tab traversal workaround for platforms on which
+                // wxWindow::Navigate() may navigate into first child
+                // instead of next sibling. Does not work perfectly
+                // in every scenario (for instance, when property grid
+                // is either first or last control).
+            #if defined(__WXGTK__)
+                wxWindow* sibling = mainControl->GetNextSibling();
+                if ( sibling )
+                    sibling->SetFocusFromKbd();
+            #else
                 Navigate(wxNavigationKeyEvent::IsForward);
+            #endif
+            }
         }
         else
         {
             if ( editorFocused )
+            {
                 UnfocusEditor();
+            }
             else
+            {
+            #if defined(__WXGTK__)
+                wxWindow* sibling = mainControl->GetPrevSibling();
+                if ( sibling )
+                    sibling->SetFocusFromKbd();
+            #else
                 Navigate(wxNavigationKeyEvent::IsBackward);
+            #endif
+            }
         }
 
         return;
@@ -5365,7 +5173,7 @@ bool wxPGStringTokenizer::HasMoreTokens()
                 }
                 else
                 {
-                    i++;
+                    ++i;
                     m_curPos = i;
                     return true;
                 }
@@ -5377,7 +5185,7 @@ bool wxPGStringTokenizer::HasMoreTokens()
                 prev_a = wxT('\0');
             }
         }
-        i++;
+        ++i;
     }
 
     m_curPos = str.end();
@@ -5402,12 +5210,6 @@ wxPGChoiceEntry::wxPGChoiceEntry()
 {
 }
 
-wxPGChoiceEntry::wxPGChoiceEntry( const wxPGChoiceEntry& entry )
-    : wxPGCell( entry.GetText(), entry.GetBitmap(),
-        entry.GetFgCol(), entry.GetBgCol() ), m_value(entry.GetValue())
-{
-}
-
 // -----------------------------------------------------------------------
 // wxPGChoicesData
 // -----------------------------------------------------------------------
@@ -5424,13 +5226,6 @@ wxPGChoicesData::~wxPGChoicesData()
 
 void wxPGChoicesData::Clear()
 {
-    unsigned int i;
-
-    for ( i=0; i<m_items.size(); i++ )
-    {
-        delete Item(i);
-    }
-
     m_items.clear();
 }
 
@@ -5438,10 +5233,32 @@ void wxPGChoicesData::CopyDataFrom( wxPGChoicesData* data )
 {
     wxASSERT( m_items.size() == 0 );
 
-    unsigned int i;
+    m_items = data->m_items;
+}
+
+wxPGChoiceEntry& wxPGChoicesData::Insert( int index,
+                                          const wxPGChoiceEntry& item )
+{
+    wxVector<wxPGChoiceEntry>::iterator it;
+    if ( index == -1 )
+    {
+        it = m_items.end();
+        index = (int) m_items.size();
+    }
+    else
+    {
+        it = m_items.begin() + index;
+    }
 
-    for ( i=0; i<data->GetCount(); i++ )
-        m_items.push_back( new wxPGChoiceEntry(*data->Item(i)) );
+    m_items.insert(it, item);
+
+    wxPGChoiceEntry& ownEntry = m_items[index];
+
+    // Need to fix value?
+    if ( ownEntry.GetValue() == wxPG_INVALID_VALUE )
+        ownEntry.SetValue(index);
+
+    return ownEntry;
 }
 
 // -----------------------------------------------------------------------
@@ -5452,9 +5269,8 @@ wxPGChoiceEntry& wxPGChoices::Add( const wxString& label, int value )
 {
     EnsureData();
 
-    wxPGChoiceEntry* p = new wxPGChoiceEntry(label, value);
-    m_data->Insert( -1, p );
-    return *p;
+    wxPGChoiceEntry entry(label, value);
+    return m_data->Insert( -1, entry );
 }
 
 // -----------------------------------------------------------------------
@@ -5463,10 +5279,9 @@ wxPGChoiceEntry& wxPGChoices::Add( const wxString& label, const wxBitmap& bitmap
 {
     EnsureData();
 
-    wxPGChoiceEntry* p = new wxPGChoiceEntry(label, value);
-    p->SetBitmap(bitmap);
-    m_data->Insert( -1, p );
-    return *p;
+    wxPGChoiceEntry entry(label, value);
+    entry.SetBitmap(bitmap);
+    return m_data->Insert( -1, entry );
 }
 
 // -----------------------------------------------------------------------
@@ -5474,10 +5289,7 @@ wxPGChoiceEntry& wxPGChoices::Add( const wxString& label, const wxBitmap& bitmap
 wxPGChoiceEntry& wxPGChoices::Insert( const wxPGChoiceEntry& entry, int index )
 {
     EnsureData();
-
-    wxPGChoiceEntry* p = new wxPGChoiceEntry(entry);
-    m_data->Insert(index, p);
-    return *p;
+    return m_data->Insert( index, entry );
 }
 
 // -----------------------------------------------------------------------
@@ -5486,9 +5298,8 @@ wxPGChoiceEntry& wxPGChoices::Insert( const wxString& label, int index, int valu
 {
     EnsureData();
 
-    wxPGChoiceEntry* p = new wxPGChoiceEntry(label, value);
-    m_data->Insert( index, p );
-    return *p;
+    wxPGChoiceEntry entry(label, value);
+    return m_data->Insert( index, entry );
 }
 
 // -----------------------------------------------------------------------
@@ -5507,9 +5318,8 @@ wxPGChoiceEntry& wxPGChoices::AddAsSorted( const wxString& label, int value )
         index++;
     }
 
-    wxPGChoiceEntry* p = new wxPGChoiceEntry(label, value);
-    m_data->Insert( index, p );
-    return *p;
+    wxPGChoiceEntry entry(label, value);
+    return m_data->Insert( index, entry );
 }
 
 // -----------------------------------------------------------------------
@@ -5525,28 +5335,11 @@ void wxPGChoices::Add( const wxChar** labels, const ValArrItem* values )
     unsigned int i;
     for ( i = 0; i < itemcount; i++ )
     {
-        int value = wxPG_INVALID_VALUE;
+        int value = i;
         if ( values )
             value = values[i];
-        m_data->Insert( -1, new wxPGChoiceEntry(labels[i], value) );
-    }
-}
-
-// -----------------------------------------------------------------------
-
-void wxPGChoices::Add( const wxArrayString& arr, const ValArrItem* values )
-{
-    EnsureData();
-
-    unsigned int i;
-    unsigned int itemcount = arr.size();
-
-    for ( i = 0; i < itemcount; i++ )
-    {
-        int value = wxPG_INVALID_VALUE;
-        if ( values )
-            value = values[i];
-        m_data->Insert( -1, new wxPGChoiceEntry(arr[i], value) );
+        wxPGChoiceEntry entry(labels[i], value);
+        m_data->Insert( i, entry );
     }
 }
 
@@ -5561,10 +5354,11 @@ void wxPGChoices::Add( const wxArrayString& arr, const wxArrayInt& arrint )
 
     for ( i = 0; i < itemcount; i++ )
     {
-        int value = wxPG_INVALID_VALUE;
+        int value = i;
         if ( &arrint && arrint.size() )
             value = arrint[i];
-        m_data->Insert( -1, new wxPGChoiceEntry(arr[i], value) );
+        wxPGChoiceEntry entry(arr[i], value);
+        m_data->Insert( i, entry );
     }
 }
 
@@ -5573,9 +5367,6 @@ void wxPGChoices::Add( const wxArrayString& arr, const wxArrayInt& arrint )
 void wxPGChoices::RemoveAt(size_t nIndex, size_t count)
 {
     wxASSERT( m_data->m_refCount != 0xFFFFFFF );
-    unsigned int i;
-    for ( i=nIndex; i<(nIndex+count); i++)
-        delete m_data->Item(i);
     m_data->m_items.erase(m_data->m_items.begin()+nIndex,
                           m_data->m_items.begin()+nIndex+count);
 }
@@ -5589,7 +5380,8 @@ int wxPGChoices::Index( const wxString& str ) const
         unsigned int i;
         for ( i=0; i< m_data->GetCount(); i++ )
         {
-            if ( m_data->Item(i)->GetText() == str )
+            const wxPGChoiceEntry& entry = m_data->Item(i);
+            if ( entry.HasText() && entry.GetText() == str )
                 return i;
         }
     }
@@ -5605,7 +5397,8 @@ int wxPGChoices::Index( int val ) const
         unsigned int i;
         for ( i=0; i< m_data->GetCount(); i++ )
         {
-            if ( m_data->Item(i)->GetValue() == val )
+            const wxPGChoiceEntry& entry = m_data->Item(i);
+            if ( entry.GetValue() == val )
                 return i;
         }
     }
@@ -5628,13 +5421,6 @@ wxArrayString wxPGChoices::GetLabels() const
 
 // -----------------------------------------------------------------------
 
-bool wxPGChoices::HasValues() const
-{
-    return true;
-}
-
-// -----------------------------------------------------------------------
-
 wxArrayInt wxPGChoices::GetValuesForStrings( const wxArrayString& strings ) const
 {
     wxArrayInt arr;
@@ -5657,7 +5443,7 @@ wxArrayInt wxPGChoices::GetValuesForStrings( const wxArrayString& strings ) cons
 
 // -----------------------------------------------------------------------
 
-wxArrayInt wxPGChoices::GetIndicesForStrings( const wxArrayString& strings, 
+wxArrayInt wxPGChoices::GetIndicesForStrings( const wxArrayString& strings,
                                               wxArrayString* unmatched ) const
 {
     wxArrayInt arr;
@@ -5856,7 +5642,8 @@ wxPGProperty* wxPropertyGridPopulator::Add( const wxString& propClass,
     m_state->DoInsert(parent, -1, property);
 
     if ( propValue )
-        property->SetValueFromString( *propValue, wxPG_FULL_VALUE );
+        property->SetValueFromString( *propValue, wxPG_FULL_VALUE|
+                                                  wxPG_PROGRAMMATIC_VALUE );
 
     return property;
 }
@@ -5909,7 +5696,7 @@ wxPGChoices wxPropertyGridPopulator::ParseChoices( const wxString& choicesString
             int state = 0;
             bool labelValid = false;
 
-            for ( ; it != choicesString.end(); it++ )
+            for ( ; it != choicesString.end(); ++it )
             {
                 wxChar c = *it;