2 * This file is part of hildon-libs
4 * Copyright (C) 2006 Nokia Corporation, all rights reserved.
6 * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
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
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.
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
26 #include "hildon-code-dialog.h"
27 #include "hildon-defines.h"
28 #include "hildon-banner.h"
30 #include <gdk/gdkkeysyms.h>
32 #include<gtk/gtkbutton.h>
33 #include<gtk/gtkentry.h>
34 #include<gtk/gtkicontheme.h>
35 #include<gtk/gtktable.h>
36 #include<gtk/gtkvbox.h>
37 #include<gtk/gtkbbox.h>
38 #include<gtk/gtklabel.h>
39 #include<gtk/gtkalignment.h>
47 #define HEIGHT (38-HILDON_MARGIN_DEFAULT)
48 #define WIDTH (60-HILDON_MARGIN_DEFAULT)
49 #define BACKSPACE_ICON "qgn_calculator_backspace"
51 #define _(String) dgettext(PACKAGE, String)
52 #define c_(String) dgettext("hildon-common-strings", String)
53 #define DEVICELOCK_OK _("secu_enter_lock_code_dialog_ok")
54 #define DEVICELOCK_CANCEL _("secu_enter_lock_code_dialog_cancel")
55 #define DEVICELOCK_TITLE _("secu_application_title")
56 #define DEVICELOCK_MAX_CHAR_REACHED c_("ckdg_ib_maximum_characters_reached")
60 #define MAX_PINCODE_LEN (10)
64 static void hildon_code_dialog_class_init (HildonCodeDialogClass *cd_class);
65 static void hildon_code_dialog_init (HildonCodeDialog *self);
66 static void hildon_code_dialog_finalize (GObject *self);
67 static void hildon_code_dialog_button_clicked (GtkButton *buttonm,
69 static void hildon_code_dialog_insert_text (GtkEditable *editable,
75 static gboolean hildon_code_dialog_key_press_event (GtkWidget *widget,
80 GtkDialogClass *parent_class;
82 struct _HildonCodeDialogPrivate
85 GtkWidget *buttons[5][3];
89 GType hildon_code_dialog_get_type (void)
91 static GType type = 0;
95 static const GTypeInfo info =
97 sizeof(HildonCodeDialogClass),
99 NULL, /* base_finalize */
100 (GClassInitFunc) hildon_code_dialog_class_init,
101 NULL, /* class_finalize */
102 NULL, /* class_data */
103 sizeof(HildonCodeDialog),
105 (GInstanceInitFunc) hildon_code_dialog_init
107 type = g_type_register_static (GTK_TYPE_DIALOG,
108 "HildonCodeDialog", &info, 0);
113 static void hildon_code_dialog_class_init (HildonCodeDialogClass *cd_class)
115 /* Get convenience variables */
116 GObjectClass *object_class = G_OBJECT_CLASS (cd_class);
118 parent_class = GTK_DIALOG_CLASS (g_type_class_peek_parent (cd_class));
120 object_class->finalize = hildon_code_dialog_finalize;
124 static void hildon_code_dialog_init (HildonCodeDialog *dialog)
126 HildonCodeDialogPrivate *priv;
128 GtkWidget *dialog_vbox1 = NULL;
129 GtkWidget *table = NULL;
130 GtkWidget *alignment = NULL;
131 GtkWidget *vbox1 = NULL;
132 GtkWidget *image1 = NULL;
133 GtkWidget *dialog_action_area1 = NULL;
136 GtkWidget *cancelButton;
138 priv = dialog->priv = (HildonCodeDialogPrivate*) g_malloc0
139 (sizeof (HildonCodeDialogPrivate));
141 const gchar* numstrs[10] = {
142 "0","1","2","3","4","5","6","7","8","9"
145 GdkPixbuf* pixbuf = NULL;
146 GtkIconTheme* icon_theme = NULL;
147 GtkIconInfo *icon_info = NULL;
150 /* Set default title */
151 gtk_window_set_title (GTK_WINDOW (dialog), DEVICELOCK_TITLE);
153 gtk_window_set_type_hint(GTK_WINDOW (dialog), GDK_WINDOW_TYPE_HINT_DIALOG);
155 hints.min_width = -1;
156 hints.min_height = -1;
157 hints.max_width = -1;
158 hints.max_height = -1;
160 gtk_window_set_geometry_hints(GTK_WINDOW(dialog), GTK_WIDGET(dialog),
162 GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE);
164 table = gtk_table_new (4, 3, FALSE);
165 gtk_table_set_row_spacings (GTK_TABLE (table), HILDON_MARGIN_DEFAULT );
166 gtk_table_set_col_spacings (GTK_TABLE (table), HILDON_MARGIN_DEFAULT );
168 dialog_vbox1 = GTK_DIALOG (dialog)->vbox;
169 vbox1 = gtk_vbox_new (FALSE, 0);
170 gtk_box_set_spacing (GTK_BOX(vbox1),HILDON_MARGIN_DOUBLE);
172 priv->help_text= gtk_label_new ("");
173 alignment=gtk_alignment_new(0.5,0,1,1);
174 gtk_container_add(GTK_CONTAINER(alignment),priv->help_text);
176 priv->entry = gtk_entry_new ();
178 GTK_WIDGET_UNSET_FLAGS(GTK_WIDGET(priv->entry),GTK_CAN_FOCUS);
179 gtk_entry_set_invisible_char (GTK_ENTRY(priv->entry), g_utf8_get_char ("*"));
180 gtk_entry_set_alignment (GTK_ENTRY(priv->entry),1.0);
182 gtk_editable_set_editable (GTK_EDITABLE(priv->entry),FALSE);
183 gtk_entry_set_visibility (GTK_ENTRY(priv->entry), FALSE);
185 gtk_box_pack_start (GTK_BOX (vbox1),alignment,TRUE,FALSE,0);
186 gtk_box_pack_start (GTK_BOX (vbox1),priv->entry,TRUE,FALSE,0);
187 gtk_box_pack_start (GTK_BOX (vbox1),table,FALSE,TRUE,0);
189 gtk_box_pack_start (GTK_BOX (dialog_vbox1), vbox1,FALSE,TRUE,0);
193 priv->buttons[0][i-1] = gtk_button_new_with_mnemonic(numstrs[i]);
194 gtk_widget_set_size_request(priv->buttons[0][i-1],WIDTH,HEIGHT);
195 gtk_table_attach_defaults(GTK_TABLE(table), priv->buttons[0][i-1],
200 priv->buttons[1][i-4] = gtk_button_new_with_mnemonic (numstrs[i]);
201 gtk_widget_set_size_request(priv->buttons[1][i-4],WIDTH,HEIGHT);
202 gtk_table_attach_defaults(GTK_TABLE(table),priv->buttons[1][i-4],
207 priv->buttons[2][i-7] = gtk_button_new_with_mnemonic (numstrs[i]);
208 gtk_widget_set_size_request(priv->buttons[2][i-7], WIDTH,HEIGHT);
209 gtk_table_attach_defaults(GTK_TABLE(table), priv->buttons[2][i-7],
213 priv->buttons[3][0] = priv->buttons[3][1] =
214 gtk_button_new_with_mnemonic (numstrs[0]);
215 gtk_widget_set_size_request (priv->buttons[3][0], WIDTH,HEIGHT);
216 gtk_table_attach (GTK_TABLE(table), priv->buttons[3][0],
217 0,2,3,4, (GtkAttachOptions) (GTK_FILL),
218 (GtkAttachOptions) (0), 0, 0);
220 priv->buttons[3][2] = gtk_button_new ();
221 gtk_widget_set_size_request(priv->buttons[3][2], WIDTH,HEIGHT);
222 gtk_table_attach_defaults(GTK_TABLE(table), priv->buttons[3][2],
225 icon_theme = gtk_icon_theme_get_default ();
227 icon_info = gtk_icon_theme_lookup_icon(icon_theme, BACKSPACE_ICON, 1,
228 GTK_ICON_LOOKUP_NO_SVG);
229 base_size = gtk_icon_info_get_base_size(icon_info);
230 gtk_icon_info_free(icon_info);
232 pixbuf = gtk_icon_theme_load_icon (icon_theme,
233 BACKSPACE_ICON, base_size,
234 GTK_ICON_LOOKUP_NO_SVG,
236 image1 = gtk_image_new_from_pixbuf (pixbuf);
237 g_object_unref (G_OBJECT(pixbuf));
238 gtk_container_add (GTK_CONTAINER (priv->buttons[3][2]), image1);
239 dialog_action_area1 = GTK_DIALOG (dialog)->action_area;
240 gtk_button_box_set_layout (GTK_BUTTON_BOX(dialog_action_area1),
243 okButton = gtk_dialog_add_button (GTK_DIALOG(dialog),DEVICELOCK_OK,
246 gtk_dialog_add_button (GTK_DIALOG(dialog),DEVICELOCK_CANCEL,
247 GTK_RESPONSE_CANCEL);
249 gtk_widget_set_sensitive (okButton, FALSE);
251 priv->buttons[4][0] = priv->buttons[4][1] = okButton;
252 priv->buttons[4][2] = cancelButton;
257 g_signal_connect (G_OBJECT(priv->entry), "insert_text",
258 G_CALLBACK (hildon_code_dialog_insert_text), dialog);
260 gtk_entry_set_max_length(GTK_ENTRY(priv->entry),MAX_PINCODE_LEN);
266 g_signal_connect (G_OBJECT (priv->buttons[x][y]), "clicked",
267 G_CALLBACK (hildon_code_dialog_button_clicked), dialog);
268 g_signal_connect (G_OBJECT (priv->buttons[x][y]), "key-press-event",
269 G_CALLBACK (hildon_code_dialog_key_press_event), dialog);
273 g_signal_connect (G_OBJECT (priv->buttons[3][0]), "clicked",
274 G_CALLBACK (hildon_code_dialog_button_clicked), dialog);
275 g_signal_connect (G_OBJECT (priv->buttons[3][0]), "key-press-event",
276 G_CALLBACK (hildon_code_dialog_key_press_event), dialog);
278 g_signal_connect (G_OBJECT (priv->buttons[3][2]), "clicked",
279 G_CALLBACK (hildon_code_dialog_button_clicked), dialog);
280 g_signal_connect (G_OBJECT (priv->buttons[3][2]), "key-press-event",
281 G_CALLBACK (hildon_code_dialog_key_press_event), dialog);
283 g_signal_connect (G_OBJECT (okButton), "key-press-event",
284 G_CALLBACK(hildon_code_dialog_key_press_event), dialog);
286 g_signal_connect (G_OBJECT (cancelButton), "key-press-event",
287 G_CALLBACK (hildon_code_dialog_key_press_event), dialog);
291 static void hildon_code_dialog_finalize (GObject *self)
293 HildonCodeDialog *dialog = HILDON_CODE_DIALOG (self);
295 fprintf( stderr, "called destroy\n" );
297 g_free (dialog->priv);
299 G_OBJECT_CLASS (parent_class)->finalize (self);
302 /* Signal handlers */
303 void hildon_code_dialog_button_clicked (GtkButton *button, gpointer user_data)
305 HildonCodeDialog *dialog = HILDON_CODE_DIALOG (user_data);
306 HildonCodeDialogPrivate *priv = dialog->priv;
307 const char *number = gtk_button_get_label (button);
309 if (number && *number )
311 gtk_entry_append_text (GTK_ENTRY (priv->entry), number);
316 gchar *text = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->entry)));
326 pos = g_utf8_find_prev_char (text, pos);
333 gtk_entry_set_text (GTK_ENTRY (priv->entry), text);
337 gtk_widget_set_sensitive (priv->buttons[4][0], FALSE);
345 static void hildon_code_dialog_insert_text (GtkEditable *editable,
347 gint new_text_length,
351 HildonCodeDialog *dialog = HILDON_CODE_DIALOG (user_data);
352 HildonCodeDialogPrivate *priv = dialog->priv;
353 gchar * text = g_strdup(gtk_entry_get_text (GTK_ENTRY (priv->entry)));
354 glong length = g_utf8_strlen (text, -1);
357 if (length == MAX_PINCODE_LEN)
359 hildon_banner_show_information (dialog,
361 DEVICELOCK_MAX_CHAR_REACHED);
366 /* make the Ok button sensitive */
367 gtk_widget_set_sensitive(priv->buttons[4][0], TRUE);
371 static gboolean hildon_code_dialog_key_press_event (GtkWidget *widget,
375 HildonCodeDialog *dialog = HILDON_CODE_DIALOG (user_data);
376 HildonCodeDialogPrivate *priv = dialog->priv;
377 GtkWidget *new_widget = widget;
380 for (x = 0; x < 5; x++)
382 for (y = 0; y < 3; y++)
384 if (priv->buttons[x][y] == widget)
392 while (new_widget == widget)
394 switch (event->keyval)
416 new_widget = priv->buttons[x][y];
419 gtk_widget_grab_focus (new_widget);
427 * hildon_code_dialog_new:
429 * Use this function to create a new HildonCodeDialog.
431 * Return value: A @HildonCodeDialog.
433 GtkWidget *hildon_code_dialog_new()
435 HildonCodeDialog *dialog = g_object_new (HILDON_TYPE_CODE_DIALOG, NULL);
437 return GTK_WIDGET (dialog);
441 * hildon_code_dialog_get_code:
442 * @dialog: The #HildonCodeDialog from which to get the entered code
444 * Use this function to access the code entered by the user.
446 * Return value: The entered code.
448 const gchar *hildon_code_dialog_get_code (HildonCodeDialog *dialog)
450 g_return_val_if_fail (HILDON_IS_CODE_DIALOG (dialog), NULL);
451 return gtk_entry_get_text (GTK_ENTRY (dialog->priv->entry));
455 * hildon_code_dialog_clear_clode:
456 * @dialog: The #HildonCodeDialog whose entry should be cleared:
458 * Use this function to clear the user entered code.
460 void hildon_code_dialog_clear_code (HildonCodeDialog *dialog)
462 g_return_if_fail (HILDON_IS_CODE_DIALOG (dialog));
463 gtk_entry_set_text (GTK_ENTRY (dialog->priv->entry), "");
464 gtk_widget_set_sensitive (dialog->priv->buttons[4][0], FALSE);
468 * hildon_code_dialog_set_help_text:
469 * @dialog: The #HildonCodeDialog whose entry should be cleared:
470 * @text: The text to use in the help label.
472 * Use this function to set the text that will be displayd in the
475 void hildon_code_dialog_set_help_text (HildonCodeDialog *dialog,
478 g_return_if_fail (HILDON_IS_CODE_DIALOG (dialog));
479 gtk_label_set_text (GTK_LABEL (dialog->priv->help_text), text);