]> git.saurik.com Git - wxWidgets.git/blobdiff - src/propgrid/propgrid.cpp
fix wxGTK1 compilation after wxTextEntry DoGetValue() change
[wxWidgets.git] / src / propgrid / propgrid.cpp
index 5418444430608b22e996e9da27d7587f0cb22285..6a5a83ab252f152c6e98dd6851b3442af05c9e51 100644 (file)
@@ -4,7 +4,7 @@
 // Author:      Jaakko Salli
 // Modified by:
 // Created:     2004-09-25
-// RCS-ID:      $Id:
+// RCS-ID:      $Id$
 // Copyright:   (c) Jaakko Salli
 // Licence:     wxWindows license
 /////////////////////////////////////////////////////////////////////////////
@@ -16,6 +16,8 @@
     #pragma hdrstop
 #endif
 
+#if wxUSE_PROPGRID
+
 #ifndef WX_PRECOMP
     #include "wx/defs.h"
     #include "wx/object.h"
@@ -38,7 +40,6 @@
     #include "wx/stattext.h"
     #include "wx/scrolwin.h"
     #include "wx/dirdlg.h"
-    #include "wx/layout.h"
     #include "wx/sizer.h"
     #include "wx/textdlg.h"
     #include "wx/filedlg.h"
 // This define is necessary to prevent macro clearing
 #define __wxPG_SOURCE_FILE__
 
-#include <wx/propgrid/propgrid.h>
-#include <wx/propgrid/editors.h>
+#include "wx/propgrid/propgrid.h"
+#include "wx/propgrid/editors.h"
 
 #if wxPG_USE_RENDERER_NATIVE
-    #include <wx/renderer.h>
+    #include "wx/renderer.h"
 #endif
 
-#include <wx/odcombo.h>
+#include "wx/odcombo.h"
 
 #include "wx/timer.h"
 #include "wx/dcbuffer.h"
-#include <wx/clipbrd.h>
-#include <wx/dataobj.h>
+#include "wx/clipbrd.h"
+#include "wx/dataobj.h"
 
 #ifdef __WXMSW__
-    #include <wx/msw/private.h>
+    #include "wx/msw/private.h"
 #endif
 
-#include <typeinfo>
-
 // Two pics for the expand / collapse buttons.
 // Files are not supplied with this project (since it is
 // recommended to use either custom or native rendering).
 
 
 //#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
 
 // -----------------------------------------------------------------------
 
@@ -135,22 +134,13 @@ void wxPropertyGrid::AutoGetTranslation ( bool ) { }
 
 // -----------------------------------------------------------------------
 
-const wxChar *wxPropertyGridNameStr = wxT("wxPropertyGrid");
+const char wxPropertyGridNameStr[] = "wxPropertyGrid";
 
 // -----------------------------------------------------------------------
 // Statics in one class for easy destruction.
-// NB: We prefer to use wxModule, as it offers more consistent behavior
-//     across platforms. However, for those rare problem situations, we
-//     also need to offer option to use simpler approach.
 // -----------------------------------------------------------------------
 
-#ifndef wxPG_USE_WXMODULE
-    #define wxPG_USE_WXMODULE 1
-#endif
-
-#if wxPG_USE_WXMODULE
-
-#include <wx/module.h>
+#include "wx/module.h"
 
 class wxPGGlobalVarsClassManager : public wxModule
 {
@@ -163,21 +153,8 @@ public:
 
 IMPLEMENT_DYNAMIC_CLASS(wxPGGlobalVarsClassManager, wxModule)
 
-#else // !wxPG_USE_WXMODULE
-
-class wxPGGlobalVarsClassManager
-{
-public:
-    wxPGGlobalVarsClassManager() {}
-    ~wxPGGlobalVarsClassManager() { delete wxPGGlobalVars; }
-};
-
-static wxPGGlobalVarsClassManager gs_pgGlobalVarsClassManager;
-
-#endif
-
 
-wxPGGlobalVarsClass* wxPGGlobalVars = (wxPGGlobalVarsClass*) NULL;
+wxPGGlobalVarsClass* wxPGGlobalVars = NULL;
 
 
 wxPGGlobalVarsClass::wxPGGlobalVarsClass()
@@ -187,7 +164,7 @@ wxPGGlobalVarsClass::wxPGGlobalVarsClass()
     m_boolChoices.Add(_("False"));
     m_boolChoices.Add(_("True"));
 
-    m_fontFamilyChoices = (wxPGChoices*) NULL;
+    m_fontFamilyChoices = NULL;
 
     m_defaultRenderer = new wxPGDefaultRenderer();
 
@@ -250,90 +227,10 @@ wxPGGlobalVarsClass::~wxPGGlobalVarsClass()
     delete wxPGProperty::sm_wxPG_LABEL;
 }
 
-// -----------------------------------------------------------------------
-// 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)
+void wxPropertyGridInitGlobalsIfNeeded()
 {
-    m_colAsLong = wxPG_COLOUR(colour.Red(),colour.Green(),colour.Blue());
 }
 
-
 // -----------------------------------------------------------------------
 // wxPGTLWHandler
 //   Intercepts Close-events sent to wxPropertyGrid's top-level parent,
@@ -427,25 +324,21 @@ protected:
         pg->OnKey( event );
     }
 
-    void OnKeyUp( wxKeyEvent& event )
-    {
-        wxPropertyGrid* pg = wxStaticCast(GetParent(), wxPropertyGrid);
-        pg->OnKeyUp( event );
-    }
+    void OnPaint( wxPaintEvent& event );
 
-    void OnNavigationKey( wxNavigationKeyEvent& event )
-    {
-        wxPropertyGrid* pg = wxStaticCast(GetParent(), wxPropertyGrid);
-        pg->OnNavigationKey( event );
-    }
+    // Always be focussable, even with child windows
+    virtual void SetCanFocus(bool WXUNUSED(canFocus))
+    {  wxPanel::SetCanFocus(true); }
 
-    void OnPaint( wxPaintEvent& event );
 
 private:
     DECLARE_EVENT_TABLE()
+    DECLARE_ABSTRACT_CLASS(wxPGCanvas)
 };
 
 
+IMPLEMENT_ABSTRACT_CLASS(wxPGCanvas,wxPanel)
+
 BEGIN_EVENT_TABLE(wxPGCanvas, wxPanel)
     EVT_MOTION(wxPGCanvas::OnMouseMove)
     EVT_PAINT(wxPGCanvas::OnPaint)
@@ -454,9 +347,6 @@ BEGIN_EVENT_TABLE(wxPGCanvas, wxPanel)
     EVT_RIGHT_UP(wxPGCanvas::OnMouseRightClick)
     EVT_LEFT_DCLICK(wxPGCanvas::OnMouseDoubleClick)
     EVT_KEY_DOWN(wxPGCanvas::OnKey)
-    EVT_KEY_UP(wxPGCanvas::OnKeyUp)
-    EVT_CHAR(wxPGCanvas::OnKey)
-    EVT_NAVIGATION_KEY(wxPGCanvas::OnNavigationKey)
 END_EVENT_TABLE()
 
 
@@ -474,6 +364,12 @@ void wxPGCanvas::OnPaint( wxPaintEvent& WXUNUSED(event) )
     // Update everything inside the box
     wxRect r = GetUpdateRegion().GetBox();
 
+    // FIXME: This is just a workaround for a bug that causes splitters not
+    //        to paint when other windows are being dragged over the grid.
+    wxRect fullRect = GetRect();
+    r.x = fullRect.x;
+    r.width = fullRect.width;
+
     // Repaint this rectangle
     pg->DrawItems( dc, r.y, r.y + r.height, &r );
 
@@ -500,7 +396,6 @@ BEGIN_EVENT_TABLE(wxPropertyGrid, wxScrolledWindow)
   EVT_CHILD_FOCUS(wxPropertyGrid::OnChildFocusEvent)
   EVT_SET_FOCUS(wxPropertyGrid::OnFocusEvent)
   EVT_KILL_FOCUS(wxPropertyGrid::OnFocusEvent)
-  EVT_TEXT_ENTER(wxPG_SUBID1,wxPropertyGrid::OnCustomEditorEvent)
   EVT_SYS_COLOUR_CHANGED(wxPropertyGrid::OnSysColourChanged)
 END_EVENT_TABLE()
 
@@ -520,7 +415,7 @@ wxPropertyGrid::wxPropertyGrid( wxWindow *parent,
                                 const wxPoint& pos,
                                 const wxSize& size,
                                 long style,
-                                const wxChar* name )
+                                const wxString& name )
     : wxScrolledWindow()
 {
     Init1();
@@ -534,7 +429,7 @@ bool wxPropertyGrid::Create( wxWindow *parent,
                              const wxPoint& pos,
                              const wxSize& size,
                              long style,
-                             const wxChar* name )
+                             const wxString& name )
 {
 
     if ( !(style&wxBORDER_MASK) )
@@ -542,18 +437,9 @@ bool wxPropertyGrid::Create( wxWindow *parent,
 
     style |= wxVSCROLL;
 
-#ifdef __WXMSW__
-    // This prevents crash under Win2K, but still
-    // enables keyboard navigation
-    if ( style & wxTAB_TRAVERSAL )
-    {
-        style &= ~(wxTAB_TRAVERSAL);
-        style |= wxWANTS_CHARS;
-    }
-#else
-    if ( style & wxTAB_TRAVERSAL )
-        style |= wxWANTS_CHARS;
-#endif
+    // Filter out wxTAB_TRAVERSAL - we will handle TABs manually
+    style &= ~(wxTAB_TRAVERSAL);
+    style |= wxWANTS_CHARS;
 
     wxScrolledWindow::Create(parent,id,pos,size,style,name);
 
@@ -569,24 +455,20 @@ bool wxPropertyGrid::Create( wxWindow *parent,
 //
 void wxPropertyGrid::Init1()
 {
-#if !wxPG_USE_WXMODULE
-    if ( !wxPGGlobalVars )
-        wxPGGlobalVars = new wxPGGlobalVarsClass();
-#endif
-
     // Register editor classes, if necessary.
     if ( wxPGGlobalVars->m_mapEditorClasses.empty() )
-        RegisterDefaultEditors();
+        wxPropertyGrid::RegisterDefaultEditors();
 
     m_iFlags = 0;
-    m_pState = (wxPropertyGridPageState*) NULL;
-    m_wndEditor = m_wndEditor2 = (wxWindow*) NULL;
-    m_selected = (wxPGProperty*) NULL;
+    m_pState = NULL;
+    m_wndEditor = m_wndEditor2 = NULL;
+    m_selected = NULL;
     m_selColumn = -1;
-    m_propHover = (wxPGProperty*) NULL;
+    m_propHover = NULL;
     m_eventObject = this;
-    m_curFocused = (wxWindow*) NULL;
+    m_curFocused = NULL;
     m_tlwHandler = NULL;
+    m_sortFunction = NULL;
     m_inDoPropertyChanged = 0;
     m_inCommitChangesFromEditor = 0;
     m_inDoSelectProperty = 0;
@@ -603,12 +485,8 @@ void wxPropertyGrid::Init1()
     AddActionTrigger( wxPG_ACTION_EXPAND_PROPERTY, WXK_RIGHT);
     AddActionTrigger( wxPG_ACTION_COLLAPSE_PROPERTY, WXK_LEFT);
     AddActionTrigger( wxPG_ACTION_CANCEL_EDIT, WXK_ESCAPE );
-    AddActionTrigger( wxPG_ACTION_CUT, 'X', wxMOD_CONTROL );
-    AddActionTrigger( wxPG_ACTION_CUT, WXK_DELETE, wxMOD_SHIFT );
-    AddActionTrigger( wxPG_ACTION_COPY, 'C', wxMOD_CONTROL);
-    AddActionTrigger( wxPG_ACTION_COPY, WXK_INSERT, wxMOD_CONTROL );
-    AddActionTrigger( wxPG_ACTION_PASTE, 'V', wxMOD_CONTROL );
-    AddActionTrigger( wxPG_ACTION_PASTE, WXK_INSERT, wxMOD_SHIFT );
+    AddActionTrigger( wxPG_ACTION_PRESS_BUTTON, WXK_DOWN, wxMOD_ALT );
+    AddActionTrigger( wxPG_ACTION_PRESS_BUTTON, WXK_F4 );
 
     m_coloursCustomized = 0;
     m_frozen = 0;
@@ -616,11 +494,9 @@ void wxPropertyGrid::Init1()
     m_canvas = NULL;
 
 #if wxPG_DOUBLE_BUFFER
-    m_doubleBuffer = (wxBitmap*) NULL;
+    m_doubleBuffer = NULL;
 #endif
 
-    m_windowsToDelete = NULL;
-
 #ifndef wxPG_ICON_WIDTH
        m_expandbmp = NULL;
        m_collbmp = NULL;
@@ -639,10 +515,6 @@ void wxPropertyGrid::Init1()
 
     m_width = m_height = 0;
 
-    SetButtonShortcut(0);
-
-    m_keyComboConsumed = 0;
-
     m_commonValues.push_back(new wxPGCommonValue(_("Unspecified"), wxPGGlobalVars->m_defaultRenderer) );
     m_cvUnspecified = 0;
 
@@ -661,7 +533,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).
@@ -701,21 +573,11 @@ void wxPropertyGrid::Init2()
        // adjust bitmap icon y position so they are centered
     m_vspacing = wxPG_DEFAULT_VSPACING;
 
-    if ( !m_font.Ok() )
-    {
-        wxFont useFont = wxScrolledWindow::GetFont();
-        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());
+    CalculateFontAndBitmapStuff( wxPG_DEFAULT_VSPACING );
 
-    // 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();
 
@@ -736,7 +598,7 @@ void wxPropertyGrid::Init2()
 
     m_canvas = new wxPGCanvas();
     m_canvas->Create(this, 1, wxPoint(0, 0), GetClientSize(),
-                     (GetWindowStyle() & wxTAB_TRAVERSAL) | wxWANTS_CHARS | wxCLIP_CHILDREN);
+                     wxWANTS_CHARS | wxCLIP_CHILDREN);
     m_canvas->SetBackgroundStyle( wxBG_STYLE_CUSTOM );
 
     m_iFlags |= wxPG_FL_INITIALIZED;
@@ -778,9 +640,7 @@ wxPropertyGrid::~wxPropertyGrid()
         delete m_doubleBuffer;
 #endif
 
-    delete m_windowsToDelete;
-
-    //m_selected = (wxPGProperty*) NULL;
+    //m_selected = NULL;
 
     if ( m_iFlags & wxPG_FL_CREATEDSTATE )
         delete m_pState;
@@ -792,18 +652,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++ )
     {
@@ -877,7 +725,7 @@ void wxPropertyGrid::SetWindowStyleFlag( long style )
             //
             // Tooltips disabled
             //
-            m_canvas->SetToolTip( (wxToolTip*) NULL );
+            m_canvas->SetToolTip( NULL );
         }
     #endif
     }
@@ -1109,8 +957,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 );
@@ -1125,6 +971,7 @@ void wxPropertyGrid::RegainColours()
             m_colCapBack = wxPGAdjustColour(col,-colDec);
         else
             m_colCapBack = col;
+        m_categoryDefaultCell.GetData()->SetBgCol(m_colCapBack);
     }
 
     if ( !(m_coloursCustomized & 0x0001) )
@@ -1139,27 +986,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) )
@@ -1193,39 +1034,16 @@ 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
-    //   personally right now.
-#if !defined(__WXMAC__)
     bool res = wxScrolledWindow::SetFont( font );
     if ( res )
     {
         CalculateFontAndBitmapStuff( m_vspacing );
-
-        if ( m_pState )
-            m_pState->CalculateFontAndBitmapStuff(m_vspacing);
-
         Refresh();
     }
 
     return res;
-#else
-    // ** wxMAC Only **
-    // TODO: Remove after SetFont crash fixed.
-    if ( m_iFlags & wxPG_FL_INITIALIZED )
-    {
-        wxLogDebug(wxT("WARNING: propGrid.cpp: wxPropertyGrid::SetFont has been disabled on wxMac since there has been crash reported in it. If you are willing to debug the cause, replace line '#if !defined(__WXMAC__)' with line '#if 1' in wxPropertyGrid::SetFont."));
-    }
-    return false;
-#endif
 }
 
 // -----------------------------------------------------------------------
@@ -1253,8 +1071,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();
 }
@@ -1266,8 +1083,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();
 }
@@ -1314,6 +1130,9 @@ void wxPropertyGrid::SetCaptionBackgroundColour( const wxColour& col )
 {
     m_colCapBack = col;
     m_coloursCustomized |= 0x02;
+
+    m_categoryDefaultCell.GetData()->SetBgCol(col);
+
     Refresh();
 }
 
@@ -1324,161 +1143,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
 // -----------------------------------------------------------------------
@@ -1490,44 +1159,15 @@ void wxPropertyGrid::PrepareAfterItemsAdded()
     m_pState->m_itemsAdded = 0;
 
     if ( m_windowStyle & wxPG_AUTO_SORT )
-        Sort();
+        Sort(wxPG_SORT_TOP_LEVEL_ONLY);
 
     RecalculateVirtualSize();
 }
 
-// -----------------------------------------------------------------------
-// wxPropertyGrid property value setting and getting
-// -----------------------------------------------------------------------
-
-void wxPropertyGrid::DoSetPropertyValueUnspecified( wxPGProperty* p )
-{
-    m_pState->DoSetPropertyValueUnspecified(p);
-    DrawItemAndChildren(p);
-
-    wxPGProperty* parent = p->GetParent();
-    while ( (parent->GetFlags() & wxPG_PROP_PARENTAL_FLAGS) == wxPG_PROP_MISC_PARENT )
-    {
-        DrawItem(parent);
-        parent = parent->GetParent();
-    }
-}
-
 // -----------------------------------------------------------------------
 // wxPropertyGrid property operations
 // -----------------------------------------------------------------------
 
-void wxPropertyGrid::DoSetPropertyName( wxPGProperty* p, const wxString& newname )
-{
-    wxCHECK_RET( p, wxT("invalid property id") );
-
-    if ( p->GetBaseName().Len() ) m_pState->m_dictName.erase( p->GetBaseName() );
-    if ( newname.Len() ) m_pState->m_dictName[newname] = (void*) p;
-
-    p->DoSetName(newname);
-}
-
-// -----------------------------------------------------------------------
-
 bool wxPropertyGrid::EnsureVisible( wxPGPropArg id )
 {
     wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false)
@@ -1644,7 +1284,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;
 
@@ -1702,7 +1342,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;
 
@@ -1743,7 +1383,7 @@ wxPGProperty* wxPropertyGrid::DoGetItemAtY( int y ) const
 {
     // Outside?
     if ( y < 0 )
-        return (wxPGProperty*) NULL;
+        return NULL;
 
     unsigned int a = 0;
     return m_pState->m_properties->GetItemAtY(y, m_lineHeight, &a);
@@ -1895,7 +1535,7 @@ void wxPropertyGrid::DrawItems( wxDC& dc,
         if ( dcPtr )
         {
             dc.SetClippingRegion( *clipRect );
-            paintFinishY = DoDrawItems( *dcPtr, NULL, NULL, clipRect, isBuffered );
+            paintFinishY = DoDrawItems( *dcPtr, clipRect, isBuffered );
         }
 
     #if wxPG_DOUBLE_BUFFER
@@ -1921,30 +1561,17 @@ void wxPropertyGrid::DrawItems( wxDC& dc,
 // -----------------------------------------------------------------------
 
 int wxPropertyGrid::DoDrawItems( wxDC& dc,
-                                 const wxPGProperty* firstItem,
-                                 const wxPGProperty* lastItem,
                                  const wxRect* clipRect,
                                  bool isBuffered ) const
 {
-    // TODO: This should somehow be eliminated.
-    wxRect tempClipRect;
-    if ( !clipRect )
-    {
-        wxASSERT(firstItem);
-        wxASSERT(lastItem);
-        tempClipRect = GetPropertyRect(firstItem, lastItem);
-        clipRect = &tempClipRect;
-    }
+    const wxPGProperty* firstItem;
+    const wxPGProperty* lastItem;
 
-    if ( !firstItem )
-        firstItem = DoGetItemAtY(clipRect->y);
+    firstItem = DoGetItemAtY(clipRect->y);
+    lastItem = DoGetItemAtY(clipRect->y+clipRect->height-1);
 
     if ( !lastItem )
-    {
-        lastItem = DoGetItemAtY(clipRect->y+clipRect->height-1);
-        if ( !lastItem )
-            lastItem = GetLastItem( wxPG_ITERATE_VISIBLE );
-    }
+        lastItem = GetLastItem( wxPG_ITERATE_VISIBLE );
 
     if ( m_frozen || m_height < 1 || firstItem == NULL )
         return clipRect->y;
@@ -2003,13 +1630,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;
     }
@@ -2019,9 +1643,9 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc,
 
     int x = m_marginWidth - xRelMod;
 
-    const wxFont& normalfont = m_font;
+    wxFont normalFont = GetFont();
 
-    bool reallyFocused = (m_iFlags & wxPG_FL_FOCUSED) ? true : false;
+    bool reallyFocused = (m_iFlags & wxPG_FL_FOCUSED) != 0;
 
     bool isEnabled = IsEnabled();
 
@@ -2056,7 +1680,7 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc,
 
     // TODO: Only render columns that are within clipping region.
 
-    dc.SetFont(normalfont);
+    dc.SetFont(normalFont);
 
     wxPropertyGridConstIterator it( state, wxPG_ITERATE_VISIBLE, firstItem );
     int endScanBottomY = lastItemBottomY + lh;
@@ -2098,7 +1722,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) )
@@ -2142,77 +1766,103 @@ 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 )
-            {
-                rowFgCol = *(wxPGColour*)m_arrFgCols[p->m_fgColIndex];
-                rowBgBrush = marginBrush;
-            }
-            else
+            renderFlags |= wxPGCellRenderer::Selected;
+
+            if ( !p->IsCategory() )
             {
-                rowFgCol = m_colDisPropFore;
-                rowBgBrush = wxBrush(m_colSelBack);
-            }
-        }
+                renderFlags |= wxPGCellRenderer::DontUseCellFgCol |
+                               wxPGCellRenderer::DontUseCellBgCol;
 
-        bool fontChanged = false;
+#if wxPG_REFRESH_CONTROLS_AFTER_REPAINT
+                wasSelectedPainted = true;
+#endif
 
-        wxRect butRect( ((p->m_depth - 1) * m_subgroup_extramargin) - xRelMod,
-                        y,
-                        m_marginWidth,
+                // 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;
+                }
+            }
+        }
+
+        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) )
+            {
+                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,
                         lh );
 
         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 );
 
@@ -2230,7 +1880,8 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc,
 
             unsigned int ci;
             int cellX = x + 1;
-            int nextCellWidth = state->m_colWidths[0];
+            int nextCellWidth = state->m_colWidths[0] -
+                                (greyDepthX - m_marginWidth);
             wxRect cellRect(greyDepthX+1, y, 0, rowHeight-1);
             int textXAdd = textMarginHere - greyDepthX;
 
@@ -2239,6 +1890,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 )
@@ -2247,22 +1903,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);
 
@@ -2277,26 +1935,28 @@ 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;
             }
         }
 
         if ( fontChanged )
-            dc.SetFont(normalfont);
+            dc.SetFont(normalFont);
 
         y += rowHeight;
     }
@@ -2324,7 +1984,7 @@ wxRect wxPropertyGrid::GetPropertyRect( const wxPGProperty* p1, const wxPGProper
 
     if ( m_width < 10 || m_height < 10 ||
          !m_pState->m_properties->GetChildCount() ||
-         p1 == (wxPGProperty*) NULL )
+         p1 == NULL )
         return wxRect(0,0,0,0);
 
     int vy = 0;
@@ -2420,11 +2080,9 @@ void wxPropertyGrid::DrawItemAndChildren( wxPGProperty* p )
     if ( m_pState->m_itemsAdded || m_frozen )
         return;
 
-    wxWindow* wndPrimary = GetEditorControl();
-
     // Update child control.
     if ( m_selected && m_selected->GetParent() == p )
-        m_selected->UpdateControl(wndPrimary);
+        RefreshEditor();
 
     const wxPGProperty* lastDrawn = p->GetLastVisibleSubItem();
 
@@ -2456,13 +2114,6 @@ 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)") );
-    }
-
     m_pState->DoClear();
 
     m_propHover = NULL;
@@ -2480,8 +2131,7 @@ void wxPropertyGrid::Clear()
 
 bool wxPropertyGrid::EnableCategories( bool enable )
 {
-    if ( !ClearSelection() )
-        return false;
+    ClearSelection(false);
 
     if ( enable )
     {
@@ -2533,13 +2183,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;
 
@@ -2569,7 +2213,7 @@ void wxPropertyGrid::SwitchState( wxPropertyGridPageState* pNewState )
         pNewState->OnClientWidthChange( pgWidth, pgWidth - pNewState->m_width );
     }
 
-    m_propHover = (wxPGProperty*) NULL;
+    m_propHover = NULL;
 
     // If necessary, convert state to correct mode.
     if ( orig_mode != new_state_mode )
@@ -2580,8 +2224,7 @@ void wxPropertyGrid::SwitchState( wxPropertyGridPageState* pNewState )
     else if ( !m_frozen )
     {
         // Refresh, if not frozen.
-        if ( m_pState->m_itemsAdded )
-            PrepareAfterItemsAdded();
+        m_pState->PrepareAfterItemsAdded();
 
         // Reselect
         if ( m_pState->m_selected )
@@ -2596,26 +2239,6 @@ void wxPropertyGrid::SwitchState( wxPropertyGridPageState* pNewState )
 
 // -----------------------------------------------------------------------
 
-void wxPropertyGrid::SortChildren( wxPGPropArg id )
-{
-    wxPG_PROP_ARG_CALL_PROLOG()
-
-    m_pState->SortChildren( p );
-}
-
-// -----------------------------------------------------------------------
-
-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)") );
-
-    m_pState->Sort();
-}
-
-// -----------------------------------------------------------------------
-
 // Call to SetSplitterPosition will always disable splitter auto-centering
 // if parent window is shown.
 void wxPropertyGrid::DoSetSplitterPosition_( int newxpos, bool refresh, int splitterIndex, bool allPages )
@@ -2677,24 +2300,6 @@ wxPGProperty* wxPropertyGrid::GetNearestPaintVisible( wxPGProperty* p ) const
 
 }
 
-// -----------------------------------------------------------------------
-
-void wxPropertyGrid::SetButtonShortcut( int keycode, bool ctrlDown, bool altDown )
-{
-    if ( keycode )
-    {
-        m_pushButKeyCode = keycode;
-        m_pushButKeyCodeNeedsCtrl = ctrlDown ? 1 : 0;
-        m_pushButKeyCodeNeedsAlt = altDown ? 1 : 0;
-    }
-    else
-    {
-        m_pushButKeyCode = WXK_DOWN;
-        m_pushButKeyCodeNeedsCtrl = 0;
-        m_pushButKeyCodeNeedsAlt = 1;
-    }
-}
-
 // -----------------------------------------------------------------------
 // Methods related to change in value, value modification and sending events
 // -----------------------------------------------------------------------
@@ -2710,7 +2315,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;
@@ -2790,7 +2395,8 @@ bool wxPropertyGrid::CommitChangesFromEditor( wxUint32 flags )
 
 // -----------------------------------------------------------------------
 
-bool wxPropertyGrid::PerformValidation( wxPGProperty* p, wxVariant& pendingValue )
+bool wxPropertyGrid::PerformValidation( wxPGProperty* p, wxVariant& pendingValue,
+                                        int flags )
 {
     //
     // Runs all validation functionality.
@@ -2859,33 +2465,37 @@ bool wxPropertyGrid::PerformValidation( wxPGProperty* p, wxVariant& pendingValue
 
     wxVariant evtChangingValue = value;
 
-    // FIXME: After proper ValueToString()s added, remove
-    // this. It is just a temporary fix, as evt_changing
-    // will simply not work for wxPG_PROP_COMPOSED_VALUE
-    // (unless it is selected, and textctrl editor is open).
-    if ( changedProperty->HasFlag(wxPG_PROP_COMPOSED_VALUE) )
+    if ( flags & SendEvtChanging )
     {
-        evtChangingProperty = baseChangedProperty;
-        if ( evtChangingProperty != p )
+        // FIXME: After proper ValueToString()s added, remove
+        // this. It is just a temporary fix, as evt_changing
+        // will simply not work for wxPG_PROP_COMPOSED_VALUE
+        // (unless it is selected, and textctrl editor is open).
+        if ( changedProperty->HasFlag(wxPG_PROP_COMPOSED_VALUE) )
         {
-            evtChangingProperty->AdaptListToValue( bcpPendingList, &evtChangingValue );
-        }
-        else
-        {
-            evtChangingValue = pendingValue;
+            evtChangingProperty = baseChangedProperty;
+            if ( evtChangingProperty != p )
+            {
+                evtChangingProperty->AdaptListToValue( bcpPendingList, &evtChangingValue );
+            }
+            else
+            {
+                evtChangingValue = pendingValue;
+            }
         }
-    }
 
-    if ( evtChangingProperty->HasFlag(wxPG_PROP_COMPOSED_VALUE) )
-    {
-        if ( changedProperty == m_selected )
-        {
-            wxASSERT( m_wndEditor->IsKindOf(CLASSINFO(wxTextCtrl)) );
-            evtChangingValue = ((wxTextCtrl*)m_wndEditor)->GetValue();
-        }
-        else
+        if ( evtChangingProperty->HasFlag(wxPG_PROP_COMPOSED_VALUE) )
         {
-            wxLogDebug(wxT("WARNING: wxEVT_PG_CHANGING is about to happen with old value."));
+            if ( changedProperty == m_selected )
+            {
+                wxWindow* editor = GetEditorControl();
+                wxASSERT( editor->IsKindOf(CLASSINFO(wxTextCtrl)) );
+                evtChangingValue = wxStaticCast(editor, wxTextCtrl)->GetValue();
+            }
+            else
+            {
+                wxLogDebug(wxT("WARNING: wxEVT_PG_CHANGING is about to happen with old value."));
+            }
         }
     }
 
@@ -2907,9 +2517,20 @@ bool wxPropertyGrid::PerformValidation( wxPGProperty* p, wxVariant& pendingValue
             return false;
     }
 
-    // SendEvent returns true if event was vetoed
-    if ( SendEvent( wxEVT_PG_CHANGING, evtChangingProperty, &evtChangingValue, 0 ) )
-        return false;
+    if ( flags & SendEvtChanging )
+    {
+        // SendEvent returns true if event was vetoed
+        if ( SendEvent( wxEVT_PG_CHANGING, evtChangingProperty, &evtChangingValue, 0 ) )
+            return false;
+    }
+
+    if ( flags & IsStandaloneValidation )
+    {
+        // If called in 'generic' context, we need to reset
+        // m_chgInfo_changedProperty and write back translated value.
+        m_chgInfo_changedProperty = NULL;
+        pendingValue = value;
+    }
 
     return true;
 }
@@ -2946,6 +2567,29 @@ void wxPropertyGrid::DoShowPropertyError( wxPGProperty* WXUNUSED(property), cons
 
 // -----------------------------------------------------------------------
 
+bool wxPropertyGrid::OnValidationFailure( wxPGProperty* property,
+                                          wxVariant& invalidValue )
+{
+    wxWindow* editor = GetEditorControl();
+
+    // First call property's handler
+    property->OnValidationFailure(invalidValue);
+
+    bool res = DoOnValidationFailure(property, invalidValue);
+
+    //
+    // For non-wxTextCtrl editors, we do need to revert the value
+    if ( !editor->IsKindOf(CLASSINFO(wxTextCtrl)) &&
+         property == m_selected )
+    {
+        property->GetEditorClass()->UpdateControl(property, editor);
+    }
+
+    property->SetFlag(wxPG_PROP_INVALID_VALUE);
+
+    return res;
+}
+
 bool wxPropertyGrid::DoOnValidationFailure( wxPGProperty* property, wxVariant& WXUNUSED(invalidValue) )
 {
     int vfb = m_validationInfo.m_failureBehavior;
@@ -2956,28 +2600,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();
 
-        if ( !property->GetCell(0) && !property->GetCell(1) )
+        // We need backup marked property's cells
+        m_propCellsBackup = property->m_cells;
+
+        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);
             }
         }
     }
@@ -3003,8 +2653,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);
 
@@ -3090,8 +2740,7 @@ bool wxPropertyGrid::DoPropertyChanged( wxPGProperty* p, unsigned int selFlags )
     // control.
     if ( selFlags & wxPG_SEL_DIALOGVAL )
     {
-        if ( editor )
-            p->GetEditorClass()->UpdateControl(p, editor);
+        RefreshEditor();
     }
     else
     {
@@ -3147,88 +2796,48 @@ bool wxPropertyGrid::ChangePropertyValue( wxPGPropArg id, wxVariant newValue )
 
 // -----------------------------------------------------------------------
 
-// Runs wxValidator for the selected property
-bool wxPropertyGrid::DoEditorValidate()
+wxVariant wxPropertyGrid::GetUncommittedPropertyValue()
 {
-#if wxUSE_VALIDATORS
-    // With traditional validator style, we dont need to more
-    if ( !(GetExtraStyle() & wxPG_EX_LEGACY_VALIDATORS) )
-        return true;
+    wxPGProperty* prop = GetSelectedProperty();
 
-    if ( m_iFlags & wxPG_FL_VALIDATION_FAILED )
-    {
-        return false;
-    }
+    if ( !prop )
+        return wxNullVariant;
 
-    wxWindow* wnd = GetEditorControl();
+    wxTextCtrl* tc = GetEditorTextCtrl();
+    wxVariant value = prop->GetValue();
 
-    wxValidator* validator = m_selected->GetValidator();
-    if ( validator && wnd )
-    {
-        // Use TextCtrl of ODComboBox instead
-        if ( wnd->IsKindOf(CLASSINFO(wxOwnerDrawnComboBox)) )
-        {
-            wnd = ((wxOwnerDrawnComboBox*)wnd)->GetTextCtrl();
+    if ( !tc || !IsEditorsValueModified() )
+        return value;
 
-            if ( !wnd )
-                return true;
-        }
+    if ( !prop->StringToValue(value, tc->GetValue()) )
+        return value;
 
-        validator->SetWindow(wnd);
+    if ( !PerformValidation(prop, value, IsStandaloneValidation) )
+        return prop->GetValue();
 
-        // Instead setting the flag after the failure, we set
-        // it before checking and then clear afterwards if things
-        // went fine. This trick is necessary since focus events
-        // may be triggered while in Validate.
-        m_iFlags |= wxPG_FL_VALIDATION_FAILED;
-        if ( !validator->Validate(this) )
-        {
-            // If you dpm't want to display message multiple times per change,
-            // comment the following line.
-            m_iFlags &= ~(wxPG_FL_VALIDATION_FAILED);
-            return false;
-        }
-        m_iFlags &= ~(wxPG_FL_VALIDATION_FAILED);
-    }
-#endif
-    return true;
+    return value;
 }
 
 // -----------------------------------------------------------------------
 
-bool wxPropertyGrid::ProcessEvent(wxEvent& event)
+// Runs wxValidator for the selected property
+bool wxPropertyGrid::DoEditorValidate()
 {
-    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);
+    return true;
 }
 
 // -----------------------------------------------------------------------
 
-// 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;
 
-    //
     // Somehow, event is handled after property has been deselected.
     // Possibly, but very rare.
     if ( !selected )
         return;
 
-    if ( m_iFlags & wxPG_FL_IN_ONCUSTOMEDITOREVENT )
+    if ( m_iFlags & wxPG_FL_IN_HANDLECUSTOMEDITOREVENT )
         return;
 
     wxVariant pendingValue(selected->GetValueRef());
@@ -3258,7 +2867,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;
@@ -3280,22 +2889,25 @@ void wxPropertyGrid::OnCustomEditorEvent( wxCommandEvent &event )
         }
     }
 
-    if ( wnd && !buttonWasHandled )
+    if ( !buttonWasHandled )
     {
-        // First call editor class' event handler.
-        const wxPGEditor* editor = selected->GetEditorClass();
-
-        if ( editor->OnEvent( this, selected, wnd, event ) )
+        if ( wnd )
         {
-            // If changes, validate them
-            if ( DoEditorValidate() )
-            {
-                if ( editor->GetValueFromControl( pendingValue, m_selected, wnd ) )
-                    valueIsPending = true;
-            }
-            else
+            // First call editor class' event handler.
+            const wxPGEditor* editor = selected->GetEditorClass();
+
+            if ( editor->OnEvent( this, selected, wnd, event ) )
             {
-                validationFailure = true;
+                // If changes, validate them
+                if ( DoEditorValidate() )
+                {
+                    if ( editor->GetValueFromControl( pendingValue, m_selected, wnd ) )
+                        valueIsPending = true;
+                }
+                else
+                {
+                    validationFailure = true;
+                }
             }
         }
 
@@ -3318,7 +2930,7 @@ void wxPropertyGrid::OnCustomEditorEvent( wxCommandEvent &event )
         if ( !PerformValidation(m_selected, pendingValue) )
             validationFailure = true;
 
-    if ( validationFailure )
+    if ( validationFailure)
     {
         OnValidationFailure(selected, pendingValue);
     }
@@ -3328,11 +2940,25 @@ void wxPropertyGrid::OnCustomEditorEvent( wxCommandEvent &event )
 
         DoPropertyChanged(selected, selFlags);
         EditorsValueWasNotModified();
+
+        // Regardless of editor type, unfocus editor on
+        // text-editing related enter press.
+        if ( event.GetEventType() == wxEVT_COMMAND_TEXT_ENTER )
+        {
+            SetFocusOnCanvas();
+        }
     }
     else
     {
         // No value after all
 
+        // Regardless of editor type, unfocus editor on
+        // text-editing related enter press.
+        if ( event.GetEventType() == wxEVT_COMMAND_TEXT_ENTER )
+        {
+            SetFocusOnCanvas();
+        }
+
         // Let unhandled button click events go to the parent
         if ( !buttonWasHandled && event.GetEventType() == wxEVT_COMMAND_BUTTON_CLICKED )
         {
@@ -3341,7 +2967,7 @@ void wxPropertyGrid::OnCustomEditorEvent( wxCommandEvent &event )
         }
     }
 
-    ClearInternalFlag(wxPG_FL_IN_ONCUSTOMEDITOREVENT);
+    ClearInternalFlag(wxPG_FL_IN_HANDLECUSTOMEDITOREVENT);
 }
 
 // -----------------------------------------------------------------------
@@ -3395,7 +3021,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 )
     {
@@ -3466,56 +3092,111 @@ void wxPropertyGrid::CustomSetCursor( int type, bool override )
 }
 
 // -----------------------------------------------------------------------
-// wxPropertyGrid property selection
+// wxPropertyGrid property selection, editor creation
 // -----------------------------------------------------------------------
 
-#define CONNECT_CHILD(EVT,FUNCTYPE,FUNC) \
-    wnd->Connect(id, EVT, \
-        (wxObjectEventFunction) (wxEventFunction)  \
-        FUNCTYPE (&wxPropertyGrid::FUNC), \
-        NULL, this );
-
-// Setups event handling for child control
-void wxPropertyGrid::SetupEventHandling( wxWindow* argWnd, int id )
+//
+// This class forwards events from property editor controls to wxPropertyGrid.
+class wxPropertyGridEditorEventForwarder : public wxEvtHandler
 {
-    wxWindow* wnd = argWnd;
+public:
+    wxPropertyGridEditorEventForwarder( wxPropertyGrid* propGrid )
+        : wxEvtHandler(), m_propGrid(propGrid)
+    {
+    }
 
-    if ( argWnd == m_wndEditor )
+    virtual ~wxPropertyGridEditorEventForwarder()
     {
-        CONNECT_CHILD(wxEVT_MOTION,(wxMouseEventFunction),OnMouseMoveChild)
-        CONNECT_CHILD(wxEVT_LEFT_UP,(wxMouseEventFunction),OnMouseUpChild)
-        CONNECT_CHILD(wxEVT_LEFT_DOWN,(wxMouseEventFunction),OnMouseClickChild)
-        CONNECT_CHILD(wxEVT_RIGHT_UP,(wxMouseEventFunction),OnMouseRightClickChild)
-        CONNECT_CHILD(wxEVT_ENTER_WINDOW,(wxMouseEventFunction),OnMouseEntry)
-        CONNECT_CHILD(wxEVT_LEAVE_WINDOW,(wxMouseEventFunction),OnMouseEntry)
     }
-    else
+
+private:
+    bool ProcessEvent( wxEvent& event )
     {
-        CONNECT_CHILD(wxEVT_NAVIGATION_KEY,(wxNavigationKeyEventFunction),OnNavigationKey)
+        // Always skip
+        event.Skip();
+
+        m_propGrid->HandleCustomEditorEvent(event);
+
+        return wxEvtHandler::ProcessEvent(event);
     }
-    CONNECT_CHILD(wxEVT_KEY_DOWN,(wxCharEventFunction),OnChildKeyDown)
-    CONNECT_CHILD(wxEVT_KEY_UP,(wxCharEventFunction),OnChildKeyUp)
-    CONNECT_CHILD(wxEVT_KILL_FOCUS,(wxFocusEventFunction),OnFocusEvent)
+
+    wxPropertyGrid*         m_propGrid;
+};
+
+// Setups event handling for child control
+void wxPropertyGrid::SetupChildEventHandling( wxWindow* argWnd )
+{
+    wxWindowID id = argWnd->GetId();
+
+    if ( argWnd == m_wndEditor )
+    {
+        argWnd->Connect(id, wxEVT_MOTION,
+            wxMouseEventHandler(wxPropertyGrid::OnMouseMoveChild),
+            NULL, this);
+        argWnd->Connect(id, wxEVT_LEFT_UP,
+            wxMouseEventHandler(wxPropertyGrid::OnMouseUpChild),
+            NULL, this);
+        argWnd->Connect(id, wxEVT_LEFT_DOWN,
+            wxMouseEventHandler(wxPropertyGrid::OnMouseClickChild),
+            NULL, this);
+        argWnd->Connect(id, wxEVT_RIGHT_UP,
+            wxMouseEventHandler(wxPropertyGrid::OnMouseRightClickChild),
+            NULL, this);
+        argWnd->Connect(id, wxEVT_ENTER_WINDOW,
+            wxMouseEventHandler(wxPropertyGrid::OnMouseEntry),
+            NULL, this);
+        argWnd->Connect(id, wxEVT_LEAVE_WINDOW,
+            wxMouseEventHandler(wxPropertyGrid::OnMouseEntry),
+            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()
 {
-    // Do not free editors immediately if processing events
-    if ( !m_windowsToDelete )
-        m_windowsToDelete = new wxArrayPtrVoid;
+    //
+    // Return focus back to canvas from children (this is required at least for
+    // GTK+, which, unlike Windows, clears focus when control is destroyed
+    // instead of moving it to closest parent).
+    wxWindow* focus = wxWindow::FindFocus();
+    if ( focus )
+    {
+        wxWindow* parent = focus->GetParent();
+        while ( parent )
+        {
+            if ( parent == m_canvas )
+            {
+                SetFocusOnCanvas();
+                break;
+            }
+            parent = parent->GetParent();
+        }
+    }
 
+    // Do not free editors immediately if processing events
     if ( m_wndEditor2 )
     {
-        m_windowsToDelete->push_back(m_wndEditor2);
+        wxEvtHandler* handler = m_wndEditor2->PopEventHandler(false);
         m_wndEditor2->Hide();
-        m_wndEditor2 = (wxWindow*) NULL;
+        wxPendingDelete.Append( handler );
+        wxPendingDelete.Append( m_wndEditor2 );
+        m_wndEditor2 = NULL;
     }
 
     if ( m_wndEditor )
     {
-        m_windowsToDelete->push_back(m_wndEditor);
+        wxEvtHandler* handler = m_wndEditor->PopEventHandler(false);
         m_wndEditor->Hide();
-        m_wndEditor = (wxWindow*) NULL;
+        wxPendingDelete.Append( handler );
+        wxPendingDelete.Append( m_wndEditor );
+        m_wndEditor = NULL;
     }
 }
 
@@ -3537,25 +3218,24 @@ bool wxPropertyGrid::DoSelectProperty( wxPGProperty* p, unsigned int flags )
 
     wxPGProperty* prev = m_selected;
 
-    //
-    // Delete windows pending for deletion
-    if ( m_windowsToDelete && !m_inDoPropertyChanged && m_windowsToDelete->size() )
-    {
-        unsigned int i;
-
-        for ( i=0; i<m_windowsToDelete->size(); i++ )
-            delete ((wxWindow*)((*m_windowsToDelete)[i]));
-
-        m_windowsToDelete->clear();
-    }
-
     if ( !m_pState )
     {
         m_inDoSelectProperty = 0;
         return false;
     }
 
-    //
+/*
+    if (m_selected)
+        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 )
     {
@@ -3570,7 +3250,7 @@ bool wxPropertyGrid::DoSelectProperty( wxPGProperty* p, unsigned int flags )
         FreeEditors();
 
         // Prevent any further selection measures in this call
-        p = (wxPGProperty*) NULL;
+        p = NULL;
     }
     else
     {
@@ -3590,8 +3270,7 @@ bool wxPropertyGrid::DoSelectProperty( wxPGProperty* p, unsigned int flags )
                 }
                 else
                 {
-                    wxScrolledWindow::SetFocus();
-                    m_editorFocused = 0;
+                    SetFocusOnCanvas();
                 }
             }
 
@@ -3622,8 +3301,8 @@ bool wxPropertyGrid::DoSelectProperty( wxPGProperty* p, unsigned int flags )
             FreeEditors();
             m_selColumn = -1;
 
-            m_selected = (wxPGProperty*) NULL;
-            m_pState->m_selected = (wxPGProperty*) NULL;
+            m_selected = NULL;
+            m_pState->m_selected = NULL;
 
             // We need to always fully refresh the grid here
             Refresh(false);
@@ -3648,10 +3327,7 @@ bool wxPropertyGrid::DoSelectProperty( wxPGProperty* p, unsigned int flags )
             if ( p != prev )
                 m_iFlags &= ~(wxPG_FL_VALIDATION_FAILED);
 
-            wxASSERT( m_wndEditor == (wxWindow*) NULL );
-
-            // Do we need OnMeasureCalls?
-            wxSize imsz = p->OnMeasureImage();
+            wxASSERT( m_wndEditor == NULL );
 
             //
             // Only create editor for non-disabled non-caption
@@ -3688,25 +3364,27 @@ bool wxPropertyGrid::DoSelectProperty( wxPGProperty* p, unsigned int flags )
 
                 m_wndEditor = wndList.m_primary;
                 m_wndEditor2 = wndList.m_secondary;
+                wxWindow* primaryCtrl = GetEditorControl();
+
+                //
+                // Essentially, primaryCtrl == m_wndEditor
+                //
 
                 // NOTE: It is allowed for m_wndEditor to be NULL - in this case
                 //       value is drawn as normal, and m_wndEditor2 is assumed
-                //       to be a right-aligned button that triggers a separate editor
+                //       to be a right-aligned button that triggers a separate editorCtrl
                 //       window.
 
                 if ( m_wndEditor )
                 {
-                    wxASSERT_MSG( m_wndEditor->GetParent() == m_canvas,
+                    wxASSERT_MSG( m_wndEditor->GetParent() == GetPanel(),
                                   wxT("CreateControls must use result of wxPropertyGrid::GetPanel() as parent of controls.") );
 
                     // Set validator, if any
                 #if wxUSE_VALIDATORS
-                    if ( !(GetExtraStyle() & wxPG_EX_LEGACY_VALIDATORS) )
-                    {
-                        wxValidator* validator = p->GetValidator();
-                        if ( validator )
-                            m_wndEditor->SetValidator(*validator);
-                    }
+                    wxValidator* validator = p->GetValidator();
+                    if ( validator )
+                        primaryCtrl->SetValidator(*validator);
                 #endif
 
                     if ( m_wndEditor->GetSize().y > (m_lineHeight+6) )
@@ -3721,10 +3399,10 @@ bool wxPropertyGrid::DoSelectProperty( wxPGProperty* p, unsigned int flags )
                     // Fix TextCtrl indentation
                 #if defined(__WXMSW__) && !defined(__WXWINCE__)
                     wxTextCtrl* tc = NULL;
-                    if ( m_wndEditor->IsKindOf(CLASSINFO(wxOwnerDrawnComboBox)) )
-                        tc = ((wxOwnerDrawnComboBox*)m_wndEditor)->GetTextCtrl();
+                    if ( primaryCtrl->IsKindOf(CLASSINFO(wxOwnerDrawnComboBox)) )
+                        tc = ((wxOwnerDrawnComboBox*)primaryCtrl)->GetTextCtrl();
                     else
-                        tc = wxDynamicCast(m_wndEditor, wxTextCtrl);
+                        tc = wxDynamicCast(primaryCtrl, wxTextCtrl);
                     if ( tc )
                         ::SendMessage(GetHwndOf(tc), EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(0, 0));
                 #endif
@@ -3750,8 +3428,7 @@ bool wxPropertyGrid::DoSelectProperty( wxPGProperty* p, unsigned int flags )
                     m_wndEditor->Move( goodPos );
                 #endif
 
-                    wxWindow* primaryCtrl = GetEditorControl();
-                    SetupEventHandling(primaryCtrl, wxPG_SUBID1);
+                    SetupChildEventHandling(primaryCtrl);
 
                     // Focus and select all (wxTextCtrl, wxComboBox etc)
                     if ( flags & wxPG_SEL_FOCUS )
@@ -3764,7 +3441,7 @@ bool wxPropertyGrid::DoSelectProperty( wxPGProperty* p, unsigned int flags )
 
                 if ( m_wndEditor2 )
                 {
-                    wxASSERT_MSG( m_wndEditor2->GetParent() == m_canvas,
+                    wxASSERT_MSG( m_wndEditor2->GetParent() == GetPanel(),
                                   wxT("CreateControls must use result of wxPropertyGrid::GetPanel() as parent of controls.") );
 
                     // Get proper id for wndSecondary
@@ -3791,7 +3468,7 @@ bool wxPropertyGrid::DoSelectProperty( wxPGProperty* p, unsigned int flags )
                 #endif
                     m_wndEditor2->Show();
 
-                    SetupEventHandling(m_wndEditor2,wxPG_SUBID2);
+                    SetupChildEventHandling(m_wndEditor2);
 
                     // If no primary editor, focus to button to allow
                     // it to interprete ENTER etc.
@@ -3809,8 +3486,8 @@ bool wxPropertyGrid::DoSelectProperty( wxPGProperty* p, unsigned int flags )
             }
             else
             {
-                // wxGTK atleast seems to need this (wxMSW not)
-                SetFocus();
+                // Make sure focus is in grid canvas (important for wxGTK, at least)
+                SetFocusOnCanvas();
             }
 
             EditorsValueWasNotModified();
@@ -3830,6 +3507,11 @@ bool wxPropertyGrid::DoSelectProperty( wxPGProperty* p, unsigned int flags )
 
             DrawItems(p, p);
         }
+        else
+        {
+            // Make sure focus is in grid canvas
+            SetFocusOnCanvas();
+        }
 
         ClearInternalFlag(wxPG_FL_IN_SELECT_PROPERTY);
     }
@@ -3844,7 +3526,7 @@ bool wxPropertyGrid::DoSelectProperty( wxPGProperty* p, unsigned int flags )
 
     if ( !(GetExtraStyle() & wxPG_EX_HELP_AS_TOOLTIPS) )
     {
-        wxStatusBar* statusbar = (wxStatusBar*) NULL;
+        wxStatusBar* statusbar = NULL;
         if ( !(m_iFlags & wxPG_FL_NOSTATUSBARHELP) )
         {
             wxFrame* frame = wxDynamicCast(::wxGetTopLevelParent(this),wxFrame);
@@ -3897,7 +3579,7 @@ bool wxPropertyGrid::UnfocusEditor()
     if ( !CommitChangesFromEditor(0) )
         return false;
 
-    m_canvas->SetFocusIgnoringChildren();
+    SetFocusOnCanvas();
     DrawItem(m_selected);
 
     return true;
@@ -3905,11 +3587,41 @@ bool wxPropertyGrid::UnfocusEditor()
 
 // -----------------------------------------------------------------------
 
+void wxPropertyGrid::RefreshEditor()
+{
+    wxPGProperty* p = m_selected;
+    if ( !p ) 
+        return;
+
+    wxWindow* wnd = GetEditorControl();
+    if ( !wnd )
+        return;
+
+    // Set editor font boldness - must do this before
+    // calling UpdateControl().
+    if ( HasFlag(wxPG_BOLD_MODIFIED) )
+    {
+        if ( p->HasFlag(wxPG_PROP_MODIFIED) )
+            wnd->SetFont(GetCaptionFont());
+        else
+            wnd->SetFont(GetFont());
+    }
+
+    const wxPGEditor* editorClass = p->GetEditorClass();
+
+    editorClass->UpdateControl(p, wnd);
+
+    if ( p->IsValueUnspecified() )
+        editorClass ->SetValueToUnspecified(p, wnd);
+}
+
+// -----------------------------------------------------------------------
+
 // This method is not inline because it called dozens of times
 // (i.e. two-arg function calls create smaller code size).
 bool wxPropertyGrid::DoClearSelection()
 {
-    return DoSelectProperty((wxPGProperty*)NULL);
+    return DoSelectProperty(NULL);
 }
 
 // -----------------------------------------------------------------------
@@ -3921,10 +3633,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
@@ -3993,7 +3704,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;
 }
@@ -4009,8 +3720,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);
@@ -4044,8 +3754,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
@@ -4078,7 +3787,7 @@ void wxPropertyGrid::RecalculateVirtualSize( int forceXPos )
     else if ( xPos > (xAmount-(width/wxPG_PIXELS_PER_UNIT)) )
         xPos = 0;
 
-    int yAmount = (y+wxPG_PIXELS_PER_UNIT+2)/wxPG_PIXELS_PER_UNIT;
+    int yAmount = y / wxPG_PIXELS_PER_UNIT;
     int yPos = GetScrollPos( wxVERTICAL );
 
     SetScrollbars( wxPG_PIXELS_PER_UNIT, wxPG_PIXELS_PER_UNIT,
@@ -4182,6 +3891,12 @@ void wxPropertyGrid::SetVirtualWidth( int width )
     m_pState->SetVirtualWidth( width );
 }
 
+void wxPropertyGrid::SetFocusOnCanvas()
+{
+    m_canvas->SetFocusIgnoringChildren();
+    m_editorFocused = 0;
+}
+
 // -----------------------------------------------------------------------
 // wxPropertyGrid mouse event handling
 // -----------------------------------------------------------------------
@@ -4218,7 +3933,7 @@ bool wxPropertyGrid::HandleMouseClick( int x, unsigned int y, wxMouseEvent &even
     // Need to set focus?
     if ( !(m_iFlags & wxPG_FL_FOCUSED) )
     {
-        m_canvas->SetFocus();
+        SetFocusOnCanvas();
     }
 
     wxPropertyGridPageState* state = m_pState;
@@ -4485,9 +4200,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
@@ -4550,7 +4265,7 @@ bool wxPropertyGrid::HandleMouseMove( int x, unsigned int y, wxMouseEvent &event
                         if ( space )
                         {
                             int tw, th;
-                           GetTextExtent( tipString, &tw, &th, 0, 0, &m_font );
+                           GetTextExtent( tipString, &tw, &th, 0, 0 );
                             if ( tw > space )
                             {
                                 SetToolTip( tipString );
@@ -4599,8 +4314,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() )
             {
 
@@ -4701,19 +4415,19 @@ bool wxPropertyGrid::OnMouseCommon( wxMouseEvent& event, int* px, int* py )
     int ux = event.m_x;
     int uy = event.m_y;
 
-    wxWindow* wnd = m_wndEditor;
+    wxWindow* wnd = GetEditorControl();
 
     // Hide popup on clicks
     if ( event.GetEventType() != wxEVT_MOTION )
         if ( wnd && wnd->IsKindOf(CLASSINFO(wxOwnerDrawnComboBox)) )
         {
-            ((wxOwnerDrawnComboBox*)m_wndEditor)->HidePopup();
+            ((wxOwnerDrawnComboBox*)wnd)->HidePopup();
         }
 
     wxRect r;
     if ( wnd )
         r = wnd->GetRect();
-    if ( wnd == (wxWindow*) NULL || m_dragStatus ||
+    if ( wnd == NULL || m_dragStatus ||
          (
            ux <= (splitterX + wxPG_SPLITTERX_DETECTMARGIN2) ||
            ux >= (r.x+r.width) ||
@@ -4856,8 +4570,6 @@ bool wxPropertyGrid::OnMouseChildCommon( wxMouseEvent &event, int* px, int *py )
     int x, y;
     event.GetPosition(&x,&y);
 
-    AdjustPosForClipperWindow( topCtrlWnd, &x, &y );
-
     int splitterX = GetSplitterPosition();
 
     wxRect r = topCtrlWnd->GetRect();
@@ -4926,20 +4638,9 @@ void wxPropertyGrid::OnMouseUpChild( wxMouseEvent &event )
 // wxPropertyGrid keyboard event handling
 // -----------------------------------------------------------------------
 
-void wxPropertyGrid::SendNavigationKeyEvent( int dir )
+int wxPropertyGrid::KeyEventToActions(wxKeyEvent &event, int* pSecond) const
 {
-    wxNavigationKeyEvent evt;
-    evt.SetFlags(wxNavigationKeyEvent::FromTab|
-                 (dir?wxNavigationKeyEvent::IsForward:
-                      wxNavigationKeyEvent::IsBackward));
-    evt.SetEventObject(this);
-    m_canvas->GetEventHandler()->AddPendingEvent(evt);
-}
-
-
-int wxPropertyGrid::KeyEventToActions(wxKeyEvent &event, int* pSecond) const
-{
-    // Translates wxKeyEvent to wxPG_ACTION_XXX
+    // Translates wxKeyEvent to wxPG_ACTION_XXX
 
     int keycode = event.GetKeyCode();
     int modifiers = event.GetModifiers();
@@ -4988,7 +4689,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 )
         {
@@ -4997,138 +4698,82 @@ void wxPropertyGrid::ClearActionTriggers( int action )
     }
 }
 
-static void CopyTextToClipboard( const wxString& text )
-{
-    if ( wxTheClipboard->Open() )
-    {
-        // This data objects are held by the clipboard, 
-        // so do not delete them in the app.
-        wxTheClipboard->SetData( new wxTextDataObject(text) );
-        wxTheClipboard->Close();
-    }
-}
-
-void wxPropertyGrid::HandleKeyEvent(wxKeyEvent &event)
+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();
+    bool editorFocused = IsEditorFocused();
 
     if ( keycode == WXK_TAB )
     {
-        SendNavigationKeyEvent( event.ShiftDown()?0:1 );
-        return;
-    }
-
-    // Ignore Alt and Control when they are down alone
-    if ( keycode == WXK_ALT ||
-         keycode == WXK_CONTROL )
-    {
-        event.Skip();
-        return;
-    }
-
-    int secondAction;
-    int action = KeyEventToActions(event, &secondAction);
-
-    if ( m_selected )
-    {
-
-        // Show dialog?
-        if ( ButtonTriggerKeyTest(event) )
-            return;
+        wxWindow* mainControl;
 
-        wxPGProperty* p = m_selected;
+        if ( HasInternalFlag(wxPG_FL_IN_MANAGER) )
+            mainControl = GetParent();
+        else
+            mainControl = this;
 
-        if ( action == wxPG_ACTION_COPY )
+        if ( !event.ShiftDown() )
         {
-            CopyTextToClipboard(p->GetDisplayedString());
+            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
         {
-            // Travel and expand/collapse
-            int selectDir = -2;
-
-            if ( p->GetChildCount() &&
-                 !(p->m_flags & wxPG_PROP_DISABLED)
-               )
-            {
-                if ( action == wxPG_ACTION_COLLAPSE_PROPERTY || secondAction == wxPG_ACTION_COLLAPSE_PROPERTY )
-                {
-                    if ( (m_windowStyle & wxPG_HIDE_MARGIN) || Collapse(p) )
-                        keycode = 0;
-                }
-                else if ( action == wxPG_ACTION_EXPAND_PROPERTY || secondAction == wxPG_ACTION_EXPAND_PROPERTY )
-                {
-                    if ( (m_windowStyle & wxPG_HIDE_MARGIN) || Expand(p) )
-                        keycode = 0;
-                }
-            }
-
-            if ( keycode )
+            if ( editorFocused )
             {
-                if ( action == wxPG_ACTION_PREV_PROPERTY || secondAction == wxPG_ACTION_PREV_PROPERTY )
-                {
-                    selectDir = -1;
-                }
-                else if ( action == wxPG_ACTION_NEXT_PROPERTY || secondAction == wxPG_ACTION_NEXT_PROPERTY )
-                {
-                    selectDir = 1;
-                }
-                else
-                {
-                    event.Skip();
-                }
-
+                UnfocusEditor();
             }
-
-            if ( selectDir >= -1 )
+            else
             {
-                p = wxPropertyGridIterator::OneStep( m_pState, wxPG_ITERATE_VISIBLE, p, selectDir );
-                if ( p )
-                    DoSelectProperty(p);
+            #if defined(__WXGTK__)
+                wxWindow* sibling = mainControl->GetPrevSibling();
+                if ( sibling )
+                    sibling->SetFocusFromKbd();
+            #else
+                Navigate(wxNavigationKeyEvent::IsBackward);
+            #endif
             }
         }
-    }
-    else
-    {
-        // If nothing was selected, select the first item now
-        // (or navigate out of tab).
-        if ( action != wxPG_ACTION_CANCEL_EDIT && secondAction != wxPG_ACTION_CANCEL_EDIT )
-        {
-            wxPGProperty* p = wxPropertyGridInterface::GetFirst();
-            if ( p ) DoSelectProperty(p);
-        }
-    }
-}
 
-// -----------------------------------------------------------------------
-
-// Potentially handles a keyboard event for editor controls.
-// Returns false if event should *not* be skipped (on true it can
-// be optionally skipped).
-// Basicly, false means that SelectProperty was called (or was about
-// to be called, if canDestroy was false).
-bool wxPropertyGrid::HandleChildKey( wxKeyEvent& event )
-{
-    bool res = true;
+        return;
+    }
 
-    if ( !m_selected || !m_wndEditor )
+    // Ignore Alt and Control when they are down alone
+    if ( keycode == WXK_ALT ||
+         keycode == WXK_CONTROL )
     {
-        return true;
+        event.Skip();
+        return;
     }
 
-    int action = KeyEventToAction(event);
+    int secondAction;
+    int action = KeyEventToActions(event, &secondAction);
 
-    // Unfocus?
-    if ( action == wxPG_ACTION_CANCEL_EDIT )
+    if ( editorFocused && action == wxPG_ACTION_CANCEL_EDIT )
     {
         //
         // Esc cancels any changes
@@ -5138,246 +4783,140 @@ bool wxPropertyGrid::HandleChildKey( wxKeyEvent& event )
 
             // Update the control as well
             m_selected->GetEditorClass()->SetControlStringValue( m_selected,
-                                                                 m_wndEditor,
+                                                                 GetEditorControl(),
                                                                  m_selected->GetDisplayedString() );
         }
 
         OnValidationFailureReset(m_selected);
 
-        res = false;
-
         UnfocusEditor();
+        return;
     }
-    else if ( action == wxPG_ACTION_COPY )
-    {
-        // NB: There is some problem with getting native cut-copy-paste keys to go through
-        //     for embedded editor wxTextCtrl. This is why we emulate.
-        //
-        wxTextCtrl* tc = GetEditorTextCtrl();
-        if ( tc )
-        {
-            wxString sel = tc->GetStringSelection();
-            if ( sel.length() )
-                CopyTextToClipboard(sel);
-        }
-        else
-        {
-            CopyTextToClipboard(m_selected->GetDisplayedString());
-        }
-    }
-    else if ( action == wxPG_ACTION_CUT )
+
+    // Except for TAB and ESC, handle child control events in child control
+    if ( fromChild )
     {
-        wxTextCtrl* tc = GetEditorTextCtrl();
-        if ( tc )
+        // Only propagate event if it had modifiers
+        if ( !event.HasModifiers() )
         {
-            long from, to;
-            tc->GetSelection(&from, &to);
-            if ( from < to )
-            {
-                CopyTextToClipboard(tc->GetStringSelection());
-                tc->Remove(from, to);
-            }
+            event.StopPropagation();
         }
-    }
-    else if ( action == wxPG_ACTION_PASTE )
-    {
-        wxTextCtrl* tc = GetEditorTextCtrl();
-        if ( tc )
-        {
-            if (wxTheClipboard->Open())
-            {
-                if (wxTheClipboard->IsSupported( wxDF_TEXT ))
-                {
-                    wxTextDataObject data;
-                    wxTheClipboard->GetData( data );
-                    long from, to;
-                    tc->GetSelection(&from, &to);
-                    if ( from < to )
-                    {
-                        tc->Remove(from, to);
-                        tc->WriteText(data.GetText());
-                    }
-                    else
-                    {
-                        tc->WriteText(data.GetText());
-                    }
-                }  
-                wxTheClipboard->Close();
-            }
-        }
-    }
-
-    return res;
-}
-
-// -----------------------------------------------------------------------
-
-void wxPropertyGrid::OnKey( wxKeyEvent &event )
-{
-
-    //
-    // Events to editor controls should get relayed here.
-    //
-    wxWindow* focused = wxWindow::FindFocus();
-
-    wxWindow* primaryCtrl = GetEditorControl();
-
-    if ( primaryCtrl &&
-         (focused==primaryCtrl
-          || m_editorFocused) )
-    {
-        // Child key must be processed here, since it can
-        // destroy the control which is referred by its own
-        // event handling.
-        HandleChildKey( event );
-    }
-    else
-        HandleKeyEvent( event );
-}
-
-// -----------------------------------------------------------------------
-
-void wxPropertyGrid::OnKeyUp(wxKeyEvent &event)
-{
-    m_keyComboConsumed = 0;
-
-    event.Skip();
-}
-
-// -----------------------------------------------------------------------
-
-void wxPropertyGrid::OnNavigationKey( wxNavigationKeyEvent& event )
-{
-    // Ignore events that occur very close to focus set
-    if ( m_iFlags & wxPG_FL_IGNORE_NEXT_NAVKEY )
-    {
-        m_iFlags &= ~(wxPG_FL_IGNORE_NEXT_NAVKEY);
         event.Skip();
         return;
     }
 
-    wxPGProperty* next = (wxPGProperty*) NULL;
-
-    int dir = event.GetDirection()?1:-1;
+    bool wasHandled = false;
 
     if ( m_selected )
     {
-        if ( dir == 1 && (m_wndEditor || m_wndEditor2) )
-        {
-            wxWindow* focused = wxWindow::FindFocus();
+        // Show dialog?
+        if ( ButtonTriggerKeyTest(action, event) )
+            return;
 
-            wxWindow* wndToCheck = GetEditorControl();
+        wxPGProperty* p = m_selected;
 
-            // ODComboBox focus goes to its text ctrl, so we need to use it instead
-            if ( wndToCheck && wndToCheck->IsKindOf(CLASSINFO(wxOwnerDrawnComboBox)) )
-            {
-                wxTextCtrl* comboTextCtrl = ((wxOwnerDrawnComboBox*)wndToCheck)->GetTextCtrl();
-                if ( comboTextCtrl )
-                    wndToCheck = comboTextCtrl;
-            }
+        // Travel and expand/collapse
+        int selectDir = -2;
 
-            /*
-            // Because of problems navigating from wxButton, do not go to it.
-            if ( !wndToCheck )
+        if ( p->GetChildCount() &&
+             !(p->m_flags & wxPG_PROP_DISABLED)
+           )
+        {
+            if ( action == wxPG_ACTION_COLLAPSE_PROPERTY || secondAction == wxPG_ACTION_COLLAPSE_PROPERTY )
             {
-                // No primary, use secondary
-                wndToCheck = m_wndEditor2;
+                if ( (m_windowStyle & wxPG_HIDE_MARGIN) || Collapse(p) )
+                    wasHandled = true;
             }
-            // If it has editor button, focus to it after the primary editor.
-            // NB: Doesn't work since wxButton on wxMSW doesn't seem to propagate
-            //     key events (yes, I'm using wxWANTS_CHARS with it, and yes I
-            //     have somewhat debugged in window.cpp itself).
-            else if ( focused == wndToCheck &&
-                      m_wndEditor2 &&
-                      !(GetExtraStyle() & wxPG_EX_NO_TAB_TO_BUTTON) )
+            else if ( action == wxPG_ACTION_EXPAND_PROPERTY || secondAction == wxPG_ACTION_EXPAND_PROPERTY )
             {
-                wndToCheck = m_wndEditor2;
-                wxLogDebug(wxT("Exp1"));
+                if ( (m_windowStyle & wxPG_HIDE_MARGIN) || Expand(p) )
+                    wasHandled = true;
             }
-            */
+        }
 
-            if ( focused != wndToCheck &&
-                 wndToCheck )
+        if ( !wasHandled )
+        {
+            if ( action == wxPG_ACTION_PREV_PROPERTY || secondAction == wxPG_ACTION_PREV_PROPERTY )
             {
-                wndToCheck->SetFocus();
-
-                // Select all text in wxTextCtrl etc.
-                if ( m_wndEditor && wndToCheck == m_wndEditor )
-                    m_selected->GetEditorClass()->OnFocus(m_selected,wndToCheck);
-
-                m_editorFocused = 1;
-                next = m_selected;
+                selectDir = -1;
+            }
+            else if ( action == wxPG_ACTION_NEXT_PROPERTY || secondAction == wxPG_ACTION_NEXT_PROPERTY )
+            {
+                selectDir = 1;
             }
         }
 
-        if ( !next )
+        if ( selectDir >= -1 )
         {
-            next = wxPropertyGridIterator::OneStep(m_pState, wxPG_ITERATE_VISIBLE, m_selected, dir);
-
-            if ( next )
-            {
-                // This allows preventing NavigateOut to occur
-                DoSelectProperty( next, wxPG_SEL_FOCUS );
-            }
+            p = wxPropertyGridIterator::OneStep( m_pState, wxPG_ITERATE_VISIBLE, p, selectDir );
+            if ( p )
+                DoSelectProperty(p);
+            wasHandled = true;
+        }
+    }
+    else
+    {
+        // If nothing was selected, select the first item now
+        // (or navigate out of tab).
+        if ( action != wxPG_ACTION_CANCEL_EDIT && secondAction != wxPG_ACTION_CANCEL_EDIT )
+        {
+            wxPGProperty* p = wxPropertyGridInterface::GetFirst();
+            if ( p ) DoSelectProperty(p);
+            wasHandled = true;
         }
     }
 
-    if ( !next )
+    if ( !wasHandled )
         event.Skip();
 }
 
 // -----------------------------------------------------------------------
 
-bool wxPropertyGrid::ButtonTriggerKeyTest( wxKeyEvent &event )
+void wxPropertyGrid::OnKey( wxKeyEvent &event )
 {
-    int keycode = event.GetKeyCode();
-
-    // Does the keycode trigger button?
-    if ( keycode == m_pushButKeyCode &&
-         m_wndEditor2 &&
-         (!m_pushButKeyCodeNeedsAlt || event.AltDown()) &&
-         (!m_pushButKeyCodeNeedsCtrl || event.ControlDown()) )
+    // If there was editor open and focused, then this event should not
+    // really be processed here.
+    if ( IsEditorFocused() )
     {
-        m_keyComboConsumed = 1;
-
-        wxCommandEvent evt(wxEVT_COMMAND_BUTTON_CLICKED,m_wndEditor2->GetId());
-        GetEventHandler()->AddPendingEvent(evt);
-        return true;
+        // However, if event had modifiers, it is probably still best
+        // to skip it.
+        if ( event.HasModifiers() )
+            event.Skip();
+        else
+            event.StopPropagation();
+        return;
     }
 
-    return false;
+    HandleKeyEvent(event, false);
 }
 
 // -----------------------------------------------------------------------
 
-void wxPropertyGrid::OnChildKeyDown( wxKeyEvent &event )
+bool wxPropertyGrid::ButtonTriggerKeyTest( int action, wxKeyEvent& event )
 {
-    int keycode = event.GetKeyCode();
-
-    // Ignore Alt and Control when they are down alone
-    if ( keycode == WXK_ALT ||
-         keycode == WXK_CONTROL )
+    if ( action == -1 )
     {
-        event.Skip();
-        return;
+        int secondAction;
+        action = KeyEventToActions(event, &secondAction);
     }
 
-    if ( ButtonTriggerKeyTest(event) )
-        return;
-
-    if ( HandleChildKey(event) == true )
-        event.Skip();
+    // Does the keycode trigger button?
+    if ( action == wxPG_ACTION_PRESS_BUTTON &&
+         m_wndEditor2 )
+    {
+        wxCommandEvent evt(wxEVT_COMMAND_BUTTON_CLICKED, m_wndEditor2->GetId());
+        GetEventHandler()->AddPendingEvent(evt);
+        return true;
+    }
 
-    GetEventHandler()->AddPendingEvent(event);
+    return false;
 }
 
-void wxPropertyGrid::OnChildKeyUp( wxKeyEvent &event )
-{
-    m_keyComboConsumed = 0;
-
-    GetEventHandler()->AddPendingEvent(event);
+// -----------------------------------------------------------------------
 
-    event.Skip();
+void wxPropertyGrid::OnChildKeyDown( wxKeyEvent &event )
+{
+    HandleKeyEvent(event, true);
 }
 
 // -----------------------------------------------------------------------
@@ -5394,6 +4933,17 @@ void wxPropertyGrid::OnIdle( wxIdleEvent& WXUNUSED(event) )
         HandleFocusChange( newFocused );
 }
 
+bool wxPropertyGrid::IsEditorFocused() const
+{
+    wxWindow* focus = wxWindow::FindFocus();
+
+    if ( focus == m_wndEditor || focus == m_wndEditor2 ||
+         focus == GetEditorControl() )
+         return true;
+
+    return false;
+}
+
 // Called by focus event handlers. newFocused is the window that becomes focused.
 void wxPropertyGrid::HandleFocusChange( wxWindow* newFocused )
 {
@@ -5421,13 +4971,8 @@ void wxPropertyGrid::HandleFocusChange( wxWindow* newFocused )
     if ( (m_iFlags & wxPG_FL_FOCUSED) !=
          (oldFlags & wxPG_FL_FOCUSED) )
     {
-        // On each focus kill, mark the next nav key event
-        // to be ignored (can't do on set focus since the
-        // event would occur before it).
         if ( !(m_iFlags & wxPG_FL_FOCUSED) )
         {
-            m_iFlags |= wxPG_FL_IGNORE_NEXT_NAVKEY;
-
             // Need to store changed value
             CommitChangesFromEditor();
         }
@@ -5460,8 +5005,6 @@ void wxPropertyGrid::HandleFocusChange( wxWindow* newFocused )
 
             }
             */
-
-            m_iFlags &= ~(wxPG_FL_IGNORE_NEXT_NAVKEY);
         }
 
         // Redraw selected
@@ -5518,20 +5061,43 @@ void wxPropertyGrid::OnCaptureChange( wxMouseCaptureChangedEvent& WXUNUSED(event
 // -----------------------------------------------------------------------
 
 // noDefCheck = true prevents infinite recursion.
-wxPGEditor* wxPropertyGrid::RegisterEditorClass( wxPGEditor* editorclass,
-                                                 const wxString& name,
+wxPGEditor* wxPropertyGrid::RegisterEditorClass( wxPGEditor* editorClass,
                                                  bool noDefCheck )
 {
-    wxASSERT( editorclass );
+    wxASSERT( editorClass );
 
     if ( !noDefCheck && wxPGGlobalVars->m_mapEditorClasses.empty() )
         RegisterDefaultEditors();
 
-    wxPGGlobalVars->m_mapEditorClasses[name] = (void*)editorclass;
+    wxString name = editorClass->GetName();
+
+    // Existing editor under this name?
+    wxPGHashMapS2P::iterator vt_it = wxPGGlobalVars->m_mapEditorClasses.find(name);
+
+    if ( vt_it != wxPGGlobalVars->m_mapEditorClasses.end() )
+    {
+        // If this name was already used, try class name.
+        name = editorClass->GetClassInfo()->GetClassName();
+        vt_it = wxPGGlobalVars->m_mapEditorClasses.find(name);
+    }
+
+    wxCHECK_MSG( vt_it == wxPGGlobalVars->m_mapEditorClasses.end(),
+                 (wxPGEditor*) vt_it->second,
+                 "Editor with given name was already registered" );
+
+    wxPGGlobalVars->m_mapEditorClasses[name] = (void*)editorClass;
 
-    return editorclass;
+    return editorClass;
 }
 
+// Use this in RegisterDefaultEditors.
+#define wxPGRegisterDefaultEditorClass(EDITOR) \
+    if ( wxPGEditor_##EDITOR == NULL ) \
+    { \
+        wxPGEditor_##EDITOR = wxPropertyGrid::RegisterEditorClass( \
+            new wxPG##EDITOR##Editor, true ); \
+    }
+
 // Registers all default editor classes
 void wxPropertyGrid::RegisterDefaultEditors()
 {
@@ -5597,7 +5163,7 @@ bool wxPGStringTokenizer::HasMoreTokens()
                 }
                 else
                 {
-                    i++;
+                    ++i;
                     m_curPos = i;
                     return true;
                 }
@@ -5609,7 +5175,7 @@ bool wxPGStringTokenizer::HasMoreTokens()
                 prev_a = wxT('\0');
             }
         }
-        i++;
+        ++i;
     }
 
     m_curPos = str.end();
@@ -5634,12 +5200,6 @@ wxPGChoiceEntry::wxPGChoiceEntry()
 {
 }
 
-wxPGChoiceEntry::wxPGChoiceEntry( const wxPGChoiceEntry& entry )
-    : wxPGCell( entry.GetText(), entry.GetBitmap(),
-        entry.GetFgCol(), entry.GetBgCol() ), m_value(entry.GetValue())
-{
-}
-
 // -----------------------------------------------------------------------
 // wxPGChoicesData
 // -----------------------------------------------------------------------
@@ -5656,293 +5216,39 @@ wxPGChoicesData::~wxPGChoicesData()
 
 void wxPGChoicesData::Clear()
 {
-    unsigned int i;
-
-    for ( i=0; i<m_items.size(); i++ )
-    {
-        delete Item(i);
-    }
-
-#if wxUSE_STL
-    m_items.resize(0);
-#else
-    m_items.Empty();
-#endif
+    m_items.clear();
 }
 
 void wxPGChoicesData::CopyDataFrom( wxPGChoicesData* data )
 {
     wxASSERT( m_items.size() == 0 );
 
-    unsigned int i;
-
-    for ( i=0; i<data->GetCount(); i++ )
-        m_items.push_back( new wxPGChoiceEntry(*data->Item(i)) );
-}
-
-// -----------------------------------------------------------------------
-// wxPGChoices
-// -----------------------------------------------------------------------
-
-wxPGChoiceEntry& wxPGChoices::Add( const wxString& label, int value )
-{
-    EnsureData();
-
-    wxPGChoiceEntry* p = new wxPGChoiceEntry(label, value);
-    m_data->Insert( -1, p );
-    return *p;
-}
-
-// -----------------------------------------------------------------------
-
-wxPGChoiceEntry& wxPGChoices::Add( const wxString& label, const wxBitmap& bitmap, int value )
-{
-    EnsureData();
-
-    wxPGChoiceEntry* p = new wxPGChoiceEntry(label, value);
-    p->SetBitmap(bitmap);
-    m_data->Insert( -1, p );
-    return *p;
-}
-
-// -----------------------------------------------------------------------
-
-wxPGChoiceEntry& wxPGChoices::Insert( const wxPGChoiceEntry& entry, int index )
-{
-    EnsureData();
-
-    wxPGChoiceEntry* p = new wxPGChoiceEntry(entry);
-    m_data->Insert(index, p);
-    return *p;
-}
-
-// -----------------------------------------------------------------------
-
-wxPGChoiceEntry& wxPGChoices::Insert( const wxString& label, int index, int value )
-{
-    EnsureData();
-
-    wxPGChoiceEntry* p = new wxPGChoiceEntry(label, value);
-    m_data->Insert( index, p );
-    return *p;
+    m_items = data->m_items;
 }
 
-// -----------------------------------------------------------------------
-
-wxPGChoiceEntry& wxPGChoices::AddAsSorted( const wxString& label, int value )
+wxPGChoiceEntry& wxPGChoicesData::Insert( int index,
+                                          const wxPGChoiceEntry& item )
 {
-    EnsureData();
-
-    size_t index = 0;
-
-    while ( index < GetCount() )
+    wxVector<wxPGChoiceEntry>::iterator it;
+    if ( index == -1 )
     {
-        int cmpRes = GetLabel(index).Cmp(label);
-        if ( cmpRes > 0 )
-            break;
-        index++;
+        it = m_items.end();
+        index = (int) m_items.size();
     }
-
-    wxPGChoiceEntry* p = new wxPGChoiceEntry(label, value);
-    m_data->Insert( index, p );
-    return *p;
-}
-
-// -----------------------------------------------------------------------
-
-void wxPGChoices::Add( const wxChar** labels, const ValArrItem* values )
-{
-    EnsureData();
-
-    unsigned int itemcount = 0;
-    const wxChar** p = &labels[0];
-    while ( *p ) { p++; itemcount++; }
-
-    unsigned int i;
-    for ( i = 0; i < itemcount; i++ )
-    {
-        int value = wxPG_INVALID_VALUE;
-        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) );
-    }
-}
-
-// -----------------------------------------------------------------------
-
-void wxPGChoices::Add( const wxArrayString& arr, const wxArrayInt& arrint )
-{
-    EnsureData();
-
-    unsigned int i;
-    unsigned int itemcount = arr.size();
-
-    for ( i = 0; i < itemcount; i++ )
-    {
-        int value = wxPG_INVALID_VALUE;
-        if ( &arrint && arrint.size() )
-            value = arrint[i];
-        m_data->Insert( -1, new wxPGChoiceEntry(arr[i], value) );
-    }
-}
-
-// -----------------------------------------------------------------------
-
-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.RemoveAt(nIndex, count);
-}
-
-// -----------------------------------------------------------------------
-
-int wxPGChoices::Index( const wxString& str ) const
-{
-    if ( IsOk() )
-    {
-        unsigned int i;
-        for ( i=0; i< m_data->GetCount(); i++ )
-        {
-            if ( m_data->Item(i)->GetText() == str )
-                return i;
-        }
-    }
-    return -1;
-}
-
-// -----------------------------------------------------------------------
-
-int wxPGChoices::Index( int val ) const
-{
-    if ( IsOk() )
-    {
-        unsigned int i;
-        for ( i=0; i< m_data->GetCount(); i++ )
-        {
-            if ( m_data->Item(i)->GetValue() == val )
-                return i;
-        }
-    }
-    return -1;
-}
-
-// -----------------------------------------------------------------------
-
-wxArrayString wxPGChoices::GetLabels() const
-{
-    wxArrayString arr;
-    unsigned int i;
-
-    if ( this && IsOk() )
-        for ( i=0; i<GetCount(); i++ )
-            arr.push_back(GetLabel(i));
-
-    return arr;
-}
-
-// -----------------------------------------------------------------------
-
-bool wxPGChoices::HasValues() const
-{
-    return true;
-}
-
-// -----------------------------------------------------------------------
-
-wxArrayInt wxPGChoices::GetValuesForStrings( const wxArrayString& strings ) const
-{
-    wxArrayInt arr;
-
-    if ( IsOk() )
-    {
-        unsigned int i;
-        for ( i=0; i< strings.size(); i++ )
-        {
-            int index = Index(strings[i]);
-            if ( index >= 0 )
-                arr.Add(GetValue(index));
-            else
-                arr.Add(wxPG_INVALID_VALUE);
-        }
-    }
-
-    return arr;
-}
-
-// -----------------------------------------------------------------------
-
-wxArrayInt wxPGChoices::GetIndicesForStrings( const wxArrayString& strings, 
-                                              wxArrayString* unmatched ) const
-{
-    wxArrayInt arr;
-
-    if ( IsOk() )
-    {
-        unsigned int i;
-        for ( i=0; i< strings.size(); i++ )
-        {
-            const wxString& str = strings[i];
-            int index = Index(str);
-            if ( index >= 0 )
-                arr.Add(index);
-            else if ( unmatched )
-                unmatched->Add(str);
-        }
-    }
-
-    return arr;
-}
-
-// -----------------------------------------------------------------------
-
-void wxPGChoices::AssignData( wxPGChoicesData* data )
-{
-    Free();
-
-    if ( data != wxPGChoicesEmptyData )
+    else
     {
-        m_data = data;
-        data->m_refCount++;
+        it = m_items.begin() + index;
     }
-}
 
-// -----------------------------------------------------------------------
+    m_items.insert(it, item);
 
-void wxPGChoices::Init()
-{
-    m_data = wxPGChoicesEmptyData;
-}
+    wxPGChoiceEntry& ownEntry = m_items[index];
 
-// -----------------------------------------------------------------------
+    // Need to fix value?
+    if ( ownEntry.GetValue() == wxPG_INVALID_VALUE )
+        ownEntry.SetValue(index);
 
-void wxPGChoices::Free()
-{
-    if ( m_data != wxPGChoicesEmptyData )
-    {
-        m_data->DecRef();
-        m_data = wxPGChoicesEmptyData;
-    }
+    return ownEntry;
 }
 
 // -----------------------------------------------------------------------
@@ -5952,15 +5258,15 @@ void wxPGChoices::Free()
 IMPLEMENT_DYNAMIC_CLASS(wxPropertyGridEvent, wxCommandEvent)
 
 
-DEFINE_EVENT_TYPE( wxEVT_PG_SELECTED )
-DEFINE_EVENT_TYPE( wxEVT_PG_CHANGING )
-DEFINE_EVENT_TYPE( wxEVT_PG_CHANGED )
-DEFINE_EVENT_TYPE( wxEVT_PG_HIGHLIGHTED )
-DEFINE_EVENT_TYPE( wxEVT_PG_RIGHT_CLICK )
-DEFINE_EVENT_TYPE( wxEVT_PG_PAGE_CHANGED )
-DEFINE_EVENT_TYPE( wxEVT_PG_ITEM_EXPANDED )
-DEFINE_EVENT_TYPE( wxEVT_PG_ITEM_COLLAPSED )
-DEFINE_EVENT_TYPE( wxEVT_PG_DOUBLE_CLICK )
+wxDEFINE_EVENT( wxEVT_PG_SELECTED, wxPropertyGridEvent );
+wxDEFINE_EVENT( wxEVT_PG_CHANGING, wxPropertyGridEvent );
+wxDEFINE_EVENT( wxEVT_PG_CHANGED, wxPropertyGridEvent );
+wxDEFINE_EVENT( wxEVT_PG_HIGHLIGHTED, wxPropertyGridEvent );
+wxDEFINE_EVENT( wxEVT_PG_RIGHT_CLICK, wxPropertyGridEvent );
+wxDEFINE_EVENT( wxEVT_PG_PAGE_CHANGED, wxPropertyGridEvent );
+wxDEFINE_EVENT( wxEVT_PG_ITEM_EXPANDED, wxPropertyGridEvent );
+wxDEFINE_EVENT( wxEVT_PG_ITEM_COLLAPSED, wxPropertyGridEvent );
+wxDEFINE_EVENT( wxEVT_PG_DOUBLE_CLICK, wxPropertyGridEvent );
 
 
 // -----------------------------------------------------------------------
@@ -6008,11 +5314,6 @@ wxEvent* wxPropertyGridEvent::Clone() const
     return new wxPropertyGridEvent( *this );
 }
 
-void wxPropertyGrid::SetPropertyAttributeAll( const wxString& attrName, wxVariant value )
-{
-    DoSetPropertyAttribute(GetRoot(), attrName, value, wxPG_RECURSE);
-}
-
 // -----------------------------------------------------------------------
 // wxPropertyGridPopulator
 // -----------------------------------------------------------------------
@@ -6096,7 +5397,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;
 }
@@ -6149,7 +5451,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;
 
@@ -6300,3 +5602,5 @@ void wxPropertyGridPopulator::ProcessError( const wxString& msg )
 }
 
 // -----------------------------------------------------------------------
+
+#endif  // wxUSE_PROPGRID