sw/qa/extras/ooxmlexport/ooxmlexport.cxx | 1 sw/source/filter/ww8/docxtablestyleexport.cxx | 48 +++ writerfilter/source/dmapper/TDefTableHandler.cxx | 264 +++++++++++++++++ writerfilter/source/dmapper/TDefTableHandler.hxx | 17 - writerfilter/source/dmapper/TablePropertiesHandler.cxx | 4 5 files changed, 330 insertions(+), 4 deletions(-)
New commits: commit 62f67d64b4c98cdfe20cad824cf11f343d3f8d7f Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Thu Oct 31 12:14:40 2013 +0100 writerfilter: implement TDefTableHandler::getInteropGrabBag This allows to roundtrip table cell borders in conditional table style definitions for DOCX. Change-Id: Ibc0da9996e98e89864c001294695328c15c1549c diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx index 5028733..1e46c83 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx @@ -1476,6 +1476,7 @@ void Test::testCalendar1() assertXPath(pXmlStyles, "/w:styles/w:style[@w:styleId='Calendar1']/w:tblStylePr[@w:type='firstRow']/w:rPr/w:rFonts", "hAnsiTheme", "minorHAnsi"); assertXPath(pXmlStyles, "/w:styles/w:style[@w:styleId='Calendar1']/w:tblStylePr[@w:type='firstRow']/w:tblPr", 1); assertXPath(pXmlStyles, "/w:styles/w:style[@w:styleId='Calendar1']/w:tblStylePr[@w:type='firstRow']/w:tcPr/w:vAlign", "val", "bottom"); + assertXPath(pXmlStyles, "/w:styles/w:style[@w:styleId='Calendar1']/w:tblStylePr[@w:type='lastRow']/w:tcPr/w:tcBorders/w:tr2bl", "val", "nil"); } void Test::testSmartart() diff --git a/sw/source/filter/ww8/docxtablestyleexport.cxx b/sw/source/filter/ww8/docxtablestyleexport.cxx index 634368a..9aaad80 100644 --- a/sw/source/filter/ww8/docxtablestyleexport.cxx +++ b/sw/source/filter/ww8/docxtablestyleexport.cxx @@ -91,6 +91,49 @@ void lcl_TableStyleTblCellMar(sax_fastparser::FSHelperPtr pSerializer, uno::Sequ pSerializer->endElementNS(XML_w, XML_tblCellMar); } +/// Export of a given table cell border type in a table style. +void lcl_TableStyleTcBorder(sax_fastparser::FSHelperPtr pSerializer, sal_Int32 nToken, const uno::Sequence<beans::PropertyValue>& rTcBorder) +{ + if (!rTcBorder.hasElements()) + return; + + sax_fastparser::FastAttributeList* pAttributeList = pSerializer->createAttrList(); + for (sal_Int32 i = 0; i < rTcBorder.getLength(); ++i) + { + if (rTcBorder[i].Name == "val") + pAttributeList->add(FSNS(XML_w, XML_val), OUStringToOString(rTcBorder[i].Value.get<OUString>(), RTL_TEXTENCODING_UTF8).getStr()); + } + sax_fastparser::XFastAttributeListRef xAttributeList(pAttributeList); + pSerializer->singleElementNS(XML_w, nToken, xAttributeList); +} + +DocxStringTokenMap const aTcBordersTokens[] = { + {"left", XML_left}, + {"right", XML_right}, + {"start", XML_start}, + {"end", XML_end}, + {"top", XML_top}, + {"bottom", XML_bottom}, + {"insideH", XML_insideH}, + {"insideV", XML_insideV}, + {"tl2br", XML_tl2br}, + {"tr2bl", XML_tr2bl}, + {0, 0} +}; + +/// Export of w:tcBorders in a table style. +void lcl_TableStyleTcBorders(sax_fastparser::FSHelperPtr pSerializer, uno::Sequence<beans::PropertyValue>& rTcBorders) +{ + if (!rTcBorders.hasElements()) + return; + + pSerializer->startElementNS(XML_w, XML_tcBorders, FSEND); + for (sal_Int32 i = 0; i < rTcBorders.getLength(); ++i) + if (sal_Int32 nToken = DocxStringGetToken(aTcBordersTokens, rTcBorders[i].Name)) + lcl_TableStyleTcBorder(pSerializer, nToken, rTcBorders[i].Value.get< uno::Sequence<beans::PropertyValue> >()); + pSerializer->endElementNS(XML_w, XML_tcBorders); +} + /// Export of w:shd in a table style. void lcl_TableStyleShd(sax_fastparser::FSHelperPtr pSerializer, uno::Sequence<beans::PropertyValue>& rShd) { @@ -325,15 +368,18 @@ void lcl_TableStyleTcPr(sax_fastparser::FSHelperPtr pSerializer, uno::Sequence<b pSerializer->startElementNS(XML_w, XML_tcPr, FSEND); - uno::Sequence<beans::PropertyValue> aShd; + uno::Sequence<beans::PropertyValue> aShd, aTcBorders; OUString aVAlign; for (sal_Int32 i = 0; i < rTcPr.getLength(); ++i) { if (rTcPr[i].Name == "shd") aShd = rTcPr[i].Value.get< uno::Sequence<beans::PropertyValue> >(); + else if (rTcPr[i].Name == "tcBorders") + aTcBorders = rTcPr[i].Value.get< uno::Sequence<beans::PropertyValue> >(); else if (rTcPr[i].Name == "vAlign") aVAlign = rTcPr[i].Value.get<OUString>(); } + lcl_TableStyleTcBorders(pSerializer, aTcBorders); lcl_TableStyleShd(pSerializer, aShd); if (!aVAlign.isEmpty()) pSerializer->singleElementNS(XML_w, XML_vAlign, diff --git a/writerfilter/source/dmapper/TDefTableHandler.cxx b/writerfilter/source/dmapper/TDefTableHandler.cxx index 04466f4..5e9c5b5 100644 --- a/writerfilter/source/dmapper/TDefTableHandler.cxx +++ b/writerfilter/source/dmapper/TDefTableHandler.cxx @@ -49,6 +49,205 @@ TDefTableHandler::~TDefTableHandler() { } +OUString lcl_getBorderTypeString(sal_Int32 nType) +{ + switch (nType) + { + case 255: return OUString("nil"); + case 0: return OUString("none"); + case 1: return OUString("single"); + case 2: return OUString("thick"); + case 3: return OUString("double"); + case 6: return OUString("dotted"); + case 7: return OUString("dashed"); + case 8: return OUString("dotDash"); + case 9: return OUString("dotDotDash"); + case 10: return OUString("triple"); + case 11: return OUString("thinThickSmallGap"); + case 12: return OUString("thickThinSmallGap"); + case 13: return OUString("thinThickThinSmallGap"); + case 14: return OUString("thinThickMediumGap"); + case 15: return OUString("thickThinMediumGap"); + case 16: return OUString("thinThickThinMediumGap"); + case 17: return OUString("thinThickLargeGap"); + case 18: return OUString("thickThinLargeGap"); + case 19: return OUString("thinThickThinLargeGap"); + case 20: return OUString("wave"); + case 21: return OUString("doubleWave"); + case 22: return OUString("dashSmallGap"); + case 23: return OUString("dashDotStroked"); + case 24: return OUString("threeDEmboss"); + case 25: return OUString("threeDEngrave"); + case 26: return OUString("outset"); + case 27: return OUString("inset"); + case 64: return OUString("apples"); + case 65: return OUString("archedScallops"); + case 66: return OUString("babyPacifier"); + case 67: return OUString("babyRattle"); + case 68: return OUString("balloons3Colors"); + case 69: return OUString("balloonsHotAir"); + case 70: return OUString("basicBlackDashes"); + case 71: return OUString("basicBlackDots"); + case 72: return OUString("basicBlackSquares"); + case 73: return OUString("basicThinLines"); + case 74: return OUString("basicWhiteDashes"); + case 75: return OUString("basicWhiteDots"); + case 76: return OUString("basicWhiteSquares"); + case 77: return OUString("basicWideInline"); + case 78: return OUString("basicWideMidline"); + case 79: return OUString("basicWideOutline"); + case 80: return OUString("bats"); + case 81: return OUString("birds"); + case 82: return OUString("birdsFlight"); + case 83: return OUString("cabins"); + case 84: return OUString("cakeSlice"); + case 85: return OUString("candyCorn"); + case 86: return OUString("celticKnotwork"); + case 87: return OUString("certificateBanner"); + case 88: return OUString("chainLink"); + case 89: return OUString("champagneBottle"); + case 90: return OUString("checkedBarBlack"); + case 91: return OUString("checkedBarColor"); + case 92: return OUString("checkered"); + case 93: return OUString("christmasTree"); + case 94: return OUString("circlesLines"); + case 95: return OUString("circlesRectangles"); + case 96: return OUString("classicalWave"); + case 97: return OUString("clocks"); + case 98: return OUString("compass"); + case 99: return OUString("confetti"); + case 100: return OUString("confettiGrays"); + case 101: return OUString("confettiOutline"); + case 102: return OUString("confettiStreamers"); + case 103: return OUString("confettiWhite"); + case 104: return OUString("cornerTriangles"); + case 105: return OUString("couponCutoutDashes"); + case 106: return OUString("couponCutoutDots"); + case 107: return OUString("crazyMaze"); + case 108: return OUString("creaturesButterfly"); + case 109: return OUString("creaturesFish"); + case 110: return OUString("creaturesInsects"); + case 111: return OUString("creaturesLadyBug"); + case 112: return OUString("crossStitch"); + case 113: return OUString("cup"); + case 114: return OUString("decoArch"); + case 115: return OUString("decoArchColor"); + case 116: return OUString("decoBlocks"); + case 117: return OUString("diamondsGray"); + case 118: return OUString("doubleD"); + case 119: return OUString("doubleDiamonds"); + case 120: return OUString("earth1"); + case 121: return OUString("earth2"); + case 122: return OUString("eclipsingSquares1"); + case 123: return OUString("eclipsingSquares2"); + case 124: return OUString("eggsBlack"); + case 125: return OUString("fans"); + case 126: return OUString("film"); + case 127: return OUString("firecrackers"); + case 128: return OUString("flowersBlockPrint"); + case 129: return OUString("flowersDaisies"); + case 130: return OUString("flowersModern1"); + case 131: return OUString("flowersModern2"); + case 132: return OUString("flowersPansy"); + case 133: return OUString("flowersRedRose"); + case 134: return OUString("flowersRoses"); + case 135: return OUString("flowersTeacup"); + case 136: return OUString("flowersTiny"); + case 137: return OUString("gems"); + case 138: return OUString("gingerbreadMan"); + case 139: return OUString("gradient"); + case 140: return OUString("handmade1"); + case 141: return OUString("handmade2"); + case 142: return OUString("heartBalloon"); + case 143: return OUString("heartGray"); + case 144: return OUString("hearts"); + case 145: return OUString("heebieJeebies"); + case 146: return OUString("holly"); + case 147: return OUString("houseFunky"); + case 148: return OUString("hypnotic"); + case 149: return OUString("iceCreamCones"); + case 150: return OUString("lightBulb"); + case 151: return OUString("lightning1"); + case 152: return OUString("lightning2"); + case 153: return OUString("mapPins"); + case 154: return OUString("mapleLeaf"); + case 155: return OUString("mapleMuffins"); + case 156: return OUString("marquee"); + case 157: return OUString("marqueeToothed"); + case 158: return OUString("moons"); + case 159: return OUString("mosaic"); + case 160: return OUString("musicNotes"); + case 161: return OUString("northwest"); + case 162: return OUString("ovals"); + case 163: return OUString("packages"); + case 164: return OUString("palmsBlack"); + case 165: return OUString("palmsColor"); + case 166: return OUString("paperClips"); + case 167: return OUString("papyrus"); + case 168: return OUString("partyFavor"); + case 169: return OUString("partyGlass"); + case 170: return OUString("pencils"); + case 171: return OUString("people"); + case 172: return OUString("peopleWaving"); + case 173: return OUString("peopleHats"); + case 174: return OUString("poinsettias"); + case 175: return OUString("postageStamp"); + case 176: return OUString("pumpkin1"); + case 177: return OUString("pushPinNote2"); + case 178: return OUString("pushPinNote1"); + case 179: return OUString("pyramids"); + case 180: return OUString("pyramidsAbove"); + case 181: return OUString("quadrants"); + case 182: return OUString("rings"); + case 183: return OUString("safari"); + case 184: return OUString("sawtooth"); + case 185: return OUString("sawtoothGray"); + case 186: return OUString("scaredCat"); + case 187: return OUString("seattle"); + case 188: return OUString("shadowedSquares"); + case 189: return OUString("sharksTeeth"); + case 190: return OUString("shorebirdTracks"); + case 191: return OUString("skyrocket"); + case 192: return OUString("snowflakeFancy"); + case 193: return OUString("snowflakes"); + case 194: return OUString("sombrero"); + case 195: return OUString("southwest"); + case 196: return OUString("stars"); + case 197: return OUString("starsTop"); + case 198: return OUString("stars3d"); + case 199: return OUString("starsBlack"); + case 200: return OUString("starsShadowed"); + case 201: return OUString("sun"); + case 202: return OUString("swirligig"); + case 203: return OUString("tornPaper"); + case 204: return OUString("tornPaperBlack"); + case 205: return OUString("trees"); + case 206: return OUString("triangleParty"); + case 207: return OUString("triangles"); + case 208: return OUString("tribal1"); + case 209: return OUString("tribal2"); + case 210: return OUString("tribal3"); + case 211: return OUString("tribal4"); + case 212: return OUString("tribal5"); + case 213: return OUString("tribal6"); + case 214: return OUString("twistedLines1"); + case 215: return OUString("twistedLines2"); + case 216: return OUString("vine"); + case 217: return OUString("waveline"); + case 218: return OUString("weavingAngles"); + case 219: return OUString("weavingBraid"); + case 220: return OUString("weavingRibbon"); + case 221: return OUString("weavingStrips"); + case 222: return OUString("whiteFlowers"); + case 223: return OUString("woodwork"); + case 224: return OUString("xIllusions"); + case 225: return OUString("zanyTriangles"); + case 226: return OUString("zigZag"); + case 227: return OUString("zigZagStitch"); + default: break; + } + return OUString(); +} void TDefTableHandler::lcl_attribute(Id rName, Value & rVal) { @@ -105,6 +304,7 @@ void TDefTableHandler::lcl_attribute(Id rName, Value & rVal) break; case NS_rtf::LN_BRCTYPE: // 0x2872 m_nLineType = nIntValue; + appendGrabBag("val", lcl_getBorderTypeString(nIntValue)); break; case NS_ooxml::LN_CT_Border_color: case NS_rtf::LN_ICO: // 0x2873 @@ -135,6 +335,13 @@ void TDefTableHandler::localResolve(Id rName, writerfilter::Reference<Properties if( pProperties.get()) { m_nLineWidth = m_nLineType = m_nLineColor = m_nLineDistance = 0; + std::vector<beans::PropertyValue> aSavedGrabBag; + if (!m_aInteropGrabBagName.isEmpty()) + { + aSavedGrabBag = m_aInteropGrabBag; + m_aInteropGrabBag.clear(); + } + m_aInteropGrabBag.clear(); pProperties->resolve( *this ); table::BorderLine2 aBorderLine; ConversionHelper::MakeBorderLine( m_nLineWidth, m_nLineType, m_nLineColor, @@ -145,39 +352,65 @@ void TDefTableHandler::localResolve(Id rName, writerfilter::Reference<Properties case NS_ooxml::LN_CT_TcBorders_top: case NS_rtf::LN_BRCTOP: m_aTopBorderLines.push_back(aBorderLine); + if (!m_aInteropGrabBagName.isEmpty()) + aSavedGrabBag.push_back(getInteropGrabBag("top")); break; case NS_ooxml::LN_CT_TcBorders_start: if( rtl ) m_aRightBorderLines.push_back(aBorderLine); else m_aLeftBorderLines.push_back(aBorderLine); + if (!m_aInteropGrabBagName.isEmpty()) + aSavedGrabBag.push_back(getInteropGrabBag("start")); break; case NS_ooxml::LN_CT_TcBorders_left: case NS_rtf::LN_BRCLEFT: m_aLeftBorderLines.push_back(aBorderLine); + if (!m_aInteropGrabBagName.isEmpty()) + aSavedGrabBag.push_back(getInteropGrabBag("left")); break; case NS_ooxml::LN_CT_TcBorders_bottom: case NS_rtf::LN_BRCBOTTOM: m_aBottomBorderLines.push_back(aBorderLine); + if (!m_aInteropGrabBagName.isEmpty()) + aSavedGrabBag.push_back(getInteropGrabBag("bottom")); break; case NS_ooxml::LN_CT_TcBorders_end: if( rtl ) m_aLeftBorderLines.push_back(aBorderLine); else m_aRightBorderLines.push_back(aBorderLine); + if (!m_aInteropGrabBagName.isEmpty()) + aSavedGrabBag.push_back(getInteropGrabBag("end")); break; case NS_ooxml::LN_CT_TcBorders_right: case NS_rtf::LN_BRCRIGHT: m_aRightBorderLines.push_back(aBorderLine); + if (!m_aInteropGrabBagName.isEmpty()) + aSavedGrabBag.push_back(getInteropGrabBag("right")); break; case NS_ooxml::LN_CT_TcBorders_insideH: m_aInsideHBorderLines.push_back(aBorderLine); + if (!m_aInteropGrabBagName.isEmpty()) + aSavedGrabBag.push_back(getInteropGrabBag("insideH")); break; case NS_ooxml::LN_CT_TcBorders_insideV: m_aInsideVBorderLines.push_back(aBorderLine); + if (!m_aInteropGrabBagName.isEmpty()) + aSavedGrabBag.push_back(getInteropGrabBag("insideV")); + break; + case NS_ooxml::LN_CT_TcBorders_tl2br: + if (!m_aInteropGrabBagName.isEmpty()) + aSavedGrabBag.push_back(getInteropGrabBag("tl2br")); + break; + case NS_ooxml::LN_CT_TcBorders_tr2bl: + if (!m_aInteropGrabBagName.isEmpty()) + aSavedGrabBag.push_back(getInteropGrabBag("tr2bl")); break; default:; } + if (!m_aInteropGrabBagName.isEmpty()) + m_aInteropGrabBag = aSavedGrabBag; } } @@ -280,6 +513,37 @@ size_t TDefTableHandler::getCellCount() const return m_aCellVertAlign.size(); } +void TDefTableHandler::enableInteropGrabBag(OUString aName) +{ + m_aInteropGrabBagName = aName; +} + +beans::PropertyValue TDefTableHandler::getInteropGrabBag(OUString aName) +{ + beans::PropertyValue aRet; + if (aName.isEmpty()) + aRet.Name = m_aInteropGrabBagName; + else + aRet.Name = aName; + + uno::Sequence<beans::PropertyValue> aSeq(m_aInteropGrabBag.size()); + beans::PropertyValue* pSeq = aSeq.getArray(); + for (std::vector<beans::PropertyValue>::iterator i = m_aInteropGrabBag.begin(); i != m_aInteropGrabBag.end(); ++i) + *pSeq++ = *i; + m_aInteropGrabBag.clear(); + + aRet.Value = uno::makeAny(aSeq); + return aRet; +} + +void TDefTableHandler::appendGrabBag(OUString aKey, OUString aValue) +{ + beans::PropertyValue aProperty; + aProperty.Name = aKey; + aProperty.Value = uno::makeAny(aValue); + m_aInteropGrabBag.push_back(aProperty); +} + } //namespace dmapper } //namespace writerfilter diff --git a/writerfilter/source/dmapper/TDefTableHandler.hxx b/writerfilter/source/dmapper/TDefTableHandler.hxx index 6e27544..993baf7 100644 --- a/writerfilter/source/dmapper/TDefTableHandler.hxx +++ b/writerfilter/source/dmapper/TDefTableHandler.hxx @@ -23,9 +23,14 @@ #include <resourcemodel/LoggedResources.hxx> #include <boost/shared_ptr.hpp> #include <vector> -namespace com{ namespace sun{ namespace star{namespace table { - struct BorderLine2; -}}}} +namespace com{ namespace sun{ namespace star{ + namespace table { + struct BorderLine2; + } + namespace beans { + struct PropertyValue; + } +}}} namespace writerfilter { namespace dmapper @@ -57,6 +62,10 @@ private: bool m_bOOXML; + OUString m_aInteropGrabBagName; + std::vector<beans::PropertyValue> m_aInteropGrabBag; + void appendGrabBag(OUString aKey, OUString aValue); + void localResolve(Id Name, writerfilter::Reference<Properties>::Pointer_t pProperties); // Properties @@ -71,6 +80,8 @@ public: void fillCellProperties( size_t nCell, ::boost::shared_ptr< TablePropertyMap > pCellProperties) const; ::boost::shared_ptr<PropertyMap> getRowProperties() const; sal_Int32 getTableWidth() const; + void enableInteropGrabBag(OUString aName); + beans::PropertyValue getInteropGrabBag(OUString aName = OUString()); }; typedef boost::shared_ptr< TDefTableHandler > TDefTableHandlerPtr; }} diff --git a/writerfilter/source/dmapper/TablePropertiesHandler.cxx b/writerfilter/source/dmapper/TablePropertiesHandler.cxx index 255547c..fe64c47 100644 --- a/writerfilter/source/dmapper/TablePropertiesHandler.cxx +++ b/writerfilter/source/dmapper/TablePropertiesHandler.cxx @@ -195,7 +195,11 @@ namespace dmapper { { //in OOXML there's one set of borders at each cell (if there is any) TDefTableHandlerPtr pTDefTableHandler( new TDefTableHandler( m_bOOXML )); + if (m_pCurrentInteropGrabBag) + pTDefTableHandler->enableInteropGrabBag("tcBorders"); pProperties->resolve( *pTDefTableHandler ); + if (m_pCurrentInteropGrabBag) + m_pCurrentInteropGrabBag->push_back(pTDefTableHandler->getInteropGrabBag()); TablePropertyMapPtr pCellPropMap( new TablePropertyMap ); pTDefTableHandler->fillCellProperties( 0, pCellPropMap ); cellProps( pCellPropMap ); _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits