LCOV - code coverage report
Current view: top level - sw/qa/extras/ooxmlexport - ooxmlexport2.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 589 597 98.7 %
Date: 2014-11-03 Functions: 603 671 89.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  */
       9             : 
      10             : #include <swmodeltestbase.hxx>
      11             : 
      12             : #include <com/sun/star/awt/XBitmap.hpp>
      13             : #include <com/sun/star/graphic/XGraphic.hpp>
      14             : #include <com/sun/star/frame/XStorable.hpp>
      15             : #include <com/sun/star/drawing/FillStyle.hpp>
      16             : #include <com/sun/star/drawing/LineJoint.hpp>
      17             : #include <com/sun/star/drawing/LineStyle.hpp>
      18             : #include <com/sun/star/drawing/XControlShape.hpp>
      19             : #include <com/sun/star/awt/Gradient.hpp>
      20             : #include <com/sun/star/style/TabStop.hpp>
      21             : #include <com/sun/star/view/XViewSettingsSupplier.hpp>
      22             : #include <com/sun/star/text/RelOrientation.hpp>
      23             : #include <com/sun/star/text/XTextFrame.hpp>
      24             : #include <com/sun/star/text/XTextTable.hpp>
      25             : #include <com/sun/star/text/XTextFramesSupplier.hpp>
      26             : #include <com/sun/star/text/XTextViewCursorSupplier.hpp>
      27             : #include <com/sun/star/text/XTextSection.hpp>
      28             : #include <com/sun/star/style/CaseMap.hpp>
      29             : #include <com/sun/star/style/ParagraphAdjust.hpp>
      30             : #include <com/sun/star/style/LineSpacing.hpp>
      31             : #include <com/sun/star/style/LineSpacingMode.hpp>
      32             : #include <com/sun/star/view/XSelectionSupplier.hpp>
      33             : #include <com/sun/star/table/BorderLine2.hpp>
      34             : #include <com/sun/star/table/ShadowFormat.hpp>
      35             : #include <com/sun/star/text/GraphicCrop.hpp>
      36             : #include <com/sun/star/text/XPageCursor.hpp>
      37             : #include <com/sun/star/awt/FontWeight.hpp>
      38             : #include <com/sun/star/awt/FontUnderline.hpp>
      39             : #include <com/sun/star/awt/FontSlant.hpp>
      40             : #include <com/sun/star/text/WritingMode2.hpp>
      41             : #include <com/sun/star/text/WrapTextMode.hpp>
      42             : #include <com/sun/star/xml/dom/XDocument.hpp>
      43             : #include <com/sun/star/style/BreakType.hpp>
      44             : #include <unotools/tempfile.hxx>
      45             : #include <comphelper/sequenceashashmap.hxx>
      46             : #include <com/sun/star/text/XDocumentIndex.hpp>
      47             : #include <com/sun/star/drawing/EnhancedCustomShapeSegment.hpp>
      48             : #include <com/sun/star/drawing/EnhancedCustomShapeSegmentCommand.hpp>
      49             : #include <com/sun/star/drawing/EnhancedCustomShapeParameterPair.hpp>
      50             : #include <com/sun/star/drawing/TextVerticalAdjust.hpp>
      51             : #include <com/sun/star/drawing/Hatch.hpp>
      52             : 
      53             : #include <string>
      54             : 
      55         264 : class Test : public SwModelTestBase
      56             : {
      57             : public:
      58         264 :     Test() : SwModelTestBase("/sw/qa/extras/ooxmlexport/data/", "Office Open XML Text") {}
      59             : 
      60             : protected:
      61             :     /**
      62             :      * Blacklist handling
      63             :      */
      64         132 :     bool mustTestImportOf(const char* filename) const SAL_OVERRIDE {
      65             :         const char* aBlacklist[] = {
      66             :             "math-escape.docx",
      67             :             "math-mso2k7.docx",
      68             :             "ImageCrop.docx",
      69             :             "test_GIF_ImageCrop.docx",
      70             :             "test_PNG_ImageCrop.docx"
      71         132 :         };
      72         132 :         std::vector<const char*> vBlacklist(aBlacklist, aBlacklist + SAL_N_ELEMENTS(aBlacklist));
      73             : 
      74             :         // If the testcase is stored in some other format, it's pointless to test.
      75         132 :         return (OString(filename).endsWith(".docx") && std::find(vBlacklist.begin(), vBlacklist.end(), filename) == vBlacklist.end());
      76             :     }
      77             : 
      78             :     /**
      79             :      * Validation handling
      80             :      */
      81         132 :     bool mustValidate(const char* filename) const SAL_OVERRIDE
      82             :     {
      83             :         const char* aWhitelist[] = {
      84             :             "page-graphic-background.odt",
      85             :             "zoom.docx",
      86             :             "empty.odt",
      87             :             "fdo38244.docx",
      88             :             "comments-nested.odt"
      89         132 :         };
      90         132 :         std::vector<const char*> vWhitelist(aWhitelist, aWhitelist + SAL_N_ELEMENTS(aWhitelist));
      91             : 
      92         132 :         return std::find(vWhitelist.begin(), vWhitelist.end(), filename) != vWhitelist.end();
      93             :     }
      94             : };
      95             : 
      96             : #if !defined(WNT)
      97             : 
      98          26 : DECLARE_OOXMLEXPORT_TEST(testPageGraphicBackground, "page-graphic-background.odt")
      99             : {
     100             :     // No idea how the graphic background should be exported (seems there is no
     101             :     // way to do a non-tiling export to OOXML), but at least the background
     102             :     // color shouldn't be black.
     103           2 :     uno::Reference<beans::XPropertySet> xPageStyle(getStyles("PageStyles")->getByName(DEFAULT_STYLE), uno::UNO_QUERY);
     104           2 :     CPPUNIT_ASSERT_EQUAL(sal_Int32(-1), getProperty<sal_Int32>(xPageStyle, "BackColor"));
     105           2 : }
     106             : 
     107          28 : DECLARE_OOXMLEXPORT_TEST(testZoom, "zoom.docx")
     108             : {
     109           4 :     uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);
     110           6 :     uno::Reference<view::XViewSettingsSupplier> xViewSettingsSupplier(xModel->getCurrentController(), uno::UNO_QUERY);
     111           6 :     uno::Reference<beans::XPropertySet> xPropertySet(xViewSettingsSupplier->getViewSettings());
     112           4 :     sal_Int16 nValue = 0;
     113           4 :     xPropertySet->getPropertyValue("ZoomValue") >>= nValue;
     114           4 :     CPPUNIT_ASSERT_EQUAL(sal_Int16(42), nValue);
     115             : 
     116             :     // Validation test: order of elements were wrong.
     117           4 :     xmlDocPtr pXmlDoc = parseExport("word/styles.xml");
     118           4 :     if (!pXmlDoc)
     119           6 :         return;
     120             :     // Order was: rsid, next.
     121           2 :     int nNext = getXPathPosition(pXmlDoc, "/w:styles/w:style[3]", "next");
     122           2 :     int nRsid = getXPathPosition(pXmlDoc, "/w:styles/w:style[3]", "rsid");
     123           2 :     CPPUNIT_ASSERT(nNext < nRsid);
     124             : 
     125           2 :     pXmlDoc = parseExport("docProps/app.xml");
     126             :     // One paragraph in the document.
     127           2 :     assertXPathContent(pXmlDoc, "/extended-properties:Properties/extended-properties:Paragraphs", "1");
     128           4 :     assertXPathContent(pXmlDoc, "/extended-properties:Properties/extended-properties:Company", "Example Ltd");
     129             : }
     130             : 
     131          26 : DECLARE_OOXMLEXPORT_TEST(defaultTabStopNotInStyles, "empty.odt")
     132             : {
     133             : // The default tab stop was mistakenly exported to a style.
     134             : // xray ThisComponent.StyleFamilies(1)(0).ParaTabStop
     135           2 :     uno::Reference< container::XNameAccess > paragraphStyles = getStyles( "ParagraphStyles" );
     136           4 :     uno::Reference< beans::XPropertySet > properties( paragraphStyles->getByName( "Standard" ), uno::UNO_QUERY );
     137             :     uno::Sequence< style::TabStop > stops = getProperty< uno::Sequence< style::TabStop > >(
     138           4 :         paragraphStyles->getByName( "Standard" ), "ParaTabStops" );
     139             : // There actually be be one tab stop, but it will be the default.
     140           2 :     CPPUNIT_ASSERT_EQUAL( static_cast<sal_Int32>(1), stops.getLength());
     141           4 :     CPPUNIT_ASSERT_EQUAL( style::TabAlign_DEFAULT, stops[ 0 ].Alignment );
     142           2 : }
     143             : 
     144          28 : DECLARE_OOXMLEXPORT_TEST(testFdo38244, "fdo38244.docx")
     145             : {
     146             :     /*
     147             :      * Comments attached to a range was imported without the range, check for the annotation mark start/end positions.
     148             :      *
     149             :      * oParas = ThisComponent.Text.createEnumeration
     150             :      * oPara = oParas.nextElement
     151             :      * oRuns = oPara.createEnumeration
     152             :      * oRun = oRuns.nextElement
     153             :      * oRun = oRuns.nextElement 'Annotation
     154             :      * oRun = oRuns.nextElement
     155             :      * oRun = oRuns.nextElement 'AnnotationEnd
     156             :      * xray oRun.TextPortionType
     157             :      */
     158           4 :     uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
     159           8 :     uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xTextDocument->getText(), uno::UNO_QUERY);
     160           8 :     uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
     161           8 :     uno::Reference<container::XEnumerationAccess> xRunEnumAccess(xParaEnum->nextElement(), uno::UNO_QUERY);
     162           8 :     uno::Reference<container::XEnumeration> xRunEnum = xRunEnumAccess->createEnumeration();
     163           4 :     xRunEnum->nextElement();
     164           8 :     uno::Reference<beans::XPropertySet> xPropertySet(xRunEnum->nextElement(), uno::UNO_QUERY);
     165           4 :     CPPUNIT_ASSERT_EQUAL(OUString("Annotation"), getProperty<OUString>(xPropertySet, "TextPortionType"));
     166           4 :     xRunEnum->nextElement();
     167           4 :     xPropertySet.set(xRunEnum->nextElement(), uno::UNO_QUERY);
     168           4 :     CPPUNIT_ASSERT_EQUAL(OUString("AnnotationEnd"), getProperty<OUString>(xPropertySet, "TextPortionType"));
     169             : 
     170             :     /*
     171             :      * Initials were not imported.
     172             :      *
     173             :      * oFields = ThisComponent.TextFields.createEnumeration
     174             :      * oField = oFields.nextElement
     175             :      * xray oField.Initials
     176             :      */
     177           8 :     uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
     178           8 :     uno::Reference<container::XEnumerationAccess> xFieldsAccess(xTextFieldsSupplier->getTextFields());
     179           8 :     uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration());
     180           4 :     xPropertySet.set(xFields->nextElement(), uno::UNO_QUERY);
     181           4 :     CPPUNIT_ASSERT_EQUAL(OUString("M"), getProperty<OUString>(xPropertySet, "Initials"));
     182             : 
     183             :     /*
     184             :      * There was a fake empty paragraph at the end of the comment text.
     185             :      *
     186             :      * oFields = ThisComponent.TextFields.createEnumeration
     187             :      * oField = oFields.nextElement
     188             :      * oParas = oField.TextRange.createEnumeration
     189             :      * oPara = oParas.nextElement
     190             :      * oPara = oParas.nextElement
     191             :      */
     192             : 
     193           4 :     xParaEnumAccess.set(getProperty< uno::Reference<container::XEnumerationAccess> >(xPropertySet, "TextRange"), uno::UNO_QUERY);
     194           4 :     xParaEnum = xParaEnumAccess->createEnumeration();
     195           4 :     xParaEnum->nextElement();
     196           4 :     bool bCaught = false;
     197             :     try
     198             :     {
     199           4 :         xParaEnum->nextElement();
     200             :     }
     201           8 :     catch (container::NoSuchElementException&)
     202             :     {
     203           4 :         bCaught = true;
     204             :     }
     205           8 :     CPPUNIT_ASSERT_EQUAL(true, bCaught);
     206           4 : }
     207             : 
     208          26 : DECLARE_OOXMLEXPORT_TEST(testCommentsNested, "comments-nested.odt")
     209             : {
     210           2 :     uno::Reference<beans::XPropertySet> xOuter(getProperty< uno::Reference<beans::XPropertySet> >(getRun(getParagraph(1), 2), "TextField"), uno::UNO_QUERY);
     211           2 :     CPPUNIT_ASSERT_EQUAL(OUString("Outer"), getProperty<OUString>(xOuter, "Content"));
     212             : 
     213           4 :     uno::Reference<beans::XPropertySet> xInner(getProperty< uno::Reference<beans::XPropertySet> >(getRun(getParagraph(1), 4), "TextField"), uno::UNO_QUERY);
     214           4 :     CPPUNIT_ASSERT_EQUAL(OUString("Inner"), getProperty<OUString>(xInner, "Content"));
     215           2 : }
     216             : 
     217          26 : DECLARE_OOXMLEXPORT_TEST(testMathEscape, "math-escape.docx")
     218             : {
     219           2 :     CPPUNIT_ASSERT_EQUAL(OUString("\\{ left [ right ] left ( right ) \\}"), getFormula(getRun(getParagraph(1), 1)));
     220           2 : }
     221             : 
     222          26 : DECLARE_OOXMLEXPORT_TEST(testFdo51034, "fdo51034.odt")
     223             : {
     224             :     // The problem was that the 'l' param of the HYPERLINK field was parsed with = "#", not += "#".
     225           2 :     CPPUNIT_ASSERT_EQUAL(OUString("http://Www.google.com/#a"), getProperty<OUString>(getRun(getParagraph(1), 1), "HyperLinkURL"));
     226           2 : }
     227             : 
     228             : // Construct the expected formula from UTF8, as there may be such characters.
     229             : // Remove all spaces, as LO export/import may change that.
     230             : // Replace symbol - (i.e. U+2212) with ASCII - , LO does this change and it shouldn't matter.
     231             : #define CHECK_FORMULA( expected, actual ) \
     232             :     CPPUNIT_ASSERT_EQUAL( \
     233             :         OUString( expected, strlen( expected ), RTL_TEXTENCODING_UTF8 ) \
     234             :             .replaceAll( " ", "" ).replaceAll( OUString( "\xe2\x88\x92", strlen( "\xe2\x88\x92" ), RTL_TEXTENCODING_UTF8 ), "-" ), \
     235             :         OUString( actual ).replaceAll( " ", "" ).replaceAll( OUString( "\xe2\x88\x92", strlen( "\xe2\x88\x92" ), RTL_TEXTENCODING_UTF8 ), "-" ))
     236             : 
     237          28 : DECLARE_OOXMLEXPORT_TEST(testMathAccents, "math-accents.docx")
     238             : {
     239           8 :     CHECK_FORMULA(
     240             :         "acute {a} grave {a} check {a} breve {a} circle {a} widevec {a} widetilde {a}"
     241             :             " widehat {a} dot {a} widevec {a} widevec {a} widetilde {a} underline {a}",
     242           4 :         getFormula( getRun( getParagraph( 1 ), 1 )));
     243           4 : }
     244             : 
     245          28 : DECLARE_OOXMLEXPORT_TEST(testMathD, "math-d.docx")
     246             : {
     247           4 :     CHECK_FORMULA( "left (x mline y mline z right )", getFormula( getRun( getParagraph( 1 ), 1 )));
     248           4 :     CHECK_FORMULA( "left (1 right )", getFormula( getRun( getParagraph( 1 ), 2 )));
     249           4 :     CHECK_FORMULA( "left [2 right ]", getFormula( getRun( getParagraph( 1 ), 3 )));
     250           4 :     CHECK_FORMULA( "left ldbracket 3 right rdbracket", getFormula( getRun( getParagraph( 1 ), 4 )));
     251           4 :     CHECK_FORMULA( "left lline 4 right rline", getFormula( getRun( getParagraph( 1 ), 5 )));
     252           4 :     CHECK_FORMULA( "left ldline 5 right rdline", getFormula( getRun( getParagraph( 1 ), 6 )));
     253           4 :     CHECK_FORMULA( "left langle 6 right rangle", getFormula( getRun( getParagraph( 1 ), 7 )));
     254           4 :     CHECK_FORMULA( "left langle a mline b right rangle", getFormula( getRun( getParagraph( 1 ), 8 )));
     255           4 :     CHECK_FORMULA( "left ({x} over {y} right )", getFormula( getRun( getParagraph( 1 ), 9 )));
     256           4 : }
     257             : 
     258          28 : DECLARE_OOXMLEXPORT_TEST(testMathEscaping, "math-escaping.docx")
     259             : {
     260           4 :     CHECK_FORMULA( "\xe2\x88\x92 \xe2\x88\x9e < x < \xe2\x88\x9e", getFormula( getRun( getParagraph( 1 ), 1 )));
     261           4 : }
     262             : 
     263          28 : DECLARE_OOXMLEXPORT_TEST(testMathLim, "math-lim.docx")
     264             : {
     265           4 :     CHECK_FORMULA( "lim from {x \xe2\x86\x92 1} {x}", getFormula( getRun( getParagraph( 1 ), 1 )));
     266           4 : }
     267             : 
     268          28 : DECLARE_OOXMLEXPORT_TEST(testMathMalformedXml, "math-malformed_xml.docx")
     269             : {
     270           4 :     CPPUNIT_ASSERT_EQUAL( 0, getLength());
     271           4 : }
     272             : 
     273          28 : DECLARE_OOXMLEXPORT_TEST(testMathMatrix, "math-matrix.docx")
     274             : {
     275           4 :     CHECK_FORMULA( "left [matrix {1 # 2 ## 3 # 4} right ]", getFormula( getRun( getParagraph( 1 ), 1 )));
     276           4 : }
     277             : 
     278          26 : DECLARE_OOXMLEXPORT_TEST(testMathMso2k7, "math-mso2k7.docx")
     279             : {
     280           2 :     CHECK_FORMULA( "A = \xcf\x80 {r} ^ {2}", getFormula( getRun( getParagraph( 1 ), 1 )));
     281             : // TODO check the stack/binom difference
     282             : //    CHECK_FORMULA( "{left (x+a right )} ^ {n} = sum from {k=0} to {n} {left (binom {n} {k} right ) {x} ^ {k} {a} ^ {n-k}}",
     283           4 :     CHECK_FORMULA( "{left (x+a right )} ^ {n} = sum from {k=0} to {n} {left (stack {n # k} right ) {x} ^ {k} {a} ^ {n-k}}",
     284           2 :         getFormula( getRun( getParagraph( 2 ), 1 )));
     285           4 :     CHECK_FORMULA( "{left (1+x right )} ^ {n} =1+ {nx} over {1!} + {n left (n-1 right ) {x} ^ {2}} over {2!} +\xe2\x80\xa6",
     286           2 :         getFormula( getRun( getParagraph( 3 ), 1 )));
     287             : // TODO check (cos/sin miss {})
     288             : //    CHECK_FORMULA( "f left (x right ) = {a} rsub {0} + sum from {n=1} to {\xe2\x88\x9e} {left ({a} rsub {n} cos {{n\xcf\x80x} over {L}} + {b} rsub {n} sin {{n\xcf\x80x} over {L}} right )}",
     289           4 :     CHECK_FORMULA( "f left (x right ) = {a} rsub {0} + sum from {n=1} to {\xe2\x88\x9e} {left ({a} rsub {n} cos {n\xcf\x80x} over {L} + {b} rsub {n} sin {n\xcf\x80x} over {L} right )}",
     290           2 :         getFormula( getRun( getParagraph( 4 ), 1 )));
     291           2 :     CHECK_FORMULA( "{a} ^ {2} + {b} ^ {2} = {c} ^ {2}", getFormula( getRun( getParagraph( 5 ), 1 )));
     292           4 :     CHECK_FORMULA( "x = {- b \xc2\xb1 sqrt {{b} ^ {2} -4 ac}} over {2 a}",
     293           2 :         getFormula( getRun( getParagraph( 6 ), 1 )));
     294           4 :     CHECK_FORMULA(
     295             :         "{e} ^ {x} =1+ {x} over {1!} + {{x} ^ {2}} over {2!} + {{x} ^ {3}} over {3!} +\xe2\x80\xa6,    -\xe2\x88\x9e<x<\xe2\x88\x9e",
     296           2 :         getFormula( getRun( getParagraph( 7 ), 1 )));
     297           4 :     CHECK_FORMULA(
     298             : //        "sin {\xce\xb1} \xc2\xb1 sin {\xce\xb2} =2 sin {{1} over {2} left (\xce\xb1\xc2\xb1\xce\xb2 right )} cos {{1} over {2} left (\xce\xb1\xe2\x88\x93\xce\xb2 right )}",
     299             : // TODO check (cos/in miss {})
     300             :         "sin \xce\xb1 \xc2\xb1 sin \xce\xb2 =2 sin {1} over {2} left (\xce\xb1\xc2\xb1\xce\xb2 right ) cos {1} over {2} left (\xce\xb1\xe2\x88\x93\xce\xb2 right )",
     301           2 :         getFormula( getRun( getParagraph( 8 ), 1 )));
     302           4 :     CHECK_FORMULA(
     303             : //        "cos {\xce\xb1} + cos {\xce\xb2} =2 cos {{1} over {2} left (\xce\xb1+\xce\xb2 right )} cos {{1} over {2} left (\xce\xb1-\xce\xb2 right )}",
     304             : // TODO check (cos/sin miss {})
     305             :         "cos \xce\xb1 + cos \xce\xb2 =2 cos {1} over {2} left (\xce\xb1+\xce\xb2 right ) cos {1} over {2} left (\xce\xb1-\xce\xb2 right )",
     306           2 :         getFormula( getRun( getParagraph( 9 ), 1 )));
     307           2 : }
     308             : 
     309          28 : DECLARE_OOXMLEXPORT_TEST(testMathNary, "math-nary.docx")
     310             : {
     311           4 :     CHECK_FORMULA( "lllint from {1} to {2} {x + 1}", getFormula( getRun( getParagraph( 1 ), 1 )));
     312           4 :     CHECK_FORMULA( "prod from {a} {b}", getFormula( getRun( getParagraph( 1 ), 2 )));
     313           4 :     CHECK_FORMULA( "sum to {2} {x}", getFormula( getRun( getParagraph( 1 ), 3 )));
     314           4 : }
     315             : 
     316          28 : DECLARE_OOXMLEXPORT_TEST(testMathOverbraceUnderbrace, "math-overbrace_underbrace.docx")
     317             : {
     318           4 :     CHECK_FORMULA( "{abcd} overbrace {4}", getFormula( getRun( getParagraph( 1 ), 1 )));
     319           4 :     CHECK_FORMULA( "{xyz} underbrace {3}", getFormula( getRun( getParagraph( 2 ), 1 )));
     320           4 : }
     321             : 
     322          28 : DECLARE_OOXMLEXPORT_TEST(testMathOverstrike, "math-overstrike.docx")
     323             : {
     324           4 :     CHECK_FORMULA( "overstrike {abc}", getFormula( getRun( getParagraph( 1 ), 1 )));
     325           4 : }
     326             : 
     327          28 : DECLARE_OOXMLEXPORT_TEST(testMathPlaceholders, "math-placeholders.docx")
     328             : {
     329           4 :     CHECK_FORMULA( "sum from <?> to <?> <?>", getFormula( getRun( getParagraph( 1 ), 1 )));
     330           4 : }
     331             : 
     332          28 : DECLARE_OOXMLEXPORT_TEST(testMathRad, "math-rad.docx")
     333             : {
     334           4 :     CHECK_FORMULA( "sqrt {4}", getFormula( getRun( getParagraph( 1 ), 1 )));
     335           4 :     CHECK_FORMULA( "nroot {3} {x + 1}", getFormula( getRun( getParagraph( 1 ), 2 )));
     336           4 : }
     337             : 
     338          28 : DECLARE_OOXMLEXPORT_TEST(testMathSubscripts, "math-subscripts.docx")
     339             : {
     340           4 :     CHECK_FORMULA( "{x} ^ {y} + {e} ^ {x}", getFormula( getRun( getParagraph( 1 ), 1 )));
     341           4 :     CHECK_FORMULA( "{x} ^ {b}", getFormula( getRun( getParagraph( 1 ), 2 )));
     342           4 :     CHECK_FORMULA( "{x} rsub {b}", getFormula( getRun( getParagraph( 1 ), 3 )));
     343           4 :     CHECK_FORMULA( "{a} rsub {c} rsup {b}", getFormula( getRun( getParagraph( 1 ), 4 )));
     344           4 :     CHECK_FORMULA( "{x} lsub {2} lsup {1}", getFormula( getRun( getParagraph( 1 ), 5 )));
     345           8 :     CHECK_FORMULA( "{{x csup {6} csub {3}} lsub {4} lsup {5}} rsub {2} rsup {1}",
     346           4 :         getFormula( getRun( getParagraph( 1 ), 6 )));
     347           4 : }
     348             : 
     349          28 : DECLARE_OOXMLEXPORT_TEST(testMathVerticalStacks, "math-vertical_stacks.docx")
     350             : {
     351           4 :     CHECK_FORMULA( "{a} over {b}", getFormula( getRun( getParagraph( 1 ), 1 )));
     352           4 :     CHECK_FORMULA( "{a} / {b}", getFormula( getRun( getParagraph( 2 ), 1 )));
     353             : // TODO check these
     354             : //    CHECK_FORMULA( "binom {a} {b}", getFormula( getRun( getParagraph( 3 ), 1 )));
     355             : //    CHECK_FORMULA( "binom {a} {binom {b} {c}}", getFormula( getRun( getParagraph( 4 ), 1 )));
     356           4 : }
     357             : 
     358          26 : DECLARE_OOXMLEXPORT_TEST(testTable, "table.odt")
     359             : {
     360             :     // Validation test: order of elements were wrong.
     361           2 :     xmlDocPtr pXmlDoc = parseExport("word/document.xml");
     362           2 :     if (!pXmlDoc)
     363           2 :         return;
     364             :     // Order was: insideH, end, insideV.
     365           2 :     int nEnd = getXPathPosition(pXmlDoc, "/w:document/w:body/w:tbl/w:tblPr/w:tblBorders", "end");
     366           2 :     int nInsideH = getXPathPosition(pXmlDoc, "/w:document/w:body/w:tbl/w:tblPr/w:tblBorders", "insideH");
     367           2 :     int nInsideV = getXPathPosition(pXmlDoc, "/w:document/w:body/w:tbl/w:tblPr/w:tblBorders", "insideV");
     368           2 :     CPPUNIT_ASSERT(nEnd < nInsideH);
     369           2 :     CPPUNIT_ASSERT(nInsideH < nInsideV);
     370             : 
     371             :     // Make sure we write qFormat for well-known style names.
     372           2 :     assertXPath(parseExport("word/styles.xml"), "//w:style[@w:styleId='Normal']/w:qFormat", 1);
     373             : }
     374             : 
     375          28 : DECLARE_OOXMLEXPORT_TEST(testTablePosition, "table-position.docx")
     376             : {
     377           4 :     sal_Int32 xCoordsFromOffice[] = { 2500, -1000, 0, 0 };
     378           4 :     sal_Int32 cellLeftMarginFromOffice[] = { 250, 100, 0, 0 };
     379             : 
     380           4 :     uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
     381           8 :     uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);
     382           8 :     uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables( ), uno::UNO_QUERY);
     383             : 
     384          20 :     for (int i=0; i<4; i++) {
     385          16 :         uno::Reference<text::XTextTable> xTable1 (xTables->getByIndex(i), uno::UNO_QUERY);
     386             :         // Verify X coord
     387          32 :         uno::Reference<view::XSelectionSupplier> xCtrl(xModel->getCurrentController(), uno::UNO_QUERY);
     388          16 :         xCtrl->select(uno::makeAny(xTable1));
     389          32 :         uno::Reference<text::XTextViewCursorSupplier> xTextViewCursorSupplier(xCtrl, uno::UNO_QUERY);
     390          32 :         uno::Reference<text::XTextViewCursor> xCursor(xTextViewCursorSupplier->getViewCursor(), uno::UNO_QUERY);
     391          16 :         awt::Point pos = xCursor->getPosition();
     392          32 :         CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Incorrect X coord computed from docx",
     393          16 :             xCoordsFromOffice[i], pos.X, 1);
     394             : 
     395             :         // Verify left margin of 1st cell :
     396             :         //  * Office left margins are measured relative to the right of the border
     397             :         //  * LO left spacing is measured from the center of the border
     398          32 :         uno::Reference<table::XCell> xCell = xTable1->getCellByName("A1");
     399          32 :         uno::Reference< beans::XPropertySet > xPropSet(xCell, uno::UNO_QUERY_THROW);
     400          16 :         sal_Int32 aLeftMargin = -1;
     401          16 :         xPropSet->getPropertyValue("LeftBorderDistance") >>= aLeftMargin;
     402          32 :         uno::Any aLeftBorder = xPropSet->getPropertyValue("LeftBorder");
     403          16 :         table::BorderLine2 aLeftBorderLine;
     404          16 :         aLeftBorder >>= aLeftBorderLine;
     405          32 :         CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Incorrect left spacing computed from docx cell margin",
     406          16 :             cellLeftMarginFromOffice[i], aLeftMargin - 0.5 * aLeftBorderLine.LineWidth, 1);
     407          20 :     }
     408           4 : }
     409             : 
     410             : struct SingleLineBorders {
     411             :     sal_Int16 top, bottom, left, right;
     412          96 :     SingleLineBorders(int t=0, int b=0, int l=0, int r=0)
     413          96 :         : top(t), bottom(b), left(l), right(r) {}
     414         192 :     sal_Int16 getBorder(int i) const
     415             :     {
     416         192 :         switch (i) {
     417          48 :             case 0: return top;
     418          48 :             case 1: return bottom;
     419          48 :             case 2: return left;
     420          48 :             case 3: return right;
     421           0 :             default: assert(false); return 0;
     422             :         }
     423             :     }
     424             : };
     425             : 
     426          28 : DECLARE_OOXMLEXPORT_TEST(testTableBorders, "table-borders.docx")
     427             : {
     428           4 :     uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
     429           8 :     uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);
     430           8 :     uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables( ), uno::UNO_QUERY);
     431           4 :     CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount());
     432           8 :     uno::Reference<text::XTextTable> xTextTable (xTables->getByIndex(0), uno::UNO_QUERY);
     433             : 
     434           8 :     std::map<OUString, SingleLineBorders> cellBorders;
     435           4 :     cellBorders[OUString("A1")] = SingleLineBorders(106, 106, 106, 106);
     436           4 :     cellBorders[OUString("B1")] = SingleLineBorders(106, 0, 106, 35);
     437           4 :     cellBorders[OUString("C1")] = SingleLineBorders(106, 106, 35, 106);
     438           4 :     cellBorders[OUString("A2")] = SingleLineBorders(106, 35, 106, 0);
     439           4 :     cellBorders[OUString("B2")] = SingleLineBorders(0, 0, 0, 0);
     440           4 :     cellBorders[OUString("C2")] = SingleLineBorders(106, 106, 0, 106);
     441           4 :     cellBorders[OUString("A3")] = SingleLineBorders(35, 35, 106, 106);
     442           4 :     cellBorders[OUString("B3")] = SingleLineBorders(0, 106, 106, 106);
     443           4 :     cellBorders[OUString("C3")] = SingleLineBorders(106, 106, 106, 106);
     444           4 :     cellBorders[OUString("A4")] = SingleLineBorders(35, 106, 106, 35);
     445           4 :     cellBorders[OUString("B4")] = SingleLineBorders(106, 106, 35, 106);
     446           4 :     cellBorders[OUString("C4")] = SingleLineBorders(106, 106, 106, 106);
     447             : 
     448             :     const OUString borderNames[] = {
     449             :         OUString("TopBorder"),
     450             :         OUString("BottomBorder"),
     451             :         OUString("LeftBorder"),
     452             :         OUString("RightBorder"),
     453           8 :     };
     454             : 
     455           8 :     uno::Sequence<OUString> const cells = xTextTable->getCellNames();
     456           4 :     sal_Int32 nLength = cells.getLength();
     457           4 :     CPPUNIT_ASSERT_EQUAL((sal_Int32)cellBorders.size(), nLength);
     458             : 
     459          52 :     for (sal_Int32 i = 0; i < nLength; ++i)
     460             :     {
     461          48 :         uno::Reference<table::XCell> xCell = xTextTable->getCellByName(cells[i]);
     462          96 :         uno::Reference< beans::XPropertySet > xPropSet(xCell, uno::UNO_QUERY_THROW);
     463          48 :         const SingleLineBorders& borders = cellBorders[cells[i]];
     464             : 
     465         240 :         for (sal_Int32 j = 0; j < 4; ++j)
     466             :         {
     467         192 :             uno::Any aBorder = xPropSet->getPropertyValue(borderNames[j]);
     468         192 :             table::BorderLine aBorderLine;
     469         192 :             if (aBorder >>= aBorderLine)
     470             :             {
     471         192 :                 std::stringstream message;
     472         192 :                 message << cells[i] << "'s " << borderNames[j] << " is incorrect";
     473         384 :                 CPPUNIT_ASSERT_EQUAL_MESSAGE(message.str(),
     474         384 :                         borders.getBorder(j), aBorderLine.OuterLineWidth);
     475             :             }
     476         192 :         }
     477          52 :     }
     478           4 : }
     479             : 
     480          26 : DECLARE_OOXMLEXPORT_TEST(testFdo51550, "fdo51550.odt")
     481             : {
     482             :     // The problem was that we lacked the fallback to export the replacement graphic for OLE objects.
     483           2 :     uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY);
     484           4 :     uno::Reference<container::XIndexAccess> xDraws(xDrawPageSupplier->getDrawPage(), uno::UNO_QUERY);
     485           4 :     CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xDraws->getCount());
     486           2 : }
     487             : 
     488             : /*
     489             :  * doesn't work on openSUSE12.2 at least
     490             : DECLARE_OOXMLEXPORT_TEST(test1Table1Page, "1-table-1-page.docx")
     491             : {
     492             :     // 2 problem for this document after export:
     493             :     //   - invalid sectPr inserted at the beginning of the page
     494             :     //   - font of empty cell is not preserved, leading to change in rows height
     495             :     uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);
     496             :     uno::Reference<text::XTextViewCursorSupplier> xTextViewCursorSupplier(xModel->getCurrentController(), uno::UNO_QUERY);
     497             :     uno::Reference<text::XPageCursor> xCursor(xTextViewCursorSupplier->getViewCursor(), uno::UNO_QUERY);
     498             :     xCursor->jumpToLastPage();
     499             :     CPPUNIT_ASSERT_EQUAL(sal_Int16(1), xCursor->getPage());
     500             : }
     501             : */
     502             : 
     503          26 : DECLARE_OOXMLEXPORT_TEST(testTextFrames, "textframes.odt")
     504             : {
     505             :     // The frames were simply missing, so let's check if all 3 frames were imported back.
     506           2 :     uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY);
     507           4 :     uno::Reference<container::XIndexAccess> xIndexAccess(xDrawPageSupplier->getDrawPage(), uno::UNO_QUERY);
     508           4 :     CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xIndexAccess->getCount());
     509           2 : }
     510             : 
     511          28 : DECLARE_OOXMLEXPORT_TEST(testTextFrameBorders, "textframe-borders.docx")
     512             : {
     513           4 :     uno::Reference<text::XTextFramesSupplier> xTextFramesSupplier(mxComponent, uno::UNO_QUERY);
     514           8 :     uno::Reference<container::XIndexAccess> xIndexAccess(xTextFramesSupplier->getTextFrames(), uno::UNO_QUERY);
     515           4 :     if (xIndexAccess->getCount())
     516             :     {
     517             :         // After import, a TextFrame is created by the VML import.
     518           2 :         uno::Reference<beans::XPropertySet> xFrame(xIndexAccess->getByIndex(0), uno::UNO_QUERY);
     519           2 :         CPPUNIT_ASSERT_EQUAL(sal_Int32(0xD99594), getProperty<sal_Int32>(xFrame, "BackColor"));
     520             : 
     521           2 :         table::BorderLine2 aBorder = getProperty<table::BorderLine2>(xFrame, "TopBorder");
     522           2 :         CPPUNIT_ASSERT_EQUAL(sal_Int32(0xC0504D), aBorder.Color);
     523           2 :         CPPUNIT_ASSERT_EQUAL(sal_uInt32(35), aBorder.LineWidth);
     524             : 
     525           2 :         table::ShadowFormat aShadowFormat = getProperty<table::ShadowFormat>(xFrame, "ShadowFormat");
     526           2 :         CPPUNIT_ASSERT_EQUAL(table::ShadowLocation_BOTTOM_RIGHT, aShadowFormat.Location);
     527           2 :         CPPUNIT_ASSERT_EQUAL(sal_Int16(48), aShadowFormat.ShadowWidth);
     528           2 :         CPPUNIT_ASSERT_EQUAL(sal_Int32(0x622423), aShadowFormat.Color);
     529             :     }
     530             :     else
     531             :     {
     532             :         // After export and import, the result is a shape.
     533           2 :         uno::Reference<beans::XPropertySet> xShape(getShape(1), uno::UNO_QUERY);
     534           2 :         CPPUNIT_ASSERT_EQUAL(sal_Int32(0xD99594), getProperty<sal_Int32>(xShape, "FillColor"));
     535             : 
     536           2 :         CPPUNIT_ASSERT_EQUAL(sal_Int32(0xC0504D), getProperty<sal_Int32>(xShape, "LineColor"));
     537           2 :         CPPUNIT_ASSERT_EQUAL(sal_Int32(35), getProperty<sal_Int32>(xShape, "LineWidth"));
     538             : 
     539           2 :         CPPUNIT_ASSERT_EQUAL(sal_Int32(48), getProperty<sal_Int32>(xShape, "ShadowXDistance"));
     540           2 :         CPPUNIT_ASSERT_EQUAL(sal_Int32(48), getProperty<sal_Int32>(xShape, "ShadowYDistance"));
     541           2 :         CPPUNIT_ASSERT_EQUAL(sal_Int32(0x622423), getProperty<sal_Int32>(xShape, "ShadowColor"));
     542           4 :     }
     543           4 : }
     544             : 
     545          28 : DECLARE_OOXMLEXPORT_TEST(testTextframeGradient, "textframe-gradient.docx")
     546             : {
     547           4 :     uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY);
     548           8 :     uno::Reference<container::XIndexAccess> xIndexAccess(xDrawPageSupplier->getDrawPage(), uno::UNO_QUERY);
     549           4 :     CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xIndexAccess->getCount());
     550             : 
     551           8 :     uno::Reference<beans::XPropertySet> xFrame(xIndexAccess->getByIndex(0), uno::UNO_QUERY);
     552           4 :     CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_GRADIENT, getProperty<drawing::FillStyle>(xFrame, "FillStyle"));
     553           4 :     awt::Gradient aGradient = getProperty<awt::Gradient>(xFrame, "FillGradient");
     554           4 :     CPPUNIT_ASSERT_EQUAL(sal_Int32(0xC0504D), aGradient.StartColor);
     555           4 :     CPPUNIT_ASSERT_EQUAL(sal_Int32(0xD99594), aGradient.EndColor);
     556           4 :     CPPUNIT_ASSERT_EQUAL(awt::GradientStyle_AXIAL, aGradient.Style);
     557             : 
     558           4 :     xFrame.set(xIndexAccess->getByIndex(1), uno::UNO_QUERY);
     559           4 :     CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_GRADIENT, getProperty<drawing::FillStyle>(xFrame, "FillStyle"));
     560           4 :     aGradient = getProperty<awt::Gradient>(xFrame, "FillGradient");
     561           4 :     CPPUNIT_ASSERT_EQUAL(sal_Int32(0x000000), aGradient.StartColor);
     562           4 :     CPPUNIT_ASSERT_EQUAL(sal_Int32(0x666666), aGradient.EndColor);
     563           4 :     CPPUNIT_ASSERT_EQUAL(awt::GradientStyle_AXIAL, aGradient.Style);
     564             : 
     565             :     // Left / right margin was incorrect: the attribute was missing and we
     566             :     // didn't have the right default (had 0 instead of the below one).
     567           4 :     CPPUNIT_ASSERT_EQUAL(sal_Int32(318), getProperty<sal_Int32>(xFrame, "LeftMargin"));
     568           8 :     CPPUNIT_ASSERT_EQUAL(sal_Int32(318), getProperty<sal_Int32>(xFrame, "RightMargin"));
     569           4 : }
     570             : 
     571          28 : DECLARE_OOXMLEXPORT_TEST(testCellBtlr, "cell-btlr.docx")
     572             : {
     573             :     /*
     574             :      * The problem was that the exporter didn't mirror the workaround of the
     575             :      * importer, regarding the btLr text direction: the <w:textDirection
     576             :      * w:val="btLr"/> token was completely missing in the output.
     577             :      */
     578             : 
     579           4 :     xmlDocPtr pXmlDoc = parseExport();
     580           4 :     if (!pXmlDoc)
     581           6 :         return;
     582           2 :     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr/w:tc/w:tcPr/w:textDirection", "val", "btLr");
     583             : }
     584             : 
     585          28 : DECLARE_OOXMLEXPORT_TEST(testTableStylerPrSz, "table-style-rPr-sz.docx")
     586             : {
     587             :     // Verify that font size inside the table is 20pt, despite the sz attribute in the table size.
     588             :     // Also check that other rPr attribute are used: italic, bold, underline
     589             :     // Office has the same behavior
     590           4 :     uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
     591           8 :     uno::Reference<container::XIndexAccess> xTables(xTextTablesSupplier->getTextTables(), uno::UNO_QUERY);
     592           8 :     uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY);
     593           8 :     uno::Reference<text::XTextRange> xCell(xTable->getCellByName("A1"), uno::UNO_QUERY);
     594           8 :     uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xCell->getText(), uno::UNO_QUERY);
     595           8 :     uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
     596           8 :     uno::Reference<text::XTextRange> xPara(xParaEnum->nextElement(), uno::UNO_QUERY);
     597             : 
     598           8 :     CPPUNIT_ASSERT_EQUAL(20.f, getProperty<float>(getRun(xPara, 1), "CharHeight"));
     599             : //    CPPUNIT_ASSERT_EQUAL(awt::FontUnderline::SINGLE, getProperty<short>(getRun(xPara, 1), "CharUnderline"));
     600             : //    CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD, getProperty<float>(getRun(xPara, 1), "CharWeight"));
     601             : //    CPPUNIT_ASSERT_EQUAL(awt::FontSlant_ITALIC, getProperty<awt::FontSlant>(getRun(xPara, 1), "CharPosture"));
     602           4 : }
     603             : 
     604          28 : DECLARE_OOXMLEXPORT_TEST(testMathLiteral, "math-literal.docx")
     605             : {
     606           8 :     CHECK_FORMULA( "iiint from {V} to <?> {\"div\" \"F\"}  dV= llint from {S} to <?> {\"F\" \xe2\x88\x99 \"n \" dS}",
     607           4 :         getFormula( getRun( getParagraph( 1 ), 1 )));
     608           4 : }
     609             : 
     610          26 : DECLARE_OOXMLEXPORT_TEST(testFdo48557, "fdo48557.odt")
     611             : {
     612             :     // Inner margins of the textframe wasn't exported.
     613           2 :     uno::Reference<text::XTextFramesSupplier> xTextFramesSupplier(mxComponent, uno::UNO_QUERY);
     614           4 :     uno::Reference<container::XIndexAccess> xIndexAccess(xTextFramesSupplier->getTextFrames(), uno::UNO_QUERY);
     615           4 :     uno::Reference<beans::XPropertySet> xFrame(getShape(1), uno::UNO_QUERY);
     616           2 :     CPPUNIT_ASSERT_EQUAL(sal_Int32(150), getProperty<sal_Int32>(xFrame, "TextLeftDistance"));
     617           2 :     CPPUNIT_ASSERT_EQUAL(sal_Int32(150), getProperty<sal_Int32>(xFrame, "TextRightDistance"));
     618           2 :     CPPUNIT_ASSERT_EQUAL(sal_Int32(150), getProperty<sal_Int32>(xFrame, "TextUpperDistance"));
     619           4 :     CPPUNIT_ASSERT_EQUAL(sal_Int32(150), getProperty<sal_Int32>(xFrame, "TextLowerDistance"));
     620           2 : }
     621             : 
     622          28 : DECLARE_OOXMLEXPORT_TEST(testI120928, "i120928.docx")
     623             : {
     624             :     // w:numPicBullet was ignored, leading to missing graphic bullet in numbering.
     625           4 :     uno::Reference<beans::XPropertySet> xPropertySet(getStyles("NumberingStyles")->getByName("WWNum1"), uno::UNO_QUERY);
     626           8 :     uno::Reference<container::XIndexAccess> xLevels(xPropertySet->getPropertyValue("NumberingRules"), uno::UNO_QUERY);
     627           8 :     uno::Sequence<beans::PropertyValue> aProps;
     628           4 :     xLevels->getByIndex(0) >>= aProps; // 1st level
     629             : 
     630           4 :     bool bIsGraphic = false;
     631          64 :     for (int i = 0; i < aProps.getLength(); ++i)
     632             :     {
     633          60 :         const beans::PropertyValue& rProp = aProps[i];
     634             : 
     635          60 :         if (rProp.Name == "NumberingType")
     636           4 :             CPPUNIT_ASSERT_EQUAL(style::NumberingType::BITMAP, rProp.Value.get<sal_Int16>());
     637          56 :         else if (rProp.Name == "GraphicURL")
     638           4 :             bIsGraphic = true;
     639             :     }
     640           8 :     CPPUNIT_ASSERT_EQUAL(true, bIsGraphic);
     641           4 : }
     642             : 
     643          28 : DECLARE_OOXMLEXPORT_TEST(testFdo64826, "fdo64826.docx")
     644             : {
     645             :     // 'Track-Changes' (Track Revisions) wasn't exported.
     646           4 :     CPPUNIT_ASSERT_EQUAL(true, bool(getProperty<sal_Bool>(mxComponent, "RecordChanges")));
     647           4 : }
     648             : 
     649          28 : DECLARE_OOXMLEXPORT_TEST(testPageBackground, "page-background.docx")
     650             : {
     651             :     // 'Document Background' wasn't exported.
     652           4 :     uno::Reference<beans::XPropertySet> xPageStyle(getStyles("PageStyles")->getByName(DEFAULT_STYLE), uno::UNO_QUERY);
     653           4 :     CPPUNIT_ASSERT_EQUAL(sal_Int32(0x92D050), getProperty<sal_Int32>(xPageStyle, "BackColor"));
     654           4 : }
     655             : 
     656          28 : DECLARE_OOXMLEXPORT_TEST(testFdo65265, "fdo65265.docx")
     657             : {
     658             :     // Redline (tracked changes) of text formatting were not exported
     659           4 :     uno::Reference<text::XTextRange> xParagraph1 = getParagraph(1);
     660           8 :     uno::Reference<text::XTextRange> xParagraph2 = getParagraph(2);
     661             : 
     662           4 :     CPPUNIT_ASSERT_EQUAL(OUString("Format"), getProperty<OUString>(getRun(xParagraph1, 3), "RedlineType"));
     663           8 :     CPPUNIT_ASSERT_EQUAL(OUString("Format"), getProperty<OUString>(getRun(xParagraph2, 2), "RedlineType"));
     664           4 : }
     665             : 
     666          28 : DECLARE_OOXMLEXPORT_TEST(testFdo65655, "fdo65655.docx")
     667             : {
     668             :     // The problem was that the DOCX had a non-blank odd footer and a blank even footer
     669             :     // The 'Different Odd & Even Pages' was turned on
     670             :     // However - LO assumed that because the 'even' footer is blank - it should ignore the 'Different Odd & Even Pages' flag
     671             :     // So it did not import it and did not export it
     672           4 :     uno::Reference<beans::XPropertySet> xPropertySet(getStyles("PageStyles")->getByName(DEFAULT_STYLE), uno::UNO_QUERY);
     673           4 :     bool bValue = false;
     674           4 :     xPropertySet->getPropertyValue("HeaderIsShared") >>= bValue;
     675           4 :     CPPUNIT_ASSERT_EQUAL(false, bool(bValue));
     676           4 :     xPropertySet->getPropertyValue("FooterIsShared") >>= bValue;
     677           4 :     CPPUNIT_ASSERT_EQUAL(false, bool(bValue));
     678           4 : }
     679             : 
     680          28 : DECLARE_OOXMLEXPORT_TEST(testFDO63053, "fdo63053.docx")
     681             : {
     682           4 :     uno::Reference<document::XDocumentPropertiesSupplier> xDocumentPropertiesSupplier(mxComponent, uno::UNO_QUERY);
     683           8 :     uno::Reference<document::XDocumentProperties> xDocumentProperties = xDocumentPropertiesSupplier->getDocumentProperties();
     684           4 :     CPPUNIT_ASSERT_EQUAL(OUString("test1&test2"), xDocumentProperties->getTitle());
     685           8 :     CPPUNIT_ASSERT_EQUAL(OUString("test1&test2"), xDocumentProperties->getSubject());
     686           4 : }
     687             : 
     688          28 : DECLARE_OOXMLEXPORT_TEST(testWatermark, "watermark.docx")
     689             : {
     690           4 :     uno::Reference<text::XTextRange> xShape(getShape(1), uno::UNO_QUERY);
     691             :     // 1st problem: last character was missing
     692           4 :     CPPUNIT_ASSERT_EQUAL(OUString("SAMPLE"), xShape->getString());
     693             : 
     694           8 :     uno::Reference<beans::XPropertySet> xPropertySet(xShape, uno::UNO_QUERY);
     695           8 :     uno::Sequence<beans::PropertyValue> aProps = getProperty< uno::Sequence<beans::PropertyValue> >(xShape, "CustomShapeGeometry");
     696           4 :     bool bFound = false;
     697          32 :     for (int i = 0; i < aProps.getLength(); ++i)
     698          28 :         if (aProps[i].Name == "TextPath")
     699           4 :             bFound = true;
     700             :     // 2nd problem: v:textpath wasn't imported
     701           4 :     CPPUNIT_ASSERT_EQUAL(true, bFound);
     702             : 
     703             :     // 3rd problem: rotation angle was 315, not 45.
     704           4 :     CPPUNIT_ASSERT_EQUAL(sal_Int32(45 * 100), getProperty<sal_Int32>(xShape, "RotateAngle"));
     705             : 
     706             :     // 4th problem: mso-position-vertical-relative:margin was ignored, VertOrientRelation was text::RelOrientation::FRAME.
     707           4 :     CPPUNIT_ASSERT_EQUAL(text::RelOrientation::PAGE_PRINT_AREA, getProperty<sal_Int16>(xShape, "VertOrientRelation"));
     708             : 
     709             :     // These problems were in the exporter
     710             :     // The textpath wasn't semi-transparent.
     711           4 :     CPPUNIT_ASSERT_EQUAL(sal_Int16(50), getProperty<sal_Int16>(xShape, "FillTransparence"));
     712             :     // The textpath had a stroke.
     713           8 :     CPPUNIT_ASSERT_EQUAL(drawing::LineStyle_NONE, getProperty<drawing::LineStyle>(xShape, "LineStyle"));
     714           4 : }
     715             : 
     716          28 : DECLARE_OOXMLEXPORT_TEST(testFdo43093, "fdo43093.docx")
     717             : {
     718             :     // The problem was that the alignment are not exchange when the paragraph are RTL.
     719           4 :     uno::Reference<uno::XInterface> xParaRtlLeft(getParagraph( 1, "RTL Left"));
     720           4 :     sal_Int32 nRtlLeft = getProperty< sal_Int32 >( xParaRtlLeft, "ParaAdjust" );
     721             :     // test the text Direction value for the pragraph
     722           4 :     sal_Int16 nRLDir  = getProperty< sal_Int32 >( xParaRtlLeft, "WritingMode" );
     723             : 
     724           8 :     uno::Reference<uno::XInterface> xParaRtlRight(getParagraph( 3, "RTL Right"));
     725           4 :     sal_Int32 nRtlRight = getProperty< sal_Int32 >( xParaRtlRight, "ParaAdjust" );
     726           4 :     sal_Int16 nRRDir  = getProperty< sal_Int32 >( xParaRtlRight, "WritingMode" );
     727             : 
     728           8 :     uno::Reference<uno::XInterface> xParaLtrLeft(getParagraph( 5, "LTR Left"));
     729           4 :     sal_Int32 nLtrLeft = getProperty< sal_Int32 >( xParaLtrLeft, "ParaAdjust" );
     730           4 :     sal_Int16 nLLDir  = getProperty< sal_Int32 >( xParaLtrLeft, "WritingMode" );
     731             : 
     732           8 :     uno::Reference<uno::XInterface> xParaLtrRight(getParagraph( 7, "LTR Right"));
     733           4 :     sal_Int32 nLtrRight = getProperty< sal_Int32 >( xParaLtrRight, "ParaAdjust" );
     734           4 :     sal_Int16 nLRDir  = getProperty< sal_Int32 >( xParaLtrRight, "WritingMode" );
     735             : 
     736             :     // this will test the both the text direction and alignment for each paragraph
     737           4 :     CPPUNIT_ASSERT_EQUAL( sal_Int32 (style::ParagraphAdjust_LEFT), nRtlLeft);
     738           4 :     CPPUNIT_ASSERT_EQUAL(text::WritingMode2::RL_TB, nRLDir);
     739             : 
     740           4 :     CPPUNIT_ASSERT_EQUAL( sal_Int32 (style::ParagraphAdjust_RIGHT), nRtlRight);
     741           4 :     CPPUNIT_ASSERT_EQUAL(text::WritingMode2::RL_TB, nRRDir);
     742             : 
     743           4 :     CPPUNIT_ASSERT_EQUAL( sal_Int32 (style::ParagraphAdjust_LEFT), nLtrLeft);
     744           4 :     CPPUNIT_ASSERT_EQUAL(text::WritingMode2::LR_TB, nLLDir);
     745             : 
     746           4 :     CPPUNIT_ASSERT_EQUAL( sal_Int32 (style::ParagraphAdjust_RIGHT), nLtrRight);
     747           8 :     CPPUNIT_ASSERT_EQUAL(text::WritingMode2::LR_TB, nLRDir);
     748           4 : }
     749             : 
     750          28 : DECLARE_OOXMLEXPORT_TEST(testFdo64238_a, "fdo64238_a.docx")
     751             : {
     752             :     // The problem was that when 'Show Only Odd Footer' was marked in Word and the Even footer *was filled*
     753             :     // then LO would still import the Even footer and concatenate it to to the odd footer.
     754             :     // This case specifically is for :
     755             :     // 'Blank Odd Footer' with 'Non-Blank Even Footer' when 'Show Only Odd Footer' is marked in Word
     756             :     // In this case the imported footer in LO was supposed to be blank, but instead was the 'even' footer
     757           4 :     uno::Reference<text::XText> xFooterText = getProperty< uno::Reference<text::XText> >(getStyles("PageStyles")->getByName(DEFAULT_STYLE), "FooterText");
     758           8 :     uno::Reference< text::XTextRange > xFooterParagraph = getParagraphOfText( 1, xFooterText );
     759           8 :     uno::Reference<container::XEnumerationAccess> xRunEnumAccess(xFooterParagraph, uno::UNO_QUERY);
     760           8 :     uno::Reference<container::XEnumeration> xRunEnum = xRunEnumAccess->createEnumeration();
     761           4 :     sal_Int32 numOfRuns = 0;
     762          16 :     while (xRunEnum->hasMoreElements())
     763             :     {
     764           8 :         uno::Reference<text::XTextRange> xRun(xRunEnum->nextElement(), uno::UNO_QUERY);
     765           8 :         numOfRuns++;
     766           8 :     }
     767           8 :     CPPUNIT_ASSERT_EQUAL(sal_Int32(2), numOfRuns);
     768           4 : }
     769             : 
     770          28 : DECLARE_OOXMLEXPORT_TEST(testFdo64238_b, "fdo64238_b.docx")
     771             : {
     772             :     // The problem was that when 'Show Only Odd Footer' was marked in Word and the Even footer *was filled*
     773             :     // then LO would still import the Even footer and concatenate it to to the odd footer.
     774             :     // This case specifically is for :
     775             :     // 'Non-Blank Odd Footer' with 'Non-Blank Even Footer' when 'Show Only Odd Footer' is marked in Word
     776             :     // In this case the imported footer in LO was supposed to be just the odd footer, but instead was the 'odd' and 'even' footers concatenated
     777           4 :     uno::Reference<text::XText> xFooterText = getProperty< uno::Reference<text::XText> >(getStyles("PageStyles")->getByName(DEFAULT_STYLE), "FooterText");
     778           8 :     uno::Reference< text::XTextRange > xFooterParagraph = getParagraphOfText( 1, xFooterText );
     779           8 :     uno::Reference<container::XEnumerationAccess> xRunEnumAccess(xFooterParagraph, uno::UNO_QUERY);
     780           8 :     uno::Reference<container::XEnumeration> xRunEnum = xRunEnumAccess->createEnumeration();
     781           4 :     sal_Int32 numOfRuns = 0;
     782          28 :     while (xRunEnum->hasMoreElements())
     783             :     {
     784          20 :         uno::Reference<text::XTextRange> xRun(xRunEnum->nextElement(), uno::UNO_QUERY);
     785          20 :         numOfRuns++;
     786          20 :     }
     787           8 :     CPPUNIT_ASSERT_EQUAL(sal_Int32(5), numOfRuns);
     788           4 : }
     789             : 
     790          28 : DECLARE_OOXMLEXPORT_TEST(testFdo56679, "fdo56679.docx")
     791             : {
     792             :     // The problem was that the DOCX importer and exporter did not handle the 'color' of an underline
     793             :     // (not the color of the text, the color of the underline itself)
     794           4 :     uno::Reference< text::XTextRange > xParagraph = getParagraph( 1 );
     795           8 :     uno::Reference< text::XTextRange > xText = getRun( xParagraph, 2, "This is a simple sentence.");
     796             : 
     797           4 :     CPPUNIT_ASSERT_EQUAL(true, bool(getProperty<sal_Bool>(xText, "CharUnderlineHasColor")));
     798           8 :     CPPUNIT_ASSERT_EQUAL(sal_Int32(0xFF0000), getProperty<sal_Int32>(xText, "CharUnderlineColor"));
     799           4 : }
     800             : 
     801          28 : DECLARE_OOXMLEXPORT_TEST(testFdo65400, "fdo65400.docx")
     802             : {
     803             :     // The problem was that if in Word you choose 'Character Shading' - then the text portion
     804             :     // is marked with 'w:shd val=pct15'. LO did not store this value and so when importing and exporting
     805             :     // this value was lost (and so Word did not show 'Character Shading' was on)
     806           4 :     uno::Reference< text::XTextRange > paragraph1 = getParagraph( 1 );
     807           8 :     uno::Reference< text::XTextRange > shaded = getRun( paragraph1, 2, "normal" );
     808           4 :     CPPUNIT_ASSERT_EQUAL( sal_Int32( 0x0026 ), getProperty< sal_Int32 >( shaded, "CharShadingValue" ));
     809           8 :     CPPUNIT_ASSERT_EQUAL( sal_Int32( 0xd8d8d8 ), getProperty< sal_Int32 >( shaded, "CharBackColor" ));
     810           4 : }
     811             : 
     812          28 : DECLARE_OOXMLEXPORT_TEST(testFdo66543, "fdo66543.docx")
     813             : {
     814             :     // The problem was that when importing DOCX with 'line numbers' - the 'start value' was imported
     815             :     // but nothing was done with it.
     816             : 
     817           4 :     uno::Reference< text::XTextRange > paragraph1 = getParagraph( 1 );
     818           4 :     CPPUNIT_ASSERT_EQUAL( sal_Int32( 1 ), getProperty< sal_Int32 >( paragraph1, "ParaLineNumberStartValue" ));
     819           4 : }
     820             : 
     821          26 : DECLARE_OOXMLEXPORT_TEST(testN822175, "n822175.odt")
     822             : {
     823           2 :     uno::Reference<beans::XPropertySet> xFrame(getShape(1), uno::UNO_QUERY);
     824             :     // Was text::WrapTextMode_THROUGH, due to missing Surround handling in the exporter.
     825           2 :     CPPUNIT_ASSERT_EQUAL(text::WrapTextMode_PARALLEL, getProperty<text::WrapTextMode>(xFrame, "Surround"));
     826           2 : }
     827             : 
     828          28 : DECLARE_OOXMLEXPORT_TEST(testFdo66688, "fdo66688.docx")
     829             : {
     830             :     // The problem was that TextFrame imported and exported the wrong value for transparency
     831             :     // (was stored as 'FillTransparence' instead of 'BackColorTransparency'
     832           4 :     uno::Reference<beans::XPropertySet> xFrame(getShape(2), uno::UNO_QUERY);
     833           4 :     CPPUNIT_ASSERT_EQUAL( sal_Int32( 80 ), getProperty< sal_Int32 >( xFrame, "FillTransparence" ) );
     834           4 : }
     835             : 
     836          28 : DECLARE_OOXMLEXPORT_TEST(testFdo66773, "fdo66773.docx")
     837             : {
     838             :     // The problem was the line spacing was interpreted by Word as 'Multiple 1.08' if no default settings were written.
     839             :     // Now after the 'docDefaults' section is written in <styles.xml> - there is no more problem.
     840             :     // (Word does not try to calculate some arbitrary value for line spacing).
     841           4 :     uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
     842           8 :     uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xTextDocument->getText(), uno::UNO_QUERY);
     843           8 :     uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
     844           4 :     CPPUNIT_ASSERT(xParaEnum->hasMoreElements());
     845             : 
     846           4 :     style::LineSpacing alineSpacing = getProperty<style::LineSpacing>(xParaEnum->nextElement(), "ParaLineSpacing");
     847           4 :     CPPUNIT_ASSERT_EQUAL(style::LineSpacingMode::PROP, alineSpacing.Mode);
     848           8 :     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(100), static_cast<sal_Int32>(alineSpacing.Height));
     849           4 : }
     850             : 
     851          26 : DECLARE_OOXMLEXPORT_TEST(testFdo58577, "fdo58577.odt")
     852             : {
     853             :     // The second frame was simply missing, so let's check if both frames were imported back.
     854           2 :     uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY);
     855           4 :     uno::Reference<container::XIndexAccess> xIndexAccess(xDrawPageSupplier->getDrawPage(), uno::UNO_QUERY);
     856           4 :     CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xIndexAccess->getCount());
     857           2 : }
     858             : 
     859          26 : DECLARE_OOXMLEXPORT_TEST(testBnc581614, "bnc581614.doc")
     860             : {
     861           2 :     uno::Reference<beans::XPropertySet> xFrame(getShape(1), uno::UNO_QUERY);
     862           2 :     CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_NONE, getProperty<drawing::FillStyle>(xFrame, "FillStyle"));
     863           2 : }
     864             : 
     865          28 : DECLARE_OOXMLEXPORT_TEST(testFdo66929, "fdo66929.docx")
     866             : {
     867             :     // The problem was that the default 'inset' attribute of the 'textbox' node was exported incorrectly.
     868             :     // A node like '<v:textbox inset="0">' was exported back as '<v:textbox inset="0pt,0pt,0pt,0pt">'
     869             :     // This is wrong because the original node denotes a specific 'left' inset, and a default 'top','right','bottom' inset
     870           4 :     uno::Reference<text::XTextFramesSupplier> xTextFramesSupplier(mxComponent, uno::UNO_QUERY);
     871           8 :     uno::Reference<container::XIndexAccess> xIndexAccess(xTextFramesSupplier->getTextFrames(), uno::UNO_QUERY);
     872           4 :     if (xIndexAccess->getCount())
     873             :     {
     874             :         // VML import -> TextFrame
     875           0 :         uno::Reference<beans::XPropertySet> xFrame(xIndexAccess->getByIndex(0), uno::UNO_QUERY);
     876           0 :         CPPUNIT_ASSERT_EQUAL( sal_Int32( 0 )  , getProperty< sal_Int32 >( xFrame, "LeftBorderDistance" ) );
     877           0 :         CPPUNIT_ASSERT_EQUAL( sal_Int32( 127 ), getProperty< sal_Int32 >( xFrame, "TopBorderDistance" ) );
     878           0 :         CPPUNIT_ASSERT_EQUAL( sal_Int32( 254 ), getProperty< sal_Int32 >( xFrame, "RightBorderDistance" ) );
     879           0 :         CPPUNIT_ASSERT_EQUAL( sal_Int32( 127 ), getProperty< sal_Int32 >( xFrame, "BottomBorderDistance" ) );
     880             :     }
     881             :     else
     882             :     {
     883             :         // drawingML import -> shape with TextBox
     884           4 :         uno::Reference<beans::XPropertySet> xShape(getShape(1), uno::UNO_QUERY);
     885           4 :         CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xShape, "TextLeftDistance"));
     886           4 :         CPPUNIT_ASSERT_EQUAL(sal_Int32(127), getProperty<sal_Int32>(xShape, "TextUpperDistance"));
     887           4 :         CPPUNIT_ASSERT_EQUAL(sal_Int32(254), getProperty<sal_Int32>(xShape, "TextRightDistance"));
     888           4 :         CPPUNIT_ASSERT_EQUAL(sal_Int32(127), getProperty<sal_Int32>(xShape, "TextLowerDistance"));
     889           4 :     }
     890           4 : }
     891             : 
     892          28 : DECLARE_OOXMLEXPORT_TEST(testPageBorderSpacingExportCase2, "page-borders-export-case-2.docx")
     893             : {
     894             :     // The problem was that the exporter didn't mirror the workaround of the
     895             :     // importer, regarding the page border's spacing : the <w:pgBorders w:offsetFrom="page">
     896             :     // and the inner nodes like <w:top w:space="24" .... />
     897             :     //
     898             :     // The exporter ALWAYS exported 'w:offsetFrom="text"' even when the spacing values where too large
     899             :     // for Word to handle (larger than 31 points)
     900             : 
     901           4 :     xmlDocPtr pXmlDoc = parseExport();
     902           4 :     if (!pXmlDoc)
     903           6 :         return;
     904             : 
     905             :     // Assert the XPath expression - page borders
     906           2 :     assertXPath(pXmlDoc, "/w:document/w:body/w:sectPr/w:pgBorders", "offsetFrom", "page");
     907             : 
     908             :     // Assert the XPath expression - 'left' border
     909           2 :     assertXPath(pXmlDoc, "/w:document/w:body/w:sectPr/w:pgBorders/w:left", "space", "24");
     910             : 
     911             :     // Assert the XPath expression - 'right' border
     912           2 :     assertXPath(pXmlDoc, "/w:document/w:body/w:sectPr/w:pgBorders/w:right", "space", "24");
     913             : }
     914             : 
     915          28 : DECLARE_OOXMLEXPORT_TEST(testFdo66145, "fdo66145.docx")
     916             : {
     917             :     // The Writer ignored the 'First Is Shared' flag
     918           8 :     CPPUNIT_ASSERT_EQUAL(OUString("This is the FIRST page header."),
     919           4 :         parseDump("/root/page[1]/header/txt/text()"));
     920           8 :     CPPUNIT_ASSERT_EQUAL(
     921             :         OUString("This is the header for the REST OF THE FILE."),
     922           4 :         parseDump("/root/page[2]/header/txt/text()"));
     923           8 :     CPPUNIT_ASSERT_EQUAL(
     924             :         OUString("This is the header for the REST OF THE FILE."),
     925           4 :         parseDump("/root/page[3]/header/txt/text()"));
     926           4 : }
     927             : 
     928          28 : DECLARE_OOXMLEXPORT_TEST(testGrabBag, "grabbag.docx")
     929             : {
     930             :     // w:mirrorIndents was lost on roundtrip, now should be handled as a grab bag property
     931           4 :     xmlDocPtr pXmlDoc = parseExport();
     932           4 :     if (!pXmlDoc)
     933           6 :         return;
     934           2 :     assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:pPr/w:mirrorIndents");
     935             : }
     936             : 
     937          28 : DECLARE_OOXMLEXPORT_TEST(testFdo66781, "fdo66781.docx")
     938             : {
     939             :     // The problem was that bullets with level=0 were shown in LO as normal bullets,
     940             :     // and when saved back to DOCX were saved with level=1 (so hidden bullets became visible)
     941           4 :     uno::Reference<beans::XPropertySet> xPropertySet(getStyles("NumberingStyles")->getByName("WWNum1"), uno::UNO_QUERY);
     942           4 :     uno::Reference<container::XIndexAccess> xLevels(xPropertySet->getPropertyValue("NumberingRules"), uno::UNO_QUERY);
     943           4 :     uno::Sequence<beans::PropertyValue> aProps;
     944           4 :     xLevels->getByIndex(0) >>= aProps; // 1st level
     945             : 
     946          56 :     for (int i = 0; i < aProps.getLength(); ++i)
     947             :     {
     948          56 :         const beans::PropertyValue& rProp = aProps[i];
     949          56 :         if (rProp.Name == "BulletChar")
     950             :         {
     951           4 :             CPPUNIT_ASSERT_EQUAL(OUString("\x0", 1, RTL_TEXTENCODING_UTF8), rProp.Value.get<OUString>());
     952           8 :             return;
     953             :         }
     954             :     }
     955             : 
     956             :     // Shouldn't reach here
     957           0 :     CPPUNIT_FAIL("Did not find bullet with level 0");
     958             : }
     959             : 
     960          26 : DECLARE_OOXMLEXPORT_TEST(testFdo60990, "fdo60990.odt")
     961             : {
     962             :     // The shape had no background, no paragraph adjust and no font color.
     963           2 :     uno::Reference<beans::XPropertySet> xShape(getShape(1), uno::UNO_QUERY);
     964           2 :     CPPUNIT_ASSERT_EQUAL(sal_Int32(0x00CFE7F5), getProperty<sal_Int32>(xShape, "FillColor"));
     965           4 :     uno::Reference<text::XText> xText = uno::Reference<text::XTextRange>(xShape, uno::UNO_QUERY)->getText();
     966           4 :     uno::Reference<text::XTextRange> xParagraph = getParagraphOfText(1, xText);
     967           2 :     CPPUNIT_ASSERT_EQUAL(style::ParagraphAdjust_CENTER, static_cast<style::ParagraphAdjust>(getProperty<sal_Int16>(xParagraph, "ParaAdjust")));
     968           4 :     CPPUNIT_ASSERT_EQUAL(sal_Int32(0x00FF00), getProperty<sal_Int32>(getRun(xParagraph, 1), "CharColor"));
     969           2 : }
     970             : 
     971          28 : DECLARE_OOXMLEXPORT_TEST(testFdo65718, "fdo65718.docx")
     972             : {
     973             :     // The problem was that the exporter always exported values of "0" for an images distance from text.
     974             :     // the actual attributes where 'distT', 'distB', 'distL', 'distR'
     975           4 :     uno::Reference<beans::XPropertySet> xPropertySet(getShape(1), uno::UNO_QUERY);
     976             : 
     977           4 :     CPPUNIT_ASSERT_EQUAL(sal_Int32( EMU_TO_MM100(0) ), getProperty<sal_Int32>(xPropertySet, "TopMargin") );
     978           4 :     CPPUNIT_ASSERT_EQUAL(sal_Int32( EMU_TO_MM100(0) ), getProperty<sal_Int32>(xPropertySet, "BottomMargin") );
     979             : 
     980             :     // Going to do '+1' because the 'getProperty' return 318 (instead of 317.5)
     981             :     // I think this is because it returns an integer, instead of a float.
     982             :     // The actual exporting to DOCX exports the correct value (114300 = 317.5 * 360)
     983             :     // The exporting to DOCX uses the 'SvxLRSpacing' that stores the value in TWIPS (180 TWIPS)
     984             :     // However, the 'LeftMargin' property is an integer property that holds that value in 'MM100' (should hold 317.5, but it is 318)
     985             :     // So I had to add the hack of the '+1' to make the test-case pass
     986           4 :     CPPUNIT_ASSERT_EQUAL(sal_Int32( EMU_TO_MM100(114300) + 1 ), getProperty<sal_Int32>(xPropertySet, "LeftMargin") );
     987           4 :     CPPUNIT_ASSERT_EQUAL(sal_Int32( EMU_TO_MM100(114300) + 1), getProperty<sal_Int32>(xPropertySet, "RightMargin") );
     988           4 : }
     989             : 
     990          28 : DECLARE_OOXMLEXPORT_TEST(testFdo64350, "fdo64350.docx")
     991             : {
     992             :     // The problem was that page border shadows were not exported
     993           4 :     table::ShadowFormat aShadow = getProperty<table::ShadowFormat>(getStyles("PageStyles")->getByName(DEFAULT_STYLE), "ShadowFormat");
     994           4 :     CPPUNIT_ASSERT_EQUAL(table::ShadowLocation_BOTTOM_RIGHT, aShadow.Location);
     995           4 : }
     996             : 
     997          28 : DECLARE_OOXMLEXPORT_TEST(testFdo67013, "fdo67013.docx")
     998             : {
     999             :     /*
    1000             :      * The problem was that borders inside headers \ footers were not exported
    1001             :      * This was checked in xray using these commands:
    1002             :      *
    1003             :      * xHeaderText = ThisComponent.getStyleFamilies().getByName("PageStyles").getByName("Standard").HeaderText
    1004             :      * xHeaderEnum = xHeaderText.createEnumeration()
    1005             :      * xHeaderFirstParagraph = xHeaderEnum.nextElement()
    1006             :      * xHeaderBottomBorder = xHeaderFirstParagraph.BottomBorder
    1007             :      *
    1008             :      * xFooterText = ThisComponent.getStyleFamilies().getByName("PageStyles").getByName("Standard").FooterText
    1009             :      * xFooterEnum = xFooterText.createEnumeration()
    1010             :      * xFooterFirstParagraph = xFooterEnum.nextElement()
    1011             :      * xFooterTopBorder = xFooterFirstParagraph.TopBorder
    1012             :      */
    1013           4 :     uno::Reference<text::XText> xHeaderText = getProperty< uno::Reference<text::XText> >(getStyles("PageStyles")->getByName(DEFAULT_STYLE), "HeaderText");
    1014           8 :     uno::Reference< text::XTextRange > xHeaderParagraph = getParagraphOfText( 1, xHeaderText );
    1015           4 :     table::BorderLine2 aHeaderBottomBorder = getProperty<table::BorderLine2>(xHeaderParagraph, "BottomBorder");
    1016           4 :     CPPUNIT_ASSERT_EQUAL(sal_Int32(0x622423), aHeaderBottomBorder.Color);
    1017           4 :     CPPUNIT_ASSERT_EQUAL(sal_Int16(106), aHeaderBottomBorder.InnerLineWidth);
    1018           4 :     CPPUNIT_ASSERT_EQUAL(sal_Int16(26), aHeaderBottomBorder.LineDistance);
    1019           4 :     CPPUNIT_ASSERT_EQUAL(sal_Int16(7), aHeaderBottomBorder.LineStyle);
    1020           4 :     CPPUNIT_ASSERT_EQUAL(sal_uInt32(159), aHeaderBottomBorder.LineWidth);
    1021           4 :     CPPUNIT_ASSERT_EQUAL(sal_Int16(26), aHeaderBottomBorder.OuterLineWidth);
    1022             : 
    1023           8 :     uno::Reference<text::XText> xFooterText = getProperty< uno::Reference<text::XText> >(getStyles("PageStyles")->getByName(DEFAULT_STYLE), "FooterText");
    1024           8 :     uno::Reference< text::XTextRange > xFooterParagraph = getParagraphOfText( 1, xFooterText );
    1025           4 :     table::BorderLine2 aFooterTopBorder = getProperty<table::BorderLine2>(xFooterParagraph, "TopBorder");
    1026           4 :     CPPUNIT_ASSERT_EQUAL(sal_Int32(0x622423), aFooterTopBorder.Color);
    1027           4 :     CPPUNIT_ASSERT_EQUAL(sal_Int16(26), aFooterTopBorder.InnerLineWidth);
    1028           4 :     CPPUNIT_ASSERT_EQUAL(sal_Int16(26), aFooterTopBorder.LineDistance);
    1029           4 :     CPPUNIT_ASSERT_EQUAL(sal_Int16(4), aFooterTopBorder.LineStyle);
    1030           4 :     CPPUNIT_ASSERT_EQUAL(sal_uInt32(159), aFooterTopBorder.LineWidth);
    1031           8 :     CPPUNIT_ASSERT_EQUAL(sal_Int16(106), aFooterTopBorder.OuterLineWidth);
    1032           4 : }
    1033             : 
    1034          28 : DECLARE_OOXMLEXPORT_TEST(testParaShadow, "para-shadow.docx")
    1035             : {
    1036             :     // The problem was that in w:pBdr, child elements had a w:shadow attribute, but that was ignored.
    1037           4 :     table::ShadowFormat aShadow = getProperty<table::ShadowFormat>(getParagraph(2), "ParaShadowFormat");
    1038           4 :     CPPUNIT_ASSERT_EQUAL(COL_BLACK, sal_uInt32(aShadow.Color));
    1039           4 :     CPPUNIT_ASSERT_EQUAL(table::ShadowLocation_BOTTOM_RIGHT, aShadow.Location);
    1040             :     // w:sz="48" is in eights of a point, 1 pt is 20 twips.
    1041           4 :     CPPUNIT_ASSERT_EQUAL(sal_Int16(convertTwipToMm100(24/8*20)), aShadow.ShadowWidth);
    1042           4 : }
    1043             : 
    1044          28 : DECLARE_OOXMLEXPORT_TEST(testTableFloating, "table-floating.docx")
    1045             : {
    1046             :     // Both the size and the position of the table was incorrect.
    1047           4 :     uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
    1048           8 :     uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY);
    1049             :     // Second table was too wide: 16249, i.e. as wide as the first table.
    1050           4 :     CPPUNIT_ASSERT_EQUAL(sal_Int32(11248), getProperty<sal_Int32>(xTables->getByIndex(1), "Width"));
    1051             : 
    1052           8 :     uno::Reference<text::XTextFramesSupplier> xTextFramesSupplier(mxComponent, uno::UNO_QUERY);
    1053           8 :     uno::Reference<container::XIndexAccess> xIndexAccess(xTextFramesSupplier->getTextFrames(), uno::UNO_QUERY);
    1054           4 :     if (xIndexAccess->getCount())
    1055             :     {
    1056             :         // After import, table is inside a TextFrame.
    1057           2 :         uno::Reference<beans::XPropertySet> xFrame(xIndexAccess->getByIndex(0), uno::UNO_QUERY);
    1058             :         // This was 0, should be the the opposite of (left margin + half of the border width).
    1059           2 :         CPPUNIT_ASSERT_EQUAL(sal_Int32(-199), getProperty<sal_Int32>(xFrame, "HoriOrientPosition"));
    1060             :         // Was 0 as well, should be the right margin.
    1061           2 :         CPPUNIT_ASSERT_EQUAL(sal_Int32(250), getProperty<sal_Int32>(xFrame, "RightMargin"));
    1062             :     }
    1063             :     else
    1064             :     {
    1065             :         // After import, table is inside a TextFrame.
    1066           2 :         uno::Reference<beans::XPropertySet> xShape(getShape(1), uno::UNO_QUERY);
    1067             :         // This was 0, should be the the opposite of (left margin + half of the border width).
    1068           2 :         CPPUNIT_ASSERT_EQUAL(sal_Int32(-199), getProperty<sal_Int32>(xShape, "HoriOrientPosition"));
    1069             :         // Was 0 as well, should be the right margin.
    1070           2 :         CPPUNIT_ASSERT_EQUAL(sal_Int32(250), getProperty<sal_Int32>(xShape, "RightMargin"));
    1071           4 :     }
    1072           4 : }
    1073             : 
    1074          28 : DECLARE_OOXMLEXPORT_TEST(testFdo44689_start_page_0, "fdo44689_start_page_0.docx")
    1075             : {
    1076             :     // The problem was that the import & export process did not analyze the 'start from page' attribute of a section
    1077           4 :     uno::Reference<beans::XPropertySet> xPara(getParagraph(0), uno::UNO_QUERY);
    1078           4 :     CPPUNIT_ASSERT_EQUAL(sal_Int16(0), getProperty<sal_Int16>(xPara, "PageNumberOffset"));
    1079           4 : }
    1080             : 
    1081          28 : DECLARE_OOXMLEXPORT_TEST(testFdo44689_start_page_7, "fdo44689_start_page_7.docx")
    1082             : {
    1083             :     // The problem was that the import & export process did not analyze the 'start from page' attribute of a section
    1084           4 :     uno::Reference<beans::XPropertySet> xPara(getParagraph(0), uno::UNO_QUERY);
    1085           4 :     CPPUNIT_ASSERT_EQUAL(sal_Int16(7), getProperty<sal_Int16>(xPara, "PageNumberOffset"));
    1086           4 : }
    1087             : 
    1088          28 : DECLARE_OOXMLEXPORT_TEST(testFdo67737, "fdo67737.docx")
    1089             : {
    1090             :     // The problem was that imported shapes did not import and render the 'flip:x' and 'flip:y' attributes
    1091           4 :     uno::Reference<drawing::XShape> xArrow = getShape(1);
    1092           4 :     uno::Sequence<beans::PropertyValue> aProps = getProperty< uno::Sequence<beans::PropertyValue> >(xArrow, "CustomShapeGeometry");
    1093           8 :     for (int i = 0; i < aProps.getLength(); ++i)
    1094             :     {
    1095           8 :         const beans::PropertyValue& rProp = aProps[i];
    1096           8 :         if (rProp.Name == "MirroredY")
    1097             :         {
    1098           4 :             CPPUNIT_ASSERT_EQUAL( true, bool(rProp.Value.get<sal_Bool>()) );
    1099           8 :             return;
    1100             :         }
    1101             :     }
    1102             : 
    1103             :     // Shouldn't reach here
    1104           0 :     CPPUNIT_FAIL("Did not find MirroredY=true property");
    1105             : }
    1106             : 
    1107          28 : DECLARE_OOXMLEXPORT_TEST(testTransparentShadow, "transparent-shadow.docx")
    1108             : {
    1109           4 :     uno::Reference<drawing::XShape> xPicture = getShape(1);
    1110           4 :     sal_Int32 nShadowColor = getProperty<sal_Int32>(xPicture, "ShadowColor");
    1111           4 :     sal_Int16 nShadowTransparence = getProperty<sal_Int16>(xPicture, "ShadowTransparence");
    1112           4 :     CPPUNIT_ASSERT_EQUAL(sal_Int32(0x808080), nShadowColor);
    1113           4 :     CPPUNIT_ASSERT_EQUAL(sal_Int16(50), nShadowTransparence);
    1114           4 : }
    1115             : 
    1116          28 : DECLARE_OOXMLEXPORT_TEST(testBnc837302, "bnc837302.docx")
    1117             : {
    1118             :     // The problem was that text with empty author was not inserted as a redline
    1119           4 :     uno::Reference<text::XTextRange> xParagraph = getParagraph(1);
    1120             : 
    1121             :     // previously 'AAA' was not an own run
    1122           4 :     getRun(xParagraph, 3, "AAA");
    1123             :     // interestingly the 'Insert' is set on the _previous_ run
    1124           4 :     CPPUNIT_ASSERT_EQUAL(OUString("Insert"), getProperty<OUString>(getRun(xParagraph, 2), "RedlineType"));
    1125             : 
    1126             :     // make sure we don't introduce a redlined delete in the 2nd paragraph
    1127           4 :     xParagraph = getParagraph(2);
    1128           4 :     CPPUNIT_ASSERT_EQUAL(false, hasProperty(getRun(xParagraph, 1), "RedlineType"));
    1129           4 : }
    1130             : 
    1131             : #endif
    1132             : 
    1133           8 : CPPUNIT_PLUGIN_IMPLEMENT();
    1134             : 
    1135             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10