/* AbiWord * Copyright (C) 2001 AbiSource, Inc. * Copyright (C) 2002-2004 Marc Maurer (j.m.maurer@student.utwente.nl) * Copyright (C) 2002-2003 William Lachance (william.lachance@sympatico.ca) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. */ /* See bug 1764 * "This product is not manufactured, approved, or supported by * Corel Corporation or Corel Corporation Limited." */ #include #include #include #include #include #include #include #include #include "ut_types.h" #include "ut_string.h" #include "ut_string_class.h" #include "ut_units.h" #include "ut_growbuf.h" #include "ut_assert.h" #include "ut_debugmsg.h" #include "ut_math.h" // for rint (font size) #include "ut_rand.h" #include "xap_Frame.h" #include "xap_EncodingManager.h" #include "pd_Document.h" #include "pt_Types.h" #include "fl_AutoLists.h" #include "fl_AutoNum.h" #include "ap_Strings.h" #include "ie_imp_WordPerfect.h" #include "ie_impexp_WordPerfect.h" // This should probably be defined in pt_Types.h static const UT_uint32 PT_MAX_ATTRIBUTES = 8; ABI_ListDefinition::ABI_ListDefinition(int iOutlineHash) : m_iOutlineHash(iOutlineHash) { for(int i=0; i(szBuf), iNumbytes, false)); WPDConfidence confidence = WPDocument::isFileFormatSupported(input, true); switch (confidence) { case WPD_CONFIDENCE_NONE: // libwpd > 0.7.1 reports POOR if the text file is plain text (that _could_ be a WP4x document) // however, we'll let the text importer handle such cases case WPD_CONFIDENCE_POOR: return UT_CONFIDENCE_ZILCH; return UT_CONFIDENCE_POOR; case WPD_CONFIDENCE_LIKELY: return UT_CONFIDENCE_SOSO; case WPD_CONFIDENCE_GOOD: return UT_CONFIDENCE_GOOD; case WPD_CONFIDENCE_EXCELLENT: return UT_CONFIDENCE_PERFECT; default: return UT_CONFIDENCE_ZILCH; } } UT_Confidence_t IE_Imp_WordPerfect_Sniffer::recognizeSuffix (const char * szSuffix) { // We recognize both word documents and their template versions if (!UT_stricmp(szSuffix,".wpd") || !UT_stricmp(szSuffix, ".wp")) return UT_CONFIDENCE_PERFECT; return UT_CONFIDENCE_ZILCH; } UT_Error IE_Imp_WordPerfect_Sniffer::constructImporter (PD_Document * pDocument, IE_Imp ** ppie) { *ppie = new IE_Imp_WordPerfect(pDocument); return UT_OK; } bool IE_Imp_WordPerfect_Sniffer::getDlgLabels (const char ** pszDesc, const char ** pszSuffixList, IEFileType * ft) { *pszDesc = "WordPerfect (.wpd, .wp)"; *pszSuffixList = "*.wpd; *.wp"; *ft = getFileType(); return true; } /****************************************************************************/ /****************************************************************************/ IE_Imp_WordPerfect::IE_Imp_WordPerfect(PD_Document * pDocument) : IE_Imp (pDocument), m_bParagraphChanged(false), m_bParagraphInSection(false), m_bInSection(false), m_bSectionChanged(false), m_leftMargin(0.0f), m_rightMargin(0.0f), m_headerId(-1), m_footerId(-1), m_nextFreeId(0), m_leftMarginOffset(0.0f), m_rightMarginOffset(0.0f), m_pCurrentListDefinition(NULL), m_iCurrentListLevel(0), m_bInCell(false), m_bHdrFtrOpenCount(0) { } IE_Imp_WordPerfect::~IE_Imp_WordPerfect() { //UT_HASH_PURGEDATA(ABI_ListDefinition *,&m_listStylesHash,delete); } UT_Error IE_Imp_WordPerfect::importFile(const char * szFilename) { gsf_init (); GError *err; GsfInput * input; input = GSF_INPUT(gsf_input_stdio_new (szFilename, &err)); if (input == NULL) { g_return_val_if_fail (err != NULL, 1); g_warning ("'%s' error: %s", szFilename, err->message); g_error_free (err); return 1; } try { WPDocument::parse(input, static_cast(this)); } catch (FileException) { UT_DEBUGMSG(("AbiWordPerfect: ERROR: File Exception!\n")); return UT_IE_IMPORTERROR; } gsf_shutdown(); return UT_OK; } void IE_Imp_WordPerfect::pasteFromBuffer (PD_DocumentRange *, unsigned char *, unsigned int, const char *) { // nada } void IE_Imp_WordPerfect::setDocumentMetaData(const UCSString &author, const UCSString &subject, const UCSString &publisher, const UCSString &category, const UCSString &keywords, const UCSString &language, const UCSString &abstract, const UCSString &descriptiveName, const UCSString &descriptiveType) { getDoc()->setMetaDataProp(PD_META_KEY_CREATOR, UT_String(UTF8String(author).getUTF8())); getDoc()->setMetaDataProp(PD_META_KEY_SUBJECT, UT_String(UTF8String(subject).getUTF8())); getDoc()->setMetaDataProp(PD_META_KEY_PUBLISHER, UT_String(UTF8String(publisher).getUTF8())); getDoc()->setMetaDataProp(PD_META_KEY_TYPE, UT_String(UTF8String(category).getUTF8())); getDoc()->setMetaDataProp(PD_META_KEY_KEYWORDS, UT_String(UTF8String(keywords).getUTF8())); getDoc()->setMetaDataProp(PD_META_KEY_LANGUAGE, UT_String(UTF8String(language).getUTF8())); getDoc()->setMetaDataProp(PD_META_KEY_DESCRIPTION, UT_String(UTF8String(abstract).getUTF8())); } void IE_Imp_WordPerfect::startDocument() { UT_DEBUGMSG(("AbiWordPerfect: startDocument\n")); } void IE_Imp_WordPerfect::endDocument() { UT_DEBUGMSG(("AbiWordPerfect: endDocument\n")); } void IE_Imp_WordPerfect::openPageSpan(const int span, const bool isLastPageSpan, const float marginLeft, const float marginRight, const float marginTop, const float marginBottom) { if (m_bHdrFtrOpenCount) return; // HACK if ( marginLeft != m_leftMargin || marginRight != m_rightMargin //|| //marginTop != m_marginBottom "" //marginBottom != m_marginBottom ) { m_leftMargin = marginLeft; m_rightMargin = marginRight; // margin properties are section properties in AbiWord m_bSectionChanged; } } void IE_Imp_WordPerfect::openHeaderFooter(const WPXHeaderFooterType headerFooterType, const WPXHeaderFooterOccurence headerFooterOccurence) { m_bHdrFtrOpenCount++; /* TODO: THIS CODE IS NOT!!!! USEFULL! - DON'T TOUCH IT - MARCM UT_String propBuffer; switch (headerFooterType) { case HEADER: m_headerId = m_nextFreeId; UT_String_sprintf(propBuffer,"id:%d; listid:0; parentid=0; type=header", m_headerId); break; case FOOTER: m_footerId = m_nextFreeId; UT_String_sprintf(propBuffer,"id:%d; listid:0; parentid=0; type=footer", m_footerId); break; default: UT_ASSERT(SHOULD_NOT_HAPPEN); break; } const XML_Char* propsArray[3]; propsArray[0] = "props"; propsArray[1] = propBuffer.c_str(); propsArray[2] = NULL; X_CheckDocumentError(appendStrux(PTX_Section, propsArray)); m_bInSection = true; m_bSectionChanged = false;*/ } void IE_Imp_WordPerfect::closeHeaderFooter(const WPXHeaderFooterType headerFooterType, const WPXHeaderFooterOccurence headerFooterOccurence) { m_bHdrFtrOpenCount--; /* TODO: THIS CODE IS NOT!!!! USEFULL! - DON'T TOUCH IT - MARCM m_nextFreeId++; */ } void IE_Imp_WordPerfect::openParagraph(const guint8 paragraphJustification, const guint32 textAttributeBits, const float marginLeftOffset, const float marginRightOffset, const gchar *fontName, const float fontSize, const float lineSpacing, const bool isColumnBreak, const bool isPageBreak) { if (m_bHdrFtrOpenCount) return; // HACK UT_DEBUGMSG(("AbiWordPerfect: openParagraph(paragraphJustification: %d, textAttributeBits: %d)\n", paragraphJustification, textAttributeBits)); // for now, we always append these options m_leftMarginOffset = marginLeftOffset; m_rightMarginOffset = marginRightOffset; if (isPageBreak) { UT_UCS4Char ucs = UCS_FF; X_CheckDocumentError(appendSpan(&ucs,1)); } else if (isColumnBreak) { UT_UCS4Char ucs = UCS_VTAB; X_CheckDocumentError(appendSpan(&ucs,1)); } else { _appendParagraph(paragraphJustification, textAttributeBits, fontName, fontSize, lineSpacing); } } void IE_Imp_WordPerfect::openSpan(const guint32 textAttributeBits, const gchar *fontName, const float fontSize) { if (m_bHdrFtrOpenCount) return; // HACK UT_DEBUGMSG(("AbiWordPerfect: openSpan(textAttributeBits: %d)\n", textAttributeBits)); _appendSpan(textAttributeBits, fontName, fontSize); } void IE_Imp_WordPerfect::openSection(const guint numColumns, const float spaceAfter) { if (m_bHdrFtrOpenCount) return; // HACK // TODO: support spaceAfter UT_DEBUGMSG(("AbiWordPerfect: openSection(numColumns: %d)\n", numColumns)); _appendSection(numColumns, m_leftMargin, m_rightMargin); } void IE_Imp_WordPerfect::insertTab() { if (m_bHdrFtrOpenCount) return; // HACK UT_UCS4Char ucs = UCS_TAB; X_CheckDocumentError(appendSpan(&ucs,1)); } void IE_Imp_WordPerfect::insertText(const UCSString &text) { if (m_bHdrFtrOpenCount) return; // HACK if (text.getLen()) { UT_DEBUGMSG(("AbiWordPerfect: insertText\n")); X_CheckDocumentError(appendSpan(text.getUCS4(), text.getLen())); } } void IE_Imp_WordPerfect::insertLineBreak() { if (m_bHdrFtrOpenCount) return; // HACK UT_UCSChar ucs = UCS_LF; X_CheckDocumentError(appendSpan(&ucs,1)); } void IE_Imp_WordPerfect::defineOrderedListLevel(const int listID, const guint16 level, const WPXNumberingType listType, const UCSString &textBeforeNumber, const UCSString &textAfterNumber, const int startingNumber) { if (m_bHdrFtrOpenCount) return; // HACK UT_DEBUGMSG(("AbiWordPerfect: defineOrderedListLevel\n")); if (!m_pCurrentListDefinition || m_pCurrentListDefinition->getOutlineHash() != listID || (m_pCurrentListDefinition->getLevelNumber(level) != (startingNumber - 1) && level==1)) { if (m_pCurrentListDefinition) delete (m_pCurrentListDefinition); m_pCurrentListDefinition = new ABI_ListDefinition(listID); } if (!m_pCurrentListDefinition->getListID(level)) { m_pCurrentListDefinition->setListID(level, UT_rand()); m_pCurrentListDefinition->setListType(level, listType); _updateDocumentOrderedListDefinition(m_pCurrentListDefinition, level, listType, textBeforeNumber, textAfterNumber, startingNumber); } } void IE_Imp_WordPerfect::defineUnorderedListLevel(const int listID, const guint16 level, const UCSString &bullet) { if (m_bHdrFtrOpenCount) return; // HACK UT_DEBUGMSG(("AbiWordPerfect: defineUnorderedListLevel\n")); if (!m_pCurrentListDefinition || m_pCurrentListDefinition->getOutlineHash() != listID) { if (m_pCurrentListDefinition) delete (m_pCurrentListDefinition); m_pCurrentListDefinition = new ABI_ListDefinition(listID); } if (!m_pCurrentListDefinition->getListID(level)) { m_pCurrentListDefinition->setListID(level, UT_rand()); _updateDocumentUnorderedListDefinition(m_pCurrentListDefinition, level); } } void IE_Imp_WordPerfect::openOrderedListLevel(const int listID) { if (m_bHdrFtrOpenCount) return; // HACK m_iCurrentListLevel++; } void IE_Imp_WordPerfect::closeOrderedListLevel() { if (m_bHdrFtrOpenCount) return; // HACK UT_DEBUGMSG(("AbiWordPerfect: closeOrderedListLevel (level: %i)\n", m_iCurrentListLevel)); UT_ASSERT(m_iCurrentListLevel > 0); // every time we close a list level, the level above it is normally renumbered to start at "1" // again. this code takes care of that. if (m_iCurrentListLevel < (WP6_NUM_LIST_LEVELS-1)) m_pCurrentListDefinition->setLevelNumber(m_iCurrentListLevel + 1, 0); m_iCurrentListLevel--; } // ASSUMPTION: We assume that unordered lists will always pass a number of "0". unpredictable behaviour // may result otherwise void IE_Imp_WordPerfect::openListElement(const guint8 paragraphJustification, const guint32 textAttributeBits, const gchar *fontName, const float fontSize, const float lineSpacing) { if (m_bHdrFtrOpenCount) return; // HACK UT_DEBUGMSG(("AbiWordPerfect: openListElement\n")); UT_ASSERT(m_pCurrentListDefinition); // FIXME: ABI_LISTS_IMPORT throw an exception back to libwpd, if this fails // Paragraph properties for our list element UT_String szListID; UT_String szParentID; UT_String szLevel; UT_String_sprintf(szListID,"%d",m_pCurrentListDefinition->getListID(m_iCurrentListLevel)); if (m_iCurrentListLevel > 1) UT_String_sprintf(szParentID,"%d", m_pCurrentListDefinition->getListID((m_iCurrentListLevel-1))); else UT_String_sprintf(szParentID,"0"); UT_String_sprintf(szLevel,"%d", m_iCurrentListLevel); const XML_Char* listAttribs[PT_MAX_ATTRIBUTES*2 + 1]; UT_uint32 attribsCount=0; listAttribs[attribsCount++] = PT_LISTID_ATTRIBUTE_NAME; listAttribs[attribsCount++] = szListID.c_str(); listAttribs[attribsCount++] = PT_PARENTID_ATTRIBUTE_NAME; listAttribs[attribsCount++] = szParentID.c_str(); listAttribs[attribsCount++] = PT_LEVEL_ATTRIBUTE_NAME; listAttribs[attribsCount++] = szLevel.c_str(); // Now handle the Abi List properties UT_String propBuffer; UT_String tempBuffer; UT_String_sprintf(tempBuffer,"list-style:%i;", m_pCurrentListDefinition->getListType(m_iCurrentListLevel)); propBuffer += tempBuffer; #if 0 // FIXME: writing the list delimiter is kind of tricky and silly (because wordperfect wants to define // it within the document, while abi wants to (sensibly probably) define it in the list definition) // (we reset it each time but only for numbered lists) if (listDefinition->isLevelNumbered(m_iCurrentListLevel)) { UT_DEBUGMSG(("WordPerfect: Appending this list delim: %s\n", m_rightListDelim.c_str())); listDefinition->setListRightDelimText(m_iCurrentListLevel, m_rightListDelim.c_str()); X_CheckWordPerfectError(_updateDocumentListDefinition(listDefinition, m_iCurrentListLevel)); } #endif if (m_pCurrentListDefinition->getListType(m_iCurrentListLevel) == BULLETED_LIST) UT_String_sprintf(tempBuffer, "field-font:Symbol; "); else UT_String_sprintf(tempBuffer, "field-font:NULL; "); m_pCurrentListDefinition->incrementLevelNumber(m_iCurrentListLevel); propBuffer += tempBuffer; UT_String_sprintf(tempBuffer, "start-value:%i; ", 1); propBuffer += tempBuffer; UT_String_sprintf(tempBuffer, "text-indent:%fin; ", WP_PARAGRAPH_STYLE_TEXT_INDENT_DECREMENT); propBuffer += tempBuffer; UT_String_sprintf(tempBuffer, "margin-left:%fin", WP_PARAGRAPH_STYLE_MARGIN_LEFT_INCREMENT*m_iCurrentListLevel); propBuffer += tempBuffer; listAttribs[attribsCount++] = PT_PROPS_ATTRIBUTE_NAME; listAttribs[attribsCount++] = propBuffer.c_str(); listAttribs[attribsCount++] = NULL; X_CheckDocumentError(appendStrux(PTX_Block, listAttribs)); // hang text off of a list label _appendListSpan(UT_rand()); getDoc()->appendFmtMark(); UT_DEBUGMSG(("WordPerfect: LISTS - Appended a list tag def'n (character props)\n")); // append a list field label const XML_Char* fielddef[3]; fielddef[0] ="type"; fielddef[1] = "list_label"; fielddef[2] = NULL; X_CheckDocumentError(appendObject(PTO_Field,fielddef)); UT_DEBUGMSG(("WordPerfect: LISTS - Appended a field def'n\n")); // insert span props _appendSpan(0, "Times New Roman", 12.0f); // insert a tab UT_UCS4Char ucs = UCS_TAB; X_CheckDocumentError(appendSpan(&ucs,1)); } void IE_Imp_WordPerfect::openFootnote(int number) { if (m_bHdrFtrOpenCount) return; // HACK UT_DEBUGMSG(("AbiWordPerfect: openFootnote(number: %d)\n", number)); const XML_Char** propsArray = NULL; UT_String footnoteId; UT_String_sprintf(footnoteId,"%i",UT_rand()); propsArray = static_cast(UT_calloc(7, sizeof(XML_Char *))); propsArray [0] = "type"; propsArray [1] = "footnote_ref"; propsArray [2] = "footnote-id"; propsArray [3] = footnoteId.c_str(); propsArray [4] = NULL; propsArray [5] = NULL; propsArray [6] = NULL; X_CheckDocumentError(appendObject(PTO_Field, propsArray)); const XML_Char * attribs[3] ={"footnote-id", footnoteId.c_str(), NULL}; X_CheckDocumentError(appendStrux(PTX_SectionFootnote,attribs)); X_CheckDocumentError(appendStrux(PTX_Block,NULL)); propsArray = static_cast(UT_calloc(7, sizeof(XML_Char *))); propsArray [0] = "type"; propsArray [1] = "footnote_anchor"; propsArray [2] = "footnote-id"; propsArray [3] = footnoteId.c_str(); propsArray [4] = NULL; propsArray [5] = NULL; propsArray [6] = NULL; X_CheckDocumentError(appendObject(PTO_Field, propsArray)); } void IE_Imp_WordPerfect::closeFootnote() { if (m_bHdrFtrOpenCount) return; // HACK UT_DEBUGMSG(("AbiWordPerfect: closeFootnote\n")); X_CheckDocumentError(appendStrux(PTX_EndFootnote,NULL)); } void IE_Imp_WordPerfect::openEndnote(int number) { if (m_bHdrFtrOpenCount) return; // HACK UT_DEBUGMSG(("AbiWordPerfect: openEndnote(number: %d)\n", number)); const XML_Char** propsArray = NULL; UT_String endnoteId; UT_String_sprintf(endnoteId,"%i",UT_rand()); propsArray = static_cast(UT_calloc(7, sizeof(XML_Char *))); propsArray [0] = "type"; propsArray [1] = "endnote_ref"; propsArray [2] = "endnote-id"; propsArray [3] = endnoteId.c_str(); propsArray [4] = NULL; propsArray [5] = NULL; propsArray [6] = NULL; X_CheckDocumentError(appendObject(PTO_Field, propsArray)); const XML_Char * attribs[3] ={"endnote-id", endnoteId.c_str(), NULL}; X_CheckDocumentError(appendStrux(PTX_SectionEndnote,attribs)); X_CheckDocumentError(appendStrux(PTX_Block,NULL)); propsArray = static_cast(UT_calloc(7, sizeof(XML_Char *))); propsArray [0] = "type"; propsArray [1] = "endnote_anchor"; propsArray [2] = "endnote-id"; propsArray [3] = endnoteId.c_str(); propsArray [4] = NULL; propsArray [5] = NULL; propsArray [6] = NULL; X_CheckDocumentError(appendObject(PTO_Field, propsArray)); } void IE_Imp_WordPerfect::closeEndnote() { if (m_bHdrFtrOpenCount) return; // HACK UT_DEBUGMSG(("AbiWordPerfect: closeEndnote\n")); X_CheckDocumentError(appendStrux(PTX_EndEndnote,NULL)); } void IE_Imp_WordPerfect::openTable(const guint8 tablePositionBits, const float marginLeftOffset, const float marginRightOffset, const float leftOffset, const vector < WPXColumnDefinition > &columns) { if (m_bHdrFtrOpenCount) return; // HACK // TODO: handle 'marginLeftOffset' and 'marginRightOffset' UT_DEBUGMSG(("AbiWordPerfect: openTable\n")); UT_String propBuffer; if (tablePositionBits & WPX_TABLE_POSITION_ALIGN_WITH_LEFT_MARGIN) { // we don't need to do anything here: this is the default behavior } else if (tablePositionBits & WPX_TABLE_POSITION_ALIGN_WITH_RIGHT_MARGIN) { // abiword does not support this I think } else if (tablePositionBits & WPX_TABLE_POSITION_CENTER_BETWEEN_MARGINS) { // abiword does not support this I think } else if (tablePositionBits & WPX_TABLE_POSITION_FULL) { // TODO: implement me } else if (tablePositionBits & WPX_TABLE_POSITION_ABSOLUTE_FROM_LEFT_MARGIN) { UT_String_sprintf(propBuffer, "table-column-leftpos:%.4fin; ", leftOffset); } else { //UT_ASSERT( SHOULD_NOT_HAPPEN ); } propBuffer += "table-column-props:"; for (UT_uint32 i=0; im_r; m_fgColor.m_g = cellFgColor->m_g; m_fgColor.m_b = cellFgColor->m_b; m_fgColor.m_s = cellFgColor->m_s; } else { m_fgColor.m_r = m_fgColor.m_g = m_fgColor.m_b = 0xFF; m_fgColor.m_s = 0x64; // 100% } if (cellBgColor != NULL) { m_bgColor.m_r = cellBgColor->m_r; m_bgColor.m_g = cellBgColor->m_g; m_bgColor.m_b = cellBgColor->m_b; m_bgColor.m_s = cellBgColor->m_s; } else { m_bgColor.m_r = m_bgColor.m_g = m_bgColor.m_b = 0xFF; m_bgColor.m_s = 0x64; // 100% } float fgAmount = (float)m_fgColor.m_s/100.0f; float bgAmount = max(((float)m_bgColor.m_s-(float)m_fgColor.m_s)/100.0f, 0.0f); int bgRed = min((int)(((float)m_fgColor.m_r*fgAmount)+((float)m_bgColor.m_r*bgAmount)), 255); int bgGreen = min((int)(((float)m_fgColor.m_g*fgAmount)+((float)m_bgColor.m_g*bgAmount)), 255); int bgBlue = min((int)(((float)m_fgColor.m_b*fgAmount)+((float)m_bgColor.m_b*bgAmount)), 255); /* END CODE COPIED FROM WPD2SXW */ // we only support bg-style:1 for now UT_String_sprintf(bgCol, "; bg-style:1; background-color:%02x%02x%02x", bgRed, bgGreen, bgBlue); propBuffer += bgCol; // TODO: Handle the Cell Background Color here, but I don't think AbiWord supports that // ... UT_DEBUGMSG(("AbiWordPerfect: Inserting a Cell definition: %s\n", propBuffer.c_str())); const XML_Char* propsArray[3]; propsArray[0] = "props"; propsArray[1] = propBuffer.c_str(); propsArray[2] = NULL; X_CheckDocumentError(appendStrux(PTX_SectionCell, propsArray)); m_bInCell = true; } void IE_Imp_WordPerfect::closeTable() { if (m_bHdrFtrOpenCount) return; // HACK if (m_bInCell) { X_CheckDocumentError(appendStrux(PTX_EndCell, NULL)); } X_CheckDocumentError(appendStrux(PTX_EndTable, NULL)); m_bInCell = false; // we need to open a new paragraph after a table, since libwpd does NOT do it // FIXME: NEED TO PASS THE CURRENT PROPERTIES INSTEAD OF NULL // NOTE: THIS SUCKS......... X_CheckDocumentError(appendStrux(PTX_Block, NULL)); } UT_Error IE_Imp_WordPerfect::_appendSpan(const guint32 textAttributeBits, const gchar *fontName, const float fontSize, UT_uint32 listTag) { UT_DEBUGMSG(("AbiWordPerfect: Appending current text properties\n")); XML_Char* pProps = "props"; UT_String propBuffer; UT_String tempBuffer; // bold propBuffer += "font-weight:"; propBuffer += (textAttributeBits & WPX_BOLD_BIT ? "bold" : "normal"); // italic propBuffer += "; font-style:"; propBuffer += (textAttributeBits & WPX_ITALICS_BIT ? "italic" : "normal"); // superscript or subscript if ((textAttributeBits & WPX_SUPERSCRIPT_BIT) || (textAttributeBits & WPX_SUBSCRIPT_BIT)) { propBuffer += "; text-position:"; propBuffer += (textAttributeBits & WPX_SUPERSCRIPT_BIT ? "superscript" : "subscript"); } // underline & strike-out if ((textAttributeBits & WPX_UNDERLINE_BIT) || (textAttributeBits & WPX_STRIKEOUT_BIT)) { propBuffer += "; text-decoration:"; propBuffer += (textAttributeBits & WPX_UNDERLINE_BIT ? "underline" : "line-through"); } // font face if (fontName != NULL) { propBuffer += "; font-family:"; propBuffer += fontName; } // font face UT_String_sprintf(tempBuffer, "; font-size:%.3fpt", fontSize); propBuffer += tempBuffer; UT_DEBUGMSG(("AbiWordPerfect: Appending span format: %s\n", propBuffer.c_str())); const XML_Char* propsArray[5]; propsArray[0] = pProps; propsArray[1] = propBuffer.c_str(); propsArray[2] = NULL; // FIXME: remove this? #if 0 if (listTag) { propsArray[2] ="type"; propsArray[3] = "list_label"; propsArray[4] = NULL; } #endif X_CheckDocumentError(appendFmt(propsArray)); return UT_OK; } UT_Error IE_Imp_WordPerfect::_appendListSpan(UT_uint32 listTag) { // List Tag to hang lists off XML_Char* pProps = "props"; UT_String propBuffer; UT_String_sprintf(propBuffer, "list-tag:%d", listTag); const XML_Char* propsArray[3]; propsArray[0] = pProps; propsArray[1] = propBuffer.c_str(); propsArray[2] = NULL; X_CheckDocumentError(appendFmt(propsArray)); return UT_OK; } UT_Error IE_Imp_WordPerfect::_appendParagraph(const guint8 paragraphJustification, const guint32 textAttributeBits, const gchar *fontName, const float fontSize, const float lineSpacing) { UT_String propBuffer; propBuffer += "text-align:"; switch (paragraphJustification) { case WPX_PARAGRAPH_JUSTIFICATION_LEFT: propBuffer += "left"; break; case WPX_PARAGRAPH_JUSTIFICATION_RIGHT: propBuffer += "right"; break; case WPX_PARAGRAPH_JUSTIFICATION_CENTER: propBuffer += "center"; break; case WPX_PARAGRAPH_JUSTIFICATION_FULL: propBuffer += "justify"; break; } UT_String tmpBuffer; UT_String_sprintf(tmpBuffer, "; margin-left:%.4fin; margin-right:%.4fin; line-height:%.4f", m_leftMarginOffset, m_rightMarginOffset, lineSpacing); propBuffer += tmpBuffer; UT_DEBUGMSG(("AbiWordPerfect: Appending paragraph properties: %s\n", propBuffer.c_str())); const XML_Char* propsArray[3]; propsArray[0] = "props"; propsArray[1] = propBuffer.c_str(); propsArray[2] = NULL; X_CheckDocumentError(appendStrux(PTX_Block, propsArray)); _appendSpan(textAttributeBits, fontName, fontSize); return UT_OK; } UT_Error IE_Imp_WordPerfect::_appendSection(guint numColumns, const float marginLeft, const float marginRight) { UT_DEBUGMSG(("AbiWordPerfect: Appending section\n")); UT_String myProps("") ; setlocale(LC_NUMERIC, "C"); myProps += UT_String_sprintf("columns:%d; page-margin-left:%.4fin; page-margin-right:%.4fin", numColumns, marginLeft, marginRight); setlocale(LC_NUMERIC, NULL); XML_Char * propsArray[3]; propsArray[0] = "props"; propsArray[1] = const_cast(reinterpret_cast(myProps.c_str())); propsArray[2] = NULL ; X_CheckDocumentError(appendStrux(PTX_Section, (const XML_Char**)propsArray)); m_bInSection = true; m_leftMargin = marginLeft; m_rightMargin = marginRight; m_bSectionChanged = false; return UT_OK; } // NB: AbiWord-2.0 doesn't properly support nested lists with different nested styles: only "1" style // really looks proper. We hack around this be only using the style given at level "1" // NB: AbiWord-2.0 doesn't properly support setting list delimeters at levels greater than 1, // we hack around this by using only "plain" (e.g.: NULL) list delimeters on levels greater than 1. UT_Error IE_Imp_WordPerfect::_updateDocumentOrderedListDefinition(ABI_ListDefinition *pListDefinition, int iLevel, const WPXNumberingType listType, const UCSString &sTextBeforeNumber, const UCSString &sTextAfterNumber, int iStartingNumber) { UT_DEBUGMSG(("AbiWordPerfect: Updating document list definition (iLevel: %i)\n", iLevel)); // finally, set the document's list identification info.. fl_AutoNum * pAuto = getDoc()->getListByID(pListDefinition->getListID(iLevel)); // not in document yet, we should create a list for it if (pAuto == NULL) { UT_DEBUGMSG(("AbiWordPerfect: pAuto is NULL: creating a list\n", iLevel)); if (iLevel > 1) { pAuto = new fl_AutoNum(pListDefinition->getListID(iLevel), pListDefinition->getListID((iLevel-1)), pListDefinition->getListType(1), iStartingNumber, const_cast(reinterpret_cast("%L")), ".", getDoc()); } else { UT_UCS4String sNumberingString; UT_UCS4String sNumber("%L", 0, false); sNumberingString += sTextBeforeNumber.getUCS4(); sNumberingString += sNumber; sNumberingString += sTextAfterNumber.getUCS4(); pAuto = new fl_AutoNum(pListDefinition->getListID(iLevel), 0, pListDefinition->getListType(iLevel), iStartingNumber, const_cast(reinterpret_cast(sNumberingString.utf8_str())), ".", getDoc()); } getDoc()->addList(pAuto); } // we should update what we have else { UT_DEBUGMSG(("AbiWordPerfect: pAuto already exists\n", iLevel)); } pAuto->fixHierarchy(); return UT_OK; } UT_Error IE_Imp_WordPerfect::_updateDocumentUnorderedListDefinition(ABI_ListDefinition *pListDefinition, int iLevel) { UT_DEBUGMSG(("AbiWordPerfect: Updating document list definition (iLevel: %i)\n", iLevel)); // finally, set the document's list identification info.. fl_AutoNum * pAuto = getDoc()->getListByID(pListDefinition->getListID(iLevel)); // not in document yet, we should create a list for it if (pAuto == NULL) { UT_DEBUGMSG(("AbiWordPerfect: pAuto is NULL: creating a list\n", iLevel)); if (iLevel > 1) { pAuto = new fl_AutoNum(pListDefinition->getListID(iLevel), pListDefinition->getListID((iLevel-1)), pListDefinition->getListType(1), 0, (XML_Char *)"%L", ".", getDoc()); } else pAuto = new fl_AutoNum(pListDefinition->getListID(iLevel), 0, pListDefinition->getListType(iLevel), 0, (XML_Char *)"%L", ".", getDoc()); getDoc()->addList(pAuto); } // we should update what we have else { UT_DEBUGMSG(("AbiWordPerfect: pAuto already exists\n", iLevel)); } pAuto->fixHierarchy(); return UT_OK; }