1/* testentrycompletion.c
2 * Copyright (C) 2004 Red Hat, Inc.
3 * Author: Matthias Clasen
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include "config.h"
20#include <stdlib.h>
21#include <string.h>
22#include <gtk/gtk.h>
23
24/* Don't copy this bad example; inline RGB data is always a better
25 * idea than inline XPMs.
26 */
27static const char *book_closed_xpm[] = {
28"16 16 6 1",
29" c None s None",
30". c black",
31"X c red",
32"o c yellow",
33"O c #808080",
34"# c white",
35" ",
36" .. ",
37" ..XX. ",
38" ..XXXXX. ",
39" ..XXXXXXXX. ",
40".ooXXXXXXXXX. ",
41"..ooXXXXXXXXX. ",
42".X.ooXXXXXXXXX. ",
43".XX.ooXXXXXX.. ",
44" .XX.ooXXX..#O ",
45" .XX.oo..##OO. ",
46" .XX..##OO.. ",
47" .X.#OO.. ",
48" ..O.. ",
49" .. ",
50" "
51};
52
53static GtkWidget *window = NULL;
54
55
56/* Creates a tree model containing the completions */
57static GtkTreeModel *
58create_simple_completion_model (void)
59{
60 GtkListStore *store;
61 GtkTreeIter iter;
62
63 store = gtk_list_store_new (n_columns: 1, G_TYPE_STRING);
64
65 gtk_list_store_append (list_store: store, iter: &iter);
66 gtk_list_store_set (list_store: store, iter: &iter, 0, "GNOME", -1);
67 gtk_list_store_append (list_store: store, iter: &iter);
68 gtk_list_store_set (list_store: store, iter: &iter, 0, "gnominious", -1);
69 gtk_list_store_append (list_store: store, iter: &iter);
70 gtk_list_store_set (list_store: store, iter: &iter, 0, "Gnomonic projection", -1);
71
72 gtk_list_store_append (list_store: store, iter: &iter);
73 gtk_list_store_set (list_store: store, iter: &iter, 0, "total", -1);
74 gtk_list_store_append (list_store: store, iter: &iter);
75 gtk_list_store_set (list_store: store, iter: &iter, 0, "totally", -1);
76 gtk_list_store_append (list_store: store, iter: &iter);
77 gtk_list_store_set (list_store: store, iter: &iter, 0, "toto", -1);
78 gtk_list_store_append (list_store: store, iter: &iter);
79 gtk_list_store_set (list_store: store, iter: &iter, 0, "tottery", -1);
80 gtk_list_store_append (list_store: store, iter: &iter);
81 gtk_list_store_set (list_store: store, iter: &iter, 0, "totterer", -1);
82 gtk_list_store_append (list_store: store, iter: &iter);
83 gtk_list_store_set (list_store: store, iter: &iter, 0, "Totten trust", -1);
84 gtk_list_store_append (list_store: store, iter: &iter);
85 gtk_list_store_set (list_store: store, iter: &iter, 0, "totipotent", -1);
86 gtk_list_store_append (list_store: store, iter: &iter);
87 gtk_list_store_set (list_store: store, iter: &iter, 0, "totipotency", -1);
88 gtk_list_store_append (list_store: store, iter: &iter);
89 gtk_list_store_set (list_store: store, iter: &iter, 0, "totemism", -1);
90 gtk_list_store_append (list_store: store, iter: &iter);
91 gtk_list_store_set (list_store: store, iter: &iter, 0, "totem pole", -1);
92 gtk_list_store_append (list_store: store, iter: &iter);
93 gtk_list_store_set (list_store: store, iter: &iter, 0, "Totara", -1);
94 gtk_list_store_append (list_store: store, iter: &iter);
95 gtk_list_store_set (list_store: store, iter: &iter, 0, "totalizer", -1);
96 gtk_list_store_append (list_store: store, iter: &iter);
97 gtk_list_store_set (list_store: store, iter: &iter, 0, "totalizator", -1);
98 gtk_list_store_append (list_store: store, iter: &iter);
99 gtk_list_store_set (list_store: store, iter: &iter, 0, "totalitarianism", -1);
100 gtk_list_store_append (list_store: store, iter: &iter);
101 gtk_list_store_set (list_store: store, iter: &iter, 0, "total parenteral nutrition", -1);
102 gtk_list_store_append (list_store: store, iter: &iter);
103 gtk_list_store_set (list_store: store, iter: &iter, 0, "total hysterectomy", -1);
104 gtk_list_store_append (list_store: store, iter: &iter);
105 gtk_list_store_set (list_store: store, iter: &iter, 0, "total eclipse", -1);
106 gtk_list_store_append (list_store: store, iter: &iter);
107 gtk_list_store_set (list_store: store, iter: &iter, 0, "Totipresence", -1);
108 gtk_list_store_append (list_store: store, iter: &iter);
109 gtk_list_store_set (list_store: store, iter: &iter, 0, "Totipalmi", -1);
110 gtk_list_store_append (list_store: store, iter: &iter);
111 gtk_list_store_set (list_store: store, iter: &iter, 0, "zombie", -1);
112 gtk_list_store_append (list_store: store, iter: &iter);
113 gtk_list_store_set (list_store: store, iter: &iter, 0, "a\303\246x", -1);
114 gtk_list_store_append (list_store: store, iter: &iter);
115 gtk_list_store_set (list_store: store, iter: &iter, 0, "a\303\246y", -1);
116 gtk_list_store_append (list_store: store, iter: &iter);
117 gtk_list_store_set (list_store: store, iter: &iter, 0, "a\303\246z", -1);
118
119 return GTK_TREE_MODEL (store);
120}
121
122/* Creates a tree model containing the completions */
123static GtkTreeModel *
124create_completion_model (void)
125{
126 GtkListStore *store;
127 GtkTreeIter iter;
128 GdkPixbuf *pixbuf;
129
130 pixbuf = gdk_pixbuf_new_from_xpm_data (data: (const char **)book_closed_xpm);
131
132 store = gtk_list_store_new (n_columns: 2, GDK_TYPE_PIXBUF, G_TYPE_STRING);
133
134 gtk_list_store_append (list_store: store, iter: &iter);
135 gtk_list_store_set (list_store: store, iter: &iter, 0, pixbuf, 1, "ambient", -1);
136 gtk_list_store_append (list_store: store, iter: &iter);
137 gtk_list_store_set (list_store: store, iter: &iter, 0, pixbuf, 1, "ambidextrously", -1);
138 gtk_list_store_append (list_store: store, iter: &iter);
139 gtk_list_store_set (list_store: store, iter: &iter, 0, pixbuf, 1, "ambidexter", -1);
140 gtk_list_store_append (list_store: store, iter: &iter);
141 gtk_list_store_set (list_store: store, iter: &iter, 0, pixbuf, 1, "ambiguity", -1);
142 gtk_list_store_append (list_store: store, iter: &iter);
143 gtk_list_store_set (list_store: store, iter: &iter, 0, pixbuf, 1, "American Party", -1);
144 gtk_list_store_append (list_store: store, iter: &iter);
145 gtk_list_store_set (list_store: store, iter: &iter, 0, pixbuf, 1, "American mountain ash", -1);
146 gtk_list_store_append (list_store: store, iter: &iter);
147 gtk_list_store_set (list_store: store, iter: &iter, 0, pixbuf, 1, "amelioration", -1);
148 gtk_list_store_append (list_store: store, iter: &iter);
149 gtk_list_store_set (list_store: store, iter: &iter, 0, pixbuf, 1, "Amelia Earhart", -1);
150 gtk_list_store_append (list_store: store, iter: &iter);
151 gtk_list_store_set (list_store: store, iter: &iter, 0, pixbuf, 1, "Totten trust", -1);
152 gtk_list_store_append (list_store: store, iter: &iter);
153 gtk_list_store_set (list_store: store, iter: &iter, 0, pixbuf, 1, "Laminated arch", -1);
154
155 return GTK_TREE_MODEL (store);
156}
157
158static gboolean
159match_func (GtkEntryCompletion *completion,
160 const char *key,
161 GtkTreeIter *iter,
162 gpointer user_data)
163{
164 char *item = NULL;
165 GtkTreeModel *model;
166
167 gboolean ret = FALSE;
168
169 model = gtk_entry_completion_get_model (completion);
170
171 gtk_tree_model_get (tree_model: model, iter, 1, &item, -1);
172
173 if (item != NULL)
174 {
175 g_print (format: "compare %s %s\n", key, item);
176 if (strncmp (s1: key, s2: item, n: strlen (s: key)) == 0)
177 ret = TRUE;
178
179 g_free (mem: item);
180 }
181
182 return ret;
183}
184
185static int timer_count = 0;
186
187static const char *dynamic_completions[] = {
188 "GNOME",
189 "gnominious",
190 "Gnomonic projection",
191 "total",
192 "totally",
193 "toto",
194 "tottery",
195 "totterer",
196 "Totten trust",
197 "totipotent",
198 "totipotency",
199 "totemism",
200 "totem pole",
201 "Totara",
202 "totalizer",
203 "totalizator",
204 "totalitarianism",
205 "total parenteral nutrition",
206 "total hysterectomy",
207 "total eclipse",
208 "Totipresence",
209 "Totipalmi",
210 "zombie"
211};
212
213static int
214animation_timer (GtkEntryCompletion *completion)
215{
216 GtkTreeIter iter;
217 int n_completions = G_N_ELEMENTS (dynamic_completions);
218 int n;
219 static GtkListStore *old_store = NULL;
220 GtkListStore *store = GTK_LIST_STORE (gtk_entry_completion_get_model (completion));
221
222 if (timer_count % 10 == 0)
223 {
224 if (!old_store)
225 {
226 g_print (format: "removing model!\n");
227
228 old_store = g_object_ref (store);
229 gtk_entry_completion_set_model (completion, NULL);
230 }
231 else
232 {
233 g_print (format: "readding model!\n");
234
235 gtk_entry_completion_set_model (completion, GTK_TREE_MODEL (old_store));
236 g_object_unref (object: old_store);
237 old_store = NULL;
238 }
239
240 timer_count ++;
241 return TRUE;
242 }
243
244 if (!old_store)
245 {
246 if ((timer_count / n_completions) % 2 == 0)
247 {
248 n = timer_count % n_completions;
249 gtk_list_store_append (list_store: store, iter: &iter);
250 gtk_list_store_set (list_store: store, iter: &iter, 0, dynamic_completions[n], -1);
251
252 }
253 else
254 {
255 if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), iter: &iter))
256 gtk_list_store_remove (list_store: store, iter: &iter);
257 }
258 }
259
260 timer_count++;
261 return TRUE;
262}
263
264static gboolean
265match_selected_cb (GtkEntryCompletion *completion,
266 GtkTreeModel *model,
267 GtkTreeIter *iter)
268{
269 char *str;
270 GtkWidget *entry;
271
272 entry = gtk_entry_completion_get_entry (completion);
273 gtk_tree_model_get (GTK_TREE_MODEL (model), iter, 1, &str, -1);
274 gtk_editable_set_text (GTK_EDITABLE (entry), text: str);
275 gtk_editable_set_position (GTK_EDITABLE (entry), position: -1);
276 g_free (mem: str);
277
278 return TRUE;
279}
280
281static void
282quit_cb (GtkWidget *widget,
283 gpointer data)
284{
285 gboolean *done = data;
286
287 *done = TRUE;
288
289 g_main_context_wakeup (NULL);
290}
291
292int
293main (int argc, char *argv[])
294{
295 GtkWidget *vbox;
296 GtkWidget *label;
297 GtkWidget *entry;
298 GtkEntryCompletion *completion;
299 GtkTreeModel *completion_model;
300 GtkCellRenderer *cell;
301 gboolean done = FALSE;
302
303 gtk_init ();
304
305 window = gtk_window_new ();
306 g_signal_connect (window, "destroy", G_CALLBACK (quit_cb), &done);
307
308 vbox = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 2);
309 gtk_widget_set_margin_start (widget: vbox, margin: 5);
310 gtk_widget_set_margin_end (widget: vbox, margin: 5);
311 gtk_widget_set_margin_top (widget: vbox, margin: 5);
312 gtk_widget_set_margin_bottom (widget: vbox, margin: 5);
313 gtk_window_set_child (GTK_WINDOW (window), child: vbox);
314
315 label = gtk_label_new (NULL);
316
317 gtk_label_set_markup (GTK_LABEL (label), str: "Completion demo, try writing <b>total</b> or <b>gnome</b> for example.");
318 gtk_box_append (GTK_BOX (vbox), child: label);
319
320 /* Create our first entry */
321 entry = gtk_entry_new ();
322
323 /* Create the completion object */
324 completion = gtk_entry_completion_new ();
325 gtk_entry_completion_set_inline_completion (completion, TRUE);
326
327 /* Assign the completion to the entry */
328 gtk_entry_set_completion (GTK_ENTRY (entry), completion);
329 g_object_unref (object: completion);
330
331 gtk_box_append (GTK_BOX (vbox), child: entry);
332
333 /* Create a tree model and use it as the completion model */
334 completion_model = create_simple_completion_model ();
335 gtk_entry_completion_set_model (completion, model: completion_model);
336 g_object_unref (object: completion_model);
337
338 /* Use model column 0 as the text column */
339 gtk_entry_completion_set_text_column (completion, column: 0);
340
341 /* Create our second entry */
342 entry = gtk_entry_new ();
343
344 /* Create the completion object */
345 completion = gtk_entry_completion_new ();
346
347 /* Assign the completion to the entry */
348 gtk_entry_set_completion (GTK_ENTRY (entry), completion);
349 g_object_unref (object: completion);
350
351 gtk_box_append (GTK_BOX (vbox), child: entry);
352
353 /* Create a tree model and use it as the completion model */
354 completion_model = create_completion_model ();
355 gtk_entry_completion_set_model (completion, model: completion_model);
356 gtk_entry_completion_set_minimum_key_length (completion, length: 2);
357 g_object_unref (object: completion_model);
358
359 /* Use model column 1 as the text column */
360 cell = gtk_cell_renderer_pixbuf_new ();
361 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (completion), cell, FALSE);
362 gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (completion), cell,
363 "pixbuf", 0, NULL);
364
365 cell = gtk_cell_renderer_text_new ();
366 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (completion), cell, FALSE);
367 gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (completion), cell,
368 "text", 1, NULL);
369
370 gtk_entry_completion_set_match_func (completion, func: match_func, NULL, NULL);
371 g_signal_connect (completion, "match-selected",
372 G_CALLBACK (match_selected_cb), NULL);
373
374 /* Create our third entry */
375 entry = gtk_entry_new ();
376
377 /* Create the completion object */
378 completion = gtk_entry_completion_new ();
379
380 /* Assign the completion to the entry */
381 gtk_entry_set_completion (GTK_ENTRY (entry), completion);
382 g_object_unref (object: completion);
383
384 gtk_box_append (GTK_BOX (vbox), child: entry);
385
386 /* Create a tree model and use it as the completion model */
387 completion_model = GTK_TREE_MODEL (gtk_list_store_new (1, G_TYPE_STRING));
388
389 gtk_entry_completion_set_model (completion, model: completion_model);
390 g_object_unref (object: completion_model);
391
392 /* Use model column 0 as the text column */
393 gtk_entry_completion_set_text_column (completion, column: 0);
394
395 /* Fill the completion dynamically */
396 g_timeout_add (interval: 1000, function: (GSourceFunc) animation_timer, data: completion);
397
398 /* Fourth entry */
399 gtk_box_append (GTK_BOX (vbox), child: gtk_label_new (str: "Model-less entry completion"));
400
401 entry = gtk_entry_new ();
402
403 /* Create the completion object */
404 completion = gtk_entry_completion_new ();
405
406 /* Assign the completion to the entry */
407 gtk_entry_set_completion (GTK_ENTRY (entry), completion);
408 g_object_unref (object: completion);
409
410 gtk_box_append (GTK_BOX (vbox), child: entry);
411
412 gtk_widget_show (widget: window);
413
414 while (!done)
415 g_main_context_iteration (NULL, TRUE);
416
417 return 0;
418}
419
420
421

source code of gtk/tests/testentrycompletion.c