/** * Write the <text:list-style> element. */ bool ODe_Style_List::write(GsfOutput* pODT, const UT_UTF8String& rSpacesOffset) const { UT_uint32 i, count; UT_UTF8String subElementSpacesOffset; UT_UTF8String output; UT_GenericVector<ODe_ListLevelStyle*>* pVector; bool ok; UT_UTF8String_sprintf(output, "%s<text:list-style style:name=\"%s\">\n", rSpacesOffset.utf8_str(), m_name.utf8_str()); ODe_writeUTF8String(pODT, output); subElementSpacesOffset = rSpacesOffset; subElementSpacesOffset += " "; pVector = m_levelStyles.enumerate(); count = pVector->getItemCount(); for (i=0; i<count; i++) { ok = (*pVector)[i]->write(pODT, subElementSpacesOffset); if (!ok) { return false; } } UT_UTF8String_sprintf(output, "%s</text:list-style>\n", rSpacesOffset.utf8_str()); ODe_writeUTF8String(pODT, output); return true; }
void ODe_TOC_Listener::openBlock(const PP_AttrProp* pAP, ODe_ListenerAction& /*rAction*/) { UT_sint32 iLevel = 0; // check if this block should appear in the TOC const gchar* pValue = NULL; bool ok = pAP->getAttribute("style", pValue); if (ok && pValue) iLevel = m_rAuxiliaryData.m_headingStyles.getHeadingOutlineLevel(pValue); if (iLevel == 0) return; m_bInTOCBlock = true; UT_return_if_fail(m_rAuxiliaryData.m_pTOCContents); UT_UTF8String sDestStyle = m_rAuxiliaryData.m_mDestStyles[iLevel]; UT_ASSERT_HARMLESS(sDestStyle != ""); UT_UTF8String output; _printSpacesOffset(output); output += "<text:p text:style-name=\"" + ODe_Style_Style::convertStyleToNCName(sDestStyle).escapeXML(); output += "\">"; ODe_writeUTF8String(m_rAuxiliaryData.m_pTOCContents, output); }
void ODe_Note_Listener::_openNote(const gchar* pNoteClass, const gchar* pNoteId, ODe_ListenerAction& /*rAction*/) { UT_uint32 noteCitation; UT_UTF8String str; UT_UTF8String output; UT_return_if_fail(pNoteId); // The note citation will be id+1 // So id=0 will have a citation "1", and so on. noteCitation = atoi(pNoteId) + 1; output += "<text:note text:id=\"note"; UT_UTF8String_sprintf(str, "%u", m_rAuxiliaryData.m_noteCount+1); output += str; output += "\" text:note-class=\""; output += pNoteClass; output += "\"><text:note-citation>"; UT_UTF8String_sprintf(str, "%u", noteCitation); output += str; output += "</text:note-citation><text:note-body>"; ODe_writeUTF8String(m_pTextOutput, output); m_rAuxiliaryData.m_noteCount++; }
void ODe_TOC_Listener::insertTabChar() { if (!m_bInTOCBlock) return; UT_return_if_fail(m_rAuxiliaryData.m_pTOCContents); ODe_writeUTF8String(m_rAuxiliaryData.m_pTOCContents, "<text:tab/>"); }
void ODe_TOC_Listener::closeBlock() { if (!m_bInTOCBlock) return; m_bInTOCBlock = false; UT_return_if_fail(m_rAuxiliaryData.m_pTOCContents); ODe_writeUTF8String(m_rAuxiliaryData.m_pTOCContents, "</text:p>\n"); }
/** * Writes <office:automatic-styles> element. */ void ODe_AutomaticStyles::write(GsfOutput* pContentStream) const { UT_GenericVector<ODe_Style_Style*>* pStyleVector; UT_GenericVector<ODe_Style_PageLayout*>* pPageLayoutVector; UT_GenericVector<ODe_Style_List*>* pListStyleVector; UT_uint32 i, count; UT_UTF8String spacesOffset = " "; ODe_writeUTF8String(pContentStream, " <office:automatic-styles>\n"); #define ODE_WRITE_STYLES(styleMap) \ pStyleVector = styleMap.enumerate(); \ count = pStyleVector->getItemCount(); \ for (i=0; i<count; i++) { \ (*pStyleVector)[i]->write(pContentStream, spacesOffset); \ } \ DELETEP(pStyleVector); ODE_WRITE_STYLES (m_textStyles); ODE_WRITE_STYLES (m_paragraphStyles); ODE_WRITE_STYLES (m_sectionStyles); ODE_WRITE_STYLES (m_tableStyles); ODE_WRITE_STYLES (m_tableColumnStyles); ODE_WRITE_STYLES (m_tableRowStyles); ODE_WRITE_STYLES (m_tableCellStyles); ODE_WRITE_STYLES (m_graphicStyles); #undef ODE_WRITE_STYLES pPageLayoutVector = m_pageLayouts.enumerate(); count = pPageLayoutVector->getItemCount(); for (i=0; i<count; i++) { (*pPageLayoutVector)[i]->write(pContentStream, spacesOffset); } pListStyleVector = m_listStyles.enumerate(); count = pListStyleVector->getItemCount(); for (i=0; i<count; i++) { (*pListStyleVector)[i]->write(pContentStream, spacesOffset); } ODe_writeUTF8String(pContentStream, " </office:automatic-styles>\n"); }
void ODe_TOC_Listener::insertText(const UT_UTF8String& rText) { if (!m_bInTOCBlock) return; if (rText.length() == 0) return; UT_return_if_fail(m_rAuxiliaryData.m_pTOCContents); ODe_writeUTF8String(m_rAuxiliaryData.m_pTOCContents, rText); }
void ODe_Frame_Listener::closeFrame(ODe_ListenerAction& rAction) { UT_UTF8String output; m_spacesOffset--; _printSpacesOffset(output); output += "</draw:text-box>\n"; m_spacesOffset--; _printSpacesOffset(output); output += "</draw:frame>"; ODe_writeUTF8String(m_pTextOutput, output); rAction.popListenerImpl(); }
bool ODe_Style_MasterPage::write(GsfOutput* pODT) const { UT_UTF8String output; UT_UTF8String_sprintf(output, " <style:master-page style:name=\"%s\" style:page-layout-name=\"%s\">\n", m_name.utf8_str(), m_pageLayoutName.utf8_str()); ODe_writeUTF8String(pODT, output); /* We have to deal with two confusion things when writing out header/footers: 1. Oddly enough AbiWord uses "header-even" and "footer-even" for page 1, 3, 5, etc :) 2. In OpenDocument you can specify an alternative header/footer for "left" pages. Oddly enough OpenOffice.org seems to interpret "left" pages as page 2, 4, 6, etc. */ if (!m_abiHeaderId.empty()) { // It has a header ODe_writeUTF8String(pODT, " <style:header>\n"); // Swap even/uneven when there is an alternative header for uneven pages to // match what OpenOffice expects if (m_abiHeaderEvenId.empty()) { ODe_gsf_output_write(pODT, gsf_output_size (m_pHeaderContentTemp), gsf_output_memory_get_bytes (GSF_OUTPUT_MEMORY (m_pHeaderContentTemp))); } else { ODe_gsf_output_write(pODT, gsf_output_size (m_pHeaderEvenContentTemp), gsf_output_memory_get_bytes (GSF_OUTPUT_MEMORY (m_pHeaderEvenContentTemp))); } ODe_writeUTF8String(pODT, " </style:header>\n"); } if (!m_abiHeaderEvenId.empty()) { // It has a different header for uneven pages ODe_writeUTF8String(pODT, " <style:header-left>\n"); ODe_gsf_output_write(pODT, gsf_output_size (m_pHeaderContentTemp), gsf_output_memory_get_bytes (GSF_OUTPUT_MEMORY (m_pHeaderContentTemp))); ODe_writeUTF8String(pODT, " </style:header-left>\n"); } if (!m_abiFooterId.empty()) { // It has a footer ODe_writeUTF8String(pODT, " <style:footer>\n"); // Swap even/uneven when there is an alternative footer for uneven pages to // match what OpenOffice expects if (m_abiFooterEvenId.empty()) { ODe_gsf_output_write(pODT, gsf_output_size (m_pFooterContentTemp), gsf_output_memory_get_bytes (GSF_OUTPUT_MEMORY (m_pFooterContentTemp))); } else { ODe_gsf_output_write(pODT, gsf_output_size (m_pFooterEvenContentTemp), gsf_output_memory_get_bytes (GSF_OUTPUT_MEMORY (m_pFooterEvenContentTemp))); } ODe_writeUTF8String(pODT, " </style:footer>\n"); } if (!m_abiFooterEvenId.empty()) { // It has a footer for uneven pages ODe_writeUTF8String(pODT, " <style:footer-left>\n"); ODe_gsf_output_write(pODT, gsf_output_size (m_pFooterContentTemp), gsf_output_memory_get_bytes (GSF_OUTPUT_MEMORY (m_pFooterContentTemp))); ODe_writeUTF8String(pODT, " </style:footer-left>\n"); } ODe_writeUTF8String(pODT, " </style:master-page>\n"); return true; }
bool ODe_MetaDataWriter::writeMetaData(PD_Document* pDoc, GsfOutfile* oo) { GsfOutput* meta = gsf_outfile_new_child (oo, "meta.xml", FALSE); static const UT_UTF8String preamble = UT_UTF8String("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" "<office:document-meta" " xmlns:office=\"urn:oasis:names:tc:opendocument:xmlns:office:1.0\"" " xmlns:xlink=\"http://www.w3.org/1999/xlink\"" " xmlns:dc=\"http://purl.org/dc/elements/1.1/\"" " xmlns:meta=\"urn:oasis:names:tc:opendocument:xmlns:meta:1.0\"" " xmlns:ooo=\"http://openoffice.org/2004/office\"" " office:version=\"1.1\">\n" "<office:meta>\n" "<meta:generator>AbiWord/") + PACKAGE_VERSION + " (" + PLATFORM + ", " + TOOLKIT + ")</meta:generator>\n"; static const char * const postamble [] = { "</office:meta>\n", "</office:document-meta>\n" }; ODe_writeUTF8String(meta, preamble); UT_UTF8String meta_val, val; #define WRITE_METADATA_ELEMENT(abiwordKey, odElementName) if (pDoc->getMetaDataProp(abiwordKey, meta_val) && meta_val.size()) { \ meta_val.escapeXML(); \ val = UT_UTF8String_sprintf("<%s>%s</%s>\n", odElementName, meta_val.utf8_str(), odElementName); \ ODe_writeUTF8String (meta, val); \ } WRITE_METADATA_ELEMENT(PD_META_KEY_TITLE, "dc:title"); WRITE_METADATA_ELEMENT(PD_META_KEY_DESCRIPTION, "dc:description"); WRITE_METADATA_ELEMENT(PD_META_KEY_SUBJECT, "dc:subject"); //Each keyword needs to be exported individually: UT_UTF8String keywords; if (pDoc->getMetaDataProp (PD_META_KEY_KEYWORDS, keywords) && keywords.size()) { UT_UTF8String buf = ""; UT_UCS4String keyword = keywords.utf8_str(); for(UT_uint32 i = 0;i < keyword.length(); i++) { if(keyword[i] != ' ') { buf += keyword[i]; } else { if(buf.empty()) //only blank space encountered continue; buf.escapeXML(); val = UT_UTF8String_sprintf("<meta:keyword>%s</meta:keyword>\n", buf.utf8_str()); ODe_writeUTF8String(meta, val); buf.clear(); } } if(buf.length()) //there may only be one keyword (i.e. no spaces encountered) { buf.escapeXML(); val = UT_UTF8String_sprintf("<meta:keyword>%s</meta:keyword>\n", buf.utf8_str()); ODe_writeUTF8String(meta, val); } } // Should have a PD_META_KEY_INITIAL_CREATOR macro for this one, but only // if it gets implemented on the document properties dialog. WRITE_METADATA_ELEMENT("meta:initial-creator", "meta:initial-creator"); WRITE_METADATA_ELEMENT(PD_META_KEY_CREATOR, "dc:creator"); WRITE_METADATA_ELEMENT("meta:printed-by", "meta:printed-by"); // ATTENTION: I'm assuming that dc.date is used by AbiWord as // the document creation date & time. WRITE_METADATA_ELEMENT(PD_META_KEY_DATE, "meta:creation-date"); // Note that, for the OpenDocument standard, dc.date // is the last modification date & time. WRITE_METADATA_ELEMENT(PD_META_KEY_DATE_LAST_CHANGED, "dc:date"); WRITE_METADATA_ELEMENT("meta:print-date", "meta:print-date"); WRITE_METADATA_ELEMENT(PD_META_KEY_LANGUAGE, "dc:language"); #undef WRITE_METADATA_ELEMENT ODe_writeToStream(meta, postamble, G_N_ELEMENTS(postamble)); ODe_gsf_output_close(meta); return true; }
bool ODe_DocumentData::writeContentXML(GsfOutfile* pOdt) { GsfOutput* pContentStream; pContentStream = gsf_outfile_new_child (pOdt, "content.xml", FALSE); const char * const preamble [] = { "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", "\n", "<office:document-content" " xmlns:office=\"urn:oasis:names:tc:opendocument:xmlns:office:1.0\"" " xmlns:style=\"urn:oasis:names:tc:opendocument:xmlns:style:1.0\"" " xmlns:text=\"urn:oasis:names:tc:opendocument:xmlns:text:1.0\"" " xmlns:table=\"urn:oasis:names:tc:opendocument:xmlns:table:1.0\"" " xmlns:draw=\"urn:oasis:names:tc:opendocument:xmlns:drawing:1.0\"" " xmlns:fo=\"urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0\"" " xmlns:xlink=\"http://www.w3.org/1999/xlink\"" " xmlns:dc=\"http://purl.org/dc/elements/1.1/\"" " xmlns:meta=\"urn:oasis:names:tc:opendocument:xmlns:meta:1.0\"" " xmlns:number=\"urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0\"" " xmlns:svg=\"urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0\"" " xmlns:chart=\"urn:oasis:names:tc:opendocument:xmlns:chart:1.0\"" " xmlns:dr3d=\"urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0\"" " xmlns:math=\"http://www.w3.org/1998/Math/MathML\"" " xmlns:form=\"urn:oasis:names:tc:opendocument:xmlns:form:1.0\"" " xmlns:script=\"urn:oasis:names:tc:opendocument:xmlns:script:1.0\"" " xmlns:ooo=\"http://openoffice.org/2004/office\"" " xmlns:ooow=\"http://openoffice.org/2004/writer\"" " xmlns:oooc=\"http://openoffice.org/2004/calc\"" " xmlns:dom=\"http://www.w3.org/2001/xml-events\"" " xmlns:xforms=\"http://www.w3.org/2002/xforms\"" " xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"" " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" " xmlns:delta=\"http://www.deltaxml.com/ns/track-changes/delta-namespace\"" " xmlns:ac=\"http://www.deltaxml.com/ns/track-changes/attribute-change-namespace\"" " xmlns:split=\"http://www.deltaxml.com/ns/track-changes/split-namespace\"" " office:version=\"1.1\">\n"}; ODe_writeToStream(pContentStream, preamble, G_N_ELEMENTS(preamble)); m_contentXMLFontDecls.write( pContentStream ); m_contentAutoStyles.write( pContentStream ); m_contentRevisions.write( pContentStream, m_pAbiDoc ); ODe_writeUTF8String(pContentStream, " <office:body>\n" " <office:text>\n"); // FIXME: here OR the one above? // m_contentRevisions.write( pContentStream, m_pAbiDoc ); ODe_gsf_output_write(pContentStream, gsf_output_size (m_pOfficeTextTemp), gsf_output_memory_get_bytes (GSF_OUTPUT_MEMORY (m_pOfficeTextTemp))); ODe_gsf_output_close (m_pOfficeTextTemp); m_pOfficeTextTemp = NULL; ODe_writeUTF8String(pContentStream, " </office:text>\n" " </office:body>\n" "</office:document-content>"); ODe_gsf_output_close(pContentStream); return true; }
bool ODe_DocumentData::writeStylesXML(GsfOutfile* pOdt) const { GsfOutput* pStylesStream; UT_GenericVector<ODe_Style_MasterPage*>* pMasterPageVector; bool ok; UT_uint32 count, i; pStylesStream = gsf_outfile_new_child (pOdt, "styles.xml", FALSE); const char * const preamble [] = { "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", "\n", "<office:document-styles" " xmlns:office=\"urn:oasis:names:tc:opendocument:xmlns:office:1.0\"" " xmlns:style=\"urn:oasis:names:tc:opendocument:xmlns:style:1.0\"" " xmlns:text=\"urn:oasis:names:tc:opendocument:xmlns:text:1.0\"" " xmlns:table=\"urn:oasis:names:tc:opendocument:xmlns:table:1.0\"" " xmlns:draw=\"urn:oasis:names:tc:opendocument:xmlns:drawing:1.0\"" " xmlns:fo=\"urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0\"" " xmlns:xlink=\"http://www.w3.org/1999/xlink\"" " xmlns:dc=\"http://purl.org/dc/elements/1.1/\"" " xmlns:meta=\"urn:oasis:names:tc:opendocument:xmlns:meta:1.0\"" " xmlns:number=\"urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0\"" " xmlns:svg=\"urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0\"" " xmlns:chart=\"urn:oasis:names:tc:opendocument:xmlns:chart:1.0\"" " xmlns:dr3d=\"urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0\"" " xmlns:math=\"http://www.w3.org/1998/Math/MathML\"" " xmlns:form=\"urn:oasis:names:tc:opendocument:xmlns:form:1.0\"" " xmlns:script=\"urn:oasis:names:tc:opendocument:xmlns:script:1.0\"" " xmlns:ooo=\"http://openoffice.org/2004/office\"" " xmlns:ooow=\"http://openoffice.org/2004/writer\"" " xmlns:oooc=\"http://openoffice.org/2004/calc\"" " xmlns:dom=\"http://www.w3.org/2001/xml-events\"" " office:version=\"1.1\">\n"}; ODe_writeToStream(pStylesStream, preamble, G_N_ELEMENTS(preamble)); m_stylesXMLFontDecls.write(pStylesStream); m_styles.write(pStylesStream); m_stylesAutoStyles.write(pStylesStream); ODe_writeUTF8String(pStylesStream, " <office:master-styles>\n"); pMasterPageVector = m_masterStyles.enumerate(); count = pMasterPageVector->getItemCount(); for (i=0; i<count; i++) { ok = (*pMasterPageVector)[i]->write(pStylesStream); if (!ok) { return false; } } ODe_writeUTF8String(pStylesStream, " </office:master-styles>\n"); ODe_writeUTF8String(pStylesStream, "</office:document-styles>"); ODe_gsf_output_close(pStylesStream); return true; }
void ODe_Frame_Listener::_openODTextbox(const PP_AttrProp& rAP, ODe_ListenerAction& /*rAction*/) { UT_UTF8String output; UT_UTF8String str; bool ok; const gchar* pValue = NULL; ODe_Style_Style* pStyle; pStyle = new ODe_Style_Style(); pStyle->setFamily("graphic"); pStyle->fetchAttributesFromAbiFrame(rAP); // Abi frames have no padding // (no margin between frame borders and its content) pStyle->setPadding("0cm"); // Abi frames are aways positioned from its top-left corner. pStyle->setHorizontalPos("from-left"); pStyle->setVerticalPos("from-top"); // For OOo to recognize a textbox as being a textbox, it will // need to have the parent style name "Frame". I can't find it // in the ODF spec, but without it OOo considers the textbox to // be a generic drawing object (check the Navigator window in OOo). pStyle->setParentStyleName("Frame"); // Make sure an (empty) Frame style exists, for completeness sake // (OOo doesn't seem to care if it exists or not). if (!m_rStyles.getGraphicsStyle("Frame")) { ODe_Style_Style* pFrameStyle = new ODe_Style_Style(); pFrameStyle->setStyleName("Frame"); pFrameStyle->setFamily("graphic"); m_rStyles.addGraphicsStyle(pFrameStyle); } m_rAutomatiStyles.storeGraphicStyle(pStyle); //// // Write <draw:frame> _printSpacesOffset(output); output += "<draw:frame"; UT_UTF8String_sprintf(str, "Frame%u", m_rAuxiliaryData.m_frameCount+1); ODe_writeAttribute(output, "draw:name", str); m_rAuxiliaryData.m_frameCount++; ODe_writeAttribute(output, "draw:style-name", pStyle->getName()); UT_UTF8String_sprintf(str, "%u", m_zIndex); ODe_writeAttribute(output, "draw:z-index", str); ok = rAP.getProperty("position-to", pValue); if (pValue && !strcmp(pValue, "block-above-text")) { ODe_writeAttribute(output, "text:anchor-type", "paragraph"); ok = rAP.getProperty("xpos", pValue); UT_ASSERT(ok && pValue != NULL); ODe_writeAttribute(output, "svg:x", pValue); ok = rAP.getProperty("ypos", pValue); UT_ASSERT(ok && pValue != NULL); ODe_writeAttribute(output, "svg:y", pValue); } else { // Everything else (column and page) will be treated as page // anchored. ODe_writeAttribute(output, "text:anchor-type", "page"); if(pValue && !strcmp(pValue, "column-above-text")) { // // Get the most recent page style so we can do the arithmetic // Won't work for x in multi-columned docs // UT_uint32 numPStyles = m_rAutomatiStyles.getSectionStylesCount(); UT_UTF8String stylePName; UT_UTF8String_sprintf(stylePName, "PLayout%d", numPStyles + 1); ODe_Style_PageLayout * pPageL = m_rAutomatiStyles.getPageLayout(stylePName.utf8_str()); ok = rAP.getProperty("frame-col-xpos", pValue); UT_ASSERT(ok && pValue != NULL); double xCol = UT_convertToInches(pValue); const gchar* pSVal= pPageL->getPageMarginLeft(); double xPageL = UT_convertToInches(pSVal); double xTot = xPageL + xCol; pValue = UT_convertInchesToDimensionString(DIM_IN,xTot,"4"); ODe_writeAttribute(output, "svg:x", pValue); ok = rAP.getProperty("frame-col-ypos", pValue); UT_ASSERT(ok && pValue != NULL); double yCol = UT_convertToInches(pValue); pSVal= pPageL->getPageMarginTop(); double yPageL = UT_convertToInches(pSVal); double yTot = yPageL + yCol; pValue = UT_convertInchesToDimensionString(DIM_IN,yTot,"4"); ODe_writeAttribute(output, "svg:y", pValue); } else { ok = rAP.getProperty("frame-page-xpos", pValue); UT_ASSERT(ok && pValue != NULL); ODe_writeAttribute(output, "svg:x", pValue); ok = rAP.getProperty("frame-page-ypos", pValue); UT_ASSERT(ok && pValue != NULL); ODe_writeAttribute(output, "svg:y", pValue); } } ok = rAP.getProperty("frame-width", pValue); if (ok && pValue != NULL) { ODe_writeAttribute(output, "svg:width", pValue); } output += ">\n"; ODe_writeUTF8String(m_pTextOutput, output); m_spacesOffset++; //// // Write <draw:text-box> output.clear(); _printSpacesOffset(output); output += "<draw:text-box"; ok = rAP.getProperty("frame-height", pValue); if (ok && pValue != NULL) { ODe_writeAttribute(output, "fo:min-height", pValue); } output += ">\n"; ODe_writeUTF8String(m_pTextOutput, output); m_spacesOffset++; }
void ODe_Note_Listener::_closeNote(ODe_ListenerAction& rAction) { ODe_writeUTF8String(m_pTextOutput, "</text:note-body></text:note>"); rAction.popListenerImpl(); }