]> git.saurik.com Git - wxWidgets.git/commitdiff
Added wxPropertyGrid::SetUnspecifiedValueAppearance(); Added wxPGEditor::SetControlAp...
authorJaakko Salli <jaakko.salli@dnainternet.net>
Tue, 22 Dec 2009 16:12:02 +0000 (16:12 +0000)
committerJaakko Salli <jaakko.salli@dnainternet.net>
Tue, 22 Dec 2009 16:12:02 +0000 (16:12 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@62973 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/propgrid/editors.h
include/wx/propgrid/property.h
include/wx/propgrid/propgrid.h
interface/wx/propgrid/propgrid.h
samples/propgrid/propgrid.cpp
src/propgrid/editors.cpp
src/propgrid/property.cpp
src/propgrid/propgrid.cpp

index 37c22eb99ede3c22f07f467e0397132bad49ca22..d35105a365f68eb1a3cec8d85609b1678de00d89 100644 (file)
@@ -163,9 +163,35 @@ public:
                                       wxWindow* ctrl ) const;
 #endif
 
                                       wxWindow* ctrl ) const;
 #endif
 
-    /** Sets value in control to unspecified. */
+    /**
+        Sets new appearance for the control. Default implementation
+        sets foreground colour, background colour, font, plus text
+        for wxTextCtrl and wxComboCtrl.
+
+        @param appearance
+            New appearance to be applied.
+
+        @param oldAppearance
+            Previously applied appearance. Used to detect which
+            control attributes need to be changed (e.g. so we only
+            change background colour if really needed).
+
+        @param unspecified
+            @true if the new appearance represents an unspecified
+            property value.
+    */
+    virtual void SetControlAppearance( wxPropertyGrid* pg,
+                                       wxPGProperty* property,
+                                       wxWindow* ctrl,
+                                       const wxPGCell& appearance,
+                                       const wxPGCell& oldAppearance,
+                                       bool unspecified ) const;
+
+    /**
+        Sets value in control to unspecified.
+    */
     virtual void SetValueToUnspecified( wxPGProperty* property,
     virtual void SetValueToUnspecified( wxPGProperty* property,
-                                        wxWindow* ctrl ) const = 0;
+                                        wxWindow* ctrl ) const;
 
     /** Sets control's value specifically from string. */
     virtual void SetControlStringValue( wxPGProperty* property,
 
     /** Sets control's value specifically from string. */
     virtual void SetControlStringValue( wxPGProperty* property,
@@ -239,8 +265,6 @@ public:
     virtual bool GetValueFromControl( wxVariant& variant,
                                       wxPGProperty* property,
                                       wxWindow* ctrl ) const;
     virtual bool GetValueFromControl( wxVariant& variant,
                                       wxPGProperty* property,
                                       wxWindow* ctrl ) const;
-    virtual void SetValueToUnspecified( wxPGProperty* property,
-                                        wxWindow* ctrl ) const;
 
     virtual wxString GetName() const;
 
 
     virtual wxString GetName() const;
 
index 9ec2776a80e421bf74b22acc99ad65ea431d1901..e8521d69444435b4d5949a19fd22cee71dab7489 100644 (file)
@@ -254,6 +254,11 @@ public:
         return (m_refData && GetData()->m_hasValidText);
     }
 
         return (m_refData && GetData()->m_hasValidText);
     }
 
+    /**
+        Sets empty but valid data to this cell object.
+    */
+    void SetEmptyData();
+
     /**
         Merges valid data from srcCell into this.
     */
     /**
         Merges valid data from srcCell into this.
     */
index 494423697da92c4b64373a99488303b788a0506a..c6ac6ece21af39b69523e5f7cc052f27dbb060cd 100644 (file)
@@ -1239,6 +1239,33 @@ public:
         return m_sortFunction;
     }
 
         return m_sortFunction;
     }
 
+    /**
+        Sets appearance of value cells representing an unspecified property
+        value. Default appearance is blank.
+
+        @remarks If you set the unspecified value to have any
+                 textual representation, then that will override
+                 "InlineHelp" attribute.
+
+        @see wxPGProperty::SetValueToUnspecified(),
+             wxPGProperty::IsValueUnspecified()
+    */
+    void SetUnspecifiedValueAppearance( const wxPGCell& cell )
+    {
+        m_unspecifiedAppearance = m_propertyDefaultCell;
+        m_unspecifiedAppearance.MergeFrom(cell);
+    }
+
+    /**
+        Returns current appearance of unspecified value cells.
+
+        @see SetUnspecifiedValueAppearance()
+    */
+    const wxPGCell& GetUnspecifiedValueAppearance() const
+    {
+        return m_unspecifiedAppearance;
+    }
+
     /**
         Returns (visual) text representation of the unspecified
         property value.
     /**
         Returns (visual) text representation of the unspecified
         property value.
@@ -1764,6 +1791,12 @@ protected:
     /** Actions and keys that trigger them. */
     wxPGHashMapI2I      m_actionTriggers;
 
     /** Actions and keys that trigger them. */
     wxPGHashMapI2I      m_actionTriggers;
 
+    /** Appearance of currently active editor. */
+    wxPGCell            m_editorAppearance;
+
+    /** Appearance of a unspecified value cell. */
+    wxPGCell            m_unspecifiedAppearance;
+
     //
     // Temporary values
     //
     //
     // Temporary values
     //
@@ -2062,6 +2095,16 @@ protected:
     */
     void RecalculateVirtualSize( int forceXPos = -1 );
 
     */
     void RecalculateVirtualSize( int forceXPos = -1 );
 
+    void SetEditorAppearance( const wxPGCell& cell,
+                              bool unspecified = false );
+
+    void ResetEditorAppearance()
+    {
+        wxPGCell cell;
+        cell.SetEmptyData();
+        SetEditorAppearance(cell, false);
+    }
+
     void PrepareAfterItemsAdded();
 
     /**
     void PrepareAfterItemsAdded();
 
     /**
index c9bc3dfc0af7b060a59456c4ee1bfffdc157cee2..6a75c9b0452f40a1d3004f5f9b6b3afe6e933315 100644 (file)
@@ -740,6 +740,13 @@ public:
     */
     wxTextCtrl* GetEditorTextCtrl() const;
 
     */
     wxTextCtrl* GetEditorTextCtrl() const;
 
+    /**
+        Returns current appearance of unspecified value cells.
+
+        @see SetUnspecifiedValueAppearance()
+    */
+    const wxPGCell& GetUnspecifiedValueAppearance() const;
+
     /**
         Returns (visual) text representation of the unspecified
         property value.
     /**
         Returns (visual) text representation of the unspecified
         property value.
@@ -981,6 +988,19 @@ public:
     */
     void SetSplitterLeft( bool privateChildrenToo = false );
 
     */
     void SetSplitterLeft( bool privateChildrenToo = false );
 
+    /**
+        Sets appearance of value cells representing an unspecified property
+        value. Default appearance is blank.
+
+        @remarks If you set the unspecified value to have any
+                 textual representation, then that will override
+                 "InlineHelp" attribute.
+
+        @see wxPGProperty::SetValueToUnspecified(),
+             wxPGProperty::IsValueUnspecified()
+    */
+    void SetUnspecifiedValueAppearance( const wxPGCell& cell );
+
     /**
         Sets vertical spacing. Can be 1, 2, or 3 - a value relative to font
         height. Value of 2 should be default on most platforms.
     /**
         Sets vertical spacing. Can be 1, 2, or 3 - a value relative to font
         height. Value of 2 should be default on most platforms.
index 410ec6936aba7fe9ace651243263db8c382a64ae..04c3db2f2d8c9db9e9ac8dc1d5d14a72af19e9fb 100644 (file)
@@ -2156,6 +2156,13 @@ void FormMain::CreateGrid( int style, int extraStyle )
 
     m_pPropGridManager->GetGrid()->SetVerticalSpacing( 2 );
 
 
     m_pPropGridManager->GetGrid()->SetVerticalSpacing( 2 );
 
+    //
+    // Set somewhat different unspecified value appearance
+    wxPGCell cell;
+    cell.SetText("Unspecified");
+    cell.SetFgCol(*wxLIGHT_GREY);
+    m_propGrid->SetUnspecifiedValueAppearance(cell);
+
     PopulateGrid();
 
     // Change some attributes in all properties
     PopulateGrid();
 
     // Change some attributes in all properties
index fa487428a4116259e6a0423a968cf43d3a9ed927..21262e302d4b27500117aa2b5905d9e597db75f5 100644 (file)
@@ -169,13 +169,11 @@ wxString wxPGEditor::GetName() const
     return GetClassInfo()->GetClassName();
 }
 
     return GetClassInfo()->GetClassName();
 }
 
-void wxPGEditor::DrawValue( wxDC& dc, const wxRect& rect, wxPGProperty* property, const wxString& text ) const
+void wxPGEditor::DrawValue( wxDC& dc, const wxRect& rect,
+                            wxPGProperty* WXUNUSED(property),
+                            const wxString& text ) const
 {
 {
-    if ( !property->IsValueUnspecified() )
-        dc.DrawText( text, rect.x+wxPG_XBEFORETEXT, rect.y );
-    else
-        dc.DrawText( property->GetGrid()->GetUnspecifiedValueText(),
-                     rect.x+wxPG_XBEFORETEXT, rect.y );
+    dc.DrawText( text, rect.x+wxPG_XBEFORETEXT, rect.y );
 }
 
 bool wxPGEditor::GetValueFromControl( wxVariant&, wxPGProperty*, wxWindow* ) const
 }
 
 bool wxPGEditor::GetValueFromControl( wxVariant&, wxPGProperty*, wxWindow* ) const
@@ -209,6 +207,104 @@ void wxPGEditor::OnFocus( wxPGProperty*, wxWindow* ) const
 {
 }
 
 {
 }
 
+void wxPGEditor::SetControlAppearance( wxPropertyGrid* pg,
+                                       wxPGProperty* property,
+                                       wxWindow* ctrl,
+                                       const wxPGCell& cell,
+                                       const wxPGCell& oCell,
+                                       bool WXUNUSED(unspecified) ) const
+{
+    // Get old editor appearance
+    wxTextCtrl* tc = NULL;
+    wxComboCtrl* cb = NULL;
+    if ( ctrl->IsKindOf(CLASSINFO(wxTextCtrl)) )
+    {
+        tc = (wxTextCtrl*) ctrl;
+    }
+    else
+    {
+        if ( ctrl->IsKindOf(CLASSINFO(wxComboCtrl)) )
+        {
+            cb = (wxComboCtrl*) ctrl;
+            tc = cb->GetTextCtrl();
+        }
+    }
+
+    if ( tc || cb )
+    {
+        wxString tcText;
+        bool changeText = false;
+
+        if ( cell.HasText() && !pg->IsEditorFocused() )
+        {
+            tcText = cell.GetText();
+            changeText = true;
+        }
+        else if ( oCell.HasText() )
+        {
+            tcText = property->GetValueAsString(
+                property->HasFlag(wxPG_PROP_READONLY)?0:wxPG_EDITABLE_VALUE);
+            changeText = true;
+        }
+
+        if ( changeText )
+        {
+            // This prevents value from being modified
+            if ( tc )
+            {
+                pg->SetupTextCtrlValue(tcText);
+                tc->SetValue(tcText);
+            }
+            else
+            {
+                cb->SetText(tcText);
+            }
+        }
+    }
+
+    wxVisualAttributes vattrs = ctrl->GetDefaultAttributes();
+
+    // Foreground colour
+    const wxColour& fgCol = cell.GetFgCol();
+    if ( fgCol.IsOk() )
+    {
+        ctrl->SetForegroundColour(fgCol);
+    }
+    else if ( oCell.GetFgCol().IsOk() )
+    {
+        ctrl->SetForegroundColour(vattrs.colFg);
+    }
+
+    // Background colour
+    const wxColour& bgCol = cell.GetBgCol();
+    if ( bgCol.IsOk() )
+    {
+        ctrl->SetBackgroundColour(bgCol);
+    }
+    else if ( oCell.GetBgCol().IsOk() )
+    {
+        ctrl->SetBackgroundColour(vattrs.colBg);
+    }
+
+    // Font
+    const wxFont& font = cell.GetFont();
+    if ( font.IsOk() )
+    {
+        ctrl->SetFont(font);
+    }
+    else if ( oCell.GetFont().IsOk() )
+    {
+        ctrl->SetFont(vattrs.font);
+    }
+
+    // Also call the old SetValueToUnspecified()
+    SetValueToUnspecified(property, ctrl);
+}
+
+void wxPGEditor::SetValueToUnspecified( wxPGProperty* WXUNUSED(property),
+                                        wxWindow* WXUNUSED(ctrl) ) const
+{
+}
 
 bool wxPGEditor::CanContainCustomImage() const
 {
 
 bool wxPGEditor::CanContainCustomImage() const
 {
@@ -235,8 +331,10 @@ wxPGWindowList wxPGTextCtrlEditor::CreateControls( wxPropertyGrid* propGrid,
          property->GetChildCount() )
         return NULL;
 
          property->GetChildCount() )
         return NULL;
 
-    int argFlags = property->HasFlag(wxPG_PROP_READONLY) ? 
-        0 : wxPG_EDITABLE_VALUE;
+    int argFlags = 0;
+    if ( !property->HasFlag(wxPG_PROP_READONLY) &&
+         !property->IsValueUnspecified() )
+        argFlags |= wxPG_EDITABLE_VALUE;
     text = property->GetValueAsString(argFlags);
 
     int flags = 0;
     text = property->GetValueAsString(argFlags);
 
     int flags = 0;
@@ -366,7 +464,7 @@ bool wxPGTextCtrlEditor::GetValueFromControl( wxVariant& variant, wxPGProperty*
 }
 
 
 }
 
 
-void wxPGTextCtrlEditor::SetValueToUnspecified( wxPGProperty* property, wxWindow* ctrl ) const
+void wxPGTextCtrlEditor::SetControlStringValue( wxPGProperty* property, wxWindow* ctrl, const wxString& txt ) const
 {
     wxTextCtrl* tc = wxStaticCast(ctrl, wxTextCtrl);
 
 {
     wxTextCtrl* tc = wxStaticCast(ctrl, wxTextCtrl);
 
@@ -374,35 +472,37 @@ void wxPGTextCtrlEditor::SetValueToUnspecified( wxPGProperty* property, wxWindow
     wxASSERT(pg);  // Really, property grid should exist if editor does
     if ( pg )
     {
     wxASSERT(pg);  // Really, property grid should exist if editor does
     if ( pg )
     {
-        wxString unspecValueText = pg->GetUnspecifiedValueText();
-        pg->SetupTextCtrlValue(unspecValueText);
-        tc->SetValue(unspecValueText);
+        pg->SetupTextCtrlValue(txt);
+        tc->SetValue(txt);
     }
 }
 
 
     }
 }
 
 
-void wxPGTextCtrlEditor::SetControlStringValue( wxPGProperty* property, wxWindow* ctrl, const wxString& txt ) const
+void wxPGTextCtrlEditor_OnFocus( wxPGProperty* property,
+                                 wxTextCtrl* tc )
 {
 {
-    wxTextCtrl* tc = wxStaticCast(ctrl, wxTextCtrl);
+    // Make sure there is correct text (instead of unspecified value
+    // indicator or inline help)
+    int flags = property->HasFlag(wxPG_PROP_READONLY) ? 
+        0 : wxPG_EDITABLE_VALUE;
+    wxString correctText = property->GetValueAsString(flags);
 
 
-    wxPropertyGrid* pg = property->GetGrid();
-    wxASSERT(pg);  // Really, property grid should exist if editor does
-    if ( pg )
+    if ( tc->GetValue() != correctText )
     {
     {
-        pg->SetupTextCtrlValue(txt);
-        tc->SetValue(txt);
+        property->GetGrid()->SetupTextCtrlValue(correctText);
+        tc->SetValue(correctText);
     }
     }
-}
-
 
 
-void wxPGTextCtrlEditor::OnFocus( wxPGProperty*, wxWindow* wnd ) const
+    tc->SetSelection(-1,-1);
+}
+void wxPGTextCtrlEditor::OnFocus( wxPGProperty* property,
+                                  wxWindow* wnd ) const
 {
     wxTextCtrl* tc = wxStaticCast(wnd, wxTextCtrl);
 {
     wxTextCtrl* tc = wxStaticCast(wnd, wxTextCtrl);
-
-    tc->SetSelection(-1,-1);
+    wxPGTextCtrlEditor_OnFocus(property, tc);
 }
 
 }
 
-
 wxPGTextCtrlEditor::~wxPGTextCtrlEditor() { }
 
 
 wxPGTextCtrlEditor::~wxPGTextCtrlEditor() { }
 
 
@@ -810,6 +910,13 @@ bool wxPGChoiceEditor_SetCustomPaintWidth( wxPropertyGrid* propGrid, wxPGComboBo
     wxSize imageSize;
     bool res;
 
     wxSize imageSize;
     bool res;
 
+    // TODO: Do this always when cell has custom text.
+    if ( property->IsValueUnspecified() )
+    {
+        cb->SetCustomPaintWidth( 0 );
+        return true;
+    }
+
     if ( cmnVal >= 0 )
     {
         // Yes, a common value is being selected
     if ( cmnVal >= 0 )
     {
         // Yes, a common value is being selected
@@ -842,10 +949,11 @@ wxWindow* wxPGChoiceEditor::CreateControlsBase( wxPropertyGrid* propGrid,
     wxString defString;
     int index = property->GetChoiceSelection();
 
     wxString defString;
     int index = property->GetChoiceSelection();
 
-    bool isUnspecified = property->IsValueUnspecified();
-
-    if ( !isUnspecified )
-        defString = property->GetDisplayedString();
+    int argFlags = 0;
+    if ( !property->HasFlag(wxPG_PROP_READONLY) &&
+         !property->IsValueUnspecified() )
+        argFlags |= wxPG_EDITABLE_VALUE;
+    defString = property->GetValueAsString(argFlags);
 
     wxArrayString labels = choices.GetLabels();
 
 
     wxArrayString labels = choices.GetLabels();
 
@@ -871,7 +979,7 @@ wxWindow* wxPGChoiceEditor::CreateControlsBase( wxPropertyGrid* propGrid,
     unsigned int cmnVals = property->GetDisplayedCommonValueCount();
     if ( cmnVals )
     {
     unsigned int cmnVals = property->GetDisplayedCommonValueCount();
     if ( cmnVals )
     {
-        if ( !isUnspecified )
+        if ( !property->IsValueUnspecified() )
         {
             int cmnVal = property->GetCommonValue();
             if ( cmnVal >= 0 )
         {
             int cmnVal = property->GetCommonValue();
             if ( cmnVal >= 0 )
@@ -1040,25 +1148,13 @@ void wxPGChoiceEditor::SetControlIntValue( wxPGProperty* WXUNUSED(property), wxW
 }
 
 
 }
 
 
-void wxPGChoiceEditor::SetValueToUnspecified( wxPGProperty* property,
+void wxPGChoiceEditor::SetValueToUnspecified( wxPGProperty* WXUNUSED(property),
                                               wxWindow* ctrl ) const
 {
     wxOwnerDrawnComboBox* cb = (wxOwnerDrawnComboBox*)ctrl;
 
                                               wxWindow* ctrl ) const
 {
     wxOwnerDrawnComboBox* cb = (wxOwnerDrawnComboBox*)ctrl;
 
-    if ( !cb->HasFlag(wxCB_READONLY) )
-    {
-        wxPropertyGrid* pg = property->GetGrid();
-        if ( pg )
-        {
-            wxString tcText = pg->GetUnspecifiedValueText();
-            pg->SetupTextCtrlValue(tcText);
-            cb->SetValue(tcText);
-        }
-    }
-    else
-    {
+    if ( cb->HasFlag(wxCB_READONLY) )
         cb->SetSelection(-1);
         cb->SetSelection(-1);
-    }
 }
 
 
 }
 
 
@@ -1144,10 +1240,11 @@ bool wxPGComboBoxEditor::GetValueFromControl( wxVariant& variant, wxPGProperty*
 }
 
 
 }
 
 
-void wxPGComboBoxEditor::OnFocus( wxPGProperty*, wxWindow* ctrl ) const
+void wxPGComboBoxEditor::OnFocus( wxPGProperty* property,
+                                  wxWindow* ctrl ) const
 {
     wxOwnerDrawnComboBox* cb = (wxOwnerDrawnComboBox*)ctrl;
 {
     wxOwnerDrawnComboBox* cb = (wxOwnerDrawnComboBox*)ctrl;
-    cb->GetTextCtrl()->SetSelection(-1,-1);
+    wxPGTextCtrlEditor_OnFocus(property, cb->GetTextCtrl());
 }
 
 
 }
 
 
@@ -1871,6 +1968,28 @@ wxWindow* wxPropertyGrid::GenerateEditorTextCtrlAndButton( const wxPoint& pos,
 
 // -----------------------------------------------------------------------
 
 
 // -----------------------------------------------------------------------
 
+void wxPropertyGrid::SetEditorAppearance( const wxPGCell& cell,
+                                          bool unspecified )
+{
+    wxPGProperty* property = GetSelection();
+    if ( !property )
+        return;
+    wxWindow* ctrl = GetEditorControl();
+    if ( !ctrl )
+        return;
+
+    property->GetEditorClass()->SetControlAppearance( this,
+                                                      property,
+                                                      ctrl,
+                                                      cell,
+                                                      m_editorAppearance,
+                                                      unspecified );
+
+    m_editorAppearance = cell;
+}
+
+// -----------------------------------------------------------------------
+
 wxTextCtrl* wxPropertyGrid::GetEditorTextCtrl() const
 {
     wxWindow* wnd = GetEditorControl();
 wxTextCtrl* wxPropertyGrid::GetEditorTextCtrl() const
 {
     wxWindow* wnd = GetEditorControl();
index 1e9f6100bd5995de7dcfafe2f02dd818ade96dc9..ca3543a2ff03f835ca985531b9fb584487c3d953 100644 (file)
@@ -135,8 +135,9 @@ int wxPGCellRenderer::PreDrawCell( wxDC& dc, const wxRect& rect, const wxPGCell&
     // If possible, use cell colours
     if ( !(flags & DontUseCellBgCol) )
     {
     // If possible, use cell colours
     if ( !(flags & DontUseCellBgCol) )
     {
-        dc.SetPen(cell.GetBgCol());
-        dc.SetBrush(cell.GetBgCol());
+        const wxColour& bgCol = cell.GetBgCol();
+        dc.SetPen(bgCol);
+        dc.SetBrush(bgCol);
     }
 
     if ( !(flags & DontUseCellFgCol) )
     }
 
     if ( !(flags & DontUseCellFgCol) )
@@ -417,6 +418,12 @@ void wxPGCell::MergeFrom( const wxPGCell& srcCell )
         data->SetBitmap(srcCell.GetBitmap());
 }
 
         data->SetBitmap(srcCell.GetBitmap());
 }
 
+void wxPGCell::SetEmptyData()
+{
+    AllocExclusive();
+}
+
+
 // -----------------------------------------------------------------------
 // wxPGProperty
 // -----------------------------------------------------------------------
 // -----------------------------------------------------------------------
 // wxPGProperty
 // -----------------------------------------------------------------------
@@ -706,8 +713,17 @@ void wxPGProperty::GetDisplayInfo( unsigned int column,
 
     if ( !(flags & wxPGCellRenderer::ChoicePopup) )
     {
 
     if ( !(flags & wxPGCellRenderer::ChoicePopup) )
     {
-        // Not painting listi of choice popups, so get text from property
-        cell = &GetCell(column);
+        // Not painting list of choice popups, so get text from property
+        if ( column != 1 || !IsValueUnspecified() || IsCategory() )
+        {
+            cell = &GetCell(column);
+        }
+        else
+        {
+            // Use special unspecified value cell
+            cell = &GetGrid()->GetUnspecifiedValueAppearance();
+        }
+
         if ( cell->HasText() )
         {
             *pString = cell->GetText();
         if ( cell->HasText() )
         {
             *pString = cell->GetText();
index b35676b458218128aa6c5851c1af141ad51ab7f3..96198a3af874a7ced74f62b496ac145b8081977a 100644 (file)
@@ -345,6 +345,9 @@ void wxPropertyGrid::Init1()
     m_mouseSide = 16;
     m_editorFocused = 0;
 
     m_mouseSide = 16;
     m_editorFocused = 0;
 
+    // Must set empty but valid data
+    m_unspecifiedAppearance.SetEmptyData();
+
     // Set default keys
     AddActionTrigger( wxPG_ACTION_NEXT_PROPERTY, WXK_RIGHT );
     AddActionTrigger( wxPG_ACTION_NEXT_PROPERTY, WXK_DOWN );
     // Set default keys
     AddActionTrigger( wxPG_ACTION_NEXT_PROPERTY, WXK_RIGHT );
     AddActionTrigger( wxPG_ACTION_NEXT_PROPERTY, WXK_DOWN );
@@ -441,9 +444,9 @@ void wxPropertyGrid::Init2()
 
     CalculateFontAndBitmapStuff( wxPG_DEFAULT_VSPACING );
 
 
     CalculateFontAndBitmapStuff( wxPG_DEFAULT_VSPACING );
 
-    // Allocate cell datas indirectly by calling setter
-    m_propertyDefaultCell.SetBgCol(*wxBLACK);
-    m_categoryDefaultCell.SetBgCol(*wxBLACK);
+    // Allocate cell datas
+    m_propertyDefaultCell.SetEmptyData();
+    m_categoryDefaultCell.SetEmptyData();
 
     RegainColours();
 
 
     RegainColours();
 
@@ -1384,6 +1387,8 @@ void wxPropertyGrid::RegainColours()
         wxColour bgCol = wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW );
         m_colPropBack = bgCol;
         m_propertyDefaultCell.GetData()->SetBgCol(bgCol);
         wxColour bgCol = wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW );
         m_colPropBack = bgCol;
         m_propertyDefaultCell.GetData()->SetBgCol(bgCol);
+        if ( !m_unspecifiedAppearance.GetBgCol().IsOk() )
+            m_unspecifiedAppearance.SetBgCol(bgCol);
     }
 
     if ( !(m_coloursCustomized & 0x0010) )
     }
 
     if ( !(m_coloursCustomized & 0x0010) )
@@ -1391,6 +1396,8 @@ void wxPropertyGrid::RegainColours()
         wxColour fgCol = wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWTEXT );
         m_colPropFore = fgCol;
         m_propertyDefaultCell.GetData()->SetFgCol(fgCol);
         wxColour fgCol = wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWTEXT );
         m_colPropFore = fgCol;
         m_propertyDefaultCell.GetData()->SetFgCol(fgCol);
+        if ( !m_unspecifiedAppearance.GetFgCol().IsOk() )
+            m_unspecifiedAppearance.SetFgCol(fgCol);
     }
 
     if ( !(m_coloursCustomized & 0x0020) )
     }
 
     if ( !(m_coloursCustomized & 0x0020) )
@@ -1462,6 +1469,7 @@ void wxPropertyGrid::SetCellBackgroundColour( const wxColour& col )
     m_coloursCustomized |= 0x08;
 
     m_propertyDefaultCell.GetData()->SetBgCol(col);
     m_coloursCustomized |= 0x08;
 
     m_propertyDefaultCell.GetData()->SetBgCol(col);
+    m_unspecifiedAppearance.SetBgCol(col);
 
     Refresh();
 }
 
     Refresh();
 }
@@ -1474,6 +1482,7 @@ void wxPropertyGrid::SetCellTextColour( const wxColour& col )
     m_coloursCustomized |= 0x10;
 
     m_propertyDefaultCell.GetData()->SetFgCol(col);
     m_coloursCustomized |= 0x10;
 
     m_propertyDefaultCell.GetData()->SetFgCol(col);
+    m_unspecifiedAppearance.SetFgCol(col);
 
     Refresh();
 }
 
     Refresh();
 }
@@ -3629,9 +3638,18 @@ void wxPropertyGrid::CustomSetCursor( int type, bool override )
     m_curcursor = type;
 }
 
     m_curcursor = type;
 }
 
+// -----------------------------------------------------------------------
+
 wxString
 wxString
-wxPropertyGrid::GetUnspecifiedValueText( int WXUNUSED(argFlags) ) const
+wxPropertyGrid::GetUnspecifiedValueText( int argFlags ) const
 {
 {
+    const wxPGCell& ua = GetUnspecifiedValueAppearance();
+
+    if ( ua.HasText() &&
+         !(argFlags & wxPG_FULL_VALUE) &&
+         !(argFlags & wxPG_EDITABLE_VALUE) )
+        return ua.GetText();
+
     return wxEmptyString;
 }
 
     return wxEmptyString;
 }
 
@@ -3916,6 +3934,9 @@ bool wxPropertyGrid::DoSelectProperty( wxPGProperty* p, unsigned int flags )
                 wxRect grect = GetEditorWidgetRect(p, m_selColumn);
                 wxPoint goodPos = grect.GetPosition();
 
                 wxRect grect = GetEditorWidgetRect(p, m_selColumn);
                 wxPoint goodPos = grect.GetPosition();
 
+                // Editor appearance can now be considered clear
+                m_editorAppearance.SetEmptyData();
+
                 const wxPGEditor* editor = p->GetEditorClass();
                 wxCHECK_MSG(editor, false,
                     wxT("NULL editor class not allowed"));
                 const wxPGEditor* editor = p->GetEditorClass();
                 wxCHECK_MSG(editor, false,
                     wxT("NULL editor class not allowed"));
@@ -3985,6 +4006,12 @@ bool wxPropertyGrid::DoSelectProperty( wxPGProperty* p, unsigned int flags )
 
                         p->GetEditorClass()->OnFocus(p, primaryCtrl);
                     }
 
                         p->GetEditorClass()->OnFocus(p, primaryCtrl);
                     }
+                    else
+                    {
+                        if ( p->IsValueUnspecified() )
+                            SetEditorAppearance(m_unspecifiedAppearance,
+                                                true);
+                    }
                 }
 
                 if ( m_wndEditor2 )
                 }
 
                 if ( m_wndEditor2 )
@@ -4151,7 +4178,7 @@ void wxPropertyGrid::RefreshEditor()
     editorClass->UpdateControl(p, wnd);
 
     if ( p->IsValueUnspecified() )
     editorClass->UpdateControl(p, wnd);
 
     if ( p->IsValueUnspecified() )
-        editorClass ->SetValueToUnspecified(p, wnd);
+        SetEditorAppearance(m_unspecifiedAppearance, true);
 }
 
 // -----------------------------------------------------------------------
 }
 
 // -----------------------------------------------------------------------