/* AbiSource * * Copyright (C) 2005 INdT * Author: Daniel d'Andrada T. de Carvalho * Copyright 2009 AbiSource Corporation B.V. * * 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. */ // Class definition include #include "ODe_Style_List.h" #include "ODe_Style_Style.h" #include "ODe_ListLevelStyle.h" // Internal includes #include "ODe_Common.h" // AbiWord includes #include #include #include #include // for fl_TabStop // External includes #include /******************************************************************************* * ODe_Style_Style ******************************************************************************/ /** * Constructor */ ODe_Style_Style::ODe_Style_Style() : m_defaultStyle(false), m_pSectionProps(NULL), m_pParagraphProps(NULL), m_pTextProps(NULL), m_pTableProps(NULL), m_pColumnProps(NULL), m_pRowProps(NULL), m_pCellProps(NULL), m_pGraphicProps(NULL) { } /** * Destructor */ ODe_Style_Style::~ODe_Style_Style() { DELETEP(m_pSectionProps); DELETEP(m_pParagraphProps); DELETEP(m_pTextProps); DELETEP(m_pTableProps); DELETEP(m_pColumnProps); DELETEP(m_pRowProps); DELETEP(m_pCellProps); DELETEP(m_pGraphicProps); } /** * Writes and its subelements. * * @param rSpacesOffset Space characters written at the beginning of * each new line. */ bool ODe_Style_Style::write(GsfOutput* pODT, const UT_UTF8String& rSpacesOffset) const { UT_UTF8String output; UT_UTF8String subOffset; UT_UTF8String escape; output += rSpacesOffset; output += !m_defaultStyle ? "write(output, subOffset); } ODE_WRITE_STYLE_PROPS(m_pSectionProps); ODE_WRITE_STYLE_PROPS(m_pParagraphProps); ODE_WRITE_STYLE_PROPS(m_pTextProps); ODE_WRITE_STYLE_PROPS(m_pTableProps); ODE_WRITE_STYLE_PROPS(m_pColumnProps); ODE_WRITE_STYLE_PROPS(m_pRowProps); ODE_WRITE_STYLE_PROPS(m_pCellProps); ODE_WRITE_STYLE_PROPS(m_pGraphicProps); #undef ODE_WRITE_STYLE_PROPS output += rSpacesOffset; output += !m_defaultStyle ? "" : ""; output += "\n"; ODe_writeUTF8String(pODT, output); return true; } /** * Returns true if the specified PP_AttrProp contains properties that belongs to * elements */ bool ODe_Style_Style::hasTextStyleProps(const PP_AttrProp* pAP) { const gchar* pValue; bool ok; ok = pAP->getProperty("color", pValue); if (ok && pValue != NULL) { return true; } ok = pAP->getProperty("bgcolor", pValue); if (ok && pValue != NULL) { return true; } ok = pAP->getProperty("text-decoration", pValue); if (ok && pValue != NULL) { return true; } ok = pAP->getProperty("text-position", pValue); if (ok && pValue != NULL) { return true; } ok = pAP->getProperty("font-family", pValue); if (ok && pValue != NULL) { return true; } ok = pAP->getProperty("font-size", pValue); if (ok && pValue != NULL) { return true; } ok = pAP->getProperty("lang", pValue); if (ok && pValue != NULL) { return true; } ok = pAP->getProperty("font-style", pValue); if (ok && pValue != NULL) { return true; } ok = pAP->getProperty("font-weight", pValue); if (ok && pValue != NULL) { return true; } ok = pAP->getProperty("display", pValue); if (ok && pValue != NULL) { return true; } ok = pAP->getProperty("text-transform", pValue); if (ok && pValue != NULL) { return true; } return false; } /** * Returns true if the specified PP_AttrProp contains properties that belongs to * elements */ bool ODe_Style_Style::hasParagraphStyleProps(const PP_AttrProp* pAP) { const gchar* pValue; bool ok; ok = pAP->getProperty("bgcolor", pValue); if (ok && pValue != NULL) { return true; } ok = pAP->getProperty("line-height", pValue); if (ok && pValue != NULL) { return true; } ok = pAP->getProperty("text-align", pValue); if (ok && pValue != NULL) { return true; } ok = pAP->getProperty("text-indent", pValue); if (ok && pValue != NULL) { return true; } ok = pAP->getProperty("widows", pValue); if (ok && pValue != NULL) { return true; } ok = pAP->getProperty("orphans", pValue); if (ok && pValue != NULL) { return true; } ok = pAP->getProperty("margin-left", pValue); if (ok && pValue != NULL) { return true; } ok = pAP->getProperty("margin-right", pValue); if (ok && pValue != NULL) { return true; } ok = pAP->getProperty("margin-top", pValue); if (ok && pValue != NULL) { return true; } ok = pAP->getProperty("margin-bottom", pValue); if (ok && pValue != NULL) { return true; } ok = pAP->getProperty("keep-with-next", pValue); if (ok && pValue != NULL) { return true; } ok = pAP->getProperty("default-tab-interval", pValue); if (ok && pValue != NULL) { return true; } ok = pAP->getProperty("tabstops", pValue); if (ok && pValue != NULL) { return true; } return false; } /** * */ bool ODe_Style_Style::hasSectionInfo(const PP_AttrProp* pAP) { const gchar* pValue; bool ok; ok = pAP->getProperty("columns", pValue); if (ok && pValue != NULL) { return true; } ok = pAP->getProperty("column-gap", pValue); if (ok && pValue != NULL) { return true; } ok= pAP->getProperty("page-margin-top",pValue); if (ok && pValue != NULL) { return true; } ok= pAP->getProperty("page-margin-left",pValue); if (ok && pValue != NULL) { return true; } ok= pAP->getProperty("page-margin-right",pValue); if (ok && pValue != NULL) { return true; } ok= pAP->getProperty("page-margin-bottom",pValue); if (ok && pValue != NULL) { return true; } ok = pAP->getProperty("page-margin-header", pValue); if (ok && pValue != NULL) { return true; } ok = pAP->getProperty("page-margin-footer", pValue); if (ok && pValue != NULL) { return true; } return false; } /** * It does not take style names into consideration. * Read it like: "is style "T1" equivalent to style "T2" * It is *NOT* like: "is style A equal to style B" */ bool ODe_Style_Style::isEquivalentTo(const ODe_Style_Style& rStyle) { bool isEqual; isEqual = m_family == rStyle.m_family && m_parentStyleName == rStyle.m_parentStyleName && m_nextStyleName == rStyle.m_nextStyleName && m_masterPageName == rStyle.m_masterPageName && m_listStyleName == rStyle.m_listStyleName; if (!isEqual) {return false;} #define ODE_EQUAL_STYLE_PROPS(m_pProps) \ if (m_pProps == NULL && rStyle.m_pProps == NULL) { \ isEqual = true; \ } else if (m_pProps != NULL && rStyle.m_pProps != NULL) { \ isEqual = (*m_pProps) == (*rStyle.m_pProps); \ } else { \ isEqual = false; \ } \ if (!isEqual) {return false;} ODE_EQUAL_STYLE_PROPS(m_pSectionProps); ODE_EQUAL_STYLE_PROPS(m_pParagraphProps); ODE_EQUAL_STYLE_PROPS(m_pTextProps); ODE_EQUAL_STYLE_PROPS(m_pTableProps); ODE_EQUAL_STYLE_PROPS(m_pColumnProps); ODE_EQUAL_STYLE_PROPS(m_pRowProps); ODE_EQUAL_STYLE_PROPS(m_pCellProps); ODE_EQUAL_STYLE_PROPS(m_pGraphicProps); #undef ODE_EQUAL_STYLE_PROPS // If not returned until here it's because they're equal. return true; } /** * */ bool ODe_Style_Style::isEmpty() const { #define ODE_IS_STYLE_PROPS_EMPTY(pStyleProps) \ if (pStyleProps) { \ if(!pStyleProps->isEmpty()) { return false; } \ } ODE_IS_STYLE_PROPS_EMPTY(m_pSectionProps); ODE_IS_STYLE_PROPS_EMPTY(m_pParagraphProps); ODE_IS_STYLE_PROPS_EMPTY(m_pTextProps); ODE_IS_STYLE_PROPS_EMPTY(m_pTableProps); ODE_IS_STYLE_PROPS_EMPTY(m_pColumnProps); ODE_IS_STYLE_PROPS_EMPTY(m_pRowProps); ODE_IS_STYLE_PROPS_EMPTY(m_pCellProps); ODE_IS_STYLE_PROPS_EMPTY(m_pGraphicProps); #undef ODE_IS_STYLE_PROPS_EMPTY return true; } /** * */ ODe_Style_Style& ODe_Style_Style::operator=(const ODe_Style_Style& rStyle) { #define ODE_COPY_STYLE_PROPS(m_pStyleProps, StyleProps) \ if (rStyle.m_pStyleProps) { \ if (m_pStyleProps == NULL) { \ m_pStyleProps = new StyleProps(); \ } \ *m_pStyleProps = *(rStyle.m_pStyleProps); \ } else { \ DELETEP(m_pStyleProps); \ } ODE_COPY_STYLE_PROPS(m_pSectionProps, SectionProps); ODE_COPY_STYLE_PROPS(m_pParagraphProps, ParagraphProps); ODE_COPY_STYLE_PROPS(m_pTextProps, TextProps); ODE_COPY_STYLE_PROPS(m_pTableProps, TableProps); ODE_COPY_STYLE_PROPS(m_pColumnProps, ColumnProps); ODE_COPY_STYLE_PROPS(m_pRowProps, RowProps); ODE_COPY_STYLE_PROPS(m_pCellProps, CellProps); ODE_COPY_STYLE_PROPS(m_pGraphicProps, GraphicProps); #undef ODE_COPY_STYLE_PROPS return *this; } /** * Defines the style from attributes and properties of an AbiWord style. * * @return "false" if an error ocurred. */ bool ODe_Style_Style::fetchAttributesFromAbiStyle(const PP_AttrProp* pAP) { const gchar* pValue; bool ok; ok = pAP->getAttribute(PT_NAME_ATTRIBUTE_NAME, pValue); if (!ok) {return false;} m_name = pValue; ok = pAP->getAttribute(PT_FOLLOWEDBY_ATTRIBUTE_NAME, pValue); if (ok && pValue != NULL) { if (strcmp("Current Settings", pValue) != 0) { m_nextStyleName = pValue; } } ok = pAP->getAttribute(PT_BASEDON_ATTRIBUTE_NAME, pValue); if (ok && pValue != NULL) { if (strcmp(pValue, "None") != 0) { // OpenDocument don't use a "None" to say that is has no parent. // To say that it simply doesn't define this attribute. m_parentStyleName = pValue; } } if (m_pTextProps == NULL) { m_pTextProps = new TextProps(); } m_pTextProps->fetchAttributesFromAbiProps(*pAP); if (m_pParagraphProps == NULL) { m_pParagraphProps = new ParagraphProps(m_defaultStyle); } m_pParagraphProps->fetchAttributesFromAbiProps(*pAP); return true; } /** * Defines the style from attributes and properties of an AbiWord . */ void ODe_Style_Style::fetchAttributesFromAbiSpan(const PP_AttrProp* pAP) { const gchar* pValue; bool ok; ok = pAP->getAttribute("style", pValue); if (ok && pValue != NULL) { m_parentStyleName = pValue; } if (m_pTextProps == NULL) { m_pTextProps = new TextProps(); } m_pTextProps->fetchAttributesFromAbiProps(*pAP); } /** * Fetch attributes from an AbiWord

tag. Usually paragraph style attributes. */ void ODe_Style_Style::fetchAttributesFromAbiBlock(const PP_AttrProp* pAP, const ODe_Style_List* pCurrentListStyle) { const gchar* pValue; bool ok; ok = pAP->getAttribute("style", pValue); if (ok && pValue != NULL) { m_parentStyleName = pValue; } if (m_pTextProps == NULL) { m_pTextProps = new TextProps(); } m_pTextProps->fetchAttributesFromAbiProps(*pAP); if (m_pParagraphProps == NULL) { m_pParagraphProps = new ParagraphProps(m_defaultStyle); } m_pParagraphProps->fetchAttributesFromAbiProps(*pAP); ok = pAP->getAttribute("listid", pValue); if (ok && pValue != NULL) { // text:space-before and text:min-label-width are not paragraph properties, // so we'll ignore those. // We could also skip the fo:text-indent and fo:margin-left when they are // the same size as those propties in the list style. It doesn't // hurt to unconditionally write them out though, so we'll leave it // as it is for now. UT_UTF8String spaceBefore; UT_UTF8String minLabelWidth; ODe_ListLevelStyle::calculateListMargins(*pAP, m_pParagraphProps->m_textIndent, spaceBefore, minLabelWidth, m_pParagraphProps->m_marginLeft); // store the list style name in the paragraph style UT_ASSERT_HARMLESS(pCurrentListStyle); if (pCurrentListStyle) m_listStyleName = pCurrentListStyle->getName(); } } /** * Fetch attributes from an AbiWord

tag. Usually column info for * an OpenDocument element. */ void ODe_Style_Style::fetchAttributesFromAbiSection(const PP_AttrProp* pAP) { if (m_pSectionProps == NULL) { m_pSectionProps = new SectionProps(); } m_pSectionProps->fetchAttributesFromAbiProps(*pAP); } /** * Defines the style from attributes and properties of an AbiWord . */ void ODe_Style_Style::fetchAttributesFromAbiTable(const PP_AttrProp* pAP) { if (m_pTableProps == NULL) { m_pTableProps = new TableProps(); } m_pTableProps->fetchAttributesFromAbiProps(*pAP); } /** * Defines the style from attributes and properties of an AbiWord . */ void ODe_Style_Style::fetchAttributesFromAbiCell(const PP_AttrProp* pAP) { if (m_pCellProps == NULL) { m_pCellProps = new CellProps(); } m_pCellProps->fetchAttributesFromAbiProps(*pAP); } /** * Defines the style from attributes and properties of an AbiWord . */ void ODe_Style_Style::fetchAttributesFromAbiFrame(const PP_AttrProp& rAP) { if (m_pGraphicProps == NULL) { m_pGraphicProps = new GraphicProps(); } m_pGraphicProps->fetchAttributesFromAbiProps(rAP); } /** * */ void ODe_Style_Style::setBreakBefore(const gchar* pBreakBefore) { if (m_pParagraphProps == NULL) { m_pParagraphProps = new ParagraphProps(m_defaultStyle); } m_pParagraphProps->m_breakBefore = pBreakBefore; } /** * */ const UT_UTF8String& ODe_Style_Style::getFontName() { if (m_pTextProps == NULL) { m_pTextProps = new TextProps(); } return m_pTextProps->m_fontName; } /** * */ void ODe_Style_Style::setColumnWidth(const gchar* pColumnWidth) { if (m_pColumnProps == NULL) { m_pColumnProps = new ColumnProps(); } m_pColumnProps->m_columnWidth = pColumnWidth; } void ODe_Style_Style::setRelColumnWidth(const gchar* pRelColumnWidth) { if (m_pColumnProps == NULL) { m_pColumnProps = new ColumnProps(); } m_pColumnProps->m_RelColumnWidth = pRelColumnWidth; } /** * */ void ODe_Style_Style::setRowHeight(const gchar* pRowHeight) { if (m_pRowProps == NULL) { m_pRowProps = new RowProps(); } m_pRowProps->m_rowHeight = pRowHeight; } /** * */ void ODe_Style_Style::setMinRowHeight(const gchar* pMinRowHeight) { if (m_pRowProps == NULL) { m_pRowProps = new RowProps(); } m_pRowProps->m_minRowHeight = pMinRowHeight; } /** * */ bool ODe_Style_Style::hasTableStyleProps(const PP_AttrProp* pAP) { const gchar* pValue; bool ok; ok = pAP->getProperty("background-color", pValue); if (ok && pValue != NULL) { return true; } ok = pAP->getProperty("table-column-props", pValue); if (ok && pValue != NULL) { return true; } ok = pAP->getProperty("table-width", pValue); if (ok && pValue != NULL) { return true; } ok = pAP->getProperty("table-rel-width", pValue); if (ok && pValue != NULL) { return true; } ok = pAP->getProperty("table-margin-left", pValue); if (ok && pValue != NULL) { return true; } ok = pAP->getProperty("table-margin-top", pValue); if (ok && pValue != NULL) { return true; } ok = pAP->getProperty("table-margin-right", pValue); if (ok && pValue != NULL) { return true; } ok = pAP->getProperty("table-margin-bottom", pValue); if (ok && pValue != NULL) { return true; } ok = pAP->getProperty("table-line-thickness", pValue); if (ok && pValue != NULL) { return true; } ok = pAP->getProperty("table-col-spacing", pValue); if (ok && pValue != NULL) { return true; } ok = pAP->getProperty("table-row-spacing", pValue); if (ok && pValue != NULL) { return true; } ok = pAP->getProperty("table-column-leftpos", pValue); if (ok && pValue != NULL) { return true; } ok = pAP->getProperty("table-rel-column-props", pValue); if (ok && pValue != NULL) { return true; } // If we reached this point it's because there are no table props at all // on this AbiWord element attributes and properties. return false; } /** * */ void ODe_Style_Style::inheritTableCellProperties(const ODe_Style_Style& tableStyle) { UT_return_if_fail(tableStyle.m_pCellProps); if (m_pCellProps == NULL) { m_pCellProps = new CellProps(); } // the following properties are always inherited by AbiWord cells m_pCellProps->m_leftThickness = tableStyle.m_pCellProps->m_leftThickness; m_pCellProps->m_leftColor = tableStyle.m_pCellProps->m_leftColor; m_pCellProps->m_rightThickness = tableStyle.m_pCellProps->m_rightThickness; m_pCellProps->m_rightColor = tableStyle.m_pCellProps->m_rightColor; m_pCellProps->m_topThickness = tableStyle.m_pCellProps->m_topThickness; m_pCellProps->m_topColor = tableStyle.m_pCellProps->m_topColor; m_pCellProps->m_bottomThickness = tableStyle.m_pCellProps->m_bottomThickness; m_pCellProps->m_bottomColor = tableStyle.m_pCellProps->m_bottomColor; // Table background colors are not inherited in AbiWord and an OpenDocument // table can have its own background color as well, so we don't inherit // this property } /** * */ void ODe_Style_Style::setWrap(const UT_UTF8String& rWrap) { if (m_pGraphicProps == NULL) { m_pGraphicProps = new GraphicProps(); } m_pGraphicProps->m_wrap = rWrap; } /** * */ void ODe_Style_Style::setRunThrough(const UT_UTF8String& rRunThrough) { if (m_pGraphicProps == NULL) { m_pGraphicProps = new GraphicProps(); } m_pGraphicProps->m_runThrough = rRunThrough; } /** * */ void ODe_Style_Style::setPadding(const UT_UTF8String& rPadding) { if (m_pGraphicProps == NULL) { m_pGraphicProps = new GraphicProps(); } m_pGraphicProps->m_padding = rPadding; } /** * */ void ODe_Style_Style::setHorizontalPos(const UT_UTF8String& rHorizontalPos) { if (m_pGraphicProps == NULL) { m_pGraphicProps = new GraphicProps(); } m_pGraphicProps->m_horizontalPos = rHorizontalPos; } /** * */ void ODe_Style_Style::setVerticalPos(const UT_UTF8String& rVerticalPos) { if (m_pGraphicProps == NULL) { m_pGraphicProps = new GraphicProps(); } m_pGraphicProps->m_verticalPos = rVerticalPos; } void ODe_Style_Style::setVerticalRel(const UT_UTF8String& rVerticalRel) { if (m_pGraphicProps == NULL) { m_pGraphicProps = new GraphicProps(); } m_pGraphicProps->m_verticalRel = rVerticalRel; } /** * */ const UT_UTF8String& ODe_Style_Style::getDefaultTabInterval() { if (m_pParagraphProps == NULL) { m_pParagraphProps = new ParagraphProps(m_defaultStyle); } return m_pParagraphProps->m_defaultTabInterval; } /** * */ void ODe_Style_Style::setDefaultTabInterval(const UT_UTF8String& rDefaultTabInterval) { if (m_pParagraphProps == NULL) { m_pParagraphProps = new ParagraphProps(m_defaultStyle); } m_pParagraphProps->m_defaultTabInterval = rDefaultTabInterval; } /******************************************************************************* * SectionProps ******************************************************************************/ /** * */ bool ODe_Style_Style::SectionProps::isEmpty() const { return m_columnCount.empty() && m_columnGap.empty(); } /** * */ void ODe_Style_Style::SectionProps:: fetchAttributesFromAbiProps(const PP_AttrProp& rAP) { const gchar* pValue; bool ok; ok = rAP.getProperty("columns", pValue); if (ok && pValue != NULL) { m_columnCount = pValue; } ok = rAP.getProperty("column-gap", pValue); if (ok && pValue != NULL) { m_columnGap = pValue; } } /** * */ void ODe_Style_Style::SectionProps:: write(UT_UTF8String& rOutput, const UT_UTF8String& rSpacesOffset) const { if (isEmpty()) { return; } rOutput += rSpacesOffset; rOutput += "\n"; rOutput += rSpacesOffset; rOutput += " 1) && (pValue[len - 1] == '+')) { gchar* temp = (gchar*)pValue; temp[len-1] = '\0'; m_lineHeightAtLeast = UT_UTF8String_sprintf("%fin", UT_convertToDimension(temp, DIM_IN)); m_lineHeight.clear(); // make sure this is empty } else { UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN); } } else if(strstr(pValue, "pt")) { // "exactly" spacing m_lineHeight = UT_UTF8String_sprintf("%fin", UT_convertToDimension(pValue, DIM_IN)); m_lineHeightAtLeast.clear(); // make sure this is empty } else { //"single", "double", "1.5 lines", or "multiple" spacing m_lineHeight = UT_UTF8String_sprintf("%.0f%%", atof(pValue) * 100); m_lineHeightAtLeast.clear(); // make sure this is empty } } ok = rAP.getProperty("text-align", pValue); if (ok && pValue != NULL) { if(!strcmp(pValue, "right")) { m_textAlign = "end"; //see Bug 10719 } else { m_textAlign = pValue; } } ok = rAP.getProperty("text-indent", pValue); if (ok && pValue != NULL) { m_textIndent = pValue; } ok = rAP.getProperty("dom-dir", pValue); if (ok && pValue != NULL) { if(!strcmp(pValue, "rtl")) { m_writingMode = "rl"; } else { m_writingMode = "lr"; } } ok = rAP.getProperty("widows", pValue); if (ok && pValue != NULL) { m_widows = pValue; } ok = rAP.getProperty("orphans", pValue); if (ok && pValue != NULL) { m_orphans = pValue; } ok = rAP.getProperty("margin-left", pValue); if (ok && pValue != NULL) { m_marginLeft = pValue; } ok = rAP.getProperty("margin-right", pValue); if (ok && pValue != NULL) { m_marginRight = pValue; } ok = rAP.getProperty("margin-top", pValue); if (ok && pValue != NULL) { m_marginTop = pValue; } ok = rAP.getProperty("margin-bottom", pValue); if (ok && pValue != NULL) { m_marginBottom = pValue; } ok = rAP.getProperty("keep-with-next", pValue); if (ok && pValue != NULL) { if (!strcmp(pValue, "yes")) { m_keepWithNext = "always"; } else { m_keepWithNext = "auto"; } } ok = rAP.getProperty("default-tab-interval", pValue); if (ok && pValue != NULL) { m_defaultTabInterval = pValue; } // tab stops ok = rAP.getProperty("tabstops", pValue); if(!ok) m_tabStops.clear(); else { // use a convenience function from fl_BlockLayout to parse the tabstops property UT_GenericVector tabStops; buildTabStops(pValue, tabStops); // convert the tabstops to a format we can write out for (UT_sint32 i = 0; i < tabStops.size(); i++) { fl_TabStop* pTabStop = tabStops[i]; UT_continue_if_fail(pTabStop); TabStop tabStop; // style:type switch (pTabStop->getType()) { case FL_TAB_LEFT: tabStop.m_type = "left"; break; case FL_TAB_CENTER: tabStop.m_type = "center"; break; case FL_TAB_RIGHT: tabStop.m_type = "right"; break; case FL_TAB_DECIMAL: { UT_LocaleInfo locale(UT_LocaleInfo::system()); UT_LocaleTransactor t(LC_NUMERIC, locale.toString().utf8_str()); // AbiWord always uses the locale-defined decimal point as the // decimal tab character. See fp_Line::_calculateWidthOfRun() // for details. lconv *loc = localeconv(); UT_UCSChar *pDecimalStr = NULL; UT_UCS4_cloneString_char(&pDecimalStr, loc->decimal_point); tabStop.m_type = "char"; tabStop.m_char.appendUCS4(pDecimalStr); FREEP(pDecimalStr); break; } case FL_TAB_NONE: // huh, a tab that is no tab?! case FL_TAB_BAR: // I have no clue what this is supposed to do, and ODF does not have any equivalent for it anyway. default: // default to a left tab tabStop.m_type = "left"; break; } // style:position UT_LocaleTransactor t(LC_NUMERIC, "C"); double pos = (double)pTabStop->getPosition() / UT_LAYOUT_RESOLUTION; tabStop.m_position = UT_UTF8String_sprintf("%fin", pos); // style:leader-style & style:leader-text switch (pTabStop->getLeader()) { case FL_LEADER_NONE: // no need to write out a style or text break; case FL_LEADER_DOT: tabStop.m_leaderStyle = "dotted"; tabStop.m_leaderText = "."; break; case FL_LEADER_HYPHEN: tabStop.m_leaderStyle = "dash"; // OOo uses "solid" for this case, but dash seems more appropriate tabStop.m_leaderText = "-"; break; case FL_LEADER_UNDERLINE: case FL_LEADER_THICKLINE: // we don't have this in the interface, but this looks like the best choice if it ever occurs case FL_LEADER_EQUALSIGN: // we don't have this in the interface, but this looks like the best choice if it ever occurs tabStop.m_leaderStyle = "solid"; tabStop.m_leaderText = "_"; break; default: // no need to write out a style or text break; } m_tabStops.push_back(tabStop); DELETEP(pTabStop); } tabStops.clear(); } } /** * */ void ODe_Style_Style::ParagraphProps:: write(UT_UTF8String& rOutput, const UT_UTF8String& rSpacesOffset) const { if (isEmpty()) { return; } rOutput += rSpacesOffset; rOutput += "\n", rSpacesOffset.utf8_str()); for (UT_uint32 i = 0; i < m_tabStops.size(); i++) { rOutput += UT_UTF8String_sprintf("%s \n", rSpacesOffset.utf8_str()); rOutput += UT_UTF8String_sprintf("%s\n", rSpacesOffset.utf8_str()); } } /** * */ ODe_Style_Style::ParagraphProps& ODe_Style_Style::ParagraphProps::operator=( const ParagraphProps& rParagraphProps) { m_textAlign = rParagraphProps.m_textAlign; m_textIndent = rParagraphProps.m_textIndent; m_lineHeight = rParagraphProps.m_lineHeight; m_lineHeightAtLeast = rParagraphProps.m_lineHeightAtLeast; m_backgroundColor = rParagraphProps.m_backgroundColor; m_widows = rParagraphProps.m_widows; m_orphans = rParagraphProps.m_orphans; m_marginLeft = rParagraphProps.m_marginLeft; m_marginRight = rParagraphProps.m_marginRight; m_marginTop = rParagraphProps.m_marginTop; m_marginBottom = rParagraphProps.m_marginBottom; m_keepWithNext = rParagraphProps.m_keepWithNext; m_breakBefore = rParagraphProps.m_breakBefore; m_writingMode = rParagraphProps.m_writingMode; m_defaultTabInterval = rParagraphProps.m_defaultTabInterval; m_tabStops = rParagraphProps.m_tabStops; return *this; } /** * */ bool ODe_Style_Style::ParagraphProps::operator==( const ODe_Style_Style::ParagraphProps& rParagraphProps) const { return m_textAlign == rParagraphProps.m_textAlign && m_textIndent == rParagraphProps.m_textIndent && m_lineHeight == rParagraphProps.m_lineHeight && m_lineHeightAtLeast == rParagraphProps.m_lineHeightAtLeast && m_backgroundColor == rParagraphProps.m_backgroundColor && m_widows == rParagraphProps.m_widows && m_orphans == rParagraphProps.m_orphans && m_marginLeft == rParagraphProps.m_marginLeft && m_marginRight == rParagraphProps.m_marginRight && m_marginTop == rParagraphProps.m_marginTop && m_marginBottom == rParagraphProps.m_marginBottom && m_keepWithNext == rParagraphProps.m_keepWithNext && m_breakBefore == rParagraphProps.m_breakBefore && m_writingMode == rParagraphProps.m_writingMode && m_defaultTabInterval == rParagraphProps.m_defaultTabInterval && m_tabStops == rParagraphProps.m_tabStops; } /******************************************************************************* * TextProps ******************************************************************************/ /** * */ bool ODe_Style_Style::TextProps::isEmpty() const { return m_color.empty() && m_underlineType.empty() && m_lineThroughType.empty() && m_textPosition.empty() && m_fontName.empty() && m_fontSize.empty() && m_language.empty() && m_country.empty() && m_fontStyle.empty() && m_fontWeight.empty() && m_backgroundColor.empty() && m_display.empty() && m_transform.empty(); } /** * */ void ODe_Style_Style::TextProps:: fetchAttributesFromAbiProps(const PP_AttrProp& rAP) { const gchar* pValue; bool ok; ok = rAP.getProperty("color", pValue); if (ok && pValue && *pValue) { // TODO: handle transparent? m_color = UT_colorToHex(pValue, true); } ok = rAP.getProperty("text-decoration", pValue); if (ok && pValue != NULL) { if (strstr(pValue, "underline")) m_underlineType = "single"; if (strstr(pValue, "line-through")) m_lineThroughType = "single"; } ok = rAP.getProperty("text-position", pValue); if (ok && pValue != NULL) { if (!strcmp("subscript", pValue)) { // Hard coded, it's ugly but I can't do otherwise. m_textPosition = "-33%"; } else if (!strcmp("superscript", pValue)) { // Hard coded, it's ugly but I can't do otherwise. m_textPosition = "33%"; } else { UT_ASSERT( !strcmp("normal", pValue) ); m_textPosition.clear(); } } ok = rAP.getProperty("font-family", pValue); if (ok && pValue != NULL) { m_fontName = pValue; } ok = rAP.getProperty("font-size", pValue); if (ok && pValue != NULL) { m_fontSize = pValue; } ok = rAP.getProperty("lang", pValue); if (ok && pValue != NULL) { if (!strcmp(pValue, "-none-")) { m_language = "none"; m_country = "none"; } else { gchar strLanguage[4]; gchar strCountry[3]; int len = strlen(pValue); bool bLong = (len == 6); // Note: not all language codes are 5 characters (e.g. cop-EG) if ((len == 5) || bLong) { strLanguage[0] = pValue[0]; strLanguage[1] = pValue[1]; if(bLong) { strLanguage[2] = pValue[2]; // pValue[3] == '-' strCountry[0] = pValue[4]; strCountry[1] = pValue[5]; } else { strLanguage[2] = 0; // pValue[2] == '-' strCountry[0] = pValue[3]; strCountry[1] = pValue[4]; } strLanguage[3] = 0; strCountry[2] = 0; m_language = strLanguage; m_country = strCountry; } else { UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN); } } } ok = rAP.getProperty("font-style", pValue); if (ok && pValue != NULL) { if (!strcmp(pValue, "italic")) { m_fontStyle = "italic"; } } ok = rAP.getProperty("font-weight", pValue); if (ok && pValue != NULL) { if (!strcmp(pValue, "bold")) { m_fontWeight = "bold"; } else if (!strcmp(pValue, "normal")) { m_fontWeight = "normal"; } } ok = rAP.getProperty("bgcolor", pValue); if (ok && pValue && *pValue) { if (!strcmp("transparent", pValue)) { m_backgroundColor = pValue; } else { m_backgroundColor = UT_colorToHex(pValue, true); } } ok = rAP.getProperty("display", pValue); if (ok && pValue != NULL) { if (!strcmp(pValue, "none")) { m_display = "none"; } else { m_display = "true"; } } ok = rAP.getProperty("text-transform", pValue); if (ok && pValue && *pValue && (!strcmp(pValue, "none") || !strcmp(pValue, "lowercase") || !strcmp(pValue, "uppercase") || !strcmp(pValue, "capitalize"))) { m_transform = pValue; } } /** * */ void ODe_Style_Style::TextProps:: write(UT_UTF8String& rOutput, const UT_UTF8String& rSpacesOffset) const { if (isEmpty()) { return; } rOutput += rSpacesOffset; rOutput += "0) { rOutput += "