tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / sw / qa / extras / layout / layout2.cxx
blob5dc1e6fff241d036acd49ca990225ebe4bb75fa4
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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/.
8 */
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>
23 #include <wrtsh.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
31 public:
32 SwLayoutWriter2()
33 : SwModelTestBase(u"/sw/qa/extras/layout/data/"_ustr)
37 protected:
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]",
59 "portion", u"foo");
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]",
63 "portion", u"baz");
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]",
68 "portion", u"foo");
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]",
72 "portion", u"baz");
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]",
77 "portion", u"foo");
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]",
81 "portion", u"baz");
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]",
86 "portion", u"foo");
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]",
90 "portion", u"baz");
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]",
95 "portion", u"foo");
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]",
99 "portion", u"baz");
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]",
104 "portion", u"foo");
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]",
108 "portion", u"baz");
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]",
118 "portion", u"fo");
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]",
122 "portion", u"ob");
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]",
126 "portion", u"az");
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",
150 "height", u"5797");
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",
171 "height", u"5797");
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",
190 "height", u"5797");
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",
206 "height", u"5797");
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());
219 // verify after load
220 CheckRedlineCharAttributesHidden();
222 dispatchCommand(mxComponent, u".uno:ShowTrackedChanges"_ustr, {});
223 CPPUNIT_ASSERT(!pLayout->IsHideRedlines());
224 // why is this needed explicitly?
225 calcLayout();
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]",
233 "portion", u"foo");
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]",
237 "portion", u"bar");
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]",
241 "portion", u"baz");
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]",
245 "portion", u"foo");
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]",
249 "portion", u"bar");
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]",
253 "portion", u"baz");
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]",
257 "portion", u"foo");
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]",
261 "portion", u"bar");
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]",
265 "portion", u"baz");
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]",
269 "portion", u"foo");
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]",
273 "portion", u"bar");
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]",
277 "portion", u"baz");
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]",
281 "portion", u"foo");
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]",
285 "portion", u"bar");
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]",
289 "portion", u"baz");
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]",
293 "portion", u"foo");
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]",
297 "portion", u"bar");
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]",
301 "portion", u"baz");
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]",
305 "portion", u"foo");
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]",
309 "portion", u"bar");
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]",
313 "portion", u"baz");
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]",
317 "portion", u"foo");
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]",
321 "portion", u"ba");
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]",
325 "portion", u"r");
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]",
329 "portion", u"baz");
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]",
333 "portion", u"foo");
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]",
337 "portion", u"bar");
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]",
341 "portion", u"baz");
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]",
345 "portion", u"fo");
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]",
349 "portion", u"o");
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]",
353 "portion", u"bar");
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]",
357 "portion", u"b");
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]",
361 "portion", u"az");
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]",
365 "portion", u"foo");
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]",
369 "portion", u"b");
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]",
373 "portion", u"a");
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]",
377 "portion", u"r");
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]",
381 "portion", u"baz");
383 // verify after hide
384 dispatchCommand(mxComponent, u".uno:ShowTrackedChanges"_ustr, {});
385 CPPUNIT_ASSERT(pLayout->IsHideRedlines());
386 // why is this needed explicitly?
387 calcLayout();
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();
400 // check footnotes
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()]",
405 "portion",
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();
423 // check footnotes
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()]",
428 "portion",
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)
436 // Open the bugdoc
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);
449 calcLayout();
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",
478 u"Lorem ");
479 assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion/SwLineLayout/child::*[3]", "portion",
480 u"ipsum dolor et ");
481 assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion/SwLineLayout/child::*[5]", "portion",
482 u"ames");
483 assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion/SwLineLayout/child::*[7]", "portion",
484 u".");
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
536 assertXPath(
537 pXmlDoc,
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");
591 // Show Changes
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
611 // This was "1."
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
619 pWrtShell->Undo();
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");
631 // Show Changes
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)");
653 // This was "b)[2.]"
654 assertXPathContent(pXmlDoc, "/metafile/push/push/push/textarray[4]/text", u"b)[a)] ");
655 // This was "c)[3.]"
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
661 pWrtShell->Undo();
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.");
669 // check Redo
670 pWrtShell->Redo();
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())))
770 return;
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())))
785 return;
787 uno::Reference<linguistic2::XSpellChecker1> xSpell = LinguMgr::GetSpellChecker();
788 LanguageType eLang
789 = LanguageTag::convertToLanguageType(lang::Locale(u"hu"_ustr, u"HU"_ustr, OUString()));
790 if (!xSpell.is() || !xSpell->hasLanguage(static_cast<sal_uInt16>(eLang)))
791 return;
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())))
807 return;
809 uno::Reference<linguistic2::XSpellChecker1> xSpell = LinguMgr::GetSpellChecker();
810 LanguageType eLang
811 = LanguageTag::convertToLanguageType(lang::Locale(u"hu"_ustr, u"HU"_ustr, OUString()));
812 if (!xSpell.is() || !xSpell->hasLanguage(static_cast<sal_uInt16>(eLang)))
813 return;
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:
840 // This was 7
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
887 // of the redline
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",
950 u"6969");
951 assertXPath(pXmlDoc, "/root/page[1]/anchored/fly/tab[1]/row[1]/cell[1]/infos/bounds", "height",
952 u"231");
953 assertXPath(pXmlDoc, "/root/page[1]/anchored/fly/tab[1]/row[1]/cell[1]/txt[1]/infos/bounds",
954 "top", u"6969");
955 assertXPath(pXmlDoc, "/root/page[1]/anchored/fly/tab[1]/row[1]/cell[1]/txt[1]/infos/bounds",
956 "height", u"231");
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",
961 u"7200");
962 assertXPath(pXmlDoc, "/root/page[1]/anchored/fly/tab[1]/row[2]/cell[1]/infos/bounds", "height",
963 u"231");
964 assertXPath(pXmlDoc, "/root/page[1]/anchored/fly/tab[1]/row[2]/cell[1]/txt[1]/infos/bounds",
965 "top", u"7200");
966 assertXPath(pXmlDoc, "/root/page[1]/anchored/fly/tab[1]/row[2]/cell[1]/txt[1]/infos/bounds",
967 "height", u"231");
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());
1035 // Show Changes
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)
1102 sal_Int32 y1
1103 = getXPath(pXmlDoc, "/metafile/push[1]/push[1]/push[1]/push[7]/polyline/point[1]", "y")
1104 .toInt32();
1105 sal_Int32 y2
1106 = getXPath(pXmlDoc, "/metafile/push[1]/push[1]/push[1]/push[7]/polyline/point[2]", "y")
1107 .toInt32();
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
1127 assertXPath(
1128 pXmlDoc,
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\")])")
1178 .toInt32();
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:
1262 // - Expected: 14
1263 // - Actual : 12
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:
1275 // - Expected: >300
1276 // - Actual : 142
1277 // i.e. the formula squashed
1278 CPPUNIT_ASSERT_GREATEREQUAL(
1279 double(300),
1280 getXPath(pXmlDoc, "/root/page/body/txt[2]/anchored/fly/notxt/infos/bounds", "height")
1281 .toDouble());
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:
1295 // - Expected: 53
1296 // - Actual : 0
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",
1299 53);
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]",
1316 "x")
1317 .toInt32();
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]",
1321 "x")
1322 .toInt32();
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.
1340 sal_Int32 nXRight
1341 = getXPath(pXmlDoc,
1342 "/metafile/push[1]/push[1]/push[1]/push[6]/push[1]/push[3]/polyline[1]/point[1]",
1343 "x")
1344 .toInt32();
1345 sal_Int32 nXLeft
1346 = getXPath(pXmlDoc,
1347 "/metafile/push[1]/push[1]/push[1]/push[6]/push[1]/push[3]/polyline[1]/point[2]",
1348 "x")
1349 .toInt32();
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)
1528 // Open bugdoc
1529 createSwDoc("tdf116256.docx");
1531 // Get the textbox
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>());
1538 // Parse the layout
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")
1543 .toInt64();
1544 const auto nCellTop
1545 = getXPath(pLayout, "//page/body/txt/anchored/fly/tab/row[1]/cell/infos/bounds", "top")
1546 .toInt64();
1547 // Get the position of the textframe too.
1548 const auto nTextBoxFrameLeft
1549 = getXPath(pLayout,
1550 "/root/page/body/txt/anchored/fly/tab/row[1]/cell/txt/anchored/fly/infos/bounds",
1551 "left")
1552 .toInt64();
1553 const auto nTextBoxFrameTop
1554 = getXPath(pLayout,
1555 "/root/page/body/txt/anchored/fly/tab/row[1]/cell/txt/anchored/fly/infos/bounds",
1556 "top")
1557 .toInt64();
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: */