1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
10 #include <swmodeltestbase.hxx>
12 #include <com/sun/star/linguistic2/XHyphenator.hpp>
13 #include <com/sun/star/view/XSelectionSupplier.hpp>
14 #include <com/sun/star/linguistic2/XSpellChecker1.hpp>
16 #include <comphelper/scopeguard.hxx>
17 #include <comphelper/sequence.hxx>
18 #include <editeng/unolingu.hxx>
19 #include <i18nlangtag/languagetag.hxx>
20 #include <o3tl/string_view.hxx>
22 #include <rootfrm.hxx>
24 #include <IDocumentLayoutAccess.hxx>
25 #include <IDocumentRedlineAccess.hxx>
26 #include <fmtanchr.hxx>
28 /// Test to assert layout / rendering result of Writer.
29 class SwLayoutWriter2
: public SwModelTestBase
33 : SwModelTestBase(u
"/sw/qa/extras/layout/data/"_ustr
)
38 void CheckRedlineCharAttributesHidden();
41 // this mainly tests that splitting portions across redlines in SwAttrIter works
42 void SwLayoutWriter2::CheckRedlineCharAttributesHidden()
44 xmlDocUniquePtr pXmlDoc
= parseLayoutDump();
45 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[1]/merged", "paraPropsNodeIndex", u
"9");
46 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwParaPortion[1]",
47 "type", u
"PortionType::Para");
48 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwParaPortion[1]",
49 "portion", u
"foobaz");
50 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[2]/merged", "paraPropsNodeIndex", u
"10");
51 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[2]/SwParaPortion/SwLineLayout/SwParaPortion[1]",
52 "type", u
"PortionType::Para");
53 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[2]/SwParaPortion/SwLineLayout/SwParaPortion[1]",
54 "portion", u
"foobaz");
55 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[3]/merged", "paraPropsNodeIndex", u
"11");
56 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[1]",
57 "type", u
"PortionType::Text");
58 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[1]",
60 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[2]",
61 "type", u
"PortionType::Text");
62 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[2]",
64 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[4]/merged", "paraPropsNodeIndex", u
"12");
65 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[4]/SwParaPortion/SwLineLayout/SwLinePortion[1]",
66 "type", u
"PortionType::Text");
67 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[4]/SwParaPortion/SwLineLayout/SwLinePortion[1]",
69 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[4]/SwParaPortion/SwLineLayout/SwLinePortion[2]",
70 "type", u
"PortionType::Text");
71 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[4]/SwParaPortion/SwLineLayout/SwLinePortion[2]",
73 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[5]/merged", "paraPropsNodeIndex", u
"13");
74 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[5]/SwParaPortion/SwLineLayout/SwLinePortion[1]",
75 "type", u
"PortionType::Text");
76 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[5]/SwParaPortion/SwLineLayout/SwLinePortion[1]",
78 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[5]/SwParaPortion/SwLineLayout/SwLinePortion[2]",
79 "type", u
"PortionType::Text");
80 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[5]/SwParaPortion/SwLineLayout/SwLinePortion[2]",
82 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[6]/merged", "paraPropsNodeIndex", u
"14");
83 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[6]/SwParaPortion/SwLineLayout/SwLinePortion[1]",
84 "type", u
"PortionType::Text");
85 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[6]/SwParaPortion/SwLineLayout/SwLinePortion[1]",
87 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[6]/SwParaPortion/SwLineLayout/SwLinePortion[2]",
88 "type", u
"PortionType::Text");
89 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[6]/SwParaPortion/SwLineLayout/SwLinePortion[2]",
91 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[7]/merged", "paraPropsNodeIndex", u
"15");
92 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[7]/SwParaPortion/SwLineLayout/SwLinePortion[1]",
93 "type", u
"PortionType::Text");
94 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[7]/SwParaPortion/SwLineLayout/SwLinePortion[1]",
96 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[7]/SwParaPortion/SwLineLayout/SwLinePortion[2]",
97 "type", u
"PortionType::Text");
98 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[7]/SwParaPortion/SwLineLayout/SwLinePortion[2]",
100 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[8]/merged", "paraPropsNodeIndex", u
"16");
101 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[8]/SwParaPortion/SwLineLayout/SwLinePortion[1]",
102 "type", u
"PortionType::Text");
103 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[8]/SwParaPortion/SwLineLayout/SwLinePortion[1]",
105 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[8]/SwParaPortion/SwLineLayout/SwLinePortion[2]",
106 "type", u
"PortionType::Text");
107 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[8]/SwParaPortion/SwLineLayout/SwLinePortion[2]",
109 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[9]/merged", "paraPropsNodeIndex", u
"17");
110 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[9]/SwParaPortion/SwLineLayout/SwParaPortion[1]",
111 "type", u
"PortionType::Para");
112 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[9]/SwParaPortion/SwLineLayout/SwParaPortion[1]",
113 "portion", u
"foobaz");
114 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[10]/merged", "paraPropsNodeIndex", u
"18");
115 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[10]/SwParaPortion/SwLineLayout/SwLinePortion[1]",
116 "type", u
"PortionType::Text");
117 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[10]/SwParaPortion/SwLineLayout/SwLinePortion[1]",
119 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[10]/SwParaPortion/SwLineLayout/SwLinePortion[2]",
120 "type", u
"PortionType::Text");
121 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[10]/SwParaPortion/SwLineLayout/SwLinePortion[2]",
123 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[10]/SwParaPortion/SwLineLayout/SwLinePortion[3]",
124 "type", u
"PortionType::Text");
125 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[10]/SwParaPortion/SwLineLayout/SwLinePortion[3]",
127 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[11]/merged", "paraPropsNodeIndex", u
"19");
128 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[11]/SwParaPortion/SwLineLayout/SwParaPortion[1]",
129 "type", u
"PortionType::Para");
130 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[11]/SwParaPortion/SwLineLayout/SwParaPortion[1]",
131 "portion", u
"foobaz");
134 CPPUNIT_TEST_FIXTURE(SwLayoutWriter2
, testTdf148897
)
136 createSwDoc("tdf148897.odt");
138 xmlDocUniquePtr pXmlDoc
= parseLayoutDump();
140 assertXPath(pXmlDoc
, "/root/page[1]/sorted_objs/fly", 1);
141 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[2]/anchored/fly", 1);
142 assertXPath(pXmlDoc
, "/root/page[2]/sorted_objs/fly", 1);
143 assertXPath(pXmlDoc
, "/root/page[2]/body/txt[3]/anchored/fly", 1);
144 assertXPath(pXmlDoc
, "/root/page[3]/sorted_objs/fly", 0);
145 assertXPath(pXmlDoc
, "/root/page[3]/body/txt/anchored/fly", 0);
146 assertXPath(pXmlDoc
, "/root/page[4]/sorted_objs/fly", 1);
147 assertXPath(pXmlDoc
, "/root/page[4]/body/txt[1]/anchored/fly", 1);
148 // fly portion exists, no overlapping text
149 assertXPath(pXmlDoc
, "/root/page[4]/body/txt[1]/SwParaPortion/SwLineLayout[1]/SwFixPortion",
151 assertXPath(pXmlDoc
, "/root/page[5]/sorted_objs/fly", 0);
152 assertXPath(pXmlDoc
, "/root/page", 5);
154 auto xModel
= mxComponent
.queryThrow
<frame::XModel
>();
155 uno::Reference
<drawing::XShape
> xShape(getShapeByName(u
"Image3"));
156 uno::Reference
<view::XSelectionSupplier
> xCtrl(xModel
->getCurrentController(), uno::UNO_QUERY
);
157 xCtrl
->select(uno::Any(xShape
));
159 dispatchCommand(mxComponent
, u
".uno:Delete"_ustr
, {});
161 pXmlDoc
= parseLayoutDump();
163 assertXPath(pXmlDoc
, "/root/page[1]/sorted_objs/fly", 0);
164 assertXPath(pXmlDoc
, "/root/page[1]/body/txt/anchored/fly", 0);
165 assertXPath(pXmlDoc
, "/root/page[2]/sorted_objs/fly", 1);
166 assertXPath(pXmlDoc
, "/root/page[2]/body/txt[1]/anchored/fly", 1);
167 assertXPath(pXmlDoc
, "/root/page[3]/sorted_objs/fly", 1);
168 assertXPath(pXmlDoc
, "/root/page[3]/body/txt[2]/anchored/fly", 1);
169 // fly portion exists, no overlapping text
170 assertXPath(pXmlDoc
, "/root/page[3]/body/txt[1]/SwParaPortion/SwLineLayout[1]/SwFixPortion",
172 assertXPath(pXmlDoc
, "/root/page[4]/sorted_objs/fly", 0);
173 assertXPath(pXmlDoc
, "/root/page[4]/body/txt/anchored/fly", 0);
174 assertXPath(pXmlDoc
, "/root/page", 4);
176 dispatchCommand(mxComponent
, u
".uno:Undo"_ustr
, {});
178 pXmlDoc
= parseLayoutDump();
180 assertXPath(pXmlDoc
, "/root/page[1]/sorted_objs/fly", 1);
181 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[2]/anchored/fly", 1);
182 assertXPath(pXmlDoc
, "/root/page[2]/sorted_objs/fly", 1);
183 assertXPath(pXmlDoc
, "/root/page[2]/body/txt[3]/anchored/fly", 1);
184 assertXPath(pXmlDoc
, "/root/page[3]/sorted_objs/fly", 0);
185 assertXPath(pXmlDoc
, "/root/page[3]/body/txt/anchored/fly", 0);
186 assertXPath(pXmlDoc
, "/root/page[4]/sorted_objs/fly", 1);
187 assertXPath(pXmlDoc
, "/root/page[4]/body/txt[1]/anchored/fly", 1);
188 // fly portion exists, no overlapping text
189 assertXPath(pXmlDoc
, "/root/page[4]/body/txt[1]/SwParaPortion/SwLineLayout[1]/SwFixPortion",
191 assertXPath(pXmlDoc
, "/root/page[5]/sorted_objs/fly", 0);
192 assertXPath(pXmlDoc
, "/root/page", 5);
194 dispatchCommand(mxComponent
, u
".uno:Redo"_ustr
, {});
196 pXmlDoc
= parseLayoutDump();
198 assertXPath(pXmlDoc
, "/root/page[1]/sorted_objs/fly", 0);
199 assertXPath(pXmlDoc
, "/root/page[1]/body/txt/anchored/fly", 0);
200 assertXPath(pXmlDoc
, "/root/page[2]/sorted_objs/fly", 1);
201 assertXPath(pXmlDoc
, "/root/page[2]/body/txt[1]/anchored/fly", 1);
202 assertXPath(pXmlDoc
, "/root/page[3]/sorted_objs/fly", 1);
203 assertXPath(pXmlDoc
, "/root/page[3]/body/txt[2]/anchored/fly", 1);
204 // fly portion exists, no overlapping text
205 assertXPath(pXmlDoc
, "/root/page[3]/body/txt[1]/SwParaPortion/SwLineLayout[1]/SwFixPortion",
207 assertXPath(pXmlDoc
, "/root/page[4]/sorted_objs/fly", 0);
208 assertXPath(pXmlDoc
, "/root/page[4]/body/txt/anchored/fly", 0);
209 assertXPath(pXmlDoc
, "/root/page", 4);
212 CPPUNIT_TEST_FIXTURE(SwLayoutWriter2
, testRedlineCharAttributes
)
214 createSwDoc("redline_charatr.fodt");
215 SwDoc
* pDoc(getSwDoc());
216 SwRootFrame
* pLayout(pDoc
->getIDocumentLayoutAccess().GetCurrentLayout());
217 CPPUNIT_ASSERT(pLayout
->IsHideRedlines());
220 CheckRedlineCharAttributesHidden();
222 dispatchCommand(mxComponent
, u
".uno:ShowTrackedChanges"_ustr
, {});
223 CPPUNIT_ASSERT(!pLayout
->IsHideRedlines());
224 // why is this needed explicitly?
226 xmlDocUniquePtr pXmlDoc
= parseLayoutDump();
228 // show: nothing is merged
229 assertXPath(pXmlDoc
, "//merged", 0);
230 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[1]",
231 "type", u
"PortionType::Text");
232 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[1]",
234 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[2]",
235 "type", u
"PortionType::Text");
236 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[2]",
238 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[3]",
239 "type", u
"PortionType::Text");
240 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[3]",
242 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[2]/SwParaPortion/SwLineLayout/SwLinePortion[1]",
243 "type", u
"PortionType::Text");
244 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[2]/SwParaPortion/SwLineLayout/SwLinePortion[1]",
246 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[2]/SwParaPortion/SwLineLayout/SwLinePortion[2]",
247 "type", u
"PortionType::Text");
248 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[2]/SwParaPortion/SwLineLayout/SwLinePortion[2]",
250 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[2]/SwParaPortion/SwLineLayout/SwLinePortion[3]",
251 "type", u
"PortionType::Text");
252 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[2]/SwParaPortion/SwLineLayout/SwLinePortion[3]",
254 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[1]",
255 "type", u
"PortionType::Text");
256 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[1]",
258 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[2]",
259 "type", u
"PortionType::Text");
260 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[2]",
262 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[3]",
263 "type", u
"PortionType::Text");
264 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[3]/SwParaPortion/SwLineLayout/SwLinePortion[3]",
266 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[4]/SwParaPortion/SwLineLayout/SwLinePortion[1]",
267 "type", u
"PortionType::Text");
268 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[4]/SwParaPortion/SwLineLayout/SwLinePortion[1]",
270 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[4]/SwParaPortion/SwLineLayout/SwLinePortion[2]",
271 "type", u
"PortionType::Text");
272 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[4]/SwParaPortion/SwLineLayout/SwLinePortion[2]",
274 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[4]/SwParaPortion/SwLineLayout/SwLinePortion[3]",
275 "type", u
"PortionType::Text");
276 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[4]/SwParaPortion/SwLineLayout/SwLinePortion[3]",
278 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[5]/SwParaPortion/SwLineLayout/SwLinePortion[1]",
279 "type", u
"PortionType::Text");
280 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[5]/SwParaPortion/SwLineLayout/SwLinePortion[1]",
282 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[5]/SwParaPortion/SwLineLayout/SwLinePortion[2]",
283 "type", u
"PortionType::Text");
284 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[5]/SwParaPortion/SwLineLayout/SwLinePortion[2]",
286 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[5]/SwParaPortion/SwLineLayout/SwLinePortion[3]",
287 "type", u
"PortionType::Text");
288 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[5]/SwParaPortion/SwLineLayout/SwLinePortion[3]",
290 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[6]/SwParaPortion/SwLineLayout/SwLinePortion[1]",
291 "type", u
"PortionType::Text");
292 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[6]/SwParaPortion/SwLineLayout/SwLinePortion[1]",
294 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[6]/SwParaPortion/SwLineLayout/SwLinePortion[2]",
295 "type", u
"PortionType::Text");
296 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[6]/SwParaPortion/SwLineLayout/SwLinePortion[2]",
298 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[6]/SwParaPortion/SwLineLayout/SwLinePortion[3]",
299 "type", u
"PortionType::Text");
300 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[6]/SwParaPortion/SwLineLayout/SwLinePortion[3]",
302 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[7]/SwParaPortion/SwLineLayout/SwLinePortion[1]",
303 "type", u
"PortionType::Text");
304 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[7]/SwParaPortion/SwLineLayout/SwLinePortion[1]",
306 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[7]/SwParaPortion/SwLineLayout/SwLinePortion[2]",
307 "type", u
"PortionType::Text");
308 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[7]/SwParaPortion/SwLineLayout/SwLinePortion[2]",
310 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[7]/SwParaPortion/SwLineLayout/SwLinePortion[3]",
311 "type", u
"PortionType::Text");
312 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[7]/SwParaPortion/SwLineLayout/SwLinePortion[3]",
314 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[8]/SwParaPortion/SwLineLayout/SwLinePortion[1]",
315 "type", u
"PortionType::Text");
316 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[8]/SwParaPortion/SwLineLayout/SwLinePortion[1]",
318 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[8]/SwParaPortion/SwLineLayout/SwLinePortion[2]",
319 "type", u
"PortionType::Text");
320 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[8]/SwParaPortion/SwLineLayout/SwLinePortion[2]",
322 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[8]/SwParaPortion/SwLineLayout/SwLinePortion[3]",
323 "type", u
"PortionType::Text");
324 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[8]/SwParaPortion/SwLineLayout/SwLinePortion[3]",
326 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[8]/SwParaPortion/SwLineLayout/SwLinePortion[4]",
327 "type", u
"PortionType::Text");
328 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[8]/SwParaPortion/SwLineLayout/SwLinePortion[4]",
330 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[9]/SwParaPortion/SwLineLayout/SwLinePortion[1]",
331 "type", u
"PortionType::Text");
332 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[9]/SwParaPortion/SwLineLayout/SwLinePortion[1]",
334 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[9]/SwParaPortion/SwLineLayout/SwLinePortion[2]",
335 "type", u
"PortionType::Text");
336 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[9]/SwParaPortion/SwLineLayout/SwLinePortion[2]",
338 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[9]/SwParaPortion/SwLineLayout/SwLinePortion[3]",
339 "type", u
"PortionType::Text");
340 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[9]/SwParaPortion/SwLineLayout/SwLinePortion[3]",
342 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[10]/SwParaPortion/SwLineLayout/SwLinePortion[1]",
343 "type", u
"PortionType::Text");
344 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[10]/SwParaPortion/SwLineLayout/SwLinePortion[1]",
346 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[10]/SwParaPortion/SwLineLayout/SwLinePortion[2]",
347 "type", u
"PortionType::Text");
348 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[10]/SwParaPortion/SwLineLayout/SwLinePortion[2]",
350 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[10]/SwParaPortion/SwLineLayout/SwLinePortion[3]",
351 "type", u
"PortionType::Text");
352 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[10]/SwParaPortion/SwLineLayout/SwLinePortion[3]",
354 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[10]/SwParaPortion/SwLineLayout/SwLinePortion[4]",
355 "type", u
"PortionType::Text");
356 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[10]/SwParaPortion/SwLineLayout/SwLinePortion[4]",
358 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[10]/SwParaPortion/SwLineLayout/SwLinePortion[5]",
359 "type", u
"PortionType::Text");
360 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[10]/SwParaPortion/SwLineLayout/SwLinePortion[5]",
362 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[11]/SwParaPortion/SwLineLayout/SwLinePortion[1]",
363 "type", u
"PortionType::Text");
364 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[11]/SwParaPortion/SwLineLayout/SwLinePortion[1]",
366 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[11]/SwParaPortion/SwLineLayout/SwLinePortion[2]",
367 "type", u
"PortionType::Text");
368 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[11]/SwParaPortion/SwLineLayout/SwLinePortion[2]",
370 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[11]/SwParaPortion/SwLineLayout/SwLinePortion[3]",
371 "type", u
"PortionType::Text");
372 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[11]/SwParaPortion/SwLineLayout/SwLinePortion[3]",
374 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[11]/SwParaPortion/SwLineLayout/SwLinePortion[4]",
375 "type", u
"PortionType::Text");
376 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[11]/SwParaPortion/SwLineLayout/SwLinePortion[4]",
378 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[11]/SwParaPortion/SwLineLayout/SwLinePortion[5]",
379 "type", u
"PortionType::Text");
380 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[11]/SwParaPortion/SwLineLayout/SwLinePortion[5]",
384 dispatchCommand(mxComponent
, u
".uno:ShowTrackedChanges"_ustr
, {});
385 CPPUNIT_ASSERT(pLayout
->IsHideRedlines());
386 // why is this needed explicitly?
388 CheckRedlineCharAttributesHidden();
391 CPPUNIT_TEST_FIXTURE(SwLayoutWriter2
, testRedlineShowHideFootnotePagination
)
393 createSwDoc("redline_footnote_pagination.fodt");
394 SwDoc
* pDoc(getSwDoc());
395 SwRootFrame
* pLayout(pDoc
->getIDocumentLayoutAccess().GetCurrentLayout());
396 CPPUNIT_ASSERT(!pLayout
->IsHideRedlines());
398 xmlDocUniquePtr pXmlDoc
= parseLayoutDump();
401 assertXPath(pXmlDoc
, "/root/page[1]/ftncont/ftn", 6);
402 assertXPath(pXmlDoc
, "/root/page[2]/ftncont/ftn", 3);
403 // check that first page ends with the y line and second page starts with z
404 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[last()]/SwParaPortion/SwLineLayout[last()]",
406 u
"yyyyyyyyy yyy yyyyyyyyyyyyyyyy yyyyyyy yyy yyyyy yyyyyyyyy yyy yyyyyyyyy ");
407 assertXPath(pXmlDoc
, "/root/page[2]/body/txt[1]/SwParaPortion/SwLineLayout[1]", "portion",
408 u
"zzz. zzz zzzz zzzz* zzz zzz zzzzzzz zzz zzzz zzzzzzzzzzzzzz zzzzzzzzzzzz ");
410 // hide redlines - all still visible footnotes move to page 1
411 dispatchCommand(mxComponent
, u
".uno:ShowTrackedChanges"_ustr
, {});
413 pXmlDoc
= parseLayoutDump();
415 assertXPath(pXmlDoc
, "/root/page[1]/ftncont/ftn", 2);
416 assertXPath(pXmlDoc
, "/root/page[2]/ftncont/ftn", 0);
418 // show again - should now get the same result as on loading
419 dispatchCommand(mxComponent
, u
".uno:ShowTrackedChanges"_ustr
, {});
421 pXmlDoc
= parseLayoutDump();
424 assertXPath(pXmlDoc
, "/root/page[1]/ftncont/ftn", 6);
425 assertXPath(pXmlDoc
, "/root/page[2]/ftncont/ftn", 3);
426 // check that first page ends with the y line and second page starts with z
427 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[last()]/SwParaPortion/SwLineLayout[last()]",
429 u
"yyyyyyyyy yyy yyyyyyyyyyyyyyyy yyyyyyy yyy yyyyy yyyyyyyyy yyy yyyyyyyyy ");
430 assertXPath(pXmlDoc
, "/root/page[2]/body/txt[1]/SwParaPortion/SwLineLayout[1]", "portion",
431 u
"zzz. zzz zzzz zzzz* zzz zzz zzzzzzz zzz zzzz zzzzzzzzzzzzzz zzzzzzzzzzzz ");
434 CPPUNIT_TEST_FIXTURE(SwLayoutWriter2
, testtdf138951
)
437 createSwDoc("tdf138951.odt");
439 // Get the only shape
440 uno::Reference
<drawing::XShape
> xShape(getShape(1), uno::UNO_QUERY
);
441 CPPUNIT_ASSERT(xShape
);
443 // Gather its formats: the shape and textbox
444 const SwFrameFormat
* pTxFrm
= SwTextBoxHelper::getOtherTextBoxFormat(xShape
);
445 CPPUNIT_ASSERT(pTxFrm
);
446 const SwFrameFormat
* pShFrm
= SwTextBoxHelper::getOtherTextBoxFormat(pTxFrm
, RES_FLYFRMFMT
);
447 CPPUNIT_ASSERT(pShFrm
);
451 // Get the bound rectangle of the textframe
452 tools::Rectangle
aTxtFrmRect(pTxFrm
->FindRealSdrObject()->GetLogicRect());
454 // Get the bound rectangle of the shape
455 tools::Rectangle
aShpRect(pShFrm
->FindRealSdrObject()->GetLogicRect());
457 // Check the anchor the same and the textbox is inside the shape
458 const bool bIsAnchTheSame
459 = *pShFrm
->GetAnchor().GetAnchorNode() == *pShFrm
->GetAnchor().GetAnchorNode();
460 CPPUNIT_ASSERT_MESSAGE("The anchor is different for the textbox and shape!", bIsAnchTheSame
);
461 CPPUNIT_ASSERT_MESSAGE("The textbox has fallen apart!", aShpRect
.Contains(aTxtFrmRect
));
462 // Without the fix the anchor differs, and the frame outside of the shape
465 CPPUNIT_TEST_FIXTURE(SwLayoutWriter2
, testTdf150717
)
467 createSwDoc("tdf150717.odt");
468 xmlDocUniquePtr pXmlDoc
= parseLayoutDump();
469 // check bookmark colors defined in metadata
470 assertXPath(pXmlDoc
, "/root/page/body/txt/SwParaPortion/SwLineLayout/child::*[2]", "colors",
471 u
"#Bookmark1 Bookmark Start");
472 assertXPath(pXmlDoc
, "/root/page/body/txt/SwParaPortion/SwLineLayout/child::*[4]", "colors",
473 u
"#Bookmark2 Bookmark Start");
474 assertXPath(pXmlDoc
, "/root/page/body/txt/SwParaPortion/SwLineLayout/child::*[6]", "colors",
475 u
"#Bookmark2 Bookmark End#Bookmark1 Bookmark End");
476 // full text, if bookmarks are visible
477 assertXPath(pXmlDoc
, "/root/page/body/txt/SwParaPortion/SwLineLayout/child::*[1]", "portion",
479 assertXPath(pXmlDoc
, "/root/page/body/txt/SwParaPortion/SwLineLayout/child::*[3]", "portion",
481 assertXPath(pXmlDoc
, "/root/page/body/txt/SwParaPortion/SwLineLayout/child::*[5]", "portion",
483 assertXPath(pXmlDoc
, "/root/page/body/txt/SwParaPortion/SwLineLayout/child::*[7]", "portion",
487 CPPUNIT_TEST_FIXTURE(SwLayoutWriter2
, testTdf150790
)
489 createSwDoc("tdf150790.fodt");
490 xmlDocUniquePtr pXmlDoc
= parseLayoutDump();
491 // point bookmark is shown as I-beam (only its text dump is |, as before on the screen)
492 assertXPath(pXmlDoc
, "/root/page/body/txt[1]/SwParaPortion/SwLineLayout/SwBookmarkPortion",
493 "colors", u
"#Bookmark 1 Bookmark");
494 // single start bookmark
495 assertXPath(pXmlDoc
, "/root/page/body/txt[2]/SwParaPortion/SwLineLayout/SwBookmarkPortion[1]",
496 "colors", u
"#Bookmark 2 Bookmark Start");
497 // single end bookmark
498 assertXPath(pXmlDoc
, "/root/page/body/txt[2]/SwParaPortion/SwLineLayout/SwBookmarkPortion[3]",
499 "colors", u
"#Bookmark 3 Bookmark End");
500 // This was |, as before the point bookmark (neighboring end and start bookmarks)
501 assertXPath(pXmlDoc
, "/root/page/body/txt[2]/SwParaPortion/SwLineLayout/SwBookmarkPortion[2]",
502 "colors", u
"#Bookmark 2 Bookmark End#Bookmark 3 Bookmark Start");
505 CPPUNIT_TEST_FIXTURE(SwLayoutWriter2
, testTdf129357
)
507 createSwDoc("tdf129357.fodt");
508 SwDocShell
* pShell
= getSwDocShell();
510 // Dump the rendering of the first page as an XML file.
511 std::shared_ptr
<GDIMetaFile
> xMetaFile
= pShell
->GetPreviewMetaFile();
512 MetafileXmlDump dumper
;
514 xmlDocUniquePtr pXmlDoc
= dumpAndParse(dumper
, *xMetaFile
);
515 CPPUNIT_ASSERT(pXmlDoc
);
517 // visible soft hyphen
518 assertXPathContent(pXmlDoc
, "/metafile/push/push/push/push/push/textarray[2]/text", u
"-");
521 CPPUNIT_TEST_FIXTURE(SwLayoutWriter2
, testRedlineNumberInNumbering
)
523 createSwDoc("tdf42748.fodt");
524 SwDocShell
* pShell
= getSwDocShell();
526 // Dump the rendering of the first page as an XML file.
527 std::shared_ptr
<GDIMetaFile
> xMetaFile
= pShell
->GetPreviewMetaFile();
528 MetafileXmlDump dumper
;
530 xmlDocUniquePtr pXmlDoc
= dumpAndParse(dumper
, *xMetaFile
);
531 CPPUNIT_ASSERT(pXmlDoc
);
533 // Assert the tracked deletion of the number of joined list item and
534 // the tracked insertion of the number after a split list item as not black
535 // (and not COL_GREEN color of the tracked text movement, see testRedlineMoving) elements
538 "/metafile/push/push/push/textcolor[not(@color='#000000') and not(@color='#008000')]", 5);
540 // tdf#145068 numbering shows changes in the associated list item, not the next one
541 // This was 1 (black numbering of the first list item previously)
542 assertXPath(pXmlDoc
, "/metafile/push/push/push/font[4][@color='#000000']", 0);
545 CPPUNIT_TEST_FIXTURE(SwLayoutWriter2
, testRedlineNumbering
)
547 createSwDoc("tdf115523.fodt");
548 SwDocShell
* pShell
= getSwDocShell();
550 // Dump the rendering of the first page as an XML file.
551 std::shared_ptr
<GDIMetaFile
> xMetaFile
= pShell
->GetPreviewMetaFile();
552 MetafileXmlDump dumper
;
554 xmlDocUniquePtr pXmlDoc
= dumpAndParse(dumper
, *xMetaFile
);
555 CPPUNIT_ASSERT(pXmlDoc
);
557 // Show the correct and the original line numbering instead of counting
558 // the deleted list items in Show Changes mode, as part of the list
559 assertXPathContent(pXmlDoc
, "/metafile/push/push/push/textarray[1]/text", u
"1.");
560 // This was "2." (deleted text node, now its text content is part of the first list item)
561 assertXPathContent(pXmlDoc
, "/metafile/push/push/push/textarray[3]/text", u
"[2.] ");
562 // This was "3." (now it's the second list item)
563 assertXPathContent(pXmlDoc
, "/metafile/push/push/push/textarray[5]/text", u
"2.[3.] ");
566 CPPUNIT_TEST_FIXTURE(SwLayoutWriter2
, testRedlineNumbering2
)
568 createSwDoc("tdf115524.fodt");
569 SwDocShell
* pShell
= getSwDocShell();
571 // Dump the rendering of the first page as an XML file.
572 std::shared_ptr
<GDIMetaFile
> xMetaFile
= pShell
->GetPreviewMetaFile();
573 MetafileXmlDump dumper
;
575 xmlDocUniquePtr pXmlDoc
= dumpAndParse(dumper
, *xMetaFile
);
576 CPPUNIT_ASSERT(pXmlDoc
);
578 // Show the correct and the original line numbering in Show Changes mode
579 assertXPathContent(pXmlDoc
, "/metafile/push/push/push/textarray[1]/text", u
"1.");
580 assertXPathContent(pXmlDoc
, "/metafile/push/push/push/textarray[3]/text", u
"2.");
581 // FIXME: show as 3.[2.]
582 assertXPathContent(pXmlDoc
, "/metafile/push/push/push/textarray[5]/text", u
"3.");
583 // This was "4." (not shown the original number)
584 assertXPathContent(pXmlDoc
, "/metafile/push/push/push/textarray[7]/text", u
"4.[3.] ");
587 CPPUNIT_TEST_FIXTURE(SwLayoutWriter2
, testTdf149710_RedlineNumberingEditing
)
589 createSwDoc("tdf149710.fodt");
592 SwWrtShell
* pWrtShell
= getSwDocShell()->GetWrtShell();
593 SwRootFrame
* pLayout(pWrtShell
->GetLayout());
594 CPPUNIT_ASSERT(!pLayout
->IsHideRedlines());
596 // delete the paragraph mark of the first list item with change tracking
597 dispatchCommand(mxComponent
, u
".uno:GoToEndOfLine"_ustr
, {});
598 dispatchCommand(mxComponent
, u
".uno:TrackChanges"_ustr
, {});
599 dispatchCommand(mxComponent
, u
".uno:Delete"_ustr
, {});
601 // Dump the rendering of the first page as an XML file.
602 SwDocShell
* pShell
= getSwDocShell();
603 std::shared_ptr
<GDIMetaFile
> xMetaFile
= pShell
->GetPreviewMetaFile();
604 MetafileXmlDump dumper
;
606 xmlDocUniquePtr pXmlDoc
= dumpAndParse(dumper
, *xMetaFile
);
607 CPPUNIT_ASSERT(pXmlDoc
);
609 // Show the correct and the original line numbering instead of counting
610 // the deleted list items in Show Changes mode, as part of the list
612 assertXPathContent(pXmlDoc
, "/metafile/push/push/push/textarray[1]/text", u
"[1.] ");
613 // This was "2." (deleted text node, now its text content is part of the first list item)
614 assertXPathContent(pXmlDoc
, "/metafile/push/push/push/textarray[3]/text", u
"1.[2.] ");
615 // This was "3." (now it's the second list item)
616 assertXPathContent(pXmlDoc
, "/metafile/push/push/push/textarray[5]/text", u
"2.[3.] ");
618 // remove the tracked deletion, and check the layout again
620 xMetaFile
= pShell
->GetPreviewMetaFile();
621 pXmlDoc
= dumpAndParse(dumper
, *xMetaFile
);
622 assertXPathContent(pXmlDoc
, "/metafile/push/push/push/textarray[1]/text", u
"1.");
623 assertXPathContent(pXmlDoc
, "/metafile/push/push/push/textarray[3]/text", u
"2.");
624 assertXPathContent(pXmlDoc
, "/metafile/push/push/push/textarray[5]/text", u
"3.");
627 CPPUNIT_TEST_FIXTURE(SwLayoutWriter2
, testTdf149709_RedlineNumberingLevel
)
629 createSwDoc("tdf149709.fodt");
632 SwWrtShell
* pWrtShell
= getSwDocShell()->GetWrtShell();
633 SwRootFrame
* pLayout(pWrtShell
->GetLayout());
634 CPPUNIT_ASSERT(!pLayout
->IsHideRedlines());
636 // insert a new list item at start of the second list item "a)"
637 dispatchCommand(mxComponent
, u
".uno:TrackChanges"_ustr
, {});
638 pWrtShell
->Down(false, 1);
639 pWrtShell
->SplitNode(false);
641 // Dump the rendering of the first page as an XML file.
642 SwDocShell
* pShell
= getSwDocShell();
643 std::shared_ptr
<GDIMetaFile
> xMetaFile
= pShell
->GetPreviewMetaFile();
644 MetafileXmlDump dumper
;
646 xmlDocUniquePtr pXmlDoc
= dumpAndParse(dumper
, *xMetaFile
);
647 CPPUNIT_ASSERT(pXmlDoc
);
649 // Show the correct and the original line numbering instead of counting
650 // the deleted list items in Show Changes mode, as part of the list
651 assertXPathContent(pXmlDoc
, "/metafile/push/push/push/textarray[1]/text", u
"1.");
652 assertXPathContent(pXmlDoc
, "/metafile/push/push/push/textarray[3]/text", u
"a)");
654 assertXPathContent(pXmlDoc
, "/metafile/push/push/push/textarray[4]/text", u
"b)[a)] ");
656 assertXPathContent(pXmlDoc
, "/metafile/push/push/push/textarray[6]/text", u
"c)[b)] ");
657 // This was "4.[2.]" (after disabling Show Changes, and enabling again)
658 assertXPathContent(pXmlDoc
, "/metafile/push/push/push/textarray[8]/text", u
"2.");
660 // remove the tracked deletion, and check the layout again
662 xMetaFile
= pShell
->GetPreviewMetaFile();
663 pXmlDoc
= dumpAndParse(dumper
, *xMetaFile
);
664 assertXPathContent(pXmlDoc
, "/metafile/push/push/push/textarray[1]/text", u
"1.");
665 assertXPathContent(pXmlDoc
, "/metafile/push/push/push/textarray[3]/text", u
"a)");
666 assertXPathContent(pXmlDoc
, "/metafile/push/push/push/textarray[5]/text", u
"b)");
667 assertXPathContent(pXmlDoc
, "/metafile/push/push/push/textarray[7]/text", u
"2.");
671 xMetaFile
= pShell
->GetPreviewMetaFile();
672 pXmlDoc
= dumpAndParse(dumper
, *xMetaFile
);
673 assertXPathContent(pXmlDoc
, "/metafile/push/push/push/textarray[1]/text", u
"1.");
674 assertXPathContent(pXmlDoc
, "/metafile/push/push/push/textarray[3]/text", u
"a)");
675 // TODO: show as b)[a)]
676 assertXPathContent(pXmlDoc
, "/metafile/push/push/push/textarray[4]/text", u
"b)");
677 // FIXME: This must be "c)[b]"
678 assertXPathContent(pXmlDoc
, "/metafile/push/push/push/textarray[6]/text", u
"c)[a)] ");
679 assertXPathContent(pXmlDoc
, "/metafile/push/push/push/textarray[8]/text", u
"2.");
682 CPPUNIT_TEST_FIXTURE(SwLayoutWriter2
, testTdf149711_importDOCXMoveToParagraphMark
)
684 createSwDoc("tdf149711.docx");
685 SwDoc
* pDoc
= getSwDoc();
686 xmlDocUniquePtr pXmlDoc
= parseLayoutDump();
687 assertXPath(pXmlDoc
, "/root/page[1]/body/txt", 6);
689 // reject tracked insertion (moveTo)
690 SwEditShell
* const pEditShell(pDoc
->GetEditShell());
691 CPPUNIT_ASSERT(pEditShell
);
692 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(2), pEditShell
->GetRedlineCount());
693 pEditShell
->RejectRedline(1);
695 pXmlDoc
= parseLayoutDump();
696 // This was 6 (not tracked paragraph mark of the moveTo list item)
697 assertXPath(pXmlDoc
, "/root/page[1]/body/txt", 5);
700 CPPUNIT_TEST_FIXTURE(SwLayoutWriter2
, testTdf152872
)
702 createSwDoc("hidden-para-separator.docx");
703 xmlDocUniquePtr pXmlDoc
= parseLayoutDump();
705 assertXPath(pXmlDoc
, "/root/page[1]/body/txt", 2);
706 assertXPath(pXmlDoc
, "/root/page/body/txt[1]/SwParaPortion/SwLineLayout", "portion", u
"C DE");
707 // 5 is empty and hidden
708 assertXPath(pXmlDoc
, "/root/page/body/txt[2]/infos/bounds", "height", u
"0");
710 dispatchCommand(mxComponent
, u
".uno:ControlCodes"_ustr
, {});
712 pXmlDoc
= parseLayoutDump();
714 assertXPath(pXmlDoc
, "/root/page[1]/body/txt", 5);
715 assertXPath(pXmlDoc
, "/root/page/body/txt[1]/SwParaPortion/SwLineLayout", "portion", u
"C ");
716 assertXPath(pXmlDoc
, "/root/page/body/txt[2]/SwParaPortion/SwLineLayout", "portion", u
"D");
717 // 3 is an empty paragraph with RES_CHRATR_HIDDEN which results in 0-height
718 // frame; ideally it should only be hidden when control codes are hidden
719 // and be a full-height frame now, but that needs more work...
720 assertXPath(pXmlDoc
, "/root/page/body/txt[3]/infos/bounds", "height", u
"0");
721 assertXPath(pXmlDoc
, "/root/page/body/txt[4]/SwParaPortion/SwLineLayout", "portion", u
"E");
722 // 5 is an empty paragraph with RES_CHRATR_HIDDEN which results in 0-height
723 // frame; ideally it should only be hidden when control codes are hidden
724 // and be a full-height frame now, but that needs more work...
725 assertXPath(pXmlDoc
, "/root/page/body/txt[5]/infos/bounds", "height", u
"0");
727 dispatchCommand(mxComponent
, u
".uno:ControlCodes"_ustr
, {});
729 pXmlDoc
= parseLayoutDump();
731 assertXPath(pXmlDoc
, "/root/page[1]/body/txt", 2);
732 assertXPath(pXmlDoc
, "/root/page/body/txt[1]/SwParaPortion/SwLineLayout", "portion", u
"C DE");
733 // 5 is empty and hidden
734 assertXPath(pXmlDoc
, "/root/page/body/txt[2]/infos/bounds", "height", u
"0");
737 CPPUNIT_TEST_FIXTURE(SwLayoutWriter2
, testTdf151954
)
739 createSwDoc("tdf151954.docx");
740 SwDoc
* pDoc
= getSwDoc();
741 xmlDocUniquePtr pXmlDoc
= parseLayoutDump();
742 assertXPath(pXmlDoc
, "/root/page[1]/body/txt", 2);
744 // accept tracked insertion (moveTo)
745 SwEditShell
* const pEditShell(pDoc
->GetEditShell());
746 CPPUNIT_ASSERT(pEditShell
);
747 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(3), pEditShell
->GetRedlineCount());
748 pEditShell
->AcceptRedline(0);
750 pXmlDoc
= parseLayoutDump();
751 // This was 1 (moveFrom was extended to the paragraph mark)
752 assertXPath(pXmlDoc
, "/root/page[1]/body/txt", 2);
755 CPPUNIT_TEST_FIXTURE(SwLayoutWriter2
, testTdf152952
)
757 createSwDoc("Hyphenated-link.rtf");
758 xmlDocUniquePtr pXmlDoc
= parseLayoutDump();
759 // URL should not be hyphenated
760 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout[1]", "portion",
761 u
" NNNNNNNNNN NNNNNNNNNNNNNNN ");
762 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout[2]", "portion",
763 u
"https://example.com/xxxxxxx/testtesttesttest/hyphenate/testtesttest ");
766 CPPUNIT_TEST_FIXTURE(SwLayoutWriter2
, testTdf152952_compat
)
768 uno::Reference
<linguistic2::XHyphenator
> xHyphenator
= LinguMgr::GetHyphenator();
769 if (!xHyphenator
->hasLocale(lang::Locale(u
"en"_ustr
, u
"US"_ustr
, OUString())))
772 createSwDoc("Hyphenated-link.fodt");
773 xmlDocUniquePtr pXmlDoc
= parseLayoutDump();
774 // URL hyphenated for backward compatibility
775 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout[1]", "portion",
776 u
" NNNNNNNNNN NNNNNNNNNNNNNNN https://example.com/xxxxxxx/testtesttesttest/hyphen");
777 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout[2]", "portion",
778 u
"ate/testtesttest ");
781 CPPUNIT_TEST_FIXTURE(SwLayoutWriter2
, testTdf158885_compound_remain
)
783 uno::Reference
<linguistic2::XHyphenator
> xHyphenator
= LinguMgr::GetHyphenator();
784 if (!xHyphenator
->hasLocale(lang::Locale(u
"hu"_ustr
, u
"HU"_ustr
, OUString())))
787 uno::Reference
<linguistic2::XSpellChecker1
> xSpell
= LinguMgr::GetSpellChecker();
789 = LanguageTag::convertToLanguageType(lang::Locale(u
"hu"_ustr
, u
"HU"_ustr
, OUString()));
790 if (!xSpell
.is() || !xSpell
->hasLanguage(static_cast<sal_uInt16
>(eLang
)))
793 createSwDoc("tdf158885_compound-remain.fodt");
794 xmlDocUniquePtr pXmlDoc
= parseLayoutDump();
795 // hyphenate compound word with 3- or more character distance from the stem boundary
796 // This was "emberel=lenes" (now "ember=ellenes", i.e. hyphenating at the stem boundary)
797 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout[1]", "portion",
798 u
"emberellenes emberellenes emberellenes emberellenes emberellenes ember");
799 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout[2]", "portion",
800 u
"ellenes emberellenes emberellenes emberellenes emberellenes emberellenes ");
803 CPPUNIT_TEST_FIXTURE(SwLayoutWriter2
, testTdf158885_not_compound_remain
)
805 uno::Reference
<linguistic2::XHyphenator
> xHyphenator
= LinguMgr::GetHyphenator();
806 if (!xHyphenator
->hasLocale(lang::Locale(u
"hu"_ustr
, u
"HU"_ustr
, OUString())))
809 uno::Reference
<linguistic2::XSpellChecker1
> xSpell
= LinguMgr::GetSpellChecker();
811 = LanguageTag::convertToLanguageType(lang::Locale(u
"hu"_ustr
, u
"HU"_ustr
, OUString()));
812 if (!xSpell
.is() || !xSpell
->hasLanguage(static_cast<sal_uInt16
>(eLang
)))
815 createSwDoc("tdf158885_not_compound-remain.fodt");
816 xmlDocUniquePtr pXmlDoc
= parseLayoutDump();
817 // hyphenate compound word with 2-character distance from the stem boundary,
818 // resulting less readable hyphenation "emberel=lenes" ("emberel" and "lenes" have
819 // different meanings, than the original word parts)
820 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout[1]", "portion",
821 u
"emberellenes emberellenes emberellenes emberellenes emberellenes emberel");
822 assertXPath(pXmlDoc
, "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout[2]", "portion",
823 u
"lenes emberellenes emberellenes emberellenes emberellenes emberellenes ");
826 CPPUNIT_TEST_FIXTURE(SwLayoutWriter2
, testRedlineNumberInFootnote
)
828 createSwDoc("tdf85610.fodt");
829 SwDocShell
* pShell
= getSwDocShell();
831 // Dump the rendering of the first page as an XML file.
832 std::shared_ptr
<GDIMetaFile
> xMetaFile
= pShell
->GetPreviewMetaFile();
833 MetafileXmlDump dumper
;
835 xmlDocUniquePtr pXmlDoc
= dumpAndParse(dumper
, *xMetaFile
);
836 CPPUNIT_ASSERT(pXmlDoc
);
838 // changed color of numbers of footnote 1 (deleted footnote) and footnote 2 (inserted footnote)
839 // decreased the black <font> elements by 2:
841 assertXPath(pXmlDoc
, "/metafile/push/push/push/font[@color='#000000']", 5);
844 CPPUNIT_TEST_FIXTURE(SwLayoutWriter2
, testRedlineMoving
)
846 createSwDoc("tdf42748.fodt");
847 SwDoc
* pDoc
= getSwDoc();
848 SwDocShell
* pShell
= getSwDocShell();
850 // create a 3-element list without change tracking
851 SwEditShell
* const pEditShell(pDoc
->GetEditShell());
852 CPPUNIT_ASSERT(pEditShell
);
853 pEditShell
->RejectRedline(0);
854 pEditShell
->AcceptRedline(0);
856 // move down first list item with track changes
857 dispatchCommand(mxComponent
, u
".uno:GoToStartOfDoc"_ustr
, {});
858 dispatchCommand(mxComponent
, u
".uno:TrackChanges"_ustr
, {});
859 dispatchCommand(mxComponent
, u
".uno:MoveDown"_ustr
, {});
861 // Dump the rendering of the first page as an XML file.
862 std::shared_ptr
<GDIMetaFile
> xMetaFile
= pShell
->GetPreviewMetaFile();
863 MetafileXmlDump dumper
;
864 xmlDocUniquePtr pXmlDoc
= dumpAndParse(dumper
, *xMetaFile
);
865 CPPUNIT_ASSERT(pXmlDoc
);
867 // text and numbering colors show moving of the list item
868 // tdf#157663: the moved text item "It" is detected as text moving again!
869 assertXPath(pXmlDoc
, "/metafile/push/push/push/textcolor[@color='#008000']", 5);
870 assertXPath(pXmlDoc
, "/metafile/push/push/push/font[@color='#008000']", 11);
873 CPPUNIT_TEST_FIXTURE(SwLayoutWriter2
, testRedlineMoving2
)
875 createSwDoc("tdf42748.fodt");
876 SwDoc
* pDoc
= getSwDoc();
877 SwDocShell
* pShell
= getSwDocShell();
879 // create a 3-element list without change tracking
880 SwEditShell
* const pEditShell(pDoc
->GetEditShell());
881 CPPUNIT_ASSERT(pEditShell
);
882 pEditShell
->RejectRedline(0);
883 pEditShell
->AcceptRedline(0);
885 // extend the first item to "An ItemIt", because detection of move needs
886 // at least 6 characters with an inner space after stripping white spaces
888 dispatchCommand(mxComponent
, u
".uno:GoToStartOfDoc"_ustr
, {});
889 SwWrtShell
* pWrtShell
= getSwDocShell()->GetWrtShell();
890 pWrtShell
->Insert(u
"An Item"_ustr
);
892 // move down first list item with track changes
893 dispatchCommand(mxComponent
, u
".uno:TrackChanges"_ustr
, {});
894 dispatchCommand(mxComponent
, u
".uno:MoveDown"_ustr
, {});
896 // Dump the rendering of the first page as an XML file.
897 std::shared_ptr
<GDIMetaFile
> xMetaFile
= pShell
->GetPreviewMetaFile();
898 MetafileXmlDump dumper
;
899 xmlDocUniquePtr pXmlDoc
= dumpAndParse(dumper
, *xMetaFile
);
900 CPPUNIT_ASSERT(pXmlDoc
);
902 // text and numbering colors show moving of the list item
903 // These were 0 (other color, not COL_GREEN, color of the tracked text movement)
904 assertXPath(pXmlDoc
, "/metafile/push/push/push/textcolor[@color='#008000']", 5);
905 assertXPath(pXmlDoc
, "/metafile/push/push/push/font[@color='#008000']", 11);
908 CPPUNIT_TEST_FIXTURE(SwLayoutWriter2
, testRedlineMovingDOCX
)
910 createSwDoc("tdf104797.docx");
911 SwDoc
* pDoc
= getSwDoc();
912 SwDocShell
* pShell
= getSwDocShell();
914 SwEditShell
* const pEditShell(pDoc
->GetEditShell());
915 CPPUNIT_ASSERT(pEditShell
);
916 // This was 2 (moveFrom and moveTo joined other redlines)
917 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(5), pEditShell
->GetRedlineCount());
919 // Dump the rendering of the first page as an XML file.
920 std::shared_ptr
<GDIMetaFile
> xMetaFile
= pShell
->GetPreviewMetaFile();
921 MetafileXmlDump dumper
;
922 xmlDocUniquePtr pXmlDoc
= dumpAndParse(dumper
, *xMetaFile
);
923 CPPUNIT_ASSERT(pXmlDoc
);
925 // text colors show moved text
926 // These were 0 (other color, not COL_GREEN, color of the tracked text movement)
927 assertXPath(pXmlDoc
, "/metafile/push/push/push/textcolor[@color='#008000']", 6);
930 CPPUNIT_TEST_FIXTURE(SwLayoutWriter2
, testTableCellInvalidate
)
932 // note: must set Hidden property, so that SfxFrameViewWindow_Impl::Resize()
933 // does *not* forward initial VCL Window Resize and thereby triggers a
934 // layout which does not happen on soffice --convert-to pdf.
935 std::vector
<beans::PropertyValue
> aFilterOptions
= {
936 { beans::PropertyValue(u
"Hidden"_ustr
, -1, uno::Any(true),
937 beans::PropertyState_DIRECT_VALUE
) },
940 // inline the loading because currently properties can't be passed...
941 OUString
const url(createFileURL(u
"table_cell_overlap.fodt"));
942 loadWithParams(url
, comphelper::containerToSequence(aFilterOptions
));
943 save(u
"writer_pdf_Export"_ustr
);
945 xmlDocUniquePtr pXmlDoc
= parseLayoutDump();
946 // somehow these 2 rows overlapped in the PDF unless CalcLayout() runs
947 assertXPath(pXmlDoc
, "/root/page[1]/anchored/fly/tab[1]/row[1]/infos/bounds", "top", u
"6969");
948 assertXPath(pXmlDoc
, "/root/page[1]/anchored/fly/tab[1]/row[1]/infos/bounds", "height", u
"231");
949 assertXPath(pXmlDoc
, "/root/page[1]/anchored/fly/tab[1]/row[1]/cell[1]/infos/bounds", "top",
951 assertXPath(pXmlDoc
, "/root/page[1]/anchored/fly/tab[1]/row[1]/cell[1]/infos/bounds", "height",
953 assertXPath(pXmlDoc
, "/root/page[1]/anchored/fly/tab[1]/row[1]/cell[1]/txt[1]/infos/bounds",
955 assertXPath(pXmlDoc
, "/root/page[1]/anchored/fly/tab[1]/row[1]/cell[1]/txt[1]/infos/bounds",
957 assertXPath(pXmlDoc
, "/root/page[1]/anchored/fly/tab[1]/row[2]/infos/bounds", "top", u
"7200");
958 assertXPath(pXmlDoc
, "/root/page[1]/anchored/fly/tab[1]/row[2]/infos/bounds", "height", u
"231");
959 // this was 6969, causing the overlap
960 assertXPath(pXmlDoc
, "/root/page[1]/anchored/fly/tab[1]/row[2]/cell[1]/infos/bounds", "top",
962 assertXPath(pXmlDoc
, "/root/page[1]/anchored/fly/tab[1]/row[2]/cell[1]/infos/bounds", "height",
964 assertXPath(pXmlDoc
, "/root/page[1]/anchored/fly/tab[1]/row[2]/cell[1]/txt[1]/infos/bounds",
966 assertXPath(pXmlDoc
, "/root/page[1]/anchored/fly/tab[1]/row[2]/cell[1]/txt[1]/infos/bounds",
970 CPPUNIT_TEST_FIXTURE(SwLayoutWriter2
, testTdf145719
)
972 createSwDoc("tdf145719.odt");
973 SwDocShell
* pShell
= getSwDocShell();
975 // Dump the rendering of the first page as an XML file.
976 std::shared_ptr
<GDIMetaFile
> xMetaFile
= pShell
->GetPreviewMetaFile();
977 MetafileXmlDump dumper
;
978 xmlDocUniquePtr pXmlDoc
= dumpAndParse(dumper
, *xMetaFile
);
979 CPPUNIT_ASSERT(pXmlDoc
);
981 // text colors show moved text
982 // This was 0 (other color, not COL_GREEN, color of the tracked text movement)
983 assertXPath(pXmlDoc
, "/metafile/push/push/push/textcolor[@color='#008000']", 4);
986 CPPUNIT_TEST_FIXTURE(SwLayoutWriter2
, testChangedTableRows
)
988 createSwDoc("changed_table_rows.fodt");
989 SwDocShell
* pShell
= getSwDocShell();
991 // Dump the rendering of the first page as an XML file.
992 std::shared_ptr
<GDIMetaFile
> xMetaFile
= pShell
->GetPreviewMetaFile();
993 MetafileXmlDump dumper
;
994 xmlDocUniquePtr pXmlDoc
= dumpAndParse(dumper
, *xMetaFile
);
995 CPPUNIT_ASSERT(pXmlDoc
);
997 // This was 0 (other color, not COL_AUTHOR_TABLE_DEL, color of the tracked row deletion)
998 assertXPath(pXmlDoc
, "/metafile/push/push/push/push/push/fillcolor[@color='#fce6f4']", 1);
999 // This was 0 (other color, not COL_AUTHOR_TABLE_INS, color of the tracked row insertion)
1000 assertXPath(pXmlDoc
, "/metafile/push/push/push/push/push/fillcolor[@color='#e1f2fa']", 1);
1001 // This was 3 (color of the cells of the last column, 2 of them disabled by change tracking )
1002 assertXPath(pXmlDoc
, "/metafile/push/push/push/push/push/fillcolor[@color='#3faf46']", 1);
1005 CPPUNIT_TEST_FIXTURE(SwLayoutWriter2
, testTdf155187_TableInTextChange
)
1007 createSwDoc("table_in_text_change.fodt");
1008 SwDocShell
* pShell
= getSwDocShell();
1010 // Dump the rendering of the first page as an XML file.
1011 std::shared_ptr
<GDIMetaFile
> xMetaFile
= pShell
->GetPreviewMetaFile();
1012 MetafileXmlDump dumper
;
1013 xmlDocUniquePtr pXmlDoc
= dumpAndParse(dumper
, *xMetaFile
);
1014 CPPUNIT_ASSERT(pXmlDoc
);
1016 // This was 0 (other color, not COL_AUTHOR_TABLE_DEL, color of the tracked row deletion)
1017 assertXPath(pXmlDoc
, "/metafile/push/push/push/push/push/fillcolor[@color='#fce6f4']", 2);
1018 // This was 0 (other color, not COL_AUTHOR_TABLE_INS, color of the tracked row insertion)
1019 assertXPath(pXmlDoc
, "/metafile/push/push/push/push/push/fillcolor[@color='#e1f2fa']", 2);
1022 CPPUNIT_TEST_FIXTURE(SwLayoutWriter2
, testTdf145225_RedlineMovingWithBadInsertion
)
1024 createSwDoc("tdf42748.fodt");
1025 SwDoc
* pDoc
= getSwDoc();
1027 // create a 3-element list without change tracking
1028 // (because the fixed problem depends on the own changes)
1029 SwEditShell
* const pEditShell(pDoc
->GetEditShell());
1030 CPPUNIT_ASSERT(pEditShell
);
1031 pEditShell
->RejectRedline(0);
1032 pEditShell
->AcceptRedline(0);
1033 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(0), pEditShell
->GetRedlineCount());
1036 SwWrtShell
* pWrtShell
= getSwDocShell()->GetWrtShell();
1037 SwRootFrame
* pLayout(pWrtShell
->GetLayout());
1038 CPPUNIT_ASSERT(!pLayout
->IsHideRedlines());
1040 // insert a tracked paragraph break in middle of the second list item, i.e. split it
1041 dispatchCommand(mxComponent
, u
".uno:GoToStartOfDoc"_ustr
, {});
1042 dispatchCommand(mxComponent
, u
".uno:TrackChanges"_ustr
, {});
1043 // positionate the cursor in the middle of the second list item
1044 pWrtShell
->Right(SwCursorSkipMode::Chars
, /*bSelect=*/false, 4, /*bBasicCall=*/false);
1045 pWrtShell
->SplitNode(false);
1046 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(1), pEditShell
->GetRedlineCount());
1048 // move up the last list item over the paragraph split
1049 dispatchCommand(mxComponent
, u
".uno:GoToEndOfDoc"_ustr
, {});
1050 dispatchCommand(mxComponent
, u
".uno:MoveUp"_ustr
, {});
1051 dispatchCommand(mxComponent
, u
".uno:MoveUp"_ustr
, {});
1052 // This was 2 (the tracked paragraph break joined with the moved list item,
1053 // setting the not changed text of the second list item to tracked insertion)
1054 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(3), pEditShell
->GetRedlineCount());
1057 CPPUNIT_TEST_FIXTURE(SwLayoutWriter2
, testTdf146964_ReappearingMovedTextInHideChangesMode
)
1059 createSwDoc("tdf54819.fodt");
1060 SwDoc
* pDoc
= getSwDoc();
1062 // enable Record Changes
1063 dispatchCommand(mxComponent
, u
".uno:TrackChanges"_ustr
, {});
1064 CPPUNIT_ASSERT_MESSAGE("redlining should be on",
1065 pDoc
->getIDocumentRedlineAccess().IsRedlineOn());
1067 // set Hide Changes mode
1068 dispatchCommand(mxComponent
, u
".uno:ShowTrackedChanges"_ustr
, {});
1069 SwWrtShell
* pWrtShell
= getSwDocShell()->GetWrtShell();
1070 SwRootFrame
* pLayout(pWrtShell
->GetLayout());
1071 CPPUNIT_ASSERT(pLayout
->IsHideRedlines());
1073 // delete and paste the deleted word again during Track Changes
1074 dispatchCommand(mxComponent
, u
".uno:WordRightSel"_ustr
, {});
1075 dispatchCommand(mxComponent
, u
".uno:Cut"_ustr
, {});
1076 dispatchCommand(mxComponent
, u
".uno:Paste"_ustr
, {});
1078 SwEditShell
* const pEditShell(pDoc
->GetEditShell());
1079 CPPUNIT_ASSERT(pEditShell
);
1080 CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type
>(2), pEditShell
->GetRedlineCount());
1082 xmlDocUniquePtr pXmlDoc
= parseLayoutDump();
1083 CPPUNIT_ASSERT(pXmlDoc
);
1084 // This was "Lorem Lorem ipsum" (reappearing deletion in Hide Changes mode)
1085 assertXPath(pXmlDoc
, "/root/page/body/txt[1]/SwParaPortion/SwLineLayout/SwParaPortion",
1086 "portion", u
"Lorem ipsum");
1089 CPPUNIT_TEST_FIXTURE(SwLayoutWriter2
, testTdf125300
)
1091 createSwDoc("tdf125300.docx");
1092 SwDocShell
* pShell
= getSwDocShell();
1094 // Dump the rendering of the first page as an XML file.
1095 std::shared_ptr
<GDIMetaFile
> xMetaFile
= pShell
->GetPreviewMetaFile();
1096 MetafileXmlDump dumper
;
1098 xmlDocUniquePtr pXmlDoc
= dumpAndParse(dumper
, *xMetaFile
);
1099 CPPUNIT_ASSERT(pXmlDoc
);
1101 // Keep line spacing before bottom cell border (it was 1892)
1103 = getXPath(pXmlDoc
, "/metafile/push[1]/push[1]/push[1]/push[7]/polyline/point[1]", "y")
1106 = getXPath(pXmlDoc
, "/metafile/push[1]/push[1]/push[1]/push[7]/polyline/point[2]", "y")
1108 CPPUNIT_ASSERT_DOUBLES_EQUAL(2092, y1
, 7);
1109 CPPUNIT_ASSERT_EQUAL(y1
, y2
);
1112 CPPUNIT_TEST_FIXTURE(SwLayoutWriter2
, testTdf116830
)
1114 createSwDoc("tdf116830.odt");
1115 SwDocShell
* pShell
= getSwDocShell();
1117 // Dump the rendering of the first page as an XML file.
1118 std::shared_ptr
<GDIMetaFile
> xMetaFile
= pShell
->GetPreviewMetaFile();
1119 MetafileXmlDump dumper
;
1120 xmlDocUniquePtr pXmlDoc
= dumpAndParse(dumper
, *xMetaFile
);
1121 CPPUNIT_ASSERT(pXmlDoc
);
1123 // Assert that the yellow rectangle (cell background) is painted after the
1124 // polypolygon (background shape).
1125 // Background shape: 1.1.1.2
1126 // Cell background: 1.1.1.3
1129 "/metafile/push[1]/push[1]/push[1]/push[2]/push[1]/push[1]/fillcolor[@color='#729fcf']", 1);
1130 assertXPath(pXmlDoc
, "/metafile/push[1]/push[1]/push[1]/push[2]/push[1]/push[1]/polypolygon",
1133 // This failed: cell background was painted before the background shape.
1134 assertXPath(pXmlDoc
,
1135 "/metafile/push[1]/push[1]/push[1]/push[3]/push[1]/fillcolor[@color='#ffff00']", 1);
1136 assertXPath(pXmlDoc
, "/metafile/push[1]/push[1]/push[1]/push[3]/push[1]/rect", 1);
1139 CPPUNIT_TEST_FIXTURE(SwLayoutWriter2
, testTdf114163
)
1141 createSwDoc("tdf114163.odt");
1142 SwDocShell
* pShell
= getSwDocShell();
1144 // Dump the rendering of the first page as an XML file.
1145 std::shared_ptr
<GDIMetaFile
> xMetaFile
= pShell
->GetPreviewMetaFile();
1146 MetafileXmlDump dumper
;
1147 xmlDocUniquePtr pXmlDoc
= dumpAndParse(dumper
, *xMetaFile
);
1148 CPPUNIT_ASSERT(pXmlDoc
);
1150 assertXPathContent(pXmlDoc
, "(//textarray)[12]/text", u
"Data3");
1151 // This failed, if the legend first label is not "Data3". The legend position is right.
1154 CPPUNIT_TEST_FIXTURE(SwLayoutWriter2
, testTdf131707
)
1156 createSwDoc("tdf131707_flyWrap.doc");
1157 xmlDocUniquePtr pXmlDoc
= parseLayoutDump();
1159 assertXPath(pXmlDoc
, "//body/tab/row[3]/cell[2]/txt/infos/bounds", "top", u
"2185");
1160 // the image should be inside of the cell boundary - so the same top or higher
1161 assertXPath(pXmlDoc
, "//body/tab/row[3]/cell[2]/txt/anchored/fly/infos/bounds", "top", u
"2185");
1164 CPPUNIT_TEST_FIXTURE(SwLayoutWriter2
, testTdf122225
)
1166 createSwDoc("tdf122225.docx");
1167 SwDocShell
* pShell
= getSwDocShell();
1169 // Dump the rendering of the first page as an XML file.
1170 std::shared_ptr
<GDIMetaFile
> xMetaFile
= pShell
->GetPreviewMetaFile();
1171 MetafileXmlDump dumper
;
1172 xmlDocUniquePtr pXmlDoc
= dumpAndParse(dumper
, *xMetaFile
);
1173 CPPUNIT_ASSERT(pXmlDoc
);
1175 // Bug 122225 - FILEOPEN DOCX Textbox of Column chart legend reduces and text of legend disappears
1176 const sal_Int32 nLegendLabelLines
1177 = getXPathContent(pXmlDoc
, "count(//text[contains(text(),\"Advanced Diploma\")])")
1179 // This failed, if the legend label is not "Advanced Diploma".
1180 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32
>(1), nLegendLabelLines
);
1182 // Bug 140623 - Fileopen DOCX: Text Orientation of X-Axis 0 instead of 45 degrees
1183 const sal_Int32 nThirdLabelLines
1184 = getXPathContent(pXmlDoc
, "count(//text[contains(text(),\"Hispanic\")])").toInt32();
1185 // This failed, if the third X axis label broke to multiple lines.
1186 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32
>(1), nThirdLabelLines
);
1189 CPPUNIT_TEST_FIXTURE(SwLayoutWriter2
, testTdf125335
)
1191 createSwDoc("tdf125335.odt");
1192 SwDocShell
* pShell
= getSwDocShell();
1194 // Dump the rendering of the first page as an XML file.
1195 std::shared_ptr
<GDIMetaFile
> xMetaFile
= pShell
->GetPreviewMetaFile();
1196 MetafileXmlDump dumper
;
1197 xmlDocUniquePtr pXmlDoc
= dumpAndParse(dumper
, *xMetaFile
);
1198 CPPUNIT_ASSERT(pXmlDoc
);
1200 assertXPathContent(pXmlDoc
, "(//textarray)[12]/text", u
"Data3");
1201 // This failed, if the legend first label is not "Data3". The legend position is bottom.
1204 CPPUNIT_TEST_FIXTURE(SwLayoutWriter2
, testTdf134247
)
1206 createSwDoc("legend-itemorder-min.docx");
1207 SwDocShell
* pShell
= getSwDocShell();
1209 // Dump the rendering of the first page as an XML file.
1210 std::shared_ptr
<GDIMetaFile
> xMetaFile
= pShell
->GetPreviewMetaFile();
1211 MetafileXmlDump dumper
;
1212 xmlDocUniquePtr pXmlDoc
= dumpAndParse(dumper
, *xMetaFile
);
1213 CPPUNIT_ASSERT(pXmlDoc
);
1215 assertXPathContent(pXmlDoc
, "(//textarray)[14]/text", u
"1. adatsor");
1216 // This failed, if the legend first label is not "1. adatsor".
1219 CPPUNIT_TEST_FIXTURE(SwLayoutWriter2
, testTdf75659
)
1221 createSwDoc("tdf75659.docx");
1222 SwDocShell
* pShell
= getSwDocShell();
1224 // Dump the rendering of the first page as an XML file.
1225 std::shared_ptr
<GDIMetaFile
> xMetaFile
= pShell
->GetPreviewMetaFile();
1226 MetafileXmlDump dumper
;
1227 xmlDocUniquePtr pXmlDoc
= dumpAndParse(dumper
, *xMetaFile
);
1228 CPPUNIT_ASSERT(pXmlDoc
);
1230 assertXPathContent(pXmlDoc
, "(//textarray)[17]/text", u
"Series1");
1231 assertXPathContent(pXmlDoc
, "(//textarray)[18]/text", u
"Series2");
1232 assertXPathContent(pXmlDoc
, "(//textarray)[19]/text", u
"Series3");
1233 // These failed, if the legend names are empty strings.
1236 CPPUNIT_TEST_FIXTURE(SwLayoutWriter2
, testTdf136816
)
1238 createSwDoc("tdf136816.odt");
1239 SwDocShell
* pShell
= getSwDocShell();
1241 // Dump the rendering of the first page as an XML file.
1242 std::shared_ptr
<GDIMetaFile
> xMetaFile
= pShell
->GetPreviewMetaFile();
1243 MetafileXmlDump dumper
;
1244 xmlDocUniquePtr pXmlDoc
= dumpAndParse(dumper
, *xMetaFile
);
1245 CPPUNIT_ASSERT(pXmlDoc
);
1247 // Check number of legend entries
1248 assertXPath(pXmlDoc
, "//text[contains(text(),\"Column\")]", 2);
1251 CPPUNIT_TEST_FIXTURE(SwLayoutWriter2
, testTdf126425
)
1253 createSwDoc("long_legendentry.docx");
1254 SwDocShell
* pShell
= getSwDocShell();
1256 // Dump the rendering of the first page as an XML file.
1257 std::shared_ptr
<GDIMetaFile
> xMetaFile
= pShell
->GetPreviewMetaFile();
1258 MetafileXmlDump dumper
;
1259 xmlDocUniquePtr pXmlDoc
= dumpAndParse(dumper
, *xMetaFile
);
1260 CPPUNIT_ASSERT(pXmlDoc
);
1261 // Without the accompanying fix in place, this test would have failed with:
1264 // i.e. the text of the chart legend lost.
1265 assertXPath(pXmlDoc
, "//textarray", 14);
1268 CPPUNIT_TEST_FIXTURE(SwLayoutWriter2
, testUnusedOLEprops
)
1270 createSwDoc("tdf138465min.docx");
1272 xmlDocUniquePtr pXmlDoc
= parseLayoutDump();
1273 CPPUNIT_ASSERT(pXmlDoc
);
1274 // Without the accompanying fix in place, this test would have failed with:
1277 // i.e. the formula squashed
1278 CPPUNIT_ASSERT_GREATEREQUAL(
1280 getXPath(pXmlDoc
, "/root/page/body/txt[2]/anchored/fly/notxt/infos/bounds", "height")
1284 CPPUNIT_TEST_FIXTURE(SwLayoutWriter2
, testTdf123268
)
1286 createSwDoc("tdf123268.odt");
1287 SwDocShell
* pShell
= getSwDocShell();
1289 // Dump the rendering of the first page as an XML file.
1290 std::shared_ptr
<GDIMetaFile
> xMetaFile
= pShell
->GetPreviewMetaFile();
1291 MetafileXmlDump dumper
;
1292 xmlDocUniquePtr pXmlDoc
= dumpAndParse(dumper
, *xMetaFile
);
1293 CPPUNIT_ASSERT(pXmlDoc
);
1294 // Without the accompanying fix in place, this test would have failed with:
1297 // i.e. the chart lost.
1298 assertXPath(pXmlDoc
, "/metafile/push[1]/push[1]/push[1]/push[3]/push[1]/push[1]/push[1]/push",
1302 CPPUNIT_TEST_FIXTURE(SwLayoutWriter2
, testTdf133005
)
1304 createSwDoc("tdf133005.odt");
1305 SwDocShell
* pShell
= getSwDocShell();
1307 // Dump the rendering of the first page as an XML file.
1308 std::shared_ptr
<GDIMetaFile
> xMetaFile
= pShell
->GetPreviewMetaFile();
1309 MetafileXmlDump dumper
;
1310 xmlDocUniquePtr pXmlDoc
= dumpAndParse(dumper
, *xMetaFile
);
1311 CPPUNIT_ASSERT(pXmlDoc
);
1313 sal_Int32 nXChartWall
= getXPath(pXmlDoc
,
1314 "/metafile/push[1]/push[1]/push[1]/push[3]/push[1]/push[1]/"
1315 "push[1]/push[1]/polyline[1]/point[2]",
1318 sal_Int32 nXColumn
= getXPath(pXmlDoc
,
1319 "/metafile/push[1]/push[1]/push[1]/push[3]/push[1]/push[1]/"
1320 "push[1]/push[41]/polypolygon/polygon/point[1]",
1324 // This failed, if the value axis doesn't appear inside category.
1325 CPPUNIT_ASSERT_DOUBLES_EQUAL(nXChartWall
, nXColumn
, 5);
1328 CPPUNIT_TEST_FIXTURE(SwLayoutWriter2
, testTdf115630
)
1330 createSwDoc("tdf115630.docx");
1331 SwDocShell
* pShell
= getSwDocShell();
1333 // Dump the rendering of the first page as an XML file.
1334 std::shared_ptr
<GDIMetaFile
> xMetaFile
= pShell
->GetPreviewMetaFile();
1335 MetafileXmlDump dumper
;
1336 xmlDocUniquePtr pXmlDoc
= dumpAndParse(dumper
, *xMetaFile
);
1337 CPPUNIT_ASSERT(pXmlDoc
);
1339 // Test wide of inner chart area.
1342 "/metafile/push[1]/push[1]/push[1]/push[6]/push[1]/push[3]/polyline[1]/point[1]",
1347 "/metafile/push[1]/push[1]/push[1]/push[6]/push[1]/push[3]/polyline[1]/point[2]",
1350 CPPUNIT_ASSERT_DOUBLES_EQUAL(2895, nXRight
- nXLeft
, 50);
1353 CPPUNIT_TEST_FIXTURE(SwLayoutWriter2
, testTdf108021
)
1355 createSwDoc("tdf108021.odt");
1356 SwDocShell
* pShell
= getSwDocShell();
1358 // Dump the rendering of the first page as an XML file.
1359 std::shared_ptr
<GDIMetaFile
> xMetaFile
= pShell
->GetPreviewMetaFile();
1360 MetafileXmlDump dumper
;
1361 xmlDocUniquePtr pXmlDoc
= dumpAndParse(dumper
, *xMetaFile
);
1362 CPPUNIT_ASSERT(pXmlDoc
);
1364 assertXPath(pXmlDoc
, "//textarray[@length='22']", 8);
1365 // This failed, if the textarray length of the first axis label not 22.
1368 CPPUNIT_TEST_FIXTURE(SwLayoutWriter2
, testTdf125334
)
1370 createSwDoc("tdf125334.odt");
1371 SwDocShell
* pShell
= getSwDocShell();
1373 // Dump the rendering of the first page as an XML file.
1374 std::shared_ptr
<GDIMetaFile
> xMetaFile
= pShell
->GetPreviewMetaFile();
1375 MetafileXmlDump dumper
;
1376 xmlDocUniquePtr pXmlDoc
= dumpAndParse(dumper
, *xMetaFile
);
1377 CPPUNIT_ASSERT(pXmlDoc
);
1379 int nCount
= countXPathNodes(pXmlDoc
, "//textarray[@length='17']");
1380 CPPUNIT_ASSERT_EQUAL(4, nCount
);
1381 // This failed, if the textarray length of the category axis label not 17.
1384 CPPUNIT_TEST_FIXTURE(SwLayoutWriter2
, testTdf122800
)
1386 createSwDoc("tdf122800.odt");
1387 SwDocShell
* pShell
= getSwDocShell();
1389 // Dump the rendering of the first page as an XML file.
1390 std::shared_ptr
<GDIMetaFile
> xMetaFile
= pShell
->GetPreviewMetaFile();
1391 MetafileXmlDump dumper
;
1392 xmlDocUniquePtr pXmlDoc
= dumpAndParse(dumper
, *xMetaFile
);
1393 CPPUNIT_ASSERT(pXmlDoc
);
1395 assertXPath(pXmlDoc
, "//textarray[@length='22']", 9);
1396 // This failed, if the textarray length of the first axis label not 22.
1399 CPPUNIT_TEST_FIXTURE(SwLayoutWriter2
, testTruncatedAxisLabel
)
1401 createSwDoc("testTruncatedAxisLabel.odt");
1402 SwDocShell
* pShell
= getSwDocShell();
1404 // Dump the rendering of the first page as an XML file.
1405 std::shared_ptr
<GDIMetaFile
> xMetaFile
= pShell
->GetPreviewMetaFile();
1406 MetafileXmlDump dumper
;
1407 xmlDocUniquePtr pXmlDoc
= dumpAndParse(dumper
, *xMetaFile
);
1408 CPPUNIT_ASSERT(pXmlDoc
);
1410 // test the X axis label visibility
1411 assertXPathContent(pXmlDoc
, "(//textarray)[1]/text", u
"Long axis label truncated 1");
1413 // test the Y axis label visibility
1414 assertXPathContent(pXmlDoc
, "(//textarray)[3]/text", u
"-5.00");
1417 CPPUNIT_TEST_FIXTURE(SwLayoutWriter2
, testTdf128996
)
1419 createSwDoc("tdf128996.docx");
1420 SwDocShell
* pShell
= getSwDocShell();
1422 // Dump the rendering of the first page as an XML file.
1423 std::shared_ptr
<GDIMetaFile
> xMetaFile
= pShell
->GetPreviewMetaFile();
1424 MetafileXmlDump dumper
;
1425 xmlDocUniquePtr pXmlDoc
= dumpAndParse(dumper
, *xMetaFile
);
1426 CPPUNIT_ASSERT(pXmlDoc
);
1428 assertXPathContent(pXmlDoc
, "(//textarray)[1]/text", u
"A very long category name 1");
1431 CPPUNIT_TEST_FIXTURE(SwLayoutWriter2
, testTdf126244
)
1433 createSwDoc("tdf126244.docx");
1434 SwDocShell
* pShell
= getSwDocShell();
1436 // Dump the rendering of the first page as an XML file.
1437 std::shared_ptr
<GDIMetaFile
> xMetaFile
= pShell
->GetPreviewMetaFile();
1438 MetafileXmlDump dumper
;
1439 xmlDocUniquePtr pXmlDoc
= dumpAndParse(dumper
, *xMetaFile
);
1440 CPPUNIT_ASSERT(pXmlDoc
);
1441 // Test the first level of vertical category axis labels orientation. The first level orientation should be horizontal.
1442 assertXPath(pXmlDoc
, "(//font)[1]", "orientation", u
"0");
1443 // Test the second level of vertical category axis labels orientation. The second level orientation should be vertical.
1444 sal_Int32 nRotation
= getXPath(pXmlDoc
, "(//font)[5]", "orientation").toInt32();
1445 CPPUNIT_ASSERT(nRotation
>= 899);
1446 CPPUNIT_ASSERT(nRotation
<= 900);
1447 // Test the third level of vertical category axis labels orientation. The third level orientation should be vertical.
1448 nRotation
= getXPath(pXmlDoc
, "(//font)[7]", "orientation").toInt32();
1449 CPPUNIT_ASSERT(nRotation
>= 899);
1450 CPPUNIT_ASSERT(nRotation
<= 900);
1453 CPPUNIT_TEST_FIXTURE(SwLayoutWriter2
, testTdf127304
)
1455 createSwDoc("tdf127304.odt");
1456 SwDocShell
* pShell
= getSwDocShell();
1458 // Dump the rendering of the first page as an XML file.
1459 std::shared_ptr
<GDIMetaFile
> xMetaFile
= pShell
->GetPreviewMetaFile();
1460 MetafileXmlDump dumper
;
1461 xmlDocUniquePtr pXmlDoc
= dumpAndParse(dumper
, *xMetaFile
);
1462 CPPUNIT_ASSERT(pXmlDoc
);
1463 // Test the first level of horizontal category axis labels orientation. The first level orientation should be vertical.
1464 sal_Int32 nRotation
= getXPath(pXmlDoc
, "(//font)[1]", "orientation").toInt32();
1465 CPPUNIT_ASSERT(nRotation
>= 899);
1466 CPPUNIT_ASSERT(nRotation
<= 900);
1467 // Test the second level of horizontal category axis labels orientation. The second level orientation should be horizontal.
1468 assertXPath(pXmlDoc
, "(//font)[5]", "orientation", u
"0");
1469 // Test the third level of horizontal category axis labels orientation. The third level orientation should be horizontal.
1470 assertXPath(pXmlDoc
, "(//font)[7]", "orientation", u
"0");
1473 CPPUNIT_TEST_FIXTURE(SwLayoutWriter2
, testHorizontal_multilevel
)
1475 createSwDoc("horizontal_multilevel.odt");
1476 SwDocShell
* pShell
= getSwDocShell();
1478 // Dump the rendering of the first page as an XML file.
1479 std::shared_ptr
<GDIMetaFile
> xMetaFile
= pShell
->GetPreviewMetaFile();
1480 MetafileXmlDump dumper
;
1481 xmlDocUniquePtr pXmlDoc
= dumpAndParse(dumper
, *xMetaFile
);
1482 CPPUNIT_ASSERT(pXmlDoc
);
1483 // Test the Y position of horizontal category axis label.
1484 sal_Int32 nYposition
= getXPath(pXmlDoc
, "(//textarray)[7]", "y").toInt32();
1485 CPPUNIT_ASSERT_DOUBLES_EQUAL(11248, nYposition
, 20);
1488 CPPUNIT_TEST_FIXTURE(SwLayoutWriter2
, testTdf69648
)
1490 createSwDoc("tdf69648.docx");
1491 xmlDocUniquePtr pXmlDoc
= parseLayoutDump();
1492 CPPUNIT_ASSERT(pXmlDoc
);
1494 const char* sShapeXPath
[2] = {
1495 "/root/page/body/txt/anchored/SwAnchoredDrawObject/SdrObjGroup/SdrObjList/SdrObject[1]",
1496 "/root/page/body/txt/anchored/SwAnchoredDrawObject/SdrObjGroup/SdrObjList/SdrObject[2]"
1498 const char* sFrameXPath
[2] = { "/root/page/body/txt/anchored/fly[1]/infos/bounds",
1499 "/root/page/body/txt/anchored/fly[2]/infos/bounds" };
1501 for (int i
= 0; i
< 2; ++i
)
1503 const auto sDrawRect
= getXPath(pXmlDoc
, sShapeXPath
[i
], "aOutRect");
1504 const auto nComaPos1
= sDrawRect
.indexOf(',', 0);
1505 const auto nComaPos2
= sDrawRect
.indexOf(',', nComaPos1
+ 1);
1506 const auto nComaPos3
= sDrawRect
.indexOf(',', nComaPos2
+ 1);
1508 const auto nDraw1
= o3tl::toInt64(sDrawRect
.subView(0, nComaPos1
));
1509 const auto nDraw2
= o3tl::toInt64(sDrawRect
.subView(nComaPos1
+ 1, nComaPos2
- nComaPos1
));
1510 const auto nDraw3
= o3tl::toInt64(sDrawRect
.subView(nComaPos2
+ 1, nComaPos3
- nComaPos2
));
1511 const auto nDraw4
= o3tl::toInt64(
1512 sDrawRect
.subView(nComaPos3
+ 1, sDrawRect
.getLength() - nComaPos3
- 1));
1513 const auto aChildShape
= SwRect(nDraw1
, nDraw2
, nDraw3
, nDraw4
);
1515 const auto nFlyLeft
= getXPath(pXmlDoc
, sFrameXPath
[i
], "left").toInt64();
1516 const auto nFlyTop
= getXPath(pXmlDoc
, sFrameXPath
[i
], "top").toInt64();
1517 const auto nFlyWidth
= getXPath(pXmlDoc
, sFrameXPath
[i
], "width").toInt64();
1518 const auto nFlyHeight
= getXPath(pXmlDoc
, sFrameXPath
[i
], "height").toInt64();
1520 const auto aFrame
= SwRect(nFlyLeft
, nFlyTop
, nFlyWidth
, nFlyHeight
);
1522 CPPUNIT_ASSERT_MESSAGE("Textbox must be inside the shape!", aChildShape
.Contains(aFrame
));
1526 CPPUNIT_TEST_FIXTURE(SwLayoutWriter2
, testTdf116256
)
1529 createSwDoc("tdf116256.docx");
1532 uno::Reference
<beans::XPropertySet
> xTextBox(getShape(2), uno::UNO_QUERY_THROW
);
1534 // Ensure that is a real textbox, and follows the text flow
1535 CPPUNIT_ASSERT(xTextBox
->getPropertyValue(u
"TextBox"_ustr
).get
<bool>());
1536 CPPUNIT_ASSERT(xTextBox
->getPropertyValue(u
"IsFollowingTextFlow"_ustr
).get
<bool>());
1539 auto pLayout
= parseLayoutDump();
1540 // Get the position of the shape
1541 const auto nCellLeft
1542 = getXPath(pLayout
, "//page/body/txt/anchored/fly/tab/row[1]/cell/infos/bounds", "left")
1545 = getXPath(pLayout
, "//page/body/txt/anchored/fly/tab/row[1]/cell/infos/bounds", "top")
1547 // Get the position of the textframe too.
1548 const auto nTextBoxFrameLeft
1550 "/root/page/body/txt/anchored/fly/tab/row[1]/cell/txt/anchored/fly/infos/bounds",
1553 const auto nTextBoxFrameTop
1555 "/root/page/body/txt/anchored/fly/tab/row[1]/cell/txt/anchored/fly/infos/bounds",
1559 // Without the fix in place these were less than they supposed to.
1560 CPPUNIT_ASSERT_GREATEREQUAL(nCellLeft
, nTextBoxFrameLeft
);
1561 CPPUNIT_ASSERT_GREATEREQUAL(nCellTop
, nTextBoxFrameTop
);
1564 CPPUNIT_PLUGIN_IMPLEMENT();
1566 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */