* hildon-widgets/hildon-calendar-popup.c * hildon-widgets/hildon-color-button.c ...
[hildon] / hildon-widgets / hildon-get-password-dialog.c
1 /*
2  * This file is part of hildon-libs
3  *
4  * Copyright (C) 2005 Nokia Corporation.
5  *
6  * Contact: Luc Pionchon <luc.pionchon@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; either 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 #include <glib.h>
26
27 #include <errno.h>
28 #include <string.h>
29 #include <strings.h>
30 #include <unistd.h>
31 #include <stdio.h>
32
33 #include <gtk/gtk.h>
34
35 /* FIXME: These two includes are broken */
36 #include <hildon-lgpl/hildon-widgets/gtk-infoprint.h>
37 #include <hildon-lgpl/hildon-widgets/hildon-input-mode-hint.h>
38
39 #include <hildon-widgets/hildon-caption.h>
40 #include <hildon-widgets/hildon-get-password-dialog.h>
41
42 #ifdef HAVE_CONFIG_H
43 #include <config.h>
44 #endif
45
46 #include <libintl.h>
47 #define _(String) dgettext(PACKAGE, String)
48
49 static GtkDialogClass * parent_class;
50
51 typedef struct _HildonGetPasswordDialogPrivate 
52   HildonGetPasswordDialogPrivate;
53
54 struct _HildonGetPasswordDialogPrivate {
55   GtkButton *okButton;
56   GtkButton *cancelButton;
57   
58   GtkLabel *domainLabel;
59   HildonCaption *passwordEntry;
60 };
61
62
63 #define HILDON_GET_PASSWORD_DIALOG_GET_PRIVATE(obj) \
64  (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
65   HILDON_TYPE_GET_PASSWORD_DIALOG, HildonGetPasswordDialogPrivate));
66
67 static void
68 hildon_get_password_dialog_class_init(HildonGetPasswordDialogClass *
69                                       class);
70 static void hildon_get_password_dialog_init(HildonGetPasswordDialog *
71                                             widget);
72 static void hildon_get_password_set_property(GObject * object,
73                                              guint prop_id,
74                                              const GValue * value,
75                                              GParamSpec * pspec);
76 static void hildon_get_password_get_property(GObject * object,
77                                              guint prop_id, GValue * value,
78                                              GParamSpec * pspec);
79 void hildon_get_password_dialog_set_domain(HildonGetPasswordDialog *dialog, 
80                                            gchar *domain);
81
82 static void _invalid_input(GtkWidget *widget, GtkInvalidInputType reason, 
83                            gpointer user_data);
84
85 enum{
86     PROP_NONE = 0,
87     PROP_DOMAIN,
88     PROP_PASSWORD,
89     PROP_NUMBERS_ONLY,
90     PROP_CAPTION_LABEL,
91     PROP_MAX_CHARS
92 };
93
94 /* Private functions */
95 static void
96 hildon_get_password_set_property(GObject * object,
97                                  guint prop_id,
98                                  const GValue * value, GParamSpec * pspec)
99 {
100   HildonGetPasswordDialog *dialog = HILDON_GET_PASSWORD_DIALOG(object);
101   HildonGetPasswordDialogPrivate *priv;
102   
103   priv = HILDON_GET_PASSWORD_DIALOG_GET_PRIVATE(dialog);
104   
105   switch (prop_id) {
106   case PROP_DOMAIN:
107     /* Set label text representing password domain */
108     gtk_label_set_text(priv->domainLabel, g_value_get_string(value));
109     break;
110   case PROP_PASSWORD:
111     gtk_entry_set_text(GTK_ENTRY
112                        (gtk_bin_get_child(GTK_BIN(priv->passwordEntry))),
113                        g_value_get_string(value));
114     break;
115   case PROP_NUMBERS_ONLY:
116     /* FIXME: This is broken, property value is not used in any way */
117     g_object_set( G_OBJECT
118                   (gtk_bin_get_child(GTK_BIN(priv->passwordEntry))),
119                   "input-mode", HILDON_INPUT_MODE_HINT_NUMERIC, NULL );
120     break;
121   case PROP_CAPTION_LABEL:
122     hildon_get_password_dialog_set_caption(dialog, g_value_get_string(value));
123     break;
124   case PROP_MAX_CHARS:
125     /* FIXME: This is broken. set_max_characters wants an int, not string */
126     hildon_get_password_dialog_set_max_characters(dialog, 
127                                                   g_value_get_string(value));
128     break;
129   default:
130     G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
131     break;
132   }
133 }
134   
135 static void
136 hildon_get_password_get_property(GObject * object,
137                                  guint prop_id,
138                                  GValue * value, GParamSpec * pspec)
139 {
140     HildonGetPasswordDialog *dialog = HILDON_GET_PASSWORD_DIALOG(object);
141     HildonGetPasswordDialogPrivate *priv;
142     const gchar *string;
143     gint max_length; 
144
145     priv = HILDON_GET_PASSWORD_DIALOG_GET_PRIVATE(dialog);
146     
147     switch (prop_id) {
148     case PROP_DOMAIN:
149       string = gtk_label_get_text(priv->domainLabel);
150       g_value_set_string(value, string);
151     case PROP_PASSWORD:
152       string = gtk_entry_get_text(GTK_ENTRY(priv->passwordEntry));
153       g_value_set_string(value, string);
154       break;
155     case PROP_CAPTION_LABEL:
156       string = hildon_caption_get_label(priv->passwordEntry);
157       g_value_set_string(value, string);
158       break;
159     case PROP_MAX_CHARS:
160       max_length = gtk_entry_get_max_length(
161               GTK_ENTRY (hildon_caption_get_control (priv->passwordEntry)));
162       g_value_set_int(value, max_length);
163       break;
164     default:
165       G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
166       break;
167     }
168 }
169
170 static void
171 hildon_get_password_dialog_class_init(HildonGetPasswordDialogClass * class)
172 {
173
174   GObjectClass *object_class = G_OBJECT_CLASS(class);
175   
176   parent_class = g_type_class_peek_parent(class);
177   
178   /* Override virtual functions */
179   object_class->set_property = hildon_get_password_set_property;
180   object_class->get_property = hildon_get_password_get_property;
181   
182   /* Install new properties */
183   /* FIXME: Why this is not READWRITE */
184   g_object_class_install_property 
185     (object_class, 
186      PROP_DOMAIN, 
187      g_param_spec_string ("domain",
188                           "Domain",
189                           "Set domain(content) for optional label.",
190                           NULL,
191                           G_PARAM_WRITABLE));
192   
193   g_object_class_install_property
194     (object_class, 
195      PROP_PASSWORD,
196      g_param_spec_string ("password",
197                           "Password",
198                           "Set content for password entry",
199                           "DEFAULT",
200                           G_PARAM_READWRITE));
201
202   /* FIXME: Why this is not READWRITE?? */
203   g_object_class_install_property
204     (object_class, 
205      PROP_NUMBERS_ONLY,
206      g_param_spec_boolean ("numbers_only",
207                           "NumbersOnly",
208                           "Set entry to accept only numeric values",
209                           FALSE,
210                           G_PARAM_WRITABLE));
211
212   g_object_class_install_property
213     (object_class, 
214      PROP_CAPTION_LABEL,
215      g_param_spec_string ("caption-label",
216                           "Caption Label",
217                           "The text to be set as the caption label",
218                           NULL,
219                           G_PARAM_READWRITE));
220
221   g_object_class_install_property
222     (object_class, 
223      PROP_MAX_CHARS,
224      g_param_spec_int ("max-characters",
225                        "Maximum Characters",
226                        "The maximum number of characters the password"
227                        " dialog accepts",
228                        G_MININT,
229                        G_MAXINT,
230                        0,
231                        G_PARAM_READWRITE));
232
233     /* Install private structure */
234     g_type_class_add_private(class,
235                              sizeof(HildonGetPasswordDialogPrivate));
236 }
237
238 static void
239 hildon_get_password_dialog_init(HildonGetPasswordDialog * dialog)
240 {
241     GtkSizeGroup * group;
242     GtkWidget *control;
243
244     /* Cache private pointer for faster member access */  
245     HildonGetPasswordDialogPrivate *priv =
246       HILDON_GET_PASSWORD_DIALOG_GET_PRIVATE(dialog);
247
248     /* Sizegroup for captions */
249     group = GTK_SIZE_GROUP(gtk_size_group_new
250                            (GTK_SIZE_GROUP_HORIZONTAL));
251
252     /* Initial properties for the dialog */
253     gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
254     gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
255     gtk_window_set_title(GTK_WINDOW(dialog), 
256                          _(HILDON_GET_PASSWORD_DIALOG_TITLE));
257
258     /* Optional password domain label */
259     priv->domainLabel = GTK_LABEL(gtk_label_new(NULL));
260     
261     /* Create buttons */
262     priv->okButton =
263       GTK_BUTTON(gtk_dialog_add_button(GTK_DIALOG(dialog),
264                                        _(HILDON_GET_PASSWORD_DIALOG_OK),
265                                        GTK_RESPONSE_OK));
266     priv->cancelButton =
267       GTK_BUTTON(gtk_dialog_add_button(GTK_DIALOG(dialog),
268                                        _(HILDON_GET_PASSWORD_DIALOG_CANCEL),
269                                        GTK_RESPONSE_CANCEL));
270
271     /* Create password text entry */
272     control = gtk_entry_new();
273     gtk_entry_set_visibility(GTK_ENTRY(control), FALSE);
274     priv->passwordEntry = HILDON_CAPTION
275       (hildon_caption_new(group,
276                           _(HILDON_GET_PASSWORD_DIALOG_PASSWORD ),
277                           control, NULL,
278                           HILDON_CAPTION_OPTIONAL));
279     hildon_caption_set_separator(HILDON_CAPTION(priv->passwordEntry), "");
280     
281
282     /* Do the basic layout */
283     gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
284                        GTK_WIDGET(priv->domainLabel), FALSE, FALSE, 0);
285     gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
286                        GTK_WIDGET(priv->passwordEntry), FALSE, FALSE, 0);
287     gtk_widget_show_all(GTK_DIALOG(dialog)->vbox);
288     
289     gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
290
291     /* FIXME: Do not leak group */
292 }
293
294 /* Public functions */
295
296 /**
297  * hildon_get_password_dialog_get_type:
298  *
299  * Returns GType for HildonGetPasswordDialog as produced by
300  * g_type_register_static().
301  *
302  * Return value: HildonGetPasswordDialog type
303  **/
304 GType hildon_get_password_dialog_get_type()
305 {
306     static GType dialog_type = 0;
307
308     if (!dialog_type) {
309         static const GTypeInfo dialog_info = {
310             sizeof(HildonGetPasswordDialogClass),
311             NULL,       /* base_init */
312             NULL,       /* base_finalize */
313             (GClassInitFunc) hildon_get_password_dialog_class_init,
314             NULL,       /* class_finalize */
315             NULL,       /* class_data */
316             sizeof(HildonGetPasswordDialog),
317             0,  /* n_preallocs */
318             (GInstanceInitFunc) hildon_get_password_dialog_init
319         };
320
321         dialog_type = g_type_register_static(GTK_TYPE_DIALOG,
322                                              "HildonGetPasswordDialog",
323                                              &dialog_info, 0);
324     }
325     return dialog_type;
326 }
327
328 /**
329  * hildon_get_password_dialog_new:
330  * @parent: parent window; can be NULL
331  * @get_old_password_title: FALSE creates a new get password dialog and
332  *                     TRUE creates a new get old password dialog 
333  * 
334  * Construct a new HildonGetPasswordDialog.
335  *
336  * Return value: a new #GtkWidget of type HildonGetPasswordDialog
337  **/
338 GtkWidget *hildon_get_password_dialog_new(GtkWindow * parent,
339                                           gboolean get_old_password_title)
340 {
341     HildonGetPasswordDialog *dialog = g_object_new
342         (HILDON_TYPE_GET_PASSWORD_DIALOG,
343          NULL);
344
345     if (get_old_password_title == FALSE) {
346       HildonGetPasswordDialogPrivate *priv;
347
348       /* Override "get old password" defaults set in dialog_init */
349       /* FIXME: This behaviour is confusing */
350       gtk_window_set_title(GTK_WINDOW(dialog), 
351                              _(HILDON_GET_PASSWORD_VERIFY_DIALOG_TITLE));
352                 priv = HILDON_GET_PASSWORD_DIALOG_GET_PRIVATE(dialog);
353         gtk_button_set_label(priv->okButton, 
354                              _(HILDON_GET_PASSWORD_VERIFY_DIALOG_OK));
355         gtk_button_set_label(priv->cancelButton, 
356                              _(HILDON_GET_PASSWORD_VERIFY_DIALOG_CANCEL));
357         hildon_caption_set_label(priv->passwordEntry,
358                                  _(HILDON_GET_PASSWORD_VERIFY_DIALOG_PASSWORD)
359                                  );
360     }
361
362     if (parent != NULL) {
363         gtk_window_set_transient_for(GTK_WINDOW(dialog), parent);
364     }
365
366     return GTK_WIDGET(dialog);
367 }
368
369 /**
370  * hildon_get_password_dialog_new:
371  * @parent: parent window; can be NULL
372  * @password: a default password to be shown in password field.
373  * @get_old_password_title: FALSE creates a new get password dialog and
374  *                     TRUE creates a new get old password dialog 
375  * 
376  * Same as #hildon_get_password_dialog_new but with a default password
377  * in password field.
378  *
379  * Return value: a new #GtkWidget of type HildonGetPasswordDialog
380  **/
381 GtkWidget *hildon_get_password_dialog_new_with_default (GtkWindow * parent,
382                                                         gchar *password,
383                                                gboolean get_old_password_title)
384 {
385     GtkWidget *dialog;
386
387     dialog = hildon_get_password_dialog_new(parent, get_old_password_title);
388     if(password != NULL)
389         g_object_set(G_OBJECT(dialog), "password", password, NULL);
390
391     return GTK_WIDGET(dialog);
392 }
393
394 /**
395  * hildon_get_password_dialog_get_password:
396  * @dialog: pointer to HildonSetPasswordDialog
397  * 
398  * Gets the currently inputted password.
399  *
400  * Return value: current password ( if the dialog is successfully 
401  * accepted with 'OK'  )
402  **/
403 const gchar
404     *hildon_get_password_dialog_get_password(HildonGetPasswordDialog *
405                                              dialog)
406 {
407     GtkEntry *entry1;
408     gchar *text1;
409
410     HildonGetPasswordDialogPrivate *priv;
411
412     priv = HILDON_GET_PASSWORD_DIALOG_GET_PRIVATE(dialog);
413
414     /* Retrieve the password entry widget */
415     entry1 = GTK_ENTRY(gtk_bin_get_child(GTK_BIN(
416                        priv->passwordEntry)));
417
418     text1 = GTK_ENTRY(entry1)->text;
419
420     return text1;
421 }
422
423 /**
424  * hildon_get_password_dialog_set_domain(GtkWidget *dialog, 
425  * @dialog: the dialog
426  * @domain: the domain or some other descriptive text to be set.
427  * 
428  * sets the optional descriptive text
429  */
430
431 void hildon_get_password_dialog_set_domain(HildonGetPasswordDialog *dialog, 
432                                                 gchar *domain)
433 {
434   HildonGetPasswordDialogPrivate *priv =
435     HILDON_GET_PASSWORD_DIALOG_GET_PRIVATE(dialog);
436   gtk_label_set_text(priv->domainLabel, domain);
437   
438 }
439
440 /**
441  * hildon_get_password_dialog_set_dialog_title
442  *        (HildonGetPasswordDialog *dialog, gchar *new_title) 
443  * @dialog: the dialog
444  * @new_ title: the text to be set as the dialog title.
445  * 
446  * sets the dialog title
447  */
448 void hildon_get_password_dialog_set_title(HildonGetPasswordDialog *dialog,
449                                           gchar *new_title)
450
451 {
452   /* FIXME: This method is completely useless, should be deprecated/removed */
453   g_return_if_fail (new_title !=NULL);
454   gtk_window_set_title(GTK_WINDOW(dialog), 
455                        new_title);
456 }
457
458 /**
459  * hildon_get_password_dialog_set_caption
460  *        (HildonGetPasswordDialog *dialog, gchar *new_caption) 
461  * @dialog: the dialog
462  * @new_caption: the text to be set as the caption label.
463  * 
464  * sets the password entry field's neigbouring label.
465  */
466
467
468 void hildon_get_password_dialog_set_caption(HildonGetPasswordDialog *dialog,
469                                                   gchar *new_caption)
470 {
471   
472
473   HildonGetPasswordDialogPrivate *priv =
474     HILDON_GET_PASSWORD_DIALOG_GET_PRIVATE(dialog);  
475   g_return_if_fail (new_caption !=NULL);
476   hildon_caption_set_label(priv->passwordEntry, new_caption);
477
478 }
479
480 /**
481  * hildon_get_password_dialog_set_max_characters
482  *        (HildonGetPasswordDialog *dialog, gint max_characters,
483  *         gchar *error_ib_message) 
484  * @dialog: the dialog
485  * @max_characters: the maximum number of characters the password dialog
486  * accepts.
487  * @new_caption: the text to be set as the caption label.
488  * 
489  * sets the password entry field's neigbouring label.
490  */
491
492 void hildon_get_password_dialog_set_max_characters (HildonGetPasswordDialog *dialog, gint max_characters )
493 {
494
495   HildonGetPasswordDialogPrivate *priv =
496     HILDON_GET_PASSWORD_DIALOG_GET_PRIVATE(dialog);  
497
498   g_return_if_fail(max_characters >0);
499   g_return_if_fail(dialog);
500
501   /* Apply the given length to password entry */
502   gtk_entry_set_max_length(GTK_ENTRY
503                            (hildon_caption_get_control
504                             (priv->passwordEntry)),
505                            max_characters);
506
507   /* Connect callback to show error banner if the limit is exceeded */
508   g_signal_connect(GTK_ENTRY
509                    (hildon_caption_get_control
510                     (priv->passwordEntry)),
511                    "invalid_input",
512                    G_CALLBACK(_invalid_input),
513                    NULL
514                    );
515
516 }
517
518 static void _invalid_input(GtkWidget *widget, GtkInvalidInputType reason, 
519                            gpointer user_data) 
520 {
521   if (reason==GTK_INVALID_INPUT_MAX_CHARS_REACHED) {
522     gtk_infoprint(GTK_WINDOW(widget), _(HILDON_GET_PASSWORD_DIALOG_MAX_CHARS));
523   }
524
525 }