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/Gradient.hpp>
13 : #include <com/sun/star/drawing/FillStyle.hpp>
14 : #include <rtl/byteseq.hxx>
15 :
16 : #include <swmodule.hxx>
17 : #include <swdll.hxx>
18 : #include <usrpref.hxx>
19 :
20 : #include <test/htmltesttools.hxx>
21 :
22 16 : class HtmlExportTest : public SwModelTestBase, public HtmlTestTools
23 : {
24 : private:
25 : FieldUnit m_eUnit;
26 :
27 : public:
28 16 : HtmlExportTest() :
29 : SwModelTestBase("/sw/qa/extras/htmlexport/data/", "HTML (StarWriter)"),
30 16 : m_eUnit(FUNIT_NONE)
31 16 : {}
32 :
33 : private:
34 19 : bool mustCalcLayoutOf(const char* filename) SAL_OVERRIDE
35 : {
36 19 : return OString(filename) != "fdo62336.docx";
37 : }
38 :
39 4 : bool mustTestImportOf(const char* filename) const SAL_OVERRIDE
40 : {
41 4 : return OString(filename) != "fdo62336.docx";
42 : }
43 :
44 15 : void preTest(const char* filename) SAL_OVERRIDE
45 : {
46 15 : if (getTestName().indexOf("SkipImage") != -1)
47 3 : setFilterOptions("SkipImages");
48 : else
49 12 : setFilterOptions("");
50 :
51 15 : if (OString(filename) == "charborder.odt")
52 : {
53 : // FIXME if padding-top gets exported as inches, not cms, we get rounding errors.
54 2 : SwGlobals::ensure(); // make sure that SW_MOD() is not 0
55 2 : SwMasterUsrPref* pPref = const_cast<SwMasterUsrPref*>(SW_MOD()->GetUsrPref(false));
56 2 : m_eUnit = pPref->GetMetric();
57 2 : pPref->SetMetric(FUNIT_CM);
58 : }
59 15 : }
60 :
61 15 : void postTest(const char* filename) SAL_OVERRIDE
62 : {
63 15 : if (OString(filename) == "charborder.odt")
64 : {
65 2 : SwMasterUsrPref* pPref = const_cast<SwMasterUsrPref*>(SW_MOD()->GetUsrPref(false));
66 2 : pPref->SetMetric(m_eUnit);
67 : }
68 15 : }
69 : };
70 :
71 : #define DECLARE_HTMLEXPORT_ROUNDTRIP_TEST(TestName, filename) DECLARE_SW_ROUNDTRIP_TEST(TestName, filename, HtmlExportTest)
72 :
73 19 : DECLARE_HTMLEXPORT_ROUNDTRIP_TEST(testFdo81276, "fdo81276.html")
74 : {
75 2 : uno::Reference<container::XNameAccess> xPageStyles(getStyles("PageStyles"));
76 4 : uno::Reference<beans::XPropertySet> xStyle(xPageStyles->getByName("HTML"), uno::UNO_QUERY);
77 : // some rounding going on here?
78 2 : CPPUNIT_ASSERT(abs(sal_Int32(29700) - getProperty<sal_Int32>(xStyle, "Width")) < 10);
79 2 : CPPUNIT_ASSERT(abs(sal_Int32(21006) - getProperty<sal_Int32>(xStyle, "Height")) < 10);
80 2 : CPPUNIT_ASSERT(abs(sal_Int32(500) - getProperty<sal_Int32>(xStyle, "LeftMargin")) < 10);
81 2 : CPPUNIT_ASSERT(abs(sal_Int32(500) - getProperty<sal_Int32>(xStyle, "RightMargin")) < 10);
82 2 : CPPUNIT_ASSERT(abs(sal_Int32(2000) - getProperty<sal_Int32>(xStyle, "TopMargin")) < 10);
83 4 : CPPUNIT_ASSERT(abs(sal_Int32(500) - getProperty<sal_Int32>(xStyle, "BottomMargin")) < 10);
84 2 : }
85 :
86 17 : DECLARE_HTMLEXPORT_ROUNDTRIP_TEST(testFdo62336, "fdo62336.docx")
87 : {
88 : // The problem was essentially a crash during table export as docx/rtf/html
89 : // If either of no-calc-layout or no-test-import is enabled, the crash does not occur
90 1 : }
91 :
92 19 : DECLARE_HTMLEXPORT_ROUNDTRIP_TEST(testFdo86857, "fdo86857.html")
93 : {
94 : // problem was that background color on page style was not exported
95 2 : uno::Reference<container::XNameAccess> xPageStyles(getStyles("PageStyles"));
96 4 : uno::Reference<beans::XPropertySet> xStyle(xPageStyles->getByName("HTML"), uno::UNO_QUERY);
97 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(0xff0000), getProperty<sal_Int32>(xStyle, "BackColor"));
98 : // check that table background color works, which still uses RES_BACKGROUND
99 4 : uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
100 4 : uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY);
101 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount());
102 4 : uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY);
103 4 : uno::Reference<text::XTextRange> xCell(xTable->getCellByName("A1"), uno::UNO_QUERY);
104 4 : CPPUNIT_ASSERT_EQUAL(sal_Int32(0x66ffff), getProperty<sal_Int32>(xCell, "BackColor"));
105 2 : }
106 :
107 19 : DECLARE_HTMLEXPORT_ROUNDTRIP_TEST(testCharacterBorder, "charborder.odt")
108 : {
109 :
110 2 : uno::Reference<beans::XPropertySet> xRun(getRun(getParagraph(1),1), uno::UNO_QUERY);
111 : // Different Border
112 : {
113 2 : CPPUNIT_ASSERT_BORDER_EQUAL(table::BorderLine2(0x6666FF,12,12,12,3,37), getProperty<table::BorderLine2>(xRun,"CharTopBorder"));
114 2 : CPPUNIT_ASSERT_BORDER_EQUAL(table::BorderLine2(0xFF9900,0,99,0,2,99), getProperty<table::BorderLine2>(xRun,"CharLeftBorder"));
115 2 : CPPUNIT_ASSERT_BORDER_EQUAL(table::BorderLine2(0xFF0000,0,169,0,1,169), getProperty<table::BorderLine2>(xRun,"CharBottomBorder"));
116 2 : CPPUNIT_ASSERT_BORDER_EQUAL(table::BorderLine2(0x0000FF,0,169,0,0,169), getProperty<table::BorderLine2>(xRun,"CharRightBorder"));
117 : }
118 :
119 : // Different Padding
120 : {
121 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(450), getProperty<sal_Int32>(xRun,"CharTopBorderDistance"));
122 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(550), getProperty<sal_Int32>(xRun,"CharLeftBorderDistance"));
123 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(150), getProperty<sal_Int32>(xRun,"CharBottomBorderDistance"));
124 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(250), getProperty<sal_Int32>(xRun,"CharRightBorderDistance"));
125 2 : }
126 :
127 : // No shadow
128 2 : }
129 :
130 : #define DECLARE_HTMLEXPORT_TEST(TestName, filename) DECLARE_SW_EXPORT_TEST(TestName, filename, HtmlExportTest)
131 :
132 13 : DECLARE_HTMLEXPORT_TEST(testExportOfImages, "textAndImage.docx")
133 : {
134 1 : htmlDocPtr pDoc = parseHtml(maTempFile);
135 1 : CPPUNIT_ASSERT(pDoc);
136 :
137 1 : assertXPath(pDoc, "/html/body", 1);
138 1 : assertXPath(pDoc, "/html/body/p/img", 1);
139 1 : }
140 :
141 13 : DECLARE_HTMLEXPORT_TEST(testExportOfImagesWithSkipImageEnabled, "textAndImage.docx")
142 : {
143 1 : htmlDocPtr pDoc = parseHtml(maTempFile);
144 1 : CPPUNIT_ASSERT(pDoc);
145 :
146 1 : assertXPath(pDoc, "/html/body", 1);
147 1 : assertXPath(pDoc, "/html/body/p/img", 0);
148 1 : }
149 :
150 13 : DECLARE_HTMLEXPORT_TEST(testSkipImageEmbedded, "skipimage-embedded.doc")
151 : {
152 : // Embedded spreadsheet was exported as image, so content was lost. Make
153 : // sure it's exported as HTML instead.
154 1 : htmlDocPtr pDoc = parseHtml(maTempFile);
155 1 : CPPUNIT_ASSERT(pDoc);
156 :
157 : // This was 0.
158 1 : assertXPath(pDoc, "//table", 1);
159 : // This was 2, the HTML header was in the document two times.
160 1 : assertXPath(pDoc, "//meta[@name='generator']", 1);
161 : // This was 0, <table> was directly under <p>, which caused errors in the parser.
162 1 : assertXPath(pDoc, "//span/table", 1);
163 1 : }
164 :
165 13 : DECLARE_HTMLEXPORT_TEST(testSkipImageEmbeddedDocument, "skipimage-embedded-document.docx")
166 : {
167 : // Similar to testSkipImageEmbedded, but with an embedded Writer object,
168 : // not a Calc one, and this time OOXML, not WW8.
169 1 : htmlDocPtr pDoc = parseHtml(maTempFile);
170 1 : CPPUNIT_ASSERT(pDoc);
171 :
172 : // This was 2, the HTML header was in the document two times.
173 1 : assertXPath(pDoc, "//meta[@name='generator']", 1);
174 : // Text of embedded document was missing.
175 1 : assertXPathContent(pDoc, "/html/body/p/span/p/span", "Inner.");
176 1 : }
177 :
178 13 : DECLARE_HTMLEXPORT_TEST(testExportImageProperties, "HTMLImage.odt")
179 : {
180 1 : htmlDocPtr pDoc = parseHtml(maTempFile);
181 1 : CPPUNIT_ASSERT(pDoc);
182 :
183 1 : assertXPath(pDoc, "/html/body", 1);
184 :
185 1 : assertXPath(pDoc, "/html/body/p/map/area", "shape", "poly");
186 1 : assertXPath(pDoc, "/html/body/p/map/area", "href", "http://www.microsoft.com/");
187 1 : assertXPath(pDoc, "/html/body/p/map/area", "target", "_self");
188 1 : assertXPath(pDoc, "/html/body/p/map/area", "alt", "microsoft");
189 :
190 1 : assertXPath(pDoc, "/html/body/p/a", 1);
191 1 : assertXPath(pDoc, "/html/body/p/a", "href", "http://www.google.com/");
192 :
193 1 : assertXPath(pDoc, "/html/body/p/a/font", 1);
194 1 : assertXPath(pDoc, "/html/body/p/a/font", "color", "#ff0000");
195 :
196 1 : assertXPath(pDoc, "/html/body/p/a/font/img", 1);
197 1 : assertXPath(pDoc, "/html/body/p/a/font/img", "name", "Text");
198 1 : assertXPath(pDoc, "/html/body/p/a/font/img", "alt", "Four colors");
199 1 : assertXPath(pDoc, "/html/body/p/a/font/img", "align", "middle");
200 :
201 : // Probably the DPI in OSX is different and Twip -> Pixel conversion produces
202 : // different results - so disable OSX for now.
203 : //
204 : // It would make sense to switch to use CSS and use "real world" units instead
205 : // i.e. (style="margin: 0cm 1.5cm; width: 1cm; height: 1cm")
206 :
207 : #if 0 // disabled as it depends that the system DPI is set to 96
208 : assertXPath(pDoc, "/html/body/p/a/font/img", "hspace", "38");
209 : assertXPath(pDoc, "/html/body/p/a/font/img", "vspace", "19");
210 : assertXPath(pDoc, "/html/body/p/a/font/img", "width", "222");
211 : assertXPath(pDoc, "/html/body/p/a/font/img", "height", "222");
212 : assertXPath(pDoc, "/html/body/p/a/font/img", "border", "3");
213 : #endif
214 :
215 1 : assertXPath(pDoc, "/html/body/p/a/font/img", "usemap", "#map1");
216 1 : }
217 :
218 13 : DECLARE_HTMLEXPORT_TEST(testExportCheckboxRadioButtonState, "checkbox-radiobutton.doc")
219 : {
220 1 : htmlDocPtr pDoc = parseHtml(maTempFile);
221 1 : CPPUNIT_ASSERT(pDoc);
222 :
223 1 : assertXPath(pDoc, "/html/body", 1);
224 1 : assertXPath(pDoc, "/html/body/p[1]/input", "type", "checkbox");
225 1 : assertXPath(pDoc, "/html/body/p[1]/input", "checked", "checked");
226 1 : assertXPath(pDoc, "/html/body/p[2]/input", "type", "checkbox");
227 1 : assertXPathNoAttribute(pDoc, "/html/body/p[2]/input", "checked");
228 1 : assertXPath(pDoc, "/html/body/form/p[1]/input", "type", "checkbox");
229 1 : assertXPath(pDoc, "/html/body/form/p[1]/input", "checked", "checked");
230 1 : assertXPath(pDoc, "/html/body/form/p[2]/input", "type", "checkbox");
231 1 : assertXPathNoAttribute(pDoc, "/html/body/form/p[2]/input", "checked");
232 1 : assertXPath(pDoc, "/html/body/form/p[3]/input", "type", "radio");
233 1 : assertXPath(pDoc, "/html/body/form/p[3]/input", "checked", "checked");
234 1 : assertXPath(pDoc, "/html/body/form/p[4]/input", "type", "radio");
235 1 : assertXPathNoAttribute(pDoc, "/html/body/form/p[4]/input", "checked");
236 1 : }
237 :
238 13 : DECLARE_HTMLEXPORT_TEST(testExportUrlEncoding, "tdf76291.odt")
239 : {
240 1 : htmlDocPtr pDoc = parseHtml(maTempFile);
241 1 : CPPUNIT_ASSERT(pDoc);
242 :
243 : // Test URI encoded hyperlink with Chinese characters
244 1 : assertXPath(pDoc, "/html/body/p/a", "href", "http://www.youtube.com/results?search_query=%E7%B2%B5%E8%AA%9Emv&sm=12");
245 1 : }
246 :
247 13 : DECLARE_HTMLEXPORT_TEST(testExportInternalUrl, "tdf90905.odt")
248 : {
249 1 : htmlDocPtr pDoc = parseHtml(maTempFile);
250 1 : CPPUNIT_ASSERT(pDoc);
251 :
252 : // Internal url should be valid
253 1 : assertXPath(pDoc, "/html/body/p/a", "href", "#0.0.1.Text|outline");
254 1 : }
255 :
256 4 : CPPUNIT_PLUGIN_IMPLEMENT();
257 :
258 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|