1 /* -*- mode: C++; tab-width: 4; c-basic-offset: 4; -*- */
2 
3 /* AbiSource
4  *
5  * Copyright (C) 2008 Firat Kiyak <firatkiyak@gmail.com>
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20  * 02110-1301 USA.
21  */
22 
23 
24 // Class definition include
25 #include <ie_exp_OpenXML.h>
26 
27 // Abiword includes
28 #include <ut_std_string.h>
29 
30 /**
31  * Constructor
32  */
IE_Exp_OpenXML(PD_Document * pDocument)33 IE_Exp_OpenXML::IE_Exp_OpenXML (PD_Document * pDocument)
34   : IE_Exp (pDocument),
35 	m_pDoc(pDocument),
36 	root(NULL),
37 	relsDir(NULL),
38 	wordDir(NULL),
39 	wordRelsDir(NULL),
40 	wordMediaDir(NULL),
41 	contentTypesStream(NULL),
42 	relStream(NULL),
43 	wordRelStream(NULL),
44 	documentStream(NULL),
45 	settingsStream(NULL),
46 	stylesStream(NULL),
47 	numberingStream(NULL),
48 	headerStream(NULL),
49 	footerStream(NULL),
50 	footnoteStream(NULL),
51 	endnoteStream(NULL),
52 	isOverline(false)
53 {
54 }
55 
56 /**
57  * Destructor
58  */
~IE_Exp_OpenXML()59 IE_Exp_OpenXML::~IE_Exp_OpenXML ()
60 {
61 	_cleanup();
62 }
63 
64 /**
65  * Export the OOXML document here
66  */
_writeDocument()67 UT_Error IE_Exp_OpenXML::_writeDocument ()
68 {
69 	UT_Error err = UT_SAVE_EXPORTERROR;
70 
71 	IE_Exp_OpenXML_Listener* listener = new IE_Exp_OpenXML_Listener(getDoc());
72 
73 	OXML_Document* doc_ptr = listener->getDocument();
74 
75 	if(doc_ptr)
76 		err = doc_ptr->serialize(this);
77 
78 	DELETEP(listener);
79 
80 	return err;
81 }
82 
83 /**
84  * Starts exporting the OXML_Document object
85  */
startDocument()86 UT_Error IE_Exp_OpenXML::startDocument()
87 {
88 	GError *err = NULL;
89 	UT_Error error = UT_OK;
90 
91 	GsfOutput* sink = getFp();
92 
93 	if(!sink)
94 		return UT_SAVE_EXPORTERROR;
95 
96 	root = gsf_outfile_zip_new(sink, &err);
97 
98 	if(err || !root)
99 	{
100 		UT_DEBUGMSG(("FRT: ERROR, Zip root file couldn't be created\n"));
101 		g_object_unref (G_OBJECT (sink));
102 		return UT_IE_COULDNOTWRITE;
103 	}
104 
105 	g_object_unref (G_OBJECT (sink));
106 
107 	error = startEndnotes();
108 	if(error != UT_OK)
109 		return error;
110 
111 	error = startFootnotes();
112 	if(error != UT_OK)
113 		return error;
114 
115 	error = startHeaders();
116 	if(error != UT_OK)
117 		return error;
118 
119 	error = startFooters();
120 	if(error != UT_OK)
121 		return error;
122 
123 	error = startContentTypes();
124 	if(error != UT_OK)
125 		return error;
126 
127 	error = startRelations();
128 	if(error != UT_OK)
129 		return error;
130 
131 	error = startWordRelations();
132 	if(error != UT_OK)
133 		return error;
134 
135 	error = startWordMedia();
136 	if(error != UT_OK)
137 		return error;
138 
139 	error = startMainPart();
140 	if(error != UT_OK)
141 		return error;
142 
143 	error = startSettings();
144 	if(error != UT_OK)
145 		return error;
146 
147 	error = startStyles();
148 	if(error != UT_OK)
149 		return error;
150 
151 	error = startNumbering();
152 	if(error != UT_OK)
153 		return error;
154 
155 	return UT_OK;
156 }
157 
158 /**
159  * Finishes exporting OXML_Document object
160  */
finishDocument()161 UT_Error IE_Exp_OpenXML::finishDocument()
162 {
163 	UT_Error error = UT_OK;
164 
165 	error = finishMainPart();
166 	if(error != UT_OK)
167 		return error;
168 
169 	error = finishSettings();
170 	if(error != UT_OK)
171 		return error;
172 
173 	error = finishNumbering();
174 	if(error != UT_OK)
175 		return error;
176 
177 	error = finishStyles();
178 	if(error != UT_OK)
179 		return error;
180 
181 	error = finishWordMedia();
182 	if(error != UT_OK)
183 		return error;
184 
185 	error = finishWordRelations();
186 	if(error != UT_OK)
187 		return error;
188 
189 	error = finishRelations();
190 	if(error != UT_OK)
191 		return error;
192 
193 	error = finishContentTypes();
194 	if(error != UT_OK)
195 		return error;
196 
197 	error = finishHeaders();
198 	if(error != UT_OK)
199 		return error;
200 
201 	error = finishFooters();
202 	if(error != UT_OK)
203 		return error;
204 
205 	error = finishFootnotes();
206 	if(error != UT_OK)
207 		return error;
208 
209 	error = finishEndnotes();
210 	if(error != UT_OK)
211 		return error;
212 
213 	if(!gsf_output_close(GSF_OUTPUT(root)))
214 	{
215 		UT_DEBUGMSG(("FRT: ERROR, zip root file couldn't be closed\n"));
216 		return UT_SAVE_EXPORTERROR;
217 	}
218 
219 	return UT_OK;
220 }
221 
222 /**
223  * Starts exporting the OXML_Section object's properties
224  */
startSectionProperties()225 UT_Error IE_Exp_OpenXML::startSectionProperties()
226 {
227 	return writeTargetStream(TARGET_DOCUMENT, "<w:sectPr>");
228 }
229 
230 /**
231  * Finishes exporting the OXML_Section object's properties
232  */
finishSectionProperties()233 UT_Error IE_Exp_OpenXML::finishSectionProperties()
234 {
235 	return writeTargetStream(TARGET_DOCUMENT, "</w:sectPr>");
236 }
237 
238 /**
239  * Starts exporting the OXML_Element_Paragraph object
240  */
startParagraph(int target)241 UT_Error IE_Exp_OpenXML::startParagraph(int target)
242 {
243 	return writeTargetStream(target, "<w:p>");
244 }
245 
246 /**
247  * Finishes exporting the OXML_Element_Paragraph object
248  */
finishParagraph(int target)249 UT_Error IE_Exp_OpenXML::finishParagraph(int target)
250 {
251 	return writeTargetStream(target, "</w:p>");
252 }
253 
254 /**
255  * Starts exporting the OXML_Element_Text object
256  */
startText(int target)257 UT_Error IE_Exp_OpenXML::startText(int target)
258 {
259 	if(isOverline)
260 	{
261 		return writeTargetStream(target, "<w:fldChar w:fldCharType=\"begin\"/></w:r><w:r><w:instrText xml:space=\"preserve\"> EQ \\x \\to(");
262 	}
263 	else
264 	{
265 		return writeTargetStream(target, "<w:t xml:space=\"preserve\">");
266 	}
267 }
268 
269 /**
270  * Writes the actual content of OXML_Element_Text object
271  */
writeText(int target,const UT_UCS4Char * text,bool list)272 UT_Error IE_Exp_OpenXML::writeText(int target, const UT_UCS4Char* text, bool list)
273 {
274 	// This shouldn't happen, but if it does just return UT_OK
275 	// to prevent export errors
276 	UT_return_val_if_fail(text, UT_OK);
277 
278 	UT_uint32 len = UT_UCS4_strlen(text);
279 
280 	UT_UTF8String sEscText;
281 	sEscText.reserve(len);
282 
283 	const UT_UCS4Char* pText;
284 	for(pText = text; pText < text + len; pText++)
285 	{
286 		// Skipping first tab character of list element
287 		if(list && pText == text && *pText == '\t')
288 		{
289 			continue;
290 		}
291 
292 		switch(*pText)
293 		{
294 			// any other special handling needed?
295 
296 			default:
297 
298 				if((*pText >= 0x20 && *pText != 0x7f) ||
299 					(*pText == '\n' || *pText == '\r' || *pText == '\t'))
300 				{
301 					sEscText.appendUCS4(pText, 1);
302 				}
303 				else
304 				{
305 					xxx_UT_DEBUGMSG(("OOXML export: dropping character (%d)\n", *pText));
306 				}
307 		}
308 	}
309 
310 	sEscText.escapeXML();
311 
312 	return writeTargetStream(target, sEscText.utf8_str());
313 }
314 
315 /**
316  * Finishes exporting the OXML_Element_Text object
317  */
finishText(int target)318 UT_Error IE_Exp_OpenXML::finishText(int target)
319 {
320 	if(isOverline)
321 	{
322 		return writeTargetStream(target, ") </w:instrText></w:r><w:r><w:fldChar w:fldCharType=\"end\"/>");
323 	}
324 	else
325 	{
326 		return writeTargetStream(target, "</w:t>");
327 	}
328 }
329 
330 /**
331  * Starts exporting the OXML_Element_Math object
332  */
startMath()333 UT_Error IE_Exp_OpenXML::startMath()
334 {
335     return writeTargetStream(TARGET_DOCUMENT, "<m:oMathPara>");
336 }
337 
338 /**
339  * Writes the actual content of OXML_Element_Math object
340  */
writeMath(const char * omml)341 UT_Error IE_Exp_OpenXML::writeMath(const char* omml)
342 {
343     std::string str;
344     str.assign(omml);
345     return writeTargetStream(TARGET_DOCUMENT, str.c_str());
346 }
347 
348 /**
349  * Finishes exporting the OXML_Element_Math object
350  */
finishMath()351 UT_Error IE_Exp_OpenXML::finishMath()
352 {
353     return writeTargetStream(TARGET_DOCUMENT, "</m:oMathPara>");
354 }
355 
356 /**
357  * Starts exporting the OXML_Element_Run object
358  */
startRun(int target)359 UT_Error IE_Exp_OpenXML::startRun(int target)
360 {
361 	return writeTargetStream(target, "<w:r>");
362 }
363 
364 /**
365  * Finishes exporting the OXML_Element_Run object
366  */
finishRun(int target)367 UT_Error IE_Exp_OpenXML::finishRun(int target)
368 {
369 	isOverline = false;
370 	return writeTargetStream(target, "</w:r>");
371 }
372 
373 /**
374  * Starts exporting the OXML_Element_Run object's properties
375  */
startRunProperties(int target)376 UT_Error IE_Exp_OpenXML::startRunProperties(int target)
377 {
378 	return writeTargetStream(target, "<w:rPr>");
379 }
380 
381 /**
382  * Finishes exporting the OXML_Element_Run object's properties
383  */
finishRunProperties(int target)384 UT_Error IE_Exp_OpenXML::finishRunProperties(int target)
385 {
386 	return writeTargetStream(target, "</w:rPr>");
387 }
388 
389 /**
390  * Starts exporting the OXML_Element_Paragraph object's properties
391  */
startParagraphProperties(int target)392 UT_Error IE_Exp_OpenXML::startParagraphProperties(int target)
393 {
394 	return writeTargetStream(target, "<w:pPr>");
395 }
396 
397 /**
398  * Finishes exporting the OXML_Element_Paragraph object's properties
399  */
finishParagraphProperties(int target)400 UT_Error IE_Exp_OpenXML::finishParagraphProperties(int target)
401 {
402 	return writeTargetStream(target, "</w:pPr>");
403 }
404 
405 /**
406  * Starts exporting the OXML_Element_Table object
407  */
startTable()408 UT_Error IE_Exp_OpenXML::startTable()
409 {
410 	return writeTargetStream(TARGET_DOCUMENT, "<w:tbl>");
411 }
412 
413 /**
414  * Finishes exporting the OXML_Element_Table object
415  */
finishTable()416 UT_Error IE_Exp_OpenXML::finishTable()
417 {
418 	return writeTargetStream(TARGET_DOCUMENT, "</w:tbl>");
419 }
420 
421 /**
422  * Starts exporting the OXML_Element_Table's properties
423  */
startTableProperties(int target)424 UT_Error IE_Exp_OpenXML::startTableProperties(int target)
425 {
426 	return writeTargetStream(target, "<w:tblPr>");
427 }
428 
429 /**
430  * Finishes exporting the OXML_Element_Table's properties
431  */
finishTableProperties(int target)432 UT_Error IE_Exp_OpenXML::finishTableProperties(int target)
433 {
434 	return writeTargetStream(target, "</w:tblPr>");
435 }
436 
437 /**
438  * Starts exporting the OXML_Element_Table's border properties
439  */
startTableBorderProperties(int target)440 UT_Error IE_Exp_OpenXML::startTableBorderProperties(int target)
441 {
442 	return writeTargetStream(target, "<w:tblBorders>");
443 }
444 
445 /**
446  * Finishes exporting the OXML_Element_Table's border properties
447  */
finishTableBorderProperties(int target)448 UT_Error IE_Exp_OpenXML::finishTableBorderProperties(int target)
449 {
450 	return writeTargetStream(target, "</w:tblBorders>");
451 }
452 
453 /**
454  * Starts exporting the OXML_Element_Cell's border properties
455  */
startCellBorderProperties(int target)456 UT_Error IE_Exp_OpenXML::startCellBorderProperties(int target)
457 {
458 	return writeTargetStream(target, "<w:tcBorders>");
459 }
460 
461 /**
462  * Finishes exporting the OXML_Element_Cell's border properties
463  */
finishCellBorderProperties(int target)464 UT_Error IE_Exp_OpenXML::finishCellBorderProperties(int target)
465 {
466 	return writeTargetStream(target, "</w:tcBorders>");
467 }
468 
469 /**
470  * Starts exporting the OXML_Element_List properties
471  */
startListProperties(int target)472 UT_Error IE_Exp_OpenXML::startListProperties(int target)
473 {
474 	return writeTargetStream(target, "<w:numPr>");
475 }
476 
477 /**
478  * Finishes exporting the OXML_Element_List properties
479  */
finishListProperties(int target)480 UT_Error IE_Exp_OpenXML::finishListProperties(int target)
481 {
482 	return writeTargetStream(target, "</w:numPr>");
483 }
484 
485 /**
486  * Starts exporting the OXML_List abstract numbering
487  */
startAbstractNumbering(int target,UT_uint32 id)488 UT_Error IE_Exp_OpenXML::startAbstractNumbering(int target, UT_uint32 id)
489 {
490 	char buffer[12];
491 	int len = snprintf(buffer, 12, "%d", id);
492 	if(len <= 0)
493 		return UT_IE_COULDNOTWRITE;
494 
495 	std::string str("<w:abstractNum w:abstractNumId=\"");
496 	str += buffer;
497 	str += "\">";
498 	return writeTargetStream(target, str.c_str());
499 }
500 
501 /**
502  * Finishes exporting the OXML_List abstract numbering
503  */
finishAbstractNumbering(int target)504 UT_Error IE_Exp_OpenXML::finishAbstractNumbering(int target)
505 {
506 	return writeTargetStream(target, "</w:abstractNum>");
507 }
508 
509 /**
510  * Starts exporting the OXML_List numbering
511  */
startNumbering(int target,UT_uint32 id)512 UT_Error IE_Exp_OpenXML::startNumbering(int target, UT_uint32 id)
513 {
514 	char buffer[12];
515 	int len = snprintf(buffer, 12, "%d", id);
516 	if(len <= 0)
517 		return UT_IE_COULDNOTWRITE;
518 
519 	std::string str("<w:num w:numId=\"");
520 	str += buffer;
521 	str += "\">";
522 	return writeTargetStream(target, str.c_str());
523 }
524 
525 /**
526  * Finishes exporting the OXML_List numbering definition
527  */
finishNumbering(int target)528 UT_Error IE_Exp_OpenXML::finishNumbering(int target)
529 {
530 	return writeTargetStream(target, "</w:num>");
531 }
532 
533 /**
534  * Starts exporting the OXML_List abstract numbering level
535  */
startNumberingLevel(int target,UT_uint32 id)536 UT_Error IE_Exp_OpenXML::startNumberingLevel(int target, UT_uint32 id)
537 {
538 	char buffer[12];
539 	int len = snprintf(buffer, 12, "%d", id);
540 	if(len <= 0)
541 		return UT_IE_COULDNOTWRITE;
542 
543 	std::string str("<w:lvl w:ilvl=\"");
544 	str += buffer;
545 	str += "\">";
546 	return writeTargetStream(target, str.c_str());
547 }
548 
549 /**
550  * Finishes exporting the OXML_List abstract numbering level
551  */
finishNumberingLevel(int target)552 UT_Error IE_Exp_OpenXML::finishNumberingLevel(int target)
553 {
554 	return writeTargetStream(target, "</w:lvl>");
555 }
556 
557 /**
558  * Starts exporting the OXML_Element_Row object
559  */
startRow()560 UT_Error IE_Exp_OpenXML::startRow()
561 {
562 	return writeTargetStream(TARGET_DOCUMENT, "<w:tr>");
563 }
564 
565 /**
566  * Finishes exporting the OXML_Element_Row object
567  */
finishRow()568 UT_Error IE_Exp_OpenXML::finishRow()
569 {
570 	return writeTargetStream(TARGET_DOCUMENT, "</w:tr>");
571 }
572 
573 /**
574  * Starts exporting the OXML_Element_Cell object
575  */
startCell()576 UT_Error IE_Exp_OpenXML::startCell()
577 {
578 	return writeTargetStream(TARGET_DOCUMENT, "<w:tc>");
579 }
580 
581 /**
582  * Finishes exporting the OXML_Element_Cell object
583  */
finishCell()584 UT_Error IE_Exp_OpenXML::finishCell()
585 {
586 	return writeTargetStream(TARGET_DOCUMENT, "</w:tc>");
587 }
588 
589 /**
590  * Starts exporting the OXML_Element_Cell object's properties
591  */
startCellProperties(int target)592 UT_Error IE_Exp_OpenXML::startCellProperties(int target)
593 {
594 	return writeTargetStream(target, "<w:tcPr>");
595 }
596 
597 /**
598  * Finishes exporting the OXML_Element_Cell object's properties
599  */
finishCellProperties(int target)600 UT_Error IE_Exp_OpenXML::finishCellProperties(int target)
601 {
602 	return writeTargetStream(target, "</w:tcPr>");
603 }
604 
605 /**
606  * Starts exporting the OXML_Element_Hyperlink object
607  */
startExternalHyperlink(const gchar * id)608 UT_Error IE_Exp_OpenXML::startExternalHyperlink(const gchar* id)
609 {
610 	std::string str("<w:hyperlink r:id=\"");
611 	str += id;
612 	str += "\">";
613 	return writeTargetStream(TARGET_DOCUMENT, str.c_str());
614 }
615 
616 /**
617  * Starts exporting the OXML_Element_Hyperlink object
618  */
startInternalHyperlink(const gchar * anchor)619 UT_Error IE_Exp_OpenXML::startInternalHyperlink(const gchar* anchor)
620 {
621 	UT_UTF8String sEscAnchor = anchor;
622 	sEscAnchor.escapeXML();
623 
624 	std::string str("<w:hyperlink w:anchor=\"");
625 	str += sEscAnchor.utf8_str();
626 	str += "\">";
627 	return writeTargetStream(TARGET_DOCUMENT, str.c_str());
628 }
629 
630 /**
631  * Finishes exporting the OXML_Element_Hyperlink object
632  */
finishHyperlink()633 UT_Error IE_Exp_OpenXML::finishHyperlink()
634 {
635 	return writeTargetStream(TARGET_DOCUMENT, "</w:hyperlink>");
636 }
637 
638 /**
639  * Exports the OXML_Element_BookmarkStart object
640  */
startBookmark(const gchar * id,const gchar * name)641 UT_Error IE_Exp_OpenXML::startBookmark(const gchar* id, const gchar* name)
642 {
643 	UT_UTF8String sEscName = name;
644 	sEscName.escapeXML();
645 
646 	std::string str("<w:bookmarkStart w:id=\"");
647 	str += id;
648 	str += "\" ";
649 	str += "w:name=\"";
650 	str += sEscName.utf8_str();
651 	str += "\"/>";
652 	return writeTargetStream(TARGET_DOCUMENT, str.c_str());
653 }
654 
655 /**
656  * Exports the OXML_Element_BookmarkFinish object
657  */
finishBookmark(const gchar * id)658 UT_Error IE_Exp_OpenXML::finishBookmark(const gchar* id)
659 {
660 	std::string str("<w:bookmarkEnd w:id=\"");
661 	str += id;
662 	str += "\"/>";
663 	return writeTargetStream(TARGET_DOCUMENT, str.c_str());
664 }
665 
666 /**
667  * Starts exporting the OXML_Element_TextBox object
668  */
startTextBox(int target,const gchar * id)669 UT_Error IE_Exp_OpenXML::startTextBox(int target, const gchar* id)
670 {
671 	std::string str("");
672 	str += "<w:pict>";
673 	str += "<v:shape w:id=\"";
674 	str += id;
675 	str += "\" ";
676 	return writeTargetStream(target, str.c_str());
677 }
678 
679 /**
680  * Finishes exporting the OXML_Element_TextBox object
681  */
finishTextBox(int target)682 UT_Error IE_Exp_OpenXML::finishTextBox(int target)
683 {
684 	std::string str("");
685 	str += "</v:shape>";
686 	str += "</w:pict>";
687 	return writeTargetStream(target, str.c_str());
688 }
689 
690 /**
691  * Starts exporting the OXML_Element_TextBox object's properties
692  */
startTextBoxProperties(int target)693 UT_Error IE_Exp_OpenXML::startTextBoxProperties(int target)
694 {
695 	std::string str("");
696 	str += "style=\"";
697 	return writeTargetStream(target, str.c_str());
698 }
699 
700 /**
701  * Finishes exporting the OXML_Element_TextBox object's properties
702  */
finishTextBoxProperties(int target)703 UT_Error IE_Exp_OpenXML::finishTextBoxProperties(int target)
704 {
705 	std::string str("");
706 	str += "\">";
707 	return writeTargetStream(target, str.c_str());
708 }
709 
710 /**
711  * Starts exporting the OXML_Element_TextBox object's content
712  */
startTextBoxContent(int target)713 UT_Error IE_Exp_OpenXML::startTextBoxContent(int target)
714 {
715 	std::string str("<v:textbox>");
716 	str += "<w:txbxContent>";
717 	return writeTargetStream(target, str.c_str());
718 }
719 
720 /**
721  * Finishes exporting the OXML_Element_TextBox object's content
722  */
finishTextBoxContent(int target)723 UT_Error IE_Exp_OpenXML::finishTextBoxContent(int target)
724 {
725 	std::string str("</w:txbxContent>");
726 	str += "</v:textbox>";
727 	return writeTargetStream(target, str.c_str());
728 }
729 
730 /**
731  * Sets textbox width
732  */
setTextBoxWidth(int target,const gchar * width)733 UT_Error IE_Exp_OpenXML::setTextBoxWidth(int target, const gchar* width)
734 {
735 	std::string str("width:");
736 	str += convertToPoints(width);
737 	str += "pt;";
738 	return writeTargetStream(target, str.c_str());
739 }
740 
741 /**
742  * Sets textbox height
743  */
setTextBoxHeight(int target,const gchar * height)744 UT_Error IE_Exp_OpenXML::setTextBoxHeight(int target, const gchar* height)
745 {
746 	std::string str("height:");
747 	str += convertToPoints(height);
748 	str += "pt;";
749 	return writeTargetStream(target, str.c_str());
750 }
751 
752 /**
753  * Writes to the target stream
754  */
writeTargetStream(int target,const char * str)755 UT_Error IE_Exp_OpenXML::writeTargetStream(int target, const char* str)
756 {
757 	if(!str)
758 		return UT_IE_COULDNOTWRITE;
759 
760 	if(!gsf_output_puts(getTargetStream(target), str))
761 	{
762 		UT_DEBUGMSG(("FRT: ERROR, cannot write string %s to target stream %d\n", str, target));
763 		return UT_IE_COULDNOTWRITE;
764 	}
765 	return UT_OK;
766 }
767 
768 /**
769  * Retrieves the target stream
770  */
getTargetStream(int target)771 GsfOutput* IE_Exp_OpenXML::getTargetStream(int target)
772 {
773 	switch(target)
774 	{
775 		case TARGET_STYLES:
776 			return stylesStream;
777 		case TARGET_DOCUMENT:
778 			return documentStream;
779 		case TARGET_DOCUMENT_RELATION:
780 			return wordRelStream;
781 		case TARGET_RELATION:
782 			return relStream;
783 		case TARGET_CONTENT:
784 			return contentTypesStream;
785 		case TARGET_NUMBERING:
786 			return numberingStream;
787 		case TARGET_HEADER:
788 			return headerStream;
789 		case TARGET_FOOTER:
790 			return footerStream;
791 		case TARGET_SETTINGS:
792 			return settingsStream;
793 		case TARGET_FOOTNOTE:
794 			return footnoteStream;
795 		case TARGET_ENDNOTE:
796 			return endnoteStream;
797 		default:
798 			UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN);
799 			return documentStream;
800 	}
801 }
802 
803 /**
804  * Sets bold style
805  */
setBold(int target)806 UT_Error IE_Exp_OpenXML::setBold(int target)
807 {
808 	return writeTargetStream(target, "<w:b/>");
809 }
810 
811 /**
812  * Sets italic style
813  */
setItalic(int target)814 UT_Error IE_Exp_OpenXML::setItalic(int target)
815 {
816 	return writeTargetStream(target, "<w:i/>");
817 }
818 
819 /**
820  * Sets underline style
821  */
setUnderline(int target)822 UT_Error IE_Exp_OpenXML::setUnderline(int target)
823 {
824 	return writeTargetStream(target, "<w:u w:val=\"single\"/>");
825 }
826 
827 /**
828  * Sets overline style
829  */
setOverline()830 UT_Error IE_Exp_OpenXML::setOverline()
831 {
832 	isOverline = true;
833 	return UT_OK;
834 }
835 
836 /**
837  * Sets line-through style
838  */
setLineThrough(int target)839 UT_Error IE_Exp_OpenXML::setLineThrough(int target)
840 {
841 	return writeTargetStream(target, "<w:strike/>");
842 }
843 
844 /**
845  * Sets superscript style
846  */
setSuperscript(int target)847 UT_Error IE_Exp_OpenXML::setSuperscript(int target)
848 {
849 	return writeTargetStream(target, "<w:vertAlign w:val=\"superscript\"/>");
850 }
851 
852 /**
853  * Sets subscript style
854  */
setSubscript(int target)855 UT_Error IE_Exp_OpenXML::setSubscript(int target)
856 {
857 	return writeTargetStream(target, "<w:vertAlign w:val=\"subscript\"/>");
858 }
859 
860 /**
861  * Sets text color style
862  */
setTextColor(int target,const gchar * color)863 UT_Error IE_Exp_OpenXML::setTextColor(int target, const gchar* color)
864 {
865 	std::string str("<w:color w:val=\"");
866 	str += UT_colorToHex(color);
867 	str += "\"/>";
868 	return writeTargetStream(target, str.c_str());
869 }
870 
871 /**
872  * Sets background color style
873  */
setBackgroundColor(int target,const gchar * color)874 UT_Error IE_Exp_OpenXML::setBackgroundColor(int target, const gchar* color)
875 {
876 	std::string str("<w:shd w:fill=\"");
877 	str += UT_colorToHex(color);
878 	str += "\"/>";
879 	return writeTargetStream(target, str.c_str());
880 }
881 
882 /**
883  * Sets font size
884  */
setFontSize(int target,const gchar * size)885 UT_Error IE_Exp_OpenXML::setFontSize(int target, const gchar* size)
886 {
887 	std::string str("<w:sz w:val=\"");
888 	str += computeFontSize(size);
889 	str += "\"/>";
890 	return writeTargetStream(target, str.c_str());
891 }
892 
893 /**
894  * Sets font family
895  */
setFontFamily(int target,const gchar * family)896 UT_Error IE_Exp_OpenXML::setFontFamily(int target, const gchar* family)
897 {
898 	UT_UTF8String sEscFamily = family;
899 	sEscFamily.escapeXML();
900 
901 	std::string str("<w:rFonts w:ascii=\"");
902 	str += sEscFamily.utf8_str();
903 	str += "\" w:cs=\"";
904 	str += sEscFamily.utf8_str();
905 	str += "\" w:hAnsi=\"";
906 	str += sEscFamily.utf8_str();
907 	str += "\"/>";
908 	return writeTargetStream(target, str.c_str());
909 }
910 
911 /**
912  * Sets language
913  */
setLanguage(int target,const gchar * lang)914 UT_Error IE_Exp_OpenXML::setLanguage(int target, const gchar* lang)
915 {
916 	UT_UTF8String sEscLang = lang;
917 	sEscLang.escapeXML();
918 
919 	std::string str("<w:lang w:val=\"");
920 	str += sEscLang.utf8_str();
921 	str += "\"/>";
922 	return writeTargetStream(target, str.c_str());
923 }
924 
925 /**
926  * Sets no proof
927  */
setNoProof(int target)928 UT_Error IE_Exp_OpenXML::setNoProof(int target)
929 {
930 	return writeTargetStream(target, "<w:noProof/>");
931 }
932 
933 /**
934  * Sets text direction, eg. right-to-left
935  */
setTextDirection(int target,const gchar * direction)936 UT_Error IE_Exp_OpenXML::setTextDirection(int target, const gchar* direction)
937 {
938 	std::string str(direction);
939 	if(str.compare("rtl") == 0)
940 		return writeTargetStream(target, "<w:rtl v:val=\"on\"/>");
941 	else if(str.compare("ltr") == 0)
942 		return writeTargetStream(target, "<w:rtl v:val=\"off\"/>");
943 	return UT_OK;
944 }
945 
946 /**
947  * Sets the widows
948  */
setWidows(int target,const gchar * widows)949 UT_Error IE_Exp_OpenXML::setWidows(int target, const gchar* widows)
950 {
951 	UT_sint32 wdws = atoi(widows);
952 	if(wdws > 0)
953 		return writeTargetStream(target, "<w:widowControl w:val=\"on\"/>");
954 	return UT_OK;
955 }
956 
957 /**
958  * Sets text alignment
959  */
setTextAlignment(int target,const gchar * alignment)960 UT_Error IE_Exp_OpenXML::setTextAlignment(int target, const gchar* alignment)
961 {
962 	std::string str("<w:jc w:val=\"");
963 	str += alignment;
964 	str += "\"/>";
965 	return writeTargetStream(target, str.c_str());
966 }
967 
968 /**
969  * Sets the paragraph style
970  */
setParagraphStyle(int target,const gchar * style)971 UT_Error IE_Exp_OpenXML::setParagraphStyle(int target, const gchar* style)
972 {
973 	UT_UTF8String sEscStyle = style;
974 	sEscStyle.escapeXML();
975 
976 	std::string str("<w:pStyle w:val=\"");
977 	str += sEscStyle.utf8_str();
978 	str += "\"/>";
979 	return writeTargetStream(target, str.c_str());
980 }
981 
982 /**
983  * Sets text indentation
984  */
setTextIndentation(int target,const gchar * indentation)985 UT_Error IE_Exp_OpenXML::setTextIndentation(int target, const gchar* indentation)
986 {
987 	const gchar* twips = convertToPositiveTwips(indentation);
988 	if(!twips)
989 		return UT_OK;
990 
991 	std::string str("<w:ind ");
992 
993 	if(isNegativeQuantity(indentation))
994 		str += "w:hanging=\"";
995 	else
996 		str += "w:firstLine=\"";
997 
998 	str += twips;
999 	str += "\"/>";
1000 	return writeTargetStream(target, str.c_str());
1001 }
1002 
1003 /**
1004  * Sets paragraph left margin
1005  */
setParagraphLeftMargin(int target,const gchar * margin)1006 UT_Error IE_Exp_OpenXML::setParagraphLeftMargin(int target, const gchar* margin)
1007 {
1008 	const gchar* twips = convertToTwips(margin);
1009 	if(!twips)
1010 		return UT_OK;
1011 
1012 	std::string str("<w:ind w:left=\"");
1013 	str += twips;
1014 	str += "\"/>";
1015 	return writeTargetStream(target, str.c_str());
1016 }
1017 
1018 /**
1019  * Sets paragraph right margin
1020  */
setParagraphRightMargin(int target,const gchar * margin)1021 UT_Error IE_Exp_OpenXML::setParagraphRightMargin(int target, const gchar* margin)
1022 {
1023 	const gchar* twips = convertToTwips(margin);
1024 	if(!twips)
1025 		return UT_OK;
1026 
1027 	std::string str("<w:ind w:right=\"");
1028 	str += twips;
1029 	str += "\"/>";
1030 	return writeTargetStream(target, str.c_str());
1031 }
1032 
1033 /**
1034  * Sets paragraph top margin
1035  */
setParagraphTopMargin(int target,const gchar * margin)1036 UT_Error IE_Exp_OpenXML::setParagraphTopMargin(int target, const gchar* margin)
1037 {
1038 	const gchar* twips = convertToPositiveTwips(margin);
1039 	if(!twips)
1040 		return UT_OK;
1041 
1042 	std::string str("<w:spacing w:before=\"");
1043 	str += twips;
1044 	str += "\"/>";
1045 	return writeTargetStream(target, str.c_str());
1046 }
1047 
1048 /**
1049  * Sets the necessary relationship for hyperlink target address
1050  */
setHyperlinkRelation(int target,const char * id,const char * addr,const char * mode)1051 UT_Error IE_Exp_OpenXML::setHyperlinkRelation(int target, const char* id, const char* addr, const char* mode)
1052 {
1053 	UT_UTF8String sEscAddr = addr;
1054 	sEscAddr.escapeURL();
1055 
1056 	std::string str("<Relationship Id=\"");
1057 	str += id;
1058 	str += "\" ";
1059 	str += "Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink\" ";
1060 	str += "Target=\"";
1061 	str += sEscAddr.utf8_str();
1062 	str += "\" ";
1063 	str += "TargetMode=\"";
1064 	str += mode;
1065 	str += "\"/>";
1066 	return writeTargetStream(target, str.c_str());
1067 }
1068 
1069 /**
1070  * Sets the necessary relationships for header
1071  */
setHeaderRelation(const char * relId,const char * headerId)1072 UT_Error IE_Exp_OpenXML::setHeaderRelation(const char* relId, const char* headerId)
1073 {
1074 	UT_Error err = UT_OK;
1075 
1076 	std::string str("<Relationship Id=\"");
1077 	str += relId;
1078 	str += "\" ";
1079 	str += "Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/header\" ";
1080 	str += "Target=\"header";
1081 	str += headerId;
1082 	str += ".xml\"/>";
1083 
1084 	err = writeTargetStream(TARGET_DOCUMENT_RELATION, str.c_str());
1085 	if(err != UT_OK)
1086 		return err;
1087 
1088 	str = "";
1089 	str += "<Override PartName=\"/word/header";
1090 	str += headerId;
1091 	str += ".xml\" ";
1092 	str += "ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml\"/>";
1093 
1094 	return writeTargetStream(TARGET_CONTENT, str.c_str());
1095 }
1096 
1097 /**
1098  * Sets the titlePg tag for the first page headers/footers
1099  */
setTitlePage()1100 UT_Error IE_Exp_OpenXML::setTitlePage()
1101 {
1102 	return writeTargetStream(TARGET_DOCUMENT, "<w:titlePg/>");
1103 }
1104 
1105 /**
1106  * Sets the evenAndOddHeaders tag for the even/odd page headers/footers
1107  */
setEvenAndOddHeaders()1108 UT_Error IE_Exp_OpenXML::setEvenAndOddHeaders()
1109 {
1110 	return writeTargetStream(TARGET_SETTINGS, "<w:evenAndOddHeaders/>");
1111 }
1112 
1113 /**
1114  * Sets the necessary relationship for footer
1115  */
setFooterRelation(const char * relId,const char * footerId)1116 UT_Error IE_Exp_OpenXML::setFooterRelation(const char* relId, const char* footerId)
1117 {
1118 	UT_Error err = UT_OK;
1119 
1120 	std::string str("<Relationship Id=\"");
1121 	str += relId;
1122 	str += "\" ";
1123 	str += "Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer\" ";
1124 	str += "Target=\"footer";
1125 	str += footerId;
1126 	str += ".xml\"/>";
1127 
1128 	err = writeTargetStream(TARGET_DOCUMENT_RELATION, str.c_str());
1129 	if(err != UT_OK)
1130 		return err;
1131 
1132 	str = "";
1133 	str += "<Override PartName=\"/word/footer";
1134 	str += footerId;
1135 	str += ".xml\" ";
1136 	str += "ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml\"/>";
1137 
1138 	return writeTargetStream(TARGET_CONTENT, str.c_str());
1139 }
1140 
1141 /**
1142  * Sets paragraph bottom margin
1143  */
setParagraphBottomMargin(int target,const gchar * margin)1144 UT_Error IE_Exp_OpenXML::setParagraphBottomMargin(int target, const gchar* margin)
1145 {
1146 	const gchar* twips = convertToPositiveTwips(margin);
1147 	if(!twips)
1148 		return UT_OK;
1149 
1150 	std::string str("<w:spacing w:after=\"");
1151 	str += twips;
1152 	str += "\"/>";
1153 	return writeTargetStream(target, str.c_str());
1154 }
1155 
1156 /**
1157  * Sets line height
1158  */
setLineHeight(int target,const gchar * height)1159 UT_Error IE_Exp_OpenXML::setLineHeight(int target, const gchar* height)
1160 {
1161 	const gchar* twips = NULL;
1162 	const gchar* lineRule = NULL;
1163 
1164 	if(strstr(height, "pt+"))
1165 	{
1166 		lineRule = "atLeast";
1167 		std::string h(height);
1168 		h.resize(h.length()-1); //get rid of '+' char
1169 		twips = convertToTwips(h.c_str());
1170 	}
1171 	else if(strstr(height, "pt"))
1172 	{
1173 		lineRule = "exact";
1174 		twips = convertToTwips(height);
1175 	}
1176 	else
1177 	{
1178 		lineRule = "auto";
1179 		twips = convertToLines(height);
1180 	}
1181 
1182 	if(!twips)
1183 		return UT_OK;
1184 
1185 	std::string str("<w:spacing w:line=\"");
1186 	str += twips;
1187 	str += "\" w:lineRule=\"";
1188 	str += lineRule;
1189 	str += "\"/>";
1190 	return writeTargetStream(target, str.c_str());
1191 }
1192 
1193 /**
1194  * Sets tab stops
1195  */
setTabstops(int target,const gchar * tabstops)1196 UT_Error IE_Exp_OpenXML::setTabstops(int target, const gchar* tabstops)
1197 {
1198 	std::string tabs("<w:tabs>");
1199 
1200 	std::string str("");
1201 	str += tabstops;
1202 	str += ",";
1203 
1204 	std::string::size_type prev = -1;
1205 	std::string::size_type pos = str.find_first_of(",");
1206 
1207 	while (pos != std::string::npos)
1208 	{
1209 		std::string token("");
1210 		token = str.substr(prev+1, pos-prev-1);
1211 
1212 		std::string::size_type typePos = token.find_first_of("/");
1213 
1214 		if(typePos != std::string::npos)
1215 		{
1216 			std::string tabStopType = token.substr(typePos+1, 1);
1217 			std::string type = token.substr(typePos+2, token.length()-1);
1218 			token = token.substr(0, typePos);
1219 
1220 			if(strstr(tabStopType.c_str(), "L"))
1221 				tabs += "<w:tab w:val=\"left\" ";
1222 			else if(strstr(tabStopType.c_str(), "R"))
1223 				tabs += "<w:tab w:val=\"right\" ";
1224 			else if(strstr(tabStopType.c_str(), "C"))
1225 				tabs += "<w:tab w:val=\"center\" ";
1226 			else if(strstr(tabStopType.c_str(), "D"))
1227 				tabs += "<w:tab w:val=\"decimal\" ";
1228 			else if(strstr(tabStopType.c_str(), "B"))
1229 				tabs += "<w:tab w:val=\"bar\" ";
1230 			else
1231 				tabs += "<w:tab w:val=\"clear\" ";
1232 
1233 
1234 			if(strstr(type.c_str(), "3"))
1235 				tabs += "w:leader=\"underscore\" ";
1236 			else if(strstr(type.c_str(), "1"))
1237 				tabs += "w:leader=\"dot\" ";
1238 			else if(strstr(type.c_str(), "2"))
1239 				tabs += "w:leader=\"hyphen\" ";
1240 
1241 			tabs += "w:pos=\"";
1242 			tabs += convertToPositiveTwips(token.c_str());
1243 			tabs += "\"/>";
1244 		}
1245 
1246 		prev = pos;
1247 		pos = str.find_first_of(",", pos + 1);
1248 	}
1249 
1250 	tabs += "</w:tabs>";
1251 
1252 	return writeTargetStream(target, tabs.c_str());
1253 }
1254 
1255 /**
1256  * Sets the columns for the section
1257  */
setColumns(int target,const gchar * num,const gchar * sep)1258 UT_Error IE_Exp_OpenXML::setColumns(int target, const gchar* num, const gchar* sep)
1259 {
1260 	if(UT_convertDimensionless(num) <= 0)
1261 		return UT_OK;
1262 
1263 	if((strcmp(sep, "on") != 0) && (strcmp(sep, "off") != 0))
1264 	{
1265 		// this code should never be reached due to the string checks in
1266 		// OXML_Section::serializeProperties()
1267 		UT_ASSERT_NOT_REACHED();
1268 		return UT_OK;
1269 	}
1270 
1271 	std::string str("");
1272 	str += "<w:cols ";
1273 	str += "w:num=\"";
1274 	str += num;
1275 	str += "\" ";
1276 	str += "w:sep=\"";
1277 	str += sep;
1278 	str += "\" ";
1279 	str += "w:equalWidth=\"1\"/>";
1280 
1281 	return writeTargetStream(target, str.c_str());
1282 }
1283 
1284 /**
1285  * Sets the section type continuous
1286  */
setContinuousSection(int target)1287 UT_Error IE_Exp_OpenXML::setContinuousSection(int target)
1288 {
1289 	std::string str("");
1290 	str += "<w:type w:val=\"continuous\"/>";
1291 	return writeTargetStream(target, str.c_str());
1292 }
1293 
1294 /**
1295  * Sets grid span for horizontally merged cells
1296  */
setGridSpan(int target,UT_sint32 hspan)1297 UT_Error IE_Exp_OpenXML::setGridSpan(int target, UT_sint32 hspan)
1298 {
1299 	char buffer[12];
1300 	int len = snprintf(buffer, 12, "%d", hspan);
1301 	if(len <= 0)
1302 		return UT_IE_COULDNOTWRITE;
1303 	std::string str("<w:gridSpan w:val=\"");
1304 	str += buffer;
1305 	str += "\"/>";
1306 	return writeTargetStream(target, str.c_str());
1307 }
1308 
1309 /**
1310  * Sets vertical merge feature for vertically merged cells
1311  */
setVerticalMerge(int target,const char * vmerge)1312 UT_Error IE_Exp_OpenXML::setVerticalMerge(int target, const char* vmerge)
1313 {
1314 	std::string str("<w:vMerge w:val=\"");
1315 	str += vmerge;
1316 	str += "\"/>";
1317 	return writeTargetStream(target, str.c_str());
1318 }
1319 
1320 
1321 /**
1322  * Sets page break
1323  */
setPageBreak(int target)1324 UT_Error IE_Exp_OpenXML::setPageBreak(int target)
1325 {
1326 	std::string str("<w:pageBreakBefore/>");
1327 	return writeTargetStream(target, str.c_str());
1328 }
1329 
1330 /**
1331  * Sets page size and orientation
1332  */
setPageSize(int target,const char * width,const char * height,const char * orientation)1333 UT_Error IE_Exp_OpenXML::setPageSize(int target, const char* width, const char* height, const char* orientation)
1334 {
1335 	std::string str("<w:pgSz w:w=\"");
1336 	str += width;
1337 	str += "\"";
1338 
1339 	str += " w:h=\"";
1340 	str += height;
1341 	str += "\"";
1342 
1343 	str += " w:orient=\"";
1344 	str += orientation;
1345 	str += "\"/>";
1346 
1347 	return writeTargetStream(target, str.c_str());
1348 }
1349 
1350 /**
1351  * Sets page margins
1352  */
setPageMargins(int target,const char * top,const char * left,const char * right,const char * bottom)1353 UT_Error IE_Exp_OpenXML::setPageMargins(int target, const char* top, const char* left, const char* right, const char* bottom)
1354 {
1355 	std::string str("<w:pgMar w:top=\"");
1356 	str += convertToTwips(top);
1357 	str += "\"";
1358 
1359 	str += " w:left=\"";
1360 	str += convertToTwips(left);
1361 	str += "\"";
1362 
1363 	str += " w:right=\"";
1364 	str += convertToTwips(right);
1365 	str += "\"";
1366 
1367 	str += " w:bottom=\"";
1368 	str += convertToTwips(bottom);
1369 	str += "\"/>";
1370 
1371 	return writeTargetStream(target, str.c_str());
1372 }
1373 
1374 /**
1375  * Sets table border style for the specified border in the table
1376  */
setTableBorder(int target,const char * border,const char * type,const char * color,const char * size)1377 UT_Error IE_Exp_OpenXML::setTableBorder(int target, const char* border, const char* type, const char* color, const char* size)
1378 {
1379 	UT_return_val_if_fail(type, UT_OK);
1380 
1381 	std::string str("<w:");
1382 	str += border;
1383 	str += " w:val=\"";
1384 	str += type;
1385 	str += "\"";
1386 
1387 	if(color)
1388 	{
1389 		str += " w:color=\"";
1390 		str += UT_colorToHex(color);
1391 		str += "\"";
1392 	}
1393 
1394 	if(size)
1395 	{
1396 		str += " w:sz=\"";
1397 		str += computeBorderWidth(size);
1398 		str += "\"";
1399 	}
1400 
1401 	str += "/>";
1402 	return writeTargetStream(target, str.c_str());
1403 }
1404 
1405 /**
1406  * Sets table row height to some exact value
1407  */
setRowHeight(int target,const char * height)1408 UT_Error IE_Exp_OpenXML::setRowHeight(int target, const char* height)
1409 {
1410 	std::string str("<w:trHeight w:val=\"");
1411 	str += convertToPositiveTwips(height);
1412 	str += "\" w:hRule=\"exact\"/>";
1413 	return writeTargetStream(target, str.c_str());
1414 }
1415 
1416 
1417 /**
1418  * Starts table grid
1419  */
startTableGrid(int target)1420 UT_Error IE_Exp_OpenXML::startTableGrid(int target)
1421 {
1422 	return writeTargetStream(target, "<w:tblGrid>");
1423 }
1424 
1425 /**
1426  * Finishes table grid
1427  */
finishTableGrid(int target)1428 UT_Error IE_Exp_OpenXML::finishTableGrid(int target)
1429 {
1430 	return writeTargetStream(target, "</w:tblGrid>");
1431 }
1432 
1433 /**
1434  * Starts table row properties
1435  */
startRowProperties(int target)1436 UT_Error IE_Exp_OpenXML::startRowProperties(int target)
1437 {
1438 	return writeTargetStream(target, "<w:trPr>");
1439 }
1440 
1441 /**
1442  * Finishes table row properties
1443  */
finishRowProperties(int target)1444 UT_Error IE_Exp_OpenXML::finishRowProperties(int target)
1445 {
1446 	return writeTargetStream(target, "</w:trPr>");
1447 }
1448 
1449 /**
1450  * Starts footnote
1451  */
startFootnote(const char * id)1452 UT_Error IE_Exp_OpenXML::startFootnote(const char* id)
1453 {
1454 	std::string str("<w:footnote w:id=\"");
1455 	str += id;
1456 	str += "\">";
1457 	return writeTargetStream(TARGET_FOOTNOTE, str.c_str());
1458 }
1459 
1460 /**
1461  * Finishes footnote
1462  */
finishFootnote()1463 UT_Error IE_Exp_OpenXML::finishFootnote()
1464 {
1465 	return writeTargetStream(TARGET_FOOTNOTE, "</w:footnote>");
1466 }
1467 
1468 /**
1469  * Starts endnote
1470  */
startEndnote(const char * id)1471 UT_Error IE_Exp_OpenXML::startEndnote(const char* id)
1472 {
1473 	std::string str("<w:endnote w:id=\"");
1474 	str += id;
1475 	str += "\">";
1476 	return writeTargetStream(TARGET_ENDNOTE, str.c_str());
1477 }
1478 
1479 /**
1480  * Finishes endnote
1481  */
finishEndnote()1482 UT_Error IE_Exp_OpenXML::finishEndnote()
1483 {
1484 	return writeTargetStream(TARGET_ENDNOTE, "</w:endnote>");
1485 }
1486 
1487 /**
1488  * Sets grid column
1489  */
setGridCol(int target,const char * column)1490 UT_Error IE_Exp_OpenXML::setGridCol(int target, const char* column)
1491 {
1492 	const gchar* twips = convertToPositiveTwips(column);
1493 	if(!twips || !*twips)
1494 		return UT_OK;
1495 
1496 	std::string str("");
1497 	str += "<w:gridCol w:w=\"";
1498 	str += twips;
1499 	str += "\"/>";
1500 	return writeTargetStream(target, str.c_str());
1501 }
1502 
1503 /**
1504  * Sets column width
1505  */
setColumnWidth(int target,const char * width)1506 UT_Error IE_Exp_OpenXML::setColumnWidth(int target, const char* width)
1507 {
1508 	const gchar* twips = convertToPositiveTwips(width);
1509 	if(!twips || !*twips)
1510 		return UT_OK;
1511 
1512 	std::string str("");
1513 	str += "<w:tcW w:w=\"";
1514 	str += twips;
1515 	str += "\" w:type=\"dxa\"/>";
1516 	return writeTargetStream(target, str.c_str());
1517 }
1518 
1519 /**
1520  * Sets list level
1521  */
setListLevel(int target,const char * level)1522 UT_Error IE_Exp_OpenXML::setListLevel(int target, const char* level)
1523 {
1524 	std::string str("<w:ilvl w:val=\"");
1525 	str += level;
1526 	str += "\"/>";
1527 	return writeTargetStream(target, str.c_str());
1528 }
1529 
1530 /**
1531  * Sets list format
1532  */
setListFormat(int target,const char * format)1533 UT_Error IE_Exp_OpenXML::setListFormat(int target, const char* format)
1534 {
1535 	std::string str("<w:numId w:val=\"");
1536 	str += format;
1537 	str += "\"/>";
1538 	return writeTargetStream(target, str.c_str());
1539 }
1540 
1541 /**
1542  * Sets list type
1543  */
setListType(int target,const char * type)1544 UT_Error IE_Exp_OpenXML::setListType(int target, const char* type)
1545 {
1546 	std::string str("<w:numFmt w:val=\"");
1547 	str += type;
1548 	str += "\"/>";
1549 	return writeTargetStream(target, str.c_str());
1550 }
1551 
1552 /**
1553  * Sets the start value of the list
1554  */
setListStartValue(int target,UT_uint32 startValue)1555 UT_Error IE_Exp_OpenXML::setListStartValue(int target, UT_uint32 startValue)
1556 {
1557 	char buffer[12];
1558 	int len = snprintf(buffer, 12, "%d", startValue);
1559 	if(len <= 0)
1560 		return UT_IE_COULDNOTWRITE;
1561 
1562 	std::string str("<w:start w:val=\"");
1563 	str += buffer;
1564 	str += "\"/>";
1565 	return writeTargetStream(target, str.c_str());
1566 }
1567 
1568 /**
1569  * Sets list level text
1570  */
setListLevelText(int target,const char * text)1571 UT_Error IE_Exp_OpenXML::setListLevelText(int target, const char* text)
1572 {
1573 	UT_UTF8String sEscText = text;
1574 	if(!isListBullet(text))
1575 		sEscText.escapeXML();
1576 
1577 	std::string str("<w:lvlText w:val=\"");
1578 	str += sEscText.utf8_str();
1579 	str += "\"/>";
1580 	return writeTargetStream(target, str.c_str());
1581 }
1582 
1583 /**
1584  * Checks whether given a string is a special list bullet symbol
1585  */
isListBullet(const char * str)1586 bool IE_Exp_OpenXML::isListBullet(const char* str)
1587 {
1588 	return !strcmp(str, BULLET) || !strcmp(str, SQUARE) || !strcmp(str, TRIANGLE) || !strcmp(str, TICK) || !strcmp(str, IMPLIES) ||
1589 			!strcmp(str, DIAMOND) || !strcmp(str, BOX) || !strcmp(str, HAND) || !strcmp(str, HEART) || !strcmp(str, DASH);
1590 }
1591 
1592 /**
1593  * Sets abstract numbering id
1594  */
setAbstractNumberingId(int target,UT_uint32 id)1595 UT_Error IE_Exp_OpenXML::setAbstractNumberingId(int target, UT_uint32 id)
1596 {
1597 	char buffer[12];
1598 	int len = snprintf(buffer, 12, "%d", id);
1599 	if(len <= 0)
1600 		return UT_IE_COULDNOTWRITE;
1601 
1602 	std::string str("<w:abstractNumId w:val=\"");
1603 	str += buffer;
1604 	str += "\"/>";
1605 	return writeTargetStream(target, str.c_str());
1606 }
1607 
1608 /**
1609  * Sets the numbering format of the list
1610  */
setNumberingFormat(int target,const char * format)1611 UT_Error IE_Exp_OpenXML::setNumberingFormat(int target, const char* format)
1612 {
1613 	std::string str("<w:numFmt w:val=\"");
1614 	str += format;
1615 	str += "\"/>";
1616 	return writeTargetStream(target, str.c_str());
1617 }
1618 
1619 /**
1620  * Sets the multilevel type of the list
1621  */
setMultilevelType(int target,const char * type)1622 UT_Error IE_Exp_OpenXML::setMultilevelType(int target, const char* type)
1623 {
1624 	std::string str("<w:multiLevelType w:val=\"");
1625 	str += type;
1626 	str += "\"/>";
1627 	return writeTargetStream(target, str.c_str());
1628 }
1629 
1630 /**
1631  * Sets the inline image
1632  */
setImage(const char * id,const char * relId,const char * filename,const char * width,const char * height)1633 UT_Error IE_Exp_OpenXML::setImage(const char* id, const char* relId, const char* filename, const char* width, const char* height)
1634 {
1635 	std::string str("");
1636 	std::string h("");
1637 	std::string w("");
1638 
1639 	h += convertToPositiveEmus(height);
1640 	w += convertToPositiveEmus(width);
1641 
1642 	str += "<w:drawing>";
1643 	str += "<wp:inline distT=\"0\" distB=\"0\" distL=\"0\" distR=\"0\">";
1644 	str += "<wp:extent cx=\"";
1645 	str += w;
1646 	str += "\" cy=\"";
1647 	str += h;
1648 	str += "\"/>";
1649 	str += "<wp:docPr id=\"";
1650 	str += id;
1651 	str += "\" name=\"";
1652 	str += filename;
1653 	str += "\"/>";
1654 	str += "<a:graphic>";
1655 	str += "<a:graphicData uri=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">";
1656 	str += "<pic:pic>";
1657 	str += "<pic:nvPicPr>";
1658 	str += "<pic:cNvPr id=\"";
1659 	str += id;
1660 	str += "\" name=\"";
1661 	str += filename;
1662 	str += "\"/>";
1663 	str += "<pic:cNvPicPr/>";
1664 	str += "</pic:nvPicPr>";
1665 	str += "<pic:blipFill>";
1666 	str += "<a:blip r:embed=\"";
1667 	str += relId;
1668 	str += "\"/>";
1669 	str += "</pic:blipFill>";
1670 	str += "<pic:spPr>";
1671 	str += "<a:xfrm>";
1672 	str += "<a:off x=\"0\" y=\"0\"/>";
1673 	str += "<a:ext cx=\"";
1674 	str += w;
1675 	str += "\" cy=\"";
1676 	str += h;
1677 	str += "\"/>";
1678 	str += "</a:xfrm>";
1679 	str += "<a:prstGeom prst=\"rect\">";
1680 	str += "<a:avLst/>";
1681 	str += "</a:prstGeom>";
1682 	str += "</pic:spPr>";
1683 	str += "</pic:pic>";
1684 	str += "</a:graphicData>";
1685 	str += "</a:graphic>";
1686 	str += "</wp:inline>";
1687 	str += "</w:drawing>";
1688 
1689 	return writeTargetStream(TARGET_DOCUMENT, str.c_str());
1690 }
1691 
1692 /**
1693  * Sets the positioned image
1694  */
setPositionedImage(const char * id,const char * relId,const char * filename,const char * width,const char * height,const char * xpos,const char * ypos,const char * wrapMode)1695 UT_Error IE_Exp_OpenXML::setPositionedImage(const char* id, const char* relId, const char* filename, const char* width, const char* height, const char* xpos, const char* ypos, const char* wrapMode)
1696 {
1697 	std::string str("");
1698 	std::string h("");
1699 	std::string w("");
1700 	std::string x("");
1701 	std::string y("");
1702 	std::string wm("bothSides"); // default wrap mode
1703 
1704 	if(!strcmp(wrapMode, "wrapped-to-right"))
1705 	{
1706 		wm = "right";
1707 	}
1708 	else if(!strcmp(wrapMode, "wrapped-to-left"))
1709 	{
1710 		wm = "left";
1711 	}
1712 
1713 	h += convertToPositiveEmus(height);
1714 	w += convertToPositiveEmus(width);
1715 	x += convertToPositiveEmus(xpos);
1716 	y += convertToPositiveEmus(ypos);
1717 
1718 	str += "<w:drawing>";
1719 	str += "<wp:anchor distT=\"0\" distB=\"0\" distL=\"0\" distR=\"0\" simplePos=\"0\" allowOverlap=\"0\" layoutInCell=\"1\" locked=\"0\" behindDoc=\"0\" relativeHeight=\"0\">";
1720 	str += "<wp:simplePos x=\"0\" y=\"0\"/>";
1721 	str += "<wp:positionH relativeFrom=\"column\">";
1722 	str += "<wp:posOffset>";
1723 	str += x;
1724 	str += "</wp:posOffset>";
1725 	str += "</wp:positionH>";
1726 	str += "<wp:positionV relativeFrom=\"paragraph\">";
1727 	str += "<wp:posOffset>";
1728 	str += y;
1729 	str += "</wp:posOffset>";
1730 	str += "</wp:positionV>";
1731 	str += "<wp:extent cx=\"";
1732 	str += w;
1733 	str += "\" cy=\"";
1734 	str += h;
1735 	str += "\"/>";
1736 	str += "<wp:effectExtent l=\"0\" t=\"0\" r=\"0\" b=\"0\"/>";
1737 	str += "<wp:wrapSquare wrapText=\"";
1738 	str += wm;
1739 	str += "\"/>";
1740 	str += "<wp:docPr id=\"";
1741 	str += id;
1742 	str += "\" name=\"";
1743 	str += filename;
1744 	str += "\"/>";
1745 	str += "<wp:cNvGraphicFramePr>";
1746 	str += "<a:graphicFrameLocks noChangeAspect=\"1\"/>";
1747 	str += "</wp:cNvGraphicFramePr>";
1748 	str += "<a:graphic>";
1749 	str += "<a:graphicData uri=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">";
1750 	str += "<pic:pic>";
1751 	str += "<pic:nvPicPr>";
1752 	str += "<pic:cNvPr id=\"";
1753 	str += id;
1754 	str += "\" name=\"";
1755 	str += filename;
1756 	str += "\"/>";
1757 	str += "<pic:cNvPicPr/>";
1758 	str += "</pic:nvPicPr>";
1759 	str += "<pic:blipFill>";
1760 	str += "<a:blip r:embed=\"";
1761 	str += relId;
1762 	str += "\"/>";
1763 	str += "</pic:blipFill>";
1764 	str += "<pic:spPr>";
1765 	str += "<a:xfrm>";
1766 	str += "<a:off x=\"0\" y=\"0\"/>";
1767 	str += "<a:ext cx=\"";
1768 	str += w;
1769 	str += "\" cy=\"";
1770 	str += h;
1771 	str += "\"/>";
1772 	str += "</a:xfrm>";
1773 	str += "<a:prstGeom prst=\"rect\">";
1774 	str += "<a:avLst/>";
1775 	str += "</a:prstGeom>";
1776 	str += "</pic:spPr>";
1777 	str += "</pic:pic>";
1778 	str += "</a:graphicData>";
1779 	str += "</a:graphic>";
1780 	str += "</wp:anchor>";
1781 	str += "</w:drawing>";
1782 
1783 	return writeTargetStream(TARGET_DOCUMENT, str.c_str());
1784 }
1785 
1786 /**
1787  * Sets the relation of the image
1788  */
setImageRelation(const char * filename,const char * id)1789 UT_Error IE_Exp_OpenXML::setImageRelation(const char* filename, const char* id)
1790 {
1791 	std::string str("<Relationship Id=\"");
1792 	str += id;
1793 	str += "\" ";
1794 	str += "Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image\" ";
1795 	str += "Target=\"media/";
1796 	str += filename;
1797 	str += "\"/>";
1798 
1799 	return writeTargetStream(TARGET_DOCUMENT_RELATION, str.c_str());
1800 }
1801 
1802 /**
1803  * Sets the simple field
1804  */
setSimpleField(int target,const char * instr,const char * value)1805 UT_Error IE_Exp_OpenXML::setSimpleField(int target, const char* instr, const char* value)
1806 {
1807 	UT_UTF8String sEscInstr = instr;
1808 	sEscInstr.escapeXML();
1809 	UT_UTF8String sEscValue = value;
1810 	sEscValue.escapeXML();
1811 
1812 	std::string str("");
1813 	str += "<w:fldSimple w:instr=\"";
1814 	str += sEscInstr.utf8_str();
1815 	str += "\">";
1816 	str += "<w:r>";
1817 	str += "<w:t>";
1818 	str += sEscValue.utf8_str();
1819 	str += "</w:t>";
1820 	str += "</w:r>";
1821 	str += "</w:fldSimple>";
1822 	return writeTargetStream(target, str.c_str());
1823 }
1824 
1825 /**
1826  * Set the header reference
1827  */
setHeaderReference(const char * id,const char * type)1828 UT_Error IE_Exp_OpenXML::setHeaderReference(const char* id, const char* type)
1829 {
1830 	std::string str("");
1831 	str += "<w:headerReference w:type=\"";
1832 	str += type;
1833 	str += "\" ";
1834 	str += "r:id=\"";
1835 	str += id;
1836 	str += "\"/>";
1837 	return writeTargetStream(TARGET_DOCUMENT, str.c_str());
1838 }
1839 
1840 /**
1841  * Set the footnote reference
1842  */
setFootnoteReference(const char * id)1843 UT_Error IE_Exp_OpenXML::setFootnoteReference(const char* id)
1844 {
1845 	std::string str("");
1846 	str += "<w:footnoteReference ";
1847 	str += "w:id=\"";
1848 	str += id;
1849 	str += "\"/>";
1850 	return writeTargetStream(TARGET_DOCUMENT, str.c_str());
1851 }
1852 
1853 /**
1854  * Set the footnoteRef tag
1855  */
setFootnoteRef()1856 UT_Error IE_Exp_OpenXML::setFootnoteRef()
1857 {
1858 	std::string str("");
1859 	str += "<w:footnoteRef/>";
1860 	return writeTargetStream(TARGET_FOOTNOTE, str.c_str());
1861 }
1862 
1863 /**
1864  * Set the endnote reference
1865  */
setEndnoteReference(const char * id)1866 UT_Error IE_Exp_OpenXML::setEndnoteReference(const char* id)
1867 {
1868 	std::string str("");
1869 	str += "<w:endnoteReference ";
1870 	str += "w:id=\"";
1871 	str += id;
1872 	str += "\"/>";
1873 	return writeTargetStream(TARGET_DOCUMENT, str.c_str());
1874 }
1875 
1876 /**
1877  * Set the endnoteRef tag
1878  */
setEndnoteRef()1879 UT_Error IE_Exp_OpenXML::setEndnoteRef()
1880 {
1881 	std::string str("");
1882 	str += "<w:endnoteRef/>";
1883 	return writeTargetStream(TARGET_ENDNOTE, str.c_str());
1884 }
1885 
1886 /**
1887  * Set the footer reference
1888  */
setFooterReference(const char * id,const char * type)1889 UT_Error IE_Exp_OpenXML::setFooterReference(const char* id, const char* type)
1890 {
1891 	std::string str("");
1892 	str += "<w:footerReference w:type=\"";
1893 	str += type;
1894 	str += "\" ";
1895 	str += "r:id=\"";
1896 	str += id;
1897 	str += "\"/>";
1898 	return writeTargetStream(TARGET_DOCUMENT, str.c_str());
1899 }
1900 
1901 /**
1902  * Checks whether the quantity string is a negative quantity
1903  */
isNegativeQuantity(const gchar * quantity)1904 bool IE_Exp_OpenXML::isNegativeQuantity(const gchar* quantity)
1905 {
1906 	return *quantity == '-';
1907 }
1908 
1909 /**
1910  * Converts the string str to EMUs, returns non-negative whole number
1911  */
convertToPositiveEmus(const gchar * str)1912 const gchar * IE_Exp_OpenXML::convertToPositiveEmus(const gchar* str)
1913 {
1914 	//1 inch = 914400 EMUs
1915 	double emu = UT_convertToInches(str) * 914400;
1916 	if(emu < 1.0)
1917 		return "0";
1918 	return UT_convertToDimensionlessString(emu, ".0");
1919 }
1920 
1921 /**
1922  * Converts the string str to points
1923  */
convertToPoints(const gchar * str)1924 const gchar * IE_Exp_OpenXML::convertToPoints(const gchar* str)
1925 {
1926 	double pt = UT_convertToPoints(str);
1927 	return UT_convertToDimensionlessString(pt, ".0");
1928 }
1929 
1930 /**
1931  * Converts the string str to twips, returns positive whole number or NULL if twips=0
1932  */
convertToPositiveTwips(const gchar * str)1933 const gchar * IE_Exp_OpenXML::convertToPositiveTwips(const gchar* str)
1934 {
1935 	double pt = UT_convertToPoints(str) * 20;
1936 	if(pt < 0)
1937 		pt = -pt;
1938 	if(pt < 1.0)
1939 		pt = 0.0;
1940 	return UT_convertToDimensionlessString(pt, ".0");
1941 }
1942 
1943 /**
1944  * Converts the string str to twips, returns NULL if twips=0
1945  */
convertToTwips(const gchar * str)1946 const gchar * IE_Exp_OpenXML::convertToTwips(const gchar* str)
1947 {
1948 	double pt = UT_convertToPoints(str) * 20;
1949 	if(pt < 1.0 && pt > -1.0)
1950 		return NULL;
1951 	return UT_convertToDimensionlessString(pt, ".0");
1952 }
1953 
1954 /**
1955  * Converts the string str to lines, returns NULL if lines=0
1956  */
convertToLines(const gchar * str)1957 const gchar * IE_Exp_OpenXML::convertToLines(const gchar* str)
1958 {
1959 	//1 point == 20 twips; 1 line == 12pts --> 1 line == 20*12=240twips
1960 	double pt = UT_convertDimensionless(str) * 240;
1961 	if(pt < 1.0 && pt > -1.0)
1962 		return NULL;
1963 	return UT_convertToDimensionlessString(pt, ".0");
1964 }
1965 
1966 /**
1967  * Converts the string str to eighths of a point
1968  */
computeBorderWidth(const gchar * str)1969 const gchar * IE_Exp_OpenXML::computeBorderWidth(const gchar* str)
1970 {
1971 	//in eighths of a point
1972 	double pt = UT_convertToPoints(str) * 8;
1973 	if(pt < 1.0 && pt > -1.0)
1974 		return "0";
1975 	return UT_convertToDimensionlessString(pt, ".0");
1976 }
1977 
1978 /**
1979  * Computes the font-size
1980  */
computeFontSize(const gchar * str)1981 const gchar * IE_Exp_OpenXML::computeFontSize(const gchar* str)
1982 {
1983 	//font-size=X pt --> return 2*X
1984 	double pt = UT_convertDimensionless(str) * 2;
1985 	return UT_convertToDimensionlessString(pt, ".0");
1986 }
1987 
1988 /**
1989  * Cleans up everything. Called by the destructor.
1990  */
_cleanup()1991 void IE_Exp_OpenXML::_cleanup ()
1992 {
1993 	m_pDoc = NULL;
1994 
1995 	if(footnoteStream && !gsf_output_is_closed(footnoteStream))
1996 		gsf_output_close(footnoteStream);
1997 
1998 	if(endnoteStream && !gsf_output_is_closed(endnoteStream))
1999 		gsf_output_close(endnoteStream);
2000 
2001 	if(settingsStream && !gsf_output_is_closed(settingsStream))
2002 		gsf_output_close(settingsStream);
2003 
2004 	if(headerStream && !gsf_output_is_closed(headerStream))
2005 		gsf_output_close(headerStream);
2006 
2007 	if(footerStream && !gsf_output_is_closed(footerStream))
2008 		gsf_output_close(footerStream);
2009 
2010 	if(numberingStream && !gsf_output_is_closed(numberingStream))
2011 		gsf_output_close(numberingStream);
2012 
2013 	if(stylesStream && !gsf_output_is_closed(stylesStream))
2014 		gsf_output_close(stylesStream);
2015 
2016 	if(contentTypesStream && !gsf_output_is_closed(contentTypesStream))
2017 		gsf_output_close(contentTypesStream);
2018 
2019 	if(relStream && !gsf_output_is_closed(relStream))
2020 		gsf_output_close(relStream);
2021 
2022 	if(wordRelStream && !gsf_output_is_closed(wordRelStream))
2023 		gsf_output_close(wordRelStream);
2024 
2025 	if(documentStream && !gsf_output_is_closed(documentStream))
2026 		gsf_output_close(documentStream);
2027 
2028 	if(relsDir)
2029 	{
2030 		GsfOutput* rels_out = GSF_OUTPUT(relsDir);
2031 		if(!gsf_output_is_closed(rels_out))
2032 			gsf_output_close(rels_out);
2033 	}
2034 
2035 	if(wordMediaDir)
2036 	{
2037 		GsfOutput* wordMedia_out = GSF_OUTPUT(wordMediaDir);
2038 		if(!gsf_output_is_closed(wordMedia_out))
2039 			gsf_output_close(wordMedia_out);
2040 	}
2041 
2042 	if(wordRelsDir)
2043 	{
2044 		GsfOutput* wordRels_out = GSF_OUTPUT(wordRelsDir);
2045 		if(!gsf_output_is_closed(wordRels_out))
2046 			gsf_output_close(wordRels_out);
2047 	}
2048 
2049 	if(wordDir)
2050 	{
2051 		GsfOutput* word_out = GSF_OUTPUT(wordDir);
2052 		if(!gsf_output_is_closed(word_out))
2053 			gsf_output_close(word_out);
2054 	}
2055 
2056 	if(root)
2057 	{
2058 		GsfOutput* root_out = GSF_OUTPUT(root);
2059 		if(!gsf_output_is_closed(root_out))
2060 			gsf_output_close(root_out);
2061 	}
2062 }
2063 
2064 /**
2065  * Starts the numbering.xml file which describes the default list styles
2066  */
startNumbering()2067 UT_Error IE_Exp_OpenXML::startNumbering()
2068 {
2069 	UT_Error err = UT_OK;
2070 
2071 	numberingStream = gsf_output_memory_new();
2072 
2073 	if(!numberingStream)
2074 	{
2075 		UT_DEBUGMSG(("FRT: ERROR, numbering.xml file couldn't be created\n"));
2076 		return UT_SAVE_EXPORTERROR;
2077 	}
2078 
2079 	err = writeXmlHeader(numberingStream);
2080 	if(err != UT_OK)
2081 	{
2082 		return err;
2083 	}
2084 
2085 	std::string str("<w:numbering ");
2086 	str += "xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"";
2087 	str += ">";
2088 
2089 	return writeTargetStream(TARGET_NUMBERING, str.c_str());
2090 }
2091 
2092 /**
2093  * Finishes the numbering.xml file which describes the contents of the package
2094  */
finishNumbering()2095 UT_Error IE_Exp_OpenXML::finishNumbering()
2096 {
2097 	UT_Error err = UT_OK;
2098 
2099 	err = writeTargetStream(TARGET_NUMBERING, "</w:numbering>");
2100 	if(err != UT_OK)
2101 	{
2102 		UT_DEBUGMSG(("FRT: ERROR, cannot write to numbering.xml file\n"));
2103 		return err;
2104 	}
2105 
2106 	GsfOutput* numberingFile = gsf_outfile_new_child(wordDir, "numbering.xml", FALSE);
2107 
2108 	if(!numberingFile)
2109 		return UT_SAVE_EXPORTERROR;
2110 
2111  	if(!gsf_output_write(numberingFile, gsf_output_size(numberingStream),
2112 					 gsf_output_memory_get_bytes(GSF_OUTPUT_MEMORY(numberingStream))))
2113 	{
2114 		gsf_output_close(numberingFile);
2115 		return UT_SAVE_EXPORTERROR;
2116 	}
2117 
2118 	if(!gsf_output_close(numberingStream))
2119 	{
2120 		gsf_output_close(numberingFile);
2121 		return UT_SAVE_EXPORTERROR;
2122 	}
2123 
2124 	if(!gsf_output_close(numberingFile))
2125 	{
2126 		UT_DEBUGMSG(("FRT: ERROR, numbering.xml file couldn't be closed\n"));
2127 		return UT_SAVE_EXPORTERROR;
2128 	}
2129 	return UT_OK;
2130 }
2131 
2132 /**
2133  * Starts the styles.xml file which describes the default styles
2134  */
startStyles()2135 UT_Error IE_Exp_OpenXML::startStyles()
2136 {
2137 	UT_Error err = UT_OK;
2138 
2139 	stylesStream = gsf_output_memory_new();
2140 
2141 	if(!stylesStream)
2142 	{
2143 		UT_DEBUGMSG(("FRT: ERROR, styles.xml file couldn't be created\n"));
2144 		return UT_SAVE_EXPORTERROR;
2145 	}
2146 
2147 	err = writeXmlHeader(stylesStream);
2148 	if(err != UT_OK)
2149 	{
2150 		return err;
2151 	}
2152 
2153 	std::string str("<w:styles ");
2154 	str += "xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" ";
2155 	str += "xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\">";
2156 
2157 	return writeTargetStream(TARGET_STYLES, str.c_str());
2158 }
2159 
2160 /**
2161  * Finishes the styles.xml file which describes the contents of the package
2162  */
finishStyles()2163 UT_Error IE_Exp_OpenXML::finishStyles()
2164 {
2165 	UT_Error err = UT_OK;
2166 
2167 	err = writeTargetStream(TARGET_STYLES, "</w:styles>");
2168 	if(err != UT_OK)
2169 	{
2170 		UT_DEBUGMSG(("FRT: ERROR, cannot write to styles.xml file\n"));
2171 		return err;
2172 	}
2173 
2174 	GsfOutput* stylesFile = gsf_outfile_new_child(wordDir, "styles.xml", FALSE);
2175 
2176 	if(!stylesFile)
2177 		return UT_SAVE_EXPORTERROR;
2178 
2179  	if(!gsf_output_write(stylesFile, gsf_output_size(stylesStream),
2180 					 gsf_output_memory_get_bytes(GSF_OUTPUT_MEMORY(stylesStream))))
2181 	{
2182 		gsf_output_close(stylesFile);
2183 		return UT_SAVE_EXPORTERROR;
2184 	}
2185 
2186 	if(!gsf_output_close(stylesStream))
2187 	{
2188 		gsf_output_close(stylesFile);
2189 		return UT_SAVE_EXPORTERROR;
2190 	}
2191 
2192 	if(!gsf_output_close(stylesFile))
2193 	{
2194 		UT_DEBUGMSG(("FRT: ERROR, styles.xml file couldn't be closed\n"));
2195 		return UT_SAVE_EXPORTERROR;
2196 	}
2197 	return UT_OK;
2198 }
2199 
2200 /**
2201  * Starts the [Content_Types].xml file which describes the contents of the package
2202  */
startContentTypes()2203 UT_Error IE_Exp_OpenXML::startContentTypes()
2204 {
2205 	UT_Error err = UT_OK;
2206 
2207 	contentTypesStream = gsf_output_memory_new();
2208 
2209 	if(!contentTypesStream)
2210 	{
2211 		UT_DEBUGMSG(("FRT: ERROR, [Content_Types].xml file couldn't be created\n"));
2212 		return UT_SAVE_EXPORTERROR;
2213 	}
2214 
2215 	//we only have .rels and .xml file types in the simple basis file
2216 	//TODO: extend this for other file types as needed
2217 	err = writeXmlHeader(contentTypesStream);
2218 	if(err != UT_OK)
2219 	{
2220 		return err;
2221 	}
2222 
2223 	std::string str("<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\">");
2224 	str += "<Default Extension=\"rels\" ContentType=\"application/vnd.openxmlformats-package.relationships+xml\"/>";
2225 	str += "<Default Extension=\"xml\" ContentType=\"application/xml\"/>";
2226 	str += "<Default Extension=\"png\" ContentType=\"image/png\"/>";
2227 	str += "<Default Extension=\"jpg\" ContentType=\"image/jpeg\"/>";
2228 	str += "<Default Extension=\"jpeg\" ContentType=\"image/jpeg\"/>";
2229 	str += "<Default Extension=\"gif\" ContentType=\"image/gif\"/>";
2230 	str += "<Default Extension=\"tiff\" ContentType=\"image/tiff\"/>";
2231 	str += "<Default Extension=\"svg\" ContentType=\"image/svg+xml\"/>";
2232 	str += "<Override PartName=\"/word/document.xml\" ";
2233 	str += "ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml\"/>";
2234 	str += "<Override PartName=\"/word/styles.xml\" ";
2235 	str += "ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml\"/>";
2236 	str += "<Override PartName=\"/word/settings.xml\" ";
2237 	str += "ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml\"/>";
2238 	str += "<Override PartName=\"/word/numbering.xml\" ";
2239 	str += "ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml\"/>";
2240 	str += "<Override PartName=\"/word/footnotes.xml\" ";
2241 	str += "ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml\"/>";
2242 	str += "<Override PartName=\"/word/endnotes.xml\" ";
2243 	str += "ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml\"/>";
2244 
2245 	return writeTargetStream(TARGET_CONTENT, str.c_str());
2246 }
2247 
2248 /**
2249  * Finishes the [Content_Types].xml file which describes the contents of the package
2250  */
finishContentTypes()2251 UT_Error IE_Exp_OpenXML::finishContentTypes()
2252 {
2253 	UT_Error err = UT_OK;
2254 
2255 	err = writeTargetStream(TARGET_CONTENT, "</Types>");
2256 	if(err != UT_OK)
2257 	{
2258 		UT_DEBUGMSG(("FRT: ERROR, cannot write to [Content_Types].xml file\n"));
2259 		return err;
2260 	}
2261 
2262 	GsfOutput* contentTypesFile = gsf_outfile_new_child(root, "[Content_Types].xml", FALSE);
2263 
2264 	if(!contentTypesFile)
2265 		return UT_SAVE_EXPORTERROR;
2266 
2267  	if(!gsf_output_write(contentTypesFile, gsf_output_size(contentTypesStream),
2268 					 gsf_output_memory_get_bytes(GSF_OUTPUT_MEMORY(contentTypesStream))))
2269 	{
2270 		gsf_output_close(contentTypesFile);
2271 		return UT_SAVE_EXPORTERROR;
2272 	}
2273 
2274 	if(!gsf_output_close(contentTypesStream))
2275 	{
2276 		gsf_output_close(contentTypesFile);
2277 		return UT_SAVE_EXPORTERROR;
2278 	}
2279 
2280 	if(!gsf_output_close(contentTypesFile))
2281 	{
2282 		UT_DEBUGMSG(("FRT: ERROR, [Content_Types].xml file couldn't be closed\n"));
2283 		return UT_SAVE_EXPORTERROR;
2284 	}
2285 	return UT_OK;
2286 }
2287 
2288 /**
2289  * Writes the relationships for the files within the package
2290  * Outputs the _rels folder and _rels/.rels file which defines the package relations.
2291  */
startRelations()2292 UT_Error IE_Exp_OpenXML::startRelations()
2293 {
2294 	UT_Error err = UT_OK;
2295 
2296 	relStream = gsf_output_memory_new();
2297 	if(!relStream)
2298 	{
2299 		UT_DEBUGMSG(("FRT: ERROR, .rels file couldn't be created\n"));
2300 		return UT_SAVE_EXPORTERROR;
2301 	}
2302 
2303 	err = writeXmlHeader(relStream);
2304 	if(err != UT_OK)
2305 	{
2306 		return err;
2307 	}
2308 
2309 	std::string str("<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">");
2310 	str += "<Relationship Id=\"rId1\" ";
2311 	str += "Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument\" ";
2312 	str += "Target=\"word/document.xml\"/>";
2313 
2314 	return writeTargetStream(TARGET_RELATION, str.c_str());
2315 
2316 }
2317 
2318 /**
2319  * Finishes the relationships
2320  */
finishRelations()2321 UT_Error IE_Exp_OpenXML::finishRelations()
2322 {
2323 	UT_Error err = UT_OK;
2324 
2325 	err = writeTargetStream(TARGET_RELATION, "</Relationships>");
2326 	if(err != UT_OK)
2327 	{
2328 		UT_DEBUGMSG(("FRT: ERROR, cannot write to .rels file\n"));
2329 		return err;
2330 	}
2331 
2332 	relsDir = GSF_OUTFILE(gsf_outfile_new_child(root, "_rels", TRUE));
2333 	if(!relsDir)
2334 	{
2335 		UT_DEBUGMSG(("FRT: ERROR, _rels directory couldn't be created\n"));
2336 		return UT_SAVE_EXPORTERROR;
2337 	}
2338 
2339 	GsfOutput* relFile = gsf_outfile_new_child(relsDir, ".rels", FALSE);
2340 
2341 	if(!relFile)
2342 		return UT_SAVE_EXPORTERROR;
2343 
2344  	if(!gsf_output_write(relFile, gsf_output_size(relStream),
2345 					 gsf_output_memory_get_bytes(GSF_OUTPUT_MEMORY(relStream))))
2346 	{
2347 		gsf_output_close(relFile);
2348 		return UT_SAVE_EXPORTERROR;
2349 	}
2350 
2351 	if(!gsf_output_close(relStream))
2352 	{
2353 		gsf_output_close(relFile);
2354 		return UT_SAVE_EXPORTERROR;
2355 	}
2356 
2357 	if(!gsf_output_close(relFile))
2358 	{
2359 		UT_DEBUGMSG(("FRT: ERROR, .rels file couldn't be closed\n"));
2360 		return UT_SAVE_EXPORTERROR;
2361 	}
2362 
2363 	return UT_OK;
2364 }
2365 
2366 /**
2367  * Outputs the word/_rels folder and word/_rels/document.xml.rels file
2368  */
startWordRelations()2369 UT_Error IE_Exp_OpenXML::startWordRelations()
2370 {
2371 	UT_Error err = UT_OK;
2372 
2373 	wordRelStream = gsf_output_memory_new();
2374 	if(!wordRelStream)
2375 	{
2376 		UT_DEBUGMSG(("FRT: ERROR, document.xml.rels file couldn't be created\n"));
2377 		return UT_SAVE_EXPORTERROR;
2378 	}
2379 
2380 	err = writeXmlHeader(wordRelStream);
2381 	if(err != UT_OK)
2382 	{
2383 		return err;
2384 	}
2385 
2386 	std::string str("<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">");
2387 	str += "<Relationship Id=\"rId1\" ";
2388 	str += "Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles\" ";
2389 	str += "Target=\"styles.xml\"/>";
2390 	str += "<Relationship Id=\"rId2\" ";
2391 	str += "Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering\" ";
2392 	str += "Target=\"numbering.xml\"/>";
2393 	str += "<Relationship Id=\"rId3\" ";
2394 	str += "Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings\" ";
2395 	str += "Target=\"settings.xml\"/>";
2396 	str += "<Relationship Id=\"rId4\" ";
2397 	str += "Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes\" ";
2398 	str += "Target=\"footnotes.xml\"/>";
2399 	str += "<Relationship Id=\"rId5\" ";
2400 	str += "Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/endnotes\" ";
2401 	str += "Target=\"endnotes.xml\"/>";
2402 
2403 	return writeTargetStream(TARGET_DOCUMENT_RELATION, str.c_str());
2404 
2405 }
2406 
2407 /**
2408  * Finishes the relationships
2409  */
finishWordRelations()2410 UT_Error IE_Exp_OpenXML::finishWordRelations()
2411 {
2412 	UT_Error err = UT_OK;
2413 
2414 	err = writeTargetStream(TARGET_DOCUMENT_RELATION, "</Relationships>");
2415 	if(err != UT_OK)
2416 	{
2417 		UT_DEBUGMSG(("FRT: ERROR, cannot write to document.xml.rels file\n"));
2418 		return err;
2419 	}
2420 
2421 	wordRelsDir = GSF_OUTFILE(gsf_outfile_new_child(wordDir, "_rels", TRUE));
2422 	if(!wordRelsDir)
2423 	{
2424 		UT_DEBUGMSG(("FRT: ERROR, word/_rels directory couldn't be created\n"));
2425 		return UT_SAVE_EXPORTERROR;
2426 	}
2427 
2428 	GsfOutput* wordRelFile = gsf_outfile_new_child(wordRelsDir, "document.xml.rels", FALSE);
2429 
2430 	if(!wordRelFile)
2431 		return UT_SAVE_EXPORTERROR;
2432 
2433  	if(!gsf_output_write(wordRelFile, gsf_output_size(wordRelStream),
2434 					 gsf_output_memory_get_bytes(GSF_OUTPUT_MEMORY(wordRelStream))))
2435 	{
2436 		gsf_output_close(wordRelFile);
2437 		return UT_SAVE_EXPORTERROR;
2438 	}
2439 
2440 	if(!gsf_output_close(wordRelStream))
2441 	{
2442 		gsf_output_close(wordRelFile);
2443 		return UT_SAVE_EXPORTERROR;
2444 	}
2445 
2446 	if(!gsf_output_close(wordRelFile))
2447 	{
2448 		UT_DEBUGMSG(("FRT: ERROR, document.xml.rels file couldn't be closed\n"));
2449 		return UT_SAVE_EXPORTERROR;
2450 	}
2451 
2452 	return UT_OK;
2453 }
2454 
2455 /**
2456  * Does nothing for now.
2457  * If we need a default file in word/media folder we should create the necessary stream here.
2458  */
startWordMedia()2459 UT_Error IE_Exp_OpenXML::startWordMedia()
2460 {
2461 	return UT_OK;
2462 }
2463 
2464 /**
2465  * Exports all the image streams to actual files in the word/media folder
2466  */
finishWordMedia()2467 UT_Error IE_Exp_OpenXML::finishWordMedia()
2468 {
2469 	wordMediaDir = GSF_OUTFILE(gsf_outfile_new_child(wordDir, "media", TRUE));
2470 	if(!wordMediaDir)
2471 	{
2472 		UT_DEBUGMSG(("FRT: ERROR, word/media directory couldn't be created\n"));
2473 		return UT_SAVE_EXPORTERROR;
2474 	}
2475 
2476 	std::map<std::string, GsfOutput*>::iterator it;
2477 	for (it = mediaStreams.begin(); it != mediaStreams.end(); it++) {
2478 
2479 		GsfOutput* imageFile = gsf_outfile_new_child(wordMediaDir, it->first.c_str(), FALSE);
2480 
2481 		if(!imageFile)
2482 			return UT_SAVE_EXPORTERROR;
2483 
2484 	 	if(!gsf_output_write(imageFile, gsf_output_size(it->second),
2485 						 gsf_output_memory_get_bytes(GSF_OUTPUT_MEMORY(it->second))))
2486 		{
2487 			gsf_output_close(imageFile);
2488 			return UT_SAVE_EXPORTERROR;
2489 		}
2490 
2491 		if(!gsf_output_close(it->second))
2492 		{
2493 			gsf_output_close(imageFile);
2494 			return UT_SAVE_EXPORTERROR;
2495 		}
2496 
2497 		if(!gsf_output_close(imageFile))
2498 		{
2499 			UT_DEBUGMSG(("FRT: ERROR, image file couldn't be closed\n"));
2500 			return UT_SAVE_EXPORTERROR;
2501 		}
2502 	}
2503 
2504 	return UT_OK;
2505 }
2506 
2507 /**
2508  * Starts the main part of the document to word/document.xml file.
2509  */
startMainPart()2510 UT_Error IE_Exp_OpenXML::startMainPart()
2511 {
2512 	UT_Error err = UT_OK;
2513 
2514 	documentStream = gsf_output_memory_new();
2515 	if(!documentStream)
2516 	{
2517 		UT_DEBUGMSG(("FRT: ERROR, document.xml file couldn't be created\n"));
2518 		return UT_SAVE_EXPORTERROR;
2519 	}
2520 
2521 	err = writeXmlHeader(documentStream);
2522 	if(err != UT_OK)
2523 	{
2524 		return err;
2525 	}
2526 
2527 	std::string str("<w:document xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" ");
2528 	str += "xmlns:v=\"urn:schemas-microsoft-com:vml\" ";
2529 	str += "xmlns:wx=\"http://schemas.microsoft.com/office/word/2003/auxHint\" ";
2530 	str += "xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\" ";
2531 	str += "xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\" ";
2532 	str += "xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" ";
2533 	str += "xmlns:pic=\"http://schemas.openxmlformats.org/drawingml/2006/picture\" ";
2534 	str += "xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"><w:body>";
2535 
2536 	return writeTargetStream(TARGET_DOCUMENT, str.c_str());
2537 }
2538 
2539 /**
2540  * Finishes the main part of the document to word/document.xml file.
2541  */
finishMainPart()2542 UT_Error IE_Exp_OpenXML::finishMainPart()
2543 {
2544 	UT_Error err = UT_OK;
2545 
2546 	err = writeTargetStream(TARGET_DOCUMENT, "</w:body></w:document>");
2547 	if(err != UT_OK)
2548 	{
2549 		UT_DEBUGMSG(("FRT: ERROR, cannot write to document.xml file\n"));
2550 		return err;
2551 	}
2552 
2553 	wordDir = GSF_OUTFILE(gsf_outfile_new_child(root, "word", TRUE));
2554 	if(!wordDir)
2555 	{
2556 		UT_DEBUGMSG(("FRT: ERROR, word directory couldn't be created\n"));
2557 		return UT_SAVE_EXPORTERROR;
2558 	}
2559 
2560 	GsfOutput* documentFile = gsf_outfile_new_child(wordDir, "document.xml", FALSE);
2561 
2562 	if(!documentFile)
2563 		return UT_SAVE_EXPORTERROR;
2564 
2565  	if(!gsf_output_write(documentFile, gsf_output_size(documentStream),
2566 					 gsf_output_memory_get_bytes(GSF_OUTPUT_MEMORY(documentStream))))
2567 	{
2568 		gsf_output_close(documentFile);
2569 		return UT_SAVE_EXPORTERROR;
2570 	}
2571 
2572 	if(!gsf_output_close(documentStream))
2573 	{
2574 		gsf_output_close(documentFile);
2575 		return UT_SAVE_EXPORTERROR;
2576 	}
2577 
2578 	if(!gsf_output_close(documentFile))
2579 	{
2580 		UT_DEBUGMSG(("FRT: ERROR, document.xml file couldn't be closed\n"));
2581 		return UT_SAVE_EXPORTERROR;
2582 	}
2583 
2584 	return UT_OK;
2585 }
2586 
2587 /**
2588  * Starts the settings of the document in word/settings.xml file.
2589  */
startSettings()2590 UT_Error IE_Exp_OpenXML::startSettings()
2591 {
2592 	UT_Error err = UT_OK;
2593 
2594 	settingsStream = gsf_output_memory_new();
2595 	if(!settingsStream)
2596 	{
2597 		UT_DEBUGMSG(("FRT: ERROR, settings.xml file couldn't be created\n"));
2598 		return UT_SAVE_EXPORTERROR;
2599 	}
2600 
2601 	err = writeXmlHeader(settingsStream);
2602 	if(err != UT_OK)
2603 	{
2604 		return err;
2605 	}
2606 
2607 	std::string str("<w:settings xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" ");
2608 	str += "xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\">";
2609 
2610 	return writeTargetStream(TARGET_SETTINGS, str.c_str());
2611 }
2612 
2613 /**
2614  * Finishes the settings of the document in word/setting.xml file.
2615  */
finishSettings()2616 UT_Error IE_Exp_OpenXML::finishSettings()
2617 {
2618 	UT_Error err = UT_OK;
2619 
2620 	err = writeTargetStream(TARGET_SETTINGS, "</w:settings>");
2621 	if(err != UT_OK)
2622 	{
2623 		UT_DEBUGMSG(("FRT: ERROR, cannot write to settings.xml file\n"));
2624 		return err;
2625 	}
2626 
2627 	GsfOutput* settingsFile = gsf_outfile_new_child(wordDir, "settings.xml", FALSE);
2628 
2629 	if(!settingsFile)
2630 		return UT_SAVE_EXPORTERROR;
2631 
2632  	if(!gsf_output_write(settingsFile, gsf_output_size(settingsStream),
2633 					 gsf_output_memory_get_bytes(GSF_OUTPUT_MEMORY(settingsStream))))
2634 	{
2635 		gsf_output_close(settingsFile);
2636 		return UT_SAVE_EXPORTERROR;
2637 	}
2638 
2639 	if(!gsf_output_close(settingsStream))
2640 	{
2641 		gsf_output_close(settingsFile);
2642 		return UT_SAVE_EXPORTERROR;
2643 	}
2644 
2645 	if(!gsf_output_close(settingsFile))
2646 	{
2647 		UT_DEBUGMSG(("FRT: ERROR, setting.xml file couldn't be closed\n"));
2648 		return UT_SAVE_EXPORTERROR;
2649 	}
2650 
2651 	return UT_OK;
2652 }
2653 
2654 /**
2655  * Does nothing for now.
2656  */
startHeaders()2657 UT_Error IE_Exp_OpenXML::startHeaders()
2658 {
2659 	return UT_OK;
2660 }
2661 
2662 /**
2663  * Finishes the headers in word/header.xml file.
2664  */
finishHeaders()2665 UT_Error IE_Exp_OpenXML::finishHeaders()
2666 {
2667 	std::map<std::string, GsfOutput*>::iterator it;
2668 	for (it = headerStreams.begin(); it != headerStreams.end(); it++) {
2669 
2670 		std::string filename("header");
2671 		filename += it->first.c_str();
2672 		filename += ".xml";
2673 
2674 		GsfOutput* headerFile = gsf_outfile_new_child(wordDir, filename.c_str(), FALSE);
2675 
2676 		if(!headerFile)
2677 			return UT_SAVE_EXPORTERROR;
2678 
2679 	 	if(!gsf_output_write(headerFile, gsf_output_size(it->second),
2680 						 gsf_output_memory_get_bytes(GSF_OUTPUT_MEMORY(it->second))))
2681 		{
2682 			gsf_output_close(headerFile);
2683 			return UT_SAVE_EXPORTERROR;
2684 		}
2685 
2686 		if(!gsf_output_close(it->second))
2687 		{
2688 			gsf_output_close(headerFile);
2689 			return UT_SAVE_EXPORTERROR;
2690 		}
2691 
2692 		if(!gsf_output_close(headerFile))
2693 		{
2694 			UT_DEBUGMSG(("FRT: ERROR, header file couldn't be closed\n"));
2695 			return UT_SAVE_EXPORTERROR;
2696 		}
2697 	}
2698 
2699 	return UT_OK;
2700 }
2701 
2702 /**
2703  * Does nothing for now.
2704  */
startFooters()2705 UT_Error IE_Exp_OpenXML::startFooters()
2706 {
2707 	return UT_OK;
2708 }
2709 
2710 /**
2711  * Finishes the headers in word/footer.xml file.
2712  */
finishFooters()2713 UT_Error IE_Exp_OpenXML::finishFooters()
2714 {
2715 	std::map<std::string, GsfOutput*>::iterator it;
2716 	for (it = footerStreams.begin(); it != footerStreams.end(); it++) {
2717 
2718 		std::string filename("footer");
2719 		filename += it->first.c_str();
2720 		filename += ".xml";
2721 
2722 		GsfOutput* footerFile = gsf_outfile_new_child(wordDir, filename.c_str(), FALSE);
2723 
2724 		if(!footerFile)
2725 			return UT_SAVE_EXPORTERROR;
2726 
2727 	 	if(!gsf_output_write(footerFile, gsf_output_size(it->second),
2728 						 gsf_output_memory_get_bytes(GSF_OUTPUT_MEMORY(it->second))))
2729 		{
2730 			gsf_output_close(footerFile);
2731 			return UT_SAVE_EXPORTERROR;
2732 		}
2733 
2734 		if(!gsf_output_close(it->second))
2735 		{
2736 			gsf_output_close(footerFile);
2737 			return UT_SAVE_EXPORTERROR;
2738 		}
2739 
2740 		if(!gsf_output_close(footerFile))
2741 		{
2742 			UT_DEBUGMSG(("FRT: ERROR, footer file couldn't be closed\n"));
2743 			return UT_SAVE_EXPORTERROR;
2744 		}
2745 	}
2746 
2747 	return UT_OK;
2748 }
2749 
2750 /**
2751  * Starts the footnotes.xml file which describes the footnotes
2752  */
startFootnotes()2753 UT_Error IE_Exp_OpenXML::startFootnotes()
2754 {
2755 	UT_Error err = UT_OK;
2756 
2757 	footnoteStream = gsf_output_memory_new();
2758 
2759 	if(!footnoteStream)
2760 	{
2761 		UT_DEBUGMSG(("FRT: ERROR, footnotes.xml file couldn't be created\n"));
2762 		return UT_SAVE_EXPORTERROR;
2763 	}
2764 
2765 	err = writeXmlHeader(footnoteStream);
2766 	if(err != UT_OK)
2767 	{
2768 		return err;
2769 	}
2770 
2771 	std::string str("<w:footnotes ");
2772 	str += "xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"";
2773 	str += ">";
2774 
2775 	return writeTargetStream(TARGET_FOOTNOTE, str.c_str());
2776 }
2777 
2778 /**
2779  * Finishes the footnotes.xml file
2780  */
finishFootnotes()2781 UT_Error IE_Exp_OpenXML::finishFootnotes()
2782 {
2783 	UT_Error err = UT_OK;
2784 
2785 	err = writeTargetStream(TARGET_FOOTNOTE, "</w:footnotes>");
2786 	if(err != UT_OK)
2787 	{
2788 		UT_DEBUGMSG(("FRT: ERROR, cannot write to footnotes.xml file\n"));
2789 		return err;
2790 	}
2791 
2792 	GsfOutput* footnoteFile = gsf_outfile_new_child(wordDir, "footnotes.xml", FALSE);
2793 
2794 	if(!footnoteFile)
2795 		return UT_SAVE_EXPORTERROR;
2796 
2797  	if(!gsf_output_write(footnoteFile, gsf_output_size(footnoteStream),
2798 					 gsf_output_memory_get_bytes(GSF_OUTPUT_MEMORY(footnoteStream))))
2799 	{
2800 		gsf_output_close(footnoteFile);
2801 		return UT_SAVE_EXPORTERROR;
2802 	}
2803 
2804 	if(!gsf_output_close(footnoteStream))
2805 	{
2806 		gsf_output_close(footnoteFile);
2807 		return UT_SAVE_EXPORTERROR;
2808 	}
2809 
2810 	if(!gsf_output_close(footnoteFile))
2811 	{
2812 		UT_DEBUGMSG(("FRT: ERROR, footnotes.xml file couldn't be closed\n"));
2813 		return UT_SAVE_EXPORTERROR;
2814 	}
2815 	return UT_OK;
2816 }
2817 
2818 /**
2819  * Starts the endnotes.xml file which describes the endnotes
2820  */
startEndnotes()2821 UT_Error IE_Exp_OpenXML::startEndnotes()
2822 {
2823 	UT_Error err = UT_OK;
2824 
2825 	endnoteStream = gsf_output_memory_new();
2826 
2827 	if(!endnoteStream)
2828 	{
2829 		UT_DEBUGMSG(("FRT: ERROR, endnotes.xml file couldn't be created\n"));
2830 		return UT_SAVE_EXPORTERROR;
2831 	}
2832 
2833 	err = writeXmlHeader(endnoteStream);
2834 	if(err != UT_OK)
2835 	{
2836 		return err;
2837 	}
2838 
2839 	std::string str("<w:endnotes ");
2840 	str += "xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"";
2841 	str += ">";
2842 
2843 	return writeTargetStream(TARGET_ENDNOTE, str.c_str());
2844 }
2845 
2846 /**
2847  * Finishes the endnotes.xml file
2848  */
finishEndnotes()2849 UT_Error IE_Exp_OpenXML::finishEndnotes()
2850 {
2851 	UT_Error err = UT_OK;
2852 
2853 	err = writeTargetStream(TARGET_ENDNOTE, "</w:endnotes>");
2854 	if(err != UT_OK)
2855 	{
2856 		UT_DEBUGMSG(("FRT: ERROR, cannot write to endnotes.xml file\n"));
2857 		return err;
2858 	}
2859 
2860 	GsfOutput* endnoteFile = gsf_outfile_new_child(wordDir, "endnotes.xml", FALSE);
2861 
2862 	if(!endnoteFile)
2863 		return UT_SAVE_EXPORTERROR;
2864 
2865  	if(!gsf_output_write(endnoteFile, gsf_output_size(endnoteStream),
2866 					 gsf_output_memory_get_bytes(GSF_OUTPUT_MEMORY(endnoteStream))))
2867 	{
2868 		gsf_output_close(endnoteFile);
2869 		return UT_SAVE_EXPORTERROR;
2870 	}
2871 
2872 	if(!gsf_output_close(endnoteStream))
2873 	{
2874 		gsf_output_close(endnoteFile);
2875 		return UT_SAVE_EXPORTERROR;
2876 	}
2877 
2878 	if(!gsf_output_close(endnoteFile))
2879 	{
2880 		UT_DEBUGMSG(("FRT: ERROR, endnotes.xml file couldn't be closed\n"));
2881 		return UT_SAVE_EXPORTERROR;
2882 	}
2883 	return UT_OK;
2884 }
2885 
2886 /**
2887  * Write the simple xml header to the file
2888  * This function should be called before anything written to file
2889  */
writeXmlHeader(GsfOutput * file)2890 UT_Error IE_Exp_OpenXML::writeXmlHeader(GsfOutput* file)
2891 {
2892 	gboolean successful = gsf_output_puts(file, "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>");
2893 
2894 	if(!successful)
2895 	{
2896 		UT_DEBUGMSG(("FRT: ERROR, xml header couldn't be written\n"));
2897 		return UT_IE_COULDNOTWRITE;
2898 	}
2899 
2900 	return UT_OK;
2901 }
2902 
startStyle(const std::string & name,const std::string & basedon,const std::string & followedby,const std::string & type)2903 UT_Error IE_Exp_OpenXML::startStyle(const std::string& name, const std::string& basedon, const std::string& followedby, const std::string& type)
2904 {
2905 	std::string sEscName = UT_escapeXML(name);
2906 	std::string sEscBasedOn = UT_escapeXML(basedon);
2907 	std::string sEscFollowedBy = UT_escapeXML(followedby);
2908 	std::string sEscType = UT_escapeXML(type);
2909 
2910 	std::string str("");
2911 	str += "<w:style";
2912 	if(!type.empty())
2913 	{
2914 		str += " w:type=\"";
2915 		str += sEscType;
2916 		str += "\"";
2917 	}
2918 	str += " w:styleId=\"";
2919 	str += sEscName;
2920 	str += "\">";
2921 	str += "<w:name w:val=\"";
2922 	str += sEscName;
2923 	str += "\"/>";
2924 
2925 	if(!basedon.empty())
2926 	{
2927 		str += "<w:basedOn w:val=\"";
2928 		str += sEscBasedOn;
2929 		str += "\"/>";
2930 	}
2931 	if(!followedby.empty())
2932 	{
2933 		str += "<w:next w:val=\"";
2934 		str += sEscFollowedBy;
2935 		str += "\"/>";
2936 	}
2937 
2938 	return writeTargetStream(TARGET_STYLES, str.c_str());
2939 }
2940 
finishStyle()2941 UT_Error IE_Exp_OpenXML::finishStyle()
2942 {
2943 	return writeTargetStream(TARGET_STYLES, "</w:style>");
2944 }
2945 
startDocumentDefaultProperties()2946 UT_Error IE_Exp_OpenXML::startDocumentDefaultProperties()
2947 {
2948 	return writeTargetStream(TARGET_STYLES, "<w:docDefaults>");
2949 }
2950 
finishDocumentDefaultProperties()2951 UT_Error IE_Exp_OpenXML::finishDocumentDefaultProperties()
2952 {
2953 	return writeTargetStream(TARGET_STYLES, "</w:docDefaults>");
2954 }
2955 
startRunDefaultProperties()2956 UT_Error IE_Exp_OpenXML::startRunDefaultProperties()
2957 {
2958 	return writeTargetStream(TARGET_STYLES, "<w:rPrDefault>");
2959 }
2960 
finishRunDefaultProperties()2961 UT_Error IE_Exp_OpenXML::finishRunDefaultProperties()
2962 {
2963 	return writeTargetStream(TARGET_STYLES, "</w:rPrDefault>");
2964 }
2965 
startParagraphDefaultProperties()2966 UT_Error IE_Exp_OpenXML::startParagraphDefaultProperties()
2967 {
2968 	return writeTargetStream(TARGET_STYLES, "<w:pPrDefault>");
2969 }
2970 
finishParagraphDefaultProperties()2971 UT_Error IE_Exp_OpenXML::finishParagraphDefaultProperties()
2972 {
2973 	return writeTargetStream(TARGET_STYLES, "</w:pPrDefault>");
2974 }
2975 
writeImage(const char * filename,const UT_ByteBuf * data)2976 UT_Error IE_Exp_OpenXML::writeImage(const char* filename, const UT_ByteBuf* data)
2977 {
2978 	GsfOutput* imageStream = gsf_output_memory_new();
2979 
2980 	if(!imageStream)
2981 	{
2982 		UT_DEBUGMSG(("FRT: ERROR, image file couldn't be created\n"));
2983 		return UT_SAVE_EXPORTERROR;
2984 	}
2985 
2986  	if(!gsf_output_write(imageStream, data->getLength(), data->getPointer(0)))
2987 	{
2988 		gsf_output_close(imageStream);
2989 		return UT_SAVE_EXPORTERROR;
2990 	}
2991 
2992 	std::string str("");
2993 	str += filename;
2994 	mediaStreams[str] = imageStream;
2995 
2996 	return UT_OK;
2997 }
2998 
startHeaderStream(const char * id)2999 UT_Error IE_Exp_OpenXML::startHeaderStream(const char* id)
3000 {
3001 	UT_Error err = UT_OK;
3002 
3003 	headerStream = gsf_output_memory_new();
3004 	if(!headerStream)
3005 	{
3006 		UT_DEBUGMSG(("FRT: ERROR, header.xml file couldn't be created\n"));
3007 		return UT_SAVE_EXPORTERROR;
3008 	}
3009 
3010 	err = writeXmlHeader(headerStream);
3011 	if(err != UT_OK)
3012 		return err;
3013 
3014 	std::string str("<w:hdr xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" ");
3015 	str += "xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\">";
3016 
3017 	std::string strId("");
3018 	strId += id;
3019 	headerStreams[strId] = headerStream;
3020 
3021 	return writeTargetStream(TARGET_HEADER, str.c_str());
3022 }
3023 
finishHeaderStream()3024 UT_Error IE_Exp_OpenXML::finishHeaderStream()
3025 {
3026 	return writeTargetStream(TARGET_HEADER, "</w:hdr>");
3027 }
3028 
startFooterStream(const char * id)3029 UT_Error IE_Exp_OpenXML::startFooterStream(const char* id)
3030 {
3031 	UT_Error err = UT_OK;
3032 
3033 	footerStream = gsf_output_memory_new();
3034 	if(!footerStream)
3035 	{
3036 		UT_DEBUGMSG(("FRT: ERROR, footer.xml file couldn't be created\n"));
3037 		return UT_SAVE_EXPORTERROR;
3038 	}
3039 
3040 	err = writeXmlHeader(footerStream);
3041 	if(err != UT_OK)
3042 		return err;
3043 
3044 	std::string str("<w:ftr xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" ");
3045 	str += "xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\">";
3046 
3047 	std::string strId("");
3048 	strId += id;
3049 	footerStreams[strId] = footerStream;
3050 
3051 	return writeTargetStream(TARGET_FOOTER, str.c_str());
3052 }
3053 
finishFooterStream()3054 UT_Error IE_Exp_OpenXML::finishFooterStream()
3055 {
3056 	return writeTargetStream(TARGET_FOOTER, "</w:ftr>");
3057 }
3058