Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : */
9 :
10 : #include <com/sun/star/awt/FontWeight.hpp>
11 : #include <com/sun/star/drawing/GraphicExportFilter.hpp>
12 : #include <com/sun/star/i18n/TextConversionOption.hpp>
13 : #include <swmodeltestbase.hxx>
14 : #include <ndtxt.hxx>
15 : #include <wrtsh.hxx>
16 : #include <crsskip.hxx>
17 : #include <shellio.hxx>
18 : #include <expfld.hxx>
19 : #include <drawdoc.hxx>
20 : #include <docary.hxx>
21 : #include <redline.hxx>
22 : #include <section.hxx>
23 : #include <fmtclds.hxx>
24 : #include <dcontact.hxx>
25 : #include <textboxhelper.hxx>
26 : #include <view.hxx>
27 : #include <hhcwrp.hxx>
28 : #include <swacorr.hxx>
29 : #include <swmodule.hxx>
30 : #include <modcfg.hxx>
31 : #include <charatr.hxx>
32 : #include <editeng/acorrcfg.hxx>
33 : #include <unotools/streamwrap.hxx>
34 : #include <test/mtfxmldump.hxx>
35 : #include <unocrsr.hxx>
36 :
37 : #include <svx/svdpage.hxx>
38 : #include <svx/svdview.hxx>
39 :
40 : #include <editeng/eeitem.hxx>
41 : #include <editeng/scripttypeitem.hxx>
42 : #include <editeng/fontitem.hxx>
43 : #include <editeng/wghtitem.hxx>
44 :
45 : #include "UndoManager.hxx"
46 :
47 : #include <com/sun/star/lang/Locale.hpp>
48 : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
49 : #include <com/sun/star/util/SearchOptions.hpp>
50 : #include <com/sun/star/util/SearchFlags.hpp>
51 : #include "com/sun/star/util/SearchAlgorithms.hpp"
52 : #include "com/sun/star/i18n/TransliterationModulesExtra.hpp"
53 : #include "com/sun/star/sdbcx/XTablesSupplier.hpp"
54 : #include <osl/file.hxx>
55 :
56 : static const char* DATA_DIRECTORY = "/sw/qa/extras/uiwriter/data/";
57 :
58 117 : class SwUiWriterTest : public SwModelTestBase
59 : {
60 :
61 : public:
62 : void testReplaceForward();
63 : //Regression test of fdo#70143
64 : //EDITING: undo search&replace corrupt text when searching backward
65 : void testReplaceBackward();
66 : void testFdo69893();
67 : void testFdo70807();
68 : void testImportRTF();
69 : void testExportRTF();
70 : void testFdo75110();
71 : void testFdo75898();
72 : void testFdo74981();
73 : void testShapeTextboxSelect();
74 : void testShapeTextboxDelete();
75 : void testCp1000071();
76 : void testShapeTextboxVertadjust();
77 : void testShapeTextboxAutosize();
78 : void testFdo82191();
79 : void testCommentedWord();
80 : void testChineseConversionBlank();
81 : void testChineseConversionNonChineseText();
82 : void testChineseConversionTraditionalToSimplified();
83 : void testChineseConversionSimplifiedToTraditional();
84 : void testFdo85554();
85 : void testAutoCorr();
86 : void testMergeDoc();
87 : void testCreatePortions();
88 : void testBookmarkUndo();
89 : void testFdo85876();
90 : void testFdo87448();
91 : void testTdf68183();
92 : void testCp1000115();
93 : void testTdf90003();
94 : void testExportToPicture();
95 : void testSearchWithTransliterate();
96 : void testTableBackgroundColor();
97 : void testTdf90362();
98 : void testUndoCharAttribute();
99 : void testTdf86639();
100 : void testTdf90883TableBoxGetCoordinates();
101 : void testEmbeddedDataSource();
102 : void testUnoCursorPointer();
103 :
104 2 : CPPUNIT_TEST_SUITE(SwUiWriterTest);
105 1 : CPPUNIT_TEST(testReplaceForward);
106 1 : CPPUNIT_TEST(testReplaceBackward);
107 1 : CPPUNIT_TEST(testFdo69893);
108 1 : CPPUNIT_TEST(testFdo70807);
109 1 : CPPUNIT_TEST(testImportRTF);
110 1 : CPPUNIT_TEST(testExportRTF);
111 1 : CPPUNIT_TEST(testFdo75110);
112 1 : CPPUNIT_TEST(testFdo75898);
113 1 : CPPUNIT_TEST(testFdo74981);
114 1 : CPPUNIT_TEST(testShapeTextboxSelect);
115 1 : CPPUNIT_TEST(testShapeTextboxDelete);
116 1 : CPPUNIT_TEST(testCp1000071);
117 1 : CPPUNIT_TEST(testShapeTextboxVertadjust);
118 1 : CPPUNIT_TEST(testShapeTextboxAutosize);
119 1 : CPPUNIT_TEST(testFdo82191);
120 1 : CPPUNIT_TEST(testCommentedWord);
121 1 : CPPUNIT_TEST(testChineseConversionBlank);
122 1 : CPPUNIT_TEST(testChineseConversionNonChineseText);
123 1 : CPPUNIT_TEST(testChineseConversionTraditionalToSimplified);
124 1 : CPPUNIT_TEST(testChineseConversionSimplifiedToTraditional);
125 1 : CPPUNIT_TEST(testFdo85554);
126 1 : CPPUNIT_TEST(testAutoCorr);
127 1 : CPPUNIT_TEST(testMergeDoc);
128 1 : CPPUNIT_TEST(testCreatePortions);
129 1 : CPPUNIT_TEST(testBookmarkUndo);
130 1 : CPPUNIT_TEST(testFdo85876);
131 1 : CPPUNIT_TEST(testFdo87448);
132 1 : CPPUNIT_TEST(testTdf68183);
133 1 : CPPUNIT_TEST(testCp1000115);
134 1 : CPPUNIT_TEST(testTdf90003);
135 1 : CPPUNIT_TEST(testExportToPicture);
136 1 : CPPUNIT_TEST(testSearchWithTransliterate);
137 1 : CPPUNIT_TEST(testTableBackgroundColor);
138 1 : CPPUNIT_TEST(testTdf90362);
139 1 : CPPUNIT_TEST(testUndoCharAttribute);
140 1 : CPPUNIT_TEST(testTdf86639);
141 1 : CPPUNIT_TEST(testTdf90883TableBoxGetCoordinates);
142 1 : CPPUNIT_TEST(testEmbeddedDataSource);
143 1 : CPPUNIT_TEST(testUnoCursorPointer);
144 5 : CPPUNIT_TEST_SUITE_END();
145 :
146 : private:
147 : SwDoc* createDoc(const char* pName = 0);
148 : };
149 :
150 35 : SwDoc* SwUiWriterTest::createDoc(const char* pName)
151 : {
152 35 : if (!pName)
153 17 : pName = "empty.odt";
154 35 : load(DATA_DIRECTORY, pName);
155 :
156 35 : SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument *>(mxComponent.get());
157 35 : CPPUNIT_ASSERT(pTextDoc);
158 35 : return pTextDoc->GetDocShell()->GetDoc();
159 : }
160 :
161 : //Replacement tests
162 :
163 2 : static void lcl_selectCharacters(SwPaM& rPaM, sal_Int32 first, sal_Int32 end)
164 : {
165 2 : rPaM.GetPoint()->nContent.Assign(rPaM.GetContentNode(), first);
166 2 : rPaM.SetMark();
167 2 : rPaM.GetPoint()->nContent.Assign(rPaM.GetContentNode(), end);
168 2 : }
169 :
170 1 : static const OUString ORIGINAL_REPLACE_CONTENT("toto titi tutu");
171 1 : static const OUString EXPECTED_REPLACE_CONTENT("toto toto tutu");
172 :
173 1 : void SwUiWriterTest::testReplaceForward()
174 : {
175 1 : SwDoc* pDoc = createDoc();
176 :
177 1 : sw::UndoManager& rUndoManager = pDoc->GetUndoManager();
178 :
179 1 : SwNodeIndex aIdx(pDoc->GetNodes().GetEndOfContent(), -1);
180 2 : SwPaM aPaM(aIdx);
181 :
182 1 : pDoc->getIDocumentContentOperations().InsertString(aPaM, ORIGINAL_REPLACE_CONTENT);
183 :
184 1 : SwTextNode* pTextNode = aPaM.GetNode().GetTextNode();
185 1 : lcl_selectCharacters(aPaM, 5, 9);
186 1 : pDoc->getIDocumentContentOperations().ReplaceRange(aPaM, OUString("toto"), false);
187 :
188 1 : CPPUNIT_ASSERT_EQUAL(EXPECTED_REPLACE_CONTENT, pTextNode->GetText());
189 :
190 1 : rUndoManager.Undo();
191 :
192 2 : CPPUNIT_ASSERT_EQUAL(ORIGINAL_REPLACE_CONTENT, pTextNode->GetText());
193 1 : }
194 :
195 1 : void SwUiWriterTest::testFdo75110()
196 : {
197 1 : SwDoc* pDoc = createDoc("fdo75110.odt");
198 1 : SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
199 :
200 1 : pWrtShell->SelAll();
201 : // The problem was that SwEditShell::DeleteSel() what this Delete() invokes took the wrong selection...
202 1 : pWrtShell->Delete();
203 1 : sw::UndoManager& rUndoManager = pDoc->GetUndoManager();
204 : // ... so this Undo() call resulted in a crash.
205 1 : rUndoManager.Undo();
206 1 : }
207 :
208 1 : void SwUiWriterTest::testFdo75898()
209 : {
210 1 : SwDoc* pDoc = createDoc("fdo75898.odt");
211 1 : SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
212 1 : pWrtShell->SelAll();
213 1 : pWrtShell->InsertRow(1, true);
214 1 : pWrtShell->InsertRow(1, true);
215 :
216 : // Now check if the table has 3 lines.
217 1 : SwShellCrsr* pShellCrsr = pWrtShell->getShellCrsr(false);
218 1 : SwTableNode* pTableNode = pShellCrsr->Start()->nNode.GetNode().FindTableNode();
219 : // This was 1, when doing the same using the UI, Writer even crashed.
220 1 : CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), pTableNode->GetTable().GetTabLines().size());
221 1 : }
222 :
223 1 : void SwUiWriterTest::testReplaceBackward()
224 : {
225 1 : SwDoc* pDoc = createDoc();
226 :
227 1 : sw::UndoManager& rUndoManager = pDoc->GetUndoManager();
228 :
229 1 : SwNodeIndex aIdx(pDoc->GetNodes().GetEndOfContent(), -1);
230 2 : SwPaM aPaM(aIdx);
231 :
232 1 : pDoc->getIDocumentContentOperations().InsertString(aPaM, OUString("toto titi tutu"));
233 1 : SwTextNode* pTextNode = aPaM.GetNode().GetTextNode();
234 1 : lcl_selectCharacters(aPaM, 9, 5);
235 :
236 1 : pDoc->getIDocumentContentOperations().ReplaceRange(aPaM, OUString("toto"), false);
237 :
238 1 : CPPUNIT_ASSERT_EQUAL(EXPECTED_REPLACE_CONTENT, pTextNode->GetText());
239 :
240 1 : rUndoManager.Undo();
241 :
242 2 : CPPUNIT_ASSERT_EQUAL(ORIGINAL_REPLACE_CONTENT, pTextNode->GetText());
243 1 : }
244 :
245 1 : void SwUiWriterTest::testFdo69893()
246 : {
247 1 : SwDoc* pDoc = createDoc("fdo69893.odt");
248 1 : SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
249 :
250 1 : pWrtShell->SelAll(); // A1 is empty -> selects the whole table.
251 1 : pWrtShell->SelAll(); // Selects the whole document.
252 :
253 1 : SwShellCrsr* pShellCrsr = pWrtShell->getShellCrsr(false);
254 1 : SwTextNode& rEnd = dynamic_cast<SwTextNode&>(pShellCrsr->End()->nNode.GetNode());
255 : // Selection did not include the para after table, this was "B1".
256 1 : CPPUNIT_ASSERT_EQUAL(OUString("Para after table."), rEnd.GetText());
257 1 : }
258 :
259 1 : void SwUiWriterTest::testFdo70807()
260 : {
261 1 : load(DATA_DIRECTORY, "fdo70807.odt");
262 :
263 1 : uno::Reference<container::XIndexAccess> stylesIter(getStyles("PageStyles"), uno::UNO_QUERY);
264 :
265 13 : for (sal_Int32 i = 0; i < stylesIter->getCount(); ++i)
266 : {
267 12 : uno::Reference<style::XStyle> xStyle(stylesIter->getByIndex(i), uno::UNO_QUERY);
268 24 : uno::Reference<container::XNamed> xName(xStyle, uno::UNO_QUERY);
269 :
270 12 : bool expectedUsedStyle = false;
271 12 : bool expectedUserDefined = false;
272 :
273 24 : OUString styleName(xName->getName());
274 :
275 : // just these styles are user defined styles
276 12 : if (styleName == "pagestyle1" || styleName == "pagestyle2")
277 2 : expectedUserDefined = true;
278 :
279 : // just these styles are used in the document
280 12 : if (styleName == "Right Page" || styleName == "pagestyle1" || styleName == "pagestyle2")
281 3 : expectedUsedStyle = true;
282 :
283 12 : CPPUNIT_ASSERT_EQUAL(expectedUserDefined, bool(xStyle->isUserDefined()));
284 12 : CPPUNIT_ASSERT_EQUAL(expectedUsedStyle, bool(xStyle->isInUse()));
285 13 : }
286 1 : }
287 :
288 1 : void SwUiWriterTest::testImportRTF()
289 : {
290 : // Insert "foobar" and position the cursor between "foo" and "bar".
291 1 : SwDoc* pDoc = createDoc();
292 1 : SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
293 1 : pWrtShell->Insert("foobar");
294 1 : pWrtShell->Left(CRSR_SKIP_CHARS, /*bSelect=*/false, 3, /*bBasicCall=*/false);
295 :
296 : // Insert the RTF at the cursor position.
297 1 : OString aData = "{\\rtf1 Hello world!\\par}";
298 2 : SvMemoryStream aStream(const_cast<sal_Char*>(aData.getStr()), aData.getLength(), StreamMode::READ);
299 2 : SwReader aReader(aStream, OUString(), OUString(), *pWrtShell->GetCrsr());
300 1 : Reader* pRTFReader = SwReaderWriter::GetReader(READER_WRITER_RTF);
301 1 : CPPUNIT_ASSERT(pRTFReader != 0);
302 1 : CPPUNIT_ASSERT_EQUAL(sal_uLong(0), aReader.Read(*pRTFReader));
303 :
304 1 : sal_uLong nIndex = pWrtShell->GetCrsr()->GetNode().GetIndex();
305 1 : CPPUNIT_ASSERT_EQUAL(OUString("fooHello world!"), pDoc->GetNodes()[nIndex - 1]->GetTextNode()->GetText());
306 2 : CPPUNIT_ASSERT_EQUAL(OUString("bar"), pDoc->GetNodes()[nIndex]->GetTextNode()->GetText());
307 1 : }
308 :
309 1 : void SwUiWriterTest::testExportRTF()
310 : {
311 : // Insert "aaabbbccc" and select "bbb".
312 1 : SwDoc* pDoc = createDoc();
313 1 : SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
314 1 : pWrtShell->Insert("aaabbbccc");
315 1 : pWrtShell->Left(CRSR_SKIP_CHARS, /*bSelect=*/false, 3, /*bBasicCall=*/false);
316 1 : pWrtShell->Left(CRSR_SKIP_CHARS, /*bSelect=*/true, 3, /*bBasicCall=*/false);
317 :
318 : // Create the clipboard document.
319 1 : boost::shared_ptr<SwDoc> pClpDoc(new SwDoc());
320 1 : pClpDoc->SetClipBoard(true);
321 1 : pWrtShell->Copy(pClpDoc.get());
322 :
323 : // And finally export it as RTF.
324 2 : WriterRef xWrt;
325 1 : SwReaderWriter::GetWriter("RTF", OUString(), xWrt);
326 2 : SvMemoryStream aStream;
327 2 : SwWriter aWrt(aStream, *pClpDoc);
328 1 : aWrt.Write(xWrt);
329 :
330 2 : OString aData(static_cast<const sal_Char*>(aStream.GetBuffer()), aStream.GetSize());
331 :
332 : //Amusingly eventually there was a commit id with "ccc" in it, and so the rtf contained
333 : //{\*\generator LibreOfficeDev/4.4.0.0.alpha0$Linux_X86_64 LibreOffice_project/f70664ccc6837f2cc21a29bb4f44e41e100efe6b}
334 : //so the test fell over. so strip the generator tag
335 1 : sal_Int32 nGeneratorStart = aData.indexOf("{\\*\\generator ");
336 1 : CPPUNIT_ASSERT(nGeneratorStart != -1);
337 1 : sal_Int32 nGeneratorEnd = aData.indexOf('}', nGeneratorStart + 1);
338 1 : CPPUNIT_ASSERT(nGeneratorEnd != -1);
339 1 : aData = aData.replaceAt(nGeneratorStart, nGeneratorEnd-nGeneratorStart+1, "");
340 :
341 1 : CPPUNIT_ASSERT(aData.startsWith("{\\rtf1"));
342 1 : CPPUNIT_ASSERT_EQUAL(sal_Int32(-1), aData.indexOf("aaa"));
343 1 : CPPUNIT_ASSERT(aData.indexOf("bbb") != -1);
344 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(-1), aData.indexOf("ccc"));
345 1 : }
346 :
347 1 : void SwUiWriterTest::testFdo74981()
348 : {
349 : // create a document with an input field
350 1 : SwDoc* pDoc = createDoc();
351 1 : SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
352 1 : SwInputField aField(static_cast<SwInputFieldType*>(pWrtShell->GetFieldType(0, RES_INPUTFLD)), OUString("foo"), OUString("bar"), 0, 0);
353 1 : pWrtShell->Insert(aField);
354 :
355 : // expect hints
356 2 : SwNodeIndex aIdx(pDoc->GetNodes().GetEndOfContent(), -1);
357 1 : SwTextNode* pTextNode = aIdx.GetNode().GetTextNode();
358 1 : CPPUNIT_ASSERT(pTextNode->HasHints());
359 :
360 : // go to the begin of the paragraph and split this node
361 1 : pWrtShell->Left(CRSR_SKIP_CHARS, false, 100, false);
362 1 : pWrtShell->SplitNode();
363 :
364 : // expect only the second paragraph to have hints
365 1 : aIdx = SwNodeIndex(pDoc->GetNodes().GetEndOfContent(), -1);
366 1 : pTextNode = aIdx.GetNode().GetTextNode();
367 1 : CPPUNIT_ASSERT(pTextNode->HasHints());
368 1 : --aIdx;
369 1 : pTextNode = aIdx.GetNode().GetTextNode();
370 2 : CPPUNIT_ASSERT(!pTextNode->HasHints());
371 1 : }
372 :
373 1 : void SwUiWriterTest::testShapeTextboxSelect()
374 : {
375 1 : SwDoc* pDoc = createDoc("shape-textbox.odt");
376 1 : SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
377 1 : SdrPage* pPage = pDoc->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0);
378 1 : SdrObject* pObject = pPage->GetObj(1);
379 1 : SwContact* pTextBox = static_cast<SwContact*>(pObject->GetUserCall());
380 : // First, make sure that pTextBox is a fly frame (textbox of a shape).
381 1 : CPPUNIT_ASSERT_EQUAL(RES_FLYFRMFMT, static_cast<RES_FMT>(pTextBox->GetFormat()->Which()));
382 :
383 : // Then select it.
384 1 : pWrtShell->SelectObj(Point(), 0, pObject);
385 1 : const SdrMarkList& rMarkList = pWrtShell->GetDrawView()->GetMarkedObjectList();
386 1 : SwDrawContact* pShape = static_cast<SwDrawContact*>(rMarkList.GetMark(0)->GetMarkedSdrObj()->GetUserCall());
387 : // And finally make sure the shape got selected, not just the textbox itself.
388 1 : CPPUNIT_ASSERT_EQUAL(RES_DRAWFRMFMT, static_cast<RES_FMT>(pShape->GetFormat()->Which()));
389 1 : }
390 :
391 1 : void SwUiWriterTest::testShapeTextboxDelete()
392 : {
393 1 : SwDoc* pDoc = createDoc("shape-textbox.odt");
394 1 : SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
395 1 : SdrPage* pPage = pDoc->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0);
396 1 : SdrObject* pObject = pPage->GetObj(0);
397 1 : pWrtShell->SelectObj(Point(), 0, pObject);
398 1 : size_t nActual = pPage->GetObjCount();
399 : // Two objects on the draw page: the shape and its textbox.
400 1 : CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), nActual);
401 :
402 1 : pWrtShell->DelSelectedObj();
403 1 : nActual = pPage->GetObjCount();
404 : // Both (not only the shape) should be removed by now (the textbox wasn't removed, so this was 1).
405 1 : CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0), nActual);
406 1 : }
407 :
408 1 : void SwUiWriterTest::testCp1000071()
409 : {
410 1 : SwDoc* pDoc = createDoc("cp1000071.odt");
411 1 : SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
412 :
413 1 : const SwRedlineTable& rTable = pDoc->getIDocumentRedlineAccess().GetRedlineTable();
414 1 : CPPUNIT_ASSERT_EQUAL( size_t( 2 ), rTable.size());
415 1 : sal_uLong redlineStart0NodeIndex = rTable[ 0 ]->Start()->nNode.GetIndex();
416 1 : sal_Int32 redlineStart0Index = rTable[ 0 ]->Start()->nContent.GetIndex();
417 1 : sal_uLong redlineEnd0NodeIndex = rTable[ 0 ]->End()->nNode.GetIndex();
418 1 : sal_Int32 redlineEnd0Index = rTable[ 0 ]->End()->nContent.GetIndex();
419 1 : sal_uLong redlineStart1NodeIndex = rTable[ 1 ]->Start()->nNode.GetIndex();
420 1 : sal_Int32 redlineStart1Index = rTable[ 1 ]->Start()->nContent.GetIndex();
421 1 : sal_uLong redlineEnd1NodeIndex = rTable[ 1 ]->End()->nNode.GetIndex();
422 1 : sal_Int32 redlineEnd1Index = rTable[ 1 ]->End()->nContent.GetIndex();
423 :
424 : // Change the document layout to be 2 columns, and then undo.
425 1 : pWrtShell->SelAll();
426 1 : SwSectionData section(CONTENT_SECTION, pWrtShell->GetUniqueSectionName());
427 2 : SfxItemSet set( pDoc->GetDocShell()->GetPool(), RES_COL, RES_COL, 0 );
428 2 : SwFormatCol col;
429 1 : col.Init( 2, 0, 10000 );
430 1 : set.Put( col );
431 1 : pWrtShell->InsertSection( section, &set );
432 1 : sw::UndoManager& rUndoManager = pDoc->GetUndoManager();
433 1 : rUndoManager.Undo();
434 :
435 : // Check that redlines are the same like at the beginning.
436 1 : CPPUNIT_ASSERT_EQUAL( size_t( 2 ), rTable.size());
437 1 : CPPUNIT_ASSERT_EQUAL( redlineStart0NodeIndex, rTable[ 0 ]->Start()->nNode.GetIndex());
438 1 : CPPUNIT_ASSERT_EQUAL( redlineStart0Index, rTable[ 0 ]->Start()->nContent.GetIndex());
439 1 : CPPUNIT_ASSERT_EQUAL( redlineEnd0NodeIndex, rTable[ 0 ]->End()->nNode.GetIndex());
440 1 : CPPUNIT_ASSERT_EQUAL( redlineEnd0Index, rTable[ 0 ]->End()->nContent.GetIndex());
441 1 : CPPUNIT_ASSERT_EQUAL( redlineStart1NodeIndex, rTable[ 1 ]->Start()->nNode.GetIndex());
442 1 : CPPUNIT_ASSERT_EQUAL( redlineStart1Index, rTable[ 1 ]->Start()->nContent.GetIndex());
443 1 : CPPUNIT_ASSERT_EQUAL( redlineEnd1NodeIndex, rTable[ 1 ]->End()->nNode.GetIndex());
444 2 : CPPUNIT_ASSERT_EQUAL( redlineEnd1Index, rTable[ 1 ]->End()->nContent.GetIndex());
445 1 : }
446 :
447 1 : void SwUiWriterTest::testShapeTextboxVertadjust()
448 : {
449 1 : SwDoc* pDoc = createDoc("shape-textbox-vertadjust.odt");
450 1 : SdrPage* pPage = pDoc->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0);
451 1 : SdrObject* pObject = pPage->GetObj(1);
452 1 : SwFrameFormat* pFormat = static_cast<SwContact*>(pObject->GetUserCall())->GetFormat();
453 : // This was SDRTEXTVERTADJUST_TOP.
454 1 : CPPUNIT_ASSERT_EQUAL(SDRTEXTVERTADJUST_CENTER, pFormat->GetTextVertAdjust().GetValue());
455 1 : }
456 :
457 1 : void SwUiWriterTest::testShapeTextboxAutosize()
458 : {
459 1 : SwDoc* pDoc = createDoc("shape-textbox-autosize.odt");
460 1 : SdrPage* pPage = pDoc->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0);
461 1 : SdrObject* pFirst = pPage->GetObj(0);
462 1 : CPPUNIT_ASSERT_EQUAL(OUString("1st"), pFirst->GetName());
463 :
464 1 : SdrObject* pSecond = pPage->GetObj(1);
465 1 : CPPUNIT_ASSERT_EQUAL(OUString("2nd"), pSecond->GetName());
466 :
467 : // Shape -> textbox synchronization was missing, the second shape had the
468 : // same height as the first, even though the first contained 1 paragraph
469 : // and the other 2 ones.
470 1 : CPPUNIT_ASSERT(pFirst->GetSnapRect().getHeight() < pSecond->GetSnapRect().getHeight());
471 1 : }
472 :
473 1 : void SwUiWriterTest::testFdo82191()
474 : {
475 1 : SwDoc* pDoc = createDoc("fdo82191.odt");
476 1 : SdrPage* pPage = pDoc->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0);
477 1 : std::set<const SwFrameFormat*> aTextBoxes = SwTextBoxHelper::findTextBoxes(pDoc);
478 : // Make sure we have a single draw shape.
479 1 : CPPUNIT_ASSERT_EQUAL(sal_Int32(1), SwTextBoxHelper::getCount(pPage, aTextBoxes));
480 :
481 2 : SwDoc aClipboard;
482 1 : SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
483 1 : SdrObject* pObject = pPage->GetObj(0);
484 : // Select it, then copy and paste.
485 1 : pWrtShell->SelectObj(Point(), 0, pObject);
486 1 : pWrtShell->Copy(&aClipboard);
487 1 : pWrtShell->Paste(&aClipboard);
488 :
489 1 : aTextBoxes = SwTextBoxHelper::findTextBoxes(pDoc);
490 : // This was one: the textbox of the shape wasn't copied.
491 2 : CPPUNIT_ASSERT_EQUAL(size_t(2), aTextBoxes.size());
492 1 : }
493 :
494 1 : void SwUiWriterTest::testCommentedWord()
495 : {
496 : // This word is commented. <- string in document
497 : // 123456789 <- character positions
498 1 : SwDoc* pDoc = createDoc("commented-word.odt");
499 1 : SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
500 : // Move the cursor into the second word.
501 1 : pWrtShell->Right(CRSR_SKIP_CHARS, /*bSelect=*/false, 5, /*bBasicCall=*/false);
502 : // Select the word.
503 1 : pWrtShell->SelWrd();
504 :
505 : // Make sure that not only the word, but its comment anchor is also selected.
506 1 : SwShellCrsr* pShellCrsr = pWrtShell->getShellCrsr(false);
507 : // This was 9, only "word", not "word<anchor character>" was selected.
508 1 : CPPUNIT_ASSERT_EQUAL(sal_Int32(10), pShellCrsr->End()->nContent.GetIndex());
509 :
510 : // Test that getAnchor() points to "word", not to an empty string.
511 1 : uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
512 2 : uno::Reference<container::XEnumerationAccess> xFieldsAccess(xTextFieldsSupplier->getTextFields());
513 2 : uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration());
514 2 : uno::Reference<text::XTextContent> xField(xFields->nextElement(), uno::UNO_QUERY);
515 2 : CPPUNIT_ASSERT_EQUAL(OUString("word"), xField->getAnchor()->getString());
516 1 : }
517 :
518 :
519 : // Chinese conversion tests
520 :
521 1 : static const OUString CHINESE_TRADITIONAL_CONTENT(sal_Unicode(0x9F8D));
522 1 : static const OUString CHINESE_SIMPLIFIED_CONTENT(sal_Unicode(0x9F99));
523 1 : static const OUString NON_CHINESE_CONTENT ("Hippopotamus");
524 :
525 : // Tests that a blank document is still blank after conversion
526 1 : void SwUiWriterTest::testChineseConversionBlank()
527 : {
528 :
529 : // Given
530 1 : SwDoc* pDoc = createDoc();
531 1 : SwView* pView = pDoc->GetDocShell()->GetView();
532 1 : const uno::Reference< uno::XComponentContext > xContext( comphelper::getProcessComponentContext() );
533 2 : SwNodeIndex aIdx(pDoc->GetNodes().GetEndOfContent(), -1);
534 2 : SwPaM aPaM(aIdx);
535 :
536 : // When
537 : SwHHCWrapper aWrap( pView, xContext, LANGUAGE_CHINESE_TRADITIONAL, LANGUAGE_CHINESE_SIMPLIFIED, NULL,
538 : i18n::TextConversionOption::CHARACTER_BY_CHARACTER, false,
539 2 : true, false, false );
540 1 : aWrap.Convert();
541 :
542 :
543 : // Then
544 1 : SwTextNode* pTextNode = aPaM.GetNode().GetTextNode();
545 2 : CPPUNIT_ASSERT_EQUAL(OUString(), pTextNode->GetText());
546 :
547 1 : }
548 :
549 : // Tests that non Chinese text is unchanged after conversion
550 1 : void SwUiWriterTest::testChineseConversionNonChineseText()
551 : {
552 :
553 : // Given
554 1 : SwDoc* pDoc = createDoc();
555 1 : SwView* pView = pDoc->GetDocShell()->GetView();
556 1 : const uno::Reference< uno::XComponentContext > xContext( comphelper::getProcessComponentContext() );
557 2 : SwNodeIndex aIdx(pDoc->GetNodes().GetEndOfContent(), -1);
558 2 : SwPaM aPaM(aIdx);
559 1 : pDoc->getIDocumentContentOperations().InsertString(aPaM, NON_CHINESE_CONTENT);
560 :
561 :
562 : // When
563 : SwHHCWrapper aWrap( pView, xContext, LANGUAGE_CHINESE_TRADITIONAL, LANGUAGE_CHINESE_SIMPLIFIED, NULL,
564 : i18n::TextConversionOption::CHARACTER_BY_CHARACTER, false,
565 2 : true, false, false );
566 1 : aWrap.Convert();
567 :
568 :
569 : // Then
570 1 : SwTextNode* pTextNode = aPaM.GetNode().GetTextNode();
571 2 : CPPUNIT_ASSERT_EQUAL(NON_CHINESE_CONTENT, pTextNode->GetText());
572 :
573 1 : }
574 :
575 : // Tests conversion of traditional Chinese characters to simplified Chinese
576 1 : void SwUiWriterTest::testChineseConversionTraditionalToSimplified()
577 : {
578 :
579 : // Given
580 1 : SwDoc* pDoc = createDoc();
581 1 : SwView* pView = pDoc->GetDocShell()->GetView();
582 1 : const uno::Reference< uno::XComponentContext > xContext( comphelper::getProcessComponentContext() );
583 2 : SwNodeIndex aIdx(pDoc->GetNodes().GetEndOfContent(), -1);
584 2 : SwPaM aPaM(aIdx);
585 1 : pDoc->getIDocumentContentOperations().InsertString(aPaM, CHINESE_TRADITIONAL_CONTENT);
586 :
587 :
588 : // When
589 : SwHHCWrapper aWrap( pView, xContext, LANGUAGE_CHINESE_TRADITIONAL, LANGUAGE_CHINESE_SIMPLIFIED, NULL,
590 : i18n::TextConversionOption::CHARACTER_BY_CHARACTER, false,
591 2 : true, false, false );
592 1 : aWrap.Convert();
593 :
594 :
595 : // Then
596 1 : SwTextNode* pTextNode = aPaM.GetNode().GetTextNode();
597 2 : CPPUNIT_ASSERT_EQUAL(CHINESE_SIMPLIFIED_CONTENT, pTextNode->GetText());
598 :
599 1 : }
600 :
601 : // Tests conversion of simplified Chinese characters to traditional Chinese
602 1 : void SwUiWriterTest::testChineseConversionSimplifiedToTraditional()
603 : {
604 :
605 : // Given
606 1 : SwDoc* pDoc = createDoc();
607 1 : SwView* pView = pDoc->GetDocShell()->GetView();
608 1 : const uno::Reference< uno::XComponentContext > xContext( comphelper::getProcessComponentContext() );
609 2 : SwNodeIndex aIdx(pDoc->GetNodes().GetEndOfContent(), -1);
610 2 : SwPaM aPaM(aIdx);
611 1 : pDoc->getIDocumentContentOperations().InsertString(aPaM, CHINESE_SIMPLIFIED_CONTENT);
612 :
613 :
614 : // When
615 : SwHHCWrapper aWrap( pView, xContext, LANGUAGE_CHINESE_SIMPLIFIED, LANGUAGE_CHINESE_TRADITIONAL, NULL,
616 : i18n::TextConversionOption::CHARACTER_BY_CHARACTER, false,
617 2 : true, false, false );
618 1 : aWrap.Convert();
619 :
620 :
621 : // Then
622 1 : SwTextNode* pTextNode = aPaM.GetNode().GetTextNode();
623 2 : CPPUNIT_ASSERT_EQUAL(CHINESE_TRADITIONAL_CONTENT, pTextNode->GetText());
624 :
625 1 : }
626 :
627 1 : void SwUiWriterTest::testFdo85554()
628 : {
629 : // Load the document, it contains one shape with a textbox.
630 1 : load("/sw/qa/extras/uiwriter/data/", "fdo85554.odt");
631 :
632 : // Add a second shape to the document.
633 1 : uno::Reference<css::lang::XMultiServiceFactory> xFactory(mxComponent, uno::UNO_QUERY);
634 2 : uno::Reference<drawing::XShape> xShape(xFactory->createInstance("com.sun.star.drawing.RectangleShape"), uno::UNO_QUERY);
635 1 : xShape->setSize(awt::Size(10000, 10000));
636 1 : xShape->setPosition(awt::Point(1000, 1000));
637 2 : uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY);
638 2 : uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage();
639 1 : xDrawPage->add(xShape);
640 :
641 : // Save it and load it back.
642 1 : reload("writer8", "fdo85554.odt");
643 :
644 1 : xDrawPageSupplier.set(mxComponent, uno::UNO_QUERY);
645 1 : xDrawPage = xDrawPageSupplier->getDrawPage();
646 : // This was 1, we lost a shape on export.
647 2 : CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2), xDrawPage->getCount());
648 1 : }
649 :
650 1 : void SwUiWriterTest::testAutoCorr()
651 : {
652 1 : SwDoc* pDoc = createDoc();
653 1 : SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
654 1 : SwAutoCorrect corr(*SvxAutoCorrCfg::Get().GetAutoCorrect());
655 1 : const sal_Unicode cIns = ' ';
656 :
657 : //Normal AutoCorrect
658 1 : pWrtShell->Insert("tset");
659 1 : pWrtShell->AutoCorrect(corr, cIns);
660 1 : sal_uLong nIndex = pWrtShell->GetCrsr()->GetNode().GetIndex();
661 1 : CPPUNIT_ASSERT_EQUAL(OUString("Test "), static_cast<SwTextNode*>(pDoc->GetNodes()[nIndex])->GetText());
662 :
663 : //AutoCorrect with change style to bolt
664 1 : pWrtShell->Insert("Bolt");
665 1 : pWrtShell->AutoCorrect(corr, cIns);
666 1 : nIndex = pWrtShell->GetCrsr()->GetNode().GetIndex();
667 2 : const uno::Reference< text::XTextRange > xRun = getRun(getParagraph(1), 2);
668 1 : CPPUNIT_ASSERT_EQUAL(OUString("Bolt"), xRun->getString());
669 1 : CPPUNIT_ASSERT_EQUAL(OUString("Arial"), getProperty<OUString>(xRun, "CharFontName"));
670 :
671 : //AutoCorrect inserts Table with 2 rows and 3 columns
672 1 : pWrtShell->Insert("4xx");
673 1 : pWrtShell->AutoCorrect(corr, cIns);
674 2 : const uno::Reference< text::XTextTable > xTable(getParagraphOrTable(2), uno::UNO_QUERY);
675 1 : CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTable->getRows()->getCount());
676 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xTable->getColumns()->getCount());
677 1 : }
678 :
679 1 : void SwUiWriterTest::testMergeDoc()
680 : {
681 1 : SwDoc* const pDoc1(createDoc("merge-change1.odt"));
682 :
683 : auto xDoc2Component(loadFromDesktop(
684 2 : getURLFromSrc(DATA_DIRECTORY) + "merge-change2.odt",
685 3 : "com.sun.star.text.TextDocument"));
686 : auto pxDoc2Document(
687 1 : dynamic_cast<SwXTextDocument *>(xDoc2Component.get()));
688 1 : CPPUNIT_ASSERT(pxDoc2Document);
689 1 : SwDoc* const pDoc2(pxDoc2Document->GetDocShell()->GetDoc());
690 :
691 1 : SwEditShell* const pEditShell(pDoc1->GetEditShell());
692 1 : pEditShell->MergeDoc(*pDoc2);
693 :
694 : // accept all redlines
695 12 : while(pEditShell->GetRedlineCount())
696 10 : pEditShell->AcceptRedline(0);
697 :
698 1 : CPPUNIT_ASSERT_EQUAL(7, getParagraphs());
699 1 : getParagraph(1, "Para One: Two Three Four Five");
700 1 : getParagraph(2, "Para Two: One Three Four Five");
701 1 : getParagraph(3, "Para Three: One Two Four Five");
702 1 : getParagraph(4, "Para Four: One Two Three Four Five");
703 1 : getParagraph(5, "Para Six: One Three Four Five");
704 1 : getParagraph(6, "");
705 1 : getParagraph(7, "");
706 1 : }
707 :
708 1 : void SwUiWriterTest::testCreatePortions()
709 : {
710 1 : createDoc("uno-cycle.odt");
711 1 : uno::Reference<text::XBookmarksSupplier> xBookmarksSupplier(mxComponent, uno::UNO_QUERY);
712 2 : uno::Reference<text::XTextContent> xText(xBookmarksSupplier->getBookmarks()->getByName("Mark"), uno::UNO_QUERY);
713 2 : uno::Reference<container::XEnumerationAccess> xTextCursor(xText->getAnchor(), uno::UNO_QUERY);
714 1 : CPPUNIT_ASSERT(xTextCursor.is());
715 :
716 : uno::Reference<container::XEnumerationAccess> xParagraph(
717 2 : xTextCursor->createEnumeration()->nextElement(), uno::UNO_QUERY);
718 1 : CPPUNIT_ASSERT(xParagraph.is());
719 : // This looped forever in lcl_CreatePortions
720 2 : xParagraph->createEnumeration();
721 1 : }
722 :
723 1 : void SwUiWriterTest::testBookmarkUndo()
724 : {
725 1 : SwDoc* pDoc = createDoc();
726 1 : sw::UndoManager& rUndoManager = pDoc->GetUndoManager();
727 1 : IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
728 1 : SwPaM aPaM( SwNodeIndex(pDoc->GetNodes().GetEndOfContent(), -1) );
729 :
730 1 : pMarkAccess->makeMark(aPaM, OUString("Mark"), IDocumentMarkAccess::MarkType::BOOKMARK);
731 1 : CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
732 1 : rUndoManager.Undo();
733 1 : CPPUNIT_ASSERT_EQUAL(sal_Int32(0), pMarkAccess->getAllMarksCount());
734 1 : rUndoManager.Redo();
735 1 : CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
736 :
737 1 : IDocumentMarkAccess::const_iterator_t ppBkmk = pMarkAccess->findMark("Mark");
738 1 : CPPUNIT_ASSERT(ppBkmk != pMarkAccess->getAllMarksEnd());
739 :
740 1 : pMarkAccess->renameMark(ppBkmk->get(), "Mark_");
741 1 : CPPUNIT_ASSERT(pMarkAccess->findMark("Mark") == pMarkAccess->getAllMarksEnd());
742 1 : CPPUNIT_ASSERT(pMarkAccess->findMark("Mark_") != pMarkAccess->getAllMarksEnd());
743 1 : rUndoManager.Undo();
744 1 : CPPUNIT_ASSERT(pMarkAccess->findMark("Mark") != pMarkAccess->getAllMarksEnd());
745 1 : CPPUNIT_ASSERT(pMarkAccess->findMark("Mark_") == pMarkAccess->getAllMarksEnd());
746 1 : rUndoManager.Redo();
747 1 : CPPUNIT_ASSERT(pMarkAccess->findMark("Mark") == pMarkAccess->getAllMarksEnd());
748 1 : CPPUNIT_ASSERT(pMarkAccess->findMark("Mark_") != pMarkAccess->getAllMarksEnd());
749 :
750 1 : pMarkAccess->deleteMark( pMarkAccess->findMark("Mark_") );
751 1 : CPPUNIT_ASSERT_EQUAL(sal_Int32(0), pMarkAccess->getAllMarksCount());
752 1 : rUndoManager.Undo();
753 1 : CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
754 1 : rUndoManager.Redo();
755 1 : CPPUNIT_ASSERT_EQUAL(sal_Int32(0), pMarkAccess->getAllMarksCount());
756 1 : }
757 :
758 2 : static void lcl_setWeight(SwWrtShell* pWrtShell, FontWeight aWeight)
759 : {
760 2 : SvxWeightItem aWeightItem(aWeight, EE_CHAR_WEIGHT);
761 4 : SvxScriptSetItem aScriptSetItem(SID_ATTR_CHAR_WEIGHT, pWrtShell->GetAttrPool());
762 2 : aScriptSetItem.PutItemForScriptType(SvtScriptType::LATIN | SvtScriptType::ASIAN | SvtScriptType::COMPLEX, aWeightItem);
763 4 : pWrtShell->SetAttrSet(aScriptSetItem.GetItemSet());
764 2 : }
765 :
766 1 : void SwUiWriterTest::testFdo85876()
767 : {
768 1 : SwDoc* const pDoc = createDoc();
769 1 : SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
770 1 : lcl_setWeight(pWrtShell, WEIGHT_BOLD);
771 1 : pWrtShell->Insert("test");
772 1 : lcl_setWeight(pWrtShell, WEIGHT_NORMAL);
773 1 : pWrtShell->SplitNode();
774 1 : pWrtShell->SplitNode();
775 1 : pWrtShell->Up(false);
776 1 : pWrtShell->Insert("test");
777 1 : auto xText = getParagraph(1)->getText();
778 1 : CPPUNIT_ASSERT(xText.is());
779 : {
780 1 : auto xCursor(xText->createTextCursorByRange(getParagraph(1)));
781 1 : CPPUNIT_ASSERT(xCursor.is());
782 1 : xCursor->collapseToStart();
783 1 : CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD, getProperty<float>(xCursor, "CharWeight"));
784 : }
785 : {
786 1 : auto xCursor(xText->createTextCursorByRange(getParagraph(2)));
787 1 : CPPUNIT_ASSERT(xCursor.is());
788 1 : xCursor->collapseToStart();
789 : // this used to be BOLD too with fdo#85876
790 1 : CPPUNIT_ASSERT_EQUAL(awt::FontWeight::NORMAL, getProperty<float>(xCursor, "CharWeight"));
791 1 : }
792 1 : }
793 :
794 1 : void SwUiWriterTest::testFdo87448()
795 : {
796 1 : createDoc("fdo87448.odt");
797 :
798 : // Save the first shape to a metafile.
799 1 : uno::Reference<drawing::XGraphicExportFilter> xGraphicExporter = drawing::GraphicExportFilter::create(comphelper::getProcessComponentContext());
800 2 : uno::Reference<lang::XComponent> xSourceDoc(getShape(1), uno::UNO_QUERY);
801 1 : xGraphicExporter->setSourceDocument(xSourceDoc);
802 :
803 2 : SvMemoryStream aStream;
804 2 : uno::Reference<io::XOutputStream> xOutputStream(new utl::OStreamWrapper(aStream));
805 : uno::Sequence<beans::PropertyValue> aDescriptor =
806 : {
807 : beans::PropertyValue("OutputStream", sal_Int32(0), uno::makeAny(xOutputStream), beans::PropertyState_DIRECT_VALUE),
808 : beans::PropertyValue("FilterName", sal_Int32(0), uno::makeAny(OUString("SVM")), beans::PropertyState_DIRECT_VALUE)
809 2 : };
810 1 : xGraphicExporter->filter(aDescriptor);
811 1 : aStream.Seek(STREAM_SEEK_TO_BEGIN);
812 :
813 : // Read it back and dump it as an XML file.
814 2 : Graphic aGraphic;
815 1 : ReadGraphic(aStream, aGraphic);
816 1 : const GDIMetaFile& rMetaFile = aGraphic.GetGDIMetaFile();
817 2 : MetafileXmlDump dumper;
818 1 : xmlDocPtr pXmlDoc = dumper.dumpAndParse(rMetaFile);
819 :
820 : // The first polyline in the document has a number of points to draw arcs,
821 : // the last one jumps back to the start, so we call "end" the last but one.
822 1 : sal_Int32 nFirstEnd = getXPath(pXmlDoc, "/metafile/polyline[1]/point[last()-1]", "x").toInt32();
823 : // The second polyline has a different start point, but the arc it draws
824 : // should end at the ~same position as the first polyline.
825 1 : sal_Int32 nSecondEnd = getXPath(pXmlDoc, "/metafile/polyline[2]/point[last()]", "x").toInt32();
826 :
827 : // nFirstEnd was 6023 and nSecondEnd was 6648, now they should be much closer, e.g. nFirstEnd = 6550, nSecondEnd = 6548
828 2 : OString aMsg = "nFirstEnd is " + OString::number(nFirstEnd) + ", nSecondEnd is " + OString::number(nSecondEnd);
829 : // Assert that the difference is less than half point.
830 2 : CPPUNIT_ASSERT_MESSAGE(aMsg.getStr(), abs(nFirstEnd - nSecondEnd) < 10);
831 1 : }
832 :
833 1 : void SwUiWriterTest::testTdf68183()
834 : {
835 : // First disable RSID and check if indeed no such attribute is inserted.
836 1 : SwDoc* pDoc = createDoc();
837 1 : SW_MOD()->GetModuleConfig()->SetStoreRsid(false);
838 1 : SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
839 1 : pWrtShell->Insert2("X");
840 :
841 1 : SwNodeIndex aIdx(pDoc->GetNodes().GetEndOfContent(), -1);
842 2 : SwPaM aPaM(aIdx);
843 1 : SwTextNode* pTextNode = aPaM.GetNode().GetTextNode();
844 1 : CPPUNIT_ASSERT_EQUAL(false, pTextNode->GetSwAttrSet().HasItem(RES_PARATR_RSID));
845 :
846 : // Then enable storing of RSID and make sure that the attribute is inserted.
847 1 : SW_MOD()->GetModuleConfig()->SetStoreRsid(true);
848 :
849 1 : pWrtShell->DelToStartOfLine();
850 1 : pWrtShell->Insert2("X");
851 :
852 2 : CPPUNIT_ASSERT_EQUAL(true, pTextNode->GetSwAttrSet().HasItem(RES_PARATR_RSID));
853 1 : }
854 :
855 1 : void SwUiWriterTest::testCp1000115()
856 : {
857 1 : createDoc("cp1000115.fodt");
858 1 : xmlDocPtr pXmlDoc = parseLayoutDump();
859 1 : xmlXPathObjectPtr pXmlObj = getXPathNode(pXmlDoc, "/root/page[2]/body/tab/row/cell[2]/txt");
860 1 : xmlNodeSetPtr pXmlNodes = pXmlObj->nodesetval;
861 : // This was 1: the long paragraph in the B1 cell did flow over to the
862 : // second page, so there was only one paragraph in the second cell of the
863 : // second page.
864 1 : CPPUNIT_ASSERT_EQUAL(2, xmlXPathNodeSetGetLength(pXmlNodes));
865 1 : xmlXPathFreeObject(pXmlObj);
866 1 : }
867 :
868 1 : void SwUiWriterTest::testTdf90003()
869 : {
870 1 : createDoc("tdf90003.odt");
871 1 : xmlDocPtr pXmlDoc = parseLayoutDump();
872 1 : CPPUNIT_ASSERT(pXmlDoc);
873 : // This was 1: an unexpected fly portion was created, resulting in too
874 : // large x position for the empty paragraph marker.
875 1 : assertXPath(pXmlDoc, "//Special[@nType='POR_FLY']", 0);
876 1 : }
877 :
878 1 : void SwUiWriterTest::testExportToPicture()
879 : {
880 1 : createDoc();
881 : uno::Sequence<beans::PropertyValue> aFilterData =
882 : {
883 : beans::PropertyValue("PixelWidth", sal_Int32(0), uno::makeAny(sal_Int32(610)), beans::PropertyState_DIRECT_VALUE),
884 : beans::PropertyValue("PixelHeight", sal_Int32(0), uno::makeAny(sal_Int32(610)), beans::PropertyState_DIRECT_VALUE)
885 1 : };
886 : uno::Sequence<beans::PropertyValue> aDescriptor =
887 : {
888 : beans::PropertyValue("FilterName", sal_Int32(0), uno::makeAny(OUString("writer_png_Export")), beans::PropertyState_DIRECT_VALUE),
889 : beans::PropertyValue("FilterData", sal_Int32(0), uno::makeAny(aFilterData), beans::PropertyState_DIRECT_VALUE)
890 2 : };
891 2 : utl::TempFile aTempFile;
892 2 : uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY);
893 1 : xStorable->storeToURL(aTempFile.GetURL(), aDescriptor);
894 1 : bool extchk = aTempFile.IsValid();
895 1 : CPPUNIT_ASSERT_EQUAL(true, extchk);
896 2 : osl::File tmpFile(aTempFile.GetURL());
897 1 : tmpFile.open(sal_uInt32(osl_File_OpenFlag_Read));
898 : sal_uInt64 val;
899 1 : CPPUNIT_ASSERT_EQUAL(osl::FileBase::E_None, tmpFile.getSize(val));
900 1 : CPPUNIT_ASSERT(val > 100);
901 2 : aTempFile.EnableKillingFile();
902 1 : }
903 :
904 1 : void SwUiWriterTest::testSearchWithTransliterate()
905 : {
906 1 : SwDoc* pDoc = createDoc();
907 1 : SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
908 1 : SwNodeIndex aIdx(pDoc->GetNodes().GetEndOfContent(), -1);
909 2 : SwPaM aPaM(aIdx);
910 1 : pDoc->getIDocumentContentOperations().InsertString(aPaM,"This is paragraph one");
911 1 : pWrtShell->SplitNode();
912 1 : aIdx = SwNodeIndex(pDoc->GetNodes().GetEndOfContent(), -1);
913 1 : aPaM = SwPaM(aIdx);
914 1 : pDoc->getIDocumentContentOperations().InsertString(aPaM,"This is Other PARAGRAPH");
915 2 : com::sun::star::util::SearchOptions SearchOpt;
916 1 : SearchOpt.algorithmType = com::sun::star::util::SearchAlgorithms_ABSOLUTE;
917 1 : SearchOpt.searchFlag = 0x00000001;
918 1 : SearchOpt.searchString = "other";
919 1 : SearchOpt.replaceString.clear();
920 1 : SearchOpt.changedChars = 0;
921 1 : SearchOpt.deletedChars = 0;
922 1 : SearchOpt.insertedChars = 0;
923 1 : SearchOpt.transliterateFlags = com::sun::star::i18n::TransliterationModulesExtra::IGNORE_DIACRITICS_CTL;
924 : //transliteration option set so that at least one of the search strings is not found
925 1 : sal_uLong case1 = pWrtShell->SearchPattern(SearchOpt,true,DOCPOS_START,DOCPOS_END,FND_IN_BODY,false);
926 1 : SwShellCrsr* pShellCrsr = pWrtShell->getShellCrsr(true);
927 1 : CPPUNIT_ASSERT_EQUAL(OUString(""),pShellCrsr->GetText());
928 1 : CPPUNIT_ASSERT_EQUAL(0,(int)case1);
929 1 : SearchOpt.searchString = "paragraph";
930 1 : SearchOpt.transliterateFlags = com::sun::star::i18n::TransliterationModulesExtra::IGNORE_KASHIDA_CTL;
931 : //transliteration option set so that all search strings are found
932 1 : sal_uLong case2 = pWrtShell->SearchPattern(SearchOpt,true,DOCPOS_START,DOCPOS_END,FND_IN_BODY,false);
933 1 : pShellCrsr = pWrtShell->getShellCrsr(true);
934 1 : CPPUNIT_ASSERT_EQUAL(OUString("paragraph"),pShellCrsr->GetText());
935 2 : CPPUNIT_ASSERT_EQUAL(1,(int)case2);
936 1 : }
937 :
938 1 : void SwUiWriterTest::testTableBackgroundColor()
939 : {
940 1 : SwDoc* pDoc = createDoc();
941 1 : SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
942 1 : SwInsertTableOptions TableOpt(tabopts::DEFAULT_BORDER, 0);
943 1 : pWrtShell->InsertTable(TableOpt, 3, 3); //Inserting Table
944 : //Checking Rows and Columns of Inserted Table
945 1 : uno::Reference<text::XTextTable> xTable(getParagraphOrTable(1), uno::UNO_QUERY);
946 1 : CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xTable->getRows()->getCount());
947 1 : CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xTable->getColumns()->getCount());
948 1 : pWrtShell->SttDoc();
949 1 : pWrtShell->SelTableRow(); //Selecting First Row
950 1 : pWrtShell->ClearMark();
951 : //Modifying the color of Table Box
952 1 : Color colour = sal_Int32(0xFF00FF);
953 1 : pWrtShell->SetBoxBackground(SvxBrushItem(colour, sal_Int16(RES_BACKGROUND)));
954 : //Checking cells for background color only A1 should be modified
955 2 : uno::Reference<table::XCell> xCell;
956 1 : xCell = xTable->getCellByName("A1");
957 1 : CPPUNIT_ASSERT_EQUAL(sal_Int32(0xFF00FF), getProperty<sal_Int32>(xCell, "BackColor"));
958 1 : xCell = xTable->getCellByName("A2");
959 1 : CPPUNIT_ASSERT_EQUAL(sal_Int32(-1), getProperty<sal_Int32>(xCell, "BackColor"));
960 1 : xCell = xTable->getCellByName("A3");
961 1 : CPPUNIT_ASSERT_EQUAL(sal_Int32(-1), getProperty<sal_Int32>(xCell, "BackColor"));
962 1 : xCell = xTable->getCellByName("B1");
963 1 : CPPUNIT_ASSERT_EQUAL(sal_Int32(-1), getProperty<sal_Int32>(xCell, "BackColor"));
964 1 : xCell = xTable->getCellByName("B2");
965 1 : CPPUNIT_ASSERT_EQUAL(sal_Int32(-1), getProperty<sal_Int32>(xCell, "BackColor"));
966 1 : xCell = xTable->getCellByName("B3");
967 1 : CPPUNIT_ASSERT_EQUAL(sal_Int32(-1), getProperty<sal_Int32>(xCell, "BackColor"));
968 1 : xCell = xTable->getCellByName("C1");
969 1 : CPPUNIT_ASSERT_EQUAL(sal_Int32(-1), getProperty<sal_Int32>(xCell, "BackColor"));
970 1 : xCell = xTable->getCellByName("C2");
971 1 : CPPUNIT_ASSERT_EQUAL(sal_Int32(-1), getProperty<sal_Int32>(xCell, "BackColor"));
972 1 : xCell = xTable->getCellByName("C3");
973 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(-1), getProperty<sal_Int32>(xCell, "BackColor"));
974 1 : }
975 :
976 1 : void SwUiWriterTest::testTdf90362()
977 : {
978 : // First check if the end of the second paragraph is indeed protected.
979 1 : SwDoc* pDoc = createDoc("tdf90362.fodt");
980 1 : SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
981 1 : pWrtShell->EndPara();
982 1 : pWrtShell->Down(/*bSelect=*/false);
983 1 : CPPUNIT_ASSERT_EQUAL(true, pWrtShell->HasReadonlySel());
984 :
985 : // Then enable ignoring of protected areas and make sure that this time the cursor is read-write.
986 1 : pWrtShell->Up(/*bSelect=*/false);
987 1 : SwViewOption aViewOptions(*pWrtShell->GetViewOptions());
988 1 : aViewOptions.SetIgnoreProtectedArea(true);
989 1 : pWrtShell->ApplyViewOptions(aViewOptions);
990 1 : pWrtShell->Down(/*bSelect=*/false);
991 1 : CPPUNIT_ASSERT_EQUAL(false, pWrtShell->HasReadonlySel());
992 1 : }
993 :
994 1 : void SwUiWriterTest::testUndoCharAttribute()
995 : {
996 : // Create a new empty Writer document
997 1 : SwDoc* pDoc = createDoc();
998 1 : SwPaM* pCrsr = pDoc->GetEditShell()->GetCrsr();
999 1 : sw::UndoManager& rUndoManager = pDoc->GetUndoManager();
1000 1 : IDocumentContentOperations & rIDCO(pDoc->getIDocumentContentOperations());
1001 : // Insert some text
1002 1 : rIDCO.InsertString(*pCrsr, "This will be bolded");
1003 : // Position of word 9876543210
1004 : // Use cursor to select part of text
1005 1 : pCrsr->SetMark();
1006 10 : for (int i = 0; i < 9; i++) {
1007 9 : pCrsr->Move(fnMoveBackward);
1008 : }
1009 : // Check that correct text was selected
1010 1 : CPPUNIT_ASSERT_EQUAL(OUString("be bolded"), pCrsr->GetText());
1011 : // Apply a "Bold" attribute to selection
1012 1 : SvxWeightItem aWeightItem(WEIGHT_BOLD, RES_CHRATR_WEIGHT);
1013 1 : rIDCO.InsertPoolItem(*pCrsr, aWeightItem);
1014 2 : SfxItemSet aSet( pDoc->GetAttrPool(), RES_CHRATR_WEIGHT, RES_CHRATR_WEIGHT);
1015 : // Adds selected text's attributes to aSet
1016 1 : pCrsr->GetNode().GetTextNode()->GetAttr(aSet, 10, 19);
1017 1 : SfxPoolItem const * aPoolItem = aSet.GetItem(RES_CHRATR_WEIGHT);
1018 1 : SfxPoolItem& ampPoolItem = aWeightItem;
1019 : // Check that bold is active on the selection; checks if it's in aSet
1020 1 : CPPUNIT_ASSERT_EQUAL((*aPoolItem == ampPoolItem), true);
1021 : // Invoke Undo
1022 1 : rUndoManager.Undo();
1023 : // Check that bold is no longer active
1024 1 : aSet.ClearItem(RES_CHRATR_WEIGHT);
1025 1 : pCrsr->GetNode().GetTextNode()->GetAttr(aSet, 10, 19);
1026 1 : aPoolItem = aSet.GetItem(RES_CHRATR_WEIGHT);
1027 2 : CPPUNIT_ASSERT_EQUAL((*aPoolItem == ampPoolItem), false);
1028 1 : }
1029 :
1030 1 : void SwUiWriterTest::testTdf86639()
1031 : {
1032 1 : SwDoc* pDoc = createDoc("tdf86639.rtf");
1033 1 : SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
1034 1 : SwTextFormatColl* pColl = pDoc->FindTextFormatCollByName("Heading");
1035 1 : pWrtShell->SetTextFormatColl(pColl);
1036 1 : OUString aExpected = pColl->GetAttrSet().GetFont().GetFamilyName();
1037 : // This was Calibri, should be Liberation Sans.
1038 1 : CPPUNIT_ASSERT_EQUAL(aExpected, getProperty<OUString>(getRun(getParagraph(1), 1), "CharFontName"));
1039 1 : }
1040 :
1041 1 : void SwUiWriterTest::testTdf90883TableBoxGetCoordinates()
1042 : {
1043 1 : SwDoc* pDoc = createDoc("tdf90883.odt");
1044 1 : SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
1045 1 : pWrtShell->Down(true);
1046 1 : SwSelBoxes aBoxes;
1047 1 : ::GetTableSel( *pWrtShell, aBoxes );
1048 1 : CPPUNIT_ASSERT_EQUAL( 2, (int)aBoxes.size() );
1049 1 : Point pos ( aBoxes[0]->GetCoordinates() );
1050 1 : CPPUNIT_ASSERT_EQUAL( 1, (int)pos.X() );
1051 1 : CPPUNIT_ASSERT_EQUAL( 1, (int)pos.Y() );
1052 1 : pos = aBoxes[1]->GetCoordinates();
1053 1 : CPPUNIT_ASSERT_EQUAL( 1, (int)pos.X() );
1054 1 : CPPUNIT_ASSERT_EQUAL( 2, (int)pos.Y() );
1055 1 : }
1056 :
1057 1 : void SwUiWriterTest::testEmbeddedDataSource()
1058 : {
1059 : #if !defined(MACOSX)
1060 : // Initially no data source.
1061 1 : uno::Reference<uno::XComponentContext> xComponentContext(comphelper::getProcessComponentContext());
1062 2 : uno::Reference<sdb::XDatabaseContext> xDatabaseContext = sdb::DatabaseContext::create(xComponentContext);
1063 1 : CPPUNIT_ASSERT(!xDatabaseContext->hasByName("calc-data-source"));
1064 :
1065 : // Load: should have a component and a data source, too.
1066 1 : load(DATA_DIRECTORY, "embedded-data-source.odt");
1067 1 : CPPUNIT_ASSERT(mxComponent.is());
1068 1 : CPPUNIT_ASSERT(xDatabaseContext->hasByName("calc-data-source"));
1069 :
1070 : // Data source has a table named Sheet1.
1071 2 : uno::Reference<sdbc::XDataSource> xDataSource(xDatabaseContext->getByName("calc-data-source"), uno::UNO_QUERY);
1072 1 : CPPUNIT_ASSERT(xDataSource.is());
1073 2 : uno::Reference<sdbcx::XTablesSupplier> xConnection(xDataSource->getConnection("", ""), uno::UNO_QUERY);
1074 2 : uno::Reference<container::XNameAccess> xTables(xConnection->getTables(), uno::UNO_QUERY);
1075 1 : CPPUNIT_ASSERT(xTables.is());
1076 1 : CPPUNIT_ASSERT(xTables->hasByName("Sheet1"));
1077 :
1078 : // Reload: should still have a component and a data source, too.
1079 1 : reload("writer8", "embedded-data-source.odt");
1080 1 : CPPUNIT_ASSERT(mxComponent.is());
1081 1 : CPPUNIT_ASSERT(xDatabaseContext->hasByName("calc-data-source"));
1082 :
1083 : // Data source has a table named Sheet1 after saving to a different directory.
1084 1 : xDataSource.set(xDatabaseContext->getByName("calc-data-source"), uno::UNO_QUERY);
1085 1 : CPPUNIT_ASSERT(xDataSource.is());
1086 1 : xConnection.set(xDataSource->getConnection("", ""), uno::UNO_QUERY);
1087 1 : xTables.set(xConnection->getTables(), uno::UNO_QUERY);
1088 1 : CPPUNIT_ASSERT(xTables.is());
1089 1 : CPPUNIT_ASSERT(xTables->hasByName("Sheet1"));
1090 :
1091 : // Close: should not have a data source anymore.
1092 1 : mxComponent->dispose();
1093 1 : mxComponent.clear();
1094 2 : CPPUNIT_ASSERT(!xDatabaseContext->hasByName("calc-data-source"));
1095 : #endif
1096 1 : }
1097 :
1098 1 : void SwUiWriterTest::testUnoCursorPointer()
1099 : {
1100 : auto xDocComponent(loadFromDesktop(
1101 2 : getURLFromSrc(DATA_DIRECTORY) + "empty.odt",
1102 3 : "com.sun.star.text.TextDocument"));
1103 : auto pxDocDocument(
1104 1 : dynamic_cast<SwXTextDocument *>(xDocComponent.get()));
1105 1 : CPPUNIT_ASSERT(pxDocDocument);
1106 1 : SwDoc* const pDoc(pxDocDocument->GetDocShell()->GetDoc());
1107 2 : std::unique_ptr<SwNodeIndex> xIdx(new SwNodeIndex(pDoc->GetNodes().GetEndOfContent(), -1));
1108 2 : std::unique_ptr<SwPosition> xPos(new SwPosition(*xIdx));
1109 2 : sw::UnoCursorPointer pCursor(pDoc->CreateUnoCrsr(*xPos));
1110 1 : CPPUNIT_ASSERT(static_cast<bool>(pCursor));
1111 1 : xPos.reset(); // we need to kill the SwPosition before disposing
1112 1 : xIdx.reset(); // we need to kill the SwNodeIndex before disposing
1113 1 : xDocComponent->dispose();
1114 2 : CPPUNIT_ASSERT(!static_cast<bool>(pCursor));
1115 1 : }
1116 :
1117 1 : CPPUNIT_TEST_SUITE_REGISTRATION(SwUiWriterTest);
1118 4 : CPPUNIT_PLUGIN_IMPLEMENT();
1119 :
1120 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|