void ODe_AbiDocListener::_closeBookmark(UT_UTF8String &sBookmarkName) { if (!m_bInBookmark || sBookmarkName.empty()) return; _closeSpan(); m_pCurrentImpl->closeBookmark(sBookmarkName); m_bInBookmark = false; m_bookmarkName.clear(); }
void ODe_DocumentData::handleDefaultTabInterval(ODe_Style_Style* pStyle) { UT_return_if_fail(pStyle); UT_UTF8String defaultTabInterval = pStyle->getDefaultTabInterval(); if (defaultTabInterval.empty()) return; // remove the default tab interval property from the style pStyle->setDefaultTabInterval(""); // ... and create a default style to hold the default tab interval property ODe_Style_Style* pDefaultStyle = m_styles.getDefaultStyles().getStyle("paragraph"); if (!pDefaultStyle) { pDefaultStyle = new ODe_Style_Style(); pDefaultStyle->setFamily("paragraph"); pDefaultStyle->makeDefaultStyle(); m_styles.getDefaultStyles().storeStyle("paragraph", pDefaultStyle); } // NOTE: if a paragraph default style already exists with a default tab interval // property set, then we'll just overwrite it. This can happen because AbiWord // supports such a property on every paragraph and paragraph style, but ODT only // supports one on the default paragraph style. pDefaultStyle->setDefaultTabInterval(defaultTabInterval); }
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; }
/** * @param ppAtts The attributes of a <draw:text-box> element. * @param rAction Any action to be taken, regarding state change. */ void ODi_Frame_ListenerState::_drawTextBox (const gchar** ppAtts, ODi_ListenerStateAction& rAction) { const gchar* attribs[3]; const gchar* pStyleName = NULL; const ODi_Style_Style* pGraphicStyle = NULL; UT_UTF8String props; UT_UTF8String sThickness; props = "frame-type:textbox"; if (!_getFrameProperties(props, ppAtts)) { // Abort mission! // <draw:frame> - 0 // <draw:text-box> - -1 // // We want to ignore the whole frame. rAction.ignoreElement(0); return; } if (!props.empty()) { props += "; "; } if (m_rElementStack.getStartTag(0)) { pStyleName = m_rElementStack.getStartTag(0)->getAttributeValue("draw:style-name"); } if (pStyleName) { pGraphicStyle = m_pStyles->getGraphicStyle(pStyleName, m_bOnContentStream); } if (pGraphicStyle) { // For now, we'll assume HAVE_BORDER_UNSPECIFIED == HAVE_BORDER_YES if (pGraphicStyle->hasBottomBorder() != ODi_Style_Style::HAVE_BORDER_NO) { props += "bot-style:1"; if(pGraphicStyle->getBorderBottom_color() && !pGraphicStyle->getBorderBottom_color()->empty()) { props += "; bot-color:"; props += *(pGraphicStyle->getBorderBottom_color()); } } else { props += "bot-style:0"; } if (pGraphicStyle->hasLeftBorder() != ODi_Style_Style::HAVE_BORDER_NO) { props += "; left-style:1"; if(pGraphicStyle->getBorderLeft_color() && !pGraphicStyle->getBorderLeft_color()->empty()) { props += "; left-color:"; props += *(pGraphicStyle->getBorderLeft_color()); } } else { props += "; left-style:0"; } if (pGraphicStyle->hasRightBorder() != ODi_Style_Style::HAVE_BORDER_NO) { props += "; right-style:1"; if(pGraphicStyle->getBorderRight_color() && !pGraphicStyle->getBorderRight_color()->empty()) { props += "; right-color:"; props += *(pGraphicStyle->getBorderRight_color()); } } else { props += "; right-style:0"; } if (pGraphicStyle->hasTopBorder() != ODi_Style_Style::HAVE_BORDER_NO) { props += "; top-style:1"; if(pGraphicStyle->getBorderTop_color() && !pGraphicStyle->getBorderTop_color()->empty()) { props += "; top-color:"; props += *(pGraphicStyle->getBorderTop_color()); } } else { props += "; top-style:0"; } if(pGraphicStyle->getBorderBottom_thickness() && !pGraphicStyle->getBorderBottom_thickness()->empty()) { sThickness.clear(); bool bRet = _convertBorderThickness(pGraphicStyle->getBorderBottom_thickness()->utf8_str(), sThickness); if(bRet) { props += "; bot-thickness:"; props += sThickness.utf8_str(); } } if(pGraphicStyle->getBorderLeft_thickness() && !pGraphicStyle->getBorderLeft_thickness()->empty()) { sThickness.clear(); bool bRet = _convertBorderThickness(pGraphicStyle->getBorderLeft_thickness()->utf8_str(), sThickness); if(bRet) { props += "; left-thickness:"; props += sThickness.utf8_str(); } } if(pGraphicStyle->getBorderRight_thickness() && !pGraphicStyle->getBorderRight_thickness()->empty()) { sThickness.clear(); bool bRet = _convertBorderThickness(pGraphicStyle->getBorderRight_thickness()->utf8_str(), sThickness); if(bRet) { props += "; right-thickness:"; props += sThickness.utf8_str(); } } if(pGraphicStyle->getBorderTop_thickness() && !pGraphicStyle->getBorderTop_thickness()->empty()) { sThickness.clear(); bool bRet = _convertBorderThickness(pGraphicStyle->getBorderTop_thickness()->utf8_str(), sThickness); if(bRet) { props += "; top-thickness:"; props += sThickness.utf8_str(); } } if(pGraphicStyle->getHorizPos(true) && !pGraphicStyle->getHorizPos(true)->empty()) { props += "; frame-horiz-align:"; props += pGraphicStyle->getHorizPos(true)->utf8_str(); } } else { //just hard-code some defaults props += "bot-style:1; left-style:1; right-style:1; top-style:1"; } attribs[0] = "props"; attribs[1] = props.utf8_str(); attribs[2] = 0; if(!m_pAbiDocument->appendStrux(PTX_SectionFrame, attribs)) { UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN); } else { m_iFrameDepth++; } // We are going to receive text content. rAction.pushState("TextContent"); }
void ODe_AbiDocListener::_outputData(const UT_UCSChar* pData, UT_uint32 length) { UT_UTF8String sBuf; const UT_UCSChar* p; UT_uint32 nSpaces = 0; UT_ASSERT(sizeof(UT_Byte) == sizeof(char)); sBuf.reserve(length); for (p=pData; (p<pData+length); /**/) { switch (*p) { case '<': if(nSpaces > 1) _appendSpaces(&sBuf, nSpaces); nSpaces = 0; sBuf += "<"; p++; break; case '>': if(nSpaces > 1) _appendSpaces(&sBuf, nSpaces); nSpaces = 0; sBuf += ">"; p++; break; case '&': if(nSpaces > 1) _appendSpaces(&sBuf, nSpaces); nSpaces = 0; sBuf += "&"; p++; break; case ' ': nSpaces++; if(nSpaces == 1) sBuf.appendUCS4 (p, 1); p++; break; case UCS_LF: // LF -- representing a Forced-Line-Break if(nSpaces > 1) _appendSpaces(&sBuf, nSpaces); nSpaces = 0; m_pCurrentImpl->insertText(sBuf); m_pCurrentImpl->insertLineBreak(); sBuf.clear(); p++; break; case UCS_VTAB: // VTAB -- representing a Forced-Column-Break if(nSpaces > 1) _appendSpaces(&sBuf, nSpaces); nSpaces = 0; m_pCurrentImpl->insertText(sBuf); m_pCurrentImpl->insertColumnBreak(); sBuf.clear(); p++; break; case UCS_TAB: if(nSpaces > 1) _appendSpaces(&sBuf, nSpaces); nSpaces = 0; m_pCurrentImpl->insertText(sBuf); m_pCurrentImpl->insertTabChar(); sBuf.clear(); p++; break; case UCS_FF: // FF -- representing a Forced-Page-Break if(nSpaces > 1) _appendSpaces(&sBuf, nSpaces); nSpaces = 0; m_pCurrentImpl->insertText(sBuf); m_pCurrentImpl->insertPageBreak(); sBuf.clear(); p++; break; default: if (*p < 0x20) // Silently eat these characters. { if(nSpaces > 1) _appendSpaces(&sBuf, nSpaces); nSpaces = 0; p++; } else { if(nSpaces > 1) _appendSpaces(&sBuf, nSpaces); nSpaces = 0; sBuf.appendUCS4 (p, 1); p++; } } } if (!sBuf.empty()) { if(nSpaces > 1) _appendSpaces(&sBuf, nSpaces); nSpaces = 0; m_pCurrentImpl->insertText(sBuf); } }
void ODe_AbiDocListener::_insertMath(PT_AttrPropIndex api) { const gchar* szMath = NULL; szMath = _getObjectKey(api, static_cast<const gchar*>("dataid")); UT_return_if_fail(szMath); const UT_ByteBuf * pByteBuf = NULL; bool bOK = m_pDocument->getDataItemDataByName(szMath, const_cast<const UT_ByteBuf **>(&pByteBuf), NULL, NULL); UT_return_if_fail(bOK); UT_UCS4_mbtowc myWC; UT_UTF8String sMathML; sMathML.appendBuf(*pByteBuf, myWC); UT_return_if_fail(!sMathML.empty()); UT_UCS4String buf = sMathML.utf8_str(); UT_UTF8String output = ""; const PP_AttrProp * pAP = NULL; bool bHaveProp = m_pDocument->getAttrProp(api,&pAP); UT_LocaleTransactor t(LC_NUMERIC, "C"); UT_UTF8String dimension; double dInch; UT_return_if_fail(bHaveProp && pAP); _openSpan(api); if(pAP->getProperty("width", szMath)) { dInch = static_cast<double>(atoi(szMath))/UT_LAYOUT_RESOLUTION; UT_UTF8String_sprintf(dimension,"%fin",dInch); output += "<draw:frame svg:width=\""; output += dimension; output += "\" svg:height=\""; } else { UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN); _closeSpan(); return; } if(pAP->getProperty("height", szMath)) { dInch = static_cast<double>(atoi(szMath))/UT_LAYOUT_RESOLUTION; dimension.clear(); UT_UTF8String_sprintf(dimension,"%fin",dInch); output += dimension; output += "\"><draw:object>"; } else { UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN); _closeSpan(); return; } for (UT_uint32 i = 0; i < buf.length(); i++) { if (buf[i] == '<') { if (((i + 1) < buf.length()) && (buf[i+1] == '/')) { output += "</math:"; i++; // skip the '/' } else if ((i + 1) < buf.length()) { output += "<math:"; } else { UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN); } } else { output += buf[i]; } } output += "</draw:object></draw:frame>"; m_pCurrentImpl->insertText(output); _closeSpan(); }