]> git.saurik.com Git - wxWidgets.git/commitdiff
Added label editing capability into wxPropertyGrid
authorJaakko Salli <jaakko.salli@dnainternet.net>
Sun, 23 Aug 2009 15:31:03 +0000 (15:31 +0000)
committerJaakko Salli <jaakko.salli@dnainternet.net>
Sun, 23 Aug 2009 15:31:03 +0000 (15:31 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@61743 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

13 files changed:
include/wx/propgrid/property.h
include/wx/propgrid/propgrid.h
include/wx/propgrid/propgridiface.h
include/wx/propgrid/propgridpagestate.h
interface/wx/propgrid/property.h
interface/wx/propgrid/propgrid.h
samples/propgrid/propgrid.cpp
samples/propgrid/propgrid.h
src/propgrid/editors.cpp
src/propgrid/property.cpp
src/propgrid/propgrid.cpp
src/propgrid/propgridiface.cpp
src/propgrid/propgridpagestate.cpp

index bddf659f98a9efe1289fde1d8a5fc879f4007beb..ca40fb77658ffe5ba0a99948e6ef1a83e0effb42 100644 (file)
@@ -1561,10 +1561,25 @@ public:
 
     /**
         Returns wxPGCell of given column.
+
+        @remarks const version of this member function returns 'default'
+                 wxPGCell object if the property itself didn't hold
+                 cell data.
     */
     const wxPGCell& GetCell( unsigned int column ) const;
 
-    wxPGCell& GetCell( unsigned int column );
+    /**
+        Returns wxPGCell of given column, creating one if necessary.
+    */
+    wxPGCell& GetCell( unsigned int column )
+    {
+        return GetOrCreateCell(column);
+    }
+
+    /**
+        Returns wxPGCell of given column, creating one if necessary.
+    */
+    wxPGCell& GetOrCreateCell( unsigned int column );
 
     /** Return number of displayed common values for this property.
     */
@@ -2242,6 +2257,13 @@ protected:
     /** Deletes all sub-properties. */
     void Empty();
 
+    bool HasCell( unsigned int column ) const
+    {
+        if ( m_cells.size() > column )
+            return true;
+        return false;
+    }
+
     void InitAfterAdded( wxPropertyGridPageState* pageState,
                          wxPropertyGrid* propgrid );
 
index b33c55ed3655331e5cb16bcb89dfd8090438baa2..aa6c9cea1b61bfa4b6836e79b13138992250a969 100644 (file)
@@ -448,22 +448,23 @@ enum wxPG_KEYBOARD_ACTIONS
 // wxPropertyGrid::DoSelectProperty flags (selFlags)
 
 // Focuses to created editor
-#define wxPG_SEL_FOCUS                  0x01
+#define wxPG_SEL_FOCUS                  0x0001
 // Forces deletion and recreation of editor
-#define wxPG_SEL_FORCE                  0x02
+#define wxPG_SEL_FORCE                  0x0002
 // For example, doesn't cause EnsureVisible
-#define wxPG_SEL_NONVISIBLE             0x04
+#define wxPG_SEL_NONVISIBLE             0x0004
 // Do not validate editor's value before selecting
-#define wxPG_SEL_NOVALIDATE             0x08
+#define wxPG_SEL_NOVALIDATE             0x0008
 // Property being deselected is about to be deleted
-#define wxPG_SEL_DELETING               0x10
+#define wxPG_SEL_DELETING               0x0010
 // Property's values was set to unspecified by the user
-#define wxPG_SEL_SETUNSPEC              0x20
+#define wxPG_SEL_SETUNSPEC              0x0020
 // Property's event handler changed the value
-#define wxPG_SEL_DIALOGVAL              0x40
+#define wxPG_SEL_DIALOGVAL              0x0040
 // Set to disable sending of wxEVT_PG_SELECTED event
-#define wxPG_SEL_DONT_SEND_EVENT        0x80
-
+#define wxPG_SEL_DONT_SEND_EVENT        0x0080
+// Don't make any graphics updates
+#define wxPG_SEL_NO_REFRESH             0x0100
 
 // -----------------------------------------------------------------------
 
@@ -583,6 +584,14 @@ enum wxPG_KEYBOARD_ACTIONS
     @event{EVT_PG_ITEM_EXPANDED(id, func)}
         Respond to wxEVT_PG_ITEM_EXPANDED event, generated when user expands
         a property or category..
+    @event{EVT_PG_LABEL_EDIT_BEGIN(id, func)}
+        Respond to wxEVT_PG_LABEL_EDIT_BEGIN event, generated when is about to
+        begin editing a property label. You can veto this event to prevent the
+        action.
+    @event{EVT_PG_LABEL_EDIT_ENDING(id, func)}
+        Respond to wxEVT_PG_LABEL_EDIT_ENDING event, generated when is about to
+        end editing of a property label. You can veto this event to prevent the
+        action.
     @endEventTable
 
     @remarks
@@ -1000,6 +1009,57 @@ public:
         return DoRemoveFromSelection(p, wxPG_SEL_DONT_SEND_EVENT);
     }
 
+    /**
+        Makes given column editable by user.
+
+        @see BeginLabelEdit(), EndLabelEdit()
+    */
+    void MakeColumnEditable( unsigned int column )
+    {
+        wxASSERT( column != 1 );
+        m_pState->m_editableColumns.push_back(column);
+    }
+
+    /**
+        Creates label editor wxTextCtrl for given column, for property
+        that is currently selected. When multiple selection is
+        enabled, this applies to whatever property GetSelection()
+        returns.
+
+        @param colIndex
+            Which column's label to edit. Note that you should not
+            use value 1, which is reserved for property value
+            column.
+
+        @see EndLabelEdit(), MakeColumnEditable()
+    */
+    void BeginLabelEdit( unsigned int column = 0 )
+    {
+        DoBeginLabelEdit(column, wxPG_SEL_DONT_SEND_EVENT);
+    }
+
+    /**
+        Destroys label editor wxTextCtrl, if any.
+
+        @param commit
+            Use @true (default) to store edited label text in
+            property cell data.
+
+        @see BeginLabelEdit(), MakeColumnEditable()
+    */
+    void EndLabelEdit( bool commit = true )
+    {
+        DoEndLabelEdit(commit, wxPG_SEL_DONT_SEND_EVENT);
+    }
+
+    /**
+        Returns currently active label editor, NULL if none.
+    */
+    wxTextCtrl* GetLabelEditor() const
+    {
+        return m_labelEditor;
+    }
+
     /** Sets category caption background colour. */
     void SetCaptionBackgroundColour(const wxColour& col);
 
@@ -1199,6 +1259,7 @@ public:
         shown).
     */
     void FixPosForTextCtrl( wxWindow* ctrl,
+                            unsigned int forColumn = 1,
                             const wxPoint& offset = wxPoint(0, 0) );
 
     /** Shortcut for creating text editor widget.
@@ -1222,7 +1283,8 @@ public:
                                       const wxString& value,
                                       wxWindow* secondary,
                                       int extraStyle = 0,
-                                      int maxLen = 0 );
+                                      int maxLen = 0,
+                                      unsigned int forColumn = 1 );
 
     /* Generates both textctrl and button.
     */
@@ -1677,9 +1739,18 @@ protected:
     /** When drawing next time, clear this many item slots at the end. */
     int                 m_clearThisMany;
 
+    // Mouse is hovering over this column (index)
+    unsigned int        m_colHover;
+
     // pointer to property that has mouse hovering
     wxPGProperty*       m_propHover;
 
+    // Active label editor
+    wxTextCtrl*         m_labelEditor;
+
+    // For which property the label editor is active
+    wxPGProperty*       m_labelEditorProperty;
+
     // EventObject for wxPropertyGridEvents
     wxWindow*           m_eventObject;
 
@@ -1701,8 +1772,9 @@ protected:
 
     // y coordinate of property that mouse hovering
     int                 m_propHoverY;
+
     // Which column's editor is selected (usually 1)?
-    int                 m_selColumn;
+    unsigned int        m_selColumn;
 
     // x relative to splitter (needed for resize).
     int                 m_ctrlXAdjust;
@@ -1804,6 +1876,7 @@ protected:
 protected:
 
     bool AddToSelectionFromInputEvent( wxPGProperty* prop,
+                                       unsigned int colIndex,
                                        wxMouseEvent* event = NULL,
                                        int selFlags = 0 );
 
@@ -1858,6 +1931,13 @@ protected:
 
     bool DoEditorValidate();
 
+    // Similar to DoSelectProperty() but also works on columns
+    // other than 1. Does not active editor if column is not
+    // editable.
+    bool DoSelectAndEdit( wxPGProperty* prop,
+                          unsigned int colIndex,
+                          unsigned int selFlags );
+
     void DoSetSelection( const wxArrayPGProperty& newSelection,
                          int selFlags = 0 );
 
@@ -1867,6 +1947,11 @@ protected:
     bool DoRemoveFromSelection( wxPGProperty* prop,
                                 int selFlags = 0 );
 
+    void DoBeginLabelEdit( unsigned int colIndex, int selFlags = 0 );
+    void DoEndLabelEdit( bool commit, int selFlags = 0 );
+    void OnLabelEditorEnterPress( wxCommandEvent& event );
+    void OnLabelEditorKeyPress( wxKeyEvent& event );
+
     wxPGProperty* DoGetItemAtY( int y ) const;
 
     void DoSetSplitterPosition_( int newxpos,
@@ -1874,6 +1959,7 @@ protected:
                                  int splitterIndex = 0,
                                  bool allPages = false );
 
+    void DestroyEditorWnd( wxWindow* wnd );
     void FreeEditors();
 
     virtual bool DoExpand( wxPGProperty* p, bool sendEvent = false );
@@ -1900,10 +1986,11 @@ protected:
 
     void PrepareAfterItemsAdded();
 
-    bool SendEvent( int eventType,
-                    wxPGProperty* p,
+    // Omit the wxPG_SEL_NOVALIDATE flag to allow vetoing the event
+    bool SendEvent( int eventType, wxPGProperty* p,
                     wxVariant* pValue = NULL,
-                    unsigned int selFlags = 0 );
+                    unsigned int selFlags = wxPG_SEL_NOVALIDATE,
+                    unsigned int column = 1 );
 
     void SetFocusOnCanvas();
 
@@ -1980,6 +2067,10 @@ wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_PROPGRID, wxEVT_PG_PAGE_CHANGED, wxPropert
 wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_PROPGRID, wxEVT_PG_ITEM_COLLAPSED, wxPropertyGridEvent );
 wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_PROPGRID, wxEVT_PG_ITEM_EXPANDED, wxPropertyGridEvent );
 wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_PROPGRID, wxEVT_PG_DOUBLE_CLICK, wxPropertyGridEvent );
+wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_PROPGRID,
+                          wxEVT_PG_LABEL_EDIT_BEGIN, wxPropertyGridEvent );
+wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_PROPGRID,
+                          wxEVT_PG_LABEL_EDIT_ENDING, wxPropertyGridEvent );
 
 #else
     enum {
@@ -1991,7 +2082,9 @@ wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_PROPGRID, wxEVT_PG_DOUBLE_CLICK, wxPropert
         wxEVT_PG_PAGE_CHANGED,
         wxEVT_PG_ITEM_COLLAPSED,
         wxEVT_PG_ITEM_EXPANDED,
-        wxEVT_PG_DOUBLE_CLICK
+        wxEVT_PG_DOUBLE_CLICK,
+        wxEVT_PG_LABEL_EDIT_BEGIN,
+        wxEVT_PG_LABEL_EDIT_ENDING
     };
 #endif
 
@@ -2012,6 +2105,8 @@ typedef void (wxEvtHandler::*wxPropertyGridEventFunction)(wxPropertyGridEvent&);
 #define EVT_PG_PAGE_CHANGED(id, fn)          DECLARE_EVENT_TABLE_ENTRY( wxEVT_PG_PAGE_CHANGED, id, -1, wxEVENT_HANDLER_CAST( wxPropertyGridEventFunction, fn ), NULL ),
 #define EVT_PG_ITEM_COLLAPSED(id, fn)        DECLARE_EVENT_TABLE_ENTRY( wxEVT_PG_ITEM_COLLAPSED, id, -1, wxEVENT_HANDLER_CAST( wxPropertyGridEventFunction, fn ), NULL ),
 #define EVT_PG_ITEM_EXPANDED(id, fn)         DECLARE_EVENT_TABLE_ENTRY( wxEVT_PG_ITEM_EXPANDED, id, -1, wxEVENT_HANDLER_CAST( wxPropertyGridEventFunction, fn ), NULL ),
+#define EVT_PG_LABEL_EDIT_BEGIN(id, fn)      DECLARE_EVENT_TABLE_ENTRY( wxEVT_PG_LABEL_EDIT_BEGIN, id, -1, wxEVENT_HANDLER_CAST( wxPropertyGridEventFunction, fn ), NULL ),
+#define EVT_PG_LABEL_EDIT_ENDING(id, fn)     DECLARE_EVENT_TABLE_ENTRY( wxEVT_PG_LABEL_EDIT_ENDING, id, -1, wxEVENT_HANDLER_CAST( wxPropertyGridEventFunction, fn ), NULL ),
 
 #define wxPropertyGridEventHandler(fn) \
     wxEVENT_HANDLER_CAST( wxPropertyGridEventFunction, fn )
@@ -2043,6 +2138,14 @@ public:
     /** Copyer. */
     virtual wxEvent* Clone() const;
 
+    /**
+        Returns the column index associated with this event.
+    */
+    unsigned int GetColumn() const
+    {
+        return m_column;
+    }
+
     wxPGProperty* GetMainParent() const
     {
         wxASSERT(m_property);
@@ -2114,6 +2217,11 @@ public:
         return m_validationInfo->GetFailureBehavior();
     }
 
+    void SetColumn( unsigned int column )
+    {
+        m_column = column;
+    }
+
     void SetCanVeto( bool canVeto ) { m_canVeto = canVeto; }
     bool WasVetoed() const { return m_wasVetoed; }
 
@@ -2137,6 +2245,8 @@ private:
     wxPropertyGrid*     m_pg;
     wxPGValidationInfo* m_validationInfo;
 
+    unsigned int        m_column;
+
     bool                m_canVeto;
     bool                m_wasVetoed;
 
index a110518c0402ff6e103a4d62ffc8718ad18b9fb2..cb16eb93d9a3a178c8edbb55e5940b993094ba68 100644 (file)
@@ -1287,6 +1287,9 @@ public:
 
     static wxPGEditor* GetEditorByName( const wxString& editorName );
 
+    // NOTE: This function reselects the property and may cause
+    //       excess flicker, so to just call Refresh() on a rect
+    //       of single property, call DrawItem() instead.
     virtual void RefreshProperty( wxPGProperty* p ) = 0;
 
 protected:
index 1f5e00078e3afb2a367e947fabdfff9ea4305c81..3ebebcf9ce7afe622f773087a6f9031f9f4023a5 100644 (file)
@@ -668,6 +668,9 @@ protected:
     /** List of column widths (first column does not include margin). */
     wxArrayInt                  m_colWidths;
 
+    /** List of indices of columns the user can edit by clicking it. */
+    wxArrayInt                  m_editableColumns;
+
     double                      m_fSplitterX;
 
     /** Most recently added category. */
index 82f34fa08facf44a477ab27fec7da0aa8c54023e..fb4c7bb7b843138f17a9e2df1f093dea7b20c49e 100644 (file)
@@ -1028,9 +1028,23 @@ public:
 
     /**
         Returns wxPGCell of given column.
+
+        @remarks const version of this member function returns 'default'
+                 wxPGCell object if the property itself didn't hold
+                 cell data.
     */
     const wxPGCell& GetCell( unsigned int column ) const;
 
+    /**
+        Returns wxPGCell of given column, creating one if necessary.
+    */
+    wxPGCell& GetCell( unsigned int column );
+
+    /**
+        Returns wxPGCell of given column, creating one if necessary.
+    */
+    wxPGCell& GetOrCreateCell( unsigned int column );
+
     /**
         Returns number of child properties.
     */
index 0872e5775d1bf4e75cbf260d99c54fc5591a20d0..bfe94e4bc583140b665fffb5cd61c30912745393 100644 (file)
@@ -359,6 +359,14 @@ typedef int (*wxPGSortCallback)(wxPropertyGrid* propGrid,
     @event{EVT_PG_ITEM_EXPANDED(id, func)}
         Respond to wxEVT_PG_ITEM_EXPANDED event, generated when user expands
         a property or category.
+    @event{EVT_PG_LABEL_EDIT_BEGIN(id, func)}
+        Respond to wxEVT_PG_LABEL_EDIT_BEGIN event, generated when is about to
+        begin editing a property label. You can veto this event to prevent the
+        action.
+    @event{EVT_PG_LABEL_EDIT_ENDING(id, func)}
+        Respond to wxEVT_PG_LABEL_EDIT_ENDING event, generated when is about to
+        end editing of a property label. You can veto this event to prevent the
+        action.
     @endEventTable
 
     @remarks
@@ -430,6 +438,21 @@ public:
     */
     static void AutoGetTranslation( bool enable );
 
+    /**
+        Creates label editor wxTextCtrl for given column, for property
+        that is currently selected. When multiple selection is
+        enabled, this applies to whatever property GetSelection()
+        returns.
+
+        @param colIndex
+            Which column's label to edit. Note that you should not
+            use value 1, which is reserved for property value
+            column.
+
+        @see EndLabelEdit(), MakeColumnEditable()
+    */
+    void BeginLabelEdit( unsigned int column = 0 );
+
     /**
         Changes value of a property, as if from an editor. Use this instead of
         SetPropertyValue() if you need the value to run through validation
@@ -491,6 +514,17 @@ public:
     */
     bool EnableCategories( bool enable );
 
+    /**
+        Destroys label editor wxTextCtrl, if any.
+
+        @param commit
+            Use @true (default) to store edited label text in
+            property cell data.
+
+        @see BeginLabelEdit(), MakeColumnEditable()
+    */
+    void EndLabelEdit( bool commit = true );
+
     /**
         Scrolls and/or expands items to ensure that the given item is visible.
 
@@ -515,6 +549,11 @@ public:
     */
     wxSize FitColumns();
 
+    /**
+        Returns currently active label editor, NULL if none.
+    */
+    wxTextCtrl* GetLabelEditor() const;
+
     /**
         Returns wxWindow that the properties are painted on, and which should be
         used as the parent for editor controls.
@@ -696,6 +735,13 @@ public:
     */
     bool IsFrozen() const;
 
+    /**
+        Makes given column editable by user.
+
+        @see BeginLabelEdit(), EndLabelEdit()
+    */
+    void MakeColumnEditable( unsigned int column );
+
     /**
         It is recommended that you call this function any time your code causes
         wxPropertyGrid's top-level parent to change. wxPropertyGrid's OnIdle()
index 41ab8716ab83c1a9e007674eaab4e3ae7637520f..c148abf8a15551a1b9733af21c7a572ce1f4e835 100644 (file)
@@ -687,7 +687,8 @@ enum
     ID_SELECTSTYLE,
     ID_SAVESTATE,
     ID_RESTORESTATE,
-    ID_RUNMINIMAL
+    ID_RUNMINIMAL,
+    ID_ENABLELABELEDITING
 };
 
 // -----------------------------------------------------------------------
@@ -713,6 +714,12 @@ BEGIN_EVENT_TABLE(FormMain, wxFrame)
     EVT_PG_DOUBLE_CLICK( PGID, FormMain::OnPropertyGridItemDoubleClick )
     // This occurs when propgridmanager's page changes.
     EVT_PG_PAGE_CHANGED( PGID, FormMain::OnPropertyGridPageChange )
+    // This occurs when user starts editing a property label
+    EVT_PG_LABEL_EDIT_BEGIN( PGID,
+        FormMain::OnPropertyGridLabelEditBegin )
+    // This occurs when user stops editing a property label
+    EVT_PG_LABEL_EDIT_ENDING( PGID,
+        FormMain::OnPropertyGridLabelEditEnding )
     // This occurs when property's editor button (if any) is clicked.
     EVT_BUTTON( PGID, FormMain::OnPropertyGridButtonClick )
 
@@ -745,6 +752,7 @@ BEGIN_EVENT_TABLE(FormMain, wxFrame)
     EVT_MENU( ID_SETBGCOLOURRECUR, FormMain::OnSetBackgroundColour )
     EVT_MENU( ID_CLEARMODIF, FormMain::OnClearModifyStatusClick )
     EVT_MENU( ID_FREEZE, FormMain::OnFreezeClick )
+    EVT_MENU( ID_ENABLELABELEDITING, FormMain::OnEnableLabelEditing )
     EVT_MENU( ID_DUMPLIST, FormMain::OnDumpList )
 
     EVT_MENU( ID_COLOURSCHEME1, FormMain::OnColourScheme )
@@ -1018,6 +1026,22 @@ void FormMain::OnPropertyGridPageChange( wxPropertyGridEvent& WXUNUSED(event) )
 
 // -----------------------------------------------------------------------
 
+void FormMain::OnPropertyGridLabelEditBegin( wxPropertyGridEvent& event )
+{
+    wxLogDebug("wxPG_EVT_LABEL_EDIT_BEGIN(%s)",
+               event.GetProperty()->GetLabel().c_str());
+}
+
+// -----------------------------------------------------------------------
+
+void FormMain::OnPropertyGridLabelEditEnding( wxPropertyGridEvent& event )
+{
+    wxLogDebug("wxPG_EVT_LABEL_EDIT_ENDING(%s)",
+               event.GetProperty()->GetLabel().c_str());
+}
+
+// -----------------------------------------------------------------------
+
 void FormMain::OnPropertyGridHighlight( wxPropertyGridEvent& WXUNUSED(event) )
 {
 }
@@ -2219,6 +2243,8 @@ FormMain::FormMain(const wxString& title, const wxPoint& pos, const wxSize& size
 
     menuTry->Append(ID_SELECTSTYLE, wxT("Set Window Style"),
         wxT("Select window style flags used by the grid."));
+    menuTry->Append(ID_ENABLELABELEDITING, "Enable label editing",
+        "This calls wxPropertyGrid::MakeColumnEditable(0)");
     menuTry->AppendSeparator();
     menuTry->AppendRadioItem( ID_COLOURSCHEME1, wxT("Standard Colour Scheme") );
     menuTry->AppendRadioItem( ID_COLOURSCHEME2, wxT("White Colour Scheme") );
@@ -2762,6 +2788,13 @@ void FormMain::OnFreezeClick( wxCommandEvent& event )
 
 // -----------------------------------------------------------------------
 
+void FormMain::OnEnableLabelEditing( wxCommandEvent& WXUNUSED(event) )
+{
+    m_propGrid->MakeColumnEditable(0);
+}
+
+// -----------------------------------------------------------------------
+
 void FormMain::OnAbout(wxCommandEvent& WXUNUSED(event))
 {
     wxString msg;
index 54c5f15ee392a7012f1e5185c09acb7a327f72b2..e3c5dc5b6ad6534bbd03e148be59333d41aab64a 100644 (file)
@@ -184,6 +184,7 @@ public:
     void OnSetBackgroundColour( wxCommandEvent& event );
     void OnClearModifyStatusClick( wxCommandEvent& event );
     void OnFreezeClick( wxCommandEvent& event );
+    void OnEnableLabelEditing( wxCommandEvent& event );
     void OnDumpList( wxCommandEvent& event );
     void OnCatColours( wxCommandEvent& event );
     void OnSetColumns( wxCommandEvent& event );
@@ -230,6 +231,8 @@ public:
     void OnPropertyGridKeyEvent( wxKeyEvent& event );
     void OnPropertyGridItemCollapse( wxPropertyGridEvent& event );
     void OnPropertyGridItemExpand( wxPropertyGridEvent& event );
+    void OnPropertyGridLabelEditBegin( wxPropertyGridEvent& event );
+    void OnPropertyGridLabelEditEnding( wxPropertyGridEvent& event );
 
     void OnAbout( wxCommandEvent& event );
 
index 6109df5f0d7676ec2eecf10011a1e700edb8a85e..940b2f62fe54d3fdeb1ee4d6ce48b57da129ecfc 100644 (file)
@@ -1603,7 +1603,9 @@ void wxPropertyGrid::CorrectEditorWidgetPosY()
 
 // Fixes position of wxTextCtrl-like control (wxSpinCtrl usually
 // fits into that category as well).
-void wxPropertyGrid::FixPosForTextCtrl( wxWindow* ctrl, const wxPoint& offset )
+void wxPropertyGrid::FixPosForTextCtrl( wxWindow* ctrl,
+                                        unsigned int forColumn,
+                                        const wxPoint& offset )
 {
     // Center the control vertically
     wxRect finalPos = ctrl->GetRect();
@@ -1616,7 +1618,10 @@ void wxPropertyGrid::FixPosForTextCtrl( wxWindow* ctrl, const wxPoint& offset )
     finalPos.y += y_adj;
     finalPos.height -= (y_adj+sz_dec);
 
-    const int textCtrlXAdjust = wxPG_TEXTCTRLXADJUST;
+    int textCtrlXAdjust = wxPG_TEXTCTRLXADJUST;
+
+    if ( forColumn != 1 )
+        textCtrlXAdjust -= 3;  // magic number!
 
     finalPos.x += textCtrlXAdjust;
     finalPos.width -= textCtrlXAdjust;
@@ -1634,7 +1639,8 @@ wxWindow* wxPropertyGrid::GenerateEditorTextCtrl( const wxPoint& pos,
                                                   const wxString& value,
                                                   wxWindow* secondary,
                                                   int extraStyle,
-                                                  int maxLen )
+                                                  int maxLen,
+                                                  unsigned int forColumn )
 {
     wxWindowID id = wxPG_SUBID1;
     wxPGProperty* prop = GetSelection();
@@ -1653,7 +1659,11 @@ wxWindow* wxPropertyGrid::GenerateEditorTextCtrl( const wxPoint& pos,
     s.x -= 8;
 #endif
 
-     // Take button into acccount
+    // For label editors, trim the size to allow better splitter grabbing
+    if ( forColumn != 1 )
+        s.x -= 2;
+
+    // Take button into acccount
     if ( secondary )
     {
         s.x -= (secondary->GetSize().x + wxPG_TEXTCTRL_AND_BUTTON_SPACING);
@@ -1681,7 +1691,13 @@ wxWindow* wxPropertyGrid::GenerateEditorTextCtrl( const wxPoint& pos,
 
     // Center the control vertically
     if ( !hasSpecialSize )
-        FixPosForTextCtrl(tc);
+        FixPosForTextCtrl(tc, forColumn);
+
+    if ( forColumn != 1 )
+    {
+        tc->SetBackgroundColour(m_colSelBack);
+        tc->SetForegroundColour(m_colSelFore);
+    }
 
 #ifdef __WXMSW__
     tc->Show();
index afb45d3fa6ecaf05a09583b7f43cf26cc44b9906..325ebc094a7c8d1e9eed66aea7110f64c9acd41b 100644 (file)
@@ -1511,7 +1511,7 @@ const wxPGCell& wxPGProperty::GetCell( unsigned int column ) const
     return pg->GetPropertyDefaultCell();
 }
 
-wxPGCell& wxPGProperty::GetCell( unsigned int column )
+wxPGCell& wxPGProperty::GetOrCreateCell( unsigned int column )
 {
     EnsureCells(column);
     return m_cells[column];
index 4f0fe084554eb9e439ecc0dd49958f168aaf8ffc..695049d66cd865db25a65b63bfa9bf7f8cc721ef 100644 (file)
@@ -428,8 +428,11 @@ void wxPropertyGrid::Init1()
     m_iFlags = 0;
     m_pState = NULL;
     m_wndEditor = m_wndEditor2 = NULL;
-    m_selColumn = -1;
+    m_selColumn = 1;
+    m_colHover = 1;
     m_propHover = NULL;
+    m_labelEditor = NULL;
+    m_labelEditorProperty = NULL;
     m_eventObject = this;
     m_curFocused = NULL;
     m_sortFunction = NULL;
@@ -759,12 +762,10 @@ bool wxPropertyGrid::DoAddToSelection( wxPGProperty* prop, int selFlags )
 
         if ( !(selFlags & wxPG_SEL_DONT_SEND_EVENT) )
         {
-            SendEvent( wxEVT_PG_SELECTED, prop, NULL, selFlags );
+            SendEvent( wxEVT_PG_SELECTED, prop, NULL );
         }
 
-        // For some reason, if we use RefreshProperty(prop) here,
-        // we may go into infinite drawing loop.
-        Refresh();
+        DrawItem(prop);
     }
 
     return true;
@@ -785,7 +786,7 @@ bool wxPropertyGrid::DoRemoveFromSelection( wxPGProperty* prop, int selFlags )
     else
     {
         m_pState->DoRemoveFromSelection(prop);
-        RefreshProperty(prop);
+        DrawItem(prop);
         res = true;
     }
 
@@ -794,7 +795,53 @@ bool wxPropertyGrid::DoRemoveFromSelection( wxPGProperty* prop, int selFlags )
 
 // -----------------------------------------------------------------------
 
+bool wxPropertyGrid::DoSelectAndEdit( wxPGProperty* prop,
+                                      unsigned int colIndex,
+                                      unsigned int selFlags )
+{
+    //
+    // NB: Enable following if label editor background colour is
+    //     ever changed to any other than m_colSelBack.
+    //
+    // We use this workaround to prevent visible flicker when editing
+    // a cell. Atleast on wxMSW, there is a difficult to find
+    // (and perhaps prevent) redraw somewhere between making property
+    // selected and enabling label editing.
+    //
+    //wxColour prevColSelBack = m_colSelBack;
+    //m_colSelBack = wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW );
+
+    bool res;
+
+    if ( colIndex == 1 )
+    {
+        res = DoSelectProperty(prop, selFlags);
+    }
+    else
+    {
+        // send event
+        DoClearSelection(false, wxPG_SEL_NO_REFRESH);
+
+        if ( m_pState->m_editableColumns.Index(colIndex) == wxNOT_FOUND )
+        {
+            res = DoAddToSelection(prop, selFlags);
+        }
+        else
+        {
+            res = DoAddToSelection(prop, selFlags|wxPG_SEL_NO_REFRESH);
+
+            DoBeginLabelEdit(colIndex, selFlags);
+        }
+    }
+
+    //m_colSelBack = prevColSelBack;
+    return res;
+}
+
+// -----------------------------------------------------------------------
+
 bool wxPropertyGrid::AddToSelectionFromInputEvent( wxPGProperty* prop,
+                                                   unsigned int colIndex,
                                                    wxMouseEvent* mouseEvent,
                                                    int selFlags )
 {
@@ -813,7 +860,7 @@ bool wxPropertyGrid::AddToSelectionFromInputEvent( wxPGProperty* prop,
                 // disturbing the selection.
                 if ( GetSelectedProperties().size() <= 1 ||
                      !alreadySelected )
-                    return DoSelectProperty(prop, selFlags);
+                    return DoSelectAndEdit(prop, colIndex, selFlags);
                 return true;
             }
             else
@@ -844,7 +891,7 @@ bool wxPropertyGrid::AddToSelectionFromInputEvent( wxPGProperty* prop,
     }
     else
     {
-        res = DoSelectProperty(prop, selFlags);
+        res = DoSelectAndEdit(prop, colIndex, selFlags);
     }
 
     return res;
@@ -875,6 +922,143 @@ void wxPropertyGrid::DoSetSelection( const wxArrayPGProperty& newSelection,
 
 // -----------------------------------------------------------------------
 
+void wxPropertyGrid::DoBeginLabelEdit( unsigned int colIndex,
+                                       int selFlags )
+{
+    wxPGProperty* selected = GetSelection();
+    wxCHECK_RET(selected, wxT("No property selected"));
+    wxCHECK_RET(colIndex != 1, wxT("Do not use this for column 1"));
+
+    if ( !(selFlags & wxPG_SEL_DONT_SEND_EVENT) )
+    {
+        if ( SendEvent( wxEVT_PG_LABEL_EDIT_BEGIN,
+                        selected, NULL, 0,
+                        colIndex ) )
+            return;
+    }
+
+    wxString text;
+    const wxPGCell* cell = NULL;
+    if ( selected->HasCell(colIndex) )
+    {
+        cell = &selected->GetCell(colIndex);
+        if ( !cell->HasText() && colIndex == 0 )
+            text = selected->GetLabel();
+    }
+
+    if ( !cell  )
+    {
+        if ( colIndex == 0 )
+            text = selected->GetLabel();
+        else
+            cell = &selected->GetOrCreateCell(colIndex);
+    }
+
+    if ( cell && cell->HasText() )
+        text = cell->GetText();
+
+    DoEndLabelEdit(true, wxPG_SEL_NOVALIDATE);  // send event
+
+    m_selColumn = colIndex;
+
+    wxRect r = GetEditorWidgetRect(selected, m_selColumn);
+
+    wxWindow* tc = GenerateEditorTextCtrl(r.GetPosition(),
+                                          r.GetSize(),
+                                          text,
+                                          NULL,
+                                          wxTE_PROCESS_ENTER,
+                                          0,
+                                          colIndex);
+
+    wxWindowID id = tc->GetId();
+    tc->Connect(id, wxEVT_COMMAND_TEXT_ENTER,
+        wxCommandEventHandler(wxPropertyGrid::OnLabelEditorEnterPress),
+        NULL, this);
+    tc->Connect(id, wxEVT_KEY_DOWN,
+        wxKeyEventHandler(wxPropertyGrid::OnLabelEditorKeyPress),
+        NULL, this);
+
+    tc->SetFocus();
+
+    m_labelEditor = wxStaticCast(tc, wxTextCtrl);
+    m_labelEditorProperty = selected;
+}
+
+// -----------------------------------------------------------------------
+
+void
+wxPropertyGrid::OnLabelEditorEnterPress( wxCommandEvent& WXUNUSED(event) )
+{
+    DoEndLabelEdit(true);
+}
+
+// -----------------------------------------------------------------------
+
+void wxPropertyGrid::OnLabelEditorKeyPress( wxKeyEvent& event )
+{
+    int keycode = event.GetKeyCode();
+
+    if ( keycode == WXK_ESCAPE )
+    {
+        DoEndLabelEdit(false);
+    }
+    else
+    {
+        event.Skip();
+    }
+}
+
+// -----------------------------------------------------------------------
+
+void wxPropertyGrid::DoEndLabelEdit( bool commit, int selFlags )
+{
+    if ( !m_labelEditor )
+        return;
+
+    wxPGProperty* prop = m_labelEditorProperty;
+    wxASSERT(prop);
+
+    if ( commit )
+    {
+        if ( !(selFlags & wxPG_SEL_DONT_SEND_EVENT) )
+        {
+            // wxPG_SEL_NOVALIDATE is passed correctly in selFlags
+            if ( SendEvent( wxEVT_PG_LABEL_EDIT_ENDING,
+                            prop, NULL, selFlags,
+                            m_selColumn ) )
+                return;
+        }
+
+        wxString text = m_labelEditor->GetValue();
+        wxPGCell* cell = NULL;
+        if ( prop->HasCell(m_selColumn) )
+        {
+            cell = &prop->GetCell(m_selColumn);
+        }
+        else
+        {
+            if ( m_selColumn == 0 )
+                prop->SetLabel(text);
+            else
+                cell = &prop->GetOrCreateCell(m_selColumn);
+        }
+
+        if ( cell )
+            cell->SetText(text);
+    }
+
+    m_selColumn = 1;
+
+    DestroyEditorWnd(m_labelEditor);
+    m_labelEditor = NULL;
+    m_labelEditorProperty = NULL;
+
+    DrawItem(prop);
+}
+
+// -----------------------------------------------------------------------
+
 void wxPropertyGrid::SetExtraStyle( long exStyle )
 {
     if ( exStyle & wxPG_EX_NATIVE_DOUBLE_BUFFERING )
@@ -2074,28 +2258,36 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc,
             {
                 cellRect.width = nextCellWidth - 1;
 
-                bool ctrlCell = false;
+                wxWindow* cellEditor = NULL;
                 int cellRenderFlags = renderFlags;
 
-                // Tree Item Button
+                // Tree Item Button (must be drawn before clipping is set up)
                 if ( ci == 0 && !HasFlag(wxPG_HIDE_MARGIN) && p->HasVisibleChildren() )
                     DrawExpanderButton( dc, butRect, p );
 
                 // Background
-                if ( isSelected && ci == 1 )
+                if ( isSelected && (ci == 1 || ci == m_selColumn) )
                 {
-                    if ( p == firstSelected && m_wndEditor )
+                    if ( p == firstSelected )
+                    {
+                        if ( ci == 1 && m_wndEditor )
+                            cellEditor = m_wndEditor;
+                        else if ( ci == m_selColumn && m_labelEditor )
+                            cellEditor = m_labelEditor;
+                    }
+
+                    if ( cellEditor )
                     {
                         wxColour editorBgCol =
-                            GetEditorControl()->GetBackgroundColour();
+                            cellEditor->GetBackgroundColour();
                         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;
+                        if ( m_dragStatus != 0 ||
+                             (m_iFlags & wxPG_FL_CUR_USES_CUSTOM_IMAGE) )
+                            cellEditor = NULL;
                     }
                     else
                     {
@@ -2128,7 +2320,7 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc,
                 cellRect.width -= textXAdd;
 
                 // Foreground
-                if ( !ctrlCell )
+                if ( !cellEditor )
                 {
                     wxPGCellRenderer* renderer;
                     int cmnVal = p->GetCommonValue();
@@ -2732,7 +2924,8 @@ bool wxPropertyGrid::PerformValidation( wxPGProperty* p, wxVariant& pendingValue
     if ( flags & SendEvtChanging )
     {
         // SendEvent returns true if event was vetoed
-        if ( SendEvent( wxEVT_PG_CHANGING, evtChangingProperty, &evtChangingValue, 0 ) )
+        if ( SendEvent( wxEVT_PG_CHANGING, evtChangingProperty,
+                        &evtChangingValue ) )
             return false;
     }
 
@@ -2974,12 +3167,12 @@ bool wxPropertyGrid::DoPropertyChanged( wxPGProperty* p, unsigned int selFlags )
 
         while ( pwc != changedProperty )
         {
-            SendEvent( wxEVT_PG_CHANGED, pwc, NULL, selFlags );
+            SendEvent( wxEVT_PG_CHANGED, pwc, NULL );
             pwc = pwc->GetParent();
         }
     }
 
-    SendEvent( wxEVT_PG_CHANGED, changedProperty, NULL, selFlags );
+    SendEvent( wxEVT_PG_CHANGED, changedProperty, NULL );
 
     m_inDoPropertyChanged = 0;
 
@@ -3375,6 +3568,17 @@ void wxPropertyGrid::SetupChildEventHandling( wxWindow* argWnd )
         NULL, this);
 }
 
+void wxPropertyGrid::DestroyEditorWnd( wxWindow* wnd )
+{
+    if ( !wnd )
+        return;
+
+    wnd->Hide();
+
+    // Do not free editors immediately (for sake of processing events)
+    wxPendingDelete.Append(wnd);
+}
+
 void wxPropertyGrid::FreeEditors()
 {
     //
@@ -3402,7 +3606,7 @@ void wxPropertyGrid::FreeEditors()
         wxEvtHandler* handler = m_wndEditor2->PopEventHandler(false);
         m_wndEditor2->Hide();
         wxPendingDelete.Append( handler );
-        wxPendingDelete.Append( m_wndEditor2 );
+        DestroyEditorWnd(m_wndEditor2);
         m_wndEditor2 = NULL;
     }
 
@@ -3411,7 +3615,7 @@ void wxPropertyGrid::FreeEditors()
         wxEvtHandler* handler = m_wndEditor->PopEventHandler(false);
         m_wndEditor->Hide();
         wxPendingDelete.Append( handler );
-        wxPendingDelete.Append( m_wndEditor );
+        DestroyEditorWnd(m_wndEditor);
         m_wndEditor = NULL;
     }
 }
@@ -3453,6 +3657,9 @@ bool wxPropertyGrid::DoSelectProperty( wxPGProperty* p, unsigned int flags )
     if ( prevFirstSel && prevFirstSel->HasFlag(wxPG_PROP_BEING_DELETED) )
         prevFirstSel = NULL;
 
+    // Always send event, as this is indirect call
+    DoEndLabelEdit(true, wxPG_SEL_NOVALIDATE);
+
 /*
     if ( prevFirstSel )
         wxPrintf( "Selected %s\n", prevFirstSel->GetClassInfo()->GetClassName() );
@@ -3470,7 +3677,6 @@ bool wxPropertyGrid::DoSelectProperty( wxPGProperty* p, unsigned int flags )
     {
         m_iFlags &= ~(wxPG_FL_ABNORMAL_EDITOR);
         m_editorFocused = 0;
-        m_selColumn = 1;
         m_pState->DoSetSelection(p);
 
         // If frozen, always free controls. But don't worry, as Thaw will
@@ -3528,10 +3734,6 @@ bool wxPropertyGrid::DoSelectProperty( wxPGProperty* p, unsigned int flags )
             }
 
             FreeEditors();
-            m_selColumn = -1;
-
-            // We need to always fully refresh the grid here
-            Refresh(false);
 
             m_iFlags &= ~(wxPG_FL_ABNORMAL_EDITOR);
             EditorsValueWasNotModified();
@@ -3541,6 +3743,12 @@ bool wxPropertyGrid::DoSelectProperty( wxPGProperty* p, unsigned int flags )
 
         m_pState->DoSetSelection(p);
 
+        // Redraw unselected
+        for ( unsigned int i=0; i<prevSelection.size(); i++ )
+        {
+            DrawItem(prevSelection[i]);
+        }
+
         //
         // Then, activate the one given.
         if ( p )
@@ -3731,7 +3939,8 @@ bool wxPropertyGrid::DoSelectProperty( wxPGProperty* p, unsigned int flags )
                 m_wndEditor->Show(true);
             }
 
-            DrawItems(p, p);
+            if ( !(flags & wxPG_SEL_NO_REFRESH) )
+                DrawItem(p);
         }
         else
         {
@@ -3791,7 +4000,7 @@ bool wxPropertyGrid::DoSelectProperty( wxPGProperty* p, unsigned int flags )
 
     // call wx event handler (here so that it also occurs on deselection)
     if ( !(flags & wxPG_SEL_DONT_SEND_EVENT) )
-        SendEvent( wxEVT_PG_SELECTED, p, NULL, flags );
+        SendEvent( wxEVT_PG_SELECTED, p, NULL );
 
     return true;
 }
@@ -4137,19 +4346,28 @@ void wxPropertyGrid::SetFocusOnCanvas()
 
 // selFlags uses same values DoSelectProperty's flags
 // Returns true if event was vetoed.
-bool wxPropertyGrid::SendEvent( int eventType, wxPGProperty* p, wxVariant* pValue, unsigned int WXUNUSED(selFlags) )
+bool wxPropertyGrid::SendEvent( int eventType, wxPGProperty* p,
+                                wxVariant* pValue,
+                                unsigned int selFlags,
+                                unsigned int column )
 {
     // Send property grid event of specific type and with specific property
     wxPropertyGridEvent evt( eventType, m_eventObject->GetId() );
     evt.SetPropertyGrid(this);
     evt.SetEventObject(m_eventObject);
     evt.SetProperty(p);
+    evt.SetColumn(column);
     if ( pValue )
     {
         evt.SetCanVeto(true);
         evt.SetupValidationInfo();
         m_validationInfo.m_pValue = pValue;
     }
+    else if ( !(selFlags & wxPG_SEL_NOVALIDATE) )
+    {
+        evt.SetCanVeto(true);
+    }
+
     wxEvtHandler* evtHandler = m_eventObject->GetEventHandler();
 
     evtHandler->ProcessEvent(evt);
@@ -4202,7 +4420,9 @@ bool wxPropertyGrid::HandleMouseClick( int x, unsigned int y, wxMouseEvent &even
                      )
                     )
                 {
-                    if ( !AddToSelectionFromInputEvent( p, &event ) )
+                    if ( !AddToSelectionFromInputEvent( p,
+                                                        columnHit,
+                                                        &event ) )
                         return res;
 
                     // On double-click, expand/collapse.
@@ -4222,7 +4442,10 @@ bool wxPropertyGrid::HandleMouseClick( int x, unsigned int y, wxMouseEvent &even
                     m_iFlags |= wxPG_FL_ACTIVATION_BY_CLICK;
                     selFlag = wxPG_SEL_FOCUS;
                 }
-                if ( !AddToSelectionFromInputEvent( p, &event, selFlag ) )
+                if ( !AddToSelectionFromInputEvent( p,
+                                                    columnHit,
+                                                    &event,
+                                                    selFlag ) )
                     return res;
 
                 m_iFlags &= ~(wxPG_FL_ACTIVATION_BY_CLICK);
@@ -4250,9 +4473,13 @@ bool wxPropertyGrid::HandleMouseClick( int x, unsigned int y, wxMouseEvent &even
                     }
                     else if ( m_dragStatus == 0 )
                     {
-                    //
-                    // Begin draggin the splitter
-                    //
+                        //
+                        // Begin draggin the splitter
+                        //
+
+                        // send event
+                        DoEndLabelEdit(true, wxPG_SEL_NOVALIDATE);
+
                         if ( m_wndEditor )
                         {
                             // Changes must be committed here or the
@@ -4321,7 +4548,7 @@ bool wxPropertyGrid::HandleMouseRightClick( int WXUNUSED(x),
     {
         // Select property here as well
         wxPGProperty* p = m_propHover;
-        AddToSelectionFromInputEvent(p, &event);
+        AddToSelectionFromInputEvent(p, m_colHover, &event);
 
         // Send right click event.
         SendEvent( wxEVT_PG_RIGHT_CLICK, p );
@@ -4342,7 +4569,7 @@ bool wxPropertyGrid::HandleMouseDoubleClick( int WXUNUSED(x),
         // Select property here as well
         wxPGProperty* p = m_propHover;
 
-        AddToSelectionFromInputEvent(p, &event);
+        AddToSelectionFromInputEvent(p, m_colHover, &event);
 
         // Send double-click event.
         SendEvent( wxEVT_PG_DOUBLE_CLICK, m_propHover );
@@ -4392,6 +4619,8 @@ bool wxPropertyGrid::HandleMouseMove( int x, unsigned int y, wxMouseEvent &event
     int columnHit = state->HitTestH( x, &splitterHit, &splitterHitOffset );
     int splitterX = x - splitterHitOffset;
 
+    m_colHover = columnHit;
+
     if ( m_dragStatus > 0 )
     {
         if ( x > (m_marginWidth + wxPG_DRAG_MARGIN) &&
@@ -5523,13 +5752,15 @@ 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 );
-
+wxDEFINE_EVENT( wxEVT_PG_LABEL_EDIT_BEGIN, wxPropertyGridEvent );
+wxDEFINE_EVENT( wxEVT_PG_LABEL_EDIT_ENDING, wxPropertyGridEvent );
 
 // -----------------------------------------------------------------------
 
 void wxPropertyGridEvent::Init()
 {
     m_validationInfo = NULL;
+    m_column = 1;
     m_canVeto = false;
     m_wasVetoed = false;
 }
index c0e9b5e46ea945c844ee4d0a7f34c0786475ace8..88e51c6db28ce11fede7770ed3c1346844c9050d 100644 (file)
@@ -216,7 +216,9 @@ wxPGProperty* wxPropertyGridInterface::GetSelection() const
 
 bool wxPropertyGridInterface::ClearSelection( bool validation )
 {
-    return DoClearSelection(validation, wxPG_SEL_DONT_SEND_EVENT);
+    bool res = DoClearSelection(validation, wxPG_SEL_DONT_SEND_EVENT);
+    GetPropertyGrid()->Refresh();
+    return res;
 }
 
 // -----------------------------------------------------------------------
index 9cb00a145a7b80bbf89c35a354a52ff71c1e8c2a..39765a7ee7cc66184f7839720f6532560a54c7a2 100644 (file)
@@ -215,6 +215,9 @@ wxPropertyGridPageState::wxPropertyGridPageState()
     m_colWidths.push_back( wxPG_DEFAULT_SPLITTERX );
     m_colWidths.push_back( wxPG_DEFAULT_SPLITTERX );
     m_fSplitterX = wxPG_DEFAULT_SPLITTERX;
+
+    // By default, we only have the 'value' column editable
+    m_editableColumns.push_back(1);
 }
 
 // -----------------------------------------------------------------------