[Libreoffice-commits] core.git: sw/qa sw/source writerfilter/source

Miklos Vajna vmiklos at collabora.co.uk
Thu Oct 31 13:03:15 CET 2013


 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 <vmiklos at 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 );


More information about the Libreoffice-commits mailing list