1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 #include <swmodeltestbase.hxx>
12 #include <boost/property_tree/json_parser.hpp>
14 #include <com/sun/star/frame/XModel2.hpp>
15 #include <com/sun/star/text/XTextViewTextRangeSupplier.hpp>
16 #include <com/sun/star/util/XCloseable.hpp>
17 #include <com/sun/star/text/XTextDocument.hpp>
18 #include <com/sun/star/beans/PropertyAttribute.hpp>
20 #include <vcl/scheduler.hxx>
21 #include <tools/json_writer.hxx>
22 #include <comphelper/propertyvalue.hxx>
23 #include <xmloff/odffields.hxx>
27 #include <unotextrange.hxx>
30 #include <rootfrm.hxx>
31 #include <sortedobjs.hxx>
32 #include <anchoredobject.hxx>
33 #include <frameformats.hxx>
34 #include <fmtanchr.hxx>
35 #include <unotxdoc.hxx>
37 /// Covers sw/source/uibase/uno/ fixes.
38 class SwUibaseUnoTest
: public SwModelTestBase
42 : SwModelTestBase("/sw/qa/uibase/uno/data/")
47 CPPUNIT_TEST_FIXTURE(SwUibaseUnoTest
, testLockControllers
)
51 uno::Reference
<frame::XModel
> xModel(mxComponent
, uno::UNO_QUERY_THROW
);
52 xModel
->lockControllers();
55 uno::Reference
<util::XCloseable
> xCloseable(mxComponent
, uno::UNO_QUERY_THROW
);
56 xCloseable
->close(false);
58 // Without the accompanying fix in place, this test would have crashed.
62 CPPUNIT_TEST_FIXTURE(SwUibaseUnoTest
, testCondFieldCachedValue
)
64 createSwDoc("cond-field-cached-value.docx");
65 Scheduler::ProcessEventsToIdle();
67 // Without the accompanying fix in place, this test would have failed with:
70 // i.e. the conditional field lost its cached content.
74 CPPUNIT_TEST_FIXTURE(SwUibaseUnoTest
, testCreateTextRangeByPixelPosition
)
76 // Given a document with 2 characters, and the pixel position of the point between them:
78 SwDoc
* pDoc
= getSwDoc();
79 SwDocShell
* pDocShell
= pDoc
->GetDocShell();
80 SwWrtShell
* pWrtShell
= pDocShell
->GetWrtShell();
81 pWrtShell
->Insert2("AZ");
82 pWrtShell
->Left(SwCursorSkipMode::Chars
, /*bSelect=*/false, 1, /*bBasicCall=*/false);
83 Point aLogic
= pWrtShell
->GetCharRect().Center();
84 SwView
* pView
= pDocShell
->GetView();
85 SwEditWin
& rEditWin
= pView
->GetEditWin();
86 Point aPixel
= rEditWin
.LogicToPixel(aLogic
);
88 // When converting that pixel position to a document model position (text range):
89 uno::Reference
<frame::XModel2
> xModel(mxComponent
, uno::UNO_QUERY
);
90 uno::Reference
<container::XEnumeration
> xControllers
= xModel
->getControllers();
91 uno::Reference
<text::XTextViewTextRangeSupplier
> xController(xControllers
->nextElement(),
93 awt::Point
aPoint(aPixel
.getX(), aPixel
.getY());
94 uno::Reference
<text::XTextRange
> xTextRange
95 = xController
->createTextRangeByPixelPosition(aPoint
);
97 // Then make sure that text range points after the first character:
98 auto pTextRange
= dynamic_cast<SwXTextRange
*>(xTextRange
.get());
99 SwPaM
aPaM(pDoc
->GetNodes());
100 pTextRange
->GetPositions(aPaM
);
101 sal_Int32 nActual
= aPaM
.GetPoint()->GetContentIndex();
102 // Without the needed PixelToLogic() call in place, this test would have failed with:
105 // i.e. the returned text range pointed before the first character, not between the first and
106 // the second character.
107 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32
>(1), nActual
);
110 CPPUNIT_TEST_FIXTURE(SwUibaseUnoTest
, testCreateTextRangeByPixelPositionGraphic
)
112 // Given a document with an as-char image and the center of that image in pixels:
114 uno::Reference
<lang::XMultiServiceFactory
> xFactory(mxComponent
, uno::UNO_QUERY
);
115 uno::Reference
<beans::XPropertySet
> xTextGraphic(
116 xFactory
->createInstance("com.sun.star.text.TextGraphicObject"), uno::UNO_QUERY
);
117 xTextGraphic
->setPropertyValue("AnchorType",
118 uno::Any(text::TextContentAnchorType_AS_CHARACTER
));
119 xTextGraphic
->setPropertyValue("Width", uno::Any(static_cast<sal_Int32
>(10000)));
120 xTextGraphic
->setPropertyValue("Height", uno::Any(static_cast<sal_Int32
>(10000)));
121 uno::Reference
<text::XTextDocument
> xTextDocument(mxComponent
, uno::UNO_QUERY
);
122 uno::Reference
<text::XText
> xBodyText
= xTextDocument
->getText();
123 uno::Reference
<text::XTextCursor
> xCursor(xBodyText
->createTextCursor());
124 uno::Reference
<text::XTextContent
> xTextContent(xTextGraphic
, uno::UNO_QUERY
);
125 xBodyText
->insertTextContent(xCursor
, xTextContent
, false);
126 SwDoc
* pDoc
= getSwDoc();
127 SwDocShell
* pDocShell
= pDoc
->GetDocShell();
128 SwWrtShell
* pWrtShell
= pDocShell
->GetWrtShell();
129 SwRootFrame
* pLayout
= pWrtShell
->GetLayout();
130 SwFrame
* pPage
= pLayout
->GetLower();
131 SwFrame
* pBody
= pPage
->GetLower();
132 SwFrame
* pText
= pBody
->GetLower();
133 SwSortedObjs
& rDrawObjs
= *pText
->GetDrawObjs();
134 SwAnchoredObject
* pAnchored
= rDrawObjs
[0];
135 Point aLogic
= pAnchored
->GetObjRect().Center();
136 SwView
* pView
= pDocShell
->GetView();
137 SwEditWin
& rEditWin
= pView
->GetEditWin();
138 Point aPixel
= rEditWin
.LogicToPixel(aLogic
);
140 // When converting that pixel position to a document model position (text range):
141 uno::Reference
<frame::XModel2
> xModel(mxComponent
, uno::UNO_QUERY
);
142 uno::Reference
<container::XEnumeration
> xControllers
= xModel
->getControllers();
143 uno::Reference
<text::XTextViewTextRangeSupplier
> xController(xControllers
->nextElement(),
145 awt::Point
aPoint(aPixel
.getX(), aPixel
.getY());
146 // Without the accompanying fix in place, this test would have crashed, because an XTextRange
147 // can't point to a graphic node.
148 uno::Reference
<text::XTextRange
> xTextRange
149 = xController
->createTextRangeByPixelPosition(aPoint
);
151 // Then make sure that the anchor of the image is returned:
152 const auto& rFormats
= *pDoc
->GetSpzFrameFormats();
153 const auto pFormat
= rFormats
[0];
154 SwPosition
aAnchorPos(*pFormat
->GetAnchor().GetContentAnchor());
155 auto pTextRange
= dynamic_cast<SwXTextRange
*>(xTextRange
.get());
156 SwPaM
aPaM(pDoc
->GetNodes());
157 pTextRange
->GetPositions(aPaM
);
158 CPPUNIT_ASSERT_EQUAL(aAnchorPos
, *aPaM
.GetPoint());
161 CPPUNIT_TEST_FIXTURE(SwUibaseUnoTest
, testCreateTextRangeByPixelPositionAtPageGraphic
)
163 // Given a document with an at-page anchored image:
165 uno::Reference
<lang::XMultiServiceFactory
> xFactory(mxComponent
, uno::UNO_QUERY
);
166 uno::Reference
<beans::XPropertySet
> xTextGraphic(
167 xFactory
->createInstance("com.sun.star.text.TextGraphicObject"), uno::UNO_QUERY
);
168 xTextGraphic
->setPropertyValue("AnchorType", uno::Any(text::TextContentAnchorType_AT_PAGE
));
169 xTextGraphic
->setPropertyValue("AnchorPageNo", uno::Any(static_cast<sal_Int16
>(1)));
170 xTextGraphic
->setPropertyValue("Width", uno::Any(static_cast<sal_Int32
>(10000)));
171 xTextGraphic
->setPropertyValue("Height", uno::Any(static_cast<sal_Int32
>(10000)));
172 uno::Reference
<text::XTextDocument
> xTextDocument(mxComponent
, uno::UNO_QUERY
);
173 uno::Reference
<text::XText
> xBodyText
= xTextDocument
->getText();
174 uno::Reference
<text::XTextCursor
> xCursor(xBodyText
->createTextCursor());
175 uno::Reference
<text::XTextContent
> xTextContent(xTextGraphic
, uno::UNO_QUERY
);
176 xBodyText
->insertTextContent(xCursor
, xTextContent
, false);
177 SwDoc
* pDoc
= getSwDoc();
178 SwDocShell
* pDocShell
= pDoc
->GetDocShell();
179 SwWrtShell
* pWrtShell
= pDocShell
->GetWrtShell();
180 SwRootFrame
* pLayout
= pWrtShell
->GetLayout();
181 SwFrame
* pPage
= pLayout
->GetLower();
182 SwSortedObjs
& rDrawObjs
= *pPage
->GetDrawObjs();
183 SwAnchoredObject
* pAnchored
= rDrawObjs
[0];
184 Point aLogic
= pAnchored
->GetObjRect().Center();
185 SwView
* pView
= pDocShell
->GetView();
186 SwEditWin
& rEditWin
= pView
->GetEditWin();
187 Point aPixel
= rEditWin
.LogicToPixel(aLogic
);
189 // When asking for the doc model pos of the image's anchor by pixel position:
190 uno::Reference
<frame::XModel2
> xModel(mxComponent
, uno::UNO_QUERY
);
191 uno::Reference
<container::XEnumeration
> xControllers
= xModel
->getControllers();
192 uno::Reference
<text::XTextViewTextRangeSupplier
> xController(xControllers
->nextElement(),
194 awt::Point
aPoint(aPixel
.getX(), aPixel
.getY());
195 // Without the accompanying fix in place, this test would have crashed.
196 uno::Reference
<text::XTextRange
> xTextRange
197 = xController
->createTextRangeByPixelPosition(aPoint
);
199 // Then make sure that the result is empty, since the image is at-page anchored:
200 CPPUNIT_ASSERT(!xTextRange
.is());
203 CPPUNIT_TEST_FIXTURE(SwUibaseUnoTest
, testGetTextFormFields
)
205 // Given a document with 3 fieldmarks: 2 zotero items and a zotero
208 for (int i
= 0; i
< 2; ++i
)
210 uno::Sequence
<css::beans::PropertyValue
> aArgs
= {
211 comphelper::makePropertyValue("FieldType", uno::Any(OUString(ODF_UNHANDLED
))),
212 comphelper::makePropertyValue("FieldCommand",
213 uno::Any(OUString("ADDIN ZOTERO_ITEM foo bar"))),
214 comphelper::makePropertyValue("FieldResult", uno::Any(OUString("result"))),
216 dispatchCommand(mxComponent
, ".uno:TextFormField", aArgs
);
219 uno::Sequence
<css::beans::PropertyValue
> aArgs
= {
220 comphelper::makePropertyValue("FieldType", uno::Any(OUString(ODF_UNHANDLED
))),
221 comphelper::makePropertyValue("FieldCommand",
222 uno::Any(OUString("ADDIN ZOTERO_BIBL foo bar"))),
223 comphelper::makePropertyValue("FieldResult",
224 uno::Any(OUString("<p>aaa</p><p>bbb</p>"))),
226 dispatchCommand(mxComponent
, ".uno:TextFormField", aArgs
);
229 // When getting the zotero items:
230 tools::JsonWriter aJsonWriter
;
231 std::string_view
aCommand(".uno:TextFormFields?type=vnd.oasis.opendocument.field.UNHANDLED&"
232 "commandPrefix=ADDIN%20ZOTERO_ITEM");
233 auto pXTextDocument
= dynamic_cast<SwXTextDocument
*>(mxComponent
.get());
234 pXTextDocument
->getCommandValues(aJsonWriter
, aCommand
);
236 // Then make sure we find the 2 items and ignore the bibliography:
237 OString
pJSON(aJsonWriter
.finishAndGetAsOString());
238 std::stringstream
aStream((std::string(pJSON
)));
239 boost::property_tree::ptree aTree
;
240 boost::property_tree::read_json(aStream
, aTree
);
241 // Without the accompanying fix in place, this test would have failed with:
242 // - No such node (fields)
243 // i.e. the returned JSON was just empty.
244 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), aTree
.get_child("fields").count(""));
247 CPPUNIT_TEST_FIXTURE(SwUibaseUnoTest
, testGetDocumentProperties
)
249 // Given a document with 3 custom properties: 2 Zotero ones and one other:
251 SwDoc
* pDoc
= getSwDoc();
252 SwDocShell
* pDocShell
= pDoc
->GetDocShell();
253 uno::Reference
<document::XDocumentPropertiesSupplier
> xDPS(pDocShell
->GetModel(),
255 uno::Reference
<document::XDocumentProperties
> xDP
= xDPS
->getDocumentProperties();
256 uno::Reference
<beans::XPropertyContainer
> xUDP
= xDP
->getUserDefinedProperties();
257 xUDP
->addProperty("ZOTERO_PREF_1", beans::PropertyAttribute::REMOVABLE
,
258 uno::Any(OUString("foo")));
259 xUDP
->addProperty("ZOTERO_PREF_2", beans::PropertyAttribute::REMOVABLE
,
260 uno::Any(OUString("bar")));
261 xUDP
->addProperty("OTHER", beans::PropertyAttribute::REMOVABLE
, uno::Any(OUString("baz")));
263 // When getting the zotero properties:
264 tools::JsonWriter aJsonWriter
;
265 std::string_view
aCommand(".uno:SetDocumentProperties?namePrefix=ZOTERO_PREF_");
266 auto pXTextDocument
= dynamic_cast<SwXTextDocument
*>(mxComponent
.get());
267 pXTextDocument
->getCommandValues(aJsonWriter
, aCommand
);
269 // Then make sure we find the 2 properties and ignore the other one:
270 OString
pJSON(aJsonWriter
.finishAndGetAsOString());
271 std::stringstream
aStream((std::string(pJSON
)));
272 boost::property_tree::ptree aTree
;
273 boost::property_tree::read_json(aStream
, aTree
);
274 // Without the accompanying fix in place, this test would have failed with:
275 // - No such node (userDefinedProperties)
276 // i.e. the returned JSON was just empty.
277 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2),
278 aTree
.get_child("userDefinedProperties").count(""));
281 CPPUNIT_TEST_FIXTURE(SwUibaseUnoTest
, testGetBookmarks
)
283 // Given a document with 3 bookmarks: 2 zotero references and a zotero bibliography:
286 uno::Sequence
<css::beans::PropertyValue
> aArgs
= {
287 comphelper::makePropertyValue("Bookmark", uno::Any(OUString("ZOTERO_BREF_1"))),
289 dispatchCommand(mxComponent
, ".uno:InsertBookmark", aArgs
);
292 uno::Sequence
<css::beans::PropertyValue
> aArgs
= {
293 comphelper::makePropertyValue("Bookmark", uno::Any(OUString("ZOTERO_BREF_2"))),
295 dispatchCommand(mxComponent
, ".uno:InsertBookmark", aArgs
);
298 uno::Sequence
<css::beans::PropertyValue
> aArgs
= {
299 comphelper::makePropertyValue("Bookmark", uno::Any(OUString("ZOTERO_BIBL"))),
301 dispatchCommand(mxComponent
, ".uno:InsertBookmark", aArgs
);
304 // When getting the reference bookmarks:
305 tools::JsonWriter aJsonWriter
;
306 std::string_view
aCommand(".uno:Bookmarks?namePrefix=ZOTERO_BREF_");
307 auto pXTextDocument
= dynamic_cast<SwXTextDocument
*>(mxComponent
.get());
308 pXTextDocument
->getCommandValues(aJsonWriter
, aCommand
);
310 // Then make sure we get the 2 references but not the bibliography:
311 OString
pJSON(aJsonWriter
.finishAndGetAsOString());
312 std::stringstream
aStream((std::string(pJSON
)));
313 boost::property_tree::ptree aTree
;
314 boost::property_tree::read_json(aStream
, aTree
);
315 // Without the accompanying fix in place, this test would have failed with:
316 // - No such node (bookmarks)
317 // i.e. the returned JSON was just empty.
318 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), aTree
.get_child("bookmarks").count(""));
321 CPPUNIT_TEST_FIXTURE(SwUibaseUnoTest
, testGetFields
)
323 // Given a document with a refmark:
325 SwDoc
* pDoc
= getSwDoc();
326 SwWrtShell
* pWrtShell
= pDoc
->GetDocShell()->GetWrtShell();
327 OUString
aName("ZOTERO_ITEM CSL_CITATION {} ");
328 for (int i
= 0; i
< 5; ++i
)
330 uno::Sequence
<css::beans::PropertyValue
> aArgs
= {
331 comphelper::makePropertyValue("TypeName", uno::Any(OUString("SetRef"))),
332 comphelper::makePropertyValue("Name", uno::Any(aName
+ OUString::number(i
+ 1))),
333 comphelper::makePropertyValue("Content", uno::Any(OUString("mycontent"))),
335 dispatchCommand(mxComponent
, ".uno:InsertField", aArgs
);
336 pWrtShell
->SttEndDoc(/*bStt=*/false);
337 pWrtShell
->SplitNode();
338 pWrtShell
->SttEndDoc(/*bStt=*/false);
341 // When getting the refmarks:
342 tools::JsonWriter aJsonWriter
;
343 std::string_view
aCommand(".uno:Fields?typeName=SetRef&namePrefix=ZOTERO_ITEM%20CSL_CITATION");
344 auto pXTextDocument
= dynamic_cast<SwXTextDocument
*>(mxComponent
.get());
345 pXTextDocument
->getCommandValues(aJsonWriter
, aCommand
);
347 // Then make sure we get the 1 refmark:
348 OString
pJSON(aJsonWriter
.finishAndGetAsOString());
349 std::stringstream
aStream((std::string(pJSON
)));
350 boost::property_tree::ptree aTree
;
351 boost::property_tree::read_json(aStream
, aTree
);
352 // Without the accompanying fix in place, this test would have failed with:
353 // - No such node (setRefs)
354 // i.e. the returned JSON was just empty.
355 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(5), aTree
.get_child("setRefs").count(""));
356 auto it
= aTree
.get_child("setRefs").begin();
357 boost::property_tree::ptree aRef
= (it
++)->second
;
358 CPPUNIT_ASSERT_EQUAL(std::string("ZOTERO_ITEM CSL_CITATION {} 1"),
359 aRef
.get
<std::string
>("name"));
360 aRef
= (it
++)->second
;
361 CPPUNIT_ASSERT_EQUAL(std::string("ZOTERO_ITEM CSL_CITATION {} 2"),
362 aRef
.get
<std::string
>("name"));
363 aRef
= (it
++)->second
;
364 // Without the accompanying fix in place, this test would have failed with:
365 // - Expected: ZOTERO_ITEM CSL_CITATION {} 3
366 // - Actual : ZOTERO_ITEM CSL_CITATION {} 4
367 // i.e. the output was unsorted.
368 CPPUNIT_ASSERT_EQUAL(std::string("ZOTERO_ITEM CSL_CITATION {} 3"),
369 aRef
.get
<std::string
>("name"));
370 aRef
= (it
++)->second
;
371 CPPUNIT_ASSERT_EQUAL(std::string("ZOTERO_ITEM CSL_CITATION {} 4"),
372 aRef
.get
<std::string
>("name"));
373 aRef
= (it
++)->second
;
374 CPPUNIT_ASSERT_EQUAL(std::string("ZOTERO_ITEM CSL_CITATION {} 5"),
375 aRef
.get
<std::string
>("name"));
378 CPPUNIT_TEST_FIXTURE(SwUibaseUnoTest
, testGetTextFormField
)
380 // Given a document with a fieldmark:
382 uno::Sequence
<css::beans::PropertyValue
> aArgs
= {
383 comphelper::makePropertyValue("FieldType", uno::Any(OUString(ODF_UNHANDLED
))),
384 comphelper::makePropertyValue("FieldCommand",
385 uno::Any(OUString("ADDIN ZOTERO_ITEM foo bar"))),
386 comphelper::makePropertyValue("FieldResult", uno::Any(OUString("result"))),
388 dispatchCommand(mxComponent
, ".uno:TextFormField", aArgs
);
390 // When stepping into the fieldmark with the cursor and getting the command value for
391 // uno:TextFormField:
392 SwDoc
* pDoc
= getSwDoc();
393 SwWrtShell
* pWrtShell
= pDoc
->GetDocShell()->GetWrtShell();
394 pWrtShell
->SttEndDoc(/*bStt=*/false);
395 pWrtShell
->Left(SwCursorSkipMode::Chars
, /*bSelect=*/false, 1, /*bBasicCall=*/false);
396 tools::JsonWriter aJsonWriter
;
397 std::string_view
aCommand(".uno:TextFormField?type=vnd.oasis.opendocument.field.UNHANDLED&"
398 "commandPrefix=ADDIN%20ZOTERO_ITEM");
399 auto pXTextDocument
= dynamic_cast<SwXTextDocument
*>(mxComponent
.get());
400 pXTextDocument
->getCommandValues(aJsonWriter
, aCommand
);
402 // Then make sure we find the inserted fieldmark:
403 OString
pJSON(aJsonWriter
.finishAndGetAsOString());
404 std::stringstream
aStream((std::string(pJSON
)));
405 boost::property_tree::ptree aTree
;
406 boost::property_tree::read_json(aStream
, aTree
);
407 // Without the accompanying fix in place, this test would have failed with:
408 // - No such node (type)
409 // i.e. the returned JSON was just an empty object.
410 auto field
= aTree
.get_child("field");
411 CPPUNIT_ASSERT_EQUAL(std::string("vnd.oasis.opendocument.field.UNHANDLED"),
412 field
.get
<std::string
>("type"));
413 CPPUNIT_ASSERT_EQUAL(std::string("ADDIN ZOTERO_ITEM foo bar"),
414 field
.get
<std::string
>("command"));
417 CPPUNIT_TEST_FIXTURE(SwUibaseUnoTest
, testGetSections
)
419 // Given a document with a section:
421 uno::Sequence
<css::beans::PropertyValue
> aArgs
= {
422 comphelper::makePropertyValue(
423 "RegionName", uno::Any(OUString("ZOTERO_BIBL {} CSL_BIBLIOGRAPHY RNDRfiit6mXBc"))),
424 comphelper::makePropertyValue("Content", uno::Any(OUString("<p>aaa</p><p>bbb</p>"))),
426 dispatchCommand(mxComponent
, ".uno:InsertSection", aArgs
);
428 // When asking for a list of section names:
429 tools::JsonWriter aJsonWriter
;
430 std::string_view
aCommand(".uno:Sections?namePrefix=ZOTERO_BIBL");
431 auto pXTextDocument
= dynamic_cast<SwXTextDocument
*>(mxComponent
.get());
432 pXTextDocument
->getCommandValues(aJsonWriter
, aCommand
);
434 // Make sure we find our just inserted section:
435 OString
pJSON(aJsonWriter
.finishAndGetAsOString());
436 std::stringstream
aStream((std::string(pJSON
)));
437 boost::property_tree::ptree aTree
;
438 boost::property_tree::read_json(aStream
, aTree
);
439 // Without the accompanying fix in place, this test would have failed with:
440 // - No such node (sections)
441 // i.e. the returned JSON was an empty object.
442 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aTree
.get_child("sections").count(""));
445 CPPUNIT_TEST_FIXTURE(SwUibaseUnoTest
, testGetBookmark
)
447 // Given a document with a bookmark:
449 uno::Sequence
<css::beans::PropertyValue
> aArgs
= {
450 comphelper::makePropertyValue("Bookmark", uno::Any(OUString("ZOTERO_BREF_1"))),
451 comphelper::makePropertyValue("BookmarkText", uno::Any(OUString("<p>aaa</p><p>bbb</p>"))),
453 dispatchCommand(mxComponent
, ".uno:InsertBookmark", aArgs
);
455 // When stepping into the bookmark with the cursor and getting the command value for
457 SwDoc
* pDoc
= getSwDoc();
458 SwWrtShell
* pWrtShell
= pDoc
->GetDocShell()->GetWrtShell();
459 pWrtShell
->SttEndDoc(/*bStt=*/false);
460 pWrtShell
->Left(SwCursorSkipMode::Chars
, /*bSelect=*/false, 1, /*bBasicCall=*/false);
461 tools::JsonWriter aJsonWriter
;
462 std::string_view
aCommand(".uno:Bookmark?namePrefix=ZOTERO_BREF_");
463 auto pXTextDocument
= dynamic_cast<SwXTextDocument
*>(mxComponent
.get());
464 pXTextDocument
->getCommandValues(aJsonWriter
, aCommand
);
466 // Then make sure we find the inserted bookmark:
467 OString
pJSON(aJsonWriter
.finishAndGetAsOString());
468 std::stringstream
aStream((std::string(pJSON
)));
469 boost::property_tree::ptree aTree
;
470 boost::property_tree::read_json(aStream
, aTree
);
471 boost::property_tree::ptree aBookmark
= aTree
.get_child("bookmark");
472 // Without the accompanying fix in place, this test would have failed with:
473 // - No such node (bookmark)
474 // i.e. the returned JSON was an empty object.
475 CPPUNIT_ASSERT_EQUAL(std::string("ZOTERO_BREF_1"), aBookmark
.get
<std::string
>("name"));
478 CPPUNIT_TEST_FIXTURE(SwUibaseUnoTest
, testGetField
)
480 // Given a document with a refmark:
482 uno::Sequence
<css::beans::PropertyValue
> aArgs
= {
483 comphelper::makePropertyValue("TypeName", uno::Any(OUString("SetRef"))),
484 comphelper::makePropertyValue("Name",
485 uno::Any(OUString("ZOTERO_ITEM CSL_CITATION {} refmark"))),
486 comphelper::makePropertyValue("Content", uno::Any(OUString("content"))),
488 dispatchCommand(mxComponent
, ".uno:InsertField", aArgs
);
490 // When in the refmark with the cursor and getting the command value for .uno:Field:
491 SwDoc
* pDoc
= getSwDoc();
492 SwWrtShell
* pWrtShell
= pDoc
->GetDocShell()->GetWrtShell();
493 pWrtShell
->SttEndDoc(/*bStt=*/false);
494 pWrtShell
->Left(SwCursorSkipMode::Chars
, /*bSelect=*/false, 1, /*bBasicCall=*/false);
495 tools::JsonWriter aJsonWriter
;
496 std::string_view
aCommand(".uno:Field?typeName=SetRef&namePrefix=ZOTERO_ITEM%20CSL_CITATION");
497 auto pXTextDocument
= dynamic_cast<SwXTextDocument
*>(mxComponent
.get());
498 pXTextDocument
->getCommandValues(aJsonWriter
, aCommand
);
500 // Then make sure we find the inserted refmark:
501 OString
pJSON(aJsonWriter
.finishAndGetAsOString());
502 std::stringstream
aStream((std::string(pJSON
)));
503 boost::property_tree::ptree aTree
;
504 boost::property_tree::read_json(aStream
, aTree
);
505 boost::property_tree::ptree aBookmark
= aTree
.get_child("setRef");
506 // Without the accompanying fix in place, this test would have failed with:
507 // - No such node (setRef)
508 // i.e. the returned JSON was an empty object.
509 CPPUNIT_ASSERT_EQUAL(std::string("ZOTERO_ITEM CSL_CITATION {} refmark"),
510 aBookmark
.get
<std::string
>("name"));
513 CPPUNIT_TEST_FIXTURE(SwUibaseUnoTest
, testDoNotBreakWrappedTables
)
515 // Given an empty document:
518 // When checking the state of the DoNotBreakWrappedTables compat flag:
519 uno::Reference
<lang::XMultiServiceFactory
> xDocument(mxComponent
, uno::UNO_QUERY
);
520 uno::Reference
<beans::XPropertySet
> xSettings(
521 xDocument
->createInstance("com.sun.star.document.Settings"), uno::UNO_QUERY
);
522 bool bDoNotBreakWrappedTables
{};
523 // Without the accompanying fix in place, this test would have failed with:
524 // An uncaught exception of type com.sun.star.beans.UnknownPropertyException
525 // i.e. the compat flag was not recognized.
526 xSettings
->getPropertyValue("DoNotBreakWrappedTables") >>= bDoNotBreakWrappedTables
;
527 // Then make sure it's false by default:
528 CPPUNIT_ASSERT(!bDoNotBreakWrappedTables
);
530 // And when setting DoNotBreakWrappedTables=true:
531 xSettings
->setPropertyValue("DoNotBreakWrappedTables", uno::Any(true));
532 // Then make sure it gets enabled:
533 xSettings
->getPropertyValue("DoNotBreakWrappedTables") >>= bDoNotBreakWrappedTables
;
534 CPPUNIT_ASSERT(bDoNotBreakWrappedTables
);
537 CPPUNIT_TEST_FIXTURE(SwUibaseUnoTest
, testAllowTextAfterFloatingTableBreak
)
539 // Given an empty document:
542 // When checking the state of the AllowTextAfterFloatingTableBreak compat flag:
543 uno::Reference
<lang::XMultiServiceFactory
> xDocument(mxComponent
, uno::UNO_QUERY
);
544 uno::Reference
<beans::XPropertySet
> xSettings(
545 xDocument
->createInstance("com.sun.star.document.Settings"), uno::UNO_QUERY
);
546 bool bAllowTextAfterFloatingTableBreak
{};
547 // Without the accompanying fix in place, this test would have failed with:
548 // An uncaught exception of type com.sun.star.beans.UnknownPropertyException
549 // i.e. the compat flag was not recognized.
550 xSettings
->getPropertyValue("AllowTextAfterFloatingTableBreak")
551 >>= bAllowTextAfterFloatingTableBreak
;
552 // Then make sure it's false by default:
553 CPPUNIT_ASSERT(!bAllowTextAfterFloatingTableBreak
);
555 // And when setting AllowTextAfterFloatingTableBreak=true:
556 xSettings
->setPropertyValue("AllowTextAfterFloatingTableBreak", uno::Any(true));
557 // Then make sure it gets enabled:
558 xSettings
->getPropertyValue("AllowTextAfterFloatingTableBreak")
559 >>= bAllowTextAfterFloatingTableBreak
;
560 CPPUNIT_ASSERT(bAllowTextAfterFloatingTableBreak
);
563 CPPUNIT_PLUGIN_IMPLEMENT();
565 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */