mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-10 02:40:11 +00:00
Landing GtkTreeModelFilter and the completion code. (Test program and
Fri Jul 11 14:32:43 2003 Kristian Rietveld <kris@gtk.org> Landing GtkTreeModelFilter and the completion code. (Test program and documentation will follow next week). * gtk/gtkcellayout.[ch], gtk/gtkentrycompletion.[ch], gtk/gtktreemodelfilter.[ch], gtk/gtkentryprivate.h: new files. * gtkentry.[ch]: added gtk_entry_{get,set}_completion, wrote necessary code to hook up completion. * gtktreeviewcolumn.c: made GtkTreeViewColumn implement the new GtkCellLayout interface. * gtkmarshalers.list: added BOOLEAN:OBJECT,BOXED. * gtk/gtk.h, gtk/Makefile.am, po/POTFILES.in: all updated for the new source files.
This commit is contained in:
parent
8aafd6bb16
commit
edef7d00d9
@ -102,6 +102,7 @@ gtk_public_h_sources = \
|
||||
gtkbutton.h \
|
||||
gtkcalendar.h \
|
||||
gtkcelleditable.h \
|
||||
gtkcelllayout.h \
|
||||
gtkcellrenderer.h \
|
||||
gtkcellrendererpixbuf.h \
|
||||
gtkcellrenderertext.h \
|
||||
@ -124,6 +125,7 @@ gtk_public_h_sources = \
|
||||
gtkdrawingarea.h \
|
||||
gtkeditable.h \
|
||||
gtkentry.h \
|
||||
gtkentrycompletion.h \
|
||||
gtkenums.h \
|
||||
gtkeventbox.h \
|
||||
gtkexpander.h \
|
||||
@ -221,6 +223,7 @@ gtk_public_h_sources = \
|
||||
gtktreednd.h \
|
||||
gtktreeitem.h \
|
||||
gtktreemodel.h \
|
||||
gtktreemodelfilter.h \
|
||||
gtktreemodelsort.h \
|
||||
gtktreeselection.h \
|
||||
gtktreesortable.h \
|
||||
@ -241,6 +244,7 @@ gtk_public_h_sources = \
|
||||
|
||||
# GTK+ header files that don't get installed
|
||||
gtk_private_h_sources = \
|
||||
gtkentryprivate.h \
|
||||
gtkrbtree.h \
|
||||
gtktextbtree.h \
|
||||
gtktextchildprivate.h \
|
||||
@ -277,6 +281,7 @@ gtk_c_sources = \
|
||||
gtkbox.c \
|
||||
gtkbutton.c \
|
||||
gtkcalendar.c \
|
||||
gtkcelllayout.c \
|
||||
gtkcellrenderer.c \
|
||||
gtkcelleditable.c \
|
||||
gtkcellrenderertext.c \
|
||||
@ -299,6 +304,7 @@ gtk_c_sources = \
|
||||
gtkdrawingarea.c \
|
||||
gtkeditable.c \
|
||||
gtkentry.c \
|
||||
gtkentrycompletion.c \
|
||||
gtkeventbox.c \
|
||||
gtkexpander.c \
|
||||
gtkfilesel.c \
|
||||
@ -403,6 +409,7 @@ gtk_c_sources = \
|
||||
gtktreedatalist.c \
|
||||
gtktreednd.c \
|
||||
gtktreemodel.c \
|
||||
gtktreemodelfilter.c \
|
||||
gtktreemodelsort.c \
|
||||
gtktreeselection.c \
|
||||
gtktreesortable.c \
|
||||
|
@ -43,6 +43,7 @@
|
||||
#include <gtk/gtkbox.h>
|
||||
#include <gtk/gtkbutton.h>
|
||||
#include <gtk/gtkcalendar.h>
|
||||
#include <gtk/gtkcelllayout.h>
|
||||
#include <gtk/gtkcellrenderer.h>
|
||||
#include <gtk/gtkcellrendererpixbuf.h>
|
||||
#include <gtk/gtkcellrenderertext.h>
|
||||
@ -63,6 +64,7 @@
|
||||
#include <gtk/gtkdrawingarea.h>
|
||||
#include <gtk/gtkeditable.h>
|
||||
#include <gtk/gtkentry.h>
|
||||
#include <gtk/gtkentrycompletion.h>
|
||||
#include <gtk/gtkenums.h>
|
||||
#include <gtk/gtkeventbox.h>
|
||||
#include <gtk/gtkexpander.h>
|
||||
@ -152,6 +154,7 @@
|
||||
#include <gtk/gtktreednd.h>
|
||||
#include <gtk/gtktreeitem.h>
|
||||
#include <gtk/gtktreemodel.h>
|
||||
#include <gtk/gtktreemodelfilter.h>
|
||||
#include <gtk/gtktreemodelsort.h>
|
||||
#include <gtk/gtktreeselection.h>
|
||||
#include <gtk/gtktreestore.h>
|
||||
|
168
gtk/gtkcelllayout.c
Normal file
168
gtk/gtkcelllayout.c
Normal file
@ -0,0 +1,168 @@
|
||||
/* gtkcelllayout.c
|
||||
* Copyright (C) 2003 Kristian Rietveld <kris@gtk.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "gtkcelllayout.h"
|
||||
|
||||
GType
|
||||
gtk_cell_layout_get_type (void)
|
||||
{
|
||||
static GType cell_layout_type = 0;
|
||||
|
||||
if (! cell_layout_type)
|
||||
{
|
||||
static const GTypeInfo cell_layout_info =
|
||||
{
|
||||
sizeof (GtkCellLayoutIface),
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
NULL
|
||||
};
|
||||
|
||||
cell_layout_type =
|
||||
g_type_register_static (G_TYPE_INTERFACE, "GtkCellLayout",
|
||||
&cell_layout_info, 0);
|
||||
|
||||
g_type_interface_add_prerequisite (cell_layout_type, G_TYPE_OBJECT);
|
||||
}
|
||||
|
||||
return cell_layout_type;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
gtk_cell_layout_pack_start (GtkCellLayout *cell_layout,
|
||||
GtkCellRenderer *cell,
|
||||
gboolean expand)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_CELL_LAYOUT (cell_layout));
|
||||
g_return_if_fail (GTK_IS_CELL_RENDERER (cell));
|
||||
|
||||
(* GTK_CELL_LAYOUT_GET_IFACE (cell_layout)->pack_start) (cell_layout,
|
||||
cell,
|
||||
expand);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_cell_layout_pack_end (GtkCellLayout *cell_layout,
|
||||
GtkCellRenderer *cell,
|
||||
gboolean expand)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_CELL_LAYOUT (cell_layout));
|
||||
g_return_if_fail (GTK_IS_CELL_RENDERER (cell));
|
||||
|
||||
(* GTK_CELL_LAYOUT_GET_IFACE (cell_layout)->pack_end) (cell_layout,
|
||||
cell,
|
||||
expand);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_cell_layout_clear (GtkCellLayout *cell_layout)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_CELL_LAYOUT (cell_layout));
|
||||
|
||||
(* GTK_CELL_LAYOUT_GET_IFACE (cell_layout)->clear) (cell_layout);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_cell_layout_set_attributesv (GtkCellLayout *cell_layout,
|
||||
GtkCellRenderer *cell,
|
||||
va_list args)
|
||||
{
|
||||
gchar *attribute;
|
||||
gint column;
|
||||
GtkCellLayoutIface *iface;
|
||||
|
||||
attribute = va_arg (args, gchar *);
|
||||
|
||||
iface = GTK_CELL_LAYOUT_GET_IFACE (cell_layout);
|
||||
|
||||
(* iface->clear_attributes) (cell_layout, cell);
|
||||
|
||||
while (attribute != NULL)
|
||||
{
|
||||
column = va_arg (args, gint);
|
||||
(* iface->add_attribute) (cell_layout, cell, attribute, column);
|
||||
attribute = va_arg (args, gchar *);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gtk_cell_layout_set_attributes (GtkCellLayout *cell_layout,
|
||||
GtkCellRenderer *cell,
|
||||
...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
g_return_if_fail (GTK_IS_CELL_LAYOUT (cell_layout));
|
||||
g_return_if_fail (GTK_IS_CELL_RENDERER (cell));
|
||||
|
||||
va_start (args, cell);
|
||||
gtk_cell_layout_set_attributesv (cell_layout, cell, args);
|
||||
va_end (args);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_cell_layout_add_attribute (GtkCellLayout *cell_layout,
|
||||
GtkCellRenderer *cell,
|
||||
const gchar *attribute,
|
||||
gint column)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_CELL_LAYOUT (cell_layout));
|
||||
g_return_if_fail (GTK_IS_CELL_RENDERER (cell));
|
||||
g_return_if_fail (attribute != NULL);
|
||||
g_return_if_fail (column >= 0);
|
||||
|
||||
(* GTK_CELL_LAYOUT_GET_IFACE (cell_layout)->add_attribute) (cell_layout,
|
||||
cell,
|
||||
attribute,
|
||||
column);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_cell_layout_set_cell_data_func (GtkCellLayout *cell_layout,
|
||||
GtkCellRenderer *cell,
|
||||
GtkCellLayoutDataFunc func,
|
||||
gpointer func_data,
|
||||
GDestroyNotify destroy)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_CELL_LAYOUT (cell_layout));
|
||||
g_return_if_fail (GTK_IS_CELL_RENDERER (cell));
|
||||
|
||||
(* GTK_CELL_LAYOUT_GET_IFACE (cell_layout)->set_cell_data_func) (cell_layout,
|
||||
cell,
|
||||
func,
|
||||
func_data,
|
||||
destroy);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_cell_layout_clear_attributes (GtkCellLayout *cell_layout,
|
||||
GtkCellRenderer *cell)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_CELL_LAYOUT (cell_layout));
|
||||
g_return_if_fail (GTK_IS_CELL_RENDERER (cell));
|
||||
|
||||
(* GTK_CELL_LAYOUT_GET_IFACE (cell_layout)->clear_attributes) (cell_layout,
|
||||
cell);
|
||||
}
|
96
gtk/gtkcelllayout.h
Normal file
96
gtk/gtkcelllayout.h
Normal file
@ -0,0 +1,96 @@
|
||||
/* gtkcelllayout.h
|
||||
* Copyright (C) 2003 Kristian Rietveld <kris@gtk.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GTK_CELL_LAYOUT_H__
|
||||
#define __GTK_CELL_LAYOUT_H__
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include <gtk/gtkcellrenderer.h>
|
||||
#include <gtk/gtktreeviewcolumn.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_CELL_LAYOUT (gtk_cell_layout_get_type ())
|
||||
#define GTK_CELL_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_CELL_LAYOUT, GtkCellLayout))
|
||||
#define GTK_IS_CELL_LAYOUT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_CELL_LAYOUT))
|
||||
#define GTK_CELL_LAYOUT_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GTK_TYPE_CELL_LAYOUT, GtkCellLayoutIface))
|
||||
|
||||
typedef struct _GtkCellLayout GtkCellLayout; /* dummy typedef */
|
||||
typedef struct _GtkCellLayoutIface GtkCellLayoutIface;
|
||||
|
||||
/* keep in sync with GtkTreeCellDataFunc */
|
||||
typedef void (* GtkCellLayoutDataFunc) (GtkCellLayout *cell_layout,
|
||||
GtkCellRenderer *cell,
|
||||
GtkTreeModel *tree_model,
|
||||
GtkTreeIter *iter,
|
||||
gpointer data);
|
||||
|
||||
struct _GtkCellLayoutIface
|
||||
{
|
||||
GTypeInterface g_iface;
|
||||
|
||||
/* Virtual Table */
|
||||
void (* pack_start) (GtkCellLayout *cell_layout,
|
||||
GtkCellRenderer *cell,
|
||||
gboolean expand);
|
||||
void (* pack_end) (GtkCellLayout *cell_layout,
|
||||
GtkCellRenderer *cell,
|
||||
gboolean expand);
|
||||
void (* clear) (GtkCellLayout *cell_layout);
|
||||
void (* add_attribute) (GtkCellLayout *cell_layout,
|
||||
GtkCellRenderer *cell,
|
||||
const gchar *attribute,
|
||||
gint column);
|
||||
void (* set_cell_data_func) (GtkCellLayout *cell_layout,
|
||||
GtkCellRenderer *cell,
|
||||
GtkCellLayoutDataFunc func,
|
||||
gpointer func_data,
|
||||
GDestroyNotify destroy);
|
||||
void (* clear_attributes) (GtkCellLayout *cell_layout,
|
||||
GtkCellRenderer *cell);
|
||||
};
|
||||
|
||||
GType gtk_cell_layout_get_type (void);
|
||||
void gtk_cell_layout_pack_start (GtkCellLayout *cell_layout,
|
||||
GtkCellRenderer *cell,
|
||||
gboolean expand);
|
||||
void gtk_cell_layout_pack_end (GtkCellLayout *cell_layout,
|
||||
GtkCellRenderer *cell,
|
||||
gboolean expand);
|
||||
void gtk_cell_layout_clear (GtkCellLayout *cell_layout);
|
||||
void gtk_cell_layout_set_attributes (GtkCellLayout *cell_layout,
|
||||
GtkCellRenderer *cell,
|
||||
...);
|
||||
void gtk_cell_layout_add_attribute (GtkCellLayout *cell_layout,
|
||||
GtkCellRenderer *cell,
|
||||
const gchar *attribute,
|
||||
gint column);
|
||||
void gtk_cell_layout_set_cell_data_func (GtkCellLayout *cell_layout,
|
||||
GtkCellRenderer *cell,
|
||||
GtkCellLayoutDataFunc func,
|
||||
gpointer func_data,
|
||||
GDestroyNotify destroy);
|
||||
void gtk_cell_layout_clear_attributes (GtkCellLayout *cell_layout,
|
||||
GtkCellRenderer *cell);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_CELL_LAYOUT_H__ */
|
256
gtk/gtkentry.c
256
gtk/gtkentry.c
@ -47,10 +47,17 @@
|
||||
#include "gtkstock.h"
|
||||
#include "gtktextutil.h"
|
||||
#include "gtkwindow.h"
|
||||
#include "gtktreeview.h"
|
||||
#include "gtktreeselection.h"
|
||||
#include "gtkentryprivate.h"
|
||||
#include "gtkcelllayout.h"
|
||||
|
||||
#define GTK_ENTRY_COMPLETION_KEY "gtk-entry-completion-key"
|
||||
|
||||
#define MIN_ENTRY_WIDTH 150
|
||||
#define DRAW_TIMEOUT 20
|
||||
#define INNER_BORDER 2
|
||||
#define COMPLETION_TIMEOUT 300
|
||||
|
||||
/* Initial size of buffer, in bytes */
|
||||
#define MIN_SIZE 16
|
||||
@ -936,6 +943,8 @@ gtk_entry_finalize (GObject *object)
|
||||
{
|
||||
GtkEntry *entry = GTK_ENTRY (object);
|
||||
|
||||
gtk_entry_set_completion (entry, NULL);
|
||||
|
||||
if (entry->cached_layout)
|
||||
g_object_unref (entry->cached_layout);
|
||||
|
||||
@ -1664,6 +1673,7 @@ gtk_entry_focus_out (GtkWidget *widget,
|
||||
GdkEventFocus *event)
|
||||
{
|
||||
GtkEntry *entry = GTK_ENTRY (widget);
|
||||
GtkEntryCompletion *completion;
|
||||
|
||||
gtk_widget_queue_draw (widget);
|
||||
|
||||
@ -1675,6 +1685,10 @@ gtk_entry_focus_out (GtkWidget *widget,
|
||||
g_signal_handlers_disconnect_by_func (gdk_keymap_get_for_display (gtk_widget_get_display (widget)),
|
||||
gtk_entry_keymap_direction_changed,
|
||||
entry);
|
||||
|
||||
completion = gtk_entry_get_completion (entry);
|
||||
if (completion)
|
||||
_gtk_entry_completion_popdown (completion);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
@ -4451,3 +4465,245 @@ gtk_entry_pend_cursor_blink (GtkEntry *entry)
|
||||
show_cursor (entry);
|
||||
}
|
||||
}
|
||||
|
||||
/* completion */
|
||||
static gint
|
||||
gtk_entry_completion_timeout (gpointer data)
|
||||
{
|
||||
GtkEntryCompletion *completion = GTK_ENTRY_COMPLETION (data);
|
||||
|
||||
GDK_THREADS_ENTER ();
|
||||
|
||||
completion->priv->completion_timeout = 0;
|
||||
|
||||
if (strlen (gtk_entry_get_text (GTK_ENTRY (completion->priv->entry))) >= completion->priv->minimum_key_length)
|
||||
{
|
||||
gint matches;
|
||||
gint actions;
|
||||
GtkTreeSelection *s;
|
||||
|
||||
gtk_entry_completion_complete (completion);
|
||||
matches = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (completion->priv->filter_model), NULL);
|
||||
|
||||
gtk_tree_selection_unselect_all (gtk_tree_view_get_selection (GTK_TREE_VIEW (completion->priv->tree_view)));
|
||||
|
||||
s = gtk_tree_view_get_selection (GTK_TREE_VIEW (completion->priv->action_view));
|
||||
|
||||
gtk_tree_selection_unselect_all (s);
|
||||
|
||||
actions = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (completion->priv->actions), NULL);
|
||||
|
||||
if (matches > 0 || actions > 0)
|
||||
_gtk_entry_completion_popup (completion);
|
||||
}
|
||||
|
||||
GDK_THREADS_LEAVE ();
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_entry_completion_key_press (GtkWidget *widget,
|
||||
GdkEventKey *event,
|
||||
gpointer user_data)
|
||||
{
|
||||
gint matches, actions = 0;
|
||||
GtkEntryCompletion *completion = GTK_ENTRY_COMPLETION (user_data);
|
||||
|
||||
if (!GTK_WIDGET_MAPPED (completion->priv->popup_window))
|
||||
return FALSE;
|
||||
|
||||
matches = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (completion->priv->filter_model), NULL);
|
||||
|
||||
if (completion->priv->actions)
|
||||
actions = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (completion->priv->actions), NULL);
|
||||
|
||||
if (event->keyval == GDK_Up || event->keyval == GDK_Down)
|
||||
{
|
||||
GtkTreePath *path = NULL;
|
||||
|
||||
if (event->keyval == GDK_Up)
|
||||
{
|
||||
completion->priv->current_selected--;
|
||||
if (completion->priv->current_selected < 0)
|
||||
completion->priv->current_selected = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
completion->priv->current_selected++;
|
||||
if (completion->priv->current_selected >= matches + actions)
|
||||
completion->priv->current_selected = 0;
|
||||
}
|
||||
|
||||
if (completion->priv->current_selected < matches)
|
||||
{
|
||||
gtk_tree_selection_unselect_all (gtk_tree_view_get_selection (GTK_TREE_VIEW (completion->priv->action_view)));
|
||||
|
||||
path = gtk_tree_path_new_from_indices (completion->priv->current_selected, -1);
|
||||
gtk_tree_view_set_cursor (GTK_TREE_VIEW (completion->priv->tree_view),
|
||||
path, NULL, FALSE);
|
||||
}
|
||||
else if (completion->priv->current_selected - matches >= 0)
|
||||
{
|
||||
gtk_tree_selection_unselect_all (gtk_tree_view_get_selection (GTK_TREE_VIEW (completion->priv->tree_view)));
|
||||
|
||||
path = gtk_tree_path_new_from_indices (completion->priv->current_selected - matches, -1);
|
||||
gtk_tree_view_set_cursor (GTK_TREE_VIEW (completion->priv->action_view),
|
||||
path, NULL, FALSE);
|
||||
}
|
||||
|
||||
gtk_tree_path_free (path);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else if (event->keyval == GDK_ISO_Enter ||
|
||||
event->keyval == GDK_Return ||
|
||||
event->keyval == GDK_Escape)
|
||||
{
|
||||
_gtk_entry_completion_popdown (completion);
|
||||
|
||||
if (event->keyval == GDK_Escape)
|
||||
return TRUE;
|
||||
|
||||
if (completion->priv->current_selected < matches)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
GtkTreeModel *model = NULL;
|
||||
GtkTreeSelection *sel;
|
||||
gboolean entry_set;
|
||||
|
||||
sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (completion->priv->tree_view));
|
||||
gtk_tree_selection_get_selected (sel, &model, &iter);
|
||||
|
||||
g_signal_emit_by_name (completion, "match_selected",
|
||||
model, &iter, &entry_set);
|
||||
|
||||
if (!entry_set)
|
||||
{
|
||||
gchar *str = NULL;
|
||||
|
||||
gtk_tree_model_get (model, &iter,
|
||||
completion->priv->text_column, &str,
|
||||
-1);
|
||||
|
||||
g_signal_handler_block (widget, completion->priv->changed_id);
|
||||
gtk_entry_set_text (GTK_ENTRY (widget), str);
|
||||
g_signal_handler_unblock (widget, completion->priv->changed_id);
|
||||
|
||||
/* move the cursor to the end */
|
||||
gtk_editable_set_position (GTK_EDITABLE (widget), -1);
|
||||
|
||||
g_free (str);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else if (completion->priv->current_selected - matches >= 0)
|
||||
{
|
||||
GtkTreePath *path;
|
||||
|
||||
path = gtk_tree_path_new_from_indices (completion->priv->current_selected - matches, -1);
|
||||
|
||||
g_signal_emit_by_name (completion, "action_activated",
|
||||
gtk_tree_path_get_indices (path)[0]);
|
||||
gtk_tree_path_free (path);
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_entry_completion_changed (GtkWidget *entry,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkEntryCompletion *completion = GTK_ENTRY_COMPLETION (user_data);
|
||||
|
||||
if (GTK_WIDGET_MAPPED (completion->priv->popup_window))
|
||||
_gtk_entry_completion_popdown (completion);
|
||||
|
||||
/* (re)install completion timeout */
|
||||
if (completion->priv->completion_timeout)
|
||||
g_source_remove (completion->priv->completion_timeout);
|
||||
|
||||
if (!gtk_entry_get_text (GTK_ENTRY (entry)))
|
||||
return;
|
||||
|
||||
/* no need to normalize for this test */
|
||||
if (! strcmp ("", gtk_entry_get_text (GTK_ENTRY (entry))))
|
||||
return;
|
||||
|
||||
completion->priv->completion_timeout =
|
||||
g_timeout_add (COMPLETION_TIMEOUT,
|
||||
gtk_entry_completion_timeout,
|
||||
completion);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_entry_set_completion (GtkEntry *entry,
|
||||
GtkEntryCompletion *completion)
|
||||
{
|
||||
GtkEntryCompletion *old;
|
||||
|
||||
g_return_if_fail (GTK_IS_ENTRY (entry));
|
||||
g_return_if_fail (!completion || GTK_IS_ENTRY_COMPLETION (completion));
|
||||
|
||||
old = gtk_entry_get_completion (entry);
|
||||
|
||||
if (old)
|
||||
{
|
||||
if (old->priv->completion_timeout)
|
||||
{
|
||||
g_source_remove (old->priv->completion_timeout);
|
||||
old->priv->completion_timeout = 0;
|
||||
}
|
||||
|
||||
if (GTK_WIDGET_MAPPED (old->priv->popup_window))
|
||||
_gtk_entry_completion_popdown (old);
|
||||
|
||||
gtk_cell_layout_clear (GTK_CELL_LAYOUT (old));
|
||||
old->priv->text_column = -1;
|
||||
|
||||
if (g_signal_handler_is_connected (entry, old->priv->changed_id))
|
||||
g_signal_handler_disconnect (entry, old->priv->changed_id);
|
||||
if (g_signal_handler_is_connected (entry, old->priv->key_press_id))
|
||||
g_signal_handler_disconnect (entry, old->priv->key_press_id);
|
||||
|
||||
old->priv->entry = NULL;
|
||||
|
||||
g_object_unref (old);
|
||||
}
|
||||
|
||||
if (!completion)
|
||||
{
|
||||
g_object_set_data (G_OBJECT (entry), GTK_ENTRY_COMPLETION_KEY, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
/* hook into the entry */
|
||||
g_object_ref (completion);
|
||||
|
||||
completion->priv->changed_id =
|
||||
g_signal_connect (entry, "changed",
|
||||
G_CALLBACK (gtk_entry_completion_changed), completion);
|
||||
|
||||
completion->priv->key_press_id =
|
||||
g_signal_connect (entry, "key_press_event",
|
||||
G_CALLBACK (gtk_entry_completion_key_press), completion);
|
||||
|
||||
completion->priv->entry = GTK_WIDGET (entry);
|
||||
g_object_set_data (G_OBJECT (entry), GTK_ENTRY_COMPLETION_KEY, completion);
|
||||
}
|
||||
|
||||
GtkEntryCompletion *
|
||||
gtk_entry_get_completion (GtkEntry *entry)
|
||||
{
|
||||
GtkEntryCompletion *completion;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_ENTRY (entry), NULL);
|
||||
|
||||
completion = GTK_ENTRY_COMPLETION (g_object_get_data (G_OBJECT (entry),
|
||||
GTK_ENTRY_COMPLETION_KEY));
|
||||
|
||||
return completion;
|
||||
}
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include <gtk/gtkeditable.h>
|
||||
#include <gtk/gtkimcontext.h>
|
||||
#include <gtk/gtkmenu.h>
|
||||
#include <gtk/gtkentrycompletion.h>
|
||||
#include <pango/pango.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -182,6 +183,10 @@ void gtk_entry_get_layout_offsets (GtkEntry *entry,
|
||||
gint *x,
|
||||
gint *y);
|
||||
|
||||
void gtk_entry_set_completion (GtkEntry *entry,
|
||||
GtkEntryCompletion *completion);
|
||||
GtkEntryCompletion *gtk_entry_get_completion (GtkEntry *entry);
|
||||
|
||||
/* Deprecated compatibility functions
|
||||
*/
|
||||
|
||||
|
956
gtk/gtkentrycompletion.c
Normal file
956
gtk/gtkentrycompletion.c
Normal file
@ -0,0 +1,956 @@
|
||||
/* gtkentrycompletion.c
|
||||
* Copyright (C) 2003 Kristian Rietveld <kris@gtk.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "gtkentrycompletion.h"
|
||||
#include "gtkentryprivate.h"
|
||||
#include "gtkcelllayout.h"
|
||||
|
||||
#include <gtk/gtkintl.h>
|
||||
#include <gtk/gtkcellrenderertext.h>
|
||||
#include <gtk/gtktreeselection.h>
|
||||
#include <gtk/gtktreeview.h>
|
||||
#include <gtk/gtkscrolledwindow.h>
|
||||
#include <gtk/gtkvbox.h>
|
||||
#include <gtk/gtkwindow.h>
|
||||
#include <gtk/gtkentry.h>
|
||||
#include <gtk/gtkmain.h>
|
||||
#include <gtk/gtksignal.h>
|
||||
#include <gtk/gtkmarshalers.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
||||
/* signals */
|
||||
enum
|
||||
{
|
||||
MATCH_SELECTED,
|
||||
ACTION_ACTIVATED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
/* properties */
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_MODEL,
|
||||
PROP_MINIMUM_KEY_LENGTH
|
||||
};
|
||||
|
||||
|
||||
static void gtk_entry_completion_class_init (GtkEntryCompletionClass *klass);
|
||||
static void gtk_entry_completion_cell_layout_init (GtkCellLayoutIface *iface);
|
||||
static void gtk_entry_completion_init (GtkEntryCompletion *completion);
|
||||
static void gtk_entry_completion_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static void gtk_entry_completion_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static void gtk_entry_completion_finalize (GObject *object);
|
||||
|
||||
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 void gtk_entry_completion_clear (GtkCellLayout *cell_layout);
|
||||
static void gtk_entry_completion_add_attribute (GtkCellLayout *cell_layout,
|
||||
GtkCellRenderer *cell,
|
||||
const char *attribute,
|
||||
gint column);
|
||||
static void gtk_entry_completion_set_cell_data_func (GtkCellLayout *cell_layout,
|
||||
GtkCellRenderer *cell,
|
||||
GtkCellLayoutDataFunc func,
|
||||
gpointer func_data,
|
||||
GDestroyNotify destroy);
|
||||
static void gtk_entry_completion_clear_attributes (GtkCellLayout *cell_layout,
|
||||
GtkCellRenderer *cell);
|
||||
|
||||
static gboolean gtk_entry_completion_visible_func (GtkTreeModel *model,
|
||||
GtkTreeIter *iter,
|
||||
gpointer data);
|
||||
static gboolean gtk_entry_completion_popup_key_press (GtkWidget *widget,
|
||||
GdkEventKey *event,
|
||||
gpointer user_data);
|
||||
static gboolean gtk_entry_completion_popup_button_press (GtkWidget *widget,
|
||||
GdkEventButton *event,
|
||||
gpointer user_data);
|
||||
static gboolean gtk_entry_completion_list_button_press (GtkWidget *widget,
|
||||
GdkEventButton *event,
|
||||
gpointer user_data);
|
||||
static gboolean gtk_entry_completion_action_button_press (GtkWidget *widget,
|
||||
GdkEventButton *event,
|
||||
gpointer user_data);
|
||||
|
||||
static void gtk_entry_completion_insert_action (GtkEntryCompletion *completion,
|
||||
gint index,
|
||||
gchar *string,
|
||||
gboolean markup);
|
||||
static void gtk_entry_completion_action_data_func (GtkTreeViewColumn *tree_column,
|
||||
GtkCellRenderer *cell,
|
||||
GtkTreeModel *model,
|
||||
GtkTreeIter *iter,
|
||||
gpointer data);
|
||||
|
||||
|
||||
static guint entry_completion_signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
|
||||
GType
|
||||
gtk_entry_completion_get_type (void)
|
||||
{
|
||||
static GType entry_completion_type = 0;
|
||||
|
||||
if (!entry_completion_type)
|
||||
{
|
||||
static const GTypeInfo entry_completion_info =
|
||||
{
|
||||
sizeof (GtkEntryCompletionClass),
|
||||
NULL,
|
||||
NULL,
|
||||
(GClassInitFunc) gtk_entry_completion_class_init,
|
||||
NULL,
|
||||
NULL,
|
||||
sizeof (GtkEntryCompletion),
|
||||
0,
|
||||
(GInstanceInitFunc) gtk_entry_completion_init
|
||||
};
|
||||
|
||||
static const GInterfaceInfo cell_layout_info =
|
||||
{
|
||||
(GInterfaceInitFunc) gtk_entry_completion_cell_layout_init,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
entry_completion_type =
|
||||
g_type_register_static (G_TYPE_OBJECT, "GtkEntryCompletion",
|
||||
&entry_completion_info, 0);
|
||||
|
||||
g_type_add_interface_static (entry_completion_type,
|
||||
GTK_TYPE_CELL_LAYOUT,
|
||||
&cell_layout_info);
|
||||
}
|
||||
|
||||
return entry_completion_type;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_entry_completion_class_init (GtkEntryCompletionClass *klass)
|
||||
{
|
||||
GObjectClass *object_class;
|
||||
|
||||
object_class = (GObjectClass *)klass;
|
||||
|
||||
object_class->set_property = gtk_entry_completion_set_property;
|
||||
object_class->get_property = gtk_entry_completion_get_property;
|
||||
object_class->finalize = gtk_entry_completion_finalize;
|
||||
|
||||
entry_completion_signals[MATCH_SELECTED] =
|
||||
g_signal_new ("match_selected",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GtkEntryCompletionClass, match_selected),
|
||||
_gtk_boolean_handled_accumulator, NULL,
|
||||
_gtk_marshal_BOOLEAN__OBJECT_BOXED,
|
||||
G_TYPE_BOOLEAN, 2,
|
||||
GTK_TYPE_TREE_MODEL,
|
||||
GTK_TYPE_TREE_ITER);
|
||||
entry_completion_signals[ACTION_ACTIVATED] =
|
||||
g_signal_new ("action_activated",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GtkEntryCompletionClass, action_activated),
|
||||
NULL, NULL,
|
||||
_gtk_marshal_NONE__INT,
|
||||
G_TYPE_NONE, 1,
|
||||
G_TYPE_INT);
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_MODEL,
|
||||
g_param_spec_object ("model",
|
||||
_("Completion Model"),
|
||||
_("The model to find matches in"),
|
||||
GTK_TYPE_TREE_MODEL,
|
||||
G_PARAM_READWRITE));
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_MINIMUM_KEY_LENGTH,
|
||||
g_param_spec_int ("minimum_key_length",
|
||||
_("Minimum Key Length"),
|
||||
_("Minimum length of the search key in order to look up matches"),
|
||||
-1,
|
||||
G_MAXINT,
|
||||
1,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_type_class_add_private (object_class, sizeof (GtkEntryCompletionPrivate));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_entry_completion_cell_layout_init (GtkCellLayoutIface *iface)
|
||||
{
|
||||
iface->pack_start = gtk_entry_completion_pack_start;
|
||||
iface->pack_end = gtk_entry_completion_pack_end;
|
||||
iface->clear = gtk_entry_completion_clear;
|
||||
iface->add_attribute = gtk_entry_completion_add_attribute;
|
||||
iface->set_cell_data_func = gtk_entry_completion_set_cell_data_func;
|
||||
iface->clear_attributes = gtk_entry_completion_clear_attributes;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_entry_completion_init (GtkEntryCompletion *completion)
|
||||
{
|
||||
GtkCellRenderer *cell;
|
||||
GtkTreeSelection *sel;
|
||||
GtkEntryCompletionPrivate *priv;
|
||||
|
||||
/* yes, also priv, need to keep the code readable */
|
||||
priv = completion->priv = GTK_ENTRY_COMPLETION_GET_PRIVATE (completion);
|
||||
|
||||
priv->minimum_key_length = 1;
|
||||
priv->text_column = -1;
|
||||
|
||||
/* completions */
|
||||
priv->filter_model = NULL;
|
||||
|
||||
priv->tree_view = gtk_tree_view_new ();
|
||||
g_signal_connect (priv->tree_view, "button_press_event",
|
||||
G_CALLBACK (gtk_entry_completion_list_button_press),
|
||||
completion);
|
||||
gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (priv->tree_view), FALSE);
|
||||
|
||||
sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->tree_view));
|
||||
gtk_tree_selection_set_mode (sel, GTK_SELECTION_SINGLE);
|
||||
gtk_tree_selection_unselect_all (sel);
|
||||
|
||||
priv->column = gtk_tree_view_column_new ();
|
||||
gtk_tree_view_append_column (GTK_TREE_VIEW (priv->tree_view), priv->column);
|
||||
|
||||
priv->scrolled_window = gtk_scrolled_window_new (NULL, NULL);
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->scrolled_window),
|
||||
GTK_POLICY_NEVER,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (priv->scrolled_window),
|
||||
GTK_SHADOW_ETCHED_IN);
|
||||
|
||||
|
||||
/* actions */
|
||||
priv->actions = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
|
||||
|
||||
priv->action_view =
|
||||
gtk_tree_view_new_with_model (GTK_TREE_MODEL (priv->actions));
|
||||
g_signal_connect (priv->action_view, "button_press_event",
|
||||
G_CALLBACK (gtk_entry_completion_action_button_press),
|
||||
completion);
|
||||
gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (priv->action_view), FALSE);
|
||||
|
||||
sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->action_view));
|
||||
gtk_tree_selection_set_mode (sel, GTK_SELECTION_SINGLE);
|
||||
gtk_tree_selection_unselect_all (sel);
|
||||
|
||||
cell = gtk_cell_renderer_text_new ();
|
||||
g_object_set (cell, "cell_background_gdk",
|
||||
&priv->tree_view->style->bg[GTK_STATE_NORMAL],
|
||||
NULL);
|
||||
gtk_tree_view_insert_column_with_data_func (GTK_TREE_VIEW (priv->action_view),
|
||||
0, "",
|
||||
cell,
|
||||
gtk_entry_completion_action_data_func,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
/* pack it all */
|
||||
priv->popup_window = gtk_window_new (GTK_WINDOW_POPUP);
|
||||
gtk_window_set_resizable (GTK_WINDOW (priv->popup_window), FALSE);
|
||||
g_signal_connect (priv->popup_window, "key_press_event",
|
||||
G_CALLBACK (gtk_entry_completion_popup_key_press),
|
||||
completion);
|
||||
g_signal_connect (priv->popup_window, "button_press_event",
|
||||
G_CALLBACK (gtk_entry_completion_popup_button_press),
|
||||
completion);
|
||||
|
||||
priv->vbox = gtk_vbox_new (FALSE, 0);
|
||||
gtk_container_add (GTK_CONTAINER (priv->popup_window), priv->vbox);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (priv->scrolled_window), priv->tree_view);
|
||||
gtk_box_pack_start (GTK_BOX (priv->vbox), priv->scrolled_window,
|
||||
TRUE, TRUE, 0);
|
||||
|
||||
/* we don't want to see the action treeview when no actions have
|
||||
* been inserted, so we pack the action treeview after the first
|
||||
* action has been added
|
||||
*/
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_entry_completion_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkEntryCompletion *completion = GTK_ENTRY_COMPLETION (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_MODEL:
|
||||
gtk_entry_completion_set_model (completion,
|
||||
g_value_get_object (value));
|
||||
break;
|
||||
|
||||
case PROP_MINIMUM_KEY_LENGTH:
|
||||
gtk_entry_completion_set_minimum_key_length (completion,
|
||||
g_value_get_int (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_entry_completion_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkEntryCompletion *completion = GTK_ENTRY_COMPLETION (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_MODEL:
|
||||
g_value_set_object (value,
|
||||
gtk_entry_completion_get_model (completion));
|
||||
break;
|
||||
|
||||
case PROP_MINIMUM_KEY_LENGTH:
|
||||
g_value_set_int (value, gtk_entry_completion_get_minimum_key_length (completion));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_entry_completion_finalize (GObject *object)
|
||||
{
|
||||
GtkEntryCompletion *completion = GTK_ENTRY_COMPLETION (object);
|
||||
|
||||
if (completion->priv->tree_view)
|
||||
gtk_widget_destroy (completion->priv->tree_view);
|
||||
|
||||
if (completion->priv->entry)
|
||||
gtk_entry_set_completion (GTK_ENTRY (completion->priv->entry), NULL);
|
||||
|
||||
if (completion->priv->actions)
|
||||
g_object_unref (completion->priv->actions);
|
||||
|
||||
if (completion->priv->case_normalized_key)
|
||||
g_free (completion->priv->case_normalized_key);
|
||||
|
||||
if (completion->priv->popup_window)
|
||||
gtk_widget_destroy (completion->priv->popup_window);
|
||||
}
|
||||
|
||||
/* implement cell layout interface */
|
||||
static void
|
||||
gtk_entry_completion_pack_start (GtkCellLayout *cell_layout,
|
||||
GtkCellRenderer *cell,
|
||||
gboolean expand)
|
||||
{
|
||||
GtkEntryCompletionPrivate *priv;
|
||||
|
||||
g_return_if_fail (GTK_IS_ENTRY_COMPLETION (cell_layout));
|
||||
|
||||
priv = GTK_ENTRY_COMPLETION_GET_PRIVATE (cell_layout);
|
||||
|
||||
gtk_tree_view_column_pack_start (priv->column, cell, expand);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_entry_completion_pack_end (GtkCellLayout *cell_layout,
|
||||
GtkCellRenderer *cell,
|
||||
gboolean expand)
|
||||
{
|
||||
GtkEntryCompletionPrivate *priv;
|
||||
|
||||
g_return_if_fail (GTK_IS_ENTRY_COMPLETION (cell_layout));
|
||||
|
||||
priv = GTK_ENTRY_COMPLETION_GET_PRIVATE (cell_layout);
|
||||
|
||||
gtk_tree_view_column_pack_end (priv->column, cell, expand);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_entry_completion_clear (GtkCellLayout *cell_layout)
|
||||
{
|
||||
GtkEntryCompletionPrivate *priv;
|
||||
|
||||
g_return_if_fail (GTK_IS_ENTRY_COMPLETION (cell_layout));
|
||||
|
||||
priv = GTK_ENTRY_COMPLETION_GET_PRIVATE (cell_layout);
|
||||
|
||||
gtk_tree_view_column_clear (priv->column);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_entry_completion_add_attribute (GtkCellLayout *cell_layout,
|
||||
GtkCellRenderer *cell,
|
||||
const gchar *attribute,
|
||||
gint column)
|
||||
{
|
||||
GtkEntryCompletionPrivate *priv;
|
||||
|
||||
g_return_if_fail (GTK_IS_ENTRY_COMPLETION (cell_layout));
|
||||
|
||||
priv = GTK_ENTRY_COMPLETION_GET_PRIVATE (cell_layout);
|
||||
|
||||
gtk_tree_view_column_add_attribute (priv->column, cell, attribute, column);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_entry_completion_set_cell_data_func (GtkCellLayout *cell_layout,
|
||||
GtkCellRenderer *cell,
|
||||
GtkCellLayoutDataFunc func,
|
||||
gpointer func_data,
|
||||
GDestroyNotify destroy)
|
||||
{
|
||||
GtkEntryCompletionPrivate *priv;
|
||||
|
||||
g_return_if_fail (GTK_IS_ENTRY_COMPLETION (cell_layout));
|
||||
|
||||
priv = GTK_ENTRY_COMPLETION_GET_PRIVATE (cell_layout);
|
||||
|
||||
gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (priv->column),
|
||||
cell, func, func_data, destroy);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_entry_completion_clear_attributes (GtkCellLayout *cell_layout,
|
||||
GtkCellRenderer *cell)
|
||||
{
|
||||
GtkEntryCompletionPrivate *priv;
|
||||
|
||||
g_return_if_fail (GTK_IS_ENTRY_COMPLETION (cell_layout));
|
||||
|
||||
priv = GTK_ENTRY_COMPLETION_GET_PRIVATE (cell_layout);
|
||||
|
||||
gtk_tree_view_column_clear_attributes (priv->column, cell);
|
||||
}
|
||||
|
||||
/* all those callbacks */
|
||||
static gboolean
|
||||
gtk_entry_completion_default_completion_func (GtkEntryCompletion *completion,
|
||||
const gchar *key,
|
||||
GtkTreeIter *iter,
|
||||
gpointer user_data)
|
||||
{
|
||||
gchar *item = NULL;
|
||||
gchar *normalized_string;
|
||||
gchar *case_normalized_string;
|
||||
|
||||
gboolean ret = FALSE;
|
||||
|
||||
GtkTreeModel *model;
|
||||
|
||||
model = gtk_tree_model_filter_get_model (completion->priv->filter_model);
|
||||
|
||||
gtk_tree_model_get (model, iter,
|
||||
completion->priv->text_column, &item,
|
||||
-1);
|
||||
|
||||
normalized_string = g_utf8_normalize (item, -1, G_NORMALIZE_ALL);
|
||||
case_normalized_string = g_utf8_casefold (normalized_string, -1);
|
||||
|
||||
if (!strncmp (key, case_normalized_string, strlen (key)))
|
||||
ret = TRUE;
|
||||
|
||||
g_free (item);
|
||||
g_free (normalized_string);
|
||||
g_free (case_normalized_string);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_entry_completion_visible_func (GtkTreeModel *model,
|
||||
GtkTreeIter *iter,
|
||||
gpointer data)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
|
||||
GtkEntryCompletion *completion = GTK_ENTRY_COMPLETION (data);
|
||||
|
||||
if (!completion->priv->case_normalized_key)
|
||||
return ret;
|
||||
|
||||
if (completion->priv->text_column >= 0)
|
||||
ret = gtk_entry_completion_default_completion_func (completion,
|
||||
completion->priv->case_normalized_key,
|
||||
iter,
|
||||
NULL);
|
||||
|
||||
else if (completion->priv->match_func)
|
||||
ret = (* completion->priv->match_func) (completion,
|
||||
completion->priv->case_normalized_key,
|
||||
iter,
|
||||
completion->priv->match_data);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_entry_completion_popup_key_press (GtkWidget *widget,
|
||||
GdkEventKey *event,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkEntryCompletion *completion = GTK_ENTRY_COMPLETION (user_data);
|
||||
|
||||
if (!GTK_WIDGET_MAPPED (completion->priv->popup_window))
|
||||
return FALSE;
|
||||
|
||||
/* propagate event to the entry */
|
||||
gtk_widget_event (completion->priv->entry, (GdkEvent *)event);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_entry_completion_popup_button_press (GtkWidget *widget,
|
||||
GdkEventButton *event,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkEntryCompletion *completion = GTK_ENTRY_COMPLETION (user_data);
|
||||
|
||||
if (!GTK_WIDGET_MAPPED (completion->priv->popup_window))
|
||||
return FALSE;
|
||||
|
||||
/* if we come here, it's usually time to popdown */
|
||||
_gtk_entry_completion_popdown (completion);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_entry_completion_list_button_press (GtkWidget *widget,
|
||||
GdkEventButton *event,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkEntryCompletion *completion = GTK_ENTRY_COMPLETION (user_data);
|
||||
GtkTreePath *path = NULL;
|
||||
|
||||
if (!GTK_WIDGET_MAPPED (completion->priv->popup_window))
|
||||
return FALSE;
|
||||
|
||||
if (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (widget),
|
||||
event->x, event->y,
|
||||
&path, NULL, NULL, NULL))
|
||||
{
|
||||
gboolean entry_set;
|
||||
GtkTreeIter iter;
|
||||
|
||||
gtk_tree_model_get_iter (GTK_TREE_MODEL (completion->priv->filter_model),
|
||||
&iter, path);
|
||||
gtk_tree_path_free (path);
|
||||
|
||||
g_signal_emit (completion, entry_completion_signals[MATCH_SELECTED],
|
||||
0, GTK_TREE_MODEL (completion->priv->filter_model),
|
||||
&iter, &entry_set);
|
||||
|
||||
if (!entry_set)
|
||||
{
|
||||
gchar *str = NULL;
|
||||
|
||||
gtk_tree_model_get (GTK_TREE_MODEL (completion->priv->filter_model),
|
||||
&iter,
|
||||
completion->priv->text_column, &str,
|
||||
-1);
|
||||
|
||||
g_signal_handler_block (completion->priv->entry,
|
||||
completion->priv->changed_id);
|
||||
gtk_entry_set_text (GTK_ENTRY (completion->priv->entry), str);
|
||||
g_signal_handler_unblock (completion->priv->entry,
|
||||
completion->priv->changed_id);
|
||||
|
||||
/* move cursor to the end */
|
||||
gtk_editable_set_position (GTK_EDITABLE (completion->priv->entry),
|
||||
-1);
|
||||
|
||||
g_free (str);
|
||||
}
|
||||
|
||||
_gtk_entry_completion_popdown (completion);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_entry_completion_action_button_press (GtkWidget *widget,
|
||||
GdkEventButton *event,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkEntryCompletion *completion = GTK_ENTRY_COMPLETION (user_data);
|
||||
GtkTreePath *path = NULL;
|
||||
|
||||
if (!GTK_WIDGET_MAPPED (completion->priv->popup_window))
|
||||
return FALSE;
|
||||
|
||||
if (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (widget),
|
||||
event->x, event->y,
|
||||
&path, NULL, NULL, NULL))
|
||||
{
|
||||
g_signal_emit (completion, entry_completion_signals[ACTION_ACTIVATED],
|
||||
0, gtk_tree_path_get_indices (path)[0]);
|
||||
gtk_tree_path_free (path);
|
||||
|
||||
_gtk_entry_completion_popdown (completion);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_entry_completion_action_data_func (GtkTreeViewColumn *tree_column,
|
||||
GtkCellRenderer *cell,
|
||||
GtkTreeModel *model,
|
||||
GtkTreeIter *iter,
|
||||
gpointer data)
|
||||
{
|
||||
gchar *string = NULL;
|
||||
gboolean markup;
|
||||
|
||||
gtk_tree_model_get (model, iter,
|
||||
0, &string,
|
||||
1, &markup,
|
||||
-1);
|
||||
|
||||
if (!string)
|
||||
return;
|
||||
|
||||
if (markup)
|
||||
g_object_set (G_OBJECT (cell),
|
||||
"text", NULL,
|
||||
"markup", string,
|
||||
NULL);
|
||||
else
|
||||
g_object_set (G_OBJECT (cell),
|
||||
"markup", NULL,
|
||||
"text", string,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/* public API */
|
||||
GtkEntryCompletion *
|
||||
gtk_entry_completion_new (void)
|
||||
{
|
||||
GtkEntryCompletion *completion;
|
||||
|
||||
completion = g_object_new (GTK_TYPE_ENTRY_COMPLETION, NULL);
|
||||
|
||||
return completion;
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
gtk_entry_completion_get_entry (GtkEntryCompletion *completion)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_ENTRY_COMPLETION (completion), NULL);
|
||||
|
||||
return completion->priv->entry;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_entry_completion_set_model (GtkEntryCompletion *completion,
|
||||
GtkTreeModel *model)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_ENTRY_COMPLETION (completion));
|
||||
g_return_if_fail (GTK_IS_TREE_MODEL (model));
|
||||
|
||||
/* code will unref the old filter model (if any) */
|
||||
completion->priv->filter_model =
|
||||
GTK_TREE_MODEL_FILTER (gtk_tree_model_filter_new (model, NULL));
|
||||
gtk_tree_model_filter_set_visible_func (completion->priv->filter_model,
|
||||
gtk_entry_completion_visible_func,
|
||||
completion,
|
||||
NULL);
|
||||
gtk_tree_view_set_model (GTK_TREE_VIEW (completion->priv->tree_view),
|
||||
GTK_TREE_MODEL (completion->priv->filter_model));
|
||||
g_object_unref (G_OBJECT (completion->priv->filter_model));
|
||||
}
|
||||
|
||||
GtkTreeModel *
|
||||
gtk_entry_completion_get_model (GtkEntryCompletion *completion)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_ENTRY_COMPLETION (completion), NULL);
|
||||
|
||||
return gtk_tree_model_filter_get_model (completion->priv->filter_model);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_entry_completion_set_match_func (GtkEntryCompletion *completion,
|
||||
GtkEntryCompletionMatchFunc func,
|
||||
gpointer func_data,
|
||||
GDestroyNotify func_notify)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_ENTRY_COMPLETION (completion));
|
||||
|
||||
if (completion->priv->match_notify)
|
||||
(* completion->priv->match_notify) (completion->priv->match_data);
|
||||
|
||||
completion->priv->match_func = func;
|
||||
completion->priv->match_data = func_data;
|
||||
completion->priv->match_notify = func_notify;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_entry_completion_set_minimum_key_length (GtkEntryCompletion *completion,
|
||||
gint length)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_ENTRY_COMPLETION (completion));
|
||||
g_return_if_fail (length >= 1);
|
||||
|
||||
completion->priv->minimum_key_length = length;
|
||||
}
|
||||
|
||||
gint
|
||||
gtk_entry_completion_get_minimum_key_length (GtkEntryCompletion *completion)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_ENTRY_COMPLETION (completion), 0);
|
||||
|
||||
return completion->priv->minimum_key_length;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_entry_completion_complete (GtkEntryCompletion *completion)
|
||||
{
|
||||
gchar *tmp;
|
||||
|
||||
g_return_if_fail (GTK_IS_ENTRY_COMPLETION (completion));
|
||||
g_return_if_fail (completion->priv->filter_model != NULL);
|
||||
|
||||
if (completion->priv->case_normalized_key)
|
||||
g_free (completion->priv->case_normalized_key);
|
||||
|
||||
tmp = g_utf8_normalize (gtk_entry_get_text (GTK_ENTRY (completion->priv->entry)),
|
||||
-1, G_NORMALIZE_ALL);
|
||||
completion->priv->case_normalized_key = g_utf8_casefold (tmp, -1);
|
||||
g_free (tmp);
|
||||
|
||||
gtk_tree_model_filter_refilter (completion->priv->filter_model);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_entry_completion_insert_action (GtkEntryCompletion *completion,
|
||||
gint index,
|
||||
gchar *string,
|
||||
gboolean markup)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
|
||||
gtk_list_store_insert (completion->priv->actions, &iter, index);
|
||||
gtk_list_store_set (completion->priv->actions, &iter,
|
||||
0, string,
|
||||
1, markup,
|
||||
-1);
|
||||
|
||||
if (!completion->priv->action_view->parent)
|
||||
{
|
||||
GtkTreePath *path = gtk_tree_path_new_from_indices (0, -1);
|
||||
|
||||
gtk_tree_view_set_cursor (GTK_TREE_VIEW (completion->priv->action_view),
|
||||
path, NULL, FALSE);
|
||||
gtk_tree_path_free (path);
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (completion->priv->vbox),
|
||||
completion->priv->action_view, FALSE, FALSE, 0);
|
||||
gtk_widget_show (completion->priv->action_view);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gtk_entry_completion_insert_action_text (GtkEntryCompletion *completion,
|
||||
gint index,
|
||||
gchar *text)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_ENTRY_COMPLETION (completion));
|
||||
g_return_if_fail (text != NULL);
|
||||
|
||||
gtk_entry_completion_insert_action (completion, index, text, FALSE);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_entry_completion_insert_action_markup (GtkEntryCompletion *completion,
|
||||
gint index,
|
||||
gchar *markup)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_ENTRY_COMPLETION (completion));
|
||||
g_return_if_fail (markup != NULL);
|
||||
|
||||
gtk_entry_completion_insert_action (completion, index, markup, TRUE);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_entry_completion_delete_action (GtkEntryCompletion *completion,
|
||||
gint index)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
|
||||
g_return_if_fail (GTK_IS_ENTRY_COMPLETION (completion));
|
||||
g_return_if_fail (index >= 0);
|
||||
|
||||
gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (completion->priv->actions),
|
||||
&iter, NULL, index);
|
||||
gtk_list_store_remove (completion->priv->actions, &iter);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_entry_completion_set_text_column (GtkEntryCompletion *completion,
|
||||
gint column)
|
||||
{
|
||||
GtkCellRenderer *cell;
|
||||
|
||||
g_return_if_fail (GTK_IS_ENTRY_COMPLETION (completion));
|
||||
g_return_if_fail (column >= 0);
|
||||
|
||||
completion->priv->text_column = column;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/* private */
|
||||
|
||||
/* lame copy from gtkentry.c */
|
||||
static void
|
||||
get_borders (GtkEntry *entry,
|
||||
gint *xborder,
|
||||
gint *yborder)
|
||||
{
|
||||
GtkWidget *widget = GTK_WIDGET (entry);
|
||||
gint focus_width;
|
||||
gboolean interior_focus;
|
||||
|
||||
gtk_widget_style_get (widget,
|
||||
"interior-focus", &interior_focus,
|
||||
"focus-line-width", &focus_width,
|
||||
NULL);
|
||||
|
||||
if (entry->has_frame)
|
||||
{
|
||||
*xborder = widget->style->xthickness;
|
||||
*yborder = widget->style->ythickness;
|
||||
}
|
||||
else
|
||||
{
|
||||
*xborder = 0;
|
||||
*yborder = 0;
|
||||
}
|
||||
|
||||
if (!interior_focus)
|
||||
{
|
||||
*xborder += focus_width;
|
||||
*yborder += focus_width;
|
||||
}
|
||||
}
|
||||
|
||||
/* this function is a bit nasty */
|
||||
void
|
||||
_gtk_entry_completion_popup (GtkEntryCompletion *completion)
|
||||
{
|
||||
gint x, y, x_border, y_border;
|
||||
gint items;
|
||||
gint height;
|
||||
GtkTreePath *path;
|
||||
|
||||
if (GTK_WIDGET_MAPPED (completion->priv->popup_window))
|
||||
return;
|
||||
|
||||
gtk_widget_show_all (completion->priv->vbox);
|
||||
|
||||
gdk_window_get_origin (completion->priv->entry->window, &x, &y);
|
||||
get_borders (GTK_ENTRY (completion->priv->entry), &x_border, &y_border);
|
||||
|
||||
items = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (completion->priv->filter_model), NULL);
|
||||
|
||||
items = MIN (items, 15);
|
||||
|
||||
gtk_tree_view_column_cell_get_size (completion->priv->column, NULL,
|
||||
NULL, NULL, NULL, &height);
|
||||
|
||||
gtk_widget_set_size_request (completion->priv->tree_view,
|
||||
completion->priv->entry->allocation.width - 2 * x_border,
|
||||
items * height);
|
||||
|
||||
if (items <= 0)
|
||||
gtk_widget_hide (completion->priv->scrolled_window);
|
||||
|
||||
/* default on the first match */
|
||||
path = gtk_tree_path_new_from_indices (0, -1);
|
||||
gtk_tree_view_set_cursor (GTK_TREE_VIEW (completion->priv->tree_view), path,
|
||||
NULL, FALSE);
|
||||
completion->priv->current_selected = 0;
|
||||
gtk_tree_path_free (path);
|
||||
|
||||
items = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (completion->priv->actions), NULL);
|
||||
|
||||
if (items)
|
||||
{
|
||||
gtk_tree_view_column_cell_get_size (gtk_tree_view_get_column (GTK_TREE_VIEW (completion->priv->action_view), 0),
|
||||
NULL, NULL, NULL, NULL,
|
||||
&height);
|
||||
|
||||
gtk_widget_set_size_request (completion->priv->action_view,
|
||||
completion->priv->entry->allocation.width - 2 * x_border,
|
||||
items * height);
|
||||
}
|
||||
|
||||
x += x_border;
|
||||
y += 2 * y_border;
|
||||
|
||||
gtk_window_move (GTK_WINDOW (completion->priv->popup_window), x, y + height);
|
||||
|
||||
gtk_widget_show (completion->priv->popup_window);
|
||||
|
||||
gtk_grab_add (completion->priv->popup_window);
|
||||
gdk_pointer_grab (completion->priv->popup_window->window, TRUE,
|
||||
GDK_BUTTON_PRESS_MASK |
|
||||
GDK_BUTTON_RELEASE_MASK |
|
||||
GDK_POINTER_MOTION_MASK,
|
||||
NULL, NULL, GDK_CURRENT_TIME);
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_entry_completion_popdown (GtkEntryCompletion *completion)
|
||||
{
|
||||
gdk_pointer_ungrab (GDK_CURRENT_TIME);
|
||||
gtk_grab_remove (completion->priv->popup_window);
|
||||
|
||||
gtk_widget_hide (completion->priv->popup_window);
|
||||
}
|
103
gtk/gtkentrycompletion.h
Normal file
103
gtk/gtkentrycompletion.h
Normal file
@ -0,0 +1,103 @@
|
||||
/* gtkentrycompletion.h
|
||||
* Copyright (C) 2003 Kristian Rietveld <kris@gtk.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GTK_ENTRY_COMPLETION_H__
|
||||
#define __GTK_ENTRY_COMPLETION_H__
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include <gtk/gtktreemodel.h>
|
||||
#include <gtk/gtkliststore.h>
|
||||
#include <gtk/gtktreeviewcolumn.h>
|
||||
#include <gtk/gtktreemodelfilter.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_ENTRY_COMPLETION (gtk_entry_completion_get_type ())
|
||||
#define GTK_ENTRY_COMPLETION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_ENTRY_COMPLETION, GtkEntryCompletion))
|
||||
#define GTK_ENTRY_COMPLETION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_ENTRY_COMPLETION, GtkEntryCompletionClass))
|
||||
#define GTK_IS_ENTRY_COMPLETION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_ENTRY_COMPLETION))
|
||||
#define GTK_IS_ENTRY_COMPLETION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_ENTRY_COMPLETION))
|
||||
#define GTK_ENTRY_COMPLETION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_ENTRY_COMPLETION, GtkEntryCompletionClass))
|
||||
#define GTK_ENTRY_COMPLETION_GET_PRIVATE(obj)(G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_ENTRY_COMPLETION, GtkEntryCompletionPrivate))
|
||||
|
||||
typedef struct _GtkEntryCompletion GtkEntryCompletion;
|
||||
typedef struct _GtkEntryCompletionClass GtkEntryCompletionClass;
|
||||
typedef struct _GtkEntryCompletionPrivate GtkEntryCompletionPrivate;
|
||||
|
||||
typedef gboolean (* GtkEntryCompletionMatchFunc) (GtkEntryCompletion *completion,
|
||||
const gchar *key,
|
||||
GtkTreeIter *iter,
|
||||
gpointer user_data);
|
||||
|
||||
|
||||
struct _GtkEntryCompletion
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
/*< private >*/
|
||||
GtkEntryCompletionPrivate *priv;
|
||||
};
|
||||
|
||||
struct _GtkEntryCompletionClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
gboolean (* match_selected) (GtkEntryCompletion *completion,
|
||||
GtkTreeModel *model,
|
||||
GtkTreeIter *iter);
|
||||
void (* action_activated) (GtkEntryCompletion *completion,
|
||||
gint index);
|
||||
};
|
||||
|
||||
/* core */
|
||||
GType gtk_entry_completion_get_type (void);
|
||||
GtkEntryCompletion *gtk_entry_completion_new (void);
|
||||
|
||||
GtkWidget *gtk_entry_completion_get_entry (GtkEntryCompletion *entry);
|
||||
|
||||
void gtk_entry_completion_set_model (GtkEntryCompletion *completion,
|
||||
GtkTreeModel *model);
|
||||
GtkTreeModel *gtk_entry_completion_get_model (GtkEntryCompletion *completion);
|
||||
|
||||
void gtk_entry_completion_set_match_func (GtkEntryCompletion *completion,
|
||||
GtkEntryCompletionMatchFunc func,
|
||||
gpointer func_data,
|
||||
GDestroyNotify func_notify);
|
||||
void gtk_entry_completion_set_minimum_key_length (GtkEntryCompletion *completion,
|
||||
gint length);
|
||||
gint gtk_entry_completion_get_minimum_key_length (GtkEntryCompletion *completion);
|
||||
void gtk_entry_completion_complete (GtkEntryCompletion *completion);
|
||||
|
||||
void gtk_entry_completion_insert_action_text (GtkEntryCompletion *completion,
|
||||
gint index,
|
||||
gchar *text);
|
||||
void gtk_entry_completion_insert_action_markup (GtkEntryCompletion *completion,
|
||||
gint index,
|
||||
gchar *markup);
|
||||
void gtk_entry_completion_delete_action (GtkEntryCompletion *completion,
|
||||
gint index);
|
||||
|
||||
/* convenience */
|
||||
void gtk_entry_completion_set_text_column (GtkEntryCompletion *completion,
|
||||
gint column);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_ENTRY_COMPLETION_H__ */
|
65
gtk/gtkentryprivate.h
Normal file
65
gtk/gtkentryprivate.h
Normal file
@ -0,0 +1,65 @@
|
||||
/* gtkentryprivate.h
|
||||
* Copyright (C) 2003 Kristian Rietveld <kris@gtk.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GTK_ENTRY_PRIVATE_H__
|
||||
#define __GTK_ENTRY_PRIVATE_H__
|
||||
|
||||
#include <gtk/gtktreeviewcolumn.h>
|
||||
#include <gtk/gtktreemodelfilter.h>
|
||||
#include <gtk/gtkliststore.h>
|
||||
#include <gtk/gtkentrycompletion.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
struct _GtkEntryCompletionPrivate
|
||||
{
|
||||
GtkWidget *entry;
|
||||
|
||||
GtkWidget *tree_view;
|
||||
GtkTreeViewColumn *column;
|
||||
GtkTreeModelFilter *filter_model;
|
||||
GtkListStore *actions;
|
||||
|
||||
GtkEntryCompletionMatchFunc match_func;
|
||||
gpointer match_data;
|
||||
GDestroyNotify match_notify;
|
||||
|
||||
gint minimum_key_length;
|
||||
gint text_column;
|
||||
gint current_selected;
|
||||
|
||||
gchar *case_normalized_key;
|
||||
|
||||
/* only used by GtkEntry when attached: */
|
||||
GtkWidget *popup_window;
|
||||
GtkWidget *vbox;
|
||||
GtkWidget *scrolled_window;
|
||||
GtkWidget *action_view;
|
||||
|
||||
gulong completion_timeout;
|
||||
gulong changed_id;
|
||||
gulong key_press_id;
|
||||
};
|
||||
|
||||
void _gtk_entry_completion_popup (GtkEntryCompletion *completion);
|
||||
void _gtk_entry_completion_popdown (GtkEntryCompletion *completion);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_ENTRY_PRIVATE_H__ */
|
@ -28,6 +28,7 @@ BOOLEAN:ENUM,INT
|
||||
BOOLEAN:OBJECT,UINT,FLAGS
|
||||
BOOLEAN:OBJECT,INT,INT,UINT
|
||||
BOOLEAN:OBJECT,STRING,STRING,BOXED
|
||||
BOOLEAN:OBJECT,BOXED
|
||||
BOOLEAN:OBJECT,BOXED,BOXED
|
||||
BOOLEAN:OBJECT,STRING,STRING
|
||||
BOOLEAN:INT,INT
|
||||
|
2746
gtk/gtktreemodelfilter.c
Normal file
2746
gtk/gtktreemodelfilter.c
Normal file
File diff suppressed because it is too large
Load Diff
99
gtk/gtktreemodelfilter.h
Normal file
99
gtk/gtktreemodelfilter.h
Normal file
@ -0,0 +1,99 @@
|
||||
/* gtktreemodelfilter.h
|
||||
* Copyright (C) 2000,2001 Red Hat, Inc., Jonathan Blandford <jrb@redhat.com>
|
||||
* Copyright (C) 2001-2003 Kristian Rietveld <kris@gtk.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public
|
||||
* License along with this program; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GTK_TREE_MODEL_FILTER_H__
|
||||
#define __GTK_TREE_MODEL_FILTER_H__
|
||||
|
||||
#include <gtk/gtktreemodel.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_TREE_MODEL_FILTER (gtk_tree_model_filter_get_type ())
|
||||
#define GTK_TREE_MODEL_FILTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_TREE_MODEL_FILTER, GtkTreeModelFilter))
|
||||
#define GTK_TREE_MODEL_FILTER_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST ((vtable), GTK_TYPE_TREE_MODEL_FILTER, GtkTreeModelFilterClass))
|
||||
#define GTK_IS_TREE_MODEL_FILTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_TREE_MODEL_FILTER))
|
||||
#define GTK_IS_TREE_MODEL_FILTER_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), GTK_TYPE_TREE_MODEL_FILTER))
|
||||
#define GTK_TREE_MODEL_FILTER_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_TREE_MODEL_FILTER, GtkTreeModelFilterClass))
|
||||
#define GTK_TREE_MODEL_FILTER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_TREE_MODEL_FILTER, GtkTreeModelFilterPrivate))
|
||||
|
||||
typedef gboolean (* GtkTreeModelFilterVisibleFunc) (GtkTreeModel *model,
|
||||
GtkTreeIter *iter,
|
||||
gpointer data);
|
||||
typedef void (* GtkTreeModelFilterModifyFunc) (GtkTreeModel *model,
|
||||
GtkTreeIter *iter,
|
||||
GValue *value,
|
||||
gint column,
|
||||
gpointer data);
|
||||
|
||||
typedef struct _GtkTreeModelFilter GtkTreeModelFilter;
|
||||
typedef struct _GtkTreeModelFilterClass GtkTreeModelFilterClass;
|
||||
typedef struct _GtkTreeModelFilterPrivate GtkTreeModelFilterPrivate;
|
||||
|
||||
struct _GtkTreeModelFilter
|
||||
{
|
||||
GObject parent;
|
||||
|
||||
/*< private >*/
|
||||
GtkTreeModelFilterPrivate *priv;
|
||||
};
|
||||
|
||||
struct _GtkTreeModelFilterClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
/* base */
|
||||
GType gtk_tree_model_filter_get_type (void);
|
||||
GtkTreeModel *gtk_tree_model_filter_new (GtkTreeModel *child_model,
|
||||
GtkTreePath *root);
|
||||
void gtk_tree_model_filter_set_visible_func (GtkTreeModelFilter *filter,
|
||||
GtkTreeModelFilterVisibleFunc func,
|
||||
gpointer data,
|
||||
GtkDestroyNotify destroy);
|
||||
void gtk_tree_model_filter_set_modify_func (GtkTreeModelFilter *filter,
|
||||
gint n_columns,
|
||||
GType *types,
|
||||
GtkTreeModelFilterModifyFunc func,
|
||||
gpointer data,
|
||||
GtkDestroyNotify destroy);
|
||||
void gtk_tree_model_filter_set_visible_column (GtkTreeModelFilter *filter,
|
||||
gint column);
|
||||
|
||||
GtkTreeModel *gtk_tree_model_filter_get_model (GtkTreeModelFilter *filter);
|
||||
|
||||
/* conversion */
|
||||
void gtk_tree_model_filter_convert_child_iter_to_iter (GtkTreeModelFilter *filter,
|
||||
GtkTreeIter *filter_iter,
|
||||
GtkTreeIter *child_iter);
|
||||
void gtk_tree_model_filter_convert_iter_to_child_iter (GtkTreeModelFilter *filter,
|
||||
GtkTreeIter *child_iter,
|
||||
GtkTreeIter *filter_iter);
|
||||
GtkTreePath *gtk_tree_model_filter_convert_child_path_to_path (GtkTreeModelFilter *filter,
|
||||
GtkTreePath *child_path);
|
||||
GtkTreePath *gtk_tree_model_filter_convert_path_to_child_path (GtkTreeModelFilter *path,
|
||||
GtkTreePath *filter_path);
|
||||
|
||||
/* extras */
|
||||
void gtk_tree_model_filter_refilter (GtkTreeModelFilter *filter);
|
||||
void gtk_tree_model_filter_clear_cache (GtkTreeModelFilter *filter);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_TREE_MODEL_FILTER_H__ */
|
@ -21,6 +21,7 @@
|
||||
#include "gtktreeviewcolumn.h"
|
||||
#include "gtktreeview.h"
|
||||
#include "gtktreeprivate.h"
|
||||
#include "gtkcelllayout.h"
|
||||
#include "gtkbutton.h"
|
||||
#include "gtkalignment.h"
|
||||
#include "gtklabel.h"
|
||||
@ -74,6 +75,7 @@ struct _GtkTreeViewColumnCellInfo
|
||||
/* Type methods */
|
||||
static void gtk_tree_view_column_init (GtkTreeViewColumn *tree_column);
|
||||
static void gtk_tree_view_column_class_init (GtkTreeViewColumnClass *klass);
|
||||
static void gtk_tree_view_column_cell_layout_init (GtkCellLayoutIface *iface);
|
||||
|
||||
/* GObject methods */
|
||||
static void gtk_tree_view_column_set_property (GObject *object,
|
||||
@ -86,6 +88,26 @@ static void gtk_tree_view_column_get_property (GObject
|
||||
GParamSpec *pspec);
|
||||
static void gtk_tree_view_column_finalize (GObject *object);
|
||||
|
||||
/* GtkCellLayout implementation */
|
||||
static void gtk_tree_view_column_cell_layout_pack_start (GtkCellLayout *cell_layout,
|
||||
GtkCellRenderer *cell,
|
||||
gboolean expand);
|
||||
static void gtk_tree_view_column_cell_layout_pack_end (GtkCellLayout *cell_layout,
|
||||
GtkCellRenderer *cell,
|
||||
gboolean expand);
|
||||
static void gtk_tree_view_column_cell_layout_clear (GtkCellLayout *cell_layout);
|
||||
static void gtk_tree_view_column_cell_layout_add_attribute (GtkCellLayout *cell_layout,
|
||||
GtkCellRenderer *cell,
|
||||
const gchar *attribute,
|
||||
gint column);
|
||||
static void gtk_tree_view_column_cell_layout_set_cell_data_func (GtkCellLayout *cell_layout,
|
||||
GtkCellRenderer *cell,
|
||||
GtkCellLayoutDataFunc func,
|
||||
gpointer func_data,
|
||||
GDestroyNotify destroy);
|
||||
static void gtk_tree_view_column_cell_layout_clear_attributes (GtkCellLayout *cell_layout,
|
||||
GtkCellRenderer *cell);
|
||||
|
||||
/* Button handling code */
|
||||
static void gtk_tree_view_column_create_button (GtkTreeViewColumn *tree_column);
|
||||
static void gtk_tree_view_column_update_button (GtkTreeViewColumn *tree_column);
|
||||
@ -145,12 +167,23 @@ gtk_tree_view_column_get_type (void)
|
||||
NULL, /* class_data */
|
||||
sizeof (GtkTreeViewColumn),
|
||||
0,
|
||||
(GInstanceInitFunc) gtk_tree_view_column_init,
|
||||
(GInstanceInitFunc) gtk_tree_view_column_init
|
||||
};
|
||||
|
||||
static const GInterfaceInfo cell_layout_info =
|
||||
{
|
||||
(GInterfaceInitFunc) gtk_tree_view_column_cell_layout_init,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
tree_column_type =
|
||||
g_type_register_static (GTK_TYPE_OBJECT, "GtkTreeViewColumn",
|
||||
&tree_column_info, 0);
|
||||
|
||||
g_type_add_interface_static (tree_column_type,
|
||||
GTK_TYPE_CELL_LAYOUT,
|
||||
&cell_layout_info);
|
||||
}
|
||||
|
||||
return tree_column_type;
|
||||
@ -314,6 +347,17 @@ gtk_tree_view_column_class_init (GtkTreeViewColumnClass *class)
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tree_view_column_cell_layout_init (GtkCellLayoutIface *iface)
|
||||
{
|
||||
iface->pack_start = gtk_tree_view_column_cell_layout_pack_start;
|
||||
iface->pack_end = gtk_tree_view_column_cell_layout_pack_end;
|
||||
iface->clear = gtk_tree_view_column_cell_layout_clear;
|
||||
iface->add_attribute = gtk_tree_view_column_cell_layout_add_attribute;
|
||||
iface->set_cell_data_func = gtk_tree_view_column_cell_layout_set_cell_data_func;
|
||||
iface->clear_attributes = gtk_tree_view_column_cell_layout_clear_attributes;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tree_view_column_init (GtkTreeViewColumn *tree_column)
|
||||
{
|
||||
@ -552,6 +596,169 @@ gtk_tree_view_column_get_property (GObject *object,
|
||||
}
|
||||
}
|
||||
|
||||
/* Implementation of GtkCellLayout interface
|
||||
*/
|
||||
|
||||
static void
|
||||
gtk_tree_view_column_cell_layout_pack_start (GtkCellLayout *cell_layout,
|
||||
GtkCellRenderer *cell,
|
||||
gboolean expand)
|
||||
{
|
||||
GtkTreeViewColumn *column;
|
||||
GtkTreeViewColumnCellInfo *cell_info;
|
||||
|
||||
g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (cell_layout));
|
||||
column = GTK_TREE_VIEW_COLUMN (cell_layout);
|
||||
g_return_if_fail (! gtk_tree_view_column_get_cell_info (column, cell));
|
||||
|
||||
g_object_ref (cell);
|
||||
gtk_object_sink (GTK_OBJECT (cell));
|
||||
|
||||
cell_info = g_new0 (GtkTreeViewColumnCellInfo, 1);
|
||||
cell_info->cell = cell;
|
||||
cell_info->expand = expand ? TRUE : FALSE;
|
||||
cell_info->pack = GTK_PACK_START;
|
||||
cell_info->has_focus = 0;
|
||||
cell_info->attributes = NULL;
|
||||
|
||||
column->cell_list = g_list_append (column->cell_list, cell_info);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tree_view_column_cell_layout_pack_end (GtkCellLayout *cell_layout,
|
||||
GtkCellRenderer *cell,
|
||||
gboolean expand)
|
||||
{
|
||||
GtkTreeViewColumn *column;
|
||||
GtkTreeViewColumnCellInfo *cell_info;
|
||||
|
||||
g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (cell_layout));
|
||||
column = GTK_TREE_VIEW_COLUMN (cell_layout);
|
||||
g_return_if_fail (! gtk_tree_view_column_get_cell_info (column, cell));
|
||||
|
||||
g_object_ref (cell);
|
||||
gtk_object_sink (GTK_OBJECT (cell));
|
||||
|
||||
cell_info = g_new0 (GtkTreeViewColumnCellInfo, 1);
|
||||
cell_info->cell = cell;
|
||||
cell_info->expand = expand ? TRUE : FALSE;
|
||||
cell_info->pack = GTK_PACK_END;
|
||||
cell_info->has_focus = 0;
|
||||
cell_info->attributes = NULL;
|
||||
|
||||
column->cell_list = g_list_append (column->cell_list, cell_info);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tree_view_column_cell_layout_clear (GtkCellLayout *cell_layout)
|
||||
{
|
||||
GList *list;
|
||||
GtkTreeViewColumn *column;
|
||||
|
||||
g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (cell_layout));
|
||||
column = GTK_TREE_VIEW_COLUMN (cell_layout);
|
||||
|
||||
for (list = column->cell_list; list; list = list->next)
|
||||
{
|
||||
GtkTreeViewColumnCellInfo *info = (GtkTreeViewColumnCellInfo *)list->data;
|
||||
|
||||
gtk_tree_view_column_clear_attributes (column, info->cell);
|
||||
g_object_unref (info->cell);
|
||||
g_free (info);
|
||||
}
|
||||
|
||||
g_list_free (column->cell_list);
|
||||
column->cell_list = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tree_view_column_cell_layout_add_attribute (GtkCellLayout *cell_layout,
|
||||
GtkCellRenderer *cell,
|
||||
const gchar *attribute,
|
||||
gint column)
|
||||
{
|
||||
GtkTreeViewColumn *tree_column;
|
||||
GtkTreeViewColumnCellInfo *info;
|
||||
|
||||
g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (cell_layout));
|
||||
tree_column = GTK_TREE_VIEW_COLUMN (cell_layout);
|
||||
|
||||
info = gtk_tree_view_column_get_cell_info (tree_column, cell);
|
||||
g_return_if_fail (info != NULL);
|
||||
|
||||
info->attributes = g_slist_prepend (info->attributes, GINT_TO_POINTER (column));
|
||||
info->attributes = g_slist_prepend (info->attributes, g_strdup (attribute));
|
||||
|
||||
if (tree_column->tree_view)
|
||||
_gtk_tree_view_column_cell_set_dirty (tree_column, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tree_view_column_cell_layout_set_cell_data_func (GtkCellLayout *cell_layout,
|
||||
GtkCellRenderer *cell,
|
||||
GtkCellLayoutDataFunc func,
|
||||
gpointer func_data,
|
||||
GDestroyNotify destroy)
|
||||
{
|
||||
GtkTreeViewColumn *column;
|
||||
GtkTreeViewColumnCellInfo *info;
|
||||
|
||||
g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (cell_layout));
|
||||
column = GTK_TREE_VIEW_COLUMN (cell_layout);
|
||||
|
||||
info = gtk_tree_view_column_get_cell_info (column, cell);
|
||||
g_return_if_fail (info != NULL);
|
||||
|
||||
if (info->destroy)
|
||||
{
|
||||
GDestroyNotify d = info->destroy;
|
||||
|
||||
info->destroy = NULL;
|
||||
d (info->func_data);
|
||||
}
|
||||
|
||||
info->func = (GtkTreeCellDataFunc)func;
|
||||
info->func_data = func_data;
|
||||
info->destroy = destroy;
|
||||
|
||||
if (column->tree_view)
|
||||
_gtk_tree_view_column_cell_set_dirty (column, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tree_view_column_cell_layout_clear_attributes (GtkCellLayout *cell_layout,
|
||||
GtkCellRenderer *cell_renderer)
|
||||
{
|
||||
GtkTreeViewColumn *column;
|
||||
GtkTreeViewColumnCellInfo *info;
|
||||
|
||||
g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (cell_layout));
|
||||
column = GTK_TREE_VIEW_COLUMN (cell_layout);
|
||||
|
||||
info = gtk_tree_view_column_get_cell_info (column, cell_renderer);
|
||||
gtk_tree_view_column_clear_attributes_by_info (column, info);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tree_view_column_clear_attributes_by_info (GtkTreeViewColumn *tree_column,
|
||||
GtkTreeViewColumnCellInfo *info)
|
||||
{
|
||||
GSList *list;
|
||||
|
||||
list = info->attributes;
|
||||
|
||||
while (list && list->next)
|
||||
{
|
||||
g_free (list->data);
|
||||
list = list->next->next;
|
||||
}
|
||||
g_slist_free (info->attributes);
|
||||
info->attributes = NULL;
|
||||
|
||||
if (tree_column->tree_view)
|
||||
_gtk_tree_view_column_cell_set_dirty (tree_column, TRUE);
|
||||
}
|
||||
|
||||
/* Helper functions
|
||||
*/
|
||||
|
||||
@ -1246,23 +1453,7 @@ gtk_tree_view_column_pack_start (GtkTreeViewColumn *tree_column,
|
||||
GtkCellRenderer *cell,
|
||||
gboolean expand)
|
||||
{
|
||||
GtkTreeViewColumnCellInfo *cell_info;
|
||||
|
||||
g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
|
||||
g_return_if_fail (GTK_IS_CELL_RENDERER (cell));
|
||||
g_return_if_fail (! gtk_tree_view_column_get_cell_info (tree_column, cell));
|
||||
|
||||
g_object_ref (cell);
|
||||
gtk_object_sink (GTK_OBJECT (cell));
|
||||
|
||||
cell_info = g_new0 (GtkTreeViewColumnCellInfo, 1);
|
||||
cell_info->cell = cell;
|
||||
cell_info->expand = expand ? TRUE : FALSE;
|
||||
cell_info->pack = GTK_PACK_START;
|
||||
cell_info->has_focus = 0;
|
||||
cell_info->attributes = NULL;
|
||||
|
||||
tree_column->cell_list = g_list_append (tree_column->cell_list, cell_info);
|
||||
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (tree_column), cell, expand);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1280,26 +1471,9 @@ gtk_tree_view_column_pack_end (GtkTreeViewColumn *tree_column,
|
||||
GtkCellRenderer *cell,
|
||||
gboolean expand)
|
||||
{
|
||||
GtkTreeViewColumnCellInfo *cell_info;
|
||||
|
||||
g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
|
||||
g_return_if_fail (GTK_IS_CELL_RENDERER (cell));
|
||||
g_return_if_fail (! gtk_tree_view_column_get_cell_info (tree_column, cell));
|
||||
|
||||
g_object_ref (cell);
|
||||
gtk_object_sink (GTK_OBJECT (cell));
|
||||
|
||||
cell_info = g_new0 (GtkTreeViewColumnCellInfo, 1);
|
||||
cell_info->cell = cell;
|
||||
cell_info->expand = expand ? TRUE : FALSE;
|
||||
cell_info->pack = GTK_PACK_END;
|
||||
cell_info->has_focus = 0;
|
||||
cell_info->attributes = NULL;
|
||||
|
||||
tree_column->cell_list = g_list_append (tree_column->cell_list, cell_info);
|
||||
gtk_cell_layout_pack_end (GTK_CELL_LAYOUT (tree_column), cell, expand);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gtk_tree_view_column_clear:
|
||||
* @tree_column: A #GtkTreeViewColumn
|
||||
@ -1309,20 +1483,7 @@ gtk_tree_view_column_pack_end (GtkTreeViewColumn *tree_column,
|
||||
void
|
||||
gtk_tree_view_column_clear (GtkTreeViewColumn *tree_column)
|
||||
{
|
||||
GList *list;
|
||||
g_return_if_fail (tree_column != NULL);
|
||||
|
||||
for (list = tree_column->cell_list; list; list = list->next)
|
||||
{
|
||||
GtkTreeViewColumnCellInfo *info = (GtkTreeViewColumnCellInfo *)list->data;
|
||||
|
||||
gtk_tree_view_column_clear_attributes (tree_column, info->cell);
|
||||
g_object_unref (info->cell);
|
||||
g_free (info);
|
||||
}
|
||||
|
||||
g_list_free (tree_column->cell_list);
|
||||
tree_column->cell_list = NULL;
|
||||
gtk_cell_layout_clear (GTK_CELL_LAYOUT (tree_column));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1371,18 +1532,8 @@ gtk_tree_view_column_add_attribute (GtkTreeViewColumn *tree_column,
|
||||
const gchar *attribute,
|
||||
gint column)
|
||||
{
|
||||
GtkTreeViewColumnCellInfo *info;
|
||||
|
||||
g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
|
||||
info = gtk_tree_view_column_get_cell_info (tree_column, cell_renderer);
|
||||
g_return_if_fail (info != NULL);
|
||||
|
||||
info->attributes = g_slist_prepend (info->attributes, GINT_TO_POINTER (column));
|
||||
info->attributes = g_slist_prepend (info->attributes, g_strdup (attribute));
|
||||
|
||||
if (tree_column->tree_view)
|
||||
_gtk_tree_view_column_cell_set_dirty (tree_column, TRUE);
|
||||
|
||||
gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (tree_column),
|
||||
cell_renderer, attribute, column);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1454,28 +1605,10 @@ gtk_tree_view_column_set_cell_data_func (GtkTreeViewColumn *tree_column,
|
||||
gpointer func_data,
|
||||
GtkDestroyNotify destroy)
|
||||
{
|
||||
GtkTreeViewColumnCellInfo *info;
|
||||
|
||||
g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
|
||||
g_return_if_fail (GTK_IS_CELL_RENDERER (cell_renderer));
|
||||
info = gtk_tree_view_column_get_cell_info (tree_column, cell_renderer);
|
||||
|
||||
g_return_if_fail (info != NULL);
|
||||
|
||||
if (info->destroy)
|
||||
{
|
||||
GtkDestroyNotify d = info->destroy;
|
||||
|
||||
info->destroy = NULL;
|
||||
d (info->func_data);
|
||||
}
|
||||
|
||||
info->func = func;
|
||||
info->func_data = func_data;
|
||||
info->destroy = destroy;
|
||||
|
||||
if (tree_column->tree_view)
|
||||
_gtk_tree_view_column_cell_set_dirty (tree_column, TRUE);
|
||||
gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (tree_column),
|
||||
cell_renderer,
|
||||
(GtkCellLayoutDataFunc)func,
|
||||
func_data, destroy);
|
||||
}
|
||||
|
||||
|
||||
@ -1491,37 +1624,10 @@ void
|
||||
gtk_tree_view_column_clear_attributes (GtkTreeViewColumn *tree_column,
|
||||
GtkCellRenderer *cell_renderer)
|
||||
{
|
||||
GtkTreeViewColumnCellInfo *info;
|
||||
|
||||
g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
|
||||
g_return_if_fail (GTK_IS_CELL_RENDERER (cell_renderer));
|
||||
|
||||
info = gtk_tree_view_column_get_cell_info (tree_column, cell_renderer);
|
||||
|
||||
gtk_tree_view_column_clear_attributes_by_info (tree_column, info);
|
||||
gtk_cell_layout_clear_attributes (GTK_CELL_LAYOUT (tree_column),
|
||||
cell_renderer);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tree_view_column_clear_attributes_by_info (GtkTreeViewColumn *tree_column,
|
||||
GtkTreeViewColumnCellInfo *info)
|
||||
{
|
||||
GSList *list;
|
||||
|
||||
list = info->attributes;
|
||||
|
||||
while (list && list->next)
|
||||
{
|
||||
g_free (list->data);
|
||||
list = list->next->next;
|
||||
}
|
||||
g_slist_free (info->attributes);
|
||||
info->attributes = NULL;
|
||||
|
||||
if (tree_column->tree_view)
|
||||
_gtk_tree_view_column_cell_set_dirty (tree_column, TRUE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gtk_tree_view_column_set_spacing:
|
||||
* @tree_column: A #GtkTreeViewColumn.
|
||||
|
@ -28,6 +28,7 @@ gtk/gtkbbox.c
|
||||
gtk/gtkbox.c
|
||||
gtk/gtkbutton.c
|
||||
gtk/gtkcalendar.c
|
||||
gtk/gtkcelllayout.c
|
||||
gtk/gtkcellrenderer.c
|
||||
gtk/gtkcellrendererpixbuf.c
|
||||
gtk/gtkcellrenderertext.c
|
||||
@ -41,6 +42,7 @@ gtk/gtkcontainer.c
|
||||
gtk/gtkcurve.c
|
||||
gtk/gtkdialog.c
|
||||
gtk/gtkentry.c
|
||||
gtk/gtkentrycompletion.c
|
||||
gtk/gtkfilesel.c
|
||||
gtk/gtkfixed.c
|
||||
gtk/gtkfontsel.c
|
||||
@ -89,6 +91,7 @@ gtk/gtkthemes.c
|
||||
gtk/gtktipsquery.c
|
||||
gtk/gtktogglebutton.c
|
||||
gtk/gtktoolbar.c
|
||||
gtk/gtktreemodelfilter.c
|
||||
gtk/gtktreemodelsort.c
|
||||
gtk/gtktreeview.c
|
||||
gtk/gtktreeviewcolumn.c
|
||||
|
Loading…
Reference in New Issue
Block a user