* src/hildon-*.c * src/hildon-*.h: Ensure a consistent include order, include <gtk...
[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                                        <libintl.h>
42 #include                                        <gdk/gdkkeysyms.h>
43
44 #include                                        "hildon-code-dialog.h"
45 #include                                        "hildon-defines.h"
46 #include                                        "hildon-banner.h"
47 #include                                        "hildon-code-dialog-private.h"
48
49 #define                                         HEIGHT (48-HILDON_MARGIN_DEFAULT)
50
51 #define                                         WIDTH  (100-HILDON_MARGIN_DEFAULT)
52
53 #define                                         BACKSPACE_ICON "qgn_calculator_backspace"
54
55 #define                                         _(String) \
56                                                 dgettext("hildon-libs", String)
57
58 #define                                         c_(String) \
59                                                 dgettext("hildon-common-strings", String)
60
61 #define                                         DEVICELOCK_OK _("secu_enter_lock_code_dialog_ok")
62
63 #define                                         DEVICELOCK_CANCEL _("secu_enter_lock_code_dialog_cancel")
64
65 #define                                         DEVICELOCK_TITLE _("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     GtkWidget *cancelButton;
193
194     priv = HILDON_CODE_DIALOG_GET_PRIVATE (dialog);
195     g_assert (priv);
196     
197     const gchar* numstrs[10] = {
198         "0","1","2","3","4","5","6","7","8","9"
199     };
200
201     GdkPixbuf* pixbuf = NULL;
202     GtkIconTheme* icon_theme = NULL;
203     GtkIconInfo *icon_info = NULL;
204     gint base_size = 0;
205
206     /* Set default title */
207     gtk_window_set_title (GTK_WINDOW (dialog), DEVICELOCK_TITLE);
208
209     gtk_window_set_type_hint (GTK_WINDOW (dialog), GDK_WINDOW_TYPE_HINT_DIALOG);
210     gtk_dialog_set_has_separator ((GtkDialog *) dialog, FALSE);
211
212     hints.min_width  = -1;
213     hints.min_height = -1;
214     hints.max_width  = -1;
215     hints.max_height = -1;
216
217     gtk_window_set_geometry_hints (GTK_WINDOW (dialog), GTK_WIDGET (dialog), &hints,
218             GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE);
219
220     table = gtk_table_new (4, 3, FALSE);
221     gtk_table_set_row_spacings (GTK_TABLE (table), HILDON_MARGIN_DEFAULT );
222     gtk_table_set_col_spacings (GTK_TABLE (table), HILDON_MARGIN_DEFAULT );
223
224     dialog_vbox1 = GTK_DIALOG (dialog)->vbox;
225     vbox1 = gtk_vbox_new (FALSE, 0);
226     gtk_box_set_spacing (GTK_BOX (vbox1), HILDON_MARGIN_DOUBLE);
227
228     priv->help_text = gtk_label_new ("");
229     alignment = gtk_alignment_new (0.5,0,1,1);
230     gtk_container_add (GTK_CONTAINER (alignment), priv->help_text);
231
232     priv->entry = gtk_entry_new ();
233     
234     GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (priv->entry), GTK_CAN_FOCUS);
235     gtk_entry_set_invisible_char (GTK_ENTRY (priv->entry), g_utf8_get_char ("*"));
236     gtk_entry_set_alignment (GTK_ENTRY (priv->entry), 1.0);
237
238     gtk_editable_set_editable (GTK_EDITABLE (priv->entry),FALSE);
239     gtk_entry_set_visibility (GTK_ENTRY (priv->entry), FALSE);
240
241     gtk_box_pack_start (GTK_BOX (vbox1), alignment, TRUE,FALSE,0);
242     gtk_box_pack_start (GTK_BOX (vbox1), priv->entry, TRUE,FALSE,0);
243     gtk_box_pack_start (GTK_BOX (vbox1), table, FALSE,TRUE,0);
244
245     gtk_box_pack_start (GTK_BOX (dialog_vbox1), vbox1, FALSE,TRUE,0);
246
247     for(i = 1;i <= 3; i++) {
248         priv->buttons[0][i-1] = gtk_button_new_with_mnemonic (numstrs[i]);
249         gtk_widget_set_size_request (priv->buttons[0][i-1], WIDTH, HEIGHT);
250         gtk_table_attach_defaults (GTK_TABLE (table), priv->buttons[0][i-1],
251                 i-1, i, 0, 1);
252     }
253
254     for(i = 4;i <= 6;i++) {
255         priv->buttons[1][i-4] = gtk_button_new_with_mnemonic (numstrs[i]);
256         gtk_widget_set_size_request (priv->buttons[1][i-4], WIDTH, HEIGHT);
257         gtk_table_attach_defaults (GTK_TABLE (table), priv->buttons[1][i-4],
258                 i-4, i-3, 1, 2);
259     }
260
261     for(i=7;i<=9;i++) {
262         priv->buttons[2][i-7] = gtk_button_new_with_mnemonic (numstrs[i]);
263         gtk_widget_set_size_request (priv->buttons[2][i-7], WIDTH, HEIGHT);
264         gtk_table_attach_defaults (GTK_TABLE (table), priv->buttons[2][i-7],
265                 i-7, i-6, 2, 3);
266     }
267
268     priv->buttons[3][0] = priv->buttons[3][1] = 
269         gtk_button_new_with_mnemonic (numstrs[0]);
270     gtk_widget_set_size_request (priv->buttons[3][0], WIDTH, HEIGHT);
271     gtk_table_attach (GTK_TABLE (table), priv->buttons[3][0],
272             0,2,3,4, (GtkAttachOptions) (GTK_FILL),
273             (GtkAttachOptions) (0), 0, 0);
274
275     priv->buttons[3][2] = gtk_button_new ();
276     gtk_widget_set_size_request (priv->buttons[3][2], WIDTH, HEIGHT);
277     gtk_table_attach_defaults (GTK_TABLE (table), priv->buttons[3][2],
278             2, 3, 3, 4);
279
280     icon_theme = gtk_icon_theme_get_default ();
281
282     icon_info = gtk_icon_theme_lookup_icon (icon_theme, BACKSPACE_ICON, 1,
283             GTK_ICON_LOOKUP_NO_SVG);
284     base_size = gtk_icon_info_get_base_size (icon_info);
285     gtk_icon_info_free (icon_info);
286     icon_info = NULL;
287     pixbuf = gtk_icon_theme_load_icon (icon_theme,
288             BACKSPACE_ICON, base_size,
289             GTK_ICON_LOOKUP_NO_SVG,
290             NULL);
291
292     image1 = gtk_image_new_from_pixbuf (pixbuf);
293     g_object_unref (G_OBJECT(pixbuf));
294     gtk_container_add (GTK_CONTAINER (priv->buttons[3][2]), image1);
295     dialog_action_area1 = GTK_DIALOG (dialog)->action_area;
296     gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area1),
297 #if GTK_CHECK_VERSION(2,11,0) || defined(MAEMO_GTK)
298                                GTK_BUTTONBOX_CENTER);
299 #else
300                                GTK_BUTTONBOX_DEFAULT_STYLE);
301 #endif
302
303     okButton = gtk_dialog_add_button (GTK_DIALOG (dialog) ,DEVICELOCK_OK,
304             GTK_RESPONSE_OK);
305     cancelButton =
306         gtk_dialog_add_button (GTK_DIALOG (dialog), DEVICELOCK_CANCEL,
307                 GTK_RESPONSE_CANCEL);
308     
309     gtk_widget_set_sensitive (okButton, FALSE);
310
311     priv->buttons[4][0] = priv->buttons[4][1] = okButton;
312     priv->buttons[4][2] = cancelButton;
313
314     priv->im_context = gtk_im_multicontext_new();
315 #ifdef MAEMO_GTK
316     g_object_set (G_OBJECT (priv->im_context), "hildon-input-mode",
317                   HILDON_GTK_INPUT_MODE_NUMERIC, NULL);
318 #endif
319
320     /*
321        Connect signals.
322     */
323     g_signal_connect (G_OBJECT (priv->im_context), "commit",
324                       G_CALLBACK (hildon_code_dialog_im_commit), dialog);
325
326     g_signal_connect (G_OBJECT (priv->entry), "insert_text",
327             G_CALLBACK (hildon_code_dialog_insert_text), dialog);
328     
329     gtk_entry_set_max_length (GTK_ENTRY (priv->entry), MAX_PINCODE_LEN);
330
331     for (x = 0; x < 3; x++)
332     {
333         for (y = 0; y < 3; y++)
334         {
335             g_signal_connect (G_OBJECT (priv->buttons[x][y]), "clicked",
336                 G_CALLBACK (hildon_code_dialog_button_clicked), dialog);
337             g_signal_connect (G_OBJECT (priv->buttons[x][y]), "key-press-event",
338                 G_CALLBACK (hildon_code_dialog_key_press_event), dialog);
339         }
340     }
341             
342     g_signal_connect (G_OBJECT (priv->buttons[3][0]), "clicked",
343                 G_CALLBACK (hildon_code_dialog_button_clicked), dialog);
344     g_signal_connect (G_OBJECT (priv->buttons[3][0]), "key-press-event",
345                 G_CALLBACK (hildon_code_dialog_key_press_event), dialog);
346     
347     g_signal_connect (G_OBJECT (priv->buttons[3][2]), "clicked",
348                 G_CALLBACK (hildon_code_dialog_button_clicked), dialog);
349     g_signal_connect (G_OBJECT (priv->buttons[3][2]), "key-press-event",
350                 G_CALLBACK (hildon_code_dialog_key_press_event), dialog);
351         
352     g_signal_connect (G_OBJECT (okButton), "key-press-event",
353                 G_CALLBACK(hildon_code_dialog_key_press_event), dialog);
354     
355     g_signal_connect (G_OBJECT (cancelButton), "key-press-event",
356                 G_CALLBACK (hildon_code_dialog_key_press_event), dialog);
357
358     gtk_widget_show_all (GTK_WIDGET (GTK_DIALOG (dialog)->vbox));
359 }
360
361 static void
362 hildon_code_dialog_realize                      (GtkWidget *widget)
363 {
364     HildonCodeDialog *dialog = HILDON_CODE_DIALOG (widget);
365     HildonCodeDialogPrivate *priv = HILDON_CODE_DIALOG_GET_PRIVATE (dialog);
366
367     if (GTK_WIDGET_CLASS (parent_class)->realize)
368       (* GTK_WIDGET_CLASS (parent_class)->realize) (widget);
369
370     gtk_im_context_set_client_window (GTK_IM_CONTEXT (priv->im_context),
371                                      GTK_WIDGET (dialog)->window);
372     gtk_im_context_focus_in (priv->im_context);
373 }
374
375 static void
376 hildon_code_dialog_unrealize                    (GtkWidget *widget)
377 {
378     HildonCodeDialog *dialog = HILDON_CODE_DIALOG (widget);
379     HildonCodeDialogPrivate *priv = HILDON_CODE_DIALOG_GET_PRIVATE (dialog);
380
381     gtk_im_context_set_client_window (GTK_IM_CONTEXT (priv->im_context), NULL);
382
383     if (GTK_WIDGET_CLASS (parent_class)->unrealize)
384       (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
385 }
386
387 static void
388 hildon_code_dialog_finalize                     (GObject *object)
389 {
390     HildonCodeDialog *dialog = HILDON_CODE_DIALOG (object);
391     HildonCodeDialogPrivate *priv = HILDON_CODE_DIALOG_GET_PRIVATE (dialog);
392
393     g_object_unref (priv->im_context);
394
395     G_OBJECT_CLASS(parent_class)->finalize(object);
396 }
397
398 static void
399 hildon_code_dialog_backspace                    (HildonCodeDialog *dialog)
400 {
401     HildonCodeDialogPrivate *priv = HILDON_CODE_DIALOG_GET_PRIVATE (dialog);
402     gchar *text, *pos;
403
404     g_assert (priv);
405
406     text = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->entry)));
407         
408     pos = text;
409
410     while (*pos != '\0')
411     {
412       pos ++;
413     }
414
415     pos = g_utf8_find_prev_char (text, pos);
416
417     if (pos)
418     {
419       *pos=0;
420     }
421
422     gtk_entry_set_text (GTK_ENTRY (priv->entry), text);
423
424     if (*text == 0)
425     {
426       gtk_widget_set_sensitive (priv->buttons[4][0], FALSE);
427     }
428
429     gtk_editable_set_position (GTK_EDITABLE (priv->entry), -1);
430
431     g_free (text);
432 }
433
434 static void 
435 hildon_code_dialog_button_clicked               (GtkButton *button, 
436                                                  gpointer user_data)
437 {
438     HildonCodeDialog *dialog = HILDON_CODE_DIALOG (user_data);
439     HildonCodeDialogPrivate *priv = HILDON_CODE_DIALOG_GET_PRIVATE (dialog);
440     g_assert (priv);
441
442     const char *number = gtk_button_get_label (button);
443
444     if (number && *number )
445     {
446         gtk_editable_set_editable (GTK_EDITABLE (priv->entry), TRUE);
447
448         g_signal_emit_by_name (GTK_ENTRY (priv->entry)->im_context, "commit",
449                                number);
450
451         gtk_editable_set_editable (GTK_EDITABLE (priv->entry), FALSE);
452
453         gtk_editable_set_position (GTK_EDITABLE (priv->entry), -1);
454     }
455     else
456     {
457         hildon_code_dialog_backspace (dialog);
458     }
459 }
460
461 static void
462 hildon_code_dialog_im_commit                    (GtkIMContext *im_context,
463                                                  gchar *utf8,
464                                                  gpointer user_data)
465 {
466     HildonCodeDialog *dialog = HILDON_CODE_DIALOG (user_data);
467     HildonCodeDialogPrivate *priv = HILDON_CODE_DIALOG_GET_PRIVATE (dialog);
468     gint digit;
469
470     g_assert (priv);
471
472     digit = g_ascii_strtod(utf8, NULL);
473
474     if (g_ascii_isdigit(*utf8))
475     {
476         gtk_editable_set_editable (GTK_EDITABLE (priv->entry), TRUE);
477
478         g_signal_emit_by_name (GTK_ENTRY (priv->entry)->im_context, "commit",
479                                utf8);
480
481         gtk_editable_set_editable (GTK_EDITABLE (priv->entry), FALSE);
482
483         gtk_editable_set_position (GTK_EDITABLE (priv->entry), -1);
484     }
485 }
486
487 static void 
488 hildon_code_dialog_insert_text                  (GtkEditable *editable,
489                                                  gchar *new_text,
490                                                  gint new_text_length,
491                                                  gint *position,
492                                                  gpointer user_data)
493 {
494     HildonCodeDialog *dialog = HILDON_CODE_DIALOG (user_data);
495     HildonCodeDialogPrivate *priv = HILDON_CODE_DIALOG_GET_PRIVATE (dialog);
496     gchar *text = g_strdup(gtk_entry_get_text (GTK_ENTRY (priv->entry)));
497     glong length = g_utf8_strlen (text, -1);
498     g_free (text);
499     g_assert (priv);
500
501     if (length == MAX_PINCODE_LEN)
502     {
503         hildon_banner_show_information (GTK_WIDGET (dialog),
504                                         NULL,
505                                         DEVICELOCK_MAX_CHAR_REACHED);
506     }
507
508     else if (! length)
509     { 
510         /* make the Ok button sensitive */
511         gtk_widget_set_sensitive (priv->buttons[4][0], TRUE);
512     }
513
514     hildon_code_dialog_input (dialog);
515 }
516
517 static gboolean 
518 hildon_code_dialog_key_press_event              (GtkWidget *widget,
519                                                  GdkEventKey *event,
520                                                  gpointer user_data)
521 {
522     HildonCodeDialog *dialog = HILDON_CODE_DIALOG (user_data);
523     HildonCodeDialogPrivate *priv = HILDON_CODE_DIALOG_GET_PRIVATE (dialog);
524     GtkWidget *new_widget = widget;
525     gint x, y;
526     
527     g_assert (priv);
528
529     if (gtk_im_context_filter_keypress (priv->im_context, event))
530         return TRUE;
531
532     if (event->keyval == GDK_BackSpace)
533     {
534         hildon_code_dialog_backspace (dialog);
535         return TRUE;
536     }
537
538     for (x = 0; x < 5; x++)
539     {
540         for (y = 0; y < 3; y++)
541         {
542             if (priv->buttons[x][y] == widget)
543                 goto found;
544         }
545     }
546     return FALSE;
547
548 found:
549
550     while (new_widget == widget)
551     {
552         switch (event->keyval)
553         {
554             case GDK_Up:
555                 x = (x+4)%5;
556                 break;
557
558             case GDK_Down:
559                 x = (x+1)%5;
560                 break;
561
562             case GDK_Left:
563                 y = (y+2)%3;
564                 break;
565
566             case GDK_Right:
567                 y = (y+1)%3;
568                 break;
569
570             default:
571                 return FALSE;
572         }
573                 
574         new_widget = priv->buttons[x][y];
575     }
576
577     gtk_widget_grab_focus (new_widget);
578
579     return TRUE;
580 }
581
582 /**
583  * hildon_code_dialog_new:
584  *
585  * Use this function to create a new HildonCodeDialog.
586  *
587  * Return value: A @HildonCodeDialog.
588  **/
589 GtkWidget*
590 hildon_code_dialog_new                          (void)
591 {
592     HildonCodeDialog *dialog = g_object_new (HILDON_TYPE_CODE_DIALOG, NULL);
593
594     return GTK_WIDGET (dialog);
595 }
596
597 /**
598  * hildon_code_dialog_get_code:
599  * @dialog: The #HildonCodeDialog from which to get the entered code
600  *
601  * Use this function to access the code entered by the user.
602  *
603  * Return value: The entered code.
604  **/
605 const gchar*
606 hildon_code_dialog_get_code                     (HildonCodeDialog *dialog)
607 {
608     g_return_val_if_fail (HILDON_IS_CODE_DIALOG (dialog), NULL);
609     
610     HildonCodeDialogPrivate *priv = HILDON_CODE_DIALOG_GET_PRIVATE (dialog);
611     g_assert (priv);
612
613     return gtk_entry_get_text (GTK_ENTRY (priv->entry));
614 }
615
616 /**
617  * hildon_code_dialog_clear_clode:
618  * @dialog: The #HildonCodeDialog whose entry should be cleared:
619  *
620  * Use this function to clear the user entered code.
621  **/
622 void 
623 hildon_code_dialog_clear_code                   (HildonCodeDialog *dialog)
624 {
625     g_return_if_fail (HILDON_IS_CODE_DIALOG (dialog));
626
627     HildonCodeDialogPrivate *priv = HILDON_CODE_DIALOG_GET_PRIVATE (dialog);
628     g_assert (priv);
629
630     gtk_entry_set_text (GTK_ENTRY (priv->entry), "");
631     gtk_widget_set_sensitive (priv->buttons[4][0], FALSE);
632 }
633
634 /**
635  * hildon_code_dialog_set_help_text:
636  * @dialog: The #HildonCodeDialog whose entry should be cleared:
637  * @text: The text to use in the help label.
638  *
639  * Use this function to set the text that will be displayd in the
640  * help label
641  **/
642 void 
643 hildon_code_dialog_set_help_text                (HildonCodeDialog *dialog, 
644                                                  const gchar *text)
645 {
646     g_return_if_fail (HILDON_IS_CODE_DIALOG (dialog));
647
648     HildonCodeDialogPrivate *priv = HILDON_CODE_DIALOG_GET_PRIVATE (dialog);
649     g_assert (priv);
650
651     gtk_label_set_text (GTK_LABEL (priv->help_text), text);
652 }
653
654 static void 
655 hildon_code_dialog_real_input                   (HildonCodeDialog *dialog)
656 {
657 }
658
659 static void 
660 hildon_code_dialog_input                        (HildonCodeDialog *dialog)
661 {
662     /* Emit the signal */
663     g_signal_emit (dialog, input_signal, 0);
664 }
665
666 /**
667  * hildon_code_dialog_set_input_sensitive
668  * @dialog: The #HildonCodeDialog whose state is to be changed
669  * @sensitive: The new state 
670  *
671  * This function will block or enable the input on the code dialog by
672  * making the input button sensitive (or not).
673  **/
674 void
675 hildon_code_dialog_set_input_sensitive          (HildonCodeDialog *dialog, 
676                                                  gboolean sensitive)
677 {
678     int i;
679     int k;
680
681     g_return_if_fail (HILDON_IS_CODE_DIALOG (dialog));
682
683     HildonCodeDialogPrivate *priv = HILDON_CODE_DIALOG_GET_PRIVATE (dialog);
684     g_assert (priv);
685
686     for (i = 0; i < 5; i++)
687         for (k = 0; k < 3; k++) 
688             if (i != 4 && (k != 0 || k != 2))
689                 gtk_widget_set_sensitive (priv->buttons [i][k], sensitive);
690
691     gtk_widget_set_sensitive (priv->help_text, sensitive);
692     gtk_widget_set_sensitive (priv->entry, sensitive);
693 }