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