[gnumeric] Import/ Export margins from/to ODF.



commit ab23942d6b6b5b449413f8168c755988b5eed884
Author: Andreas J Guelzow <aguelzow pyrshep ca>
Date:   Tue Jun 21 14:44:22 2011 -0600

    Import/ Export margins from/to ODF.
    
    2011-06-21  Andreas J. Guelzow <aguelzow pyrshep ca>
    
    	* openoffice-read.c (odf_get_paper_size): new
    	(odf_page_layout_properties): new
    	(odf_page_layout): new
    	(odf_page_layout_end): new
    	(odf_master_page): use the specified page layout
    	(odf_header_footer): text:p may occur outside a style:region-*
    	(odf_hf_region): avoid null-dereference
    	(odf_hf_span): ditto
    	(odf_hf_item): ditto
    	(odf_hf_title): also write the title item, skip the
    	  warning since LO includes unused layouts with this item.
    	(styles_dtd): connect the above
    	(openoffice_file_open):initialize and finalize new page layout hash

 NEWS                                 |    2 +-
 plugins/openoffice/ChangeLog         |   16 +++
 plugins/openoffice/openoffice-read.c |  174 +++++++++++++++++++++++++++++-----
 3 files changed, 166 insertions(+), 26 deletions(-)
---
diff --git a/NEWS b/NEWS
index 4a99fb5..f3dcabe 100644
--- a/NEWS
+++ b/NEWS
@@ -3,7 +3,7 @@ Gnumeric 1.10.17
 Andreas:
 	* Fix some style import from ODF. [#652492]
 	* Import/Export header and footer from/to ODF.
-	* Export margins to ODF.
+	* Import/ Export margins from/to ODF.
 
 Morten:
 	* Fix --with-gnome compilation:  [#652802]
diff --git a/plugins/openoffice/ChangeLog b/plugins/openoffice/ChangeLog
index 190f875..bd8ff79 100644
--- a/plugins/openoffice/ChangeLog
+++ b/plugins/openoffice/ChangeLog
@@ -1,5 +1,21 @@
 2011-06-21  Andreas J. Guelzow <aguelzow pyrshep ca>
 
+	* openoffice-read.c (odf_get_paper_size): new
+	(odf_page_layout_properties): new
+	(odf_page_layout): new
+	(odf_page_layout_end): new
+	(odf_master_page): use the specified page layout
+	(odf_header_footer): text:p may occur outside a style:region-*
+	(odf_hf_region): avoid null-dereference
+	(odf_hf_span): ditto
+	(odf_hf_item): ditto
+	(odf_hf_title): also write the title item, skip the
+	  warning since LO includes unused layouts with this item.
+	(styles_dtd): connect the above
+	(openoffice_file_open):initialize and finalize new page layout hash
+
+2011-06-21  Andreas J. Guelzow <aguelzow pyrshep ca>
+
 	* openoffice-write.c (page_layout_name): new
 	(odf_write_page_layout): new
 	(odf_write_automatic_styles): call odf_write_page_layout
diff --git a/plugins/openoffice/openoffice-read.c b/plugins/openoffice/openoffice-read.c
index 1582c0b..cdb98f5 100644
--- a/plugins/openoffice/openoffice-read.c
+++ b/plugins/openoffice/openoffice-read.c
@@ -326,6 +326,7 @@ typedef struct {
 		GHashTable	*row;
 		GHashTable	*sheet;
 		GHashTable	*master_pages;
+		GHashTable	*page_layouts;
 	} styles;
 	struct {
 		GnmStyle	*cells;
@@ -4269,22 +4270,117 @@ odf_number_style_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
 
 /*****************************************************************************************************/
 
+static GtkPaperSize *
+odf_get_paper_size (gnm_float width, gnm_float height)
+{
+	GtkPaperSize *size = NULL;
+	char *name, *display_name;
+
+	GList *plist = gtk_paper_size_get_paper_sizes (TRUE), *l;
+
+	for (l = plist; l != NULL; l = l->next) {
+		GtkPaperSize *n_size = l->data;
+		double n_width = gtk_paper_size_get_width (n_size, GTK_UNIT_POINTS);
+		double n_height = gtk_paper_size_get_height (n_size, GTK_UNIT_POINTS);
+		double w_diff = n_width - width;
+		double h_diff = n_height - height;
+		
+		if (w_diff > -2. && w_diff < 2. && h_diff > -2 && h_diff < 2) {
+			size = gtk_paper_size_copy (n_size);
+			break;
+		}
+	} 
+	go_list_free_custom (plist, (GFreeFunc)gtk_paper_size_free);
+
+	if (size != NULL)
+		return size;
+
+	name = g_strdup_printf ("odf_%ix%i", (int)width, (int)height);
+	display_name = g_strdup_printf (_("Paper from ODF file: %ipt\xE2\xA8\x89%ipt"), (int)width, (int)height);
+	size = gtk_paper_size_new_custom (name, display_name, width, height, GTK_UNIT_POINTS);
+	g_free (name);
+	g_free (display_name);
+	return size;
+}
+
+static void
+odf_page_layout_properties (GsfXMLIn *xin, xmlChar const **attrs)
+{
+	OOParseState *state = (OOParseState *)xin->user_state;
+	gnm_float pts, height, width;
+	gboolean h_set = FALSE, w_set = FALSE;
+	GtkPageSetup *gps;
+
+	if (state->cur_pi == NULL)
+		return;
+	gps = print_info_get_page_setup (state->cur_pi);
+
+	for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2)
+		if (oo_attr_distance (xin, attrs, OO_NS_FO, "margin-left", &pts))
+			gtk_page_setup_set_left_margin (gps, pts, GTK_UNIT_POINTS);
+		else if (oo_attr_distance (xin, attrs, OO_NS_FO, "margin-right", &pts))
+			gtk_page_setup_set_right_margin (gps, pts, GTK_UNIT_POINTS);
+		else if (oo_attr_distance (xin, attrs, OO_NS_FO, "margin-top", &pts))
+			gtk_page_setup_set_top_margin (gps, pts, GTK_UNIT_POINTS);
+		else if (oo_attr_distance (xin, attrs, OO_NS_FO, "margin-bottom", &pts))
+			gtk_page_setup_set_bottom_margin (gps, pts, GTK_UNIT_POINTS);
+		else if (oo_attr_distance (xin, attrs, OO_NS_FO, "page-height", &height))
+			h_set = TRUE;
+		else if (oo_attr_distance (xin, attrs, OO_NS_FO, "page-width", &width))
+			w_set = TRUE;
+	
+	if (h_set && w_set) {
+		GtkPaperSize *size;
+		size = odf_get_paper_size (width, height);
+		gtk_page_setup_set_paper_size (gps, size);
+		gtk_paper_size_free (size);
+	}
+}
+
+static void
+odf_page_layout (GsfXMLIn *xin, xmlChar const **attrs)
+{
+	OOParseState *state = (OOParseState *)xin->user_state;
+	char const *name = NULL;
+
+	for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2)
+		if (gsf_xml_in_namecmp (xin, CXML2C (attrs[0]), OO_NS_STYLE, "name"))
+			name = CXML2C (attrs[1]);
+
+	if (name != NULL) {
+		state->cur_pi = print_info_new (TRUE);		
+		g_hash_table_insert (state->styles.page_layouts, g_strdup (name), state->cur_pi);
+	} else
+		oo_warning (xin, _("Missing page layout identifier"));
+}
+
+static void
+odf_page_layout_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
+{
+	OOParseState *state = (OOParseState *)xin->user_state;
+
+	state->cur_pi = NULL;
+}
+
 static void
 odf_master_page (GsfXMLIn *xin, xmlChar const **attrs)
 {
 	OOParseState *state = (OOParseState *)xin->user_state;
 	char const *name = NULL;
-	/* char const *pl_name = NULL; */
+	char const *pl_name = NULL;
+	PrintInformation *pi;
 
 	for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2)
 		if (gsf_xml_in_namecmp (xin, CXML2C (attrs[0]), OO_NS_STYLE, "name"))
 			name = CXML2C (attrs[1]);
-		/* else if (gsf_xml_in_namecmp (xin, CXML2C (attrs[0]),  */
-		/* 			     OO_NS_STYLE, "page-layout-name")) */
-		/* 	pl_name = CXML2C (attrs[1]); */
+		else if (gsf_xml_in_namecmp (xin, CXML2C (attrs[0]),
+					     OO_NS_STYLE, "page-layout-name"))
+			pl_name = CXML2C (attrs[1]);
 
 	if (name != NULL) {
-		state->cur_pi = print_info_new (TRUE);
+		if (pl_name != NULL)
+			pi = g_hash_table_lookup (state->styles.page_layouts, pl_name);
+		state->cur_pi = (pi == NULL) ? print_info_new (TRUE) : print_info_dup (pi);
 		print_hf_free (state->cur_pi->header);
 		print_hf_free (state->cur_pi->footer);
 		state->cur_pi->header = print_hf_new (NULL, NULL, NULL);
@@ -4308,13 +4404,27 @@ static void
 odf_header_footer (GsfXMLIn *xin, xmlChar const **attrs)
 {
 	OOParseState *state = (OOParseState *)xin->user_state;
-	/* gboolean display = true; */
+	gboolean display = TRUE;
+	gdouble margin;
+	GtkPageSetup *gps;
+
+	if (state->cur_pi == NULL)
+		return;
+	gps = print_info_get_page_setup (state->cur_pi);
 
-	/* for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2) */
-	/* 	if (oo_attr_bool (xin, attrs, OO_NS_STYLE, "display", */
-	/* 			  &display)) ; */
-	state->cur_hf = (xin->node->user_data.v_int == 0) 
-		? state->cur_pi->header : state->cur_pi->footer;
+	for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2)
+		if (oo_attr_bool (xin, attrs, OO_NS_STYLE, "display",
+				  &display)) ;
+	if (xin->node->user_data.v_int == 0) {
+		state->cur_hf = state->cur_pi->header;
+		margin = gtk_page_setup_get_top_margin (gps, GTK_UNIT_POINTS);
+		print_info_set_edge_to_below_header (state->cur_pi, margin + (display ? 36 : 0));
+	} else {
+		state->cur_hf = state->cur_pi->footer;
+		margin = gtk_page_setup_get_bottom_margin (gps, GTK_UNIT_POINTS);
+		print_info_set_edge_to_above_footer (state->cur_pi, margin + (display ? 36 : 0));
+	}
+	state->cur_hf_format = &state->cur_hf->middle_format;
 }
 
 static void
@@ -4322,17 +4432,18 @@ odf_hf_region (GsfXMLIn *xin, xmlChar const **attrs)
 {
 	OOParseState *state = (OOParseState *)xin->user_state;
 
-	switch (xin->node->user_data.v_int) {
-	case 0:
-		state->cur_hf_format = &state->cur_hf->left_format;
-		break;
-	case 1:
-		state->cur_hf_format = &state->cur_hf->middle_format;
-		break;
-	case 2:
-		state->cur_hf_format = &state->cur_hf->right_format;
-		break;
-	}
+	if (state->cur_hf != NULL)
+		switch (xin->node->user_data.v_int) {
+		case 0:
+			state->cur_hf_format = &state->cur_hf->left_format;
+			break;
+		case 1:
+			state->cur_hf_format = &state->cur_hf->middle_format;
+			break;
+		case 2:
+			state->cur_hf_format = &state->cur_hf->right_format;
+			break;
+		}
 }
 
 static void
@@ -4340,6 +4451,9 @@ odf_hf_span (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
 {
 	OOParseState *state = (OOParseState *)xin->user_state;
 	char *new;
+
+	if (state->cur_hf_format == NULL)
+		return;
 	
 	if (*(state->cur_hf_format) == NULL)
 		new = g_strdup (xin->content->str);
@@ -4355,6 +4469,9 @@ odf_hf_item (GsfXMLIn *xin, char const *item)
 	OOParseState *state = (OOParseState *)xin->user_state;
 	char *new;
 	
+	if (state->cur_hf_format == NULL)
+		return;
+
 	if (*(state->cur_hf_format) == NULL)
 		new = g_strconcat ("&[", item, "]", NULL);
 	else
@@ -4431,6 +4548,9 @@ odf_hf_file (GsfXMLIn *xin, xmlChar const **attrs)
 	int tmp = 2;
 	char *new;
 
+	if (state->cur_hf_format == NULL)
+		return;
+
 	for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2)
 		if (oo_attr_enum (xin, attrs, OO_NS_TABLE, "display-list", dropdown_types, &tmp)) ;
 	
@@ -4489,7 +4609,7 @@ odf_hf_expression (GsfXMLIn *xin, xmlChar const **attrs)
 static void
 odf_hf_title (GsfXMLIn *xin, xmlChar const **attrs)
 {
-	oo_warning (xin, _("Unknown Header/Footer Item: Title"));	
+	odf_hf_item (xin, _("title"));
 }
 
 /*****************************************************************************************************/
@@ -8334,8 +8454,8 @@ GSF_XML_IN_NODE (OFFICE_DOC_STYLES, OFFICE_STYLES, OO_NS_OFFICE, "styles", GSF_X
 
 GSF_XML_IN_NODE (OFFICE_DOC_STYLES, AUTOMATIC_STYLES, OO_NS_OFFICE, "automatic-styles", GSF_XML_NO_CONTENT, NULL, NULL),
   GSF_XML_IN_NODE (AUTOMATIC_STYLES, STYLE, OO_NS_STYLE, "style", GSF_XML_NO_CONTENT, NULL, NULL), /* 2nd */
-  GSF_XML_IN_NODE (AUTOMATIC_STYLES, PAGE_LAYOUT, OO_NS_STYLE, "page-layout", GSF_XML_NO_CONTENT, NULL, NULL),
-GSF_XML_IN_NODE (PAGE_LAYOUT, PAGE_LAYOUT_PROPS, OO_NS_STYLE, "page-layout-properties", GSF_XML_NO_CONTENT, NULL, NULL),
+  GSF_XML_IN_NODE (AUTOMATIC_STYLES, PAGE_LAYOUT, OO_NS_STYLE, "page-layout", GSF_XML_NO_CONTENT,  &odf_page_layout, &odf_page_layout_end),
+GSF_XML_IN_NODE (PAGE_LAYOUT, PAGE_LAYOUT_PROPS, OO_NS_STYLE, "page-layout-properties", GSF_XML_NO_CONTENT, &odf_page_layout_properties, NULL),
 GSF_XML_IN_NODE (PAGE_LAYOUT, HEADER_STYLE, OO_NS_STYLE, "header-style", GSF_XML_NO_CONTENT, NULL, NULL),
 GSF_XML_IN_NODE (HEADER_STYLE, HEADER_FOOTER_PROPERTIES, OO_NS_STYLE, "header-footer-properties", GSF_XML_NO_CONTENT, NULL, NULL),
 GSF_XML_IN_NODE (HEADER_FOOTER_PROPERTIES, HF_BACK_IMAGE, OO_NS_STYLE, "background-image", GSF_XML_NO_CONTENT, NULL, NULL),
@@ -9622,6 +9742,9 @@ openoffice_file_open (GOFileOpener const *fo, GOIOContext *io_context,
 	state.styles.master_pages = g_hash_table_new_full (g_str_hash, g_str_equal,
 		(GDestroyNotify) g_free,
 		(GDestroyNotify) print_info_free);
+	state.styles.page_layouts = g_hash_table_new_full (g_str_hash, g_str_equal,
+		(GDestroyNotify) g_free,
+		(GDestroyNotify) print_info_free);
 	state.formats = g_hash_table_new_full (g_str_hash, g_str_equal,
 		(GDestroyNotify) g_free,
 		(GDestroyNotify) go_format_unref);
@@ -9807,6 +9930,7 @@ openoffice_file_open (GOFileOpener const *fo, GOIOContext *io_context,
 	g_hash_table_destroy (state.styles.cell_date);
 	g_hash_table_destroy (state.styles.cell_time);
 	g_hash_table_destroy (state.styles.master_pages);
+	g_hash_table_destroy (state.styles.page_layouts);
 	go_slist_free_custom (state.chart.saved_graph_styles,
 			      (GFreeFunc) g_hash_table_destroy);
 	g_hash_table_destroy (state.chart.graph_styles);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]