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