]> Pileus Git - ~andy/gtk/blob - tests/testentrycompletion.c
gtk: remove "gboolean homogeneous" from gtk_box_new()
[~andy/gtk] / tests / testentrycompletion.c
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 *
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 *
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
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
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
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 
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
294 new_prop_editor (GObject *object)
295 {
296         gtk_widget_show (create_prop_editor (object, G_OBJECT_TYPE (object)));
297 }
298
299 static void
300 add_with_prop_edit_button (GtkWidget *vbox, GtkWidget *entry, GtkEntryCompletion *completion)
301 {
302         GtkWidget *hbox, *button;
303
304         hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 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 
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_box_new (GTK_ORIENTATION_VERTICAL, 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