void OpfListener::startElement(const gchar* name, const gchar** atts) { if (!UT_go_utf8_collate_casefold(name, "manifest")) { m_inManifest = true; } if (!UT_go_utf8_collate_casefold(name, "spine")) { m_inSpine = true; } if (m_inManifest) { if (!UT_go_utf8_collate_casefold(name, "item")) { m_manifestItems.insert( make_pair(std::string(UT_getAttribute("id", atts)), std::string(UT_getAttribute("href", atts)))); UT_DEBUGMSG(("Found manifest item: %s\n", UT_getAttribute("href", atts))); } } if (m_inSpine) { if (!UT_go_utf8_collate_casefold(name, "itemref")) { // We can ignore "linear" attribute as it said in specification m_spine.push_back(std::string(UT_getAttribute("idref", atts))); UT_DEBUGMSG(("Found spine itemref: %s\n", UT_getAttribute("idref", atts))); } } }
void ODi_Style_PageLayout::startElement(const gchar* pName, const gchar** ppAtts, ODi_ListenerStateAction& /*rAction*/) { const gchar* pVal; if (!strcmp("style:page-layout", pName)) { pVal = UT_getAttribute ("style:name", ppAtts); UT_ASSERT(pVal); m_name = pVal; } else if (!strcmp("style:page-layout-properties", pName)) { _parsePageLayoutProperties(ppAtts); } else if (!strcmp("style:columns", pName)) { pVal = UT_getAttribute ("fo:column-count", ppAtts); if (pVal) { if (!strcmp(pVal,"0")) { // see Bug 10076 pVal = "1"; } m_columnCount = pVal; } pVal = UT_getAttribute ("fo:column-gap", ppAtts); if (pVal) { m_columnGap = pVal; } } else if (!strcmp("style:column-sep", pName)) { pVal = UT_getAttribute ("style:width", ppAtts); if (pVal) { if (UT_convertDimensionless(pVal) > 0) { m_columnLine = "on"; } } if(m_columnLine.empty()) { pVal = UT_getAttribute ("style:style", ppAtts); } else { pVal = NULL; //m_columnLine is already set to "on" - don't bother looking up more props } if (pVal) { if (strcmp(pVal,"none")) { m_columnLine = "on"; } } } else if (!strcmp("style:header-footer-properties", pName)) { _parseHeaderFooterProperties(ppAtts); } else if (!strcmp("style:background-image", pName)) { _parseBackgroundImage(ppAtts); } }
bool pt_PieceTable::insertStruxBeforeFrag(pf_Frag * pF, PTStruxType pts, const gchar ** attributes, pf_Frag_Strux ** ppfs_ret) { UT_return_val_if_fail(pF , false); pf_Frag_Strux * pfs = NULL; if(!_makeStrux(pts, attributes, pfs) || !pfs) return false; if(attributes) { const gchar * pXID = UT_getAttribute(PT_XID_ATTRIBUTE_NAME, attributes); UT_uint32 iXID = 0; if(pXID && *pXID) { iXID = atoi(pXID); pfs->setXID(iXID); } } m_fragments.insertFragBefore(pF, pfs); if (ppfs_ret) *ppfs_ret = pfs; return true; }
bool pt_PieceTable::insertStruxBeforeFrag(pf_Frag * pF, PTStruxType pts, const gchar ** attributes, pf_Frag_Strux ** ppfs_ret) { UT_return_val_if_fail(pF , false); pf_Frag_Strux * pfs = NULL; if(!_makeStrux(pts, attributes, pfs) || !pfs) return false; if(attributes) { const gchar * pXID = UT_getAttribute(PT_XID_ATTRIBUTE_NAME, attributes); UT_uint32 iXID = 0; if(pXID && *pXID) { iXID = atoi(pXID); pfs->setXID(iXID); } } m_fragments.insertFragBefore(pF, pfs); if (ppfs_ret) *ppfs_ret = pfs; // insert frag in the embedded_strux list if needed if ((pts == PTX_EndFootnote) || (pts == PTX_EndEndnote) || (pts == PTX_EndAnnotation)) { _insertNoteInEmbeddedStruxList(pfs); } return true; }
void ContainerListener::startElement(const gchar* name, const gchar** atts) { if (!UT_go_utf8_collate_casefold(name, "rootfile")) { m_rootFilePath = std::string(UT_getAttribute("full-path", atts)); UT_DEBUGMSG(("Found rootfile%s\n", m_rootFilePath.c_str())); } }
bool pt_PieceTable::appendStyle(const gchar ** attributes) { // this function can only be called while loading the document. //UT_ASSERT(m_pts==PTS_Loading); // first, store the attributes and properties and get an index to them. PT_AttrPropIndex indexAP; if (!m_varset.storeAP(attributes,&indexAP)) return false; // verify unique name UT_ASSERT_HARMLESS(sizeof(char) == sizeof(gchar)); const char * szName = UT_getAttribute(PT_NAME_ATTRIBUTE_NAME, attributes); if (!szName || !*szName) { UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN); return true; // silently ignore unnamed styles } UT_DEBUGMSG(("STYLE: Appending style %s \n",szName)); PD_Style * pStyle = NULL; if (getStyle(szName,&pStyle) == true) { // duplicate name UT_return_val_if_fail (pStyle, false); if (pStyle->isUserDefined()) { // already loaded, ignore redefinition UT_DEBUGMSG(("appendStyle[%s]: duplicate definition ignored\n", szName)); return true; } // override builtin definition return pStyle->setIndexAP(indexAP); } else { // this is a new name pStyle = new PD_Style(this, indexAP, szName); UT_DEBUGMSG(("STYLE: Creating new style %s saving in hash \n",szName)); // // TODO: Learn how to use Dom's AbiObject instead of this hack. // Rob asks, as AbiObject is no more, is this still a hack? // if (pStyle) m_hashStyles.insert(szName,pStyle); return true; } }
/** * Adds a <style:page-layout> (ODi_Style_PageLayout class) * * @return The address of the newly created ODi_Style_PageLayout. */ ODi_Style_PageLayout* ODi_Office_Styles::addPageLayout(const gchar** ppAtts, ODi_ElementStack& rElementStack, ODi_Abi_Data& rAbiData) { const gchar* pAttrValue; ODi_Style_PageLayout* pStyle; pStyle = new ODi_Style_PageLayout(rElementStack, rAbiData); pAttrValue = UT_getAttribute("style:name", ppAtts); m_pageLayoutStyles.insert(std::make_pair(pAttrValue, pStyle)); return pStyle; }
/** * Adds a <style:master-page> (ODi_Style_MasterPage class) * * @return The address of the newly created ODi_Style_MasterPage. */ ODi_Style_MasterPage* ODi_Office_Styles::addMasterPage(const gchar** ppAtts, PD_Document* pDocument, ODi_ElementStack& rElementStack) { const gchar* pAttrValue; ODi_Style_MasterPage* pStyle; pStyle = new ODi_Style_MasterPage(pDocument, rElementStack); pAttrValue = UT_getAttribute("style:name", ppAtts); m_masterPageStyles.insert(std::make_pair(pAttrValue, pStyle)); return pStyle; }
/** * Adds a list style (<text:list-style>) */ ODi_Style_List* ODi_Office_Styles::addList(const gchar** ppAtts, ODi_ElementStack& rElementStack) { const gchar* pAttrValue = NULL; ODi_Style_List* pStyle = NULL; pStyle = new ODi_Style_List(rElementStack); pAttrValue = UT_getAttribute("style:name", ppAtts); UT_DEBUGMSG(("Adding list |%s| to outline collection \n",pAttrValue)); m_listStyles.insert(std::make_pair(pAttrValue, pStyle)); return pStyle; }
/** * Parses <style:header-footer-properties> start tags. */ void ODi_Style_PageLayout::_parseHeaderFooterProperties(const gchar** ppAtts) { const gchar* pVal = NULL; pVal = UT_getAttribute ("svg:height", ppAtts); if (m_rElementStack.hasElement("style:header-style")) { m_headerHeight = pVal; pVal = UT_getAttribute ("fo:margin-bottom", ppAtts); if (pVal) { m_headerMarginBottom = pVal; } } else { UT_ASSERT(m_rElementStack.hasElement("style:footer-style")); m_footerHeight = pVal; pVal = UT_getAttribute ("fo:margin-top", ppAtts); if (pVal) { m_footerMarginTop = pVal; } } }
/** * Adds a notes configuration (<text:notes-configuration>) */ ODi_NotesConfiguration* ODi_Office_Styles::addNotesConfiguration( const gchar** ppAtts, ODi_ElementStack& rElementStack) { const gchar* pAttrValue = NULL; ODi_NotesConfiguration* pNotesConfig = NULL; pNotesConfig = new ODi_NotesConfiguration(rElementStack); pAttrValue = UT_getAttribute("text:note-class", ppAtts); m_notesConfigurations.insert(std::make_pair(pAttrValue, pNotesConfig)); return pNotesConfig; }
bool pt_PieceTable::appendStrux(PTStruxType pts, const gchar ** attributes, pf_Frag_Strux ** ppfs_ret) { pf_Frag_Strux * pfs = NULL; if(!_makeStrux(pts, attributes, pfs) || !pfs) return false; if(attributes) { const gchar * pXID = UT_getAttribute(PT_XID_ATTRIBUTE_NAME, attributes); UT_uint32 iXID = 0; if(pXID && *pXID) { iXID = atoi(pXID); pfs->setXID(iXID); } } pf_Frag * pfPrev = m_fragments.getLast(); bool bDoInsertFmt = false; if(pfPrev != NULL && pfPrev->getType() == pf_Frag::PFT_Strux) { pf_Frag_Strux * pfsPrev = static_cast<pf_Frag_Strux *>(pfPrev); if(pfsPrev->getStruxType() == PTX_Block) { bDoInsertFmt = true; } } m_fragments.appendFrag(pfs); // insert frag in the embedded_strux list if needed if ((pts == PTX_EndFootnote) || (pts == PTX_EndEndnote) || (pts == PTX_EndAnnotation)) { _insertNoteInEmbeddedStruxList(pfs); } if(bDoInsertFmt) { insertFmtMarkBeforeFrag(static_cast<pf_Frag *>(pfs)); } if (ppfs_ret) *ppfs_ret = pfs; return true; }
bool pt_PieceTable::appendObject(PTObjectType pto, const gchar ** attributes) { pf_Frag_Object * pfo = NULL; if(!_makeObject(pto,attributes,pfo) || !pfo) return false; if(attributes) { const gchar * pXID = UT_getAttribute(PT_XID_ATTRIBUTE_NAME, attributes); UT_uint32 iXID = 0; if(pXID && *pXID) { iXID = atoi(pXID); pfo->setXID(iXID); } } m_fragments.appendFrag(pfo); return true; }
ODi_Style_Style* ODi_Office_Styles::addDefaultStyle(const gchar** ppAtts, ODi_ElementStack& rElementStack, ODi_Abi_Data & rAbiData) { const gchar* pAttr = NULL; pAttr = UT_getAttribute("style:family", ppAtts); if (pAttr && !strcmp("paragraph", pAttr)) { return m_paragraphStyleStyles.addDefaultStyle(rElementStack,rAbiData); } else if (pAttr && !strcmp("table", pAttr)) { return m_tableStyleStyles.addDefaultStyle(rElementStack,rAbiData); } else { // Not currently supported return NULL; } }
/** * Parses the <style:background-image> start tag. */ void ODi_Style_PageLayout::_parseBackgroundImage(const gchar** ppAtts) { const gchar* pVal = NULL; pVal = UT_getAttribute ("xlink:href", ppAtts); if(!pVal) { // this is a perfectly valid case. UT_DEBUGMSG(("ODT import: no background image found.\n")); return; } UT_String dataId; // id of the data item that contains the image. if(!m_rAbiData.addImageDataItem(dataId, ppAtts)) { UT_DEBUGMSG(("ODT import: no suitable image importer found\n")); return; } m_backgroundImage = dataId.c_str(); }
bool pt_PieceTable::_makeStrux(PTStruxType pts, const gchar ** attributes, pf_Frag_Strux * &pfs) { // create a new structure fragment at the current end of the document. // this function can only be called while loading the document. UT_return_val_if_fail (m_pts==PTS_Loading, false); // first, store the attributes and properties and get an index to them. PT_AttrPropIndex indexAP; if (!m_varset.storeAP(attributes,&indexAP)) return false; // // OK we've got to interogate attributes to determine what sort of section strux // we have. // if((pts == PTX_Section) && (attributes != NULL)) { const char * szStruxType = UT_getAttribute("type",attributes); if(szStruxType) { if(strcmp(szStruxType,"header") == 0 || strcmp(szStruxType,"footer") == 0 || strcmp(szStruxType,"header-even") == 0 || strcmp(szStruxType,"footer-even") == 0 || strcmp(szStruxType,"header-first") == 0 || strcmp(szStruxType,"footer-first") == 0 || strcmp(szStruxType,"header-last") == 0 || strcmp(szStruxType,"footer-last") == 0) { pts = PTX_SectionHdrFtr; } } } if (!_createStrux(pts,indexAP,&pfs)) return false; return true; }
/** * Parses the <style:page-layout-properties> start tag. */ void ODi_Style_PageLayout::_parsePageLayoutProperties(const gchar** ppAtts) { const gchar* pVal = NULL; _parsePageDimension( m_pageWidth, UT_getAttribute ("fo:page-width", ppAtts) ); _parsePageDimension( m_pageHeight, UT_getAttribute ("fo:page-height", ppAtts) ); _parsePageDimension( m_marginLeft, UT_getAttribute ("fo:margin-left", ppAtts) ); _parsePageDimension( m_marginTop, UT_getAttribute ("fo:margin-top", ppAtts) ); _parsePageDimension( m_marginRight, UT_getAttribute ("fo:margin-right", ppAtts) ); _parsePageDimension( m_marginBottom, UT_getAttribute ("fo:margin-bottom",ppAtts) ); pVal = UT_getAttribute ("style:print-orientation", ppAtts); if (pVal) { m_printOrientation = pVal; } pVal = UT_getAttribute ("fo:background-color", ppAtts); if (pVal) { m_backgroundColor = pVal; } }
bool pt_PieceTable::insertObjectBeforeFrag(pf_Frag * pF, PTObjectType pto, const gchar ** attributes) { // cannot insert before first fragment UT_return_val_if_fail(pF && pF->getPrev() && pF != m_fragments.getFirst(), false); pf_Frag_Object * pfo = NULL; if(!_makeObject(pto,attributes,pfo) || !pfo) return false; if(attributes) { const gchar * pXID = UT_getAttribute(PT_XID_ATTRIBUTE_NAME, attributes); UT_uint32 iXID = 0; if(pXID && *pXID) { iXID = atoi(pXID); pfo->setXID(iXID); } } m_fragments.insertFragBefore(pF, pfo); return true; }
bool AP_Dialog_Paragraph::setDialogData(const gchar ** pProps) { UT_return_val_if_fail (pProps, false); // NOTICE : When setting values, this function always calls // NOTICE : _set[thing]ItemValue() with the bToggleDirty flag // NOTICE : set to false, because these are the "un-dirty" // NOTICE : values. if (pProps[0]) { const gchar * sz; sz = UT_getAttribute("text-align", pProps); if (sz) { tAlignState t = align_LEFT; if (strcmp(sz, "center") == 0) t = align_CENTERED; else if (strcmp(sz, "right") == 0) t = align_RIGHT; else if (strcmp(sz, "justify") == 0) t = align_JUSTIFIED; else if (strcmp(sz, "left") == 0) t = align_LEFT; else UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN); _setMenuItemValue(id_MENU_ALIGNMENT, t, op_INIT); } sz = UT_getAttribute("dom-dir", pProps); if (sz) { tCheckState t = check_FALSE; if (strcmp(sz, "ltr") == 0) t = check_FALSE; else if (strcmp(sz, "rtl") == 0) t = check_TRUE; else UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN); _setCheckItemValue(id_CHECK_DOMDIRECTION, t, op_INIT); } sz = UT_getAttribute("margin-left", pProps); if (sz) _setSpinItemValue(id_SPIN_LEFT_INDENT, sz, op_INIT); sz = UT_getAttribute("margin-right", pProps); if (sz) _setSpinItemValue(id_SPIN_RIGHT_INDENT, sz, op_INIT); sz = UT_getAttribute("text-indent", pProps); if (sz) { // NOTE : Calling UT_convertDimensionless() _discards_ all // NOTE : unit system information. IFF all units are // NOTE : consistent among all paragraph properties will // NOTE : the comparisons be valid. For now this should be // NOTE : valid. if (UT_convertDimensionless(sz) > (double) 0) { // if text-indent is greater than margin-left, we have a "first line" case _setMenuItemValue(id_MENU_SPECIAL_INDENT, indent_FIRSTLINE, op_INIT); } else if (UT_convertDimensionless(sz) < (double) 0) { // if text-indent is less than margin-left, we have a "hanging" case _setMenuItemValue(id_MENU_SPECIAL_INDENT, indent_HANGING, op_INIT); } else { // they're equal then there's nothing special about them _setMenuItemValue(id_MENU_SPECIAL_INDENT, indent_NONE, op_INIT); } // set the value regardless; dialog will enable/disable field // if spacing is "NONE". Must flip the sign (strip minus) // to give illusion of Word's definitions of indent/margin. const gchar * newSz = sz; if (sz[0] == '-') newSz++; _setSpinItemValue(id_SPIN_SPECIAL_INDENT, newSz, op_INIT); } sz = UT_getAttribute("line-height", pProps); if (sz) { UT_uint32 nLen = strlen(sz); if (nLen > 0) { const char * pPlusFound = strrchr(sz, '+'); if (pPlusFound && *(pPlusFound + 1) == 0) { _setMenuItemValue(id_MENU_SPECIAL_SPACING, spacing_ATLEAST, op_INIT); // need to strip off that plus int posPlus = pPlusFound - (char*) sz; UT_return_val_if_fail (posPlus>=0, false); UT_return_val_if_fail (posPlus<100, false); char pTmp[100]; strcpy(pTmp, sz); pTmp[posPlus] = 0; _setSpinItemValue(id_SPIN_SPECIAL_SPACING, (gchar*)pTmp, op_INIT); } else { if(UT_hasDimensionComponent(sz)) _setMenuItemValue(id_MENU_SPECIAL_SPACING, spacing_EXACTLY, op_INIT); //see Bug 10086 for fabs() usage else if((strcmp("1.0", sz) == 0) || (fabs(UT_convertDimensionless(sz) - (double) 1.0) < 1.0e-7)) _setMenuItemValue(id_MENU_SPECIAL_SPACING, spacing_SINGLE, op_INIT); else if((strcmp("1.5", sz) == 0) || (fabs(UT_convertDimensionless(sz) - (double) 1.5) < 1.0e-7)) _setMenuItemValue(id_MENU_SPECIAL_SPACING, spacing_ONEANDHALF, op_INIT); else if((strcmp("2.0", sz) == 0) || (fabs(UT_convertDimensionless(sz) - (double) 2.0) < 1.0e-7)) _setMenuItemValue(id_MENU_SPECIAL_SPACING, spacing_DOUBLE, op_INIT); else _setMenuItemValue(id_MENU_SPECIAL_SPACING, spacing_MULTIPLE, op_INIT); // set the spin contents regardless of menu content; platforms will // enable or disable the spin item for varying states of menu _setSpinItemValue(id_SPIN_SPECIAL_SPACING, sz, op_INIT); } } } sz = UT_getAttribute("margin-top", pProps); if (sz) _setSpinItemValue(id_SPIN_BEFORE_SPACING, sz, op_INIT); sz = UT_getAttribute("margin-bottom", pProps); if (sz) _setSpinItemValue(id_SPIN_AFTER_SPACING, sz, op_INIT); { // NOTE : "orphans" and "widows" hold a number specifying the number // NOTE : of lines to consider an orphaned or widowed piece of text. // NOTE : If they're both 0 they're off. If either is greater than // NOTE : 0, then some form of control is in effect. If the property // NOTE : is not set, they're indeterminate (e.g. because we're setting // NOTE : properties for text with multiple "orphans" values), or because // NOTE : the block has no value for orphans/widows here. bool bNoOrphans = false; bool bNoWidows = false; double orphans = 0, widows = 0; sz = UT_getAttribute("orphans", pProps); if (sz) orphans = UT_convertDimensionless(sz); else bNoOrphans = true; sz = UT_getAttribute("widows", pProps); if (sz) widows = UT_convertDimensionless(sz); else bNoWidows = true; if (bNoOrphans && bNoWidows) _setCheckItemValue(id_CHECK_WIDOW_ORPHAN, check_INDETERMINATE, op_INIT); else if (orphans > 0 || widows > 0) _setCheckItemValue(id_CHECK_WIDOW_ORPHAN, check_TRUE, op_INIT); else _setCheckItemValue(id_CHECK_WIDOW_ORPHAN, check_FALSE, op_INIT); } sz = UT_getAttribute("keep-together", pProps); if (sz) { if (strcmp(sz, "yes") == 0) _setCheckItemValue(id_CHECK_KEEP_LINES, check_TRUE, op_INIT); else _setCheckItemValue(id_CHECK_KEEP_LINES, check_FALSE, op_INIT); } else _setCheckItemValue(id_CHECK_KEEP_LINES, check_INDETERMINATE, op_INIT); sz = UT_getAttribute("keep-with-next", pProps); if (sz) { if (strcmp(sz, "yes") == 0) _setCheckItemValue(id_CHECK_KEEP_NEXT, check_TRUE, op_INIT); else _setCheckItemValue(id_CHECK_KEEP_NEXT, check_FALSE, op_INIT); } else _setCheckItemValue(id_CHECK_KEEP_NEXT, check_INDETERMINATE, op_INIT); // these are not like the others, they set fields on this, not dialogData. sz = UT_getAttribute("page-margin-left", pProps); if (sz) { m_pageLeftMargin = g_strdup(sz); } else { m_pageLeftMargin = g_strdup(PP_lookupProperty("page-margin-left")->getInitial()); } sz = UT_getAttribute("page-margin-right", pProps); if (sz) { m_pageRightMargin = g_strdup(sz); } else { m_pageRightMargin = g_strdup(PP_lookupProperty("page-margin-right")->getInitial()); } // TODO : add these to PP_Property (pp_Property.cpp) !!! // TODO : and to FV_View::getBlockFormat (or else they won't come in) /* m_pageBreakBefore; m_suppressLineNumbers; m_noHyphenate; */ } return true; }
bool pt_PieceTable::_realChangeSpanFmt(PTChangeFmt ptc, PT_DocPosition dpos1, PT_DocPosition dpos2, const gchar ** attributes, const gchar ** properties, bool bRevisionDelete) { // apply a span-level formatting change to the given region. UT_return_val_if_fail (m_pts==PTS_Editing,false); _tweakFieldSpan(dpos1,dpos2); // // Deal with case of exactly selecting the endOfFootnote // pf_Frag * pfEndDum = m_fragments.findFirstFragBeforePos(dpos2); if(isEndFootnote(pfEndDum)) { if(dpos2 > dpos1) { dpos2--; } } // // Deal with addStyle // bool bApplyStyle = (PTC_AddStyle == ptc); const gchar ** sProps = NULL; const gchar ** lProps = properties; if(bApplyStyle) { // // OK for styles we expand out all defined properties including BasedOn styles // Then we use these to eliminate any specfic properties in the current strux // Then properties in the current strux will resolve to those defined in the // style (they exist there) to specifc values in strux (if not overridden by // the style) then finally to default value. // const gchar * szStyle = UT_getAttribute(PT_STYLE_ATTRIBUTE_NAME,attributes); PD_Style * pStyle = NULL; UT_return_val_if_fail (szStyle,false); getDocument()->getStyle(szStyle,&pStyle); UT_return_val_if_fail (pStyle,false); UT_Vector vProps; // // Get the vector of properties // pStyle->getAllProperties(&vProps,0); // // Finally make the const gchar * array of properties // UT_uint32 countp = vProps.getItemCount() + 1; sProps = (const gchar **) UT_calloc(countp, sizeof(gchar *)); countp--; UT_uint32 i; for(i=0; i<countp; i++) { sProps[i] = (const gchar *) vProps.getNthItem(i); } sProps[i] = NULL; lProps = sProps; } if (dpos1 == dpos2) // if length of change is zero, then we have a toggle format. { UT_uint32 startUndoPos = m_history.getUndoPos(); bool bRes = _insertFmtMarkFragWithNotify(ptc,dpos1,attributes,lProps); UT_uint32 endUndoPos = m_history.getUndoPos(); // Won't be a persistant change if it's just a toggle PX_ChangeRecord *pcr=0; m_history.getUndo(&pcr,true); if (pcr && (startUndoPos != endUndoPos) ) { UT_DEBUGMSG(("Setting persistance of change to false\n")); pcr->setPersistance(false); m_history.setSavePosition(m_history.getSavePosition()+1); } if(bApplyStyle) { FREEP(sProps); } return bRes; } UT_return_val_if_fail (dpos1 < dpos2,false); bool bHaveAttributes, bHaveProperties; bHaveAttributes = (attributes && *attributes); bHaveProperties = (lProps && *lProps); pf_Frag * pf_First; pf_Frag * pf_End; PT_BlockOffset fragOffset_First; PT_BlockOffset fragOffset_End; bool bFound; bFound = getFragsFromPositions(dpos1,dpos2,&pf_First,&fragOffset_First,&pf_End,&fragOffset_End); UT_return_val_if_fail (bFound, false); #if 0 { pf_Frag * pf1, * pf2; PT_BlockOffset fo1, fo2; bool bFound1 = getFragFromPosition(dpos1,&pf1,&fo1); bool bFound2 = getFragFromPosition(dpos2,&pf2,&fo2); UT_return_val_if_fail (bFound1 && bFound2, false); UT_return_val_if_fail ((pf1==pf_First) && (fragOffset_First==fo1), false); UT_return_val_if_fail ((pf2==pf_End) && (fragOffset_End==fo2), false); } #endif // see if the amount of text to be changed is completely // contained within a single fragment. if so, we have a // simple change. otherwise, we need to set up a multi-step // change -- it may not actually take more than one step, // but it is too complicated to tell at this point, so we // assume it will and don't worry about it. // // we are in a simple change if the beginning and end are // within the same fragment. // NOTE: if we call beginMultiStepGlob() we ***MUST*** call // NOTE: endMultiStepGlob() before we return -- otherwise, // NOTE: the undo/redo won't be properly bracketed. bool bSimple = (pf_First == pf_End); if (!bSimple) beginMultiStepGlob(); pf_Frag_Strux * pfsContainer = NULL; pf_Frag * pfNewEnd; UT_uint32 fragOffsetNewEnd; UT_uint32 length = dpos2 - dpos1; while (length != 0) { // FIXME: Special check to support a FmtMark at the end of the // document. This is necessary because FmtMarks don't have a // length... See bug 452. if (0 == length && (!pf_First || pf_Frag::PFT_FmtMark != pf_First->getType())) break; UT_return_val_if_fail (dpos1+length==dpos2, false); UT_uint32 lengthInFrag = pf_First->getLength() - fragOffset_First; UT_uint32 lengthThisStep = UT_MIN(lengthInFrag, length); switch (pf_First->getType()) { case pf_Frag::PFT_EndOfDoc: default: UT_DEBUGMSG(("fragment type: %d\n",pf_First->getType())); UT_ASSERT_HARMLESS(0); if(bApplyStyle) { FREEP(sProps); } return false; case pf_Frag::PFT_Strux: { // we are only applying span-level changes, so we ignore strux. // but we still need to update our loop indices. pfNewEnd = pf_First->getNext(); fragOffsetNewEnd = 0; pfsContainer = static_cast<pf_Frag_Strux *> (pf_First); bool bFoundStrux = false; if(isEndFootnote(pfsContainer)) { bFoundStrux = _getStruxFromFragSkip(pfsContainer,&pfsContainer); UT_return_val_if_fail (bFoundStrux, false); } } break; case pf_Frag::PFT_Text: { if (!pfsContainer) { bool bFoundStrux; bFoundStrux = _getStruxFromPosition(dpos1,&pfsContainer); UT_return_val_if_fail (bFoundStrux,false); if(isEndFootnote(pfsContainer)) { bFoundStrux = _getStruxFromFragSkip(pfsContainer,&pfsContainer); UT_return_val_if_fail (bFoundStrux,false); } } bool bResult; bResult = _fmtChangeSpanWithNotify(ptc,static_cast<pf_Frag_Text *>(pf_First), fragOffset_First,dpos1,lengthThisStep, attributes,lProps, pfsContainer,&pfNewEnd,&fragOffsetNewEnd,bRevisionDelete); UT_return_val_if_fail (bResult,false); } break; case pf_Frag::PFT_Object: { if (!pfsContainer) { bool bFoundStrux; bFoundStrux = _getStruxFromPosition(dpos1,&pfsContainer); UT_return_val_if_fail (bFoundStrux,false); if(isEndFootnote(pfsContainer)) { bFoundStrux = _getStruxFromFragSkip(pfsContainer,&pfsContainer); UT_return_val_if_fail (bFoundStrux,false); } } bool bResult; bResult = _fmtChangeObjectWithNotify(ptc,static_cast<pf_Frag_Object *>(pf_First), fragOffset_First,dpos1,lengthThisStep, attributes,lProps, pfsContainer,&pfNewEnd,&fragOffsetNewEnd,false); UT_return_val_if_fail (bResult,false); } break; case pf_Frag::PFT_FmtMark: { if (!pfsContainer) { bool bFoundStrux; bFoundStrux = _getStruxFromPosition(dpos1,&pfsContainer); UT_return_val_if_fail (bFoundStrux,false); if(isEndFootnote(pfsContainer)) { bFoundStrux = _getStruxFromFragSkip(pfsContainer,&pfsContainer); UT_return_val_if_fail (bFoundStrux,false); } } bool bResult; bResult = _fmtChangeFmtMarkWithNotify(ptc,static_cast<pf_Frag_FmtMark *>(pf_First), dpos1, attributes,lProps, pfsContainer,&pfNewEnd,&fragOffsetNewEnd); UT_return_val_if_fail (bResult,false); } break; } dpos1 += lengthThisStep; length -= lengthThisStep; // since _fmtChange{Span,FmtMark,...}WithNotify(), can delete pf_First, mess with the // fragment list, and does some aggressive coalescing of // fragments, we cannot just do a pf_First->getNext() here. // to advance to the next fragment, we use the *NewEnd variables // that each of the cases routines gave us. pf_First = pfNewEnd; if (!pf_First) length = 0; fragOffset_First = fragOffsetNewEnd; } if(bApplyStyle) { FREEP(sProps); } if (!bSimple) endMultiStepGlob(); return true; }
/** * Adds a <style:style> (ODi_Style_Style class). * * @param bAutomatic true if the style is an OpenDocument "automatic style". * * @return The address of the newly created ODi_Style_Style or NULL, if the * specified style is not currently supported (like graphic styles). */ ODi_Style_Style* ODi_Office_Styles::addStyle(const gchar** ppAtts, ODi_ElementStack& rElementStack, ODi_Abi_Data & rAbiData) { const gchar* pFamily; const gchar* pName; const gchar* pDisplayName; ODi_Style_Style* pStyle = NULL; const ODi_Style_Style* pConstStyle; UT_UTF8String replacementName; UT_UTF8String replacementDisplayName; pFamily = UT_getAttribute("style:family", ppAtts); pName = UT_getAttribute("style:name", ppAtts); pDisplayName = UT_getAttribute("style:display-name", ppAtts); UT_ASSERT(pName); UT_return_val_if_fail(pFamily, pStyle); if(!strcmp(pFamily, "text")) { // AbiWord doesn't support two styles with the same name, differing only // on its type (eg: A "Example" character style and a "Example" // paragraph style). // Do I already have a paragraph style with this name? pConstStyle = m_paragraphStyleStyles.getStyle(pName, true); if (pConstStyle) { replacementName = pName; replacementName += "_text"; if (pDisplayName) { replacementDisplayName = pDisplayName; replacementDisplayName += "_text"; } pStyle = m_textStyleStyles.addStyle(ppAtts, rElementStack, rAbiData, &replacementName, &replacementDisplayName); } else { pStyle = m_textStyleStyles.addStyle(ppAtts, rElementStack,rAbiData); } } else if(!strcmp(pFamily, "paragraph")) { // AbiWord doesn't support two styles with the same name, differing only // on its type (eg: A "Example" character style and a "Example" // paragraph style). // Do I already have a text style with this name? pConstStyle = m_textStyleStyles.getStyle(pName, true); if (pConstStyle) { replacementName = pName; replacementName += "_paragraph"; if (pDisplayName) { replacementDisplayName = pDisplayName; replacementDisplayName += "_paragraph"; } pStyle = m_paragraphStyleStyles.addStyle(ppAtts, rElementStack, rAbiData, &replacementName, &replacementDisplayName); } else { pStyle = m_paragraphStyleStyles.addStyle(ppAtts, rElementStack,rAbiData); } } else if(!strcmp(pFamily, "section")) { pStyle = m_sectionStyleStyles.addStyle(ppAtts, rElementStack,rAbiData); } else if(!strcmp(pFamily, "graphic")) { pStyle = m_graphicStyleStyles.addStyle(ppAtts, rElementStack,rAbiData); } else if(!strcmp(pFamily, "table")) { pStyle = m_tableStyleStyles.addStyle(ppAtts, rElementStack,rAbiData); } else if(!strcmp(pFamily, "table-column")) { pStyle = m_tableColumnStyleStyles.addStyle(ppAtts, rElementStack,rAbiData); } else if(!strcmp(pFamily, "table-row")) { pStyle = m_tableRowStyleStyles.addStyle(ppAtts, rElementStack,rAbiData); } else if(!strcmp(pFamily, "table-cell")) { pStyle = m_tableCellStyleStyles.addStyle(ppAtts, rElementStack,rAbiData); } return pStyle; }
const gchar * IE_Imp_XML::_getXMLPropValue(const gchar *name, const gchar ** atts) { return UT_getAttribute(name, atts); }
const gchar* UT_getAttribute( const gchar* name, const gchar** atts, const gchar* def ) { const gchar* p = UT_getAttribute ( name, atts ); return p ? p : def; }
static bool _getTranslationCode (FV_View * pView, UT_String & langCode) { XAP_Frame * pFrame = static_cast<XAP_Frame *> (pView->getParentData()); UT_return_val_if_fail(pFrame,false); bool bRet = false; pFrame->raise(); XAP_Dialog_Id id = XAP_DIALOG_ID_LANGUAGE; XAP_DialogFactory * pDialogFactory = static_cast<XAP_DialogFactory *>(pFrame->getDialogFactory()); XAP_Dialog_Language * pDialog = static_cast<XAP_Dialog_Language *>(pDialogFactory->requestDialog(id)); UT_return_val_if_fail(pDialog,false); UT_String code ("en-US"); const gchar ** props_in = NULL; if (pView->getCharFormat(&props_in)) { const gchar * xml_code = UT_getAttribute("lang", props_in); if ( xml_code ) { code = xml_code ; if ( code.size() >= 2 ) { code = code.substr (0, 2); code += '_'; } } pDialog->setLanguageProperty(UT_getAttribute("lang", props_in)); FREEP(props_in); } // run the dialog pDialog->runModal(pFrame); // extract what they did bool bOK = (pDialog->getAnswer() == XAP_Dialog_Language::a_OK); if (bOK) { const gchar * s; if (pDialog->getChangedLangProperty(&s)) { UT_String changedLang = s; if (changedLang.size() >= 2) { code += changedLang.substr(0, 2); langCode = code; bRet = true; } } } pDialogFactory->releaseDialog(pDialog); return bRet; }
/*! * * This function loads the standard values into Delim, decimal, format * m_fAlign, m_iLevel and m_iStarValue based on m_NewListType * * m_fAlign and m_fIndent should be in inches */ void AP_Dialog_Lists::fillUncustomizedValues(void) { // if we can get the current font, we will use it where appropriate // the "NULL" string does not work too well on Windows in numbered lists const gchar** props_in = NULL; const gchar * font_family; if (getView()->getCharFormat(&props_in)) font_family = UT_getAttribute("font-family", props_in); else font_family =(const gchar *) "NULL"; if(m_NewListType == NOT_A_LIST) { m_pszDelim = "%L"; m_fAlign = 0.0; m_fIndent = 0.0; m_iLevel = 0; m_pszFont = "NULL"; m_pszDecimal = "."; m_iStartValue = 1; } if(m_iLevel <= 0) { m_iLevel = 1; } m_pszDelim = "%L"; m_fAlign = (float)(LIST_DEFAULT_INDENT * m_iLevel); m_fIndent = (float)-LIST_DEFAULT_INDENT_LABEL; if( m_NewListType == NUMBERED_LIST) { m_pszFont = font_family; m_pszDecimal = "."; m_iStartValue = 1; m_pszDelim = "%L."; } else if( m_NewListType == LOWERCASE_LIST) { m_pszFont = font_family; m_pszDecimal = "."; m_iStartValue = 1; m_pszDelim = "%L)"; } else if( m_NewListType == UPPERCASE_LIST) { m_pszFont = font_family; m_pszDecimal = "."; m_iStartValue = 1; m_pszDelim = "%L)"; } else if( m_NewListType == HEBREW_LIST) { m_pszFont = font_family; m_pszDecimal = ""; m_iStartValue = 1; m_pszDelim = "%L"; } else if( m_NewListType == ARABICNUMBERED_LIST) { m_pszFont = font_family; m_pszDecimal = ""; m_iStartValue = 1; m_pszDelim = "%L"; } else if( m_NewListType < BULLETED_LIST) { m_pszFont = "NULL"; m_pszDecimal = "."; m_iStartValue = 1; m_pszDelim = "%L"; } else { m_pszFont = "NULL"; m_pszDecimal = "."; m_iStartValue = 0; } if(m_NewListType == BULLETED_LIST || m_NewListType == IMPLIES_LIST) { m_pszFont = "Symbol"; } else if (m_NewListType == NOT_A_LIST) { m_pszFont = "NULL"; } else if(m_NewListType > DASHED_LIST && m_NewListType < OTHER_NUMBERED_LISTS) { m_pszFont = _getDingbatsFontName(); } if(props_in) g_free(props_in); }
bool ODi_Frame_ListenerState::_getFrameProperties(UT_UTF8String& rProps, const gchar** ppAtts) { const gchar* pStyleName; const ODi_Style_Style* pGraphicStyle; const UT_UTF8String* pWrap; const UT_UTF8String* pBackgroundColor; const gchar* pVal = NULL; pStyleName = m_rElementStack.getStartTag(0)->getAttributeValue("draw:style-name"); UT_ASSERT(pStyleName); pGraphicStyle = m_pStyles->getGraphicStyle(pStyleName, m_bOnContentStream); UT_return_val_if_fail(pGraphicStyle, false); pWrap = pGraphicStyle->getWrap(false); if ( !strcmp(pWrap->utf8_str(), "run-through")) { // Floating wrapping. rProps += "; wrap-mode:above-text"; } else if ( !strcmp(pWrap->utf8_str(), "left")) { rProps += "; wrap-mode:wrapped-to-left"; } else if ( !strcmp(pWrap->utf8_str(), "right")) { rProps += "; wrap-mode:wrapped-to-right"; } else if ( !strcmp(pWrap->utf8_str(), "parallel")) { rProps += "; wrap-mode:wrapped-both"; } else { // Unsupported. // Let's put an arbitrary wrap mode to avoid an error. rProps += "; wrap-mode:wrapped-both"; } pBackgroundColor = pGraphicStyle->getBackgroundColor(); if(pBackgroundColor && pBackgroundColor->length()) { rProps += "; background-color:"; rProps += pBackgroundColor->utf8_str(); } pVal = m_rElementStack.getStartTag(0)->getAttributeValue("text:anchor-type"); if (pVal && !strcmp(pVal, "paragraph")) { rProps += "; position-to:block-above-text"; pVal = m_rElementStack.getStartTag(0)->getAttributeValue("svg:x"); if (pVal) { rProps += "; xpos:"; rProps += pVal; } pVal = m_rElementStack.getStartTag(0)->getAttributeValue("svg:y"); if (pVal) { rProps += "; ypos:"; rProps += pVal; } } else if (pVal && !strcmp(pVal, "page")) { rProps += "; position-to:page-above-text"; pVal = m_rElementStack.getStartTag(0)->getAttributeValue("svg:x"); if (pVal && *pVal) { rProps += "; frame-page-xpos:"; rProps += pVal; } pVal = m_rElementStack.getStartTag(0)->getAttributeValue("svg:y"); if (pVal && *pVal) { rProps += "; frame-page-ypos:"; rProps += pVal; } } else if (pVal && (!strcmp(pVal, "char") || !strcmp(pVal, "as-char"))) { // AbiWord does not support anchoring frames/texboxes to chars; // let's just convert it to paragraph anchoring, so we don't lose the // entire frame // FIXME: "char" means an inline thing in AbiWord terms, NOT a positioned thing rProps += "; position-to:block-above-text"; pVal = m_rElementStack.getStartTag(0)->getAttributeValue("svg:x"); if (pVal && *pVal) { rProps += "; xpos:"; rProps += pVal; } pVal = m_rElementStack.getStartTag(0)->getAttributeValue("svg:y"); if (pVal && *pVal) { rProps += "; ypos:"; rProps += pVal; } } else { UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN); return false; } // From the OpenDocument standard v1.0, about text boxes properties: // // "The fo:min-height and fo:min-width attributes specify a minimum height // or width for a text box. If they are existing, they overwrite the height // or width of a text box specified by the svg:height and svg:width // attributes of the surrounding <draw:frame> element." // TODO: make a robust support for the relation between fo:min-width/height // and svg:width/height on both <draw:frame> and <draw:text-box> pVal = UT_getAttribute("fo:min-width", ppAtts); if (pVal == NULL) { pVal = m_rElementStack.getStartTag(0)->getAttributeValue("svg:width"); if (pVal == NULL) { pVal = m_rElementStack.getStartTag(0)->getAttributeValue("fo:min-width"); if (UT_determineDimension(pVal, DIM_none) == DIM_PERCENT) { // TODO: Do the conversion from percentage to a real // unit (ie: "cm" or "in"). UT_ASSERT_HARMLESS(UT_NOT_IMPLEMENTED); } } } else { if (UT_determineDimension(pVal, DIM_none) == DIM_PERCENT) { // TODO: Do the conversion from percentage to a real // unit (ie: "cm" or "in"). UT_ASSERT_HARMLESS(UT_NOT_IMPLEMENTED); } } UT_ASSERT_HARMLESS(pVal); // Is it really ok to not have a defined width? if (pVal) { rProps += "; frame-width:"; rProps += pVal; } pVal = UT_getAttribute("style:rel-width", ppAtts); if(pVal) { rProps += "; frame-rel-width:"; rProps += pVal; } else { pVal = m_rElementStack.getStartTag(0)->getAttributeValue("style:rel-width"); if(pVal) { rProps += "; frame-rel-width:"; rProps += pVal; } } pVal = UT_getAttribute("fo:min-height", ppAtts); if (pVal == NULL) { pVal = m_rElementStack.getStartTag(0)->getAttributeValue("svg:height"); if (pVal == NULL) { pVal = m_rElementStack.getStartTag(0)->getAttributeValue("fo:min-height"); if (UT_determineDimension(pVal, DIM_none) == DIM_PERCENT) { // TODO: Do the conversion from percentage to a real // unit (ie: "cm" or "in"). UT_ASSERT_HARMLESS(UT_NOT_IMPLEMENTED); } } } else { if (UT_determineDimension(pVal, DIM_none) == DIM_PERCENT) { // TODO: Do the conversion from percentage to a real // unit (ie: "cm" or "in"). UT_ASSERT_HARMLESS(UT_NOT_IMPLEMENTED); } rProps += "; frame-min-height:"; rProps += pVal; } if (pVal) { rProps += "; frame-height:"; rProps += pVal; } return true; }
/** * Adds an data item (<d> tag) in the AbiWord document for the specified image. * * Code mainly from Dom Lachowicz and/or Robert Staudinger. * * @param rDataId Receives the id that has been given to the added data item. * @param ppAtts The attributes of a <draw:image> element. */ bool ODi_Abi_Data::addImageDataItem(UT_String& rDataId, const gchar** ppAtts) { const gchar* pHRef = UT_getAttribute ("xlink:href", ppAtts); UT_return_val_if_fail(pHRef,false); // If we have a string smaller then this we are in trouble. File corrupted? UT_return_val_if_fail((strlen(pHRef) >= 10 /*10 == strlen("Pictures/a")*/), false); UT_Error error = UT_OK; UT_ByteBuf img_buf; GsfInfile* pPictures_dir; FG_Graphic* pFG = NULL; const UT_ByteBuf* pPictData = NULL; UT_uint32 imageID; // The subdirectory that holds the picture. e.g: "ObjectReplacements" or "Pictures" UT_String dirName; // The file name of the picture. e.g.: "Object 1" or "10000201000000D100000108FF0E3707.png" UT_String fileName; const std::string id = m_href_to_id[pHRef]; if (!id.empty()) { // This image was already added. // Use the existing data item id. rDataId = id; return true; } // Get a new, unique, ID. imageID = m_pAbiDocument->getUID(UT_UniqueId::Image); UT_String_sprintf(rDataId, "%d", imageID); // Add this id to the list UT_DebugOnly<href_id_map_t::iterator> iter = m_href_to_id .insert(m_href_to_id.begin(), href_id_map_t::value_type(pHRef, rDataId.c_str())); UT_ASSERT((href_id_map_t::iterator)iter != m_href_to_id.end()); _splitDirectoryAndFileName(pHRef, dirName, fileName); pPictures_dir = GSF_INFILE(gsf_infile_child_by_name(m_pGsfInfile, dirName.c_str())); UT_return_val_if_fail(pPictures_dir, false); // Loads img_buf error = _loadStream(pPictures_dir, fileName.c_str(), img_buf); g_object_unref (G_OBJECT (pPictures_dir)); if (error != UT_OK) { return false; } // Builds pImporter from img_buf error = IE_ImpGraphic::loadGraphic (img_buf, IEGFT_Unknown, &pFG); if ((error != UT_OK) || !pFG) { // pictData is already freed in ~FG_Graphic return false; } // Builds pPictData from pFG // TODO: can we get back a vector graphic? pPictData = pFG->getBuffer(); if (!pPictData) { // i don't think that this could ever happen, but... UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN); return false; } // // Create the data item. // if (!m_pAbiDocument->createDataItem(rDataId.c_str(), false, pPictData, pFG->getMimeType(), NULL)) { UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN); return false; } return true; }
/** * Adds an data item (<d> tag) in the AbiWord document for the specified image. * * Code mainly from Dom Lachowicz and/or Robert Staudinger. * * @param rDataId Receives the id that has been given to the added data item. * @param ppAtts The attributes of a <draw:image> element. */ bool ODi_Abi_Data::addObjectDataItem(UT_String& rDataId, const gchar** ppAtts, int& pto_Type) { const gchar* pHRef = UT_getAttribute ("xlink:href", ppAtts); UT_return_val_if_fail(pHRef,false); // If we have a string smaller then this we are in trouble. File corrupted? UT_return_val_if_fail((strlen(pHRef) >= 10 /*10 == strlen("Pictures/a")*/), false); UT_Error error = UT_OK; UT_ByteBuf *object_buf; GsfInfile* pObjects_dir; UT_uint32 objectID; // The subdirectory that holds the picture. e.g: "ObjectReplacements" or "Pictures" UT_String dirName; // The file name of the picture. e.g.: "Object 1" or "10000201000000D100000108FF0E3707.png" UT_String fileName; const std::string id = m_href_to_id[pHRef]; if (!id.empty()) { // This object was already added. // Use the existing data item id. rDataId = id; return true; } // Get a new, unique, ID. objectID = m_pAbiDocument->getUID(UT_UniqueId::Math); UT_String_sprintf(rDataId, "MathLatex%d", objectID); // Add this id to the list UT_DebugOnly<href_id_map_t::iterator> iter = m_href_to_id .insert(m_href_to_id.begin(), href_id_map_t::value_type(pHRef, rDataId.c_str())); UT_ASSERT((href_id_map_t::iterator)iter != m_href_to_id.end()); _splitDirectoryAndFileName(pHRef, dirName, fileName); if (fileName.empty ()) fileName = "content.xml"; pObjects_dir = GSF_INFILE(gsf_infile_child_by_name(m_pGsfInfile, dirName.c_str())); UT_return_val_if_fail(pObjects_dir, false); // Loads object_buf object_buf = new UT_ByteBuf (); error = _loadStream(pObjects_dir, fileName.c_str(), *object_buf); g_object_unref (G_OBJECT (pObjects_dir)); if (error != UT_OK) { delete object_buf; return false; } // check to ensure that we're seeing math. this can probably be made smarter. static const char math_header[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE math:math"; if ((object_buf->getLength () > strlen (math_header)) && (strncmp ((const char*)object_buf->getPointer (0), math_header, strlen (math_header)) != 0)) { delete object_buf; return false; } // // Create the data item. // if (!m_pAbiDocument->createDataItem(rDataId.c_str(), false, object_buf, "application/mathml+xml", NULL)) { UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN); return false; } pto_Type = PTO_Math; return true; }