[goffice] Make the content of GOData subclasses accessible from GOData.
- From: Emmanuel Pacaud <emmanuel src gnome org>
- To: svn-commits-list gnome org
- Subject: [goffice] Make the content of GOData subclasses accessible from GOData.
- Date: Thu, 23 Apr 2009 11:06:44 -0400 (EDT)
commit 56bc5ca6d5de548616200de1201e4242a1213639
Author: Emmanuel Pacaud <emmanuel pacaud lapp in2p3 fr>
Date: Tue Apr 21 13:54:54 2009 +0200
Make the content of GOData subclasses accessible from GOData.
This allows to create a GOData based class that can handle a data
set with any number of dimensions.
---
goffice/data/go-data-impl.h | 31 ++-
goffice/data/go-data.c | 441 ++++++++++++++++++++++++++++++++++++++++++-
goffice/data/go-data.h | 34 +++-
3 files changed, 480 insertions(+), 26 deletions(-)
diff --git a/goffice/data/go-data-impl.h b/goffice/data/go-data-impl.h
index e202201..bf96ba7 100644
--- a/goffice/data/go-data-impl.h
+++ b/goffice/data/go-data-impl.h
@@ -30,8 +30,7 @@ G_BEGIN_DECLS
typedef enum {
GO_DATA_CACHE_IS_VALID = 1 << 0,
GO_DATA_IS_EDITABLE = 1 << 1,
- GO_DATA_VECTOR_LEN_CACHED = 1 << 2,
- GO_DATA_MATRIX_SIZE_CACHED = GO_DATA_VECTOR_LEN_CACHED
+ GO_DATA_SIZE_CACHED = 1 << 2
} GODataFlags;
struct _GOData {
@@ -41,12 +40,19 @@ struct _GOData {
typedef struct {
GObjectClass base;
- GOData *(*dup) (GOData const *src);
- gboolean (*eq) (GOData const *a, GOData const *b);
- GOFormat *(*preferred_fmt) (GOData const *dat);
- char *(*as_str) (GOData const *dat);
- gboolean (*from_str) (GOData *dat, char const *str);
- void (*emit_changed) (GOData *dat);
+ GOData * (*dup) (GOData const *src);
+ gboolean (*eq) (GOData const *a, GOData const *b);
+ GOFormat * (*preferred_fmt) (GOData const *dat);
+ char * (*as_str) (GOData const *dat);
+ gboolean (*from_str) (GOData *dat, char const *str);
+ void (*emit_changed) (GOData *dat);
+
+ unsigned int (*get_n_sizes) (GOData *data);
+ void (*get_sizes) (GOData *data, unsigned int *sizes);
+ double * (*get_values) (GOData *data);
+ void (*get_bounds) (GOData *data, double *minimum, double *maximum);
+ double (*get_value) (GOData *data, unsigned int *positions);
+ char * (*get_string) (GOData *data, unsigned int *positions);
/* signals */
void (*changed) (GOData *dat);
@@ -54,15 +60,18 @@ typedef struct {
struct _GODataScalar {
GOData base;
+
+ double value;
};
typedef struct {
GODataClass base;
double (*get_value) (GODataScalar *scalar);
char const *(*get_str) (GODataScalar *scalar);
-/* PangoLayout *(get_fmt_str) (GODataScalar *scalar); */
} GODataScalarClass;
+#define GO_DATA_VECTOR_LEN_CACHED GO_DATA_SIZE_CACHED
+
struct _GODataVector {
GOData base;
@@ -77,9 +86,10 @@ typedef struct {
void (*load_values) (GODataVector *vec);
double (*get_value) (GODataVector *vec, unsigned i);
char *(*get_str) (GODataVector *vec, unsigned i);
-/* PangoLayout *(get_fmt_str) (GODataVector *vec, unsigned i); */
} GODataVectorClass;
+#define GO_DATA_MATRIX_SIZE_CACHED GO_DATA_SIZE_CACHED
+
struct _GODataMatrix {
GOData base;
@@ -95,7 +105,6 @@ typedef struct {
void (*load_values) (GODataMatrix *vec);
double (*get_value) (GODataMatrix *mat, unsigned i, unsigned j);
char *(*get_str) (GODataMatrix *mat, unsigned i, unsigned j);
-/* PangoLayout *(get_fmt_str) (GODataMatrix *mat, unsigned i, unsigned j); */
} GODataMatrixClass;
G_END_DECLS
diff --git a/goffice/data/go-data.c b/goffice/data/go-data.c
index 17087c3..83f7c0c 100644
--- a/goffice/data/go-data.c
+++ b/goffice/data/go-data.c
@@ -207,14 +207,347 @@ go_data_emit_changed (GOData *dat)
g_signal_emit (G_OBJECT (dat), go_data_signals [CHANGED], 0);
}
+typedef enum {
+ GO_DATA_VARIATION_CHECK_INCREASING,
+ GO_DATA_VARIATION_CHECK_DECREASING,
+ GO_DATA_VARIATION_CHECK_UNIFORMLY
+} GODataVariationCheck;
+
+static gboolean
+go_data_check_variation (GOData *data, GODataVariationCheck check)
+{
+ double *values;
+ unsigned int n_values;
+
+ g_return_val_if_fail (GO_IS_DATA (data), FALSE);
+
+ values = go_data_get_values (data);
+ if (values == NULL)
+ return FALSE;
+
+ n_values = go_data_get_n_values (data);
+ if (n_values < 1)
+ return FALSE;
+
+ switch (check) {
+ case GO_DATA_VARIATION_CHECK_UNIFORMLY:
+ return go_range_vary_uniformly (values, n_values);
+ case GO_DATA_VARIATION_CHECK_INCREASING:
+ return go_range_increasing (values, n_values);
+ default:
+ return go_range_decreasing (values, n_values);
+ }
+}
+
+gboolean
+go_data_is_increasing (GOData *data)
+{
+ return go_data_check_variation (data, GO_DATA_VARIATION_CHECK_INCREASING);
+}
+
+gboolean
+go_data_is_decreasing (GOData *data)
+{
+ return go_data_check_variation (data, GO_DATA_VARIATION_CHECK_DECREASING);
+}
+
+gboolean
+go_data_is_varying_uniformly (GOData *data)
+{
+ return go_data_check_variation (data, GO_DATA_VARIATION_CHECK_UNIFORMLY);
+}
+
+unsigned int
+go_data_get_n_values (GOData *data)
+{
+ GODataClass const *data_class;
+ unsigned int n_values;
+ unsigned int n_sizes;
+ unsigned int *sizes;
+ unsigned int i;
+
+ g_return_val_if_fail (GO_IS_DATA (data), 0);
+
+ data_class = GO_DATA_GET_CLASS (data);
+ g_return_val_if_fail (data_class->get_n_sizes != NULL, 0);
+
+ n_sizes = data_class->get_n_sizes (data);
+ if (n_sizes < 1)
+ return 1;
+
+ sizes = g_newa (unsigned int, n_sizes);
+
+ g_return_val_if_fail (data_class->get_sizes != NULL, 0);
+
+ data_class->get_sizes (data, sizes);
+
+ n_values = 1;
+ for (i = 0; i < n_sizes; i++)
+ n_values *= sizes[i];
+
+ return n_values;
+}
+
+static void
+go_data_get_sizes (GOData *data, unsigned int n_sizes, unsigned int *sizes)
+{
+ GODataClass const *data_class;
+ unsigned int actual_n_sizes;
+ unsigned int i;
+
+ g_return_if_fail (n_sizes > 0);
+ g_return_if_fail (sizes != NULL);
+
+ data_class = GO_DATA_GET_CLASS (data);
+
+ g_return_if_fail (data_class->get_n_sizes != NULL);
+
+ actual_n_sizes = data_class->get_n_sizes (data);
+ if (actual_n_sizes > n_sizes) {
+ unsigned int *actual_sizes;
+
+ actual_sizes = g_newa (unsigned int, actual_n_sizes);
+ data_class->get_sizes (data, actual_sizes);
+
+ memcpy (sizes, actual_sizes, sizeof (unsigned int) * n_sizes);
+ } else {
+ data_class->get_sizes (data, sizes);
+
+ for (i = actual_n_sizes; i < n_sizes; i++)
+ sizes[i] = 1;
+ }
+}
+
+unsigned int
+go_data_get_vector_size (GOData *data)
+{
+ unsigned int size;
+
+ g_return_val_if_fail (GO_IS_DATA (data), 0);
+
+ go_data_get_sizes (data, 1, &size);
+
+ return size;
+}
+
+void
+go_data_get_matrix_size (GOData *data, unsigned int *n_columns, unsigned int *n_rows)
+{
+ unsigned int sizes[2];
+
+ if (!GO_IS_DATA (data)) {
+ if (n_columns != NULL)
+ *n_columns = 0;
+
+ if (n_rows != NULL)
+ *n_rows = 0;
+
+ g_return_if_fail (GO_IS_DATA (data));
+ }
+
+ go_data_get_sizes (data, 2, sizes);
+
+ if (n_columns != NULL)
+ *n_columns = sizes[0];
+
+ if (n_rows != NULL)
+ *n_rows = sizes[1];
+}
+
+double *
+go_data_get_values (GOData *data)
+{
+ GODataClass const *data_class;
+
+ g_return_val_if_fail (GO_IS_DATA (data), NULL);
+
+ data_class = GO_DATA_GET_CLASS (data);
+
+ g_return_val_if_fail (data_class->get_values != NULL, NULL);
+
+ return data_class->get_values (data);
+}
+
+void
+go_data_get_bounds (GOData *data, double *minimum, double *maximum)
+{
+ GODataClass const *data_class;
+ double dummy;
+
+ g_return_if_fail (GO_IS_DATA (data));
+ g_return_if_fail (minimum != NULL && maximum != NULL);
+
+ if (maximum == NULL)
+ maximum = &dummy;
+ else if (minimum == NULL)
+ minimum = &dummy;
+
+ data_class = GO_DATA_GET_CLASS (data);
+
+ g_return_if_fail (data_class->get_bounds != NULL);
+
+ data_class->get_bounds (data, minimum, maximum);
+}
+
+static double
+go_data_get_value (GOData *data, unsigned int n_positions, unsigned int *positions)
+{
+ GODataClass const *data_class;
+ unsigned int i;
+ unsigned int n_sizes;
+
+ g_return_val_if_fail (GO_IS_DATA (data), go_nan);
+ g_return_val_if_fail (n_positions < 1 || positions != NULL, go_nan);
+
+ data_class = GO_DATA_GET_CLASS (data);
+
+ n_sizes = data_class->get_n_sizes (data);
+
+ if (n_sizes > n_positions) {
+ unsigned int *actual_positions;
+
+ actual_positions = g_newa (unsigned int, n_sizes);
+ memcpy (actual_positions, positions, n_positions * sizeof (unsigned int));
+
+ for (i = n_positions; i < n_sizes; i++)
+ actual_positions[i] = 0;
+
+ return data_class->get_value (data, actual_positions);
+ } else
+ return data_class->get_value (data, positions);
+}
+
+double
+go_data_get_scalar_value (GOData *data)
+{
+ return go_data_get_value (data, 0, NULL);
+}
+
+double
+go_data_get_vector_value (GOData *data, unsigned int column)
+{
+ return go_data_get_value (data, 1, &column);
+}
+
+double
+go_data_get_matrix_value (GOData *data, unsigned int column, unsigned int row)
+{
+ unsigned int positions[2];
+
+ positions[0] = column;
+ positions[1] = row;
+
+ return go_data_get_value (data, 2, positions);
+}
+
+static char *
+go_data_get_string (GOData *data, unsigned int n_positions, unsigned int *positions)
+{
+ GODataClass const *data_class;
+ unsigned int i;
+ unsigned int n_sizes;
+
+ g_return_val_if_fail (GO_IS_DATA (data), NULL);
+ g_return_val_if_fail (n_positions < 1 || positions != NULL, NULL);
+
+ data_class = GO_DATA_GET_CLASS (data);
+
+ n_sizes = data_class->get_n_sizes (data);
+
+ if (n_sizes > n_positions) {
+ unsigned int *actual_positions;
+
+ actual_positions = g_newa (unsigned int, n_sizes);
+ memcpy (actual_positions, positions, n_positions * sizeof (unsigned int));
+
+ for (i = n_positions; i < n_sizes; i++)
+ actual_positions[i] = 0;
+
+ return data_class->get_string (data, actual_positions);
+ } else
+ return data_class->get_string (data, positions);
+}
+
+char *
+go_data_get_scalar_string (GOData *data)
+{
+ return go_data_get_string (data, 0, NULL);
+}
+
+char *
+go_data_get_vector_string (GOData *data, unsigned int column)
+{
+ return go_data_get_string (data, 1, &column);
+}
+
+char *
+go_data_get_matrix_string (GOData *data, unsigned int column, unsigned int row)
+{
+ unsigned int positions[2];
+
+ positions[0] = column;
+ positions[1] = row;
+
+ return go_data_get_string (data, 2, positions);
+}
+
/*************************************************************************/
#define GO_DATA_SCALAR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), GO_TYPE_DATA_SCALAR, GODataScalarClass))
#define GO_IS_DATA_SCALAR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GO_TYPE_DATA_SCALAR))
#define GO_DATA_SCALAR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GO_TYPE_DATA_SCALAR, GODataScalarClass))
+static unsigned int
+_data_scalar_get_n_sizes (GOData *data)
+{
+ return 1;
+}
+
+static double *
+_data_scalar_get_values (GOData *data)
+{
+ GODataScalar *scalar = (GODataScalar *) data;
+
+ go_data_scalar_get_value (scalar);
+
+ return &scalar->value;
+}
+
+static void
+_data_scalar_get_bounds (GOData *data, double *minimum, double *maximum)
+{
+ GODataScalar *scalar = (GODataScalar *) data;
+
+ go_data_scalar_get_value (scalar);
+
+ *minimum = scalar->value;
+ *maximum = scalar->value;
+}
+
+static double
+_data_scalar_get_value (GOData *data, unsigned int *positions)
+{
+ return go_data_scalar_get_value ((GODataScalar *) data);
+}
+
+static char *
+_data_scalar_get_string (GOData *data, unsigned int *positions)
+{
+ return g_strdup (go_data_scalar_get_str ((GODataScalar *) data));
+}
+
+static void
+go_data_scalar_class_init (GODataClass *data_class)
+{
+ data_class->get_n_sizes = _data_scalar_get_n_sizes;
+ data_class->get_values = _data_scalar_get_values;
+ data_class->get_bounds = _data_scalar_get_bounds;
+ data_class->get_value = _data_scalar_get_value;
+ data_class->get_string = _data_scalar_get_string;
+}
+
GSF_CLASS_ABSTRACT (GODataScalar, go_data_scalar,
- NULL, NULL,
+ go_data_scalar_class_init, NULL,
GO_TYPE_DATA)
double
@@ -222,7 +555,9 @@ go_data_scalar_get_value (GODataScalar *scalar)
{
GODataScalarClass const *klass = GO_DATA_SCALAR_GET_CLASS (scalar);
g_return_val_if_fail (klass != NULL, 0.); /* TODO : make this a nan */
- return (*klass->get_value) (scalar);
+ scalar->value = (*klass->get_value) (scalar);
+
+ return scalar->value;
}
char const *
@@ -240,14 +575,59 @@ go_data_scalar_get_str (GODataScalar *scalar)
#define GO_DATA_VECTOR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GO_TYPE_DATA_VECTOR, GODataVectorClass))
static void
-go_data_vector_emit_changed (GOData *data)
+_data_vector_emit_changed (GOData *data)
{
data->flags &= ~(GO_DATA_CACHE_IS_VALID | GO_DATA_VECTOR_LEN_CACHED);
}
+
+static unsigned int
+_data_vector_get_n_sizes (GOData *data)
+{
+ return 1;
+}
+
+static void
+_data_vector_get_sizes (GOData *data, unsigned int *sizes)
+{
+ GODataVector *vector = (GODataVector *) data;
+
+ sizes[0] = vector->len;
+}
+
+static double *
+_data_vector_get_values (GOData *data)
+{
+ return go_data_vector_get_values ((GODataVector *) data);
+}
+
static void
-go_data_vector_class_init (GODataClass *klass)
+_data_vector_get_bounds (GOData *data, double *minimum, double *maximum)
+{
+ go_data_vector_get_minmax ((GODataVector *) data, minimum, maximum);
+}
+
+static double
+_data_vector_get_value (GOData *data, unsigned int *positions)
+{
+ return go_data_vector_get_value ((GODataVector *) data, positions[0]);
+}
+
+static char *
+_data_vector_get_string (GOData *data, unsigned int *positions)
{
- klass->emit_changed = go_data_vector_emit_changed;
+ return go_data_vector_get_str ((GODataVector *) data, positions[0]);
+}
+
+static void
+go_data_vector_class_init (GODataClass *data_class)
+{
+ data_class->emit_changed = _data_vector_emit_changed;
+ data_class->get_n_sizes = _data_vector_get_n_sizes;
+ data_class->get_sizes = _data_vector_get_sizes;
+ data_class->get_values = _data_vector_get_values;
+ data_class->get_bounds = _data_vector_get_bounds;
+ data_class->get_value = _data_vector_get_value;
+ data_class->get_string = _data_vector_get_string;
}
GSF_CLASS_ABSTRACT (GODataVector, go_data_vector,
@@ -366,15 +746,60 @@ go_data_vector_vary_uniformly (GODataVector *vec)
#define GO_DATA_MATRIX_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GO_TYPE_DATA_MATRIX, GODataMatrixClass))
static void
-go_data_matrix_emit_changed (GOData *data)
+_data_matrix_emit_changed (GOData *data)
{
data->flags &= ~(GO_DATA_CACHE_IS_VALID | GO_DATA_MATRIX_SIZE_CACHED);
}
+static unsigned int
+_data_matrix_get_n_sizes (GOData *data)
+{
+ return 2;
+}
+
+static void
+_data_matrix_get_sizes (GOData *data, unsigned int *sizes)
+{
+ GODataMatrix *matrix = (GODataMatrix *) data;
+
+ sizes[0] = matrix->size.columns;
+ sizes[1] = matrix->size.rows;
+}
+
+static double *
+_data_matrix_get_values (GOData *data)
+{
+ return go_data_matrix_get_values ((GODataMatrix *) data);
+}
+
+static void
+_data_matrix_get_bounds (GOData *data, double *minimum, double *maximum)
+{
+ go_data_matrix_get_minmax ((GODataMatrix *) data, minimum, maximum);
+}
+
+static double
+_data_matrix_get_value (GOData *data, unsigned int *positions)
+{
+ return go_data_matrix_get_value ((GODataMatrix *) data, positions[0], positions[1]);
+}
+
+static char *
+_data_matrix_get_string (GOData *data, unsigned int *positions)
+{
+ return go_data_matrix_get_str ((GODataMatrix *) data, positions[0], positions[1]);
+}
+
static void
-go_data_matrix_class_init (GODataClass *klass)
+go_data_matrix_class_init (GODataClass *data_class)
{
- klass->emit_changed = go_data_matrix_emit_changed;
+ data_class->emit_changed = _data_matrix_emit_changed;
+ data_class->get_n_sizes = _data_matrix_get_n_sizes;
+ data_class->get_sizes = _data_matrix_get_sizes;
+ data_class->get_values = _data_matrix_get_values;
+ data_class->get_bounds = _data_matrix_get_bounds;
+ data_class->get_value = _data_matrix_get_value;
+ data_class->get_string = _data_matrix_get_string;
}
GSF_CLASS_ABSTRACT (GODataMatrix, go_data_matrix,
diff --git a/goffice/data/go-data.h b/goffice/data/go-data.h
index f15625a..49e6728 100644
--- a/goffice/data/go-data.h
+++ b/goffice/data/go-data.h
@@ -18,6 +18,7 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
* USA
*/
+
#ifndef GO_DATA_H
#define GO_DATA_H
@@ -31,13 +32,32 @@ G_BEGIN_DECLS
#define GO_DATA(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GO_TYPE_DATA, GOData))
#define GO_IS_DATA(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GO_TYPE_DATA))
-GType go_data_get_type (void);
-GOData *go_data_dup (GOData const *src);
-gboolean go_data_eq (GOData const *a, GOData const *b);
-GOFormat *go_data_preferred_fmt (GOData const *dat);
-char *go_data_as_str (GOData const *dat);
-gboolean go_data_from_str (GOData *dat, char const *str);
-void go_data_emit_changed (GOData *dat);
+GType go_data_get_type (void);
+GOData * go_data_dup (GOData const *src);
+gboolean go_data_eq (GOData const *a, GOData const *b);
+GOFormat * go_data_preferred_fmt (GOData const *dat);
+char * go_data_as_str (GOData const *dat);
+gboolean go_data_from_str (GOData *dat, char const *str);
+void go_data_emit_changed (GOData *dat);
+
+double * go_data_get_values (GOData *data);
+void go_data_get_bounds (GOData *data, double *minimum, double *maximum);
+gboolean go_data_is_increasing (GOData *data);
+gboolean go_data_is_decreasing (GOData *data);
+gboolean go_data_is_varying_uniformly (GOData *data);
+
+unsigned int go_data_get_n_values (GOData *data);
+
+unsigned int go_data_get_vector_size (GOData *data);
+void go_data_get_matrix_size (GOData *data, unsigned int *n_rows, unsigned int *n_columns);
+
+double go_data_get_scalar_value (GOData *data);
+double go_data_get_vector_value (GOData *data, unsigned int column);
+double go_data_get_matrix_value (GOData *data, unsigned int row, unsigned int column);
+
+char * go_data_get_scalar_string (GOData *data);
+char * go_data_get_vector_string (GOData *data, unsigned int column);
+char * go_data_get_matrix_string (GOData *data, unsigned int row, unsigned int column);
/*************************************************************************/
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]