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

Generated by: LCOV version 1.11