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, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
19 */
20
21 #include "config.h"
22 #include <stdlib.h>
23 #include <string.h>
24 #include <gtk/gtk.h>
25
26 #include "prop-editor.h"
27
28 /* Don't copy this bad example; inline RGB data is always a better
29 * idea than inline XPMs.
30 */
31 static char *book_closed_xpm[] = {
32 "16 16 6 1",
33 " c None s None",
34 ". c black",
35 "X c red",
36 "o c yellow",
37 "O c #808080",
38 "# c white",
39 " ",
40 " .. ",
41 " ..XX. ",
42 " ..XXXXX. ",
43 " ..XXXXXXXX. ",
44 ".ooXXXXXXXXX. ",
45 "..ooXXXXXXXXX. ",
46 ".X.ooXXXXXXXXX. ",
47 ".XX.ooXXXXXX.. ",
48 " .XX.ooXXX..#O ",
49 " .XX.oo..##OO. ",
50 " .XX..##OO.. ",
51 " .X.#OO.. ",
52 " ..O.. ",
53 " .. ",
54 " "
55 };
56
57 static GtkWidget *window = NULL;
58
59
60 /* Creates a tree model containing the completions */
61 GtkTreeModel *
create_simple_completion_model(void)62 create_simple_completion_model (void)
63 {
64 GtkListStore *store;
65 GtkTreeIter iter;
66
67 store = gtk_list_store_new (1, G_TYPE_STRING);
68
69 gtk_list_store_append (store, &iter);
70 gtk_list_store_set (store, &iter, 0, "GNOME", -1);
71 gtk_list_store_append (store, &iter);
72 gtk_list_store_set (store, &iter, 0, "gnominious", -1);
73 gtk_list_store_append (store, &iter);
74 gtk_list_store_set (store, &iter, 0, "Gnomonic projection", -1);
75
76 gtk_list_store_append (store, &iter);
77 gtk_list_store_set (store, &iter, 0, "total", -1);
78 gtk_list_store_append (store, &iter);
79 gtk_list_store_set (store, &iter, 0, "totally", -1);
80 gtk_list_store_append (store, &iter);
81 gtk_list_store_set (store, &iter, 0, "toto", -1);
82 gtk_list_store_append (store, &iter);
83 gtk_list_store_set (store, &iter, 0, "tottery", -1);
84 gtk_list_store_append (store, &iter);
85 gtk_list_store_set (store, &iter, 0, "totterer", -1);
86 gtk_list_store_append (store, &iter);
87 gtk_list_store_set (store, &iter, 0, "Totten trust", -1);
88 gtk_list_store_append (store, &iter);
89 gtk_list_store_set (store, &iter, 0, "totipotent", -1);
90 gtk_list_store_append (store, &iter);
91 gtk_list_store_set (store, &iter, 0, "totipotency", -1);
92 gtk_list_store_append (store, &iter);
93 gtk_list_store_set (store, &iter, 0, "totemism", -1);
94 gtk_list_store_append (store, &iter);
95 gtk_list_store_set (store, &iter, 0, "totem pole", -1);
96 gtk_list_store_append (store, &iter);
97 gtk_list_store_set (store, &iter, 0, "Totara", -1);
98 gtk_list_store_append (store, &iter);
99 gtk_list_store_set (store, &iter, 0, "totalizer", -1);
100 gtk_list_store_append (store, &iter);
101 gtk_list_store_set (store, &iter, 0, "totalizator", -1);
102 gtk_list_store_append (store, &iter);
103 gtk_list_store_set (store, &iter, 0, "totalitarianism", -1);
104 gtk_list_store_append (store, &iter);
105 gtk_list_store_set (store, &iter, 0, "total parenteral nutrition", -1);
106 gtk_list_store_append (store, &iter);
107 gtk_list_store_set (store, &iter, 0, "total hysterectomy", -1);
108 gtk_list_store_append (store, &iter);
109 gtk_list_store_set (store, &iter, 0, "total eclipse", -1);
110 gtk_list_store_append (store, &iter);
111 gtk_list_store_set (store, &iter, 0, "Totipresence", -1);
112 gtk_list_store_append (store, &iter);
113 gtk_list_store_set (store, &iter, 0, "Totipalmi", -1);
114 gtk_list_store_append (store, &iter);
115 gtk_list_store_set (store, &iter, 0, "zombie", -1);
116 gtk_list_store_append (store, &iter);
117 gtk_list_store_set (store, &iter, 0, "a\303\246x", -1);
118 gtk_list_store_append (store, &iter);
119 gtk_list_store_set (store, &iter, 0, "a\303\246y", -1);
120 gtk_list_store_append (store, &iter);
121 gtk_list_store_set (store, &iter, 0, "a\303\246z", -1);
122
123 return GTK_TREE_MODEL (store);
124 }
125
126 /* Creates a tree model containing the completions */
127 GtkTreeModel *
create_completion_model(void)128 create_completion_model (void)
129 {
130 GtkListStore *store;
131 GtkTreeIter iter;
132 GdkPixbuf *pixbuf;
133
134 pixbuf = gdk_pixbuf_new_from_xpm_data ((const char **)book_closed_xpm);
135
136 store = gtk_list_store_new (2, GDK_TYPE_PIXBUF, G_TYPE_STRING);
137
138 gtk_list_store_append (store, &iter);
139 gtk_list_store_set (store, &iter, 0, pixbuf, 1, "ambient", -1);
140 gtk_list_store_append (store, &iter);
141 gtk_list_store_set (store, &iter, 0, pixbuf, 1, "ambidextrously", -1);
142 gtk_list_store_append (store, &iter);
143 gtk_list_store_set (store, &iter, 0, pixbuf, 1, "ambidexter", -1);
144 gtk_list_store_append (store, &iter);
145 gtk_list_store_set (store, &iter, 0, pixbuf, 1, "ambiguity", -1);
146 gtk_list_store_append (store, &iter);
147 gtk_list_store_set (store, &iter, 0, pixbuf, 1, "American Party", -1);
148 gtk_list_store_append (store, &iter);
149 gtk_list_store_set (store, &iter, 0, pixbuf, 1, "American mountain ash", -1);
150 gtk_list_store_append (store, &iter);
151 gtk_list_store_set (store, &iter, 0, pixbuf, 1, "amelioration", -1);
152 gtk_list_store_append (store, &iter);
153 gtk_list_store_set (store, &iter, 0, pixbuf, 1, "Amelia Earhart", -1);
154 gtk_list_store_append (store, &iter);
155 gtk_list_store_set (store, &iter, 0, pixbuf, 1, "Totten trust", -1);
156 gtk_list_store_append (store, &iter);
157 gtk_list_store_set (store, &iter, 0, pixbuf, 1, "Laminated arch", -1);
158
159 return GTK_TREE_MODEL (store);
160 }
161
162 static gboolean
match_func(GtkEntryCompletion * completion,const gchar * key,GtkTreeIter * iter,gpointer user_data)163 match_func (GtkEntryCompletion *completion,
164 const gchar *key,
165 GtkTreeIter *iter,
166 gpointer user_data)
167 {
168 gchar *item = NULL;
169 GtkTreeModel *model;
170
171 gboolean ret = FALSE;
172
173 model = gtk_entry_completion_get_model (completion);
174
175 gtk_tree_model_get (model, iter, 1, &item, -1);
176
177 if (item != NULL)
178 {
179 g_print ("compare %s %s\n", key, item);
180 if (strncmp (key, item, strlen (key)) == 0)
181 ret = TRUE;
182
183 g_free (item);
184 }
185
186 return ret;
187 }
188
189 static void
activated_cb(GtkEntryCompletion * completion,gint index,gpointer user_data)190 activated_cb (GtkEntryCompletion *completion,
191 gint index,
192 gpointer user_data)
193 {
194 g_print ("action activated: %d\n", index);
195 }
196
197 static gint timer_count = 0;
198
199 static gchar *dynamic_completions[] = {
200 "GNOME",
201 "gnominious",
202 "Gnomonic projection",
203 "total",
204 "totally",
205 "toto",
206 "tottery",
207 "totterer",
208 "Totten trust",
209 "totipotent",
210 "totipotency",
211 "totemism",
212 "totem pole",
213 "Totara",
214 "totalizer",
215 "totalizator",
216 "totalitarianism",
217 "total parenteral nutrition",
218 "total hysterectomy",
219 "total eclipse",
220 "Totipresence",
221 "Totipalmi",
222 "zombie"
223 };
224
225 static gint
animation_timer(GtkEntryCompletion * completion)226 animation_timer (GtkEntryCompletion *completion)
227 {
228 GtkTreeIter iter;
229 gint n_completions = G_N_ELEMENTS (dynamic_completions);
230 gint n;
231 static GtkListStore *old_store = NULL;
232 GtkListStore *store = GTK_LIST_STORE (gtk_entry_completion_get_model (completion));
233
234 if (timer_count % 10 == 0)
235 {
236 if (!old_store)
237 {
238 g_print ("removing model!\n");
239
240 old_store = g_object_ref (gtk_entry_completion_get_model (completion));
241 gtk_entry_completion_set_model (completion, NULL);
242 }
243 else
244 {
245 g_print ("readding model!\n");
246
247 gtk_entry_completion_set_model (completion, GTK_TREE_MODEL (old_store));
248 g_object_unref (old_store);
249 old_store = NULL;
250 }
251
252 timer_count ++;
253 return TRUE;
254 }
255
256 if (!old_store)
257 {
258 if ((timer_count / n_completions) % 2 == 0)
259 {
260 n = timer_count % n_completions;
261 gtk_list_store_append (store, &iter);
262 gtk_list_store_set (store, &iter, 0, dynamic_completions[n], -1);
263
264 }
265 else
266 {
267 if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter))
268 gtk_list_store_remove (store, &iter);
269 }
270 }
271
272 timer_count++;
273 return TRUE;
274 }
275
276 gboolean
match_selected_cb(GtkEntryCompletion * completion,GtkTreeModel * model,GtkTreeIter * iter)277 match_selected_cb (GtkEntryCompletion *completion,
278 GtkTreeModel *model,
279 GtkTreeIter *iter)
280 {
281 gchar *str;
282 GtkWidget *entry;
283
284 entry = gtk_entry_completion_get_entry (completion);
285 gtk_tree_model_get (GTK_TREE_MODEL (model), iter, 1, &str, -1);
286 gtk_entry_set_text (GTK_ENTRY (entry), str);
287 gtk_editable_set_position (GTK_EDITABLE (entry), -1);
288 g_free (str);
289
290 return TRUE;
291 }
292
293 static void
new_prop_editor(GObject * object)294 new_prop_editor (GObject *object)
295 {
296 gtk_widget_show (create_prop_editor (object, G_OBJECT_TYPE (object)));
297 }
298
299 static void
add_with_prop_edit_button(GtkWidget * vbox,GtkWidget * entry,GtkEntryCompletion * completion)300 add_with_prop_edit_button (GtkWidget *vbox, GtkWidget *entry, GtkEntryCompletion *completion)
301 {
302 GtkWidget *hbox, *button;
303
304 hbox = gtk_hbox_new (FALSE, 12);
305 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
306
307 gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
308
309 button = gtk_button_new_with_label ("Properties");
310 g_signal_connect_swapped (button, "clicked", G_CALLBACK (new_prop_editor), completion);
311 gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
312 }
313
314 int
main(int argc,char * argv[])315 main (int argc, char *argv[])
316 {
317 GtkWidget *vbox;
318 GtkWidget *label;
319 GtkWidget *entry;
320 GtkEntryCompletion *completion;
321 GtkTreeModel *completion_model;
322 GtkCellRenderer *cell;
323
324 gtk_init (&argc, &argv);
325
326 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
327 gtk_container_set_border_width (GTK_CONTAINER (window), 5);
328 g_signal_connect (window, "delete_event", gtk_main_quit, NULL);
329
330 vbox = gtk_vbox_new (FALSE, 2);
331 gtk_container_add (GTK_CONTAINER (window), vbox);
332
333 gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
334
335 label = gtk_label_new (NULL);
336
337 gtk_label_set_markup (GTK_LABEL (label), "Completion demo, try writing <b>total</b> or <b>gnome</b> for example.");
338 gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
339
340 /* Create our first entry */
341 entry = gtk_entry_new ();
342
343 /* Create the completion object */
344 completion = gtk_entry_completion_new ();
345 gtk_entry_completion_set_inline_completion (completion, TRUE);
346
347 /* Assign the completion to the entry */
348 gtk_entry_set_completion (GTK_ENTRY (entry), completion);
349 g_object_unref (completion);
350
351 add_with_prop_edit_button (vbox, entry, completion);
352
353 /* Create a tree model and use it as the completion model */
354 completion_model = create_simple_completion_model ();
355 gtk_entry_completion_set_model (completion, completion_model);
356 g_object_unref (completion_model);
357
358 /* Use model column 0 as the text column */
359 gtk_entry_completion_set_text_column (completion, 0);
360
361 /* Create our second entry */
362 entry = gtk_entry_new ();
363
364 /* Create the completion object */
365 completion = gtk_entry_completion_new ();
366
367 /* Assign the completion to the entry */
368 gtk_entry_set_completion (GTK_ENTRY (entry), completion);
369 g_object_unref (completion);
370
371 add_with_prop_edit_button (vbox, entry, completion);
372
373 /* Create a tree model and use it as the completion model */
374 completion_model = create_completion_model ();
375 gtk_entry_completion_set_model (completion, completion_model);
376 gtk_entry_completion_set_minimum_key_length (completion, 2);
377 g_object_unref (completion_model);
378
379 /* Use model column 1 as the text column */
380 cell = gtk_cell_renderer_pixbuf_new ();
381 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (completion), cell, FALSE);
382 gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (completion), cell,
383 "pixbuf", 0, NULL);
384
385 cell = gtk_cell_renderer_text_new ();
386 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (completion), cell, FALSE);
387 gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (completion), cell,
388 "text", 1, NULL);
389
390 gtk_entry_completion_set_match_func (completion, match_func, NULL, NULL);
391 g_signal_connect (completion, "match-selected",
392 G_CALLBACK (match_selected_cb), NULL);
393
394 gtk_entry_completion_insert_action_text (completion, 100, "action!");
395 gtk_entry_completion_insert_action_text (completion, 101, "'nother action!");
396 g_signal_connect (completion, "action_activated", G_CALLBACK (activated_cb), NULL);
397
398 /* Create our third entry */
399 entry = gtk_entry_new ();
400
401 /* Create the completion object */
402 completion = gtk_entry_completion_new ();
403
404 /* Assign the completion to the entry */
405 gtk_entry_set_completion (GTK_ENTRY (entry), completion);
406 g_object_unref (completion);
407
408 add_with_prop_edit_button (vbox, entry, completion);
409
410 /* Create a tree model and use it as the completion model */
411 completion_model = GTK_TREE_MODEL (gtk_list_store_new (1, G_TYPE_STRING));
412
413 gtk_entry_completion_set_model (completion, completion_model);
414 g_object_unref (completion_model);
415
416 /* Use model column 0 as the text column */
417 gtk_entry_completion_set_text_column (completion, 0);
418
419 /* Fill the completion dynamically */
420 gdk_threads_add_timeout (1000, (GSourceFunc) animation_timer, completion);
421
422 /* Fourth entry */
423 gtk_box_pack_start (GTK_BOX (vbox), gtk_label_new ("Model-less entry completion"), FALSE, FALSE, 0);
424
425 entry = gtk_entry_new ();
426
427 /* Create the completion object */
428 completion = gtk_entry_completion_new ();
429
430 /* Assign the completion to the entry */
431 gtk_entry_set_completion (GTK_ENTRY (entry), completion);
432 g_object_unref (completion);
433
434 add_with_prop_edit_button (vbox, entry, completion);
435
436 gtk_widget_show_all (window);
437
438 gtk_main ();
439
440 return 0;
441 }
442
443
444