summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2020-06-24 22:26:24 -0400
committerMatthias Clasen <mclasen@redhat.com>2020-06-25 08:24:05 -0400
commit0b8092a2ba9558879ae1b5adb68a86399a6869ef (patch)
tree46f5e52c6628d4d2e06f57c47a2a0bea8f008020
parentab3b1d9d2a9321d50c56eb3dc32fc8dbfd52cad4 (diff)
downloadgtk+-port-entry-completion.tar.gz
entrycompletion: port to list modelsport-entry-completion
Replace tree models and cell renderers with list models and factories, in the entry completion api. The new apis are gtk_entry_completion_set_model gtk_entry_completion_set_expression gtk_entry_completion_set_factory Port all internal uses of GtkEntryCompletion. testentrycompletion has an example of using a custom model, factory and expression.
-rw-r--r--demos/gtk-demo/entry_completion.c23
-rw-r--r--demos/widget-factory/widget-factory.ui18
-rw-r--r--docs/reference/gtk/gtk4-sections.txt12
-rw-r--r--gtk/gtkentry.c6
-rw-r--r--gtk/gtkentrycompletion.c1068
-rw-r--r--gtk/gtkentrycompletion.h58
-rw-r--r--gtk/gtkentryprivate.h51
-rw-r--r--gtk/gtkplacesview.c14
-rw-r--r--gtk/ui/gtkplacesview.ui7
-rw-r--r--tests/testentrycompletion.c421
-rw-r--r--tests/testgtk.c14
-rw-r--r--testsuite/gtk/cellarea.c51
12 files changed, 581 insertions, 1162 deletions
diff --git a/demos/gtk-demo/entry_completion.c b/demos/gtk-demo/entry_completion.c
index 40d64bd8b6..3d48ae6cd9 100644
--- a/demos/gtk-demo/entry_completion.c
+++ b/demos/gtk-demo/entry_completion.c
@@ -8,8 +8,8 @@
#include <glib/gi18n.h>
#include <gtk/gtk.h>
-/* Creates a tree model containing the completions */
-static GtkTreeModel *
+/* Creates a list model containing the completions */
+static GListModel *
create_completion_model (void)
{
const char *strings[] = {
@@ -42,20 +42,8 @@ create_completion_model (void)
"aæz",
NULL
};
- int i;
- GtkListStore *store;
- GtkTreeIter iter;
- store = gtk_list_store_new (1, G_TYPE_STRING);
-
- for (i = 0; strings[i]; i++)
- {
- /* Append one word */
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter, 0, strings[i], -1);
- }
-
- return GTK_TREE_MODEL (store);
+ return G_LIST_MODEL (gtk_string_list_new (strings));
}
@@ -67,7 +55,7 @@ do_entry_completion (GtkWidget *do_widget)
GtkWidget *label;
GtkWidget *entry;
GtkEntryCompletion *completion;
- GtkTreeModel *completion_model;
+ GListModel *completion_model;
if (!window)
{
@@ -105,9 +93,6 @@ do_entry_completion (GtkWidget *do_widget)
gtk_entry_completion_set_model (completion, completion_model);
g_object_unref (completion_model);
- /* Use model column 0 as the text column */
- gtk_entry_completion_set_text_column (completion, 0);
-
gtk_entry_completion_set_inline_completion (completion, TRUE);
gtk_entry_completion_set_inline_selection (completion, TRUE);
}
diff --git a/demos/widget-factory/widget-factory.ui b/demos/widget-factory/widget-factory.ui
index 5414ce82be..1699c5b18f 100644
--- a/demos/widget-factory/widget-factory.ui
+++ b/demos/widget-factory/widget-factory.ui
@@ -200,18 +200,18 @@
</row>
</data>
</object>
+ <object class="GtkStringList" id="name_list">
+ <items>
+ <item>Andrea</item>
+ <item>Otto</item>
+ <item>Orville</item>
+ <item>Benjamin</item>
+ </items>
+ </object>
<object class="GtkEntryCompletion" id="name_completion">
- <property name="model">liststore1</property>
- <property name="text-column">2</property>
+ <property name="model">name_list</property>
<property name="inline-completion">1</property>
- <property name="popup-single-match">0</property>
<property name="inline-selection">1</property>
- <child>
- <object class="GtkCellRendererText"/>
- <attributes>
- <attribute name="text">2</attribute>
- </attributes>
- </child>
</object>
<object class="GtkListStore" id="lrmodel">
<columns>
diff --git a/docs/reference/gtk/gtk4-sections.txt b/docs/reference/gtk/gtk4-sections.txt
index 39e04bfb81..03285e5a65 100644
--- a/docs/reference/gtk/gtk4-sections.txt
+++ b/docs/reference/gtk/gtk4-sections.txt
@@ -1162,24 +1162,20 @@ gtk_entry_buffer_get_type
<FILE>gtkentrycompletion</FILE>
<TITLE>GtkEntryCompletion</TITLE>
GtkEntryCompletion
-GtkEntryCompletionMatchFunc
gtk_entry_completion_new
-gtk_entry_completion_new_with_area
gtk_entry_completion_get_entry
gtk_entry_completion_set_model
gtk_entry_completion_get_model
-gtk_entry_completion_set_match_func
+gtk_entry_completion_set_expression
+gtk_entry_completion_get_expression
+gtk_entry_completion_set_factory
+gtk_entry_completion_get_factory
gtk_entry_completion_set_minimum_key_length
gtk_entry_completion_get_minimum_key_length
gtk_entry_completion_compute_prefix
gtk_entry_completion_complete
gtk_entry_completion_get_completion_prefix
gtk_entry_completion_insert_prefix
-gtk_entry_completion_insert_action_text
-gtk_entry_completion_insert_action_markup
-gtk_entry_completion_delete_action
-gtk_entry_completion_set_text_column
-gtk_entry_completion_get_text_column
gtk_entry_completion_set_inline_completion
gtk_entry_completion_get_inline_completion
gtk_entry_completion_set_inline_selection
diff --git a/gtk/gtkentry.c b/gtk/gtkentry.c
index 6ab195c7c6..c20cef4418 100644
--- a/gtk/gtkentry.c
+++ b/gtk/gtkentry.c
@@ -1752,7 +1752,7 @@ gtk_entry_size_allocate (GtkWidget *widget,
completion = gtk_entry_get_completion (entry);
if (completion)
- _gtk_entry_completion_resize_popup (completion);
+ gtk_entry_completion_resize_popup (completion);
}
if (priv->emoji_chooser)
@@ -3183,7 +3183,7 @@ gtk_entry_set_completion (GtkEntry *entry,
if (old)
{
- _gtk_entry_completion_disconnect (old);
+ gtk_entry_completion_disconnect (old);
g_object_unref (old);
}
@@ -3196,7 +3196,7 @@ gtk_entry_set_completion (GtkEntry *entry,
/* hook into the entry */
g_object_ref (completion);
- _gtk_entry_completion_connect (completion, entry);
+ gtk_entry_completion_connect (completion, entry);
g_object_set_qdata (G_OBJECT (entry), quark_entry_completion, completion);
diff --git a/gtk/gtkentrycompletion.c b/gtk/gtkentrycompletion.c
index 09a43778b2..4eab9cdfe1 100644
--- a/gtk/gtkentrycompletion.c
+++ b/gtk/gtkentrycompletion.c
@@ -29,9 +29,8 @@
* in the entry, #GtkEntryCompletion checks which rows in the model match
* the current content of the entry, and displays a list of matches.
* By default, the matching is done by comparing the entry text
- * case-insensitively against the text column of the model (see
- * gtk_entry_completion_set_text_column()), but this can be overridden
- * with a custom match function (see gtk_entry_completion_set_match_func()).
+ * case-insensitively against the text obtained from the model using
+ * an expression set with gtk_entry_completion_set_expression().
*
* When the user selects a completion, the content of the entry is
* updated. By default, the content of the entry is replaced by the
@@ -41,19 +40,6 @@
* the signal handler to suppress the default behaviour.
*
* To add completion functionality to an entry, use gtk_entry_set_completion().
- *
- * GtkEntryCompletion uses a #GtkTreeModelFilter model to represent the
- * subset of the entire model that is currently matching. While the
- * GtkEntryCompletion signals #GtkEntryCompletion::match-selected and
- * #GtkEntryCompletion::cursor-on-match take the original model and an
- * iter pointing to that model as arguments, other callbacks and signals
- * (such as #GtkCellLayoutDataFuncs or #GtkCellArea::apply-attributes)
- * will generally take the filter model as argument. As long as you are
- * only calling gtk_tree_model_get(), this will make no difference to
- * you. If for some reason, you need the original model, use
- * gtk_tree_model_filter_get_model(). Don’t forget to use
- * gtk_tree_model_filter_convert_iter_to_child_iter() to obtain a
- * matching iter.
*/
#include "config.h"
@@ -62,14 +48,8 @@
#include "gtkentryprivate.h"
#include "gtktextprivate.h"
-#include "gtkcelllayout.h"
-#include "gtkcellareabox.h"
#include "gtkintl.h"
-#include "gtkcellrenderertext.h"
-#include "gtkframe.h"
-#include "gtktreeselection.h"
-#include "gtktreeview.h"
#include "gtkscrolledwindow.h"
#include "gtksizerequest.h"
#include "gtkbox.h"
@@ -86,6 +66,16 @@
#include "gtkwidgetprivate.h"
#include "gtknative.h"
#include "gtkstylecontext.h"
+#include "gtkstringfilter.h"
+#include "gtkbuildable.h"
+#include "gtkfilterlistmodel.h"
+#include "gtklistview.h"
+#include "gtkstringlist.h"
+#include "gtksignallistitemfactory.h"
+#include "gtklistitem.h"
+#include "gtklabel.h"
+#include "gtksingleselection.h"
+#include "gtkselectionmodel.h"
#include <string.h>
@@ -107,21 +97,18 @@ enum
{
PROP_0,
PROP_MODEL,
+ PROP_EXPRESSION,
+ PROP_FACTORY,
PROP_MINIMUM_KEY_LENGTH,
- PROP_TEXT_COLUMN,
PROP_INLINE_COMPLETION,
PROP_POPUP_COMPLETION,
PROP_POPUP_SET_WIDTH,
PROP_POPUP_SINGLE_MATCH,
PROP_INLINE_SELECTION,
- PROP_CELL_AREA,
NUM_PROPERTIES
};
-static void gtk_entry_completion_cell_layout_init (GtkCellLayoutIface *iface);
-static GtkCellArea* gtk_entry_completion_get_area (GtkCellLayout *cell_layout);
-
static void gtk_entry_completion_constructed (GObject *object);
static void gtk_entry_completion_set_property (GObject *object,
guint prop_id,
@@ -134,29 +121,17 @@ static void gtk_entry_completion_get_property (GObject *object,
static void gtk_entry_completion_finalize (GObject *object);
static void gtk_entry_completion_dispose (GObject *object);
-static gboolean gtk_entry_completion_visible_func (GtkTreeModel *model,
- GtkTreeIter *iter,
- gpointer data);
-static void gtk_entry_completion_list_activated (GtkTreeView *treeview,
- GtkTreePath *path,
- GtkTreeViewColumn *column,
- gpointer user_data);
-static void gtk_entry_completion_selection_changed (GtkTreeSelection *selection,
- gpointer data);
-
+static void gtk_entry_completion_list_activated (GtkListView *listview,
+ guint position,
+ gpointer user_data);
static gboolean gtk_entry_completion_match_selected (GtkEntryCompletion *completion,
- GtkTreeModel *model,
- GtkTreeIter *iter);
+ guint position);
static gboolean gtk_entry_completion_real_insert_prefix (GtkEntryCompletion *completion,
- const gchar *prefix);
+ const char *prefix);
static gboolean gtk_entry_completion_cursor_on_match (GtkEntryCompletion *completion,
- GtkTreeModel *model,
- GtkTreeIter *iter);
+ guint position);
static gboolean gtk_entry_completion_insert_completion (GtkEntryCompletion *completion,
- GtkTreeModel *model,
- GtkTreeIter *iter);
-static void gtk_entry_completion_insert_completion_text (GtkEntryCompletion *completion,
- const gchar *text);
+ guint position);
static void connect_completion_signals (GtkEntryCompletion *completion);
static void disconnect_completion_signals (GtkEntryCompletion *completion);
@@ -166,11 +141,12 @@ static GParamSpec *entry_completion_props[NUM_PROPERTIES] = { NULL, };
static guint entry_completion_signals[LAST_SIGNAL] = { 0 };
/* GtkBuildable */
-static void gtk_entry_completion_buildable_init (GtkBuildableIface *iface);
+static void
+gtk_entry_completion_buildable_init (GtkBuildableIface *iface)
+{
+}
G_DEFINE_TYPE_WITH_CODE (GtkEntryCompletion, gtk_entry_completion, G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (GTK_TYPE_CELL_LAYOUT,
- gtk_entry_completion_cell_layout_init)
G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
gtk_entry_completion_buildable_init))
@@ -222,16 +198,11 @@ gtk_entry_completion_class_init (GtkEntryCompletionClass *klass)
/**
* GtkEntryCompletion::match-selected:
* @widget: the object which received the signal
- * @model: the #GtkTreeModel containing the matches
- * @iter: a #GtkTreeIter positioned at the selected match
+ * @selected: the position of the selected item
*
* Gets emitted when a match from the list is selected.
* The default behaviour is to replace the contents of the
- * entry with the contents of the text column in the row
- * pointed to by @iter.
- *
- * Note that @model is the model that was passed to
- * gtk_entry_completion_set_model().
+ * entry with the contents of the selected item.
*
* Returns: %TRUE if the signal has been handled
*/
@@ -241,25 +212,20 @@ gtk_entry_completion_class_init (GtkEntryCompletionClass *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);
+ _gtk_marshal_BOOLEAN__UINT,
+ G_TYPE_BOOLEAN, 1,
+ G_TYPE_UINT);
/**
* GtkEntryCompletion::cursor-on-match:
* @widget: the object which received the signal
- * @model: the #GtkTreeModel containing the matches
- * @iter: a #GtkTreeIter positioned at the selected match
+ * @selected: the position of the selected item
*
* Gets emitted when a match from the cursor is on a match
* of the list. The default behaviour is to replace the contents
* of the entry with the contents of the text column in the row
* pointed to by @iter.
*
- * Note that @model is the model that was passed to
- * gtk_entry_completion_set_model().
- *
* Returns: %TRUE if the signal has been handled
*/
entry_completion_signals[CURSOR_ON_MATCH] =
@@ -268,10 +234,9 @@ gtk_entry_completion_class_init (GtkEntryCompletionClass *klass)
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkEntryCompletionClass, cursor_on_match),
_gtk_boolean_handled_accumulator, NULL,
- _gtk_marshal_BOOLEAN__OBJECT_BOXED,
- G_TYPE_BOOLEAN, 2,
- GTK_TYPE_TREE_MODEL,
- GTK_TYPE_TREE_ITER);
+ _gtk_marshal_BOOLEAN__UINT,
+ G_TYPE_BOOLEAN, 1,
+ G_TYPE_UINT);
/**
* GtkEntryCompletion::no-matches:
@@ -291,13 +256,43 @@ gtk_entry_completion_class_init (GtkEntryCompletionClass *klass)
NULL,
G_TYPE_NONE, 0);
+ /**
+ * GtkEntryCompletion:model:
+ *
+ * Model for the displayed list items.
+ */
entry_completion_props[PROP_MODEL] =
g_param_spec_object ("model",
P_("Completion Model"),
P_("The model to find matches in"),
- GTK_TYPE_TREE_MODEL,
+ G_TYPE_LIST_MODEL,
GTK_PARAM_READWRITE);
+ /**
+ * GtkEntryCompletion:factory:
+ *
+ * Factory for populating list items.
+ */
+ entry_completion_props[PROP_FACTORY] =
+ g_param_spec_object ("factory",
+ P_("Factory"),
+ P_("The factory for populating list items"),
+ GTK_TYPE_LIST_ITEM_FACTORY,
+ GTK_PARAM_READWRITE);
+
+ /**
+ * GtkEntryCompletion:expression: (type GtkExpression)
+ *
+ * An expression to evaluate to obtain strings to match against the text
+ * of the entry. If #GtkEntryCompletion:factory is not set, the expression
+ * is also used to bind strings to labels produced by a default factory.
+ */
+ entry_completion_props[PROP_EXPRESSION] =
+ gtk_param_spec_expression ("expression",
+ P_("Expression to use"),
+ P_("Expression to evaluate to get strings"),
+ GTK_PARAM_READWRITE);
+
entry_completion_props[PROP_MINIMUM_KEY_LENGTH] =
g_param_spec_int ("minimum-key-length",
P_("Minimum Key Length"),
@@ -306,25 +301,12 @@ gtk_entry_completion_class_init (GtkEntryCompletionClass *klass)
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
/**
- * GtkEntryCompletion:text-column:
- *
- * The column of the model containing the strings.
- * Note that the strings must be UTF-8.
- */
- entry_completion_props[PROP_TEXT_COLUMN] =
- g_param_spec_int ("text-column",
- P_("Text column"),
- P_("The column of the model containing the strings."),
- -1, G_MAXINT, -1,
- GTK_PARAM_READWRITE);
-
- /**
* GtkEntryCompletion:inline-completion:
*
* Determines whether the common prefix of the possible completions
* should be inserted automatically in the entry. Note that this
- * requires text-column to be set, even if you are using a custom
- * match function.
+ * requires #GtkEntryCompletion:expression to be set, even if you
+ * are using a custom match function.
**/
entry_completion_props[PROP_INLINE_COMPLETION] =
g_param_spec_boolean ("inline-completion",
@@ -387,56 +369,58 @@ gtk_entry_completion_class_init (GtkEntryCompletionClass *klass)
FALSE,
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
- /**
- * GtkEntryCompletion:cell-area:
- *
- * The #GtkCellArea used to layout cell renderers in the treeview column.
- *
- * If no area is specified when creating the entry completion with
- * gtk_entry_completion_new_with_area() a horizontally oriented
- * #GtkCellAreaBox will be used.
- */
- entry_completion_props[PROP_CELL_AREA] =
- g_param_spec_object ("cell-area",
- P_("Cell Area"),
- P_("The GtkCellArea used to layout cells"),
- GTK_TYPE_CELL_AREA,
- GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
-
g_object_class_install_properties (object_class, NUM_PROPERTIES, entry_completion_props);
}
-
static void
-gtk_entry_completion_buildable_custom_tag_end (GtkBuildable *buildable,
- GtkBuilder *builder,
- GObject *child,
- const gchar *tagname,
- gpointer data)
+setup_item (GtkSignalListItemFactory *factory,
+ GtkListItem *item)
{
- /* Just ignore the boolean return from here */
- _gtk_cell_layout_buildable_custom_tag_end (buildable, builder, child, tagname, data);
-}
+ GtkWidget *label;
-static void
-gtk_entry_completion_buildable_init (GtkBuildableIface *iface)
-{
- iface->add_child = _gtk_cell_layout_buildable_add_child;
- iface->custom_tag_start = _gtk_cell_layout_buildable_custom_tag_start;
- iface->custom_tag_end = gtk_entry_completion_buildable_custom_tag_end;
+ label = gtk_label_new ("");
+ gtk_label_set_xalign (GTK_LABEL (label), 0);
+ gtk_list_item_set_child (item, label);
}
static void
-gtk_entry_completion_cell_layout_init (GtkCellLayoutIface *iface)
+bind_item (GtkSignalListItemFactory *factory,
+ GtkListItem *item,
+ GtkEntryCompletion *completion)
{
- iface->get_area = gtk_entry_completion_get_area;
+ GtkWidget *label;
+ gpointer obj;
+ GValue value = G_VALUE_INIT;
+
+ label = gtk_list_item_get_child (item);
+ obj = gtk_list_item_get_item (item);
+
+ if (completion->expression &&
+ gtk_expression_evaluate (completion->expression, obj, &value))
+ {
+ gtk_label_set_label (GTK_LABEL (label), g_value_get_string (&value));
+ g_value_unset (&value);
+ }
+ else if (GTK_IS_STRING_OBJECT (obj))
+ {
+ const char *string;
+
+ string = gtk_string_object_get_string (GTK_STRING_OBJECT (obj));
+ gtk_label_set_label (GTK_LABEL (label), string);
+ }
+ else
+ {
+ g_critical ("Either GtkEntryCompletion:factory or GtkEntryCompletion:expression must be set");
+ }
}
static void
gtk_entry_completion_init (GtkEntryCompletion *completion)
{
+ GListModel *model;
+ GtkFilter *filter;
+
completion->minimum_key_length = 1;
- completion->text_column = -1;
completion->has_completion = FALSE;
completion->inline_completion = FALSE;
completion->popup_completion = TRUE;
@@ -444,7 +428,21 @@ gtk_entry_completion_init (GtkEntryCompletion *completion)
completion->popup_single_match = TRUE;
completion->inline_selection = FALSE;
- completion->filter_model = NULL;
+ completion->expression = gtk_property_expression_new (GTK_TYPE_STRING_OBJECT, NULL, "string");
+
+ filter = gtk_string_filter_new ();
+ gtk_string_filter_set_expression (GTK_STRING_FILTER (filter), completion->expression);
+ gtk_string_filter_set_match_mode (GTK_STRING_FILTER (filter), GTK_STRING_FILTER_MATCH_MODE_PREFIX);
+ gtk_string_filter_set_ignore_case (GTK_STRING_FILTER (filter), TRUE);
+
+ model = G_LIST_MODEL (gtk_string_list_new ((const char *[]){ NULL }));
+ completion->filter_model = G_LIST_MODEL (gtk_filter_list_model_new (model, filter));
+ g_object_unref (model);
+ g_object_unref (filter);
+
+ completion->factory = gtk_signal_list_item_factory_new ();
+ g_signal_connect (completion->factory, "setup", G_CALLBACK (setup_item), NULL);
+ g_signal_connect (completion->factory, "bind", G_CALLBACK (bind_item), completion);
}
static gboolean
@@ -462,49 +460,32 @@ propagate_to_entry (GtkEventControllerKey *key,
static void
gtk_entry_completion_constructed (GObject *object)
{
- GtkEntryCompletion *completion = GTK_ENTRY_COMPLETION (object);
- GtkTreeSelection *sel;
- GtkWidget *popup_frame;
- GtkEventController *controller;
+ GtkEntryCompletion *completion = GTK_ENTRY_COMPLETION (object);
+ GtkEventController *controller;
+ GListModel *selection;
G_OBJECT_CLASS (gtk_entry_completion_parent_class)->constructed (object);
- if (!completion->cell_area)
- {
- completion->cell_area = gtk_cell_area_box_new ();
- g_object_ref_sink (completion->cell_area);
- }
+ completion->list_view = gtk_list_view_new ();
+ gtk_list_view_set_single_click_activate (GTK_LIST_VIEW (completion->list_view), TRUE);
+ selection = G_LIST_MODEL (gtk_single_selection_new (completion->filter_model));
+ gtk_single_selection_set_autoselect (GTK_SINGLE_SELECTION (selection), FALSE);
+ gtk_single_selection_set_can_unselect (GTK_SINGLE_SELECTION (selection), TRUE);
+ gtk_list_view_set_model (GTK_LIST_VIEW (completion->list_view), selection);
+ g_object_unref (selection);
- /* completions */
- completion->tree_view = gtk_tree_view_new ();
- g_signal_connect (completion->tree_view, "row-activated",
- G_CALLBACK (gtk_entry_completion_list_activated),
- completion);
+ gtk_list_view_set_factory (GTK_LIST_VIEW (completion->list_view), completion->factory);
- gtk_tree_view_set_enable_search (GTK_TREE_VIEW (completion->tree_view), FALSE);
- gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (completion->tree_view), FALSE);
- gtk_tree_view_set_hover_selection (GTK_TREE_VIEW (completion->tree_view), TRUE);
- gtk_tree_view_set_activate_on_single_click (GTK_TREE_VIEW (completion->tree_view), TRUE);
-
- sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (completion->tree_view));
- gtk_tree_selection_set_mode (sel, GTK_SELECTION_SINGLE);
- gtk_tree_selection_unselect_all (sel);
- g_signal_connect (sel, "changed",
- G_CALLBACK (gtk_entry_completion_selection_changed),
+ g_signal_connect (completion->list_view, "activate",
+ G_CALLBACK (gtk_entry_completion_list_activated),
completion);
- completion->first_sel_changed = TRUE;
-
- completion->column = gtk_tree_view_column_new_with_area (completion->cell_area);
- gtk_tree_view_append_column (GTK_TREE_VIEW (completion->tree_view), completion->column);
completion->scrolled_window = gtk_scrolled_window_new ();
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (completion->scrolled_window),
GTK_POLICY_NEVER,
GTK_POLICY_AUTOMATIC);
-
- /* a nasty hack to get the completions treeview to size nicely */
- gtk_widget_set_size_request (gtk_scrolled_window_get_vscrollbar (GTK_SCROLLED_WINDOW (completion->scrolled_window)),
- -1, 0);
+ gtk_scrolled_window_set_max_content_height (GTK_SCROLLED_WINDOW (completion->scrolled_window), 400);
+ gtk_scrolled_window_set_propagate_natural_height (GTK_SCROLLED_WINDOW (completion->scrolled_window), TRUE);
/* pack it all */
completion->popup_window = gtk_popover_new ();
@@ -522,21 +503,18 @@ gtk_entry_completion_constructed (GObject *object)
controller = GTK_EVENT_CONTROLLER (gtk_gesture_click_new ());
g_signal_connect_swapped (controller, "released",
- G_CALLBACK (_gtk_entry_completion_popdown),
+ G_CALLBACK (gtk_entry_completion_popdown),
completion);
gtk_widget_add_controller (completion->popup_window, controller);
- popup_frame = gtk_frame_new (NULL);
- gtk_popover_set_child (GTK_POPOVER (completion->popup_window), popup_frame);
-
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (completion->scrolled_window),
- completion->tree_view);
+ completion->list_view);
gtk_widget_set_hexpand (completion->scrolled_window, TRUE);
gtk_widget_set_vexpand (completion->scrolled_window, TRUE);
- gtk_frame_set_child (GTK_FRAME (popup_frame), completion->scrolled_window);
+ gtk_popover_set_child (GTK_POPOVER (completion->popup_window),
+ completion->scrolled_window);
}
-
static void
gtk_entry_completion_set_property (GObject *object,
guint prop_id,
@@ -544,7 +522,6 @@ gtk_entry_completion_set_property (GObject *object,
GParamSpec *pspec)
{
GtkEntryCompletion *completion = GTK_ENTRY_COMPLETION (object);
- GtkCellArea *area;
switch (prop_id)
{
@@ -553,54 +530,44 @@ gtk_entry_completion_set_property (GObject *object,
g_value_get_object (value));
break;
+ case PROP_FACTORY:
+ gtk_entry_completion_set_factory (completion,
+ g_value_get_object (value));
+ break;
+
+ case PROP_EXPRESSION:
+ gtk_entry_completion_set_expression (completion,
+ gtk_value_get_expression (value));
+ break;
+
case PROP_MINIMUM_KEY_LENGTH:
gtk_entry_completion_set_minimum_key_length (completion,
g_value_get_int (value));
break;
- case PROP_TEXT_COLUMN:
- completion->text_column = g_value_get_int (value);
- break;
-
case PROP_INLINE_COMPLETION:
- gtk_entry_completion_set_inline_completion (completion,
- g_value_get_boolean (value));
+ gtk_entry_completion_set_inline_completion (completion,
+ g_value_get_boolean (value));
break;
case PROP_POPUP_COMPLETION:
- gtk_entry_completion_set_popup_completion (completion,
- g_value_get_boolean (value));
+ gtk_entry_completion_set_popup_completion (completion,
+ g_value_get_boolean (value));
break;
case PROP_POPUP_SET_WIDTH:
- gtk_entry_completion_set_popup_set_width (completion,
- g_value_get_boolean (value));
+ gtk_entry_completion_set_popup_set_width (completion,
+ g_value_get_boolean (value));
break;
case PROP_POPUP_SINGLE_MATCH:
- gtk_entry_completion_set_popup_single_match (completion,
- g_value_get_boolean (value));
+ gtk_entry_completion_set_popup_single_match (completion,
+ g_value_get_boolean (value));
break;
case PROP_INLINE_SELECTION:
- gtk_entry_completion_set_inline_selection (completion,
- g_value_get_boolean (value));
- break;
-
- case PROP_CELL_AREA:
- /* Construct-only, can only be assigned once */
- area = g_value_get_object (value);
- if (area)
- {
- if (completion->cell_area != NULL)
- {
- g_warning ("cell-area has already been set, ignoring construct property");
- g_object_ref_sink (area);
- g_object_unref (area);
- }
- else
- completion->cell_area = g_object_ref_sink (area);
- }
+ gtk_entry_completion_set_inline_selection (completion,
+ g_value_get_boolean (value));
break;
default:
@@ -620,16 +587,19 @@ gtk_entry_completion_get_property (GObject *object,
switch (prop_id)
{
case PROP_MODEL:
- g_value_set_object (value,
- gtk_entry_completion_get_model (completion));
+ 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));
+ case PROP_FACTORY:
+ g_value_set_object (value, gtk_entry_completion_get_factory (completion));
break;
- case PROP_TEXT_COLUMN:
- g_value_set_int (value, gtk_entry_completion_get_text_column (completion));
+ case PROP_EXPRESSION:
+ gtk_value_set_expression (value, gtk_entry_completion_get_expression (completion));
+ break;
+
+ case PROP_MINIMUM_KEY_LENGTH:
+ g_value_set_int (value, gtk_entry_completion_get_minimum_key_length (completion));
break;
case PROP_INLINE_COMPLETION:
@@ -652,10 +622,6 @@ gtk_entry_completion_get_property (GObject *object,
g_value_set_boolean (value, gtk_entry_completion_get_inline_selection (completion));
break;
- case PROP_CELL_AREA:
- g_value_set_object (value, completion->cell_area);
- break;
-
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -670,9 +636,6 @@ gtk_entry_completion_finalize (GObject *object)
g_free (completion->case_normalized_key);
g_free (completion->completion_prefix);
- if (completion->match_notify)
- (* completion->match_notify) (completion->match_data);
-
G_OBJECT_CLASS (gtk_entry_completion_parent_class)->finalize (object);
}
@@ -684,135 +647,30 @@ gtk_entry_completion_dispose (GObject *object)
if (completion->entry)
gtk_entry_set_completion (GTK_ENTRY (completion->entry), NULL);
- g_clear_object (&completion->cell_area);
+ g_clear_object (&completion->filter_model);
+ g_clear_object (&completion->expression);
+ g_clear_object (&completion->factory);
G_OBJECT_CLASS (gtk_entry_completion_parent_class)->dispose (object);
}
-/* implement cell layout interface (only need to return the underlying cell area) */
-static GtkCellArea*
-gtk_entry_completion_get_area (GtkCellLayout *cell_layout)
-{
- GtkEntryCompletion *completion = GTK_ENTRY_COMPLETION (cell_layout);
-
- if (G_UNLIKELY (!completion->cell_area))
- {
- completion->cell_area = gtk_cell_area_box_new ();
- g_object_ref_sink (completion->cell_area);
- }
-
- return completion->cell_area;
-}
-
/* 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->filter_model);
-
- g_return_val_if_fail (gtk_tree_model_get_column_type (model, completion->text_column) == G_TYPE_STRING,
- FALSE);
-
- gtk_tree_model_get (model, iter,
- completion->text_column, &item,
- -1);
-
- if (item != NULL)
- {
- normalized_string = g_utf8_normalize (item, -1, G_NORMALIZE_ALL);
-
- if (normalized_string != NULL)
- {
- case_normalized_string = g_utf8_casefold (normalized_string, -1);
-
- if (!strncmp (key, case_normalized_string, strlen (key)))
- ret = TRUE;
-
- g_free (case_normalized_string);
- }
- g_free (normalized_string);
- }
- g_free (item);
-
- 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->case_normalized_key)
- return ret;
-
- if (completion->match_func)
- ret = (* completion->match_func) (completion,
- completion->case_normalized_key,
- iter,
- completion->match_data);
- else if (completion->text_column >= 0)
- ret = gtk_entry_completion_default_completion_func (completion,
- completion->case_normalized_key,
- iter,
- NULL);
-
- return ret;
-}
static void
-gtk_entry_completion_list_activated (GtkTreeView *treeview,
- GtkTreePath *path,
- GtkTreeViewColumn *column,
- gpointer user_data)
+gtk_entry_completion_list_activated (GtkListView *listview,
+ guint position,
+ gpointer user_data)
{
GtkEntryCompletion *completion = GTK_ENTRY_COMPLETION (user_data);
- GtkTreeIter iter;
gboolean entry_set;
- GtkTreeModel *model;
- GtkTreeIter child_iter;
GtkText *text = gtk_entry_get_text_widget (GTK_ENTRY (completion->entry));
- gtk_tree_model_get_iter (GTK_TREE_MODEL (completion->filter_model), &iter, path);
- gtk_tree_model_filter_convert_iter_to_child_iter (completion->filter_model,
- &child_iter,
- &iter);
- model = gtk_tree_model_filter_get_model (completion->filter_model);
-
g_signal_handler_block (text, completion->changed_id);
g_signal_emit (completion, entry_completion_signals[MATCH_SELECTED],
- 0, model, &child_iter, &entry_set);
+ 0, position, &entry_set);
g_signal_handler_unblock (text, completion->changed_id);
- _gtk_entry_completion_popdown (completion);
-}
-
-static void
-gtk_entry_completion_selection_changed (GtkTreeSelection *selection,
- gpointer data)
-{
- GtkEntryCompletion *completion = GTK_ENTRY_COMPLETION (data);
-
- if (completion->first_sel_changed)
- {
- completion->first_sel_changed = FALSE;
- if (gtk_widget_is_focus (completion->tree_view))
- gtk_tree_selection_unselect_all (selection);
- }
+ gtk_entry_completion_popdown (completion);
}
/* public API */
@@ -835,26 +693,6 @@ gtk_entry_completion_new (void)
}
/**
- * gtk_entry_completion_new_with_area:
- * @area: the #GtkCellArea used to layout cells
- *
- * Creates a new #GtkEntryCompletion object using the
- * specified @area to layout cells in the underlying
- * #GtkTreeViewColumn for the drop-down menu.
- *
- * Returns: A newly created #GtkEntryCompletion object
- */
-GtkEntryCompletion *
-gtk_entry_completion_new_with_area (GtkCellArea *area)
-{
- GtkEntryCompletion *completion;
-
- completion = g_object_new (GTK_TYPE_ENTRY_COMPLETION, "cell-area", area, NULL);
-
- return completion;
-}
-
-/**
* gtk_entry_completion_get_entry:
* @completion: a #GtkEntryCompletion
*
@@ -873,7 +711,7 @@ gtk_entry_completion_get_entry (GtkEntryCompletion *completion)
/**
* gtk_entry_completion_set_model:
* @completion: a #GtkEntryCompletion
- * @model: (allow-none): the #GtkTreeModel
+ * @model: (allow-none): the #GListModel
*
* Sets the model for a #GtkEntryCompletion. If @completion already has
* a model set, it will remove it before setting the new model.
@@ -881,36 +719,23 @@ gtk_entry_completion_get_entry (GtkEntryCompletion *completion)
*/
void
gtk_entry_completion_set_model (GtkEntryCompletion *completion,
- GtkTreeModel *model)
+ GListModel *model)
{
g_return_if_fail (GTK_IS_ENTRY_COMPLETION (completion));
- g_return_if_fail (model == NULL || GTK_IS_TREE_MODEL (model));
+ g_return_if_fail (model == NULL || G_IS_LIST_MODEL (model));
+
+ gtk_filter_list_model_set_model (GTK_FILTER_LIST_MODEL (completion->filter_model), model);
if (!model)
{
- gtk_tree_view_set_model (GTK_TREE_VIEW (completion->tree_view),
- NULL);
- _gtk_entry_completion_popdown (completion);
- completion->filter_model = NULL;
+ gtk_entry_completion_popdown (completion);
return;
}
- /* code will unref the old filter model (if any) */
- completion->filter_model =
- GTK_TREE_MODEL_FILTER (gtk_tree_model_filter_new (model, NULL));
- gtk_tree_model_filter_set_visible_func (completion->filter_model,
- gtk_entry_completion_visible_func,
- completion,
- NULL);
-
- gtk_tree_view_set_model (GTK_TREE_VIEW (completion->tree_view),
- GTK_TREE_MODEL (completion->filter_model));
- g_object_unref (completion->filter_model);
-
g_object_notify_by_pspec (G_OBJECT (completion), entry_completion_props[PROP_MODEL]);
if (gtk_widget_get_visible (completion->popup_window))
- _gtk_entry_completion_resize_popup (completion);
+ gtk_entry_completion_resize_popup (completion);
}
/**
@@ -920,45 +745,103 @@ gtk_entry_completion_set_model (GtkEntryCompletion *completion,
* Returns the model the #GtkEntryCompletion is using as data source.
* Returns %NULL if the model is unset.
*
- * Returns: (nullable) (transfer none): A #GtkTreeModel, or %NULL if none
+ * Returns: (nullable) (transfer none): A #GListModel, or %NULL if none
* is currently being used
*/
-GtkTreeModel *
+GListModel *
gtk_entry_completion_get_model (GtkEntryCompletion *completion)
{
g_return_val_if_fail (GTK_IS_ENTRY_COMPLETION (completion), NULL);
- if (!completion->filter_model)
- return NULL;
+ return gtk_filter_list_model_get_model (GTK_FILTER_LIST_MODEL (completion->filter_model));
+}
+
+/**
+ * gtk_entry_completion_set_expression:
+ * @completion: a #GtkEntryCompletion
+ * @expression: (nullable): a #GtkExpression, or %NULL
+ *
+ * Sets the expression that gets evaluated to obtain strings from items
+ * when finding completions. The expression must have a value type of
+ * #GTK_TYPE_STRING.
+ */
+void
+gtk_entry_completion_set_expression (GtkEntryCompletion *completion,
+ GtkExpression *expression)
+{
+ GtkFilter *filter;
+
+ g_return_if_fail (GTK_IS_ENTRY_COMPLETION (completion));
+ g_return_if_fail (expression == NULL || GTK_IS_EXPRESSION (expression));
+
+ if (completion->expression)
+ gtk_expression_unref (completion->expression);
+
+ completion->expression = expression;
+
+ if (completion->expression)
+ gtk_expression_ref (completion->expression);
+
+ filter = gtk_filter_list_model_get_filter (GTK_FILTER_LIST_MODEL (completion->filter_model));
+ gtk_string_filter_set_expression (GTK_STRING_FILTER (filter), completion->expression);
- return gtk_tree_model_filter_get_model (completion->filter_model);
+ g_object_notify_by_pspec (G_OBJECT (completion), entry_completion_props[PROP_EXPRESSION]);
}
/**
- * gtk_entry_completion_set_match_func:
+ * gtk_entry_completion_get_expression:
* @completion: a #GtkEntryCompletion
- * @func: the #GtkEntryCompletionMatchFunc to use
- * @func_data: user data for @func
- * @func_notify: destroy notify for @func_data.
*
- * Sets the match function for @completion to be @func. The match function
- * is used to determine if a row should or should not be in the completion
- * list.
+ * Gets the expression set with gtk_entry_completion_set_expression().
+ *
+ * Returns: (nullable) (transfer none): a #GtkExpression or %NULL
*/
+GtkExpression *
+gtk_entry_completion_get_expression (GtkEntryCompletion *completion)
+{
+ g_return_val_if_fail (GTK_IS_ENTRY_COMPLETION (completion), NULL);
+
+ return completion->expression;
+}
+
+/**
+ * gtk_entry_completion_set_factory:
+ * @completion: a #GtkEntryCompletion
+ * @factory: (allow-none) (transfer none): the factory to use or %NULL for none
+ *
+ * Sets the #GtkListItemFactory to use for populating list items.
+ **/
void
-gtk_entry_completion_set_match_func (GtkEntryCompletion *completion,
- GtkEntryCompletionMatchFunc func,
- gpointer func_data,
- GDestroyNotify func_notify)
+gtk_entry_completion_set_factory (GtkEntryCompletion *completion,
+ GtkListItemFactory *factory)
{
g_return_if_fail (GTK_IS_ENTRY_COMPLETION (completion));
+ g_return_if_fail (factory == NULL || GTK_IS_LIST_ITEM_FACTORY (factory));
+
+ if (!g_set_object (&completion->factory, factory))
+ return;
- if (completion->match_notify)
- (* completion->match_notify) (completion->match_data);
+ if (completion->list_view)
+ gtk_list_view_set_factory (GTK_LIST_VIEW (completion->list_view), factory);
- completion->match_func = func;
- completion->match_data = func_data;
- completion->match_notify = func_notify;
+ g_object_notify_by_pspec (G_OBJECT (completion), entry_completion_props[PROP_FACTORY]);
+}
+
+/**
+ * gtk_entry_completion_set_factory:
+ * @completion: a #GtkEntryCompletion
+ * @self: a #GtkDropDown
+ *
+ * Gets the factory that's currently used to populate list items in the popup.
+ *
+ * Returns: (nullable) (transfer none): The factory in use
+ **/
+GtkListItemFactory *
+gtk_entry_completion_get_factory (GtkEntryCompletion *completion)
+{
+ g_return_val_if_fail (GTK_IS_ENTRY_COMPLETION (completion), NULL);
+
+ return completion->factory;
}
/**
@@ -1014,148 +897,56 @@ gtk_entry_completion_get_minimum_key_length (GtkEntryCompletion *completion)
void
gtk_entry_completion_complete (GtkEntryCompletion *completion)
{
- gchar *tmp;
- GtkTreeIter iter;
+ GtkFilter *filter;
+ const char *text;
g_return_if_fail (GTK_IS_ENTRY_COMPLETION (completion));
g_return_if_fail (GTK_IS_ENTRY (completion->entry));
- if (!completion->filter_model)
+ filter = gtk_filter_list_model_get_filter (GTK_FILTER_LIST_MODEL (completion->filter_model));
+ if (!filter)
return;
- g_free (completion->case_normalized_key);
-
- tmp = g_utf8_normalize (gtk_editable_get_text (GTK_EDITABLE (completion->entry)),
- -1, G_NORMALIZE_ALL);
- completion->case_normalized_key = g_utf8_casefold (tmp, -1);
- g_free (tmp);
+ text = gtk_editable_get_text (GTK_EDITABLE (completion->entry));
+ gtk_string_filter_set_search (GTK_STRING_FILTER (filter), text);
- gtk_tree_model_filter_refilter (completion->filter_model);
-
- if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (completion->filter_model), &iter))
+ if (g_list_model_get_n_items (completion->filter_model) == 0)
g_signal_emit (completion, entry_completion_signals[NO_MATCHES], 0);
if (gtk_widget_get_visible (completion->popup_window))
- _gtk_entry_completion_resize_popup (completion);
-}
-
-/**
- * gtk_entry_completion_set_text_column:
- * @completion: a #GtkEntryCompletion
- * @column: the column in the model of @completion to get strings from
- *
- * Convenience function for setting up the most used case of this code: a
- * completion list with just strings. This function will set up @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.
- */
-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);
-
- if (completion->text_column == column)
- return;
-
- completion->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);
-
- g_object_notify_by_pspec (G_OBJECT (completion), entry_completion_props[PROP_TEXT_COLUMN]);
-}
-
-/**
- * gtk_entry_completion_get_text_column:
- * @completion: a #GtkEntryCompletion
- *
- * Returns the column in the model of @completion to get strings from.
- *
- * Returns: the column containing the strings
- */
-gint
-gtk_entry_completion_get_text_column (GtkEntryCompletion *completion)
-{
- g_return_val_if_fail (GTK_IS_ENTRY_COMPLETION (completion), -1);
-
- return completion->text_column;
+ gtk_entry_completion_resize_popup (completion);
}
/* private */
/* some nasty size requisition */
void
-_gtk_entry_completion_resize_popup (GtkEntryCompletion *completion)
+gtk_entry_completion_resize_popup (GtkEntryCompletion *completion)
{
GtkAllocation allocation;
- gint matches, items, height;
- GdkSurface *surface;
GtkRequisition entry_req;
- GtkRequisition tree_req;
- GtkTreePath *path;
- gint width;
+ GtkRequisition list_req;
+ int width;
- surface = gtk_native_get_surface (gtk_widget_get_native (completion->entry));
-
- if (!surface)
- return;
-
- if (!completion->filter_model)
+ if (!gtk_native_get_surface (gtk_widget_get_native (completion->entry)))
return;
gtk_widget_get_surface_allocation (completion->entry, &allocation);
- gtk_widget_get_preferred_size (completion->entry,
- &entry_req, NULL);
-
- matches = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (completion->filter_model), NULL);
+ gtk_widget_get_preferred_size (completion->entry, &entry_req, NULL);
/* Call get preferred size on the on the tree view to force it to validate its
* cells before calling into the cell size functions.
*/
- gtk_widget_get_preferred_size (completion->tree_view,
- &tree_req, NULL);
- gtk_tree_view_column_cell_get_size (completion->column,
- NULL, NULL, NULL, &height);
-
- gtk_widget_realize (completion->tree_view);
-
- items = MIN (matches, 10);
-
- if (items <= 0)
- gtk_widget_hide (completion->scrolled_window);
- else
- gtk_widget_show (completion->scrolled_window);
+ gtk_widget_get_preferred_size (completion->list_view, &list_req, NULL);
+ gtk_widget_realize (completion->list_view);
if (completion->popup_set_width)
width = allocation.width;
else
width = -1;
- gtk_tree_view_columns_autosize (GTK_TREE_VIEW (completion->tree_view));
gtk_scrolled_window_set_min_content_width (GTK_SCROLLED_WINDOW (completion->scrolled_window), width);
gtk_widget_set_size_request (completion->popup_window, width, -1);
- gtk_scrolled_window_set_min_content_height (GTK_SCROLLED_WINDOW (completion->scrolled_window), items * height);
-
- if (matches > 0)
- {
- path = gtk_tree_path_new_from_indices (0, -1);
- gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (completion->tree_view), path,
- NULL, FALSE, 0.0, 0.0);
- gtk_tree_path_free (path);
- }
gtk_native_check_resize (GTK_NATIVE (completion->popup_window));
}
@@ -1178,13 +969,13 @@ gtk_entry_completion_popup (GtkEntryCompletion *completion)
gtk_widget_realize (completion->popup_window);
- _gtk_entry_completion_resize_popup (completion);
+ gtk_entry_completion_resize_popup (completion);
gtk_popover_popup (GTK_POPOVER (completion->popup_window));
}
void
-_gtk_entry_completion_popdown (GtkEntryCompletion *completion)
+gtk_entry_completion_popdown (GtkEntryCompletion *completion)
{
if (!gtk_widget_get_mapped (completion->popup_window))
return;
@@ -1193,30 +984,48 @@ _gtk_entry_completion_popdown (GtkEntryCompletion *completion)
}
static gboolean
+gtk_entry_completion_get_text (GtkEntryCompletion *completion,
+ guint position,
+ GValue *value)
+{
+ gpointer item;
+
+ item = g_list_model_get_item (completion->filter_model, position);
+
+ if (completion->expression == NULL ||
+ !gtk_expression_evaluate (completion->expression, item, value))
+ {
+ g_object_unref (item);
+ return FALSE;
+ }
+
+ g_object_unref (item);
+ return TRUE;
+}
+
+static gboolean
gtk_entry_completion_match_selected (GtkEntryCompletion *completion,
- GtkTreeModel *model,
- GtkTreeIter *iter)
+ guint position)
{
- gchar *str = NULL;
+ GValue value = G_VALUE_INIT;
- gtk_tree_model_get (model, iter, completion->text_column, &str, -1);
- gtk_editable_set_text (GTK_EDITABLE (completion->entry), str ? str : "");
+ if (!gtk_entry_completion_get_text (completion, position, &value))
+ return FALSE;
- /* move cursor to the end */
+ gtk_editable_set_text (GTK_EDITABLE (completion->entry),
+ g_value_get_string (&value));
gtk_editable_set_position (GTK_EDITABLE (completion->entry), -1);
- g_free (str);
+ g_value_unset (&value);
return TRUE;
}
static gboolean
gtk_entry_completion_cursor_on_match (GtkEntryCompletion *completion,
- GtkTreeModel *model,
- GtkTreeIter *iter)
+ guint position)
{
- gtk_entry_completion_insert_completion (completion, model, iter);
-
+ gtk_entry_completion_insert_completion (completion, position);
return TRUE;
}
@@ -1228,7 +1037,7 @@ gtk_entry_completion_cursor_on_match (GtkEntryCompletion *completion,
* Computes the common prefix that is shared by all rows in @completion
* that start with @key. If no row matches @key, %NULL will be returned.
* Note that a text column must have been set for this function to work,
- * see gtk_entry_completion_set_text_column() for details.
+ * see gtk_entry_completion_set_text_column() for details.
*
* Returns: (nullable) (transfer full): The common prefix all rows starting with
* @key or %NULL if no row matches @key.
@@ -1237,23 +1046,30 @@ gchar *
gtk_entry_completion_compute_prefix (GtkEntryCompletion *completion,
const char *key)
{
- GtkTreeIter iter;
- gchar *prefix = NULL;
- gboolean valid;
+ char *prefix = NULL;
+ guint i, n;
- if (completion->text_column < 0)
- return NULL;
-
- valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (completion->filter_model),
- &iter);
-
- while (valid)
+ n = g_list_model_get_n_items (completion->filter_model);
+ for (i = 0; i < n; i++)
{
- gchar *text;
+ gpointer item = g_list_model_get_item (completion->filter_model, i);
+ GValue value = G_VALUE_INIT;
+ const char *text;
- gtk_tree_model_get (GTK_TREE_MODEL (completion->filter_model),
- &iter, completion->text_column, &text,
- -1);
+ if (completion->expression &&
+ gtk_expression_evaluate (completion->expression, item, &value))
+ {
+ text = g_value_get_string (&value);
+ }
+ else if (GTK_IS_STRING_OBJECT (item))
+ {
+ text = gtk_string_object_get_string (GTK_STRING_OBJECT (item));
+ }
+ else
+ {
+ g_object_unref (item);
+ continue;
+ }
if (text && g_str_has_prefix (text, key))
{
@@ -1261,8 +1077,8 @@ gtk_entry_completion_compute_prefix (GtkEntryCompletion *completion,
prefix = g_strdup (text);
else
{
- gchar *p = prefix;
- gchar *q = text;
+ char *p = prefix;
+ char *q = (char *)text;
while (*p && *p == *q)
{
@@ -1288,9 +1104,8 @@ gtk_entry_completion_compute_prefix (GtkEntryCompletion *completion,
}
}
- g_free (text);
- valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (completion->filter_model),
- &iter);
+ g_value_unset (&value);
+ g_object_unref (item);
}
return prefix;
@@ -1299,13 +1114,13 @@ gtk_entry_completion_compute_prefix (GtkEntryCompletion *completion,
static gboolean
gtk_entry_completion_real_insert_prefix (GtkEntryCompletion *completion,
- const gchar *prefix)
+ const char *prefix)
{
if (prefix)
{
gint key_len;
gint prefix_len;
- const gchar *key;
+ const char *key;
prefix_len = g_utf8_strlen (prefix, -1);
@@ -1345,21 +1160,25 @@ gtk_entry_completion_get_completion_prefix (GtkEntryCompletion *completion)
return completion->completion_prefix;
}
-static void
-gtk_entry_completion_insert_completion_text (GtkEntryCompletion *completion,
- const gchar *new_text)
+static gboolean
+gtk_entry_completion_insert_completion (GtkEntryCompletion *completion,
+ guint position)
{
- gint len;
+ GValue value = G_VALUE_INIT;
+ int len;
GtkText *text = gtk_entry_get_text_widget (GTK_ENTRY (completion->entry));
GtkEntryBuffer *buffer = gtk_text_get_buffer (text);
+ if (!gtk_entry_completion_get_text (completion, position, &value))
+ return FALSE;
+
if (completion->changed_id > 0)
g_signal_handler_block (text, completion->changed_id);
if (completion->insert_text_id > 0)
g_signal_handler_block (buffer, completion->insert_text_id);
- gtk_editable_set_text (GTK_EDITABLE (completion->entry), new_text);
+ gtk_editable_set_text (GTK_EDITABLE (completion->entry), g_value_get_string (&value));
len = g_utf8_strlen (completion->completion_prefix, -1);
gtk_editable_select_region (GTK_EDITABLE (completion->entry), len, -1);
@@ -1369,25 +1188,8 @@ gtk_entry_completion_insert_completion_text (GtkEntryCompletion *completion,
if (completion->insert_text_id > 0)
g_signal_handler_unblock (buffer, completion->insert_text_id);
-}
-
-static gboolean
-gtk_entry_completion_insert_completion (GtkEntryCompletion *completion,
- GtkTreeModel *model,
- GtkTreeIter *iter)
-{
- gchar *str = NULL;
-
- if (completion->text_column < 0)
- return FALSE;
- gtk_tree_model_get (model, iter,
- completion->text_column, &str,
- -1);
-
- gtk_entry_completion_insert_completion_text (completion, str);
-
- g_free (str);
+ g_value_unset (&value);
return TRUE;
}
@@ -1437,14 +1239,12 @@ gtk_entry_completion_set_inline_completion (GtkEntryCompletion *completion,
{
g_return_if_fail (GTK_IS_ENTRY_COMPLETION (completion));
- inline_completion = inline_completion != FALSE;
+ if (completion->inline_completion == inline_completion)
+ return;
- if (completion->inline_completion != inline_completion)
- {
- completion->inline_completion = inline_completion;
+ completion->inline_completion = inline_completion;
- g_object_notify_by_pspec (G_OBJECT (completion), entry_completion_props[PROP_INLINE_COMPLETION]);
- }
+ g_object_notify_by_pspec (G_OBJECT (completion), entry_completion_props[PROP_INLINE_COMPLETION]);
}
/**
@@ -1477,14 +1277,12 @@ gtk_entry_completion_set_popup_completion (GtkEntryCompletion *completion,
{
g_return_if_fail (GTK_IS_ENTRY_COMPLETION (completion));
- popup_completion = popup_completion != FALSE;
+ if (completion->popup_completion == popup_completion)
+ return;
- if (completion->popup_completion != popup_completion)
- {
- completion->popup_completion = popup_completion;
+ completion->popup_completion = popup_completion;
- g_object_notify_by_pspec (G_OBJECT (completion), entry_completion_props[PROP_POPUP_COMPLETION]);
- }
+ g_object_notify_by_pspec (G_OBJECT (completion), entry_completion_props[PROP_POPUP_COMPLETION]);
}
@@ -1563,14 +1361,12 @@ gtk_entry_completion_set_popup_single_match (GtkEntryCompletion *completion,
{
g_return_if_fail (GTK_IS_ENTRY_COMPLETION (completion));
- popup_single_match = popup_single_match != FALSE;
+ if (completion->popup_single_match == popup_single_match)
+ return;
- if (completion->popup_single_match != popup_single_match)
- {
- completion->popup_single_match = popup_single_match;
+ completion->popup_single_match = popup_single_match;
- g_object_notify_by_pspec (G_OBJECT (completion), entry_completion_props[PROP_POPUP_SINGLE_MATCH]);
- }
+ g_object_notify_by_pspec (G_OBJECT (completion), entry_completion_props[PROP_POPUP_SINGLE_MATCH]);
}
/**
@@ -1605,14 +1401,12 @@ gtk_entry_completion_set_inline_selection (GtkEntryCompletion *completion,
{
g_return_if_fail (GTK_IS_ENTRY_COMPLETION (completion));
- inline_selection = inline_selection != FALSE;
+ if (completion->inline_selection == inline_selection)
+ return;
- if (completion->inline_selection != inline_selection)
- {
- completion->inline_selection = inline_selection;
+ completion->inline_selection = inline_selection;
- g_object_notify_by_pspec (G_OBJECT (completion), entry_completion_props[PROP_INLINE_SELECTION]);
- }
+ g_object_notify_by_pspec (G_OBJECT (completion), entry_completion_props[PROP_INLINE_SELECTION]);
}
/**
@@ -1636,33 +1430,35 @@ static gint
gtk_entry_completion_timeout (gpointer data)
{
GtkEntryCompletion *completion = GTK_ENTRY_COMPLETION (data);
+ const char *text;
completion->completion_timeout = 0;
+ text = gtk_editable_get_text (GTK_EDITABLE (completion->entry));
if (completion->filter_model &&
- g_utf8_strlen (gtk_editable_get_text (GTK_EDITABLE (completion->entry)), -1)
- >= completion->minimum_key_length)
+ g_utf8_strlen (text, -1) >= completion->minimum_key_length)
{
- gint matches;
+ int matches;
gboolean popup_single;
gtk_entry_completion_complete (completion);
- matches = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (completion->filter_model), NULL);
- gtk_tree_selection_unselect_all (gtk_tree_view_get_selection (GTK_TREE_VIEW (completion->tree_view)));
+ matches = g_list_model_get_n_items (completion->filter_model);
+ gtk_selection_model_unselect_all (GTK_SELECTION_MODEL (gtk_list_view_get_model (GTK_LIST_VIEW (completion->list_view))));
g_object_get (completion, "popup-single-match", &popup_single, NULL);
- if (matches > (popup_single ? 0: 1))
+ if ((completion->popup_single_match && matches > 0) || matches > 1)
{
if (gtk_widget_get_visible (completion->popup_window))
- _gtk_entry_completion_resize_popup (completion);
+ gtk_entry_completion_resize_popup (completion);
else
gtk_entry_completion_popup (completion);
}
else
- _gtk_entry_completion_popdown (completion);
+ gtk_entry_completion_popdown (completion);
}
else if (gtk_widget_get_visible (completion->popup_window))
- _gtk_entry_completion_popdown (completion);
+ gtk_entry_completion_popdown (completion);
+
return G_SOURCE_REMOVE;
}
@@ -1691,10 +1487,9 @@ gtk_entry_completion_key_pressed (GtkEventControllerKey *controller,
GdkModifierType state,
gpointer user_data)
{
- gint matches;
GtkEntryCompletion *completion = GTK_ENTRY_COMPLETION (user_data);
GtkWidget *widget = completion->entry;
- GtkText *text = gtk_entry_get_text_widget (GTK_ENTRY (widget));
+ int matches;
if (!completion->popup_completion)
return FALSE;
@@ -1714,12 +1509,10 @@ gtk_entry_completion_key_pressed (GtkEventControllerKey *controller,
if (!gtk_widget_get_mapped (completion->popup_window))
return FALSE;
- matches = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (completion->filter_model), NULL);
+ matches = g_list_model_get_n_items (completion->filter_model);
if (keyval_is_cursor_move (keyval))
{
- GtkTreePath *path = NULL;
-
if (keyval == GDK_KEY_Up || keyval == GDK_KEY_KP_Up)
{
if (completion->current_selected < 0)
@@ -1777,7 +1570,7 @@ gtk_entry_completion_key_pressed (GtkEventControllerKey *controller,
if (completion->current_selected < 0)
{
- gtk_tree_selection_unselect_all (gtk_tree_view_get_selection (GTK_TREE_VIEW (completion->tree_view)));
+ gtk_selection_model_unselect_all (GTK_SELECTION_MODEL (gtk_list_view_get_model (GTK_LIST_VIEW (completion->list_view))));
if (completion->inline_selection &&
completion->completion_prefix)
@@ -1789,34 +1582,40 @@ gtk_entry_completion_key_pressed (GtkEventControllerKey *controller,
}
else if (completion->current_selected < matches)
{
- path = gtk_tree_path_new_from_indices (completion->current_selected, -1);
- gtk_tree_view_set_cursor (GTK_TREE_VIEW (completion->tree_view),
- path, NULL, FALSE);
+ gtk_selection_model_select_item (GTK_SELECTION_MODEL (gtk_list_view_get_model (GTK_LIST_VIEW (completion->list_view))),
+ completion->current_selected,
+ TRUE);
if (completion->inline_selection)
{
+ gpointer obj = gtk_single_selection_get_selected_item (GTK_SINGLE_SELECTION (gtk_list_view_get_model (GTK_LIST_VIEW (completion->list_view))));
- GtkTreeIter iter;
- GtkTreeIter child_iter;
- GtkTreeModel *model = NULL;
- GtkTreeSelection *sel;
gboolean entry_set;
- sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (completion->tree_view));
- if (!gtk_tree_selection_get_selected (sel, &model, &iter))
+ if (obj == NULL)
return FALSE;
- gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model), &child_iter, &iter);
- model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (model));
if (completion->completion_prefix == NULL)
completion->completion_prefix = g_strdup (gtk_editable_get_text (GTK_EDITABLE (completion->entry)));
- g_signal_emit_by_name (completion, "cursor-on-match", model,
- &child_iter, &entry_set);
+ g_signal_emit_by_name (completion, "cursor-on-match",
+ completion->current_selected, &entry_set);
}
}
+ else if (completion->current_selected - matches >= 0)
+ {
+ gtk_selection_model_select_item (GTK_SELECTION_MODEL (gtk_list_view_get_model (GTK_LIST_VIEW (completion->list_view))),
+ completion->current_selected - matches,
+ TRUE);
- gtk_tree_path_free (path);
+ if (completion->inline_selection &&
+ completion->completion_prefix)
+ {
+ gtk_editable_set_text (GTK_EDITABLE (completion->entry),
+ completion->completion_prefix);
+ gtk_editable_set_position (GTK_EDITABLE (widget), -1);
+ }
+ }
return TRUE;
}
@@ -1829,7 +1628,7 @@ gtk_entry_completion_key_pressed (GtkEventControllerKey *controller,
gboolean retval = TRUE;
gtk_entry_reset_im_context (GTK_ENTRY (widget));
- _gtk_entry_completion_popdown (completion);
+ gtk_entry_completion_popdown (completion);
if (completion->current_selected < 0)
{
@@ -1853,8 +1652,9 @@ gtk_entry_completion_key_pressed (GtkEventControllerKey *controller,
keyval == GDK_KEY_KP_Right ||
keyval == GDK_KEY_Escape)
gtk_editable_set_position (GTK_EDITABLE (widget), -1);
- /* Let the default keybindings run for Left, i.e. either move to the
- * * previous character or select word if a modifier is used */
+ /* Let the default keybindings run for Left, i.e. either move
+ * to the previous character or select word if a modifier is used
+ */
else
retval = FALSE;
}
@@ -1870,7 +1670,7 @@ keypress_completion_out:
keyval == GDK_KEY_ISO_Left_Tab)
{
gtk_entry_reset_im_context (GTK_ENTRY (widget));
- _gtk_entry_completion_popdown (completion);
+ gtk_entry_completion_popdown (completion);
g_clear_pointer (&completion->completion_prefix, g_free);
@@ -1880,43 +1680,31 @@ keypress_completion_out:
keyval == GDK_KEY_KP_Enter ||
keyval == GDK_KEY_Return)
{
- GtkTreeIter iter;
- GtkTreeModel *model = NULL;
- GtkTreeModel *child_model;
- GtkTreeIter child_iter;
- GtkTreeSelection *sel;
gboolean retval = TRUE;
gtk_entry_reset_im_context (GTK_ENTRY (widget));
- _gtk_entry_completion_popdown (completion);
+ gtk_entry_completion_popdown (completion);
if (completion->current_selected < matches)
{
- gboolean entry_set;
+ gpointer obj = gtk_single_selection_get_selected_item (GTK_SINGLE_SELECTION (gtk_list_view_get_model (GTK_LIST_VIEW (completion->list_view))));
+ GValue value = G_VALUE_INIT;
- sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (completion->tree_view));
- if (gtk_tree_selection_get_selected (sel, &model, &iter))
+ if (completion->expression &&
+ gtk_expression_evaluate (completion->expression, obj, &value))
{
- gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model), &child_iter, &iter);
- child_model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (model));
+ GtkText *text = gtk_entry_get_text_widget (GTK_ENTRY (completion->entry));
+ gboolean entry_set;
+
g_signal_handler_block (text, completion->changed_id);
g_signal_emit_by_name (completion, "match-selected",
- child_model, &child_iter, &entry_set);
+ completion->current_selected, &entry_set);
g_signal_handler_unblock (text, completion->changed_id);
if (!entry_set)
{
- gchar *str = NULL;
-
- gtk_tree_model_get (model, &iter,
- completion->text_column, &str,
- -1);
-
- gtk_editable_set_text (GTK_EDITABLE (widget), str);
-
- /* move the cursor to the end */
+ gtk_editable_set_text (GTK_EDITABLE (widget), g_value_get_string (&value));
gtk_editable_set_position (GTK_EDITABLE (widget), -1);
- g_free (str);
}
}
else
@@ -1938,6 +1726,7 @@ gtk_entry_completion_changed (GtkWidget *widget,
gpointer user_data)
{
GtkEntryCompletion *completion = GTK_ENTRY_COMPLETION (user_data);
+ const char *text;
if (!completion->popup_completion)
return;
@@ -1949,30 +1738,31 @@ gtk_entry_completion_changed (GtkWidget *widget,
completion->completion_timeout = 0;
}
- if (!gtk_editable_get_text (GTK_EDITABLE (widget)))
+ text = gtk_editable_get_text (GTK_EDITABLE (widget));
+ if (!text)
return;
/* no need to normalize for this test */
if (completion->minimum_key_length > 0 &&
- strcmp ("", gtk_editable_get_text (GTK_EDITABLE (widget))) == 0)
+ strcmp ("", text) == 0)
{
if (gtk_widget_get_visible (completion->popup_window))
- _gtk_entry_completion_popdown (completion);
+ gtk_entry_completion_popdown (completion);
return;
}
- completion->completion_timeout =
- g_timeout_add (COMPLETION_TIMEOUT,
- gtk_entry_completion_timeout,
- completion);
- g_source_set_name_by_id (completion->completion_timeout, "[gtk] gtk_entry_completion_timeout");
+ completion->completion_timeout = g_timeout_add (COMPLETION_TIMEOUT,
+ gtk_entry_completion_timeout,
+ completion);
+ g_source_set_name_by_id (completion->completion_timeout,
+ "[gtk] gtk_entry_completion_timeout");
}
static gboolean
check_completion_callback (GtkEntryCompletion *completion)
{
completion->check_completion_idle = NULL;
-
+
gtk_entry_completion_complete (completion);
gtk_entry_completion_insert_prefix (completion);
@@ -2117,7 +1907,7 @@ disconnect_completion_signals (GtkEntryCompletion *completion)
}
void
-_gtk_entry_completion_disconnect (GtkEntryCompletion *completion)
+gtk_entry_completion_disconnect (GtkEntryCompletion *completion)
{
if (completion->completion_timeout)
{
@@ -2131,26 +1921,20 @@ _gtk_entry_completion_disconnect (GtkEntryCompletion *completion)
}
if (gtk_widget_get_mapped (completion->popup_window))
- _gtk_entry_completion_popdown (completion);
+ gtk_entry_completion_popdown (completion);
disconnect_completion_signals (completion);
-
- unset_accessible_relation (completion->popup_window,
- completion->entry);
+ unset_accessible_relation (completion->popup_window, completion->entry);
gtk_widget_unparent (completion->popup_window);
-
completion->entry = NULL;
}
void
-_gtk_entry_completion_connect (GtkEntryCompletion *completion,
- GtkEntry *entry)
+gtk_entry_completion_connect (GtkEntryCompletion *completion,
+ GtkEntry *entry)
{
completion->entry = GTK_WIDGET (entry);
-
- set_accessible_relation (completion->popup_window,
- completion->entry);
+ set_accessible_relation (completion->popup_window, completion->entry);
gtk_widget_set_parent (completion->popup_window, GTK_WIDGET (entry));
-
connect_completion_signals (completion);
}
diff --git a/gtk/gtkentrycompletion.h b/gtk/gtkentrycompletion.h
index 6fd623edd9..2809ad2dd7 100644
--- a/gtk/gtkentrycompletion.h
+++ b/gtk/gtkentrycompletion.h
@@ -23,11 +23,8 @@
#endif
#include <gdk/gdk.h>
-#include <gtk/gtktreemodel.h>
-#include <gtk/gtkliststore.h>
-#include <gtk/gtkcellarea.h>
-#include <gtk/gtktreeviewcolumn.h>
-#include <gtk/gtktreemodelfilter.h>
+#include <gtk/gtklistitemfactory.h>
+#include <gtk/gtkexpression.h>
G_BEGIN_DECLS
@@ -37,50 +34,31 @@ G_BEGIN_DECLS
typedef struct _GtkEntryCompletion GtkEntryCompletion;
-/**
- * GtkEntryCompletionMatchFunc:
- * @completion: the #GtkEntryCompletion
- * @key: the string to match, normalized and case-folded
- * @iter: a #GtkTreeIter indicating the row to match
- * @user_data: user data given to gtk_entry_completion_set_match_func()
- *
- * A function which decides whether the row indicated by @iter matches
- * a given @key, and should be displayed as a possible completion for @key.
- * Note that @key is normalized and case-folded (see g_utf8_normalize()
- * and g_utf8_casefold()). If this is not appropriate, match functions
- * have access to the unmodified key via
- * `gtk_editable_get_text (GTK_EDITABLE (gtk_entry_completion_get_entry ()))`.
- *
- * Returns: %TRUE if @iter should be displayed as a possible completion
- * for @key
- */
-typedef gboolean (* GtkEntryCompletionMatchFunc) (GtkEntryCompletion *completion,
- const gchar *key,
- GtkTreeIter *iter,
- gpointer user_data);
-
-
GDK_AVAILABLE_IN_ALL
GType gtk_entry_completion_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_ALL
GtkEntryCompletion *gtk_entry_completion_new (void);
GDK_AVAILABLE_IN_ALL
-GtkEntryCompletion *gtk_entry_completion_new_with_area (GtkCellArea *area);
-
-GDK_AVAILABLE_IN_ALL
GtkWidget *gtk_entry_completion_get_entry (GtkEntryCompletion *completion);
GDK_AVAILABLE_IN_ALL
void gtk_entry_completion_set_model (GtkEntryCompletion *completion,
- GtkTreeModel *model);
+ GListModel *model);
GDK_AVAILABLE_IN_ALL
-GtkTreeModel *gtk_entry_completion_get_model (GtkEntryCompletion *completion);
+GListModel * gtk_entry_completion_get_model (GtkEntryCompletion *completion);
GDK_AVAILABLE_IN_ALL
-void gtk_entry_completion_set_match_func (GtkEntryCompletion *completion,
- GtkEntryCompletionMatchFunc func,
- gpointer func_data,
- GDestroyNotify func_notify);
+void gtk_entry_completion_set_expression (GtkEntryCompletion *completion,
+ GtkExpression *expression);
+GDK_AVAILABLE_IN_ALL
+GtkExpression * gtk_entry_completion_get_expression (GtkEntryCompletion *completion);
+
+GDK_AVAILABLE_IN_ALL
+void gtk_entry_completion_set_factory (GtkEntryCompletion *completion,
+ GtkListItemFactory *factory);
+GDK_AVAILABLE_IN_ALL
+GtkListItemFactory *gtk_entry_completion_get_factory (GtkEntryCompletion *completion);
+
GDK_AVAILABLE_IN_ALL
void gtk_entry_completion_set_minimum_key_length (GtkEntryCompletion *completion,
gint length);
@@ -122,12 +100,6 @@ gboolean gtk_entry_completion_get_popup_single_match (GtkEntryComplet
GDK_AVAILABLE_IN_ALL
const gchar *gtk_entry_completion_get_completion_prefix (GtkEntryCompletion *completion);
-/* convenience */
-GDK_AVAILABLE_IN_ALL
-void gtk_entry_completion_set_text_column (GtkEntryCompletion *completion,
- gint column);
-GDK_AVAILABLE_IN_ALL
-gint gtk_entry_completion_get_text_column (GtkEntryCompletion *completion);
G_END_DECLS
diff --git a/gtk/gtkentryprivate.h b/gtk/gtkentryprivate.h
index a04b63e288..0008c1c38a 100644
--- a/gtk/gtkentryprivate.h
+++ b/gtk/gtkentryprivate.h
@@ -38,43 +38,34 @@ struct _GtkEntryCompletion
GtkWidget *entry;
- GtkWidget *tree_view;
- GtkTreeViewColumn *column;
- GtkTreeModelFilter *filter_model;
- GtkCellArea *cell_area;
-
- GtkEntryCompletionMatchFunc match_func;
- gpointer match_data;
- GDestroyNotify match_notify;
+ GListModel *filter_model;
+ GtkExpression *expression;
+ GtkListItemFactory *factory;
gint minimum_key_length;
- gint text_column;
-
- gchar *case_normalized_key;
+ char *case_normalized_key;
GtkEventController *entry_key_controller;
GtkEventController *entry_focus_controller;
- /* only used by GtkEntry when attached: */
GtkWidget *popup_window;
GtkWidget *scrolled_window;
+ GtkWidget *list_view;
gulong completion_timeout;
gulong changed_id;
gulong insert_text_id;
- gint current_selected;
+ int current_selected;
- guint first_sel_changed : 1;
- guint has_completion : 1;
- guint inline_completion : 1;
- guint popup_completion : 1;
- guint popup_set_width : 1;
+ guint has_completion : 1;
+ guint inline_completion : 1;
+ guint popup_completion : 1;
+ guint popup_set_width : 1;
guint popup_single_match : 1;
guint inline_selection : 1;
- guint has_grab : 1;
- gchar *completion_prefix;
+ char *completion_prefix;
GSource *check_completion_idle;
};
@@ -84,23 +75,19 @@ struct _GtkEntryCompletionClass
GObjectClass parent_class;
gboolean (* match_selected) (GtkEntryCompletion *completion,
- GtkTreeModel *model,
- GtkTreeIter *iter);
- void (* action_activated) (GtkEntryCompletion *completion,
- gint index_);
+ guint position);
gboolean (* insert_prefix) (GtkEntryCompletion *completion,
- const gchar *prefix);
+ const char *prefix);
gboolean (* cursor_on_match) (GtkEntryCompletion *completion,
- GtkTreeModel *model,
- GtkTreeIter *iter);
+ guint position);
void (* no_matches) (GtkEntryCompletion *completion);
};
-void _gtk_entry_completion_resize_popup (GtkEntryCompletion *completion);
-void _gtk_entry_completion_popdown (GtkEntryCompletion *completion);
-void _gtk_entry_completion_connect (GtkEntryCompletion *completion,
- GtkEntry *entry);
-void _gtk_entry_completion_disconnect (GtkEntryCompletion *completion);
+void gtk_entry_completion_resize_popup (GtkEntryCompletion *completion);
+void gtk_entry_completion_popdown (GtkEntryCompletion *completion);
+void gtk_entry_completion_connect (GtkEntryCompletion *completion,
+ GtkEntry *entry);
+void gtk_entry_completion_disconnect (GtkEntryCompletion *completion);
GtkIMContext * _gtk_entry_get_im_context (GtkEntry *entry);
GtkEventController * gtk_entry_get_key_controller (GtkEntry *entry);
diff --git a/gtk/gtkplacesview.c b/gtk/gtkplacesview.c
index eb2b9baf7d..1af94d0e11 100644
--- a/gtk/gtkplacesview.c
+++ b/gtk/gtkplacesview.c
@@ -30,6 +30,7 @@
#include "gtktypebuiltins.h"
#include "gtkeventcontrollerkey.h"
#include "gtkpopovermenu.h"
+#include "gtkstringlist.h"
/*
* SECTION:gtkplacesview
@@ -98,7 +99,7 @@ struct _GtkPlacesView
GtkSizeGroup *space_size_group;
GtkEntryCompletion *address_entry_completion;
- GtkListStore *completion_store;
+ GListModel *completion_store;
GCancellable *networks_fetching_cancellable;
@@ -551,12 +552,12 @@ populate_servers (GtkPlacesView *view)
while ((child = gtk_widget_get_first_child (GTK_WIDGET (view->recent_servers_listbox))))
gtk_list_box_remove (GTK_LIST_BOX (view->listbox), child);
- gtk_list_store_clear (view->completion_store);
+ while (g_list_model_get_n_items (G_LIST_MODEL (view->completion_store)) > 0)
+ gtk_string_list_remove (GTK_STRING_LIST (view->completion_store), 0);
for (i = 0; i < num_uris; i++)
{
RemoveServerData *data;
- GtkTreeIter iter;
GtkWidget *row;
GtkWidget *grid;
GtkWidget *button;
@@ -568,12 +569,7 @@ populate_servers (GtkPlacesView *view)
dup_uri = g_strdup (uris[i]);
/* add to the completion list */
- gtk_list_store_append (view->completion_store, &iter);
- gtk_list_store_set (view->completion_store,
- &iter,
- 0, name,
- 1, uris[i],
- -1);
+ gtk_string_list_append (GTK_STRING_LIST (view->completion_store), uris[i]);
/* add to the recent servers listbox */
row = gtk_list_box_row_new ();
diff --git a/gtk/ui/gtkplacesview.ui b/gtk/ui/gtkplacesview.ui
index 4668ae758b..a2a1afac65 100644
--- a/gtk/ui/gtkplacesview.ui
+++ b/gtk/ui/gtkplacesview.ui
@@ -1,15 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface domain="gtk40">
<requires lib="gtk+" version="3.16"/>
- <object class="GtkListStore" id="completion_store">
- <columns>
- <column type="gchararray"/>
- <column type="gchararray"/>
- </columns>
+ <object class="GtkStringList" id="completion_store">
</object>
<object class="GtkEntryCompletion" id="address_entry_completion">
<property name="model">completion_store</property>
- <property name="text-column">1</property>
<property name="inline-completion">1</property>
<property name="popup-completion">0</property>
</object>
diff --git a/tests/testentrycompletion.c b/tests/testentrycompletion.c
index 68985d7383..6588c8ce5d 100644
--- a/tests/testentrycompletion.c
+++ b/tests/testentrycompletion.c
@@ -21,272 +21,80 @@
#include <string.h>
#include <gtk/gtk.h>
-/* Don't copy this bad example; inline RGB data is always a better
- * idea than inline XPMs.
- */
-static const char *book_closed_xpm[] = {
-"16 16 6 1",
-" c None s None",
-". c black",
-"X c red",
-"o c yellow",
-"O c #808080",
-"# c white",
-" ",
-" .. ",
-" ..XX. ",
-" ..XXXXX. ",
-" ..XXXXXXXX. ",
-".ooXXXXXXXXX. ",
-"..ooXXXXXXXXX. ",
-".X.ooXXXXXXXXX. ",
-".XX.ooXXXXXX.. ",
-" .XX.ooXXX..#O ",
-" .XX.oo..##OO. ",
-" .XX..##OO.. ",
-" .X.#OO.. ",
-" ..O.. ",
-" .. ",
-" "
-};
-
static GtkWidget *window = NULL;
-/* Creates a tree model containing the completions */
-static GtkTreeModel *
+/* Creates a list model containing the completions */
+static GListModel *
create_simple_completion_model (void)
{
- GtkListStore *store;
- GtkTreeIter iter;
-
- store = gtk_list_store_new (1, G_TYPE_STRING);
-
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter, 0, "GNOME", -1);
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter, 0, "gnominious", -1);
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter, 0, "Gnomonic projection", -1);
-
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter, 0, "total", -1);
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter, 0, "totally", -1);
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter, 0, "toto", -1);
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter, 0, "tottery", -1);
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter, 0, "totterer", -1);
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter, 0, "Totten trust", -1);
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter, 0, "totipotent", -1);
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter, 0, "totipotency", -1);
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter, 0, "totemism", -1);
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter, 0, "totem pole", -1);
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter, 0, "Totara", -1);
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter, 0, "totalizer", -1);
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter, 0, "totalizator", -1);
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter, 0, "totalitarianism", -1);
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter, 0, "total parenteral nutrition", -1);
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter, 0, "total hysterectomy", -1);
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter, 0, "total eclipse", -1);
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter, 0, "Totipresence", -1);
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter, 0, "Totipalmi", -1);
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter, 0, "zombie", -1);
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter, 0, "a\303\246x", -1);
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter, 0, "a\303\246y", -1);
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter, 0, "a\303\246z", -1);
-
- return GTK_TREE_MODEL (store);
-}
-
-/* Creates a tree model containing the completions */
-static GtkTreeModel *
-create_completion_model (void)
-{
- GtkListStore *store;
- GtkTreeIter iter;
- GdkPixbuf *pixbuf;
-
- pixbuf = gdk_pixbuf_new_from_xpm_data ((const char **)book_closed_xpm);
-
- store = gtk_list_store_new (2, GDK_TYPE_PIXBUF, G_TYPE_STRING);
-
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter, 0, pixbuf, 1, "ambient", -1);
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter, 0, pixbuf, 1, "ambidextrously", -1);
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter, 0, pixbuf, 1, "ambidexter", -1);
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter, 0, pixbuf, 1, "ambiguity", -1);
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter, 0, pixbuf, 1, "American Party", -1);
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter, 0, pixbuf, 1, "American mountain ash", -1);
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter, 0, pixbuf, 1, "amelioration", -1);
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter, 0, pixbuf, 1, "Amelia Earhart", -1);
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter, 0, pixbuf, 1, "Totten trust", -1);
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter, 0, pixbuf, 1, "Laminated arch", -1);
-
- return GTK_TREE_MODEL (store);
+ const char *strings[] = {
+ "GNOME",
+ "gnominious",
+ "Gnomonic projection",
+ "total",
+ "totally",
+ "toto",
+ "tottery",
+ "totterer",
+ "Totten trust",
+ "totipotent",
+ "totipotency",
+ "totemism",
+ "totem pole",
+ "Totara",
+ "totalizer",
+ "totalizator",
+ "totalitarianism",
+ "total parenteral nutrition",
+ "total hysterectomy",
+ "total eclipse",
+ "Totipresence",
+ "Totipalmi",
+ "zombie",
+ "a\303\246x",
+ "a\303\246y",
+ "a\303\246z",
+ NULL
+ };
+
+ return G_LIST_MODEL (gtk_string_list_new (strings));
}
-static gboolean
-match_func (GtkEntryCompletion *completion,
- const gchar *key,
- GtkTreeIter *iter,
- gpointer user_data)
+static char *
+get_file_name (gpointer item)
{
- gchar *item = NULL;
- GtkTreeModel *model;
-
- gboolean ret = FALSE;
-
- model = gtk_entry_completion_get_model (completion);
-
- gtk_tree_model_get (model, iter, 1, &item, -1);
-
- if (item != NULL)
- {
- g_print ("compare %s %s\n", key, item);
- if (strncmp (key, item, strlen (key)) == 0)
- ret = TRUE;
-
- g_free (item);
- }
-
- return ret;
+ return g_strdup (g_file_info_get_display_name (G_FILE_INFO (item)));
}
-static gint timer_count = 0;
-
-static const char *dynamic_completions[] = {
- "GNOME",
- "gnominious",
- "Gnomonic projection",
- "total",
- "totally",
- "toto",
- "tottery",
- "totterer",
- "Totten trust",
- "totipotent",
- "totipotency",
- "totemism",
- "totem pole",
- "Totara",
- "totalizer",
- "totalizator",
- "totalitarianism",
- "total parenteral nutrition",
- "total hysterectomy",
- "total eclipse",
- "Totipresence",
- "Totipalmi",
- "zombie"
-};
-
-static gint
-animation_timer (GtkEntryCompletion *completion)
-{
- GtkTreeIter iter;
- gint n_completions = G_N_ELEMENTS (dynamic_completions);
- gint n;
- static GtkListStore *old_store = NULL;
- GtkListStore *store = GTK_LIST_STORE (gtk_entry_completion_get_model (completion));
-
- if (timer_count % 10 == 0)
- {
- if (!old_store)
- {
- g_print ("removing model!\n");
-
- old_store = g_object_ref (store);
- gtk_entry_completion_set_model (completion, NULL);
- }
- else
- {
- g_print ("readding model!\n");
-
- gtk_entry_completion_set_model (completion, GTK_TREE_MODEL (old_store));
- g_object_unref (old_store);
- old_store = NULL;
- }
-
- timer_count ++;
- return TRUE;
- }
-
- if (!old_store)
- {
- if ((timer_count / n_completions) % 2 == 0)
- {
- n = timer_count % n_completions;
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter, 0, dynamic_completions[n], -1);
-
- }
- else
- {
- if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter))
- gtk_list_store_remove (store, &iter);
- }
- }
-
- timer_count++;
- return TRUE;
-}
-
-static gboolean
-match_selected_cb (GtkEntryCompletion *completion,
- GtkTreeModel *model,
- GtkTreeIter *iter)
+static void
+setup_item (GtkSignalListItemFactory *factory,
+ GtkListItem *item)
{
- gchar *str;
- GtkWidget *entry;
-
- entry = gtk_entry_completion_get_entry (completion);
- gtk_tree_model_get (GTK_TREE_MODEL (model), iter, 1, &str, -1);
- gtk_editable_set_text (GTK_EDITABLE (entry), str);
- gtk_editable_set_position (GTK_EDITABLE (entry), -1);
- g_free (str);
+ GtkWidget *box;
+ GtkWidget *icon;
+ GtkWidget *label;
- return TRUE;
+ box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
+ icon = gtk_image_new ();
+ label = gtk_label_new ("");
+ gtk_label_set_xalign (GTK_LABEL (label), 0);
+ gtk_box_append (GTK_BOX (box), icon);
+ gtk_box_append (GTK_BOX (box), label);
+ gtk_list_item_set_child (item, box);
}
static void
-quit_cb (GtkWidget *widget,
- gpointer data)
+bind_item (GtkSignalListItemFactory *factory,
+ GtkListItem *item)
{
- gboolean *done = data;
-
- *done = TRUE;
+ GFileInfo *info = G_FILE_INFO (gtk_list_item_get_item (item));
+ GtkWidget *box = gtk_list_item_get_child (item);
+ GtkWidget *icon = gtk_widget_get_first_child (box);
+ GtkWidget *label = gtk_widget_get_last_child (box);
- g_main_context_wakeup (NULL);
+ gtk_image_set_from_gicon (GTK_IMAGE (icon), g_file_info_get_icon (info));
+ gtk_label_set_label (GTK_LABEL (label), g_file_info_get_display_name (info));
}
int
@@ -296,124 +104,79 @@ main (int argc, char *argv[])
GtkWidget *label;
GtkWidget *entry;
GtkEntryCompletion *completion;
- GtkTreeModel *completion_model;
- GtkCellRenderer *cell;
- gboolean done = FALSE;
+ GListModel *model;
+ char *cwd;
+ GFile *file;
+ GtkExpression *expression;
+ GtkListItemFactory *factory;
gtk_init ();
window = gtk_window_new ();
- g_signal_connect (window, "destroy", G_CALLBACK (quit_cb), &done);
-
+
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
gtk_widget_set_margin_start (vbox, 5);
gtk_widget_set_margin_end (vbox, 5);
gtk_widget_set_margin_top (vbox, 5);
gtk_widget_set_margin_bottom (vbox, 5);
gtk_window_set_child (GTK_WINDOW (window), vbox);
-
+
label = gtk_label_new (NULL);
gtk_label_set_markup (GTK_LABEL (label), "Completion demo, try writing <b>total</b> or <b>gnome</b> for example.");
gtk_box_append (GTK_BOX (vbox), label);
- /* Create our first entry */
entry = gtk_entry_new ();
-
- /* Create the completion object */
+
completion = gtk_entry_completion_new ();
gtk_entry_completion_set_inline_completion (completion, TRUE);
-
- /* Assign the completion to the entry */
- gtk_entry_set_completion (GTK_ENTRY (entry), completion);
- g_object_unref (completion);
-
- gtk_box_append (GTK_BOX (vbox), entry);
-
- /* Create a tree model and use it as the completion model */
- completion_model = create_simple_completion_model ();
- gtk_entry_completion_set_model (completion, completion_model);
- g_object_unref (completion_model);
-
- /* Use model column 0 as the text column */
- gtk_entry_completion_set_text_column (completion, 0);
+ model = create_simple_completion_model ();
+ gtk_entry_completion_set_model (completion, model);
+ g_object_unref (model);
- /* Create our second entry */
- entry = gtk_entry_new ();
-
- /* Create the completion object */
- completion = gtk_entry_completion_new ();
-
- /* Assign the completion to the entry */
gtk_entry_set_completion (GTK_ENTRY (entry), completion);
g_object_unref (completion);
-
+
gtk_box_append (GTK_BOX (vbox), entry);
- /* Create a tree model and use it as the completion model */
- completion_model = create_completion_model ();
- gtk_entry_completion_set_model (completion, completion_model);
- gtk_entry_completion_set_minimum_key_length (completion, 2);
- g_object_unref (completion_model);
-
- /* Use model column 1 as the text column */
- cell = gtk_cell_renderer_pixbuf_new ();
- gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (completion), cell, FALSE);
- gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (completion), cell,
- "pixbuf", 0, NULL);
-
- cell = gtk_cell_renderer_text_new ();
- gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (completion), cell, FALSE);
- gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (completion), cell,
- "text", 1, NULL);
-
- gtk_entry_completion_set_match_func (completion, match_func, NULL, NULL);
- g_signal_connect (completion, "match-selected",
- G_CALLBACK (match_selected_cb), NULL);
-
- /* Create our third entry */
entry = gtk_entry_new ();
- /* Create the completion object */
completion = gtk_entry_completion_new ();
-
- /* Assign the completion to the entry */
gtk_entry_set_completion (GTK_ENTRY (entry), completion);
- g_object_unref (completion);
-
- gtk_box_append (GTK_BOX (vbox), entry);
-
- /* Create a tree model and use it as the completion model */
- completion_model = GTK_TREE_MODEL (gtk_list_store_new (1, G_TYPE_STRING));
-
- gtk_entry_completion_set_model (completion, completion_model);
- g_object_unref (completion_model);
- /* Use model column 0 as the text column */
- gtk_entry_completion_set_text_column (completion, 0);
+ gtk_box_append (GTK_BOX (vbox), entry);
- /* Fill the completion dynamically */
- g_timeout_add (1000, (GSourceFunc) animation_timer, completion);
+ cwd = g_get_current_dir ();
+ file = g_file_new_for_path (cwd);
+ model = G_LIST_MODEL (gtk_directory_list_new ("standard::display-name,standard::content-type,standard::icon,standard::size", file));
+ gtk_entry_completion_set_model (completion, model);
+ g_object_unref (model);
+ g_object_unref (file);
+ g_free (cwd);
- /* Fourth entry */
- gtk_box_append (GTK_BOX (vbox), gtk_label_new ("Model-less entry completion"));
+ expression = gtk_cclosure_expression_new (G_TYPE_STRING, NULL,
+ 0, NULL,
+ (GCallback)get_file_name,
+ NULL, NULL);
+ gtk_entry_completion_set_expression (completion, expression);
- entry = gtk_entry_new ();
+ factory = gtk_signal_list_item_factory_new ();
+ g_signal_connect (factory, "setup", G_CALLBACK (setup_item), NULL);
+ g_signal_connect (factory, "bind", G_CALLBACK (bind_item), NULL);
+ gtk_entry_completion_set_factory (completion, factory);
+ g_object_unref (factory);
- /* Create the completion object */
- completion = gtk_entry_completion_new ();
+ gtk_expression_unref (expression);
- /* Assign the completion to the entry */
- gtk_entry_set_completion (GTK_ENTRY (entry), completion);
g_object_unref (completion);
- gtk_box_append (GTK_BOX (vbox), entry);
+ gtk_window_present (GTK_WINDOW (window));
- gtk_widget_show (window);
-
- while (!done)
+ while (g_list_model_get_n_items (gtk_window_get_toplevels ()) > 0)
g_main_context_iteration (NULL, TRUE);
+ gtk_window_destroy (GTK_WINDOW (window));
+
return 0;
}
diff --git a/tests/testgtk.c b/tests/testgtk.c
index 28bd0db358..7ff1e0c36f 100644
--- a/tests/testgtk.c
+++ b/tests/testgtk.c
@@ -2850,17 +2850,10 @@ static const gchar *cursor_names[] = {
NULL
};
-static GtkTreeModel *
+static GListModel *
cursor_model (void)
{
- GtkListStore *store;
- gint i;
- store = gtk_list_store_new (1, G_TYPE_STRING);
-
- for (i = 0; i < G_N_ELEMENTS (cursor_names); i++)
- gtk_list_store_insert_with_values (store, NULL, -1, 0, cursor_names[i], -1);
-
- return (GtkTreeModel *)store;
+ return G_LIST_MODEL (gtk_string_list_new (cursor_names));
}
static void
@@ -2961,7 +2954,7 @@ create_cursors (GtkWidget *widget)
GtkWidget *entry;
GtkWidget *size;
GtkEntryCompletion *completion;
- GtkTreeModel *model;
+ GListModel *model;
gboolean cursor_demo = FALSE;
GtkGesture *gesture;
@@ -3038,7 +3031,6 @@ create_cursors (GtkWidget *widget)
completion = gtk_entry_completion_new ();
model = cursor_model ();
gtk_entry_completion_set_model (completion, model);
- gtk_entry_completion_set_text_column (completion, 0);
gtk_entry_set_completion (GTK_ENTRY (entry), completion);
g_object_unref (model);
gtk_widget_set_hexpand (entry, TRUE);
diff --git a/testsuite/gtk/cellarea.c b/testsuite/gtk/cellarea.c
index 1319ad5fb1..bd53702ddf 100644
--- a/testsuite/gtk/cellarea.c
+++ b/testsuite/gtk/cellarea.c
@@ -255,53 +255,6 @@ test_column_object_new (void)
g_object_unref (col);
}
-/* test that we have a cell area after new() */
-static void
-test_completion_new (void)
-{
- GtkEntryCompletion *c;
- GtkCellArea *area;
-
- c = gtk_entry_completion_new ();
-
- area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (c));
- g_assert (GTK_IS_CELL_AREA_BOX (area));
-
- g_object_ref_sink (c);
- g_object_unref (c);
-}
-
-/* test that new_with_area() keeps the provided area */
-static void
-test_completion_new_with_area (void)
-{
- GtkEntryCompletion *c;
- GtkCellArea *area;
-
- area = gtk_cell_area_box_new ();
- c = gtk_entry_completion_new_with_area (area);
- g_assert (gtk_cell_layout_get_area (GTK_CELL_LAYOUT (c)) == area);
-
- g_object_ref_sink (c);
- g_object_unref (c);
-}
-
-/* test that g_object_new keeps the provided area */
-static void
-test_completion_object_new (void)
-{
- GtkEntryCompletion *c;
- GtkCellArea *area;
-
- area = gtk_cell_area_box_new ();
- gtk_orientable_set_orientation (GTK_ORIENTABLE (area), GTK_ORIENTATION_HORIZONTAL);
- c = g_object_new (GTK_TYPE_ENTRY_COMPLETION, "cell-area", area, NULL);
- g_assert (gtk_cell_layout_get_area (GTK_CELL_LAYOUT (c)) == area);
-
- g_object_ref_sink (c);
- g_object_unref (c);
-}
-
int
main (int argc, char *argv[])
{
@@ -324,9 +277,5 @@ main (int argc, char *argv[])
g_test_add_func ("/tests/column-new-with-area", test_column_new_with_area);
g_test_add_func ("/tests/column-object-new", test_column_object_new);
- g_test_add_func ("/tests/completion-new", test_completion_new);
- g_test_add_func ("/tests/completion-new-with-area", test_completion_new_with_area);
- g_test_add_func ("/tests/completion-object-new", test_completion_object_new);
-
return g_test_run();
}