store separators as gunichar array. Use the default separator in case that

2007-08-10  Sven Neumann  <sven@gimp.org>

	* libgimpwidgets/gimpnumberpairentry.c: store separators as
	gunichar array. Use the default separator in case that no
	separator is set. Rewritten gimp_number_pair_entry_parse_text()
	to handle non-ASCII separators.

svn path=/trunk/; revision=23195
This commit is contained in:
Sven Neumann
2007-08-10 16:54:05 +00:00
committed by Sven Neumann
parent fd5363cd87
commit c25f3e445b
2 changed files with 114 additions and 92 deletions

View File

@ -1,3 +1,10 @@
2007-08-10 Sven Neumann <sven@gimp.org>
* libgimpwidgets/gimpnumberpairentry.c: store separators as
gunichar array. Use the default separator in case that no
separator is set. Rewritten gimp_number_pair_entry_parse_text()
to handle non-ASCII separators.
2007-08-10 Martin Nordholts <martinn@svn.gnome.org> 2007-08-10 Martin Nordholts <martinn@svn.gnome.org>
* app/tools/gimpcroptool.c (gimp_crop_tool_button_release): Set * app/tools/gimpcroptool.c (gimp_crop_tool_button_release): Set
@ -11,7 +18,7 @@
* app/widgets/gimppropwidgets.c * app/widgets/gimppropwidgets.c
(gimp_prop_number_pair_entry_config_notify): Fixed bug where (gimp_prop_number_pair_entry_config_notify): Fixed bug where
property notifications were checked againts hardcoded property property notifications were checked against hardcoded property
names instead of the ones configured to the names instead of the ones configured to the
GimpPropNumberPairEntryData object. GimpPropNumberPairEntryData object.

View File

@ -24,6 +24,7 @@
#include "config.h" #include "config.h"
#include <stdlib.h>
#include <string.h> #include <string.h>
#include <gtk/gtk.h> #include <gtk/gtk.h>
@ -89,7 +90,8 @@ typedef struct
* widget is used for aspect ratio, valid separators are typically * widget is used for aspect ratio, valid separators are typically
* ':' and '/'. * ':' and '/'.
*/ */
gchar *separators; gunichar *separators;
glong num_separators;
/* Whether or to not to divide the numbers with the greatest common /* Whether or to not to divide the numbers with the greatest common
* divisor when input ends in '='. * divisor when input ends in '='.
@ -107,9 +109,8 @@ typedef struct
static void gimp_number_pair_entry_finalize (GObject *entry); static void gimp_number_pair_entry_finalize (GObject *entry);
static gint gimp_number_pair_entry_valid_separator (GimpNumberPairEntry *entry, static gboolean gimp_number_pair_entry_valid_separator (GimpNumberPairEntry *entry,
gchar canditate); gunichar canditate);
static void gimp_number_pair_entry_ratio_to_fraction (gdouble ratio, static void gimp_number_pair_entry_ratio_to_fraction (gdouble ratio,
gdouble *numerator, gdouble *numerator,
gdouble *denominator); gdouble *denominator);
@ -148,7 +149,9 @@ G_DEFINE_TYPE (GimpNumberPairEntry, gimp_number_pair_entry, GTK_TYPE_ENTRY)
#define parent_class gimp_number_pair_entry_parent_class #define parent_class gimp_number_pair_entry_parent_class
/* What the user shall end the input with when simplification is desired. */ /* What the user shall end the input with when simplification is desired. */
#define SIMPLIFICATION_CHAR '=' #define SIMPLIFICATION_CHAR ((gunichar) '=')
#define DEFAULT_SEPARATOR ((gunichar) ',')
static guint entry_signals[LAST_SIGNAL] = { 0 }; static guint entry_signals[LAST_SIGNAL] = { 0 };
@ -220,7 +223,7 @@ gimp_number_pair_entry_class_init (GimpNumberPairEntryClass *klass)
g_param_spec_string ("separators", g_param_spec_string ("separators",
"Separators", "Separators",
"A string of valid separators", "A string of valid separators",
",", NULL,
GIMP_PARAM_READWRITE | GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY)); G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (object_class, PROP_ALLOW_SIMPLIFICATION, g_object_class_install_property (object_class, PROP_ALLOW_SIMPLIFICATION,
@ -273,7 +276,8 @@ gimp_number_pair_entry_init (GimpNumberPairEntry *entry)
priv->default_left_number = 1.0; priv->default_left_number = 1.0;
priv->default_right_number = 1.0; priv->default_right_number = 1.0;
priv->user_override = FALSE; priv->user_override = FALSE;
priv->separators = g_strdup_printf (","); priv->separators = NULL;
priv->num_separators = 0;
priv->allow_simplification = FALSE; priv->allow_simplification = FALSE;
priv->min_valid_value = G_MINDOUBLE; priv->min_valid_value = G_MINDOUBLE;
priv->max_valid_value = G_MAXDOUBLE; priv->max_valid_value = G_MAXDOUBLE;
@ -299,6 +303,7 @@ gimp_number_pair_entry_finalize (GObject *object)
{ {
g_free (priv->separators); g_free (priv->separators);
priv->separators = NULL; priv->separators = NULL;
priv->num_separators = 0;
} }
G_OBJECT_CLASS (parent_class)->finalize (object); G_OBJECT_CLASS (parent_class)->finalize (object);
@ -797,11 +802,17 @@ gimp_number_pair_entry_strdup_number_pair_string (GimpNumberPairEntry *entry,
gdouble right_number) gdouble right_number)
{ {
GimpNumberPairEntryPrivate *priv = GIMP_NUMBER_PAIR_ENTRY_GET_PRIVATE (entry); GimpNumberPairEntryPrivate *priv = GIMP_NUMBER_PAIR_ENTRY_GET_PRIVATE (entry);
gchar sep[8];
gint len;
return g_strdup_printf ("%g%c%g", if (priv->num_separators > 0)
left_number, len = g_unichar_to_utf8 (priv->separators[0], sep);
priv->separators[0], else
right_number); len = g_unichar_to_utf8 (DEFAULT_SEPARATOR, sep);
sep[len] = '\0';
return g_strdup_printf ("%g%s%g", left_number, sep, right_number);
} }
static void static void
@ -818,16 +829,24 @@ gimp_number_pair_entry_update_text (GimpNumberPairEntry *entry)
g_free (buffer); g_free (buffer);
} }
static gint static gboolean
gimp_number_pair_entry_valid_separator (GimpNumberPairEntry *entry, gimp_number_pair_entry_valid_separator (GimpNumberPairEntry *entry,
gchar candidate) gunichar candidate)
{ {
GimpNumberPairEntryPrivate *priv = GIMP_NUMBER_PAIR_ENTRY_GET_PRIVATE (entry); GimpNumberPairEntryPrivate *priv = GIMP_NUMBER_PAIR_ENTRY_GET_PRIVATE (entry);
const gchar *c;
for (c = priv->separators; *c; c++) if (priv->num_separators > 0)
if (*c == candidate) {
gint i;
for (i = 0; i < priv->num_separators; i++)
if (priv->separators[i] == candidate)
return TRUE; return TRUE;
}
else if (candidate == DEFAULT_SEPARATOR)
{
return TRUE;
}
return FALSE; return FALSE;
} }
@ -842,85 +861,73 @@ gimp_number_pair_entry_parse_text (GimpNumberPairEntry *entry,
gdouble new_left_number; gdouble new_left_number;
gdouble new_right_number; gdouble new_right_number;
gboolean simplify = FALSE;
gchar *end;
gchar separator; /* try to parse a number */
gchar simplification_char; new_left_number = strtod (text, &end);
gchar dummy;
gint parsed_count; if (end == text)
ParseResult parse_result; return PARSE_CLEAR;
else
text = end;
parse_result = PARSE_INVALID; /* skip over whitespace */
while (g_unichar_isspace (g_utf8_get_char (text)))
text = g_utf8_next_char (text);
parsed_count = sscanf (text, /* check for a valid separator */
" %lf %c %lf %c %c ", if (! gimp_number_pair_entry_valid_separator (entry, g_utf8_get_char (text)))
&new_left_number, return PARSE_INVALID;
&separator, else
&new_right_number, text = g_utf8_next_char (text);
&simplification_char,
&dummy);
/* try to parse another number */
new_right_number = strtod (text, &end);
/* Analyze parsed data */ if (end == text)
return PARSE_INVALID;
else
text = end;
switch (parsed_count) /* skip over whitespace */
while (g_unichar_isspace (g_utf8_get_char (text)))
text = g_utf8_next_char (text);
/* check for the simplification char */
if (g_utf8_get_char (text) == SIMPLIFICATION_CHAR)
{ {
case EOF: simplify = priv->allow_simplification;
case 0: text = g_utf8_next_char (text);
/* Unambigous user clear */
parse_result = PARSE_CLEAR;
break;
case 3:
/* Valid user entry, enter user-override mode */
if (gimp_number_pair_entry_valid_separator (entry, separator) &&
gimp_number_pair_entry_numbers_in_range (entry,
new_left_number,
new_right_number))
{
parse_result = PARSE_VALID;
*left_value = new_left_number;
*right_value = new_right_number;
} }
break; /* skip over whitespace */
while (g_unichar_isspace (g_utf8_get_char (text)))
text = g_utf8_next_char (text);
/* check for trailing garbage */
if (*text)
return PARSE_INVALID;
case 4: if (! gimp_number_pair_entry_numbers_in_range (entry,
if (priv->allow_simplification &&
gimp_number_pair_entry_valid_separator (entry, separator) &&
simplification_char == SIMPLIFICATION_CHAR &&
new_right_number != 0.0 &&
gimp_number_pair_entry_numbers_in_range (entry,
new_left_number, new_left_number,
new_right_number)) new_right_number))
{ return PARSE_INVALID;
parse_result = PARSE_VALID;
if (simplify && new_right_number != 0.0)
{
gimp_number_pair_entry_ratio_to_fraction (new_left_number / gimp_number_pair_entry_ratio_to_fraction (new_left_number /
new_right_number, new_right_number,
left_value, left_value,
right_value); right_value);
} }
else
break; {
*left_value = new_left_number;
case 1: *right_value = new_right_number;
case 2:
case 5:
default:
/* Ambigous user input */
parse_result = PARSE_INVALID;
break;
} }
return parse_result; return PARSE_VALID;
} }
static void static void
@ -962,10 +969,15 @@ gimp_number_pair_entry_set_property (GObject *object,
break; break;
case PROP_SEPARATORS: case PROP_SEPARATORS:
g_free (priv->separators); g_free (priv->separators);
priv->separators = g_value_dup_string (value); priv->num_separators = 0;
if (g_value_get_string (value))
priv->separators = g_utf8_to_ucs4 (g_value_get_string (value), -1,
NULL, &priv->num_separators, NULL);
else
priv->separators = NULL;
break; break;
case PROP_ALLOW_SIMPLIFICATION: case PROP_ALLOW_SIMPLIFICATION:
priv->user_override = g_value_get_boolean (value); priv->allow_simplification = g_value_get_boolean (value);
break; break;
case PROP_MIN_VALID_VALUE: case PROP_MIN_VALID_VALUE:
priv->min_valid_value = g_value_get_double (value); priv->min_valid_value = g_value_get_double (value);
@ -1014,7 +1026,10 @@ gimp_number_pair_entry_get_property (GObject *object,
g_value_set_boolean (value, priv->user_override); g_value_set_boolean (value, priv->user_override);
break; break;
case PROP_SEPARATORS: case PROP_SEPARATORS:
g_value_set_string (value, priv->separators); g_value_take_string (value,
g_ucs4_to_utf8 (priv->separators,
priv->num_separators,
NULL, NULL, NULL));
break; break;
case PROP_ALLOW_SIMPLIFICATION: case PROP_ALLOW_SIMPLIFICATION:
g_value_set_boolean (value, priv->allow_simplification); g_value_set_boolean (value, priv->allow_simplification);