X-Git-Url: http://git.maemo.org/git/?a=blobdiff_plain;f=src%2Fhildon2%2Fmodest-number-editor.c;h=2a1dc7390010b2ea29e2ec2f68b12d27bb150cf0;hb=498fadac9d0a9985864ffcfecc153c604cd07fe5;hp=086b636886b50f1798596b58b639a755b2536adc;hpb=13500f228c1f0fb62aed96baae7293851090554f;p=modest diff --git a/src/hildon2/modest-number-editor.c b/src/hildon2/modest-number-editor.c index 086b636..2a1dc73 100644 --- a/src/hildon2/modest-number-editor.c +++ b/src/hildon2/modest-number-editor.c @@ -1,8 +1,31 @@ /* - * This file is a part of modest + * Copyright (C) 2008 Nokia Corporation, all rights reserved. + * All rights reserved. * - * Copyright (C) 2005, 2006, 2008 Nokia Corporation, all rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the Nokia Corporation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** @@ -49,13 +72,14 @@ typedef struct _ModestNumberEditorPrivate Modes struct _ModestNumberEditorPrivate { - gint start; /* Minimum */ - gint end; /* Maximum */ - gint default_val; - - /* Timer IDs */ - guint select_all_idle_id; /* Selection repaint hack - see modest_number_editor_select_all */ + gint start; /* Minimum */ + gint end; /* Maximum */ + gint default_val; + gboolean is_valid; + + /* Timer IDs */ + guint select_all_idle_id; /* Selection repaint hack + see modest_number_editor_select_all */ }; @@ -103,6 +127,7 @@ modest_number_editor_get_property (GObject *object, enum { RANGE_ERROR, + VALID_CHANGED, LAST_SIGNAL }; @@ -184,6 +209,14 @@ modest_number_editor_class_init (ModestNumberEditorClass *editor g_signal_accumulator_true_handled, NULL, modest_marshal_BOOLEAN__ENUM, G_TYPE_BOOLEAN, 1, MODEST_TYPE_NUMBER_EDITOR_ERROR_TYPE); + + ModestNumberEditor_signal[VALID_CHANGED] = + g_signal_new ("valid_changed", MODEST_TYPE_NUMBER_EDITOR, + G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET + (ModestNumberEditorClass, valid_changed), + NULL, NULL, + g_cclosure_marshal_VOID__BOOLEAN, + G_TYPE_NONE, 1, G_TYPE_BOOLEAN); } static void @@ -211,21 +244,7 @@ modest_number_editor_init (ModestNumberEditor *editor) g_assert (priv); priv->select_all_idle_id = 0; - - /* Connect child widget signals */ - g_signal_connect (GTK_OBJECT (editor), "changed", - G_CALLBACK (modest_number_editor_entry_changed), - editor); - - g_signal_connect (GTK_OBJECT (editor), "focus-out-event", - G_CALLBACK (modest_number_editor_entry_focusout), - editor); - - - g_object_set (G_OBJECT (editor), - "hildon-input-mode", HILDON_GTK_INPUT_MODE_NUMERIC, NULL); - - modest_number_editor_set_range (editor, G_MININT, G_MAXINT); + priv->is_valid = TRUE; } /* Format given number to editor field, no checks performed, all signals @@ -260,89 +279,95 @@ static void modest_number_editor_validate_value (ModestNumberEditor *editor, gboolean allow_intermediate) { - ModestNumberEditorPrivate *priv; - gint error_code, fixup_value; - const gchar *text; - long value; - gchar *tail; - gboolean r; - - g_assert (MODEST_IS_NUMBER_EDITOR(editor)); - - priv = MODEST_NUMBER_EDITOR_GET_PRIVATE (editor); - g_assert (priv); - - text = gtk_entry_get_text (GTK_ENTRY (editor)); - error_code = -1; - fixup_value = priv->default_val; - - if (text && text[0]) - { - /* Try to convert entry text to number */ - value = strtol (text, &tail, 10); - - /* Check if conversion succeeded */ - if (tail[0] == 0) - { - /* Check if value is in allowed range. This is tricky in those - cases when user is editing a value. - For example: Range = [100, 500] and user have just inputted "4". - This should not lead into error message. Otherwise value is - resetted back to "100" and next "4" press will reset it back - and so on. */ - if (allow_intermediate) - { - /* We now have the following error cases: - * If inputted value as above maximum and - maximum is either positive or then maximum - negative and value is positive. - * If inputted value is below minimum and minimum - is negative or minumum positive and value - negative or zero. - In all other cases situation can be fixed just by - adding new numbers to the string. - */ - if (value > priv->end && (priv->end >= 0 || (priv->end < 0 && value >= 0))) - { - error_code = MODEST_NUMBER_EDITOR_ERROR_MAXIMUM_VALUE_EXCEED; - fixup_value = priv->end; - } - else if (value < priv->start && (priv->start < 0 || (priv->start >= 0 && value <= 0))) - { - error_code = MODEST_NUMBER_EDITOR_ERROR_MINIMUM_VALUE_EXCEED; - fixup_value = priv->start; - } - } - else - { - if (value > priv->end) { - error_code = MODEST_NUMBER_EDITOR_ERROR_MAXIMUM_VALUE_EXCEED; - fixup_value = priv->end; - } - else if (value < priv->start) { - error_code = MODEST_NUMBER_EDITOR_ERROR_MINIMUM_VALUE_EXCEED; - fixup_value = priv->start; - } - } - } - /* The only valid case when conversion can fail is when we - have plain '-', intermediate forms are allowed AND - minimum bound is negative */ - else if (! allow_intermediate || strcmp (text, "-") != 0 || priv->start >= 0) - error_code = MODEST_NUMBER_EDITOR_ERROR_ERRONEOUS_VALUE; - } - else if (! allow_intermediate) - error_code = MODEST_NUMBER_EDITOR_ERROR_ERRONEOUS_VALUE; - - if (error_code != -1) - { - /* If entry is empty and intermediate forms are nor allowed, - emit error signal */ - /* Change to default value */ - modest_number_editor_set_value (editor, fixup_value); - g_signal_emit (editor, ModestNumberEditor_signal[RANGE_ERROR], 0, error_code, &r); - add_select_all_idle (editor); - } + ModestNumberEditorPrivate *priv; + gint error_code, fixup_value; + const gchar *text; + long value; + gchar *tail; + gboolean r; + gboolean is_valid = TRUE; + + g_assert (MODEST_IS_NUMBER_EDITOR(editor)); + + priv = MODEST_NUMBER_EDITOR_GET_PRIVATE (editor); + g_assert (priv); + + text = gtk_entry_get_text (GTK_ENTRY (editor)); + error_code = -1; + fixup_value = priv->default_val; + + if (text && text[0]) { + /* Try to convert entry text to number */ + value = strtol (text, &tail, 10); + + /* Check if conversion succeeded */ + if (tail[0] == 0) { + /* Check if value is in allowed range. This is tricky in those + cases when user is editing a value. + For example: Range = [100, 500] and user have just inputted "4". + This should not lead into error message. Otherwise value is + resetted back to "100" and next "4" press will reset it back + and so on. */ + + if (allow_intermediate) { + /* We now have the following error cases: + * If inputted value as above maximum and + maximum is either positive or then maximum + negative and value is positive. + * If inputted value is below minimum and minimum + is negative or minumum positive and value + negative or zero. + In all other cases situation can be fixed just by + adding new numbers to the string. + */ + if (value > priv->end && (priv->end >= 0 || (priv->end < 0 && value >= 0))) { + error_code = MODEST_NUMBER_EDITOR_ERROR_MAXIMUM_VALUE_EXCEED; + fixup_value = priv->end; + is_valid = FALSE; + } else if (value < priv->start && (priv->start < 0 || (priv->start >= 0 && value <= 0))) { + error_code = MODEST_NUMBER_EDITOR_ERROR_MINIMUM_VALUE_EXCEED; + fixup_value = priv->start; + is_valid = FALSE; + } + } else { + if (value > priv->end) { + error_code = MODEST_NUMBER_EDITOR_ERROR_MAXIMUM_VALUE_EXCEED; + fixup_value = priv->end; + is_valid = FALSE; + } else if (value < priv->start) { + error_code = MODEST_NUMBER_EDITOR_ERROR_MINIMUM_VALUE_EXCEED; + fixup_value = priv->start; + is_valid = FALSE; + } + } + /* The only valid case when conversion can fail is when we + have plain '-', intermediate forms are allowed AND + minimum bound is negative */ + } else { + is_valid = FALSE; + if (! allow_intermediate || strcmp (text, "-") != 0 || priv->start >= 0) + error_code = MODEST_NUMBER_EDITOR_ERROR_ERRONEOUS_VALUE; + } + } else { + is_valid = FALSE; + if (! allow_intermediate) + error_code = MODEST_NUMBER_EDITOR_ERROR_ERRONEOUS_VALUE; + } + + if (error_code != -1) { + /* If entry is empty and intermediate forms are nor allowed, + emit error signal */ + /* Change to default value */ + modest_number_editor_set_value (editor, fixup_value); + g_signal_emit (editor, ModestNumberEditor_signal[RANGE_ERROR], 0, error_code, &r); + add_select_all_idle (editor); + is_valid = modest_number_editor_is_valid (editor); + } + + if (priv->is_valid != is_valid) { + priv->is_valid = is_valid; + g_signal_emit (editor, ModestNumberEditor_signal[VALID_CHANGED], 0, is_valid); + } } static void @@ -359,10 +384,15 @@ modest_number_editor_entry_focusout (GtkWidget *widget, GdkEventFocus *event, gpointer data) { - g_assert (MODEST_IS_NUMBER_EDITOR(data)); + GtkWidget *window; + + g_assert (MODEST_IS_NUMBER_EDITOR(data)); - modest_number_editor_validate_value (MODEST_NUMBER_EDITOR(data), FALSE); - return FALSE; + window = gtk_widget_get_toplevel (widget); + if (window && gtk_window_has_toplevel_focus (GTK_WINDOW (window))) + modest_number_editor_validate_value (MODEST_NUMBER_EDITOR(data), FALSE); + + return FALSE; } static gboolean @@ -423,6 +453,21 @@ modest_number_editor_new (gint min, { ModestNumberEditor *editor = g_object_new (MODEST_TYPE_NUMBER_EDITOR, NULL); + /* Connect child widget signals */ + g_signal_connect (GTK_OBJECT (editor), "changed", + G_CALLBACK (modest_number_editor_entry_changed), + editor); + + g_signal_connect (GTK_OBJECT (editor), "focus-out-event", + G_CALLBACK (modest_number_editor_entry_focusout), + editor); + + /* Numeric input mode */ + hildon_gtk_entry_set_input_mode (GTK_ENTRY (editor), + HILDON_GTK_INPUT_MODE_NUMERIC); + hildon_gtk_widget_set_theme_size ((GtkWidget *) editor, + HILDON_SIZE_FINGER_HEIGHT); + /* Set user inputted range to editor */ modest_number_editor_set_range (editor, min, max); @@ -467,6 +512,26 @@ modest_number_editor_set_range (ModestNumberEditor *editor, } /** + * modest_number_editor_is_valid: + * @editor: pointer to #ModestNumberEditor + * + * Returns: if @editor contents are valid + */ +gboolean +modest_number_editor_is_valid (ModestNumberEditor *editor) +{ + ModestNumberEditorPrivate *priv; + + g_return_val_if_fail (MODEST_IS_NUMBER_EDITOR (editor), FALSE); + + priv = MODEST_NUMBER_EDITOR_GET_PRIVATE (editor); + g_assert (priv); + + return priv->is_valid; + +} + +/** * modest_number_editor_get_value: * @editor: pointer to #ModestNumberEditor *