[gnumeric] ssdiff: compare styles too.
- From: Morten Welinder <mortenw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnumeric] ssdiff: compare styles too.
- Date: Fri, 28 Dec 2012 00:46:45 +0000 (UTC)
commit 65a74f2f051ee35f4dfeff501142cc88b1e66808
Author: Morten Welinder <terra gnome org>
Date: Thu Dec 27 19:46:14 2012 -0500
ssdiff: compare styles too.
ChangeLog | 7 +
plugins/openoffice/openoffice-write.c | 2 +-
src/sheet-style.c | 6 +-
src/sheet-style.h | 2 +-
src/ssdiff.c | 260 +++++++++++++++++++++++++++++----
5 files changed, 245 insertions(+), 32 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index da14001..60f1383 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2012-12-27 Morten Welinder <terra gnome org>
+
+ * src/ssdiff.c (diff_sheets): Compare styles too.
+
+ * src/sheet-style.c (sheet_style_range_foreach): Add optional
+ range argument. All callers changed.
+
2012-12-24 Morten Welinder <terra gnome org>
* src/ssdiff.c (def_cell_changed): Merge cell_added and
diff --git a/plugins/openoffice/openoffice-write.c b/plugins/openoffice/openoffice-write.c
index b035e1a..6766b3f 100644
--- a/plugins/openoffice/openoffice-write.c
+++ b/plugins/openoffice/openoffice-write.c
@@ -1968,7 +1968,7 @@ odf_write_cell_styles (GnmOOExport *state)
int i;
for (i = 0; i < workbook_sheet_count (state->wb); i++) {
state->sheet = workbook_sheet_by_index (state->wb, i);
- sheet_style_range_foreach (state->sheet,
+ sheet_style_range_foreach (state->sheet, NULL,
(GHFunc) odf_save_this_style,
state);
}
diff --git a/src/sheet-style.c b/src/sheet-style.c
index 335e69d..b425c95 100644
--- a/src/sheet-style.c
+++ b/src/sheet-style.c
@@ -3001,17 +3001,19 @@ sheet_style_foreach (Sheet const *sheet, GHFunc func, gpointer user_data)
/**
* sheet_style_range_foreach:
* @sheet: #Sheet
+ * @r: optional range
* @func: (scope call): callback.
* @user_data: user data
* @optimize:
*
**/
void
-sheet_style_range_foreach (Sheet const *sheet, GHFunc func, gpointer user_data)
+sheet_style_range_foreach (Sheet const *sheet, GnmRange const *r,
+ GHFunc func, gpointer user_data)
{
GnmStyleList *styles, *l;
- styles = sheet_style_get_range (sheet, NULL);
+ styles = sheet_style_get_range (sheet, r);
for (l = styles; l; l = l->next) {
GnmStyleRegion *sr = l->data;
diff --git a/src/sheet-style.h b/src/sheet-style.h
index a9c1cb2..ebe10f2 100644
--- a/src/sheet-style.h
+++ b/src/sheet-style.h
@@ -60,7 +60,7 @@ GnmHLink *sheet_style_region_contains_link (Sheet const *sheet, GnmRange const *
void sheet_style_foreach (Sheet const *sheet,
GHFunc func,
gpointer user_data);
-void sheet_style_range_foreach (Sheet const *sheet,
+void sheet_style_range_foreach (Sheet const *sheet, GnmRange const *r,
GHFunc func,
gpointer user_data);
diff --git a/src/ssdiff.c b/src/ssdiff.c
index 57d1397..bf52343 100644
--- a/src/ssdiff.c
+++ b/src/ssdiff.c
@@ -19,8 +19,11 @@
#include "workbook-view.h"
#include "workbook.h"
#include "sheet.h"
+#include "sheet-style.h"
#include "cell.h"
#include "value.h"
+#include "ranges.h"
+#include "mstyle.h"
#include <gsf/gsf-libxml.h>
#include <gsf/gsf-output-stdio.h>
@@ -55,6 +58,14 @@ static const GOptionEntry ssdiff_options [] = {
typedef struct GnmDiffState_ GnmDiffState;
typedef struct {
+ /* Start comparison of two workbooks. */
+ void (*diff_start) (GnmDiffState *state);
+
+ /* Finish comparison started with above. */
+ void (*diff_end) (GnmDiffState *state);
+
+ /* ------------------------------ */
+
/* Start looking at a sheet. Either sheet might be NULL. */
void (*sheet_start) (GnmDiffState *state,
Sheet const *os, Sheet const *ns);
@@ -65,10 +76,21 @@ typedef struct {
/* The order of sheets has changed. */
void (*sheet_order_changed) (GnmDiffState *state);
+ /* An integer attribute of the sheet has changed. */
+ void (*sheet_attr_int_changed) (GnmDiffState *state, const char *name,
+ int o, int n);
+
/* ------------------------------ */
/* A cell was changed/added/removed. */
- void (*cell_changed) (GnmDiffState *state, GnmCell const *oc, GnmCell const *nc);
+ void (*cell_changed) (GnmDiffState *state,
+ GnmCell const *oc, GnmCell const *nc);
+
+ /* ------------------------------ */
+
+ /* The style of an area was changed. */
+ void (*style_changed) (GnmDiffState *state, GnmRange const *r,
+ GnmStyle const *os, GnmStyle const *ns);
} GnmDiffActions;
struct GnmDiffState_ {
@@ -82,13 +104,27 @@ struct GnmDiffState_ {
const GnmDiffActions *actions;
GsfOutput *output;
- GsfXMLOut *xml;
- Sheet const *pending_sheet;
+ /* The following for xml mode. */
+ GsfXMLOut *xml;
+ gboolean cells_open;
+ gboolean styles_open;
};
/* -------------------------------------------------------------------------- */
+static void
+def_diff_start (GnmDiffState *state)
+{
+ (void)state;
+}
+
+static void
+def_diff_end (GnmDiffState *state)
+{
+ (void)state;
+}
+
static const char *
def_cell_name (GnmCell const *oc)
{
@@ -106,10 +142,14 @@ def_cell_name (GnmCell const *oc)
static void
def_sheet_start (GnmDiffState *state, Sheet const *os, Sheet const *ns)
{
- if (os && !ns)
+ if (os && ns)
+ gsf_output_printf (state->output, _("Differences for sheet %s:\n"), os->name_quoted);
+ else if (os)
gsf_output_printf (state->output, _("Sheet %s removed.\n"), os->name_quoted);
- else if (!os && ns)
+ else if (ns)
gsf_output_printf (state->output, _("Sheet %s added.\n"), ns->name_quoted);
+ else
+ g_assert_not_reached ();
}
static void
@@ -125,6 +165,14 @@ def_sheet_order_changed (GnmDiffState *state)
}
static void
+def_sheet_attr_int_changed (GnmDiffState *state, const char *name,
+ G_GNUC_UNUSED int o, G_GNUC_UNUSED int n)
+{
+ gsf_output_printf (state->output, _("Sheet attribute %s changed.\n"),
+ name);
+}
+
+static void
def_cell_changed (GnmDiffState *state, GnmCell const *oc, GnmCell const *nc)
{
if (oc && nc)
@@ -137,39 +185,75 @@ def_cell_changed (GnmDiffState *state, GnmCell const *oc, GnmCell const *nc)
g_assert_not_reached ();
}
+static void
+def_style_changed (GnmDiffState *state, GnmRange const *r,
+ G_GNUC_UNUSED GnmStyle const *os,
+ G_GNUC_UNUSED GnmStyle const *ns)
+{
+ gsf_output_printf (state->output, _("Style of %s was changed.\n"),
+ range_as_string (r));
+}
+
static const GnmDiffActions default_actions = {
+ def_diff_start,
+ def_diff_end,
def_sheet_start,
def_sheet_end,
def_sheet_order_changed,
- def_cell_changed
+ def_sheet_attr_int_changed,
+ def_cell_changed,
+ def_style_changed,
};
/* -------------------------------------------------------------------------- */
static void
-xml_delayed_sheet_start (GnmDiffState *state)
+xml_diff_start (GnmDiffState *state)
{
- gsf_xml_out_start_element (state->xml, DIFF "Sheet");
- gsf_xml_out_add_cstr (state->xml, "Name", state->pending_sheet->name_unquoted);
- state->pending_sheet = NULL;
+ gsf_xml_out_start_element (state->xml, DIFF "Diff");
}
-
+
+static void
+xml_diff_end (GnmDiffState *state)
+{
+ gsf_xml_out_end_element (state->xml); /* </Diff> */
+}
+
static void
xml_sheet_start (GnmDiffState *state, Sheet const *os, Sheet const *ns)
{
- state->pending_sheet = os ? os : ns;
- if (!(os && ns)) {
- xml_delayed_sheet_start (state);
- gsf_xml_out_add_int (state->xml, "Old", os != NULL);
- gsf_xml_out_add_int (state->xml, "New", ns != NULL);
+ Sheet const *sheet = os ? os : ns;
+
+ gsf_xml_out_start_element (state->xml, DIFF "Sheet");
+ gsf_xml_out_add_cstr (state->xml, "Name", sheet->name_unquoted);
+ gsf_xml_out_add_int (state->xml, "Old", os != NULL);
+ gsf_xml_out_add_int (state->xml, "New", ns != NULL);
+}
+
+static void
+xml_close_cells (GnmDiffState *state)
+{
+ if (state->cells_open) {
+ gsf_xml_out_end_element (state->xml); /* </Cells> */
+ state->cells_open = FALSE;
+ }
+}
+
+static void
+xml_close_styles (GnmDiffState *state)
+{
+ if (state->styles_open) {
+ gsf_xml_out_end_element (state->xml); /* </Styles> */
+ state->styles_open = FALSE;
}
}
static void
xml_sheet_end (GnmDiffState *state)
{
- if (state->pending_sheet == NULL)
- gsf_xml_out_end_element (state->xml); /* </Sheet> */
+ xml_close_cells (state);
+ xml_close_styles (state);
+ gsf_xml_out_end_element (state->xml); /* </Sheet> */
}
static void
@@ -181,12 +265,28 @@ xml_sheet_order_changed (GnmDiffState *state)
}
static void
+xml_sheet_attr_int_changed (GnmDiffState *state, const char *name,
+ int o, int n)
+{
+ char *elem;
+
+ elem = g_strconcat (DIFF, name, NULL);
+ gsf_xml_out_start_element (state->xml, elem);
+ gsf_xml_out_add_int (state->xml, "Old", o);
+ gsf_xml_out_add_int (state->xml, "New", n);
+ gsf_xml_out_end_element (state->xml); /* elem */
+ g_free (elem);
+}
+
+static void
xml_cell_changed (GnmDiffState *state, GnmCell const *oc, GnmCell const *nc)
{
const GnmCellPos *pos;
- if (state->pending_sheet)
- xml_delayed_sheet_start (state);
+ if (!state->cells_open) {
+ gsf_xml_out_start_element (state->xml, DIFF "Cells");
+ state->cells_open = TRUE;
+ }
gsf_xml_out_start_element (state->xml, DIFF "Cell");
@@ -196,24 +296,48 @@ xml_cell_changed (GnmDiffState *state, GnmCell const *oc, GnmCell const *nc)
if (oc) {
char *txt = gnm_cell_get_entered_text (oc);
- gsf_xml_out_add_cstr (state->xml, "old", txt);
+ gsf_xml_out_add_cstr (state->xml, "Old", txt);
g_free (txt);
}
if (nc) {
char *txt = gnm_cell_get_entered_text (nc);
- gsf_xml_out_add_cstr (state->xml, "new", txt);
+ gsf_xml_out_add_cstr (state->xml, "New", txt);
g_free (txt);
}
gsf_xml_out_end_element (state->xml); /* </Cell> */
}
+static void
+xml_style_changed (GnmDiffState *state, GnmRange const *r,
+ GnmStyle const *os, GnmStyle const *ns)
+{
+ xml_close_cells (state);
+
+ if (!state->styles_open) {
+ gsf_xml_out_start_element (state->xml, DIFF "Styles");
+ state->styles_open = TRUE;
+ }
+
+ gsf_xml_out_start_element (state->xml, DIFF "StyleRegion");
+ gsf_xml_out_add_uint (state->xml, "startCol", r->start.col);
+ gsf_xml_out_add_uint (state->xml, "startRow", r->start.row);
+ gsf_xml_out_add_uint (state->xml, "endCol", r->end.col);
+ gsf_xml_out_add_uint (state->xml, "endRow", r->end.row);
+ /* FIXME: Add how they differ. */
+ gsf_xml_out_end_element (state->xml); /* </StyleRegion> */
+}
+
static const GnmDiffActions xml_actions = {
+ xml_diff_start,
+ xml_diff_end,
xml_sheet_start,
xml_sheet_end,
xml_sheet_order_changed,
- xml_cell_changed
+ xml_sheet_attr_int_changed,
+ xml_cell_changed,
+ xml_style_changed,
};
/* -------------------------------------------------------------------------- */
@@ -290,15 +414,89 @@ diff_sheets_cells (GnmDiffState *state, Sheet *old_sheet, Sheet *new_sheet)
}
static void
-diff_sheets (GnmDiffState *state, Sheet *old_sheet, Sheet *new_sheet)
+diff_sheets_attrs (GnmDiffState *state, Sheet *old_sheet, Sheet *new_sheet)
{
- /* Compare sheet attributes and sizes */
+ GnmSheetSize const *os = gnm_sheet_get_size (old_sheet);
+ GnmSheetSize const *ns = gnm_sheet_get_size (new_sheet);
+
+ if (os->max_cols != ns->max_cols)
+ state->actions->sheet_attr_int_changed
+ (state, "Cols", os->max_cols, ns->max_cols);
+ if (os->max_rows != ns->max_rows)
+ state->actions->sheet_attr_int_changed
+ (state, "Rows", os->max_rows, ns->max_rows);
+}
- /* Compare row/column attributes. */
+struct cb_diff_sheets_styles {
+ GnmDiffState *state;
+ Sheet const *old_sheet;
+ Sheet const *new_sheet;
+ GnmStyle *old_style;
+ GnmCellPos old_offset;
+};
- diff_sheets_cells (state, old_sheet, new_sheet);
+static void
+cb_diff_sheets_styles_2 (G_GNUC_UNUSED gpointer key,
+ gpointer sr_, gpointer user_data)
+{
+ GnmStyleRegion *sr = sr_;
+ struct cb_diff_sheets_styles *data = user_data;
+ GnmRange r = sr->range;
+
+ if (gnm_style_equal (data->old_style, sr->style))
+ return;
+
+ /* sheet_style_range_foreach calls us with ranges that are relative
+ to its input range. Weird. */
+ r.start.col += data->old_offset.col;
+ r.start.row += data->old_offset.row;
- /* Compare style */
+ data->state->actions->style_changed (data->state, &r,
+ data->old_style, sr->style);
+}
+
+static void
+cb_diff_sheets_styles_1 (G_GNUC_UNUSED gpointer key,
+ gpointer sr_, gpointer user_data)
+{
+ GnmStyleRegion *sr = sr_;
+ struct cb_diff_sheets_styles *data = user_data;
+
+ data->old_style = sr->style;
+ data->old_offset = sr->range.start;
+ sheet_style_range_foreach (data->new_sheet, &sr->range,
+ cb_diff_sheets_styles_2,
+ data);
+}
+
+static void
+diff_sheets_styles (GnmDiffState *state, Sheet *old_sheet, Sheet *new_sheet)
+{
+ GnmSheetSize const *os = gnm_sheet_get_size (old_sheet);
+ GnmSheetSize const *ns = gnm_sheet_get_size (new_sheet);
+ GnmRange r;
+ struct cb_diff_sheets_styles data;
+
+ /* Compare largest common area only. */
+ range_init (&r, 0, 0,
+ MIN (os->max_cols, ns->max_cols) - 1,
+ MIN (os->max_rows, ns->max_rows) - 1);
+
+ data.state = state;
+ data.old_sheet = old_sheet;
+ data.new_sheet = new_sheet;
+ sheet_style_range_foreach (old_sheet, &r,
+ cb_diff_sheets_styles_1,
+ &data);
+}
+
+static void
+diff_sheets (GnmDiffState *state, Sheet *old_sheet, Sheet *new_sheet)
+{
+ diff_sheets_attrs (state, old_sheet, new_sheet);
+ /* Compare row/column attributes. */
+ diff_sheets_cells (state, old_sheet, new_sheet);
+ diff_sheets_styles (state, old_sheet, new_sheet);
}
static int
@@ -335,6 +533,10 @@ diff (char const *oldfilename, char const *newfilename,
goto error;
state.new.wb = wb_view_get_workbook (state.new.wbv);
+ /* ---------------------------------------- */
+
+ state.actions->diff_start (&state);
+
/*
* This doesn't handle sheet renames very well, but simply considers
* that a sheet deletion and a sheet insert.
@@ -374,6 +576,8 @@ diff (char const *oldfilename, char const *newfilename,
if (sheet_order_changed)
state.actions->sheet_order_changed (&state);
+ state.actions->diff_end (&state);
+
out:
g_free (state.old.url);
g_free (state.new.url);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]