diff options
author | Lars Uebernickel <lars@uebernic.de> | 2013-11-02 14:22:33 +0100 |
---|---|---|
committer | Lars Uebernickel <lars@uebernic.de> | 2013-11-02 20:14:22 +0100 |
commit | f6a0debdd9d4f90b9d6b54c263b10926ba530c7e (patch) | |
tree | 58cb26a4b73b392e629800b5cc15eb66e3c0f7bd /gtk/gtkentrycompletion.c | |
parent | 88e2c0ee69c34b6ff5da9949946f6b7ec3b07494 (diff) | |
download | gtk+-f6a0debdd9d4f90b9d6b54c263b10926ba530c7e.tar.gz |
gtk_entry_completion_set_text_column: reuse old renderer
gtk_entry_completion_set_text_column() always added a cell renderer,
regardless of whether there was an existing one already installed. This
patch reuses an old renderer if it exists, but only if it was added by a
previous call to this function.
To avoid conflicts, all renderers that were added manually are removed
when calling this function. Also, the renderer added by this function is
removed when manually adding new renderers. This effectively gives
GtkEntryCompletion two modes (managed and manual cell renderers) and
allows seamless switching between the two.
This is a minor API break. However, this shouldn't be an issue in
practice as applications couldn't call set_text_column() more than once
because of this bug. Also, it is unlikely that many applications mix
set_text_column() and custom cell renderers. The interaction between the
two modes was erratic and not documented well.
https://bugzilla.gnome.org/show_bug.cgi?id=635499
Diffstat (limited to 'gtk/gtkentrycompletion.c')
-rw-r--r-- | gtk/gtkentrycompletion.c | 128 |
1 files changed, 116 insertions, 12 deletions
diff --git a/gtk/gtkentrycompletion.c b/gtk/gtkentrycompletion.c index 0d77663970..61a3249aec 100644 --- a/gtk/gtkentrycompletion.c +++ b/gtk/gtkentrycompletion.c @@ -117,6 +117,14 @@ enum static void gtk_entry_completion_cell_layout_init (GtkCellLayoutIface *iface); +static GList * gtk_entry_completion_get_cells (GtkCellLayout *cell_layout); +static void gtk_entry_completion_clear (GtkCellLayout *cell_layout); +static void gtk_entry_completion_pack_start (GtkCellLayout *cell_layout, + GtkCellRenderer *cell, + gboolean expand); +static void gtk_entry_completion_pack_end (GtkCellLayout *cell_layout, + GtkCellRenderer *cell, + gboolean expand); static GtkCellArea* gtk_entry_completion_get_area (GtkCellLayout *cell_layout); static GObject *gtk_entry_completion_constructor (GType type, @@ -478,6 +486,10 @@ gtk_entry_completion_buildable_init (GtkBuildableIface *iface) static void gtk_entry_completion_cell_layout_init (GtkCellLayoutIface *iface) { + iface->get_cells = gtk_entry_completion_get_cells; + iface->clear = gtk_entry_completion_clear; + iface->pack_start = gtk_entry_completion_pack_start; + iface->pack_end = gtk_entry_completion_pack_end; iface->get_area = gtk_entry_completion_get_area; } @@ -814,7 +826,73 @@ gtk_entry_completion_dispose (GObject *object) G_OBJECT_CLASS (gtk_entry_completion_parent_class)->dispose (object); } -/* implement cell layout interface (only need to return the underlying cell area) */ +static void +gtk_entry_completion_clear_text_column_renderer (GtkEntryCompletion *completion) +{ + if (completion->priv->text_column != -1) + { + gtk_cell_layout_clear (GTK_CELL_LAYOUT (completion)); + completion->priv->text_column = -1; + g_object_notify (G_OBJECT (completion), "text_column"); + } +} + +static GList * +gtk_entry_completion_get_cells (GtkCellLayout *cell_layout) +{ + GtkEntryCompletion *completion = GTK_ENTRY_COMPLETION (cell_layout); + + if (completion->priv->text_column == -1) + { + GtkCellArea *area; + + area = gtk_entry_completion_get_area (cell_layout); + return gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (area)); + } + else + { + /* Don't expose the internally created cell renderer */ + return NULL; + } +} + +static void +gtk_entry_completion_clear (GtkCellLayout *cell_layout) +{ + GtkCellArea *area; + + gtk_entry_completion_clear_text_column_renderer (GTK_ENTRY_COMPLETION (cell_layout)); + + area = gtk_entry_completion_get_area (cell_layout); + gtk_cell_layout_clear (GTK_CELL_LAYOUT (area)); +} + +static void +gtk_entry_completion_pack_start (GtkCellLayout *cell_layout, + GtkCellRenderer *cell, + gboolean expand) +{ + GtkCellArea *area; + + gtk_entry_completion_clear_text_column_renderer (GTK_ENTRY_COMPLETION (cell_layout)); + + area = gtk_entry_completion_get_area (cell_layout); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (area), cell, expand); +} + +static void +gtk_entry_completion_pack_end (GtkCellLayout *cell_layout, + GtkCellRenderer *cell, + gboolean expand) +{ + GtkCellArea *area; + + gtk_entry_completion_clear_text_column_renderer (GTK_ENTRY_COMPLETION (cell_layout)); + + area = gtk_entry_completion_get_area (cell_layout); + gtk_cell_layout_pack_end (GTK_CELL_LAYOUT (area), cell, expand); +} + static GtkCellArea* gtk_entry_completion_get_area (GtkCellLayout *cell_layout) { @@ -1393,10 +1471,12 @@ gtk_entry_completion_delete_action (GtkEntryCompletion *completion, * to have a list displaying all (and just) strings in the completion list, * and to get those strings from @column in the model of @completion. * - * This functions creates and adds a #GtkCellRendererText for the selected - * column. If you need to set the text column, but don't want the cell - * renderer, use g_object_set() to set the #GtkEntryCompletion:text-column - * property directly. + * Any cell renderers that were added to @completion before calling this + * function will be removed. + * + * Conversely, the cell renderer created by this function will be + * removed when new renderers are added to @completion with + * gtk_cell_layout_pack_start() or gtk_cell_layout_pack_end(). * * Since: 2.4 */ @@ -1409,15 +1489,39 @@ gtk_entry_completion_set_text_column (GtkEntryCompletion *completion, g_return_if_fail (GTK_IS_ENTRY_COMPLETION (completion)); g_return_if_fail (column >= 0); - completion->priv->text_column = column; + /* clear manually set cell renderers */ + if (completion->priv->text_column == -1) + gtk_cell_layout_clear (GTK_CELL_LAYOUT (completion)); - cell = gtk_cell_renderer_text_new (); - gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (completion), - cell, TRUE); - gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (completion), - cell, - "text", column); + if (completion->priv->text_column >= 0) + { + GtkCellArea *area; + GList *cells; + + /* Call get_cells() on the internal area instead of on completion, + * because completion returns NULL for when the renderer is + * internal (i.e., was added by this function). + */ + area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (completion)); + cells = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (area)); + g_assert (cells); + + cell = cells->data; + + g_list_free (cells); + } + else + { + cell = gtk_cell_renderer_text_new (); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (completion), + cell, TRUE); + } + + gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (completion), cell, + "text", column, + NULL); + completion->priv->text_column = column; g_object_notify (G_OBJECT (completion), "text-column"); } |