2008-07-29 Claudio Saavedra <csaavedra@igalia.com>
[hildon] / src / hildon-code-dialog.c
1 /*
2  * This file is a part of hildon
3  *
4  * Copyright (C) 2006 Nokia Corporation, all rights reserved.
5  *
6  * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public License
10  * as published by the Free Software Foundation; version 2.1 of
11  * the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21  * 02110-1301 USA
22  *
23  */
24
25 /**
26  * SECTION:hildon-code-dialog
27  * @short_description: A keypad-like widget used to enter pincodes.
28  *
29  * #HildonCodeDialog displays a keypad that can be used to enter 
30  * numerical pin codes or lock codes. It emits a 'input' signal each time 
31  * an input action is performed on the dialog.
32  *
33  */
34
35 /* FIXME We need property access in this widget */
36
37 #ifdef                                          HAVE_CONFIG_H
38 #include                                        <config.h>
39 #endif
40
41 #include                                        "hildon-code-dialog.h"
42 #include                                        "hildon-defines.h"
43 #include                                        "hildon-banner.h"
44
45 #include                                        <gdk/gdkkeysyms.h>
46 #include                                        <gtk/gtkbutton.h>
47 #include                                        <gtk/gtkentry.h>
48 #include                                        <gtk/gtkicontheme.h>
49 #include                                        <gtk/gtktable.h>
50 #include                                        <gtk/gtkvbox.h>
51 #include                                        <gtk/gtkbbox.h>
52 #include                                        <gtk/gtklabel.h>
53 #include                                        <gtk/gtkalignment.h>
54 #include                                        <gtk/gtkversion.h>
55 #include                                        <libintl.h>
56 #include                                        "hildon-code-dialog-private.h"
57
58 #define                                         HEIGHT (48-HILDON_MARGIN_DEFAULT)
59
60 #define                                         WIDTH  (100-HILDON_MARGIN_DEFAULT)
61
62 #define                                         BACKSPACE_ICON "qgn_calculator_backspace"
63
64 #define                                         _(String) \
65                                                 dgettext("hildon-libs", String)
66
67 #define                                         c_(String) \
68                                                 dgettext("hildon-common-strings", String)
69
70 #define                                         DEVICELOCK_OK _("secu_enter_lock_code_dialog_ok")
71
72 #define                                         DEVICELOCK_CANCEL _("secu_enter_lock_code_dialog_cancel")
73
74 #define                                         DEVICELOCK_TITLE _("secu_application_title")
75
76 #define                                         DEVICELOCK_MAX_CHAR_REACHED c_("ckdg_ib_maximum_characters_reached")
77         
78 #define                                         MAX_PINCODE_LEN (10)
79
80 static void 
81 hildon_code_dialog_class_init                   (HildonCodeDialogClass *cd_class);
82
83 static void 
84 hildon_code_dialog_init                         (HildonCodeDialog *self);
85
86 static void
87 hildon_code_dialog_realize                      (GtkWidget *widget);
88
89 static void
90 hildon_code_dialog_unrealize                    (GtkWidget *widget);
91
92 static void
93 hildon_code_dialog_finalize                     (GObject *object);
94
95 static void 
96 hildon_code_dialog_button_clicked               (GtkButton *buttonm,
97                                                  gpointer user_data);
98
99 static void
100 hildon_code_dialog_backspace                    (HildonCodeDialog *dialog);
101
102 static void
103 hildon_code_dialog_im_commit                    (GtkIMContext *im_context,
104                                                  gchar *utf8,
105                                                  gpointer user_data);
106
107 static void 
108 hildon_code_dialog_insert_text                  (GtkEditable *editable,
109                                                  gchar *new_text,
110                                                  gint new_text_length,
111                                                  gint *position,
112                                                  gpointer user_data);
113
114 static gboolean 
115 hildon_code_dialog_key_press_event              (GtkWidget *widget,
116                                                  GdkEventKey *event,
117                                                  gpointer user_data);
118
119 static void 
120 hildon_code_dialog_real_input                   (HildonCodeDialog *dialog);
121
122 static void
123 hildon_code_dialog_input                        (HildonCodeDialog *dialog);
124
125 static GtkDialogClass*                          parent_class = NULL;
126
127 static guint                                    input_signal;
128
129 /**
130  * hildon_code_dialog_get_type:
131  *
132  * Initializes and returns the type of a hildon code dialog.
133  *
134  * @Returns: GType of #HildonCodeDialog
135  */
136 GType G_GNUC_CONST
137 hildon_code_dialog_get_type                     (void)
138 {
139     static GType type = 0;
140
141     if (!type)
142     {
143         static const GTypeInfo info = 
144         {
145             sizeof (HildonCodeDialogClass),
146             NULL, /* base_init */
147             NULL, /* base_finalize */
148             (GClassInitFunc) hildon_code_dialog_class_init,
149             NULL,       /* class_finalize */
150             NULL,       /* class_data */
151             sizeof (HildonCodeDialog),
152             0,  /* n_preallocs */
153             (GInstanceInitFunc) hildon_code_dialog_init
154         };
155         type = g_type_register_static (GTK_TYPE_DIALOG,
156                 "HildonCodeDialog", &info, 0);
157     }
158     return type;
159 }
160
161 static void
162 hildon_code_dialog_class_init                   (HildonCodeDialogClass *cd_class)
163 {
164     GObjectClass *gobject_class = G_OBJECT_CLASS (cd_class);
165     GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (cd_class);
166
167     parent_class = GTK_DIALOG_CLASS (g_type_class_peek_parent (cd_class));
168     g_type_class_add_private (cd_class, sizeof (HildonCodeDialogPrivate));
169
170     gobject_class->finalize = hildon_code_dialog_finalize;
171
172     widget_class->realize = hildon_code_dialog_realize;
173     widget_class->unrealize = hildon_code_dialog_unrealize;
174
175     cd_class->input = hildon_code_dialog_real_input;
176
177     /* FIXME Document this signal! */
178     input_signal = g_signal_new("input",
179                                 HILDON_TYPE_CODE_DIALOG,
180                                 G_SIGNAL_RUN_LAST,
181                                 G_STRUCT_OFFSET (HildonCodeDialogClass, input),
182                                 NULL, NULL,
183                                 g_cclosure_marshal_VOID__VOID,
184                                 G_TYPE_NONE,
185                                 0);
186 }
187
188 static void 
189 hildon_code_dialog_init                         (HildonCodeDialog *dialog)
190 {
191     HildonCodeDialogPrivate *priv;
192     gint i, x, y;
193     GtkWidget *dialog_vbox1 = NULL;
194     GtkWidget *table = NULL;
195     GtkWidget *alignment = NULL;
196     GtkWidget *vbox1 = NULL;
197     GtkWidget *image1 = NULL;
198     GtkWidget *dialog_action_area1 = NULL;
199     GdkGeometry hints;
200     GtkWidget *okButton;
201     GtkWidget *cancelButton;
202
203     priv = HILDON_CODE_DIALOG_GET_PRIVATE (dialog);
204     g_assert (priv);
205     
206     const gchar* numstrs[10] = {
207         "0","1","2","3","4","5","6","7","8","9"
208     };
209
210     GdkPixbuf* pixbuf = NULL;
211     GtkIconTheme* icon_theme = NULL;
212     GtkIconInfo *icon_info = NULL;
213     gint base_size = 0;
214
215     /* Set default title */
216     gtk_window_set_title (GTK_WINDOW (dialog), DEVICELOCK_TITLE);
217
218     gtk_window_set_type_hint (GTK_WINDOW (dialog), GDK_WINDOW_TYPE_HINT_DIALOG);
219     gtk_dialog_set_has_separator ((GtkDialog *) dialog, FALSE);
220
221     hints.min_width  = -1;
222     hints.min_height = -1;
223     hints.max_width  = -1;
224     hints.max_height = -1;
225
226     gtk_window_set_geometry_hints (GTK_WINDOW (dialog), GTK_WIDGET (dialog), &hints,
227             GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE);
228
229     table = gtk_table_new (4, 3, FALSE);
230     gtk_table_set_row_spacings (GTK_TABLE (table), HILDON_MARGIN_DEFAULT );
231     gtk_table_set_col_spacings (GTK_TABLE (table), HILDON_MARGIN_DEFAULT );
232
233     dialog_vbox1 = GTK_DIALOG (dialog)->vbox;
234     vbox1 = gtk_vbox_new (FALSE, 0);
235     gtk_box_set_spacing (GTK_BOX (vbox1), HILDON_MARGIN_DOUBLE);
236
237     priv->help_text = gtk_label_new ("");
238     alignment = gtk_alignment_new (0.5,0,1,1);
239     gtk_container_add (GTK_CONTAINER (alignment), priv->help_text);
240
241     priv->entry = gtk_entry_new ();
242     
243     GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (priv->entry), GTK_CAN_FOCUS);
244     gtk_entry_set_invisible_char (GTK_ENTRY (priv->entry), g_utf8_get_char ("*"));
245     gtk_entry_set_alignment (GTK_ENTRY (priv->entry), 1.0);
246
247     gtk_editable_set_editable (GTK_EDITABLE (priv->entry),FALSE);
248     gtk_entry_set_visibility (GTK_ENTRY (priv->entry), FALSE);
249
250     gtk_box_pack_start (GTK_BOX (vbox1), alignment, TRUE,FALSE,0);
251     gtk_box_pack_start (GTK_BOX (vbox1), priv->entry, TRUE,FALSE,0);
252     gtk_box_pack_start (GTK_BOX (vbox1), table, FALSE,TRUE,0);
253
254     gtk_box_pack_start (GTK_BOX (dialog_vbox1), vbox1, FALSE,TRUE,0);
255
256     for(i = 1;i <= 3; i++) {
257         priv->buttons[0][i-1] = gtk_button_new_with_mnemonic (numstrs[i]);
258         gtk_widget_set_size_request (priv->buttons[0][i-1], WIDTH, HEIGHT);
259         gtk_table_attach_defaults (GTK_TABLE (table), priv->buttons[0][i-1],
260                 i-1, i, 0, 1);
261     }
262
263     for(i = 4;i <= 6;i++) {
264         priv->buttons[1][i-4] = gtk_button_new_with_mnemonic (numstrs[i]);
265         gtk_widget_set_size_request (priv->buttons[1][i-4], WIDTH, HEIGHT);
266         gtk_table_attach_defaults (GTK_TABLE (table), priv->buttons[1][i-4],
267                 i-4, i-3, 1, 2);
268     }
269
270     for(i=7;i<=9;i++) {
271         priv->buttons[2][i-7] = gtk_button_new_with_mnemonic (numstrs[i]);
272         gtk_widget_set_size_request (priv->buttons[2][i-7], WIDTH, HEIGHT);
273         gtk_table_attach_defaults (GTK_TABLE (table), priv->buttons[2][i-7],
274                 i-7, i-6, 2, 3);
275     }
276
277     priv->buttons[3][0] = priv->buttons[3][1] = 
278         gtk_button_new_with_mnemonic (numstrs[0]);
279     gtk_widget_set_size_request (priv->buttons[3][0], WIDTH, HEIGHT);
280     gtk_table_attach (GTK_TABLE (table), priv->buttons[3][0],
281             0,2,3,4, (GtkAttachOptions) (GTK_FILL),
282             (GtkAttachOptions) (0), 0, 0);
283
284     priv->buttons[3][2] = gtk_button_new ();
285     gtk_widget_set_size_request (priv->buttons[3][2], WIDTH, HEIGHT);
286     gtk_table_attach_defaults (GTK_TABLE (table), priv->buttons[3][2],
287             2, 3, 3, 4);
288
289     icon_theme = gtk_icon_theme_get_default ();
290
291     icon_info = gtk_icon_theme_lookup_icon (icon_theme, BACKSPACE_ICON, 1,
292             GTK_ICON_LOOKUP_NO_SVG);
293     base_size = gtk_icon_info_get_base_size (icon_info);
294     gtk_icon_info_free (icon_info);
295     icon_info = NULL;
296     pixbuf = gtk_icon_theme_load_icon (icon_theme,
297             BACKSPACE_ICON, base_size,
298             GTK_ICON_LOOKUP_NO_SVG,
299             NULL);
300
301     image1 = gtk_image_new_from_pixbuf (pixbuf);
302     g_object_unref (G_OBJECT(pixbuf));
303     gtk_container_add (GTK_CONTAINER (priv->buttons[3][2]), image1);
304     dialog_action_area1 = GTK_DIALOG (dialog)->action_area;
305     gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area1),
306 #if GTK_CHECK_VERSION(2,11,0) || defined(MAEMO_GTK)
307                                GTK_BUTTONBOX_CENTER);
308 #else
309                                GTK_BUTTONBOX_DEFAULT_STYLE);
310 #endif
311
312     okButton = gtk_dialog_add_button (GTK_DIALOG (dialog) ,DEVICELOCK_OK,
313             GTK_RESPONSE_OK);
314     cancelButton =
315         gtk_dialog_add_button (GTK_DIALOG (dialog), DEVICELOCK_CANCEL,
316                 GTK_RESPONSE_CANCEL);
317     
318     gtk_widget_set_sensitive (okButton, FALSE);
319
320     priv->buttons[4][0] = priv->buttons[4][1] = okButton;
321     priv->buttons[4][2] = cancelButton;
322
323     priv->im_context = gtk_im_multicontext_new();
324 #ifdef MAEMO_GTK
325     g_object_set (G_OBJECT (priv->im_context), "hildon-input-mode",
326                   HILDON_GTK_INPUT_MODE_NUMERIC, NULL);
327 #endif
328
329     /*
330        Connect signals.
331     */
332     g_signal_connect (G_OBJECT (priv->im_context), "commit",
333                       G_CALLBACK (hildon_code_dialog_im_commit), dialog);
334
335     g_signal_connect (G_OBJECT (priv->entry), "insert_text",
336             G_CALLBACK (hildon_code_dialog_insert_text), dialog);
337     
338     gtk_entry_set_max_length (GTK_ENTRY (priv->entry), MAX_PINCODE_LEN);
339
340     for (x = 0; x < 3; x++)
341     {
342         for (y = 0; y < 3; y++)
343         {
344             g_signal_connect (G_OBJECT (priv->buttons[x][y]), "clicked",
345                 G_CALLBACK (hildon_code_dialog_button_clicked), dialog);
346             g_signal_connect (G_OBJECT (priv->buttons[x][y]), "key-press-event",
347                 G_CALLBACK (hildon_code_dialog_key_press_event), dialog);
348         }
349     }
350             
351     g_signal_connect (G_OBJECT (priv->buttons[3][0]), "clicked",
352                 G_CALLBACK (hildon_code_dialog_button_clicked), dialog);
353     g_signal_connect (G_OBJECT (priv->buttons[3][0]), "key-press-event",
354                 G_CALLBACK (hildon_code_dialog_key_press_event), dialog);
355     
356     g_signal_connect (G_OBJECT (priv->buttons[3][2]), "clicked",
357                 G_CALLBACK (hildon_code_dialog_button_clicked), dialog);
358     g_signal_connect (G_OBJECT (priv->buttons[3][2]), "key-press-event",
359                 G_CALLBACK (hildon_code_dialog_key_press_event), dialog);
360         
361     g_signal_connect (G_OBJECT (okButton), "key-press-event",
362                 G_CALLBACK(hildon_code_dialog_key_press_event), dialog);
363     
364     g_signal_connect (G_OBJECT (cancelButton), "key-press-event",
365                 G_CALLBACK (hildon_code_dialog_key_press_event), dialog);
366
367     gtk_widget_show_all (GTK_WIDGET (GTK_DIALOG (dialog)->vbox));
368 }
369
370 static void
371 hildon_code_dialog_realize                      (GtkWidget *widget)
372 {
373     HildonCodeDialog *dialog = HILDON_CODE_DIALOG (widget);
374     HildonCodeDialogPrivate *priv = HILDON_CODE_DIALOG_GET_PRIVATE (dialog);
375
376     if (GTK_WIDGET_CLASS (parent_class)->realize)
377       (* GTK_WIDGET_CLASS (parent_class)->realize) (widget);
378
379     gtk_im_context_set_client_window (GTK_IM_CONTEXT (priv->im_context),
380                                      GTK_WIDGET (dialog)->window);
381     gtk_im_context_focus_in (priv->im_context);
382 }
383
384 static void
385 hildon_code_dialog_unrealize                    (GtkWidget *widget)
386 {
387     HildonCodeDialog *dialog = HILDON_CODE_DIALOG (widget);
388     HildonCodeDialogPrivate *priv = HILDON_CODE_DIALOG_GET_PRIVATE (dialog);
389
390     gtk_im_context_set_client_window (GTK_IM_CONTEXT (priv->im_context), NULL);
391
392     if (GTK_WIDGET_CLASS (parent_class)->unrealize)
393       (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
394 }
395
396 static void
397 hildon_code_dialog_finalize                     (GObject *object)
398 {
399     HildonCodeDialog *dialog = HILDON_CODE_DIALOG (object);
400     HildonCodeDialogPrivate *priv = HILDON_CODE_DIALOG_GET_PRIVATE (dialog);
401
402     g_object_unref (priv->im_context);
403
404     G_OBJECT_CLASS(parent_class)->finalize(object);
405 }
406
407 static void
408 hildon_code_dialog_backspace                    (HildonCodeDialog *dialog)
409 {
410     HildonCodeDialogPrivate *priv = HILDON_CODE_DIALOG_GET_PRIVATE (dialog);
411     gchar *text, *pos;
412
413     g_assert (priv);
414
415     text = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->entry)));
416         
417     pos = text;
418
419     while (*pos != '\0')
420     {
421       pos ++;
422     }
423
424     pos = g_utf8_find_prev_char (text, pos);
425
426     if (pos)
427     {
428       *pos=0;
429     }
430
431     gtk_entry_set_text (GTK_ENTRY (priv->entry), text);
432
433     if (*text == 0)
434     {
435       gtk_widget_set_sensitive (priv->buttons[4][0], FALSE);
436     }
437
438     gtk_editable_set_position (GTK_EDITABLE (priv->entry), -1);
439
440     g_free (text);
441 }
442
443 static void 
444 hildon_code_dialog_button_clicked               (GtkButton *button, 
445                                                  gpointer user_data)
446 {
447     HildonCodeDialog *dialog = HILDON_CODE_DIALOG (user_data);
448     HildonCodeDialogPrivate *priv = HILDON_CODE_DIALOG_GET_PRIVATE (dialog);
449     g_assert (priv);
450
451     const char *number = gtk_button_get_label (button);
452
453     if (number && *number )
454     {
455         gtk_editable_set_editable (GTK_EDITABLE (priv->entry), TRUE);
456
457         g_signal_emit_by_name (GTK_ENTRY (priv->entry)->im_context, "commit",
458                                number);
459
460         gtk_editable_set_editable (GTK_EDITABLE (priv->entry), FALSE);
461
462         gtk_editable_set_position (GTK_EDITABLE (priv->entry), -1);
463     }
464     else
465     {
466         hildon_code_dialog_backspace (dialog);
467     }
468 }
469
470 static void
471 hildon_code_dialog_im_commit                    (GtkIMContext *im_context,
472                                                  gchar *utf8,
473                                                  gpointer user_data)
474 {
475     HildonCodeDialog *dialog = HILDON_CODE_DIALOG (user_data);
476     HildonCodeDialogPrivate *priv = HILDON_CODE_DIALOG_GET_PRIVATE (dialog);
477     gint digit;
478
479     g_assert (priv);
480
481     digit = g_ascii_strtod(utf8, NULL);
482
483     if (g_ascii_isdigit(*utf8))
484     {
485         gtk_editable_set_editable (GTK_EDITABLE (priv->entry), TRUE);
486
487         g_signal_emit_by_name (GTK_ENTRY (priv->entry)->im_context, "commit",
488                                utf8);
489
490         gtk_editable_set_editable (GTK_EDITABLE (priv->entry), FALSE);
491
492         gtk_editable_set_position (GTK_EDITABLE (priv->entry), -1);
493     }
494 }
495
496 static void 
497 hildon_code_dialog_insert_text                  (GtkEditable *editable,
498                                                  gchar *new_text,
499                                                  gint new_text_length,
500                                                  gint *position,
501                                                  gpointer user_data)
502 {
503     HildonCodeDialog *dialog = HILDON_CODE_DIALOG (user_data);
504     HildonCodeDialogPrivate *priv = HILDON_CODE_DIALOG_GET_PRIVATE (dialog);
505     gchar *text = g_strdup(gtk_entry_get_text (GTK_ENTRY (priv->entry)));
506     glong length = g_utf8_strlen (text, -1);
507     g_free (text);
508     g_assert (priv);
509
510     if (length == MAX_PINCODE_LEN)
511     {
512         hildon_banner_show_information (GTK_WIDGET (dialog),
513                                         NULL,
514                                         DEVICELOCK_MAX_CHAR_REACHED);
515     }
516
517     else if (! length)
518     { 
519         /* make the Ok button sensitive */
520         gtk_widget_set_sensitive (priv->buttons[4][0], TRUE);
521     }
522
523     hildon_code_dialog_input (dialog);
524 }
525
526 static gboolean 
527 hildon_code_dialog_key_press_event              (GtkWidget *widget,
528                                                  GdkEventKey *event,
529                                                  gpointer user_data)
530 {
531     HildonCodeDialog *dialog = HILDON_CODE_DIALOG (user_data);
532     HildonCodeDialogPrivate *priv = HILDON_CODE_DIALOG_GET_PRIVATE (dialog);
533     GtkWidget *new_widget = widget;
534     gint x, y;
535     
536     g_assert (priv);
537
538     if (gtk_im_context_filter_keypress (priv->im_context, event))
539         return TRUE;
540
541     if (event->keyval == GDK_BackSpace)
542     {
543         hildon_code_dialog_backspace (dialog);
544         return TRUE;
545     }
546
547     for (x = 0; x < 5; x++)
548     {
549         for (y = 0; y < 3; y++)
550         {
551             if (priv->buttons[x][y] == widget)
552                 goto found;
553         }
554     }
555     return FALSE;
556
557 found:
558
559     while (new_widget == widget)
560     {
561         switch (event->keyval)
562         {
563             case GDK_Up:
564                 x = (x+4)%5;
565                 break;
566
567             case GDK_Down:
568                 x = (x+1)%5;
569                 break;
570
571             case GDK_Left:
572                 y = (y+2)%3;
573                 break;
574
575             case GDK_Right:
576                 y = (y+1)%3;
577                 break;
578
579             default:
580                 return FALSE;
581         }
582                 
583         new_widget = priv->buttons[x][y];
584     }
585
586     gtk_widget_grab_focus (new_widget);
587
588     return TRUE;
589 }
590
591 /**
592  * hildon_code_dialog_new:
593  *
594  * Use this function to create a new HildonCodeDialog.
595  *
596  * Return value: A @HildonCodeDialog.
597  **/
598 GtkWidget*
599 hildon_code_dialog_new                          (void)
600 {
601     HildonCodeDialog *dialog = g_object_new (HILDON_TYPE_CODE_DIALOG, NULL);
602
603     return GTK_WIDGET (dialog);
604 }
605
606 /**
607  * hildon_code_dialog_get_code:
608  * @dialog: The #HildonCodeDialog from which to get the entered code
609  *
610  * Use this function to access the code entered by the user.
611  *
612  * Return value: The entered code.
613  **/
614 const gchar*
615 hildon_code_dialog_get_code                     (HildonCodeDialog *dialog)
616 {
617     g_return_val_if_fail (HILDON_IS_CODE_DIALOG (dialog), NULL);
618     
619     HildonCodeDialogPrivate *priv = HILDON_CODE_DIALOG_GET_PRIVATE (dialog);
620     g_assert (priv);
621
622     return gtk_entry_get_text (GTK_ENTRY (priv->entry));
623 }
624
625 /**
626  * hildon_code_dialog_clear_clode:
627  * @dialog: The #HildonCodeDialog whose entry should be cleared:
628  *
629  * Use this function to clear the user entered code.
630  **/
631 void 
632 hildon_code_dialog_clear_code                   (HildonCodeDialog *dialog)
633 {
634     g_return_if_fail (HILDON_IS_CODE_DIALOG (dialog));
635
636     HildonCodeDialogPrivate *priv = HILDON_CODE_DIALOG_GET_PRIVATE (dialog);
637     g_assert (priv);
638
639     gtk_entry_set_text (GTK_ENTRY (priv->entry), "");
640     gtk_widget_set_sensitive (priv->buttons[4][0], FALSE);
641 }
642
643 /**
644  * hildon_code_dialog_set_help_text:
645  * @dialog: The #HildonCodeDialog whose entry should be cleared:
646  * @text: The text to use in the help label.
647  *
648  * Use this function to set the text that will be displayd in the
649  * help label
650  **/
651 void 
652 hildon_code_dialog_set_help_text                (HildonCodeDialog *dialog, 
653                                                  const gchar *text)
654 {
655     g_return_if_fail (HILDON_IS_CODE_DIALOG (dialog));
656
657     HildonCodeDialogPrivate *priv = HILDON_CODE_DIALOG_GET_PRIVATE (dialog);
658     g_assert (priv);
659
660     gtk_label_set_text (GTK_LABEL (priv->help_text), text);
661 }
662
663 static void 
664 hildon_code_dialog_real_input                   (HildonCodeDialog *dialog)
665 {
666 }
667
668 static void 
669 hildon_code_dialog_input                        (HildonCodeDialog *dialog)
670 {
671     /* Emit the signal */
672     g_signal_emit (dialog, input_signal, 0);
673 }
674
675 /**
676  * hildon_code_dialog_set_input_sensitive
677  * @dialog: The #HildonCodeDialog whose state is to be changed
678  * @sensitive: The new state 
679  *
680  * This function will block or enable the input on the code dialog by
681  * making the input button sensitive (or not).
682  **/
683 void
684 hildon_code_dialog_set_input_sensitive          (HildonCodeDialog *dialog, 
685                                                  gboolean sensitive)
686 {
687     int i;
688     int k;
689
690     g_return_if_fail (HILDON_IS_CODE_DIALOG (dialog));
691
692     HildonCodeDialogPrivate *priv = HILDON_CODE_DIALOG_GET_PRIVATE (dialog);
693     g_assert (priv);
694
695     for (i = 0; i < 5; i++)
696         for (k = 0; k < 3; k++) 
697             if (i != 4 && (k != 0 || k != 2))
698                 gtk_widget_set_sensitive (priv->buttons [i][k], sensitive);
699
700     gtk_widget_set_sensitive (priv->help_text, sensitive);
701     gtk_widget_set_sensitive (priv->entry, sensitive);
702 }