2008-04-15 13:21:13 <timj@imendio.com>
[hildon] / src / hildon-set-password-dialog.c
1 /*
2  * This file is a part of hildon
3  *
4  * Copyright (C) 2005, 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-set-password-dialog
27  * @short_description: A dialog used to set, change or remove a password.
28  * @see_also: #HildonGetPasswordDialog
29  *
30  * HildonSetPasswordDialog allows setting and changing a password. 
31  * 
32  * In Change mode: Dialog is used to change or remove an existing
33  * password. Unselecting the check box dims the password fields below
34  * it. If the dialog is accepted with 'OK' while the check box is
35  * unselected, a Confirmation Note is shown.  If the Confirmation Note
36  * Dialog is accepted with 'Remove', the password protection is removed.  
37  * 
38  * In Set mode: Set Password Dialog is used to define a password, or
39  * change a password that cannot be removed.
40  */
41
42 #ifdef                                          HAVE_CONFIG_H
43 #include                                        <config.h>
44 #endif
45
46 #include                                        "hildon-set-password-dialog.h"
47 #include                                        <gdk/gdkkeysyms.h>
48 #include                                        <gtk/gtk.h>
49 #include                                        <glib.h>
50 #include                                        <errno.h>
51 #include                                        <string.h>
52 #include                                        <strings.h>
53 #include                                        <unistd.h>
54 #include                                        <stdio.h>
55 #include                                        "hildon-caption.h"
56 #include                                        "hildon-note.h"
57 #include                                        "hildon-defines.h"
58 #include                                        "hildon-banner.h"
59 #include                                        <libintl.h>
60 #include                                        "hildon-set-password-dialog-private.h"
61
62 #define                                         HILDON_SET_PASSWORD_DIALOG_TITLE "ecdg_ti_set_password"
63
64 #define                                         HILDON_SET_PASSWORD_DIALOG_PASSWORD "ecdg_fi_set_passwd_enter_pwd"
65
66 #define                                         HILDON_SET_PASSWORD_DIALOG_VERIFY_PASSWORD "ecdg_fi_set_passwd_confirm"
67
68 #define                                         HILDON_SET_PASSWORD_DIALOG_OK "ecdg_bd_set_password_dialog_ok"
69
70 #define                                         HILDON_SET_PASSWORD_DIALOG_CANCEL "ecdg_bd_set_password_dialog_cancel"
71
72 #define                                         HILDON_SET_MODIFY_PASSWORD_DIALOG_TITLE "ckdg_ti_dialog_c_passwd_change_password"
73
74 #define                                         HILDON_SET_MODIFY_PASSWORD_DIALOG_LABEL "ckdg_fi_dialog_c_passwd_pwd_protect"
75
76 #define                                         HILDON_SET_MODIFY_PASSWORD_DIALOG_PASSWORD "ckdg_fi_dialog_c_passwd_new_pwd"
77
78 #define                                         HILDON_SET_MODIFY_PASSWORD_DIALOG_VERIFY_PASSWORD "ckdg_fi_dialog_c_passwd_ver_pwd"
79
80 #define                                         HILDON_SET_MODIFY_PASSWORD_DIALOG_OK "ckdg_bd_change_password_dialog_ok"
81
82 #define                                         HILDON_SET_MODIFY_PASSWORD_DIALOG_CANCEL "ckdg_bd_change_password_dialog_cancel"
83
84 #define                                         HILDON_SET_PASSWORD_DIALOG_MISMATCH "ecdg_ib_passwords_do_not_match"
85
86 #define                                         HILDON_SET_PASSWORD_DIALOG_EMPTY "ecdg_ib_password_is_empty"
87
88 #define                                         HILDON_SET_PASSWORD_DIALOG_REMOVE_PROTECTION "ckdg_nc_dialog_c_passwd_remove_pwd"
89
90 #define                                         HILDON_REMOVE_PROTECTION_CONFIRMATION_REMOVE "ckdg_bd_dialog_c_passwd_remove_button"
91
92 #define                                         HILDON_REMOVE_PROTECTION_CONFIRMATION_CANCEL "ckdg_bd_dialog_c_passwd_cancel_button"
93
94 #define                                         _(String) dgettext("hildon-libs", String)
95
96 #define                                         c_(String) dgettext("hildon-common-strings", String)
97
98 static GtkDialogClass*                          parent_class;
99
100 static void
101 hildon_set_password_dialog_class_init           (HildonSetPasswordDialogClass *class);
102
103 static void 
104 hildon_set_password_dialog_init                 (HildonSetPasswordDialog *dialog);
105
106 static void 
107 hildon_checkbox_toggled                         (GtkWidget *widget, 
108                                                  gpointer dialog);
109
110 static void
111 hildon_set_password_response_change             (GtkDialog *d,
112                                                  gint arg1, 
113                                                  gpointer unused);
114
115 static void
116 hildon_set_password_response_set                (GtkDialog * d, 
117                                                  gint arg1, 
118                                                  gpointer unused);
119
120 static void 
121 create_contents                                 (HildonSetPasswordDialog *dialog);
122
123 static void
124 hildon_set_password_set_property                (GObject *object,
125                                                  guint prop_id,
126                                                  const GValue *value,
127                                                  GParamSpec *pspec);
128
129 static void
130 hildon_set_password_get_property                (GObject *object,
131                                                  guint prop_id, 
132                                                  GValue *value,
133                                                  GParamSpec *pspec);
134
135 enum 
136 {
137     PROP_0,
138     PROP_MESSAGE,
139     PROP_PASSWORD,
140     PROP_HILDON_PASSWORD_DIALOG
141 };
142
143 static void
144 hildon_set_password_set_property                (GObject *object,
145                                                  guint prop_id,
146                                                  const GValue *value, 
147                                                  GParamSpec *pspec)
148 {
149     HildonSetPasswordDialog *dialog = HILDON_SET_PASSWORD_DIALOG (object);
150     HildonSetPasswordDialogPrivate *priv;
151
152     priv = HILDON_SET_PASSWORD_DIALOG_GET_PRIVATE (dialog);
153     g_assert (priv);
154
155     switch (prop_id) {
156
157         case PROP_MESSAGE:
158             /* Update domain label to display new value */
159             gtk_label_set_text (priv->message_label, g_value_get_string (value));
160             break;
161
162         case PROP_PASSWORD:
163             /* Update password entry to display new value */
164             gtk_entry_set_text (GTK_ENTRY (priv->pwd1st_entry), g_value_get_string (value));
165             break;
166
167         case PROP_HILDON_PASSWORD_DIALOG:
168             /* Note this is a G_PARAM_CONSTRUCT_ONLY type property */
169             priv->protection = g_value_get_boolean (value);
170
171             /* We now have the necessary information to populate the dialog */
172             /* FIXME It looks kinda extremally bad that this is here... 
173              * what about situations where this prop is NOT set during 
174              * constructing? */
175             create_contents (dialog);
176             break;
177
178         default:
179             G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
180             break;
181     }
182 }
183
184 static void
185 hildon_set_password_get_property                (GObject *object,
186                                                  guint prop_id,
187                                                  GValue *value,
188                                                  GParamSpec *pspec)
189 {
190     HildonSetPasswordDialogPrivate *priv = NULL;
191
192     priv = HILDON_SET_PASSWORD_DIALOG_GET_PRIVATE (object);
193     g_assert (priv);
194
195     switch (prop_id) {
196
197         case PROP_MESSAGE:
198             g_value_set_string (value, gtk_label_get_text (priv->message_label));
199             break;
200
201         case PROP_PASSWORD:
202             g_value_set_string (value,
203                     gtk_entry_get_text (GTK_ENTRY (priv->pwd1st_entry)));
204             break;
205
206         case PROP_HILDON_PASSWORD_DIALOG:
207             g_value_set_boolean (value, priv->protection);
208             break;
209
210         default:
211             G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
212             break;
213     }
214 }
215
216
217 static void
218 create_contents                                 (HildonSetPasswordDialog *dialog)
219 {
220     HildonSetPasswordDialogPrivate *priv = NULL;
221     AtkObject *atk_aux = NULL;
222
223     GtkSizeGroup *group;
224
225     priv = HILDON_SET_PASSWORD_DIALOG_GET_PRIVATE (dialog);
226     g_assert (priv);
227     priv->checkbox = NULL;
228
229     /* Size group for labels */
230     group = GTK_SIZE_GROUP (gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL));
231
232     gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
233
234     /* Setup and pack domain label */
235     priv->message_label = GTK_LABEL (gtk_label_new (NULL));
236     gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
237             GTK_WIDGET(priv->message_label), FALSE, FALSE, 0);
238     gtk_widget_show (GTK_WIDGET (priv->message_label));
239
240     if (priv->protection == TRUE) {
241         /* Use Change Password Dialog strings */
242         priv->pwd1st_caption_string = _(HILDON_SET_MODIFY_PASSWORD_DIALOG_PASSWORD);
243         priv->pwd2nd_caption_string = _(HILDON_SET_MODIFY_PASSWORD_DIALOG_VERIFY_PASSWORD);
244
245         /* Setup checkbox to enable/disable password protection */
246         priv->checkbox = gtk_check_button_new ();
247         gtk_widget_show (priv->checkbox);
248         priv->checkbox_caption = hildon_caption_new
249             (group,
250              _(HILDON_SET_MODIFY_PASSWORD_DIALOG_LABEL),
251              priv->checkbox,
252              NULL, HILDON_CAPTION_OPTIONAL);
253         hildon_caption_set_separator (HILDON_CAPTION (priv->checkbox_caption), "");
254         gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
255                 priv->checkbox_caption, TRUE, TRUE, 0);
256         gtk_widget_show (priv->checkbox_caption);
257         gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->checkbox),
258                 TRUE);
259         gtk_signal_connect (GTK_OBJECT (priv->checkbox), "toggled",
260                 G_CALLBACK (hildon_checkbox_toggled), dialog);
261
262         /* Setup appropriate response handler */
263         g_signal_connect (G_OBJECT (dialog), "response",
264                 G_CALLBACK (hildon_set_password_response_change),
265                 NULL);
266     } else {
267         /* Use Set Password Dialog strings */
268         priv->pwd1st_caption_string = _(HILDON_SET_PASSWORD_DIALOG_PASSWORD);
269         priv->pwd2nd_caption_string = _(HILDON_SET_PASSWORD_DIALOG_VERIFY_PASSWORD);
270
271         /* Setup appropriate response handler */
272         g_signal_connect (G_OBJECT (dialog), "response",
273                 G_CALLBACK(hildon_set_password_response_set),
274                 NULL);
275     }
276
277     /* Create the password field */
278     priv->pwd1st_entry = gtk_entry_new ();
279     if ((atk_aux = gtk_widget_get_accessible(priv->pwd1st_entry)))
280       {
281         atk_object_set_name(atk_aux, _("Old Passwd"));
282       }
283     
284
285 #ifdef MAEMO_GTK
286     g_object_set (priv->pwd1st_entry, "hildon-input-mode", HILDON_GTK_INPUT_MODE_FULL, NULL);
287 #endif
288
289     gtk_entry_set_visibility (GTK_ENTRY(priv->pwd1st_entry), FALSE);
290     gtk_widget_show (priv->pwd1st_entry);
291     priv->pwd1st_caption = hildon_caption_new (group,
292             priv->pwd1st_caption_string,
293             priv->pwd1st_entry,
294             NULL, HILDON_CAPTION_OPTIONAL);
295
296     hildon_caption_set_separator (HILDON_CAPTION(priv->pwd1st_caption), "");
297     gtk_entry_set_visibility (GTK_ENTRY (priv->pwd1st_entry), FALSE);
298     gtk_box_pack_start (GTK_BOX(GTK_DIALOG (dialog)->vbox),
299             priv->pwd1st_caption, TRUE, TRUE, 0);
300     gtk_widget_show (priv->pwd1st_caption);
301
302     /* Create the password verify field */
303     priv->pwd2nd_entry = gtk_entry_new();
304     if ((atk_aux = gtk_widget_get_accessible(priv->pwd2nd_entry)))
305       {
306         atk_object_set_name(atk_aux, _("New Passwd"));
307       }
308
309
310 #ifdef MAEMO_GTK
311     g_object_set (priv->pwd2nd_entry, "hildon-input-mode", HILDON_GTK_INPUT_MODE_FULL, NULL);
312 #endif
313
314     gtk_widget_show (priv->pwd2nd_entry);
315     priv->pwd2nd_caption = hildon_caption_new (group,
316             priv->pwd2nd_caption_string,
317             priv->pwd2nd_entry,
318             NULL, HILDON_CAPTION_OPTIONAL);
319     hildon_caption_set_separator (HILDON_CAPTION (priv->pwd2nd_caption), "");
320     gtk_entry_set_visibility (GTK_ENTRY (priv->pwd2nd_entry), FALSE);
321     gtk_box_pack_start (GTK_BOX(GTK_DIALOG (dialog)->vbox),
322             priv->pwd2nd_caption, TRUE, TRUE, 0);
323     gtk_widget_show (priv->pwd2nd_caption);
324
325     /* Set dialog title */
326     gtk_window_set_title (GTK_WINDOW (dialog),
327             _(priv->protection
328                 ? HILDON_SET_MODIFY_PASSWORD_DIALOG_TITLE
329                 : HILDON_SET_PASSWORD_DIALOG_TITLE));
330
331     /* Create the OK/CANCEL buttons */
332     gtk_dialog_add_button (GTK_DIALOG (dialog),  _(priv->protection
333                                 ? HILDON_SET_MODIFY_PASSWORD_DIALOG_OK
334                                 : HILDON_SET_PASSWORD_DIALOG_OK), GTK_RESPONSE_OK);
335
336     gtk_dialog_add_button (GTK_DIALOG (dialog), _(priv->protection
337                                ? HILDON_SET_MODIFY_PASSWORD_DIALOG_CANCEL
338                                : HILDON_SET_PASSWORD_DIALOG_CANCEL), GTK_RESPONSE_CANCEL);
339
340     gtk_widget_show_all (GTK_DIALOG (dialog)->vbox);
341     gtk_widget_show_all (GTK_DIALOG (dialog)->action_area);
342  
343     /* Ensure group is freed when all its contents have been removed */
344     g_object_unref (group);
345 }
346
347 static void
348 hildon_set_password_dialog_class_init           (HildonSetPasswordDialogClass *class)
349 {
350     GObjectClass *object_class = G_OBJECT_CLASS (class);
351
352     parent_class = g_type_class_peek_parent (class);
353
354     /* Override virtual methods */
355     object_class->set_property = hildon_set_password_set_property;
356     object_class->get_property = hildon_set_password_get_property;
357
358     /* Install new properties */
359     g_object_class_install_property (object_class, 
360             PROP_MESSAGE, 
361             g_param_spec_string ("message",
362                 "Message",
363                 "A message to display to the user",
364                 NULL,
365                 G_PARAM_READWRITE));
366
367     /**
368      * HildonSetPasswordDialog:modify-protection:
369      *
370      * Password type.
371      */
372     g_object_class_install_property (object_class, 
373             PROP_HILDON_PASSWORD_DIALOG, 
374             g_param_spec_boolean ("modify-protection",
375                 "Password type",
376                 "Set type to dialog",
377                 TRUE, 
378                 G_PARAM_CONSTRUCT_ONLY |
379                 G_PARAM_READWRITE));
380
381     /**
382      * HildonSetPasswordDialog:password:
383      *
384      * Content of the password field.
385      */
386     g_object_class_install_property (object_class, 
387             PROP_PASSWORD, 
388             g_param_spec_string ("password",
389                 "Password content",
390                 "Set content to dialog",
391                 "DEFAULT",
392                 G_PARAM_READWRITE));
393
394     /* Install private structure */
395     g_type_class_add_private (class,
396             sizeof (HildonSetPasswordDialogPrivate));
397 }
398
399 static void
400 hildon_set_password_dialog_init                 (HildonSetPasswordDialog *dialog)
401 {
402     /* Most of the initializations are done in create_contents()
403        after the 'modify_protection' property has been set */
404
405     gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
406 }
407
408
409 /* We come here when response button is clicked and dialog 
410    is used to change existing password. */
411 static void
412 hildon_set_password_response_change             (GtkDialog *dialog, 
413                                                  gint arg1,
414                                                  gpointer unused)
415 {
416     GtkEntry *pwd1st_entry;
417     GtkEntry *pwd2nd_entry;
418     gchar *text1;
419     gchar *text2;
420     HildonNote *note;
421     gint i;
422     HildonSetPasswordDialogPrivate *priv;
423
424     priv = HILDON_SET_PASSWORD_DIALOG_GET_PRIVATE (dialog);
425     g_assert (priv);
426
427     /* Password and verification */
428     pwd1st_entry = GTK_ENTRY (gtk_bin_get_child
429             (GTK_BIN (priv->pwd1st_caption)));
430     pwd2nd_entry = GTK_ENTRY (gtk_bin_get_child
431             (GTK_BIN (priv->pwd2nd_caption)));
432     text1 = GTK_ENTRY (pwd1st_entry)->text;
433     text2 = GTK_ENTRY (pwd2nd_entry)->text;
434
435     /* User accepted the dialog */
436     if (arg1 == GTK_RESPONSE_OK) {
437         /* Is the checkbox marked, so password protection is still in use? */  
438         if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->checkbox))){
439             /* Yes, Something is given as password as well? */
440             if (text1[0] != '\0') {
441                 if (strcmp (text1, text2) == 0) {
442                     /* Passwords match, so accept change password */
443                     priv->protection = TRUE;
444
445                 } else if (text2[0] == '\0') {
446                     /* Second field is empty, so show error, but don't clear fields */
447                     g_signal_stop_emission_by_name (G_OBJECT(dialog),
448                             "response");
449
450                     hildon_banner_show_information (GTK_WIDGET (dialog), NULL,
451                             c_(HILDON_SET_PASSWORD_DIALOG_MISMATCH));
452
453                     gtk_widget_grab_focus (GTK_WIDGET (pwd2nd_entry));
454
455                 } else {
456                     /* Error: Passwords don't match, so start over */
457                     g_signal_stop_emission_by_name (G_OBJECT(dialog),
458                             "response");
459
460                     gtk_entry_set_text (pwd1st_entry, "");
461                     gtk_entry_set_text (pwd2nd_entry, "");
462
463                     hildon_banner_show_information (GTK_WIDGET (dialog), NULL,
464                             c_(HILDON_SET_PASSWORD_DIALOG_MISMATCH));
465
466                     gtk_widget_grab_focus (GTK_WIDGET (pwd1st_entry));
467                 }
468             } else {
469                 /* No, the password is empty */
470                 g_signal_stop_emission_by_name (G_OBJECT (dialog), "response");
471
472                 if (text2[0] == '\0') {
473                     /* Error: Both fields are empty */
474                     hildon_banner_show_information (GTK_WIDGET (dialog), NULL, c_(HILDON_SET_PASSWORD_DIALOG_EMPTY));
475                 } else {
476                     /* Error: Second field doesn't match
477                        the empty first field, so start over */
478                     hildon_banner_show_information (GTK_WIDGET (dialog), NULL, c_(HILDON_SET_PASSWORD_DIALOG_MISMATCH));
479                     gtk_entry_set_text(pwd2nd_entry, "");
480                 }
481
482                 gtk_widget_grab_focus (GTK_WIDGET (pwd1st_entry));
483             }
484         } else {
485             /* No, user wants to remove password protection. 
486                Confirm remove password protection */
487             note = HILDON_NOTE (hildon_note_new_confirmation
488                     (GTK_WINDOW (dialog),
489                      c_(HILDON_SET_PASSWORD_DIALOG_REMOVE_PROTECTION)));
490
491             hildon_note_set_button_texts
492                 (HILDON_NOTE (note),
493                  c_(HILDON_REMOVE_PROTECTION_CONFIRMATION_REMOVE), 
494                  c_(HILDON_REMOVE_PROTECTION_CONFIRMATION_CANCEL));
495
496             /* Display confirmation note */
497             i = gtk_dialog_run (GTK_DIALOG (note));
498
499             gtk_widget_destroy (GTK_WIDGET (note));
500
501             if (i == GTK_RESPONSE_OK)
502                 /* Remove password protection */
503                 priv->protection = FALSE;
504             else {
505                 /* Remove password protection cancelled */
506                 priv->protection = TRUE;
507                 g_signal_stop_emission_by_name (G_OBJECT(dialog), "response");
508             }
509         }
510
511     } else {
512         /* Watch out for fading boolean values */
513         priv->protection = TRUE;
514     }
515 }
516
517 /* We come here when response button is clicked and dialog 
518    is used to set new password. */
519 static void
520 hildon_set_password_response_set                (GtkDialog *dialog, 
521                                                  gint arg1,
522                                                  gpointer unused)
523 {
524     GtkEntry *pwd1st_entry;
525     GtkEntry *pwd2nd_entry;
526     gchar *text1;
527     gchar *text2;
528
529     HildonSetPasswordDialogPrivate *priv;
530
531     priv = HILDON_SET_PASSWORD_DIALOG_GET_PRIVATE (dialog);
532     g_assert (priv);
533
534     /* Password and confirmation */
535     pwd1st_entry = GTK_ENTRY (gtk_bin_get_child
536             (GTK_BIN (priv->pwd1st_caption)));
537
538     pwd2nd_entry = GTK_ENTRY (gtk_bin_get_child
539             (GTK_BIN (priv->pwd2nd_caption)));
540
541     text1 = GTK_ENTRY (pwd1st_entry)->text;
542     text2 = GTK_ENTRY (pwd2nd_entry)->text;
543
544     if (arg1 == GTK_RESPONSE_OK) {
545         /* User provided something for password? */
546         if (text1[0] != '\0') {
547             if (strcmp (text1, text2) == 0) {
548                 /* Passwords match, so accept set password */
549                 priv->protection = TRUE;
550
551             } else if (text2[0] == '\0') {
552                 /* Second field is empty, so show error,
553                    but don't clear the fields */
554                 g_signal_stop_emission_by_name (G_OBJECT(dialog), "response");
555                 hildon_banner_show_information (GTK_WIDGET (dialog), NULL, c_(HILDON_SET_PASSWORD_DIALOG_MISMATCH));
556
557                 gtk_widget_grab_focus (GTK_WIDGET (priv->pwd2nd_entry));
558
559             } else {
560                 /* Error: Passwords don't match, so start over */
561                 g_signal_stop_emission_by_name (G_OBJECT(dialog), "response");
562                 gtk_entry_set_text (pwd1st_entry, "");
563                 gtk_entry_set_text (pwd2nd_entry, "");
564                 hildon_banner_show_information (GTK_WIDGET (dialog), NULL, c_(HILDON_SET_PASSWORD_DIALOG_MISMATCH));
565
566                 gtk_widget_grab_focus (GTK_WIDGET (priv->pwd1st_entry));
567             }
568         } else {
569             /* First field is empty */
570             g_signal_stop_emission_by_name (G_OBJECT (dialog), "response");
571             if (text2[0] == '\0') {
572                 /* Error: Both fields are empty */
573                 hildon_banner_show_information (GTK_WIDGET (dialog), NULL, c_(HILDON_SET_PASSWORD_DIALOG_EMPTY));
574             } else {
575                 /* Error: Second field doesn't match
576                    the empty first field, so start over */
577                 hildon_banner_show_information (GTK_WIDGET (dialog), NULL, c_(HILDON_SET_PASSWORD_DIALOG_MISMATCH));
578                 gtk_entry_set_text (pwd2nd_entry, "");
579             }
580
581             gtk_widget_grab_focus (GTK_WIDGET (pwd1st_entry));
582         }
583     } else { 
584         /* Watch out for fading boolean values */
585         priv->protection = FALSE;
586     }         
587 }
588
589 static void
590 hildon_checkbox_toggled                         (GtkWidget *widget, 
591                                                  gpointer dialog)
592 {
593     HildonSetPasswordDialogPrivate *priv = HILDON_SET_PASSWORD_DIALOG_GET_PRIVATE (dialog);
594     gboolean active;
595
596     g_assert (priv);
597
598     /* If the user enabled/disabled the password protection feature
599        we enable/disable password entries accordingly */
600     active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
601     gtk_widget_set_sensitive (GTK_WIDGET (priv->pwd1st_entry), active);
602     gtk_widget_set_sensitive (GTK_WIDGET (priv->pwd2nd_entry), active);
603 }
604
605 /**
606  * hildon_set_password_dialog_get_type:
607  *
608  * Returns GType for HildonPasswordDialog as produced by
609  * g_type_register_static().
610  *
611  * Returns: HildonSetPasswordDialog type
612  */
613 GType G_GNUC_CONST
614 hildon_set_password_dialog_get_type             (void)
615 {
616     static GType dialog_type = 0;
617
618     if (! dialog_type) {
619         static const GTypeInfo dialog_info = {
620             sizeof (HildonSetPasswordDialogClass),
621             NULL,       /* base_init */
622             NULL,       /* base_finalize */
623             (GClassInitFunc) hildon_set_password_dialog_class_init,
624             NULL,       /* class_finalize */
625             NULL,       /* class_data */
626             sizeof (HildonSetPasswordDialog),
627             0,  /* n_preallocs */
628             (GInstanceInitFunc) hildon_set_password_dialog_init
629         };
630
631         dialog_type = g_type_register_static (GTK_TYPE_DIALOG,
632                 "HildonSetPasswordDialog",
633                 &dialog_info, 0);
634     }
635
636     return dialog_type;
637 }
638
639 /**
640  * hildon_set_password_dialog_new:
641  * @parent: parent window; can be NULL
642  * @modify_protection: TRUE creates a new change password dialog and FALSE
643  *                     creates a new set password dialog 
644  * 
645  * Constructs a new HildonSetPasswordDialog.
646  *
647  * Returns: a new #GtkWidget of type HildonSetPasswordDialog
648  */
649 GtkWidget*
650 hildon_set_password_dialog_new                  (GtkWindow *parent,
651                                                  gboolean modify_protection)
652 {
653     return hildon_set_password_dialog_new_with_default (parent, "", modify_protection);
654 }
655
656 /**
657  * hildon_set_password_dialog_new_with_default:
658  * @parent: parent window; can be NULL
659  * @password: a default password to be shown in password field
660  * @modify_protection: TRUE creates a new change password dialog and FALSE
661  *                     creates a new set password dialog 
662  * 
663  * Same as #hildon_set_password_dialog_new, but with a default password
664  * in password field.
665  *
666  * Returns: a new #GtkWidget of type HildonSetPasswordDialog
667  */
668
669 GtkWidget*
670 hildon_set_password_dialog_new_with_default     (GtkWindow *parent,
671                                                  const gchar *password,
672                                                  gboolean modify_protection)
673 {
674     GtkWidget *dialog = g_object_new (HILDON_TYPE_SET_PASSWORD_DIALOG,
675             "modify_protection", modify_protection,
676             "password", password, NULL);
677
678     if (parent != NULL) {
679         gtk_window_set_transient_for (GTK_WINDOW (dialog), parent);
680     }
681
682     return dialog;
683 }
684
685 /**
686  * hildon_set_password_dialog_get_password:
687  * @dialog: pointer to HildonSetPasswordDialog
688  * 
689  * Returns current password.
690  *
691  * Returns: changed password ( if the dialog is successfully 
692  * accepted with 'OK' ( and when the check box is 'ON' ( in Change Password
693  * Dialog ))
694  */
695 const gchar*
696 hildon_set_password_dialog_get_password         (HildonSetPasswordDialog *dialog)
697 {
698     HildonSetPasswordDialogPrivate *priv;
699
700     g_return_val_if_fail (HILDON_IS_SET_PASSWORD_DIALOG (dialog), NULL);
701
702     priv = HILDON_SET_PASSWORD_DIALOG_GET_PRIVATE (dialog);
703     g_assert (priv);
704
705     return GTK_ENTRY (priv->pwd1st_entry)->text;
706 }
707
708 /**
709  * hildon_set_password_dialog_get_protected:
710  * @dialog: pointer to HildonSetPasswordDialog
711  * 
712  * Returns the protection mode.
713  *
714  * Returns: password protection mode ( TRUE when the protection is
715  *               'ON' and FALSE when the protection is 'OFF' )
716  */
717 gboolean
718 hildon_set_password_dialog_get_protected        (HildonSetPasswordDialog *dialog)
719 {
720     HildonSetPasswordDialogPrivate *priv;
721
722     g_return_val_if_fail (HILDON_IS_SET_PASSWORD_DIALOG (dialog), FALSE);
723
724     priv = HILDON_SET_PASSWORD_DIALOG_GET_PRIVATE (dialog);
725     g_assert (priv);
726
727     return priv->protection;
728 }
729
730 /**
731  * hildon_set_password_dialog_set_message:
732  * @dialog: the dialog
733  * @message: the message or some other descriptive text to be set
734  * 
735  * Sets the optional descriptive text.
736  */
737 void 
738 hildon_set_password_dialog_set_message          (HildonSetPasswordDialog *dialog, 
739                                                  const gchar *message)
740 {
741     HildonSetPasswordDialogPrivate *priv = NULL;
742
743     g_return_if_fail (HILDON_IS_SET_PASSWORD_DIALOG (dialog));
744
745     priv = HILDON_SET_PASSWORD_DIALOG_GET_PRIVATE (dialog);
746     g_assert (priv);
747
748     gtk_label_set_text (priv->message_label, message);  
749 }