2 * This file is a part of hildon
4 * Copyright (C) 2008 Nokia Corporation.
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version. or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free
18 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include "hildon-touch-selector.h"
22 #include "hildon-touch-selector-entry.h"
24 G_DEFINE_TYPE (HildonTouchSelectorEntry, hildon_touch_selector_entry, HILDON_TYPE_TOUCH_SELECTOR)
26 #define HILDON_TOUCH_SELECTOR_ENTRY_GET_PRIVATE(o) \
27 (G_TYPE_INSTANCE_GET_PRIVATE ((o), HILDON_TYPE_TOUCH_SELECTOR_ENTRY, HildonTouchSelectorEntryPrivate))
29 typedef struct _HildonTouchSelectorEntryPrivate HildonTouchSelectorEntryPrivate;
31 static void entry_on_text_changed (GtkEditable * editable, gpointer userdata);
32 static void hildon_touch_selector_entry_changed (HildonTouchSelector * selector,
35 static void hildon_touch_selector_entry_set_model (HildonTouchSelector * selector,
36 gint column, GtkTreeModel *model);
37 static gboolean hildon_touch_selector_entry_has_multiple_selection (HildonTouchSelector * selector);
39 struct _HildonTouchSelectorEntryPrivate {
50 hildon_touch_selector_entry_get_property (GObject *object, guint property_id,
51 GValue *value, GParamSpec *pspec)
53 switch (property_id) {
54 case PROP_TEXT_COLUMN:
55 g_value_set_int (value,
56 hildon_touch_selector_entry_get_text_column (HILDON_TOUCH_SELECTOR_ENTRY (object)));
58 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
63 hildon_touch_selector_entry_set_property (GObject *object, guint property_id,
64 const GValue *value, GParamSpec *pspec)
66 switch (property_id) {
67 case PROP_TEXT_COLUMN:
68 hildon_touch_selector_entry_set_text_column (HILDON_TOUCH_SELECTOR_ENTRY (object),
69 g_value_get_int (value));
71 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
76 hildon_touch_selector_entry_class_init (HildonTouchSelectorEntryClass *klass)
78 GObjectClass *object_class = G_OBJECT_CLASS (klass);
79 HildonTouchSelectorClass *selector_class = HILDON_TOUCH_SELECTOR_CLASS (klass);
81 g_type_class_add_private (klass, sizeof (HildonTouchSelectorEntryPrivate));
83 selector_class->set_model = hildon_touch_selector_entry_set_model;
84 selector_class->has_multiple_selection = hildon_touch_selector_entry_has_multiple_selection;
86 object_class->get_property = hildon_touch_selector_entry_get_property;
87 object_class->set_property = hildon_touch_selector_entry_set_property;
89 g_object_class_install_property (G_OBJECT_CLASS (klass),
91 g_param_spec_int ("text-column",
93 "A column in the data source model to get the strings from.",
101 hildon_touch_selector_entry_print_func (HildonTouchSelector * selector)
103 HildonTouchSelectorEntryPrivate *priv;
105 priv = HILDON_TOUCH_SELECTOR_ENTRY_GET_PRIVATE (selector);
107 return g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->entry)));
111 hildon_touch_selector_entry_init (HildonTouchSelectorEntry *self)
113 HildonTouchSelectorEntryPrivate *priv;
114 GtkEntryCompletion *completion;
116 priv = HILDON_TOUCH_SELECTOR_ENTRY_GET_PRIVATE (self);
118 priv->entry = gtk_entry_new ();
119 gtk_entry_set_activates_default (GTK_ENTRY (priv->entry), TRUE);
121 completion = gtk_entry_completion_new ();
122 gtk_entry_completion_set_inline_completion (completion, TRUE);
123 gtk_entry_completion_set_popup_completion (completion, FALSE);
124 gtk_entry_set_completion (GTK_ENTRY (priv->entry), completion);
126 gtk_widget_show (priv->entry);
127 g_signal_connect (G_OBJECT (priv->entry), "changed",
128 G_CALLBACK (entry_on_text_changed), self);
129 priv->signal_id = g_signal_connect (G_OBJECT (self), "changed",
130 G_CALLBACK (hildon_touch_selector_entry_changed), NULL);
132 hildon_touch_selector_set_print_func (HILDON_TOUCH_SELECTOR (self), hildon_touch_selector_entry_print_func);
133 gtk_box_pack_start (GTK_BOX (self), priv->entry, FALSE, FALSE, 0);
137 hildon_touch_selector_entry_new (void)
139 return g_object_new (HILDON_TYPE_TOUCH_SELECTOR_ENTRY, NULL);
143 * hildon_touch_selector_entry_new_text:
146 * Creates a #HildonTouchSelectorEntry with a single text column that
147 * can be populated conveniently through hildon_touch_selector_append_text(),
148 * hildon_touch_selector_prepend_text(), hildon_touch_selector_insert_text().
150 * Returns: A new #HildonTouchSelectorEntry
153 hildon_touch_selector_entry_new_text (void)
157 GtkEntryCompletion *completion;
158 HildonTouchSelectorEntryPrivate *priv;
160 selector = hildon_touch_selector_entry_new ();
162 priv = HILDON_TOUCH_SELECTOR_ENTRY_GET_PRIVATE (selector);
164 model = gtk_list_store_new (1, G_TYPE_STRING);
165 completion = gtk_entry_get_completion (GTK_ENTRY (priv->entry));
166 gtk_entry_completion_set_model (completion, GTK_TREE_MODEL (model));
168 hildon_touch_selector_append_text_column (HILDON_TOUCH_SELECTOR (selector),
169 GTK_TREE_MODEL (model), FALSE);
170 hildon_touch_selector_entry_set_text_column (HILDON_TOUCH_SELECTOR_ENTRY (selector), 0);
176 hildon_touch_selector_entry_set_text_column (HildonTouchSelectorEntry *selector,
179 HildonTouchSelectorEntryPrivate *priv;
180 GtkEntryCompletion *completion;
182 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR_ENTRY (selector));
183 g_return_if_fail (text_column >= -1);
185 priv = HILDON_TOUCH_SELECTOR_ENTRY_GET_PRIVATE (selector);
186 completion = gtk_entry_get_completion (GTK_ENTRY (priv->entry));
188 gtk_entry_completion_set_text_column (completion, text_column);
189 priv->text_column = text_column;
193 hildon_touch_selector_entry_get_text_column (HildonTouchSelectorEntry *selector)
195 HildonTouchSelectorEntryPrivate *priv;
197 g_return_val_if_fail (HILDON_IS_TOUCH_SELECTOR_ENTRY (selector), -1);
199 priv = HILDON_TOUCH_SELECTOR_ENTRY_GET_PRIVATE (selector);
201 return priv->text_column;
205 entry_on_text_changed (GtkEditable * editable,
208 HildonTouchSelector *selector;
209 HildonTouchSelectorEntryPrivate *priv;
215 gboolean found = FALSE;
217 entry = GTK_ENTRY (editable);
218 selector = HILDON_TOUCH_SELECTOR (userdata);
219 priv = HILDON_TOUCH_SELECTOR_ENTRY_GET_PRIVATE (selector);
221 prefix = gtk_entry_get_text (entry);
222 model = hildon_touch_selector_get_model (HILDON_TOUCH_SELECTOR (selector), 0);
224 if (!gtk_tree_model_get_iter_first (model, &iter)) {
229 gtk_tree_model_get (model, &iter, priv->text_column, &text, -1);
230 found = g_str_has_prefix (text, prefix);
232 } while (found != TRUE && gtk_tree_model_iter_next (model, &iter));
234 g_signal_handler_block (selector, priv->signal_id);
236 /* We emit the HildonTouchSelector::changed signal because a change in the
237 GtkEntry represents a change in current selection, and therefore, users
238 should be notified. */
240 hildon_touch_selector_set_active_iter (selector, 0, &iter, TRUE);
242 g_signal_emit_by_name (selector, "changed", 0);
244 g_signal_handler_unblock (selector, priv->signal_id);
248 /* FIXME: This is actually a very ugly way to retrieve the text. Ideally,
249 we would have API to retrieve it from the base clase (HildonTouchSelector).
250 In the meantime, leaving it here.
253 hildon_touch_selector_get_text_from_model (HildonTouchSelectorEntry * selector)
255 HildonTouchSelectorEntryPrivate *priv;
259 GList *selected_rows;
262 priv = HILDON_TOUCH_SELECTOR_ENTRY_GET_PRIVATE (selector);
264 model = hildon_touch_selector_get_model (HILDON_TOUCH_SELECTOR (selector), 0);
265 selected_rows = hildon_touch_selector_get_selected_rows (HILDON_TOUCH_SELECTOR (selector), 0);
267 if (selected_rows == NULL) {
271 /* We are in single selection mode */
272 g_assert (selected_rows->next == NULL);
274 path = (GtkTreePath *)selected_rows->data;
275 gtk_tree_model_get_iter (model, &iter, path);
276 gtk_tree_model_get (model, &iter, priv->text_column, &text, -1);
278 gtk_tree_path_free (path);
279 g_list_free (selected_rows);
285 hildon_touch_selector_entry_changed (HildonTouchSelector * selector,
286 gint column, gpointer user_data)
288 HildonTouchSelectorEntryPrivate *priv;
291 priv = HILDON_TOUCH_SELECTOR_ENTRY_GET_PRIVATE (selector);
293 text = hildon_touch_selector_get_text_from_model (HILDON_TOUCH_SELECTOR_ENTRY (selector));
294 gtk_entry_set_text (GTK_ENTRY (priv->entry), text);
295 gtk_editable_select_region (GTK_EDITABLE (priv->entry), 0, -1);
300 hildon_touch_selector_entry_set_model (HildonTouchSelector * selector,
301 gint column, GtkTreeModel *model)
303 GtkEntryCompletion *completion;
304 HildonTouchSelectorEntryPrivate *priv;
306 g_return_if_fail (HILDON_IS_TOUCH_SELECTOR_ENTRY (selector));
307 g_return_if_fail (column == 0);
308 g_return_if_fail (GTK_IS_TREE_MODEL (model));
310 HILDON_TOUCH_SELECTOR_CLASS (hildon_touch_selector_entry_parent_class)->set_model (selector, column, model);
312 priv = HILDON_TOUCH_SELECTOR_ENTRY_GET_PRIVATE (selector);
314 completion = gtk_entry_get_completion (GTK_ENTRY (priv->entry));
315 gtk_entry_completion_set_model (completion, model);
316 gtk_entry_completion_set_text_column (completion, priv->text_column);
320 hildon_touch_selector_entry_has_multiple_selection (HildonTouchSelector * selector)
322 /* Always TRUE, given the GtkEntry. */