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