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