]> git.saurik.com Git - wxWidgets.git/commitdiff
Implement icon text column using native GTK renderers in wxDVC.
authorVadim Zeitlin <vadim@wxwidgets.org>
Fri, 16 Oct 2009 01:29:06 +0000 (01:29 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Fri, 16 Oct 2009 01:29:06 +0000 (01:29 +0000)
This has a possible advantage of a more native look and feel (although it's
hard to tell the difference between drawing the icon ourselves and how the
default GTK+ renderer does it to be honest) and a very real advantage of
allowing to edit in place cells with icons. It also reduces code duplication
in GTK implementation.

Modify the sample to make the icon-text column in the list model editable to
show that it works. This required storing the values of the second column as
well, so do it in its own array and to avoid calling it "m_array2", rename the
existing m_array to m_textColValues (which accounts for most of the diff in
the sample) and call the new one m_iconColValues.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@62423 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/gtk/dataview.h
samples/dataview/dataview.cpp
samples/dataview/mymodels.cpp
samples/dataview/mymodels.h
src/gtk/dataview.cpp

index ee1bdb3ccbfb0251b62c87048119b978a65a2f42..d217d2f88eb9a375b637e5775eb9aad1ca2498d6 100644 (file)
@@ -19,6 +19,7 @@
 class WXDLLIMPEXP_FWD_ADV wxDataViewCtrl;
 class WXDLLIMPEXP_FWD_ADV wxDataViewCtrlInternal;
 
+typedef struct _GtkTreeViewColumn      GtkTreeViewColumn;
 
 // ---------------------------------------------------------
 // wxDataViewRenderer
@@ -37,7 +38,22 @@ public:
     virtual void SetAlignment( int align );
     virtual int GetAlignment() const;
 
-    // implementation
+
+    // GTK-specific implementation
+    // ---------------------------
+
+    // pack the GTK cell renderers used by this renderer to the given column
+    //
+    // by default only a single m_renderer is used but some renderers use more
+    // than one GTK cell renderer
+    virtual void GtkPackIntoColumn(GtkTreeViewColumn *column);
+
+    // called when the cell value was edited by user with the new value
+    //
+    // it validates the new value and notifies the model about the change by
+    // calling GtkOnCellChanged() if it was accepted
+    void GtkOnTextEdited(const gchar *itempath, const wxString& value);
+
     GtkCellRenderer* GetGtkHandle() { return m_renderer; }
     void GtkInitHandlers();
     void GtkUpdateAlignment();
@@ -46,6 +62,11 @@ public:
     void GtkSetUsingDefaultAttrs(bool def) { m_usingDefaultAttrs = def; }
 
 protected:
+    virtual void GtkOnCellChanged(const wxVariant& value,
+                                  const wxDataViewItem& item,
+                                  unsigned col);
+
+
     GtkCellRenderer   *m_renderer;
     int                m_alignment;
 
@@ -68,12 +89,30 @@ public:
                             wxDataViewCellMode mode = wxDATAVIEW_CELL_INERT,
                             int align = wxDVR_DEFAULT_ALIGNMENT );
 
-    bool SetValue( const wxVariant &value );
-    bool GetValue( wxVariant &value ) const;
+    virtual bool SetValue( const wxVariant &value )
+    {
+        return SetTextValue(value);
+    }
 
-    void SetAlignment( int align );
+    virtual bool GetValue( wxVariant &value ) const
+    {
+        wxString str;
+        if ( !GetTextValue(str) )
+            return false;
+
+        value = str;
+
+        return true;
+    }
+
+    virtual void SetAlignment( int align );
 
 protected:
+    // implementation of Set/GetValue()
+    bool SetTextValue(const wxString& str);
+    bool GetTextValue(wxString& str) const;
+
+
     DECLARE_DYNAMIC_CLASS_NO_COPY(wxDataViewTextRenderer)
 };
 
@@ -156,7 +195,7 @@ private:
     wxDC        *m_dc;
 
 public:
-    // Internal, temporay for RenderText.
+    // Internal, temporary for RenderText.
     GtkCellRenderer      *m_text_renderer;
     GdkWindow            *window;
     GtkWidget            *widget;
@@ -200,7 +239,7 @@ protected:
 // wxDataViewIconTextRenderer
 // ---------------------------------------------------------
 
-class WXDLLIMPEXP_ADV wxDataViewIconTextRenderer: public wxDataViewCustomRenderer
+class WXDLLIMPEXP_ADV wxDataViewIconTextRenderer: public wxDataViewTextRenderer
 {
 public:
     wxDataViewIconTextRenderer( const wxString &varianttype = wxT("wxDataViewIconText"),
@@ -211,17 +250,19 @@ public:
     bool SetValue( const wxVariant &value );
     bool GetValue( wxVariant &value ) const;
 
-    virtual bool Render( wxRect cell, wxDC *dc, int state );
-    virtual wxSize GetSize() const;
+    virtual void GtkPackIntoColumn(GtkTreeViewColumn *column);
 
-    virtual bool HasEditorCtrl() const { return true; }
-    virtual wxControl* CreateEditorCtrl( wxWindow *parent, wxRect labelRect, const wxVariant &value );
-    virtual bool GetValueFromEditorCtrl( wxControl* editor, wxVariant &value );
+protected:
+    virtual void GtkOnCellChanged(const wxVariant& value,
+                                  const wxDataViewItem& item,
+                                  unsigned col);
 
 private:
     wxDataViewIconText   m_value;
 
-protected:
+    // we use the base class m_renderer for the text and this one for the icon
+    GtkCellRenderer *m_rendererIcon;
+
     DECLARE_DYNAMIC_CLASS_NO_COPY(wxDataViewIconTextRenderer)
 };
 
index 101be7269d14187e737ea350e8d8207283f0eeaa..7e65b9b9a665aa495b204ca7ddd9dff533598f02 100644 (file)
@@ -545,13 +545,8 @@ void MyFrame::BuildDataViewCtrl(wxPanel* parent, unsigned int nPanel, unsigned l
             m_ctrl[1]->AssociateModel( m_list_model.get() );
 
             // the various columns
-#if 1
-            m_ctrl[1]->AppendTextColumn("editable string", 0, wxDATAVIEW_CELL_EDITABLE, 120);
-            m_ctrl[1]->AppendIconTextColumn(wxIcon(wx_small_xpm), 1, wxDATAVIEW_CELL_INERT )->SetTitle( "icon");
-#else
             m_ctrl[1]->AppendTextColumn("editable string", 0, wxDATAVIEW_CELL_EDITABLE);
-            m_ctrl[1]->AppendIconTextColumn("icon", 1, wxDATAVIEW_CELL_INERT);
-#endif
+            m_ctrl[1]->AppendIconTextColumn("icon", 1, wxDATAVIEW_CELL_EDITABLE);
             m_ctrl[1]->AppendColumn(
                 new wxDataViewColumn("attributes", new wxDataViewTextRenderer, 2 ));
         }
index d8854606d34ebb3a0933223e2a20ac939c37d8fd..4be852d6ff22811e4ee2f6231a5d5d02c9ed965d 100644 (file)
@@ -334,31 +334,34 @@ MyListModel::MyListModel() :
     m_virtualItems = INITIAL_NUMBER_OF_ITEMS;
 
     // the first 100 items are really stored in this model;
-    // all the others are synthetized on request
-    for (unsigned int i = 0; i < 100; i++)
+    // all the others are synthesized on request
+    static const unsigned NUMBER_REAL_ITEMS = 100;
+
+    m_textColValues.reserve(NUMBER_REAL_ITEMS);
+    for (unsigned int i = 0; i < NUMBER_REAL_ITEMS; i++)
     {
-        wxString str;
-        str.Printf( "real row %d", i );
-        m_array.Add( str );
+        m_textColValues.push_back(wxString::Format("real row %d", i));
     }
 
+    m_iconColValues.assign(NUMBER_REAL_ITEMS, "test");
+
     m_icon[0] = wxIcon( null_xpm );
     m_icon[1] = wxIcon( wx_small_xpm );
 }
 
 void MyListModel::Prepend( const wxString &text )
 {
-    m_array.Insert( text, 0 );
+    m_textColValues.Insert( text, 0 );
     RowPrepended();
 }
 
 void MyListModel::DeleteItem( const wxDataViewItem &item )
 {
     unsigned int row = GetRow( item );
-    if (row >= m_array.GetCount())
+    if (row >= m_textColValues.GetCount())
         return;
 
-    m_array.RemoveAt( row );
+    m_textColValues.RemoveAt( row );
     RowDeleted( row );
 }
 
@@ -369,7 +372,7 @@ void MyListModel::DeleteItems( const wxDataViewItemArray &items )
     for (i = 0; i < items.GetCount(); i++)
     {
         unsigned int row = GetRow( items[i] );
-        if (row < m_array.GetCount())
+        if (row < m_textColValues.GetCount())
             rows.Add( row );
     }
 
@@ -377,7 +380,7 @@ void MyListModel::DeleteItems( const wxDataViewItemArray &items )
     {
         // none of the selected items were in the range of the items
         // which we store... for simplicity, don't allow removing them
-        wxLogError( "Cannot remove rows with an index greater than %d", m_array.GetCount() );
+        wxLogError( "Cannot remove rows with an index greater than %d", m_textColValues.GetCount() );
         return;
     }
 
@@ -386,7 +389,7 @@ void MyListModel::DeleteItems( const wxDataViewItemArray &items )
     // remaining indeces would all be wrong.
     rows.Sort( my_sort_reverse );
     for (i = 0; i < rows.GetCount(); i++)
-        m_array.RemoveAt( rows[i] );
+        m_textColValues.RemoveAt( rows[i] );
 
     // This is just to test if wxDataViewCtrl can
     // cope with removing rows not sorted in
@@ -398,7 +401,7 @@ void MyListModel::DeleteItems( const wxDataViewItemArray &items )
 void MyListModel::AddMany()
 {
     m_virtualItems += 1000;
-    Reset( m_array.GetCount() + m_virtualItems );
+    Reset( m_textColValues.GetCount() + m_virtualItems );
 }
 
 void MyListModel::GetValueByRow( wxVariant &variant,
@@ -406,15 +409,20 @@ void MyListModel::GetValueByRow( wxVariant &variant,
 {
     if (col==0)
     {
-        if (row >= m_array.GetCount())
+        if (row >= m_textColValues.GetCount())
             variant = wxString::Format( "virtual row %d", row );
         else
-            variant = m_array[ row ];
+            variant = m_textColValues[ row ];
     }
     else if (col==1)
     {
-        wxDataViewIconText data( "test", m_icon[ row%2 ] );
-        variant << data;
+        wxString text;
+        if ( row >= m_iconColValues.GetCount() )
+            text = "virtual icon";
+        else
+            text = m_iconColValues[row];
+
+        variant << wxDataViewIconText(text, m_icon[row % 2]);
     }
     else if (col==2)
     {
@@ -474,19 +482,35 @@ bool MyListModel::GetAttrByRow( unsigned int row, unsigned int col,
 bool MyListModel::SetValueByRow( const wxVariant &variant,
                                  unsigned int row, unsigned int col )
 {
-    if (col == 0)
+    switch ( col )
     {
-        if (row >= m_array.GetCount())
-        {
-            // the item is not in the range of the items
-            // which we store... for simplicity, don't allow editing it
-            wxLogError( "Cannot edit rows with an index greater than %d", m_array.GetCount() );
-            return false;
-        }
+        case 0:
+        case 1:
+            if (row >= m_textColValues.GetCount())
+            {
+                // the item is not in the range of the items
+                // which we store... for simplicity, don't allow editing it
+                wxLogError( "Cannot edit rows with an index greater than %d",
+                            m_textColValues.GetCount() );
+                return false;
+            }
 
-        m_array[row] = variant.GetString();
-        return true;
+            if ( col == 0 )
+            {
+                m_textColValues[row] = variant.GetString();
+            }
+            else // col == 1
+            {
+                wxDataViewIconText iconText;
+                iconText << variant;
+                m_iconColValues[row] = iconText.GetText();
+            }
+            break;
+
+        default:
+            wxLogError("Cannot edit the column %d", col);
+            return false;
     }
 
-    return false;
+    return true;
 }
index ba4397c1f19aa865c8df6e6e3744a0862d1d79ea..a078c59150674b825740cb7ce2ddcb76aaa2488a 100644 (file)
@@ -215,7 +215,7 @@ public:
 
     virtual unsigned int GetRowCount()
     {
-        return m_array.GetCount();
+        return m_textColValues.GetCount();
     }
 
     virtual void GetValueByRow( wxVariant &variant,
@@ -225,7 +225,8 @@ public:
                                 unsigned int row, unsigned int col );
 
 private:
-    wxArrayString    m_array;
+    wxArrayString    m_textColValues;
+    wxArrayString    m_iconColValues;
     wxIcon           m_icon[2];
     int              m_virtualItems;
 };
index 064708d6d3a9c4086e22f55561bc09e83ec566c6..d951f74ea9e052b458f91831364d844f01d06c3b 100644 (file)
@@ -1560,6 +1560,11 @@ wxDataViewRenderer::wxDataViewRenderer( const wxString &varianttype, wxDataViewC
     //       after the m_renderer pointer has been initialized
 }
 
+void wxDataViewRenderer::GtkPackIntoColumn(GtkTreeViewColumn *column)
+{
+    gtk_tree_view_column_pack_end( column, m_renderer, TRUE /* expand */);
+}
+
 void wxDataViewRenderer::GtkInitHandlers()
 {
     if (!gtk_check_version(2,6,0))
@@ -1686,37 +1691,48 @@ int wxDataViewRenderer::GetAlignment() const
     return m_alignment;
 }
 
+void
+wxDataViewRenderer::GtkOnTextEdited(const gchar *itempath, const wxString& str)
+{
+    wxVariant value(str);
+    if (!Validate( value ))
+        return;
+
+    GtkTreePath *path = gtk_tree_path_new_from_string( itempath );
+    GtkTreeIter iter;
+    GetOwner()->GetOwner()->GtkGetInternal()->get_iter( &iter, path );
+    wxDataViewItem item( (void*) iter.user_data );;
+    gtk_tree_path_free( path );
+
+    GtkOnCellChanged(value, item, GetOwner()->GetModelColumn());
+}
+
+void
+wxDataViewRenderer::GtkOnCellChanged(const wxVariant& value,
+                                     const wxDataViewItem& item,
+                                     unsigned col)
+{
+    wxDataViewModel *model = GetOwner()->GetOwner()->GetModel();
+    model->SetValue( value, item, col );
+    model->ValueChanged( item, col );
+}
+
 // ---------------------------------------------------------
 // wxDataViewTextRenderer
 // ---------------------------------------------------------
 
-extern "C" {
-static void wxGtkTextRendererEditedCallback( GtkCellRendererText *renderer,
-    gchar *arg1, gchar *arg2, gpointer user_data );
-}
+extern "C"
+{
 
 static void wxGtkTextRendererEditedCallback( GtkCellRendererText *WXUNUSED(renderer),
     gchar *arg1, gchar *arg2, gpointer user_data )
 {
     wxDataViewRenderer *cell = (wxDataViewRenderer*) user_data;
 
-    wxString tmp = wxGTK_CONV_BACK_FONT(arg2, cell->GetOwner()->GetOwner()->GetFont());
-    wxVariant value = tmp;
-    if (!cell->Validate( value ))
-        return;
-
-    wxDataViewModel *model = cell->GetOwner()->GetOwner()->GetModel();
-
-    GtkTreePath *path = gtk_tree_path_new_from_string( arg1 );
-    GtkTreeIter iter;
-    cell->GetOwner()->GetOwner()->GtkGetInternal()->get_iter( &iter, path );
-    wxDataViewItem item( (void*) iter.user_data );;
-    gtk_tree_path_free( path );
-
-    unsigned int model_col = cell->GetOwner()->GetModelColumn();
+    cell->GtkOnTextEdited(arg1, wxGTK_CONV_BACK_FONT(
+                arg2, cell->GetOwner()->GetOwner()->GetFont()));
+}
 
-    model->SetValue( value, item, model_col );
-    model->ValueChanged( item, model_col );
 }
 
 IMPLEMENT_CLASS(wxDataViewTextRenderer, wxDataViewRenderer)
@@ -1746,29 +1762,25 @@ wxDataViewTextRenderer::wxDataViewTextRenderer( const wxString &varianttype, wxD
     SetAlignment(align);
 }
 
-bool wxDataViewTextRenderer::SetValue( const wxVariant &value )
+bool wxDataViewTextRenderer::SetTextValue(const wxString& str)
 {
-    wxString tmp = value;
-
     GValue gvalue = { 0, };
     g_value_init( &gvalue, G_TYPE_STRING );
-    g_value_set_string( &gvalue, wxGTK_CONV_FONT( tmp, GetOwner()->GetOwner()->GetFont() ) );
+    g_value_set_string( &gvalue, wxGTK_CONV_FONT( str, GetOwner()->GetOwner()->GetFont() ) );
     g_object_set_property( G_OBJECT(m_renderer), "text", &gvalue );
     g_value_unset( &gvalue );
 
     return true;
 }
 
-bool wxDataViewTextRenderer::GetValue( wxVariant &value ) const
+bool wxDataViewTextRenderer::GetTextValue(wxString& str) const
 {
     GValue gvalue = { 0, };
     g_value_init( &gvalue, G_TYPE_STRING );
     g_object_get_property( G_OBJECT(m_renderer), "text", &gvalue );
-    wxString tmp = wxGTK_CONV_BACK_FONT( g_value_get_string( &gvalue ), const_cast<wxDataViewTextRenderer*>(this)->GetOwner()->GetOwner()->GetFont() );
+    str = wxGTK_CONV_BACK_FONT( g_value_get_string( &gvalue ), const_cast<wxDataViewTextRenderer*>(this)->GetOwner()->GetOwner()->GetFont() );
     g_value_unset( &gvalue );
 
-    value = tmp;
-
     return true;
 }
 
@@ -1797,13 +1809,28 @@ void wxDataViewTextRenderer::SetAlignment( int align )
 // wxDataViewBitmapRenderer
 // ---------------------------------------------------------
 
+namespace
+{
+
+// set "pixbuf" property on the given renderer
+void SetPixbufProp(GtkCellRenderer *renderer, GdkPixbuf *pixbuf)
+{
+    GValue gvalue = { 0, };
+    g_value_init( &gvalue, G_TYPE_OBJECT );
+    g_value_set_object( &gvalue, pixbuf );
+    g_object_set_property( G_OBJECT(renderer), "pixbuf", &gvalue );
+    g_value_unset( &gvalue );
+}
+
+} // anonymous namespace
+
 IMPLEMENT_CLASS(wxDataViewBitmapRenderer, wxDataViewRenderer)
 
 wxDataViewBitmapRenderer::wxDataViewBitmapRenderer( const wxString &varianttype, wxDataViewCellMode mode,
                                                     int align ) :
     wxDataViewRenderer( varianttype, mode, align )
 {
-    m_renderer = (GtkCellRenderer*) gtk_cell_renderer_pixbuf_new();
+    m_renderer = gtk_cell_renderer_pixbuf_new();
 
     SetMode(mode);
     SetAlignment(align);
@@ -1816,38 +1843,23 @@ bool wxDataViewBitmapRenderer::SetValue( const wxVariant &value )
         wxBitmap bitmap;
         bitmap << value;
 
-        // This may create a Pixbuf representation in the
-        // wxBitmap object (and it will stay there)
-        GdkPixbuf *pixbuf = bitmap.GetPixbuf();
-
-        GValue gvalue = { 0, };
-        g_value_init( &gvalue, G_TYPE_OBJECT );
-        g_value_set_object( &gvalue, pixbuf );
-        g_object_set_property( G_OBJECT(m_renderer), "pixbuf", &gvalue );
-        g_value_unset( &gvalue );
-
-        return true;
+        // GetPixbuf() may create a Pixbuf representation in the wxBitmap
+        // object (and it will stay there and remain owned by wxBitmap)
+        SetPixbufProp(m_renderer, bitmap.GetPixbuf());
     }
-
-    if (value.GetType() == wxT("wxIcon"))
+    else if (value.GetType() == wxT("wxIcon"))
     {
-        wxIcon bitmap;
-        bitmap << value;
+        wxIcon icon;
+        icon << value;
 
-        // This may create a Pixbuf representation in the
-        // wxBitmap object (and it will stay there)
-        GdkPixbuf *pixbuf = bitmap.GetPixbuf();
-
-        GValue gvalue = { 0, };
-        g_value_init( &gvalue, G_TYPE_OBJECT );
-        g_value_set_object( &gvalue, pixbuf );
-        g_object_set_property( G_OBJECT(m_renderer), "pixbuf", &gvalue );
-        g_value_unset( &gvalue );
-
-        return true;
+        SetPixbufProp(m_renderer, icon.GetPixbuf());
+    }
+    else
+    {
+        return false;
     }
 
-    return false;
+    return true;
 }
 
 bool wxDataViewBitmapRenderer::GetValue( wxVariant &WXUNUSED(value) ) const
@@ -2399,67 +2411,63 @@ bool wxDataViewDateRenderer::Activate( wxRect WXUNUSED(cell), wxDataViewModel *m
 
 IMPLEMENT_CLASS(wxDataViewIconTextRenderer, wxDataViewCustomRenderer)
 
-wxDataViewIconTextRenderer::wxDataViewIconTextRenderer(
-  const wxString &varianttype, wxDataViewCellMode mode, int align ) :
-    wxDataViewCustomRenderer( varianttype, mode, align )
+wxDataViewIconTextRenderer::wxDataViewIconTextRenderer
+                            (
+                             const wxString &varianttype,
+                             wxDataViewCellMode mode,
+                             int align
+                            )
+    : wxDataViewTextRenderer(varianttype, mode, align)
 {
-    SetMode(mode);
-    SetAlignment(align);
+    m_rendererIcon = gtk_cell_renderer_pixbuf_new();
 }
 
 wxDataViewIconTextRenderer::~wxDataViewIconTextRenderer()
 {
 }
 
-bool wxDataViewIconTextRenderer::SetValue( const wxVariant &value )
+void wxDataViewIconTextRenderer::GtkPackIntoColumn(GtkTreeViewColumn *column)
 {
-    m_value << value;
-    return true;
-}
+    // add the icon renderer first
+    gtk_tree_view_column_pack_start(column, m_rendererIcon, FALSE /* !expand */);
 
-bool wxDataViewIconTextRenderer::GetValue( wxVariant &WXUNUSED(value) ) const
-{
-    return false;
+    // add the text renderer too
+    wxDataViewRenderer::GtkPackIntoColumn(column);
 }
 
-bool wxDataViewIconTextRenderer::Render( wxRect cell, wxDC *dc, int state )
+bool wxDataViewIconTextRenderer::SetValue( const wxVariant &value )
 {
-    const wxIcon &icon = m_value.GetIcon();
-    int offset = 0;
-    if (icon.IsOk())
-    {
-        int yoffset = wxMax( 0, (cell.height - icon.GetHeight()) / 2 );
-        dc->DrawIcon( icon, cell.x, cell.y + yoffset );
-        offset = icon.GetWidth() + 4;
-    }
+    m_value << value;
 
-    RenderText( m_value.GetText(), offset, cell, dc, state );
+    SetTextValue(m_value.GetText());
+    SetPixbufProp(m_rendererIcon, m_value.GetIcon().GetPixbuf());
 
     return true;
 }
 
-wxSize wxDataViewIconTextRenderer::GetSize() const
+bool wxDataViewIconTextRenderer::GetValue(wxVariant& value) const
 {
-    wxSize size;
-    if (m_value.GetIcon().IsOk())
-        size.x = 4 + m_value.GetIcon().GetWidth();
-    wxCoord x,y,d;
-    GetView()->GetTextExtent( m_value.GetText(), &x, &y, &d );
-    size.x += x;
-    size.y = y+d;
-    return size;
-}
+    wxString str;
+    if ( !GetTextValue(str) )
+        return false;
 
-wxControl* wxDataViewIconTextRenderer::CreateEditorCtrl(
-    wxWindow *WXUNUSED(parent), wxRect WXUNUSED(labelRect), const wxVariant &WXUNUSED(value) )
-{
-    return NULL;
+    // user doesn't have any way to edit the icon so leave it unchanged
+    value << wxDataViewIconText(str, m_value.GetIcon());
+
+    return true;
 }
 
-bool wxDataViewIconTextRenderer::GetValueFromEditorCtrl(
-   wxControl* WXUNUSED(editor), wxVariant &WXUNUSED(value) )
+void
+wxDataViewIconTextRenderer::GtkOnCellChanged(const wxVariant& value,
+                                             const wxDataViewItem& item,
+                                             unsigned col)
 {
-    return false;
+    // we receive just the text part of our value as it's the only one which
+    // can be edited, but we need the full wxDataViewIconText value for the
+    // model
+    wxVariant valueIconText;
+    valueIconText << wxDataViewIconText(value.GetString(), m_value.GetIcon());
+    wxDataViewTextRenderer::GtkOnCellChanged(valueIconText, item, col);
 }
 
 // ---------------------------------------------------------
@@ -2679,7 +2687,6 @@ void wxDataViewColumn::Init(wxAlignment align, int flags, int width)
 {
     m_isConnected = false;
 
-    GtkCellRenderer *renderer = (GtkCellRenderer *) GetRenderer()->GetGtkHandle();
     GtkTreeViewColumn *column = gtk_tree_view_column_new();
     m_column = (GtkWidget*) column;
 
@@ -2698,10 +2705,13 @@ void wxDataViewColumn::Init(wxAlignment align, int flags, int width)
     gtk_box_pack_end( GTK_BOX(box), GTK_WIDGET(m_label), FALSE, FALSE, 1 );
     gtk_tree_view_column_set_widget( column, box );
 
-    gtk_tree_view_column_pack_end( column, renderer, TRUE );
+    wxDataViewRenderer * const colRenderer = GetRenderer();
+    GtkCellRenderer * const cellRenderer = colRenderer->GetGtkHandle();
+
+    colRenderer->GtkPackIntoColumn(column);
 
-    gtk_tree_view_column_set_cell_data_func( column, renderer,
-        wxGtkTreeCellDataFunc, (gpointer) GetRenderer(), NULL );
+    gtk_tree_view_column_set_cell_data_func( column, cellRenderer,
+        wxGtkTreeCellDataFunc, (gpointer) colRenderer, NULL );
 }
 
 void wxDataViewColumn::OnInternalIdle()