[gnumeric] Metadata: don't use GValue transform functions.
- From: Morten Welinder <mortenw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnumeric] Metadata: don't use GValue transform functions.
- Date: Wed, 15 Jul 2020 22:35:07 +0000 (UTC)
commit 98f30ca96786c6b62d6a3aae09daadc0e81c9eb7
Author: Morten Welinder <terra gnome org>
Date: Wed Jul 15 18:34:10 2020 -0400
Metadata: don't use GValue transform functions.
They are global and interfere with graph saving. Not at all good!
See #510.
NEWS | 1 +
src/dialogs/ChangeLog | 11 ++
src/dialogs/dialog-doc-metadata.c | 243 +++++++++++++-------------------------
3 files changed, 97 insertions(+), 158 deletions(-)
---
diff --git a/NEWS b/NEWS
index 937dcce03..6e98d62ee 100644
--- a/NEWS
+++ b/NEWS
@@ -30,6 +30,7 @@ Morten:
* Fix global name parsing problem with non-uniform sheet sizing.
* Avoid style dependency redraw during file load.
* Tend to dead kittens.
+ * Fix metadata dialog. [#510]
--------------------------------------------------------------------------
Gnumeric 1.12.47
diff --git a/src/dialogs/ChangeLog b/src/dialogs/ChangeLog
index e2bd5b7c2..69ea9285f 100644
--- a/src/dialogs/ChangeLog
+++ b/src/dialogs/ChangeLog
@@ -1,3 +1,14 @@
+2020-07-15 Morten Welinder <terra gnome org>
+
+ * dialog-doc-metadata.c
+ (dialog_doc_metadata_init_properties_page): Fix 64-bit crash.
+ (dialog_doc_metadata_init): Don't register GValue transformations
+ -- they are global and interfere with graph saving, see #510.
+ (dialog_doc_metadata_get_prop_val): Handle GValue-to-string here.
+ Plug leak.
+ (dialog_doc_metadata_set_gsf_prop_val): Handle string-to-GValue
+ here.
+
2020-07-03 Morten Welinder <terra gnome org>
* dialog-cell-format.c (fmt_dialog_impl): When we have
diff --git a/src/dialogs/dialog-doc-metadata.c b/src/dialogs/dialog-doc-metadata.c
index 7c96459c3..7f94fecab 100644
--- a/src/dialogs/dialog-doc-metadata.c
+++ b/src/dialogs/dialog-doc-metadata.c
@@ -260,19 +260,17 @@ dialog_doc_metadata_get_value_type (GValue *value)
default:
/* Check if it is a GsfDocPropVector or GsfTimeStamp */
- {
- if (VAL_IS_GSF_TIMESTAMP (value))
- val_type = GSF_TIMESTAMP_TYPE;
- else if (VAL_IS_GSF_DOCPROP_VECTOR (value))
- val_type = GSF_DOCPROP_VECTOR_TYPE;
- else {
- g_printerr ("GType %s (%i) not handled in metadata dialog.\n",
- g_type_name (val_type), (int) val_type);
- val_type = G_TYPE_INVALID;
- }
-
- break;
+ if (VAL_IS_GSF_TIMESTAMP (value))
+ val_type = GSF_TIMESTAMP_TYPE;
+ else if (VAL_IS_GSF_DOCPROP_VECTOR (value))
+ val_type = GSF_DOCPROP_VECTOR_TYPE;
+ else {
+ g_printerr ("GType %s (%i) not handled in metadata dialog.\n",
+ g_type_name (val_type), (int) val_type);
+ val_type = G_TYPE_INVALID;
}
+
+ break;
}
return val_type;
}
@@ -287,22 +285,19 @@ dialog_doc_metadata_get_value_type (GValue *value)
*/
static void
-dialog_doc_metadata_transform_str_to_timestamp (const GValue *string_value,
+dialog_doc_metadata_transform_str_to_timestamp (const char *str,
GValue *timestamp_value)
{
time_t s;
gnm_float serial;
gint int_serial;
GsfTimestamp *gt;
- gchar const *str;
GnmValue *conversion;
GOFormat *fmt;
- g_return_if_fail (G_VALUE_HOLDS_STRING (string_value));
g_return_if_fail (VAL_IS_GSF_TIMESTAMP (timestamp_value));
fmt = go_format_new_from_XL ("yyyy-mm-dd hh:mm:ss");
- str = g_value_get_string (string_value);
conversion = format_match_number (str, fmt, NULL);
go_format_unref (fmt);
if (conversion) {
@@ -327,64 +322,16 @@ dialog_doc_metadata_transform_str_to_timestamp (const GValue *string_value,
}
static void
-dialog_doc_metadata_transform_str_to_float (const GValue *string_value,
- GValue *float_value)
-{
- gnm_float x;
- gchar const *str;
- GnmValue *conversion;
-
- g_return_if_fail (G_VALUE_HOLDS_STRING (string_value));
- g_return_if_fail (G_VALUE_HOLDS_FLOAT (float_value));
-
- str = g_value_get_string (string_value);
- conversion = format_match_number (str, NULL, NULL);
- if (conversion) {
- x = value_get_as_float (conversion);
- value_release (conversion);
- } else
- x = 0.;
-
- g_value_set_float (float_value, x);
-}
-
-static void
-dialog_doc_metadata_transform_str_to_boolean (const GValue *string_value,
- GValue *b_value)
-{
- gboolean x, err;
- gchar const *str;
- GnmValue *conversion;
-
- g_return_if_fail (G_VALUE_HOLDS_STRING (string_value));
- g_return_if_fail (G_VALUE_HOLDS_BOOLEAN (b_value));
-
- str = g_value_get_string (string_value);
- conversion = format_match_number (str, NULL, NULL);
- if (conversion) {
- x = value_get_as_bool (conversion, &err);
- value_release (conversion);
- if (err)
- x = FALSE;
- } else
- x = FALSE;
-
- g_value_set_boolean (b_value, x);
-}
-
-static void
-dialog_doc_metadata_transform_str_to_docprop_vect (const GValue *string_value,
- GValue *docprop_value)
+dialog_doc_metadata_transform_str_to_docprop_vect (const char *str,
+ GValue *docprop_value)
{
- char const *str, *s;
+ char const *s;
GsfDocPropVector *gdpv;
GValue *value;
- g_return_if_fail (G_VALUE_HOLDS_STRING (string_value));
g_return_if_fail (VAL_IS_GSF_DOCPROP_VECTOR (docprop_value));
gdpv = gsf_docprop_vector_new ();
- str = g_value_get_string (string_value);
while (*str == ' ') {str++;}
@@ -473,38 +420,6 @@ dialog_doc_metadata_transform_timestamp_to_str (const GValue *timestamp_value,
time2str_go (timestamp->timet));
}
-static void
-dialog_doc_metadata_transform_float_to_str (const GValue *float_value,
- GValue *string_value)
-{
- gnm_float x;
- char *str;
- GOFormat *fmt;
-
- g_return_if_fail (G_VALUE_HOLDS_FLOAT (float_value));
- g_return_if_fail (G_VALUE_HOLDS_STRING (string_value));
-
- x = g_value_get_float (float_value);
-
- fmt = go_format_general ();
- str = go_format_value (fmt, x);
- g_value_take_string (string_value, str);
-}
-
-static void
-dialog_doc_metadata_transform_boolean_to_str (const GValue *b_value,
- GValue *string_value)
-{
- gboolean x;
-
- g_return_if_fail (G_VALUE_HOLDS_BOOLEAN (b_value));
- g_return_if_fail (G_VALUE_HOLDS_STRING (string_value));
-
- x = g_value_get_boolean (b_value);
-
- g_value_set_static_string (string_value, x ? _("TRUE") : _("FALSE"));
-}
-
static gchar*
gnm_docprop_vector_as_string (GsfDocPropVector *vector)
{
@@ -828,16 +743,11 @@ dialog_doc_metadata_set_gsf_prop_val (DialogDocMetaData *state,
/* such as from string to double, so we do that ourselves */
switch (t) {
case G_TYPE_STRING:
- g_value_set_string (prop_value, g_strdup (str_val));
- break;
+ g_value_set_string (prop_value, str_val);
+ return;
case G_TYPE_DOUBLE:
case G_TYPE_FLOAT: {
- GnmParsePos pos;
- GnmValue *val = NULL;
- GnmExprTop const *texpr = NULL;
- parse_pos_init_sheet (&pos, workbook_sheet_by_index (state->wb, 0));
- parse_text_value_or_expr (&pos, str_val,
- &val, &texpr);
+ GnmValue *val = format_match_number (str_val, NULL, workbook_date_conv (state->wb));
if (val != NULL) {
gnm_float fl = value_get_as_float (val);
value_release (val);
@@ -846,21 +756,34 @@ dialog_doc_metadata_set_gsf_prop_val (DialogDocMetaData *state,
else
g_value_set_float (prop_value, fl);
}
- if (texpr)
- gnm_expr_top_unref (texpr);
- break;
+ return;
}
- default:
- if (g_value_type_transformable (t, G_TYPE_STRING)) {
- GValue string_value = G_VALUE_INIT;
- g_value_init (&string_value, G_TYPE_STRING);
- g_value_set_string (&string_value, g_strdup (str_val));
- g_value_transform (&string_value, prop_value);
- g_value_unset (&string_value);
- } else
- g_printerr (_("Transform function of G_TYPE_STRING to %s is required!\n"),
- g_type_name (t));
- break;
+ case G_TYPE_INT:
+ g_value_set_int (prop_value, strtol (str_val, NULL, 10));
+ return;
+ case G_TYPE_UINT:
+ g_value_set_uint (prop_value, strtoul (str_val, NULL, 10));
+ return;
+ case G_TYPE_BOOLEAN: {
+ GnmValue *val = format_match_number (str_val, NULL, workbook_date_conv (state->wb));
+ gboolean b = FALSE;
+ if (val != NULL) {
+ gboolean err;
+ b = value_get_as_bool (val, &err);
+ value_release (val);
+ }
+ g_value_set_boolean (prop_value, b);
+ return;
+ }
+ }
+
+ if (t == GSF_TIMESTAMP_TYPE) {
+ dialog_doc_metadata_transform_str_to_timestamp (str_val, prop_value);
+ } else if (t == GSF_DOCPROP_VECTOR_TYPE) {
+ dialog_doc_metadata_transform_str_to_docprop_vect (str_val, prop_value);
+ } else {
+ g_printerr (_("Transform function of G_TYPE_STRING to %s is required!\n"),
+ g_type_name (t));
}
}
@@ -1645,19 +1568,57 @@ dialog_doc_metadata_get_prop_val (G_GNUC_UNUSED DialogDocMetaData *state,
{
GValue str_value = G_VALUE_INIT;
gboolean ret = FALSE;
+ GType t;
+ char *s;
g_return_val_if_fail (prop_value != NULL, NULL);
g_value_init (&str_value, G_TYPE_STRING);
+ t = G_VALUE_TYPE (prop_value);
+ switch (t) {
+ case G_TYPE_INT:
+ case G_TYPE_UINT:
+ case G_TYPE_STRING:
+ ret = g_value_transform (prop_value, &str_value);
+ break;
+
+ case G_TYPE_BOOLEAN: {
+ gboolean b = g_value_get_boolean (prop_value);
+ g_value_set_string (&str_value, go_locale_boolean_name (b));
+ ret = TRUE;
+ break;
+ }
- ret = g_value_transform (prop_value, &str_value);
+ case G_TYPE_FLOAT:
+ case G_TYPE_DOUBLE: {
+ double d = (t == G_TYPE_FLOAT)
+ ? g_value_get_float (prop_value)
+ : g_value_get_double (prop_value);
+ GString *res = g_string_new (NULL);
+ go_dtoa (res, "!g", d);
+ g_value_set_string (&str_value, res->str);
+ g_string_free (res, TRUE);
+ ret = TRUE;
+ break;
+ }
+ }
+
+ if (t == GSF_TIMESTAMP_TYPE) {
+ dialog_doc_metadata_transform_timestamp_to_str (prop_value, &str_value);
+ ret = TRUE;
+ } else if (t == GSF_DOCPROP_VECTOR_TYPE) {
+ dialog_doc_metadata_transform_docprop_vect_to_str (prop_value, &str_value);
+ ret = TRUE;
+ }
if (ret == FALSE) {
g_warning ("Metadata tag '%s' holds unrecognized value type.", prop_name);
return NULL;
}
- return g_value_dup_string (&str_value);
+ s = g_value_dup_string (&str_value);
+ g_value_unset (&str_value);
+ return s;
}
/**
@@ -1890,7 +1851,7 @@ dialog_doc_metadata_init_properties_page (DialogDocMetaData *state)
G_TYPE_STRING,
G_TYPE_STRING,
G_TYPE_BOOLEAN,
- G_TYPE_INT);
+ G_TYPE_GTYPE);
gtk_tree_view_set_model (state->properties,
GTK_TREE_MODEL (state->properties_store));
@@ -2339,40 +2300,6 @@ dialog_doc_metadata_init (DialogDocMetaData *state,
"changed",
G_CALLBACK (cb_dialog_doc_metadata_selection_changed), state);
-
- /* Register g_value_transform functions */
- g_value_register_transform_func (G_TYPE_STRING,
- GSF_TIMESTAMP_TYPE,
- dialog_doc_metadata_transform_str_to_timestamp);
-
- g_value_register_transform_func (G_TYPE_STRING,
- G_TYPE_FLOAT,
- dialog_doc_metadata_transform_str_to_float);
-
- g_value_register_transform_func (G_TYPE_STRING,
- GSF_DOCPROP_VECTOR_TYPE,
- dialog_doc_metadata_transform_str_to_docprop_vect);
-
- g_value_register_transform_func (G_TYPE_STRING,
- G_TYPE_BOOLEAN,
- dialog_doc_metadata_transform_str_to_boolean);
-
- g_value_register_transform_func (GSF_TIMESTAMP_TYPE,
- G_TYPE_STRING,
- dialog_doc_metadata_transform_timestamp_to_str);
-
- g_value_register_transform_func (GSF_DOCPROP_VECTOR_TYPE,
- G_TYPE_STRING,
- dialog_doc_metadata_transform_docprop_vect_to_str);
-
- g_value_register_transform_func (G_TYPE_FLOAT,
- G_TYPE_STRING,
- dialog_doc_metadata_transform_float_to_str);
-
- g_value_register_transform_func (G_TYPE_BOOLEAN,
- G_TYPE_STRING,
- dialog_doc_metadata_transform_boolean_to_str);
-
for (i = 0; page_info[i].page > -1; i++) {
const page_info_t *this_page = &page_info[i];
this_page->page_initializer (state);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]