*
* Copyright (C) 2006 Nokia Corporation, all rights reserved.
*
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ * Contact: Rodrigo Novo <rodrigo.novo@nokia.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; version 2.1 of
- * the License.
+ * the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* @short_description: A keypad-like widget used to enter pincodes.
*
* #HildonCodeDialog displays a keypad that can be used to enter
- * numerical pin codes or lock codes.
+ * numerical pin codes or lock codes. It emits a 'input' signal each time
+ * an input action is performed on the dialog.
*
*/
/* FIXME We need property access in this widget */
+#undef HILDON_DISABLE_DEPRECATED
+
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
+#include <libintl.h>
+#include <gdk/gdkkeysyms.h>
+
#include "hildon-code-dialog.h"
#include "hildon-defines.h"
#include "hildon-banner.h"
-
-#include <gdk/gdkkeysyms.h>
-#include <gtk/gtkbutton.h>
-#include <gtk/gtkentry.h>
-#include <gtk/gtkicontheme.h>
-#include <gtk/gtktable.h>
-#include <gtk/gtkvbox.h>
-#include <gtk/gtkbbox.h>
-#include <gtk/gtklabel.h>
-#include <gtk/gtkalignment.h>
-#include <libintl.h>
#include "hildon-code-dialog-private.h"
-#define HEIGHT (38-HILDON_MARGIN_DEFAULT)
+#define HEIGHT (48-HILDON_MARGIN_DEFAULT)
-#define WIDTH (60-HILDON_MARGIN_DEFAULT)
+#define WIDTH (100-HILDON_MARGIN_DEFAULT)
-#define BACKSPACE_ICON "qgn_calculator_backspace"
+#define BACKSPACE_ICON "general_backspace"
#define _(String) \
dgettext("hildon-libs", String)
#define c_(String) \
dgettext("hildon-common-strings", String)
-#define DEVICELOCK_OK _("secu_enter_lock_code_dialog_ok")
-
-#define DEVICELOCK_CANCEL _("secu_enter_lock_code_dialog_cancel")
+#define DEVICELOCK_OK _("wdgt_bd_done")
#define DEVICELOCK_TITLE _("secu_application_title")
static void
hildon_code_dialog_init (HildonCodeDialog *self);
+static void
+hildon_code_dialog_realize (GtkWidget *widget);
+
+static void
+hildon_code_dialog_unrealize (GtkWidget *widget);
+
+static void
+hildon_code_dialog_finalize (GObject *object);
+
static void
hildon_code_dialog_button_clicked (GtkButton *buttonm,
gpointer user_data);
+static void
+hildon_code_dialog_backspace (HildonCodeDialog *dialog);
+
+static void
+hildon_code_dialog_im_commit (GtkIMContext *im_context,
+ gchar *utf8,
+ gpointer user_data);
+
static void
hildon_code_dialog_insert_text (GtkEditable *editable,
gchar *new_text,
GdkEventKey *event,
gpointer user_data);
+static void
+hildon_code_dialog_real_input (HildonCodeDialog *dialog);
+
+static void
+hildon_code_dialog_input (HildonCodeDialog *dialog);
+
static GtkDialogClass* parent_class = NULL;
+static guint input_signal;
+
/**
* hildon_code_dialog_get_type:
*
* Initializes and returns the type of a hildon code dialog.
*
- * @Returns: GType of #HildonCodeDialog
+ * Returns: GType of #HildonCodeDialog
*/
GType G_GNUC_CONST
hildon_code_dialog_get_type (void)
static void
hildon_code_dialog_class_init (HildonCodeDialogClass *cd_class)
{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (cd_class);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (cd_class);
+
parent_class = GTK_DIALOG_CLASS (g_type_class_peek_parent (cd_class));
g_type_class_add_private (cd_class, sizeof (HildonCodeDialogPrivate));
+
+ gobject_class->finalize = hildon_code_dialog_finalize;
+
+ widget_class->realize = hildon_code_dialog_realize;
+ widget_class->unrealize = hildon_code_dialog_unrealize;
+
+ cd_class->input = hildon_code_dialog_real_input;
+
+ /* FIXME Document this signal! */
+ input_signal = g_signal_new("input",
+ HILDON_TYPE_CODE_DIALOG,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (HildonCodeDialogClass, input),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
}
static void
GtkWidget *dialog_action_area1 = NULL;
GdkGeometry hints;
GtkWidget *okButton;
- GtkWidget *cancelButton;
priv = HILDON_CODE_DIALOG_GET_PRIVATE (dialog);
g_assert (priv);
gtk_window_set_title (GTK_WINDOW (dialog), DEVICELOCK_TITLE);
gtk_window_set_type_hint (GTK_WINDOW (dialog), GDK_WINDOW_TYPE_HINT_DIALOG);
+ gtk_dialog_set_has_separator ((GtkDialog *) dialog, FALSE);
hints.min_width = -1;
hints.min_height = -1;
gtk_container_add (GTK_CONTAINER (priv->buttons[3][2]), image1);
dialog_action_area1 = GTK_DIALOG (dialog)->action_area;
gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area1),
- GTK_BUTTONBOX_END);
+#if GTK_CHECK_VERSION(2,11,0) || defined(MAEMO_GTK)
+ GTK_BUTTONBOX_CENTER);
+#else
+ GTK_BUTTONBOX_DEFAULT_STYLE);
+#endif
okButton = gtk_dialog_add_button (GTK_DIALOG (dialog) ,DEVICELOCK_OK,
GTK_RESPONSE_OK);
- cancelButton =
- gtk_dialog_add_button (GTK_DIALOG (dialog), DEVICELOCK_CANCEL,
- GTK_RESPONSE_CANCEL);
-
+
gtk_widget_set_sensitive (okButton, FALSE);
priv->buttons[4][0] = priv->buttons[4][1] = okButton;
- priv->buttons[4][2] = cancelButton;
+
+ priv->im_context = gtk_im_multicontext_new();
+#ifdef MAEMO_GTK
+ g_object_set (G_OBJECT (priv->im_context), "hildon-input-mode",
+ HILDON_GTK_INPUT_MODE_NUMERIC, NULL);
+#endif
/*
Connect signals.
*/
+ g_signal_connect (G_OBJECT (priv->im_context), "commit",
+ G_CALLBACK (hildon_code_dialog_im_commit), dialog);
+
g_signal_connect (G_OBJECT (priv->entry), "insert_text",
G_CALLBACK (hildon_code_dialog_insert_text), dialog);
g_signal_connect (G_OBJECT (okButton), "key-press-event",
G_CALLBACK(hildon_code_dialog_key_press_event), dialog);
- g_signal_connect (G_OBJECT (cancelButton), "key-press-event",
- G_CALLBACK (hildon_code_dialog_key_press_event), dialog);
-
gtk_widget_show_all (GTK_WIDGET (GTK_DIALOG (dialog)->vbox));
}
+static void
+hildon_code_dialog_realize (GtkWidget *widget)
+{
+ HildonCodeDialog *dialog = HILDON_CODE_DIALOG (widget);
+ HildonCodeDialogPrivate *priv = HILDON_CODE_DIALOG_GET_PRIVATE (dialog);
+
+ if (GTK_WIDGET_CLASS (parent_class)->realize)
+ (* GTK_WIDGET_CLASS (parent_class)->realize) (widget);
+
+ gtk_im_context_set_client_window (GTK_IM_CONTEXT (priv->im_context),
+ GTK_WIDGET (dialog)->window);
+ gtk_im_context_focus_in (priv->im_context);
+}
+
+static void
+hildon_code_dialog_unrealize (GtkWidget *widget)
+{
+ HildonCodeDialog *dialog = HILDON_CODE_DIALOG (widget);
+ HildonCodeDialogPrivate *priv = HILDON_CODE_DIALOG_GET_PRIVATE (dialog);
+
+ gtk_im_context_set_client_window (GTK_IM_CONTEXT (priv->im_context), NULL);
+
+ if (GTK_WIDGET_CLASS (parent_class)->unrealize)
+ (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
+}
+
+static void
+hildon_code_dialog_finalize (GObject *object)
+{
+ HildonCodeDialog *dialog = HILDON_CODE_DIALOG (object);
+ HildonCodeDialogPrivate *priv = HILDON_CODE_DIALOG_GET_PRIVATE (dialog);
+
+ g_object_unref (priv->im_context);
+
+ G_OBJECT_CLASS(parent_class)->finalize(object);
+}
+
+static void
+hildon_code_dialog_backspace (HildonCodeDialog *dialog)
+{
+ HildonCodeDialogPrivate *priv = HILDON_CODE_DIALOG_GET_PRIVATE (dialog);
+ gchar *text, *pos;
+
+ g_assert (priv);
+
+ text = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->entry)));
+
+ pos = text;
+
+ while (*pos != '\0')
+ {
+ pos ++;
+ }
+
+ pos = g_utf8_find_prev_char (text, pos);
+
+ if (pos)
+ {
+ *pos=0;
+ }
+
+ gtk_entry_set_text (GTK_ENTRY (priv->entry), text);
+
+ if (*text == 0)
+ {
+ gtk_widget_set_sensitive (priv->buttons[4][0], FALSE);
+ }
+
+ gtk_editable_set_position (GTK_EDITABLE (priv->entry), -1);
+
+ g_free (text);
+}
+
static void
hildon_code_dialog_button_clicked (GtkButton *button,
gpointer user_data)
if (number && *number )
{
- gtk_entry_append_text (GTK_ENTRY (priv->entry), number);
+ gtk_editable_set_editable (GTK_EDITABLE (priv->entry), TRUE);
+
+ g_signal_emit_by_name (GTK_ENTRY (priv->entry)->im_context, "commit",
+ number);
+
+ gtk_editable_set_editable (GTK_EDITABLE (priv->entry), FALSE);
+
+ gtk_editable_set_position (GTK_EDITABLE (priv->entry), -1);
}
else
{
- /* Backspace */
- gchar *text = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->entry)));
- gchar *pos;
-
- pos = text;
+ hildon_code_dialog_backspace (dialog);
+ }
+}
- while (*pos != '\0')
- {
- pos ++;
- }
+static void
+hildon_code_dialog_im_commit (GtkIMContext *im_context,
+ gchar *utf8,
+ gpointer user_data)
+{
+ HildonCodeDialog *dialog = HILDON_CODE_DIALOG (user_data);
+ HildonCodeDialogPrivate *priv = HILDON_CODE_DIALOG_GET_PRIVATE (dialog);
+ gint digit;
- pos = g_utf8_find_prev_char (text, pos);
+ g_assert (priv);
- if (pos)
- {
- *pos=0;
- }
+ digit = g_ascii_strtod(utf8, NULL);
- gtk_entry_set_text (GTK_ENTRY (priv->entry), text);
+ if (g_ascii_isdigit(*utf8))
+ {
+ gtk_editable_set_editable (GTK_EDITABLE (priv->entry), TRUE);
- if (*text == 0)
- {
- gtk_widget_set_sensitive (priv->buttons[4][0], FALSE);
- }
+ g_signal_emit_by_name (GTK_ENTRY (priv->entry)->im_context, "commit",
+ utf8);
- g_free (text);
+ gtk_editable_set_editable (GTK_EDITABLE (priv->entry), FALSE);
+
+ gtk_editable_set_position (GTK_EDITABLE (priv->entry), -1);
}
}
/* make the Ok button sensitive */
gtk_widget_set_sensitive (priv->buttons[4][0], TRUE);
}
+
+ hildon_code_dialog_input (dialog);
}
static gboolean
g_assert (priv);
+ if (gtk_im_context_filter_keypress (priv->im_context, event))
+ return TRUE;
+
+ if (event->keyval == GDK_BackSpace)
+ {
+ hildon_code_dialog_backspace (dialog);
+ return TRUE;
+ }
+
for (x = 0; x < 5; x++)
{
for (y = 0; y < 3; y++)
gtk_label_set_text (GTK_LABEL (priv->help_text), text);
}
+
+static void
+hildon_code_dialog_real_input (HildonCodeDialog *dialog)
+{
+}
+
+static void
+hildon_code_dialog_input (HildonCodeDialog *dialog)
+{
+ /* Emit the signal */
+ g_signal_emit (dialog, input_signal, 0);
+}
+
+/**
+ * hildon_code_dialog_set_input_sensitive
+ * @dialog: The #HildonCodeDialog whose state is to be changed
+ * @sensitive: The new state
+ *
+ * This function will block or enable the input on the code dialog by
+ * making the input button sensitive (or not).
+ **/
+void
+hildon_code_dialog_set_input_sensitive (HildonCodeDialog *dialog,
+ gboolean sensitive)
+{
+ int i;
+ int k;
+
+ g_return_if_fail (HILDON_IS_CODE_DIALOG (dialog));
+
+ HildonCodeDialogPrivate *priv = HILDON_CODE_DIALOG_GET_PRIVATE (dialog);
+ g_assert (priv);
+
+ for (i = 0; i < 5; i++)
+ for (k = 0; k < 3; k++)
+ if (i != 4 && (k != 0 || k != 2))
+ gtk_widget_set_sensitive (priv->buttons [i][k], sensitive);
+
+ gtk_widget_set_sensitive (priv->help_text, sensitive);
+ gtk_widget_set_sensitive (priv->entry, sensitive);
+}