[goffice] Data labels work.
- From: Jean BrÃfort <jbrefort src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [goffice] Data labels work.
- Date: Sun, 14 Aug 2011 13:21:00 +0000 (UTC)
commit 0b59d6e0ef831d1e62aebb6bf701fee9eb85aa91
Author: Jean Brefort <jean brefort normalesup org>
Date: Sun Aug 14 15:25:23 2011 +0200
Data labels work.
ChangeLog | 13 ++++
goffice/data/go-data-impl.h | 1 +
goffice/data/go-data.c | 8 ++
goffice/data/go-data.h | 1 +
goffice/graph/gog-label.c | 1 -
goffice/graph/gog-series-labels.c | 135 ++++++++++++++++++++++++++++++++++++-
goffice/graph/gog-series-labels.h | 9 +++
goffice/graph/gog-series.c | 7 ++-
plugins/plot_barcol/gog-barcol.c | 9 +--
9 files changed, 175 insertions(+), 9 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index d3fcb32..4378dab 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2011-08-14 Jean Brefort <jean brefort normalesup org>
+
+ * goffice/data/go-data-impl.h: add new is_valid method.
+ * goffice/data/go-data.c (go_data_is_valid): ditto.
+ * goffice/data/go-data.h: ditto.
+ * goffice/graph/gog-label.c (gog_text_view_size_request): don't unref a
+ GOString twice.
+ * goffice/graph/gog-series-labels.c: more work on data labels.
+ * goffice/graph/gog-series-labels.h: ditto.
+ * goffice/graph/gog-series.c (role_series_labels_can_add),
+ (gog_series_update): ditto.
+ * plugins/plot_barcol/gog-barcol.c (gog_barcol_view_render): ditto.
+
2011-08-12 Morten Welinder <terra gnome org>
* goffice/utils/go-format.c (go_format_value_gstring): Avoid
diff --git a/goffice/data/go-data-impl.h b/goffice/data/go-data-impl.h
index f6b6a90..d4b6a9b 100644
--- a/goffice/data/go-data-impl.h
+++ b/goffice/data/go-data-impl.h
@@ -58,6 +58,7 @@ typedef struct {
double (*get_value) (GOData *data, unsigned int *coordinates);
char * (*get_string) (GOData *data, unsigned int *coordinates);
PangoAttrList * (*get_markup) (GOData *data, unsigned int *coordinates);
+ gboolean (*is_valid) (GOData const *data);
/* signals */
void (*changed) (GOData *dat);
diff --git a/goffice/data/go-data.c b/goffice/data/go-data.c
index 2596096..dcb76c9 100644
--- a/goffice/data/go-data.c
+++ b/goffice/data/go-data.c
@@ -209,6 +209,14 @@ go_data_unserialize (GOData *dat, char const *str, gpointer user)
return (*klass->unserialize) (dat, str, user);
}
+gboolean
+go_data_is_valid (GOData const *data)
+{
+ GODataClass const *klass = GO_DATA_GET_CLASS (data);
+ g_return_val_if_fail (klass != NULL, FALSE);
+ return (klass->is_valid != NULL)? (*klass->is_valid) (data): FALSE;
+}
+
/**
* go_data_emit_changed :
* @dat : #GOData
diff --git a/goffice/data/go-data.h b/goffice/data/go-data.h
index 4b77f2c..1451cff 100644
--- a/goffice/data/go-data.h
+++ b/goffice/data/go-data.h
@@ -37,6 +37,7 @@ GOData * go_data_dup (GOData const *src);
gboolean go_data_eq (GOData const *a, GOData const *b);
GOFormat const *go_data_preferred_fmt (GOData const *dat);
GODateConventions const *go_data_date_conv (GOData const *dat);
+gboolean go_data_is_valid (GOData const *dat);
char * go_data_serialize (GOData const *dat, gpointer user);
gboolean go_data_unserialize (GOData *dat, char const *str, gpointer user);
diff --git a/goffice/graph/gog-label.c b/goffice/graph/gog-label.c
index 07ea47a..41089c0 100644
--- a/goffice/graph/gog-label.c
+++ b/goffice/graph/gog-label.c
@@ -560,7 +560,6 @@ gog_text_view_size_request (GogView *v,
req->w = aabr.w;
req->h = aabr.h;
}
- go_string_unref (gostr);
g_free (str);
}
text_view_parent_klass->size_request (v, available, req);
diff --git a/goffice/graph/gog-series-labels.c b/goffice/graph/gog-series-labels.c
index b027566..33d396e 100644
--- a/goffice/graph/gog-series-labels.c
+++ b/goffice/graph/gog-series-labels.c
@@ -560,7 +560,7 @@ gog_series_labels_parent_changed (GogObject *obj, gboolean was_set)
switch (plot->desc.series.dim[j].ms_type) {
case GOG_MS_DIM_VALUES:
labels->format = g_strdup_printf ("%%%u", j);
- j = plot->desc.series.num_dim; /* ensure we exit the loop */
+ j = plot->desc.series.num_dim; /* ensure we exit the loop */
break;
default:
break;
@@ -570,11 +570,121 @@ gog_series_labels_parent_changed (GogObject *obj, gboolean was_set)
}
static void
+gog_series_labels_changed (GogObject *obj, gboolean size)
+{
+ gog_object_emit_changed (gog_object_get_parent (obj), size);
+}
+
+struct attr_closure {
+ PangoAttrList *l;
+ unsigned offset;
+};
+
+static gboolean
+attr_position (PangoAttribute *attr, gpointer data)
+{
+ struct attr_closure *c = (struct attr_closure *) data;
+ PangoAttribute *new_attr = pango_attribute_copy (attr);
+ new_attr->start_index += c->offset;
+ new_attr->end_index += c->offset;
+ pango_attr_list_change (c->l, new_attr);
+ return FALSE;
+}
+
+static void
+gog_series_labels_update (GogObject *obj)
+{
+ GogSeriesLabels *labels = GOG_SERIES_LABELS (obj);
+ GogObject *parent = gog_object_get_parent (GOG_OBJECT (obj));
+ unsigned i, n;
+ if (labels->elements) {
+ n = labels->n_elts;
+ for (i = 0; i < n; i++)
+ go_string_unref (labels->elements[i].str);
+ g_free (labels->elements);
+ }
+ if (GOG_IS_SERIES (parent)) {
+ GogSeries *series = GOG_SERIES (parent);
+ labels->n_elts = n = gog_series_num_elements (series);
+ labels->elements = g_new0 (GogSeriesLabelElt, n);
+ for (i = 0; i < n; i++) {
+ GString *str = g_string_new ("");
+ unsigned index;
+ PangoAttrList *markup = pango_attr_list_new (), *l;
+ char const *format = labels->format;
+ char *next;
+ while (*format) {
+ if (*format == '%') {
+ format++;
+ switch (*format) {
+ case 0: /* protect from an unexpected string end */
+ break;
+ case 'c':
+ next = go_data_get_vector_string (labels->custom_labels.data, i);
+ if (next) {
+ index = str->len;
+ g_string_append (str, next);
+ g_free (next);
+ l = go_data_get_vector_markup (labels->custom_labels.data, i);
+ if (l) {
+ struct attr_closure c;
+ c.l = markup;
+ c.offset = index;
+ pango_attr_list_filter (l, attr_position, &c);
+ pango_attr_list_unref (l);
+ }
+ }
+ break;
+ case 'l':
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ index = *format - '0';
+ next = go_data_get_vector_string (series->values[index].data, i);
+ if (next) {
+ g_string_append (str, next);
+ g_free (next);
+ }
+ break;
+ case '%':
+ g_string_append_c (str, '%');
+ break;
+ default:
+ continue;
+ }
+ format++;
+ } else {
+ next = g_utf8_next_char (format);
+ g_string_append_len (str, format, next - format);
+ format = next;
+ }
+ }
+ labels->elements[i].str = go_string_new_rich (g_string_free (str, FALSE), -1, FALSE, markup, NULL);
+ }
+ } else
+ labels->elements = NULL; /* FIXME: might be a SeriesElement */
+}
+
+static void
gog_series_labels_finalize (GObject *obj)
{
GogSeriesLabels *labels = GOG_SERIES_LABELS (obj);
gog_dataset_finalize (GOG_DATASET (obj));
g_free (labels->format);
+ if (labels->elements) {
+ unsigned i, n = labels->n_elts;
+ for (i = 0; i < n; i++)
+ go_string_unref (labels->elements[i].str);
+ g_free (labels->elements);
+ }
series_labels_parent_klass->finalize (obj);
}
@@ -611,6 +721,8 @@ gog_series_labels_class_init (GObjectClass *obj_klass)
gog_klass->populate_editor = gog_series_labels_populate_editor;
#endif
gog_klass->parent_changed = gog_series_labels_parent_changed;
+ gog_klass->changed = gog_series_labels_changed;
+ gog_klass->update = gog_series_labels_update;
style_klass->init_style = gog_series_labels_init_style;
}
@@ -632,7 +744,7 @@ gog_series_labels_dataset_get_elem (GogDataset const *set, int dim_i)
static void
gog_series_labels_dataset_dim_changed (GogDataset *set, int dim_i)
{
- gog_object_request_update (GOG_OBJECT (set));
+ gog_object_request_update (gog_object_get_parent (GOG_OBJECT (set)));
}
static void
@@ -718,3 +830,22 @@ gog_series_labels_get_position (GogSeriesLabels const *lbls)
return (lbls->position == GOG_SERIES_LABELS_DEFAULT_POS)?
lbls->default_pos: lbls->position;
}
+
+GogSeriesLabelElt const *gog_series_labels_scalar_get_element (GogSeriesLabels const *lbls)
+{
+ g_return_val_if_fail (GOG_IS_SERIES_LABELS (lbls), NULL);
+ return lbls->elements;
+}
+
+GogSeriesLabelElt const *gog_series_labels_vector_get_element (GogSeriesLabels const *lbls, unsigned n)
+{
+ GogObject *obj;
+ g_return_val_if_fail (GOG_IS_SERIES_LABELS (lbls) && lbls->elements != NULL, NULL);
+ obj= gog_object_get_parent (GOG_OBJECT (lbls));
+ if (GOG_IS_SERIES (obj)) {
+ GogSeries *series = GOG_SERIES (obj);
+ g_return_val_if_fail (n < gog_series_num_elements (series), NULL);
+ return lbls->elements + n;
+ }
+ return NULL;
+}
diff --git a/goffice/graph/gog-series-labels.h b/goffice/graph/gog-series-labels.h
index 5fa7585..caf2cd7 100644
--- a/goffice/graph/gog-series-labels.h
+++ b/goffice/graph/gog-series-labels.h
@@ -27,6 +27,11 @@
G_BEGIN_DECLS
+typedef struct {
+ GOString *str;
+ double legend_offset, legend_width, width, height;
+} GogSeriesLabelElt;
+
struct _GogSeriesLabels {
GogOutlinedObject base;
@@ -37,6 +42,8 @@ struct _GogSeriesLabels {
unsigned offset; /* position offset in pixels */
char *format;
GogDatasetElement custom_labels;
+ unsigned n_elts;
+ GogSeriesLabelElt *elements;
};
#define GOG_TYPE_SERIES_LABELS (gog_series_labels_get_type ())
@@ -49,6 +56,8 @@ void gog_series_labels_set_allowed_position (GogSeriesLabels *lbls, unsigned all
void gog_series_labels_set_position (GogSeriesLabels *lbls, GogSeriesLabelsPos pos);
void gog_series_labels_set_default_position (GogSeriesLabels *lbls, GogSeriesLabelsPos pos);
GogSeriesLabelsPos gog_series_labels_get_position (GogSeriesLabels const *lbls);
+GogSeriesLabelElt const *gog_series_labels_scalar_get_element (GogSeriesLabels const *lbls);
+GogSeriesLabelElt const *gog_series_labels_vector_get_element (GogSeriesLabels const *lbls, unsigned n);
G_END_DECLS
diff --git a/goffice/graph/gog-series.c b/goffice/graph/gog-series.c
index e954ada..f770478 100644
--- a/goffice/graph/gog-series.c
+++ b/goffice/graph/gog-series.c
@@ -305,7 +305,7 @@ role_series_labels_can_add (GogObject const *parent)
{
GogSeries *series = GOG_SERIES (parent);
- return (series->allowed_pos != 0);
+ return (series->allowed_pos != 0 && gog_object_get_child_by_name (parent, "Data labels") == NULL);
}
static void
@@ -628,7 +628,12 @@ static void
gog_series_update (GogObject *obj)
{
GogSeries *series = GOG_SERIES (obj);
+ GogObjectRole const *role = gog_object_find_role_by_name (obj, "Data labels");
+ GSList *l = gog_object_get_children (obj, role), *ptr;
series->needs_recalc = FALSE;
+ for (ptr = l; ptr; ptr = ptr->next)
+ gog_object_request_update (ptr->data);
+ g_slist_free (l);
}
static void
diff --git a/plugins/plot_barcol/gog-barcol.c b/plugins/plot_barcol/gog-barcol.c
index 684cd6d..3113c5d 100644
--- a/plugins/plot_barcol/gog-barcol.c
+++ b/plugins/plot_barcol/gog-barcol.c
@@ -378,8 +378,8 @@ typedef struct {
typedef struct {
double x;
double y;
- char *str;
- GOAnchorType anchor;
+ GogSeriesLabelElt const *elt;
+ GOAnchorType anchor;
} LabelData;
static int
@@ -642,7 +642,7 @@ gog_barcol_view_render (GogView *view, GogViewAllocation const *bbox)
if (labels[i]) {
label_pos[i] = g_malloc (sizeof (LabelData) * lengths[i]);
for (j = 0; j < lengths[i]; j++)
- label_pos[i][j].str = go_data_get_vector_string (base_series->values[1].data, j);
+ label_pos[i][j].elt = gog_series_labels_vector_get_element (labels[i] , j);
} else
label_pos[i] = NULL;
}
@@ -862,8 +862,7 @@ gog_barcol_view_render (GogView *view, GogViewAllocation const *bbox)
for (j = 0; j < lengths[i]; j++) {
alloc.x = label_pos[i][j].x;
alloc.y = label_pos[i][j].y;
- gog_renderer_draw_text (view->renderer, label_pos[i][j].str, &alloc, label_pos[i][j].anchor, FALSE);
- g_free (label_pos[i][j].str);
+ gog_renderer_draw_gostring (view->renderer, label_pos[i][j].elt->str, &alloc, label_pos[i][j].anchor);
}
gog_renderer_pop_style (view->renderer);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]