[goffice] Make chart position persistent in auto mode. [#152674]
- From: Jean Bréfort <jbrefort src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [goffice] Make chart position persistent in auto mode. [#152674]
- Date: Thu, 29 Oct 2009 16:38:06 +0000 (UTC)
commit b2edcabf1807ced28bb12d8f2619c1ba8cb8c477
Author: Jean Brefort <jean brefort normalesup org>
Date: Thu Oct 29 17:38:22 2009 +0100
Make chart position persistent in auto mode. [#152674]
ChangeLog | 15 ++++
NEWS | 1 +
goffice/graph/gog-chart-impl.h | 5 +-
goffice/graph/gog-chart.c | 75 +++++++++++++++--
goffice/graph/gog-graph.c | 57 ++++++++-----
goffice/graph/gog-object-prefs.ui | 162 +++++++++++++++++++++++++++++++++++++
goffice/graph/gog-object.c | 35 ++++++++-
7 files changed, 317 insertions(+), 33 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 16e211c..7673940 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,20 @@
2009-10-29 Jean Brefort <jean brefort normalesup org>
+ * goffice/graph/gog-chart-impl.h: add persistent position for auto mode.
+ Fixes #152674.
+ * goffice/graph/gog-chart.c (gog_chart_set_property),
+ (gog_chart_get_property), (gog_chart_class_init), (gog_chart_init),
+ (gog_chart_get_position), (gog_chart_set_position): ditto.
+ * goffice/graph/gog-graph.c (role_chart_post_add),
+ (gog_graph_validate_chart_layout), (gog_graph_view_size_allocate):
+ * goffice/graph/gog-object-prefs.ui: add a user interface to set column
+ and row position of a chart in the graph.
+ * goffice/graph/gog-object.c (update_select_state),
+ (cb_manual_position_changed), (cb_chart_position_changed),
+ (gog_object_populate_editor): ditto.
+
+2009-10-29 Jean Brefort <jean brefort normalesup org>
+
* goffice/canvas/goc-graph.c (goc_graph_update_bounds): set the right size.
* goffice/graph/gog-renderer.c (gog_renderer_update): fixed resizing a
graph. [#599887]
diff --git a/NEWS b/NEWS
index 36b33d2..861af79 100644
--- a/NEWS
+++ b/NEWS
@@ -7,6 +7,7 @@ Jean:
* Make titles the first logical child and ensure they are rendered last.
Really fixes #152675.
* Fix graph scale after a size change. [#599887]
+ * Make chart position persistent in auto mode. [#152674]
Morten:
* Canvas improvements for arrows.
diff --git a/goffice/graph/gog-chart-impl.h b/goffice/graph/gog-chart-impl.h
index 9c8bd80..46b3fb1 100644
--- a/goffice/graph/gog-chart-impl.h
+++ b/goffice/graph/gog-chart-impl.h
@@ -34,7 +34,10 @@ struct _GogChart {
gboolean cardinality_valid;
/* use a simple grid layout to position charts within graph */
- unsigned x, y, cols, rows;
+ unsigned x_pos, y_pos;
+ unsigned cols, rows; /* if == 0, chart is not positionned */
+ /* actual chart position in graph grid after layout validation */
+ unsigned x_pos_actual, y_pos_actual;
GogObject *grid;
GSList *axes;
diff --git a/goffice/graph/gog-chart.c b/goffice/graph/gog-chart.c
index 7e264ac..38c1352 100644
--- a/goffice/graph/gog-chart.c
+++ b/goffice/graph/gog-chart.c
@@ -90,6 +90,10 @@ enum {
CHART_PROP_CARDINALITY_VALID,
CHART_PROP_PLOT_AREA,
CHART_PROP_PLOT_AREA_IS_MANUAL,
+ CHART_PROP_X_POS,
+ CHART_PROP_Y_POS,
+ CHART_PROP_ROWS,
+ CHART_PROP_COLUMNS
};
static GType gog_chart_view_get_type (void);
@@ -128,6 +132,7 @@ gog_chart_set_property (GObject *obj, guint param_id,
GogChart *chart = GOG_CHART (obj);
char **str_doubles;
char const *str;
+ gboolean changed = FALSE;
switch (param_id) {
case CHART_PROP_PLOT_AREA:
@@ -146,9 +151,30 @@ gog_chart_set_property (GObject *obj, guint param_id,
case CHART_PROP_PLOT_AREA_IS_MANUAL:
chart->is_plot_area_manual = g_value_get_boolean (value);
break;
+ case CHART_PROP_X_POS:
+ chart->x_pos = g_value_get_int (value);
+ changed = TRUE;
+ break;
+ case CHART_PROP_Y_POS:
+ chart->y_pos = g_value_get_int (value);
+ changed = TRUE;
+ break;
+ case CHART_PROP_COLUMNS:
+ chart->cols = g_value_get_int (value);
+ changed = TRUE;
+ break;
+ case CHART_PROP_ROWS:
+ chart->rows = g_value_get_int (value);
+ changed = TRUE;
+ break;
default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, param_id, pspec);
return; /* NOTE : RETURN */
}
+
+ if (changed) {
+ gog_graph_validate_chart_layout (GOG_GRAPH (GOG_OBJECT (chart)->parent));
+ gog_object_emit_changed (GOG_OBJECT (obj), TRUE);
+ }
}
static void
@@ -178,6 +204,18 @@ gog_chart_get_property (GObject *obj, guint param_id,
case CHART_PROP_PLOT_AREA_IS_MANUAL:
g_value_set_boolean (value, chart->is_plot_area_manual);
break;
+ case CHART_PROP_X_POS:
+ g_value_set_int (value, chart->x_pos);
+ break;
+ case CHART_PROP_Y_POS:
+ g_value_set_int (value, chart->y_pos);
+ break;
+ case CHART_PROP_COLUMNS:
+ g_value_set_int (value, chart->cols);
+ break;
+ case CHART_PROP_ROWS:
+ g_value_set_int (value, chart->rows);
+ break;
default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, param_id, pspec);
break;
@@ -505,6 +543,23 @@ gog_chart_class_init (GogObjectClass *gog_klass)
_("Is plot area manual"),
FALSE,
GSF_PARAM_STATIC | G_PARAM_READWRITE | GO_PARAM_PERSISTENT));
+ g_object_class_install_property (gobject_klass, CHART_PROP_X_POS,
+ g_param_spec_int ("xpos", _("xpos"),
+ _("Horizontal chart position in graph grid"),
+ 0, G_MAXINT, 0, G_PARAM_READWRITE | GO_PARAM_PERSISTENT));
+ /* we need to force saving of ypos since the default is not constant */
+ g_object_class_install_property (gobject_klass, CHART_PROP_Y_POS,
+ g_param_spec_int ("ypos", _("ypos"),
+ _("Vertical chart position in graph grid"),
+ 0, G_MAXINT, 0, G_PARAM_READWRITE | GO_PARAM_PERSISTENT | GOG_PARAM_FORCE_SAVE));
+ g_object_class_install_property (gobject_klass, CHART_PROP_COLUMNS,
+ g_param_spec_int ("columns", _("columns"),
+ _("Number of columns in graph grid"),
+ 1, G_MAXINT, 1, G_PARAM_READWRITE | GO_PARAM_PERSISTENT));
+ g_object_class_install_property (gobject_klass, CHART_PROP_ROWS,
+ g_param_spec_int ("rows", _("rows"),
+ _("Number of rows in graph grid"),
+ 1, G_MAXINT, 1, G_PARAM_READWRITE | GO_PARAM_PERSISTENT));
gog_klass->view_type = gog_chart_view_get_type ();
gog_klass->update = gog_chart_update;
@@ -515,10 +570,12 @@ gog_chart_class_init (GogObjectClass *gog_klass)
static void
gog_chart_init (GogChart *chart)
{
- chart->x = 0;
- chart->y = 0;
- chart->cols = 0;
- chart->rows = 0;
+ chart->x_pos =
+ chart->y_pos =
+ chart->cols =
+ chart->rows =
+ chart->x_pos_actual =
+ chart->y_pos_actual = 0;
/* start as true so that we can queue an update when it changes */
chart->cardinality_valid = TRUE;
@@ -554,8 +611,8 @@ gog_chart_get_position (GogChart const *chart,
if (chart->cols <= 0 || chart->rows <= 0)
return FALSE;
- if (x != NULL) *x = chart->x;
- if (y != NULL) *y = chart->y;
+ if (x != NULL) *x = chart->x_pos;
+ if (y != NULL) *y = chart->y_pos;
if (cols != NULL) *cols = chart->cols;
if (rows != NULL) *rows = chart->rows;
@@ -577,12 +634,12 @@ gog_chart_set_position (GogChart *chart,
{
g_return_if_fail (GOG_IS_CHART (chart));
- if (chart->x == x && chart->y == y &&
+ if (chart->x_pos == x && chart->y_pos == y &&
chart->cols == cols && chart->rows == rows)
return;
- chart->x = x;
- chart->y = y;
+ chart->x_pos = x;
+ chart->y_pos = y;
chart->cols = cols;
chart->rows = rows;
diff --git a/goffice/graph/gog-graph.c b/goffice/graph/gog-graph.c
index d090159..44e7734 100644
--- a/goffice/graph/gog-graph.c
+++ b/goffice/graph/gog-graph.c
@@ -246,9 +246,24 @@ static void
role_chart_post_add (GogObject *parent, GogObject *chart)
{
GogGraph *graph = GOG_GRAPH (parent);
+ unsigned ypos = 0;
+ if (graph->charts != NULL) {
+ /* find the first row with an unoccupied first column */
+ gboolean *occ = g_alloca (graph->num_rows * sizeof (gboolean));
+ GSList *ptr;
+ int col, row;
+ memset (occ, 0, graph->num_rows * sizeof (gboolean));
+ for (ptr = graph->charts; ptr != NULL; ptr = ptr->next)
+ if (gog_chart_get_position (GOG_CHART (ptr->data), &col, &row, NULL, NULL) && col == 0 && row < (int) graph->num_rows)
+ occ[row] = TRUE;
+ while (ypos < graph->num_rows && occ[ypos])
+ ypos++;
+ }
graph->charts = g_slist_prepend (graph->charts, chart);
- gog_chart_set_position (GOG_CHART (chart),
- 0, GOG_GRAPH (graph)->num_rows, 1, 1);
+ if (!gog_chart_get_position (GOG_CHART (chart), NULL, NULL, NULL, NULL))
+ /* search the first row with column 0 unocupied */
+ gog_chart_set_position (GOG_CHART (chart),
+ 0, ypos, 1, 1);
}
static void
@@ -419,17 +434,19 @@ gog_graph_validate_chart_layout (GogGraph *graph)
max_col = max_row = 0;
for (ptr = graph->charts ; ptr != NULL ; ptr = ptr->next) {
chart = ptr->data;
- if (max_col < (chart->x + chart->cols))
- max_col = (chart->x + chart->cols);
- if (max_row < (chart->y + chart->rows))
- max_row = (chart->y + chart->rows);
+ chart->x_pos_actual = chart->x_pos;
+ chart->y_pos_actual = chart->y_pos;
+ if (max_col < (chart->x_pos_actual + chart->cols))
+ max_col = (chart->x_pos_actual + chart->cols);
+ if (max_row < (chart->y_pos_actual + chart->rows))
+ max_row = (chart->y_pos_actual + chart->rows);
}
/* 2) see if we need to contract any cols */
for (i = 0 ; i < max_col ; ) {
for (ptr = graph->charts ; ptr != NULL ; ptr = ptr->next) {
chart = ptr->data;
- if (chart->x <= i && i < (chart->x + chart->cols))
+ if (chart->x_pos_actual <= i && i < (chart->x_pos_actual + chart->cols))
break;
}
if (ptr == NULL) {
@@ -437,18 +454,18 @@ gog_graph_validate_chart_layout (GogGraph *graph)
max_col--;
for (ptr = graph->charts ; ptr != NULL ; ptr = ptr->next) {
chart = ptr->data;
- if (chart->x > i)
- (chart->x)--;
+ if (chart->x_pos_actual > i)
+ (chart->x_pos_actual)--;
}
} else
- i = chart->x + chart->cols;
+ i = chart->x_pos_actual + chart->cols;
}
/* 3) see if we need to contract any rows */
for (i = 0 ; i < max_row ; ) {
for (ptr = graph->charts ; ptr != NULL ; ptr = ptr->next) {
chart = ptr->data;
- if (chart->y <= i && i < (chart->y + chart->rows))
+ if (chart->y_pos_actual <= i && i < (chart->y_pos_actual + chart->rows))
break;
}
if (ptr == NULL) {
@@ -456,11 +473,11 @@ gog_graph_validate_chart_layout (GogGraph *graph)
max_row--;
for (ptr = graph->charts ; ptr != NULL ; ptr = ptr->next) {
chart = ptr->data;
- if (chart->y > i)
- (chart->y)--;
+ if (chart->y_pos_actual > i)
+ (chart->y_pos_actual)--;
}
} else
- i = chart->y + chart->rows;
+ i = chart->y_pos_actual + chart->rows;
}
changed |= (graph->num_cols != max_col || graph->num_rows != max_row);
@@ -797,7 +814,6 @@ gog_graph_view_size_allocate (GogView *view, GogViewAllocation const *bbox)
{
GSList *ptr;
double h, w;
- unsigned x, y, rows, cols;
GogView *child;
GogGraph *graph = GOG_GRAPH (view->model);
GogViewAllocation tmp, res = *bbox;
@@ -814,12 +830,11 @@ gog_graph_view_size_allocate (GogView *view, GogViewAllocation const *bbox)
for (ptr = view->children; ptr != NULL ; ptr = ptr->next) {
child = ptr->data;
if (GOG_POSITION_IS_SPECIAL (child->model->position)) {
- gog_chart_get_position (GOG_CHART (child->model),
- &x, &y, &cols, &rows);
- tmp.x = x * w + res.x;
- tmp.y = y * h + res.y;
- tmp.w = cols * w;
- tmp.h = rows * h;
+ GogChart *chart = GOG_CHART (child->model);
+ tmp.x = chart->x_pos_actual * w + res.x;
+ tmp.y = chart->y_pos_actual * h + res.y;
+ tmp.w = chart->cols * w;
+ tmp.h = chart->rows * h;
gog_view_size_allocate (child, &tmp);
}
}
diff --git a/goffice/graph/gog-object-prefs.ui b/goffice/graph/gog-object-prefs.ui
index a3e6062..0890442 100644
--- a/goffice/graph/gog-object-prefs.ui
+++ b/goffice/graph/gog-object-prefs.ui
@@ -1,5 +1,6 @@
<?xml version="1.0"?>
<interface>
+ <!-- interface-requires gtk+ 2.12 -->
<!-- interface-naming-policy toplevel-contextual -->
<object class="GtkAdjustment" id="adjustment1">
<property name="lower">-10000</property>
@@ -426,6 +427,143 @@
<property name="tab_fill">False</property>
</packing>
</child>
+ <child>
+ <object class="GtkTable" id="chart-table">
+ <property name="visible">True</property>
+ <property name="n_rows">2</property>
+ <property name="n_columns">4</property>
+ <property name="column_spacing">12</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="col-lbl">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Column:</property>
+ </object>
+ <packing>
+ <property name="x_options"></property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="row-lbl">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Row:</property>
+ </object>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="col-span-lbl">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="xpad">12</property>
+ <property name="label" translatable="yes">Width in columns:</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="row-span-lbl">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="xpad">12</property>
+ <property name="label" translatable="yes">Height in rows:</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="xpos">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">●</property>
+ <property name="adjustment">col-adj</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="ypos">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">●</property>
+ <property name="adjustment">row-adj</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="columns">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">●</property>
+ <property name="adjustment">col-span-adj</property>
+ </object>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="right_attach">4</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="rows">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">●</property>
+ <property name="adjustment">row-span-adj</property>
+ </object>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="right_attach">4</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">page 3</property>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
</object>
<packing>
<property name="position">1</property>
@@ -450,4 +588,28 @@
<column type="gchararray"/>
</columns>
</object>
+ <object class="GtkAdjustment" id="row-adj">
+ <property name="upper">100</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10.01</property>
+ </object>
+ <object class="GtkAdjustment" id="row-span-adj">
+ <property name="value">1</property>
+ <property name="lower">1</property>
+ <property name="upper">100</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="col-adj">
+ <property name="upper">10000</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="col-span-adj">
+ <property name="value">1</property>
+ <property name="lower">1</property>
+ <property name="upper">100</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
</interface>
diff --git a/goffice/graph/gog-object.c b/goffice/graph/gog-object.c
index e10f130..2d7f3c1 100644
--- a/goffice/graph/gog-object.c
+++ b/goffice/graph/gog-object.c
@@ -318,6 +318,8 @@ update_select_state (ObjectPrefState *state)
int index = gog_object_get_position_flags (state->gobj, GOG_POSITION_MANUAL) == 0 ? 0 : 1;
gtk_combo_box_set_active (GTK_COMBO_BOX (state->position_select_combo), index);
+ if (index == 0 && GOG_IS_CHART (state->gobj))
+ index = 2;
gtk_notebook_set_current_page (GTK_NOTEBOOK (state->position_notebook), index);
}
}
@@ -330,6 +332,8 @@ cb_manual_position_changed (GtkComboBox *combo, ObjectPrefState *state)
gog_object_set_position_flags (state->gobj,
index != 0 ? GOG_POSITION_MANUAL : 0,
GOG_POSITION_MANUAL);
+ if (index == 0 && GOG_IS_CHART (state->gobj))
+ index = 2;
gtk_notebook_set_current_page (GTK_NOTEBOOK (state->position_notebook), index);
}
@@ -357,6 +361,13 @@ cb_update_editor (GogObject *gobj, ObjectPrefState *state)
}
static void
+cb_chart_position_changed (GtkWidget *spin, ObjectPrefState *state)
+{
+ g_object_set (G_OBJECT (state->gobj), gtk_widget_get_name (spin),
+ (int) gtk_spin_button_get_value (GTK_SPIN_BUTTON (spin)), NULL);
+}
+
+static void
gog_object_populate_editor (GogObject *gobj,
GOEditor *editor,
G_GNUC_UNUSED GogDataAllocator *dalloc,
@@ -492,8 +503,28 @@ gog_object_populate_editor (GogObject *gobj,
w = go_gtk_builder_get_widget (gui, "manual_sizes");
gtk_widget_hide (w);
}
- } else
- gtk_notebook_set_current_page (GTK_NOTEBOOK (state->position_notebook), 0);
+ }
+ if (GOG_IS_CHART (gobj)) {
+ /* setting special notebook page */
+ int col, row, cols, rows;
+ g_object_get (G_OBJECT (gobj), "xpos", &col, "ypos", &row, "columns", &cols, "rows", &rows, NULL);
+ w = go_gtk_builder_get_widget (gui, "xpos");
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (w), col);
+ g_signal_connect (G_OBJECT (w), "value-changed",
+ G_CALLBACK (cb_chart_position_changed), state);
+ w = go_gtk_builder_get_widget (gui, "columns");
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (w), cols);
+ g_signal_connect (G_OBJECT (w), "value-changed",
+ G_CALLBACK (cb_chart_position_changed), state);
+ w = go_gtk_builder_get_widget (gui, "ypos");
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (w), row);
+ g_signal_connect (G_OBJECT (w), "value-changed",
+ G_CALLBACK (cb_chart_position_changed), state);
+ w = go_gtk_builder_get_widget (gui, "rows");
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (w), rows);
+ g_signal_connect (G_OBJECT (w), "value-changed",
+ G_CALLBACK (cb_chart_position_changed), state);
+ }
g_object_unref (G_OBJECT (widget_size_group));
g_object_unref (G_OBJECT (label_size_group));
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]