1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 #include <swmodeltestbase.hxx>
12 #include <com/sun/star/frame/XStorable.hpp>
13 #include <com/sun/star/packages/zip/ZipFileAccess.hpp>
14 #include <com/sun/star/text/BibliographyDataType.hpp>
15 #include <com/sun/star/text/XTextDocument.hpp>
17 #include <sfx2/dispatch.hxx>
18 #include <sfx2/viewfrm.hxx>
19 #include <svx/svdpage.hxx>
20 #include <editeng/eeitem.hxx>
21 #include <editeng/adjustitem.hxx>
22 #include <editeng/outlobj.hxx>
23 #include <editeng/editobj.hxx>
24 #include <comphelper/processfactory.hxx>
25 #include <comphelper/propertyvalue.hxx>
26 #include <unotools/ucbstreamhelper.hxx>
27 #include <xmloff/odffields.hxx>
28 #include <comphelper/string.hxx>
29 #include <comphelper/propertysequence.hxx>
30 #include <comphelper/sequence.hxx>
31 #include <osl/thread.hxx>
33 #include <IDocumentContentOperations.hxx>
35 #include <fmtanchr.hxx>
38 #include <IDocumentDrawModelAccess.hxx>
39 #include <drawdoc.hxx>
45 /// Covers sw/source/uibase/shells/ fixes.
46 class SwUibaseShellsTest
: public SwModelTestBase
50 : SwModelTestBase("/sw/qa/uibase/shells/data/")
55 CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest
, testTdf130179
)
58 SwDoc
* pDoc
= getSwDoc();
59 IDocumentContentOperations
& rIDCO
= pDoc
->getIDocumentContentOperations();
60 SwCursorShell
* pShell(pDoc
->GetEditShell());
61 SfxItemSet
aFrameSet(pDoc
->GetAttrPool(), svl::Items
<RES_FRMATR_BEGIN
, RES_FRMATR_END
- 1>);
62 SfxItemSet
aGrfSet(pDoc
->GetAttrPool(), svl::Items
<RES_GRFATR_BEGIN
, RES_GRFATR_END
- 1>);
63 SwFormatAnchor
aAnchor(RndStdIds::FLY_AT_PARA
);
64 aFrameSet
.Put(aAnchor
);
66 CPPUNIT_ASSERT(rIDCO
.InsertGraphic(*pShell
->GetCursor(), OUString(), OUString(), &aGrf
,
67 &aFrameSet
, &aGrfSet
, nullptr));
68 CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc
->GetFlyCount(FLYCNTTYPE_GRF
));
70 SwView
* pView
= pDoc
->GetDocShell()->GetView();
73 std::unique_ptr
<SfxPoolItem
> pItem
;
74 pView
->GetViewFrame().GetBindings().QueryState(FN_POSTIT
, pItem
);
75 // Without the accompanying fix in place, this test would have failed with:
77 // - Expression: !pItem
78 // i.e. comment insertion was enabled for an at-para anchored image.
79 CPPUNIT_ASSERT(!pItem
);
82 CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest
, testShapeTextAlignment
)
84 // FIXME find out why this fails on macOS/Windows
85 #if !defined(MACOSX) && !defined(_WIN32)
86 // Create a document with a rectangle in it.
88 SwDoc
* pDoc
= getSwDoc();
89 SwWrtShell
* pWrtShell
= pDoc
->GetDocShell()->GetWrtShell();
90 Point
aStartPos(1000, 1000);
91 pWrtShell
->BeginCreate(SdrObjKind::Rectangle
, aStartPos
);
92 Point
aMovePos(2000, 2000);
93 pWrtShell
->MoveCreate(aMovePos
);
94 pWrtShell
->EndCreate(SdrCreateCmd::ForceEnd
);
96 // Start shape text edit.
97 SwView
* pView
= pDoc
->GetDocShell()->GetView();
100 // Start the actual text edit.
101 SdrPage
* pPage
= pWrtShell
->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0);
102 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pPage
->GetObjCount());
103 SdrObject
* pObject
= pPage
->GetObj(0);
104 pView
->EnterShapeDrawTextMode(pObject
);
105 pView
->AttrChangedNotify(nullptr);
107 // Change paragraph adjustment to center.
108 pView
->GetViewFrame().GetDispatcher()->Execute(SID_ATTR_PARA_ADJUST_CENTER
,
109 SfxCallMode::SYNCHRON
);
111 // End shape text edit.
112 pWrtShell
->EndTextEdit();
114 const OutlinerParaObject
* pOutliner
= pObject
->GetOutlinerParaObject();
115 // Without the accompanying fix in place, this test would have failed, because the shape had no
116 // text or text formatting. In other words the paragraph adjustment command was ignored.
117 CPPUNIT_ASSERT(pOutliner
);
118 const SfxItemSet
& rParaAttribs
= pOutliner
->GetTextObject().GetParaAttribs(0);
119 SvxAdjust eAdjust
= rParaAttribs
.GetItem(EE_PARA_JUST
)->GetAdjust();
120 CPPUNIT_ASSERT_EQUAL(SvxAdjust::Center
, eAdjust
);
124 CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest
, testOleSavePreviewUpdate
)
126 // Load a document with 2 charts in it. The second is down enough that you have to scroll to
127 // trigger its rendering. Previews are missing for both.
128 createSwDoc("ole-save-preview-update.odt");
130 // Explicitly update OLE previews, etc.
131 dispatchCommand(mxComponent
, ".uno:UpdateAll", {});
133 // Save the document and see if we get the previews.
134 uno::Reference
<frame::XStorable
> xStorable(mxComponent
, uno::UNO_QUERY
);
135 xStorable
->storeToURL(maTempFile
.GetURL(), {});
136 uno::Reference
<packages::zip::XZipFileAccess2
> xNameAccess
137 = packages::zip::ZipFileAccess::createWithURL(comphelper::getComponentContext(m_xSFactory
),
138 maTempFile
.GetURL());
140 // Without the accompanying fix in place, this test would have failed, because the object
141 // replacements were not generated, even after UpdateAll.
142 CPPUNIT_ASSERT(xNameAccess
->hasByName("ObjectReplacements/Object 1"));
143 CPPUNIT_ASSERT(xNameAccess
->hasByName("ObjectReplacements/Object 2"));
146 CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest
, testOlePreviewUpdate
)
148 // Given a document with an embedded Writer object:
149 createSwDoc("ole-preview-update.odt");
151 // When updating "all" (including OLE previews):
152 dispatchCommand(mxComponent
, ".uno:UpdateAll", {});
154 // Then make sure the preview is no longer a 0-sized stream:
155 uno::Reference
<frame::XStorable
> xStorable(mxComponent
, uno::UNO_QUERY
);
156 xStorable
->storeToURL(maTempFile
.GetURL(), {});
157 uno::Reference
<packages::zip::XZipFileAccess2
> xNameAccess
158 = packages::zip::ZipFileAccess::createWithURL(comphelper::getComponentContext(m_xSFactory
),
159 maTempFile
.GetURL());
160 uno::Reference
<io::XInputStream
> xInputStream(
161 xNameAccess
->getByName("ObjectReplacements/Object 1"), uno::UNO_QUERY
);
162 std::unique_ptr
<SvStream
> pStream(utl::UcbStreamHelper::CreateStream(xInputStream
, true));
163 // Without the accompanying fix in place, this test would have failed, the stream was still
165 CPPUNIT_ASSERT_GREATER(static_cast<sal_uInt64
>(0), pStream
->remainingSize());
168 CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest
, testBibliographyUrlContextMenu
)
170 // Given a document with a bibliography field:
172 SwDoc
* pDoc
= getSwDoc();
173 uno::Reference
<lang::XMultiServiceFactory
> xFactory(mxComponent
, uno::UNO_QUERY
);
174 uno::Reference
<beans::XPropertySet
> xField(
175 xFactory
->createInstance("com.sun.star.text.TextField.Bibliography"), uno::UNO_QUERY
);
176 uno::Sequence
<beans::PropertyValue
> aFields
= {
177 comphelper::makePropertyValue("BibiliographicType", text::BibliographyDataType::WWW
),
178 comphelper::makePropertyValue("Identifier", OUString("AT")),
179 comphelper::makePropertyValue("Author", OUString("Author")),
180 comphelper::makePropertyValue("Title", OUString("Title")),
181 comphelper::makePropertyValue("URL", OUString("http://www.example.com/test.pdf#page=1")),
183 xField
->setPropertyValue("Fields", uno::Any(aFields
));
184 uno::Reference
<text::XTextDocument
> xTextDocument(mxComponent
, uno::UNO_QUERY
);
185 uno::Reference
<text::XText
> xText
= xTextDocument
->getText();
186 uno::Reference
<text::XTextCursor
> xCursor
= xText
->createTextCursor();
187 uno::Reference
<text::XTextContent
> xContent(xField
, uno::UNO_QUERY
);
188 xText
->insertTextContent(xCursor
, xContent
, /*bAbsorb=*/false);
190 // When selecting the field and opening the context menu:
191 SwDocShell
* pDocShell
= pDoc
->GetDocShell();
192 SwWrtShell
* pWrtShell
= pDocShell
->GetWrtShell();
193 pWrtShell
->Left(SwCursorSkipMode::Chars
, /*bSelect=*/true, 1, /*bBasicCall=*/false);
194 SfxDispatcher
* pDispatcher
= pDocShell
->GetViewShell()->GetViewFrame().GetDispatcher();
195 css::uno::Any aState
;
196 SfxItemState eStateOpen
= pDispatcher
->QueryState(SID_OPEN_HYPERLINK
, aState
);
197 SfxItemState eStateCopy
= pDispatcher
->QueryState(SID_COPY_HYPERLINK_LOCATION
, aState
);
199 // Then the "open hyperlink" and "copy hyperlink location" menu items should be visible:
200 // Without the accompanying fix in place, this test would have failed with:
201 // - Expected: 32 (SfxItemState::DEFAULT)
202 // - Actual : 1 (SfxItemState::DISABLED)
203 // i.e. the menu item was not visible for biblio entry fields with an URL.
204 CPPUNIT_ASSERT_EQUAL(SfxItemState::DEFAULT
, eStateOpen
);
205 CPPUNIT_ASSERT_EQUAL(SfxItemState::DEFAULT
, eStateCopy
);
208 CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest
, testProtectedFieldsCopyHyperlinkLocation
)
210 // Given a test document document that contains:
213 // - bibliography mark
217 // - bibliography table heading
218 // - bibliography entry containing only url
220 createSwDoc("protectedLinkCopy.fodt");
222 // Copy generic hyperlink
223 dispatchCommand(mxComponent
, ".uno:CopyHyperlinkLocation", {});
224 dispatchCommand(mxComponent
, ".uno:GoDown", {});
225 dispatchCommand(mxComponent
, ".uno:Paste", {});
226 // Assert generic hyperlink was correctly copied and pasted
227 CPPUNIT_ASSERT_EQUAL(OUString("http://reset.url/1"), getParagraph(2)->getString());
229 dispatchCommand(mxComponent
, ".uno:GoDown", {});
230 dispatchCommand(mxComponent
, ".uno:GoLeft", {});
231 // Copy bibliography mark hyperlink
232 dispatchCommand(mxComponent
, ".uno:CopyHyperlinkLocation", {});
233 dispatchCommand(mxComponent
, ".uno:GoDown", {});
234 dispatchCommand(mxComponent
, ".uno:Paste", {});
235 // Assert bibliography mark hyperlink was correctly copied and pasted
236 CPPUNIT_ASSERT_EQUAL(OUString("https://test.url/1"), getParagraph(4)->getString());
238 dispatchCommand(mxComponent
, ".uno:GoDown", {});
239 dispatchCommand(mxComponent
, ".uno:GoLeft", {});
240 // Copy generic hyperlink
241 dispatchCommand(mxComponent
, ".uno:CopyHyperlinkLocation", {});
242 dispatchCommand(mxComponent
, ".uno:GoDown", {});
243 dispatchCommand(mxComponent
, ".uno:Paste", {});
244 // Assert generic hyperlink was correctly copied and pasted
245 CPPUNIT_ASSERT_EQUAL(OUString("http://reset.url/2"), getParagraph(6)->getString());
247 dispatchCommand(mxComponent
, ".uno:GoDown", {});
248 dispatchCommand(mxComponent
, ".uno:GoDown", {});
249 dispatchCommand(mxComponent
, ".uno:GoLeft", {});
250 // Copy bibliography table hyperlink
251 dispatchCommand(mxComponent
, ".uno:CopyHyperlinkLocation", {});
252 dispatchCommand(mxComponent
, ".uno:GoDown", {});
253 dispatchCommand(mxComponent
, ".uno:Paste", {});
254 // Assert bibliography table entry hyperlink was correctly copied and pasted
255 CPPUNIT_ASSERT_EQUAL(OUString("https://test.url/1"), getParagraph(9)->getString());
258 CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest
, testBibliographyLocalCopyContextMenu
)
260 // Given a document with a bibliography field's local copy:
262 SwDoc
* pDoc
= getSwDoc();
263 uno::Reference
<lang::XMultiServiceFactory
> xFactory(mxComponent
, uno::UNO_QUERY
);
264 uno::Reference
<beans::XPropertySet
> xField(
265 xFactory
->createInstance("com.sun.star.text.TextField.Bibliography"), uno::UNO_QUERY
);
266 uno::Sequence
<beans::PropertyValue
> aFields
= {
267 comphelper::makePropertyValue("BibiliographicType", text::BibliographyDataType::WWW
),
268 comphelper::makePropertyValue("Identifier", OUString("AT")),
269 comphelper::makePropertyValue("Author", OUString("Author")),
270 comphelper::makePropertyValue("Title", OUString("Title")),
271 comphelper::makePropertyValue("URL", OUString("http://www.example.com/test.pdf#page=1")),
272 comphelper::makePropertyValue("LocalURL", OUString("file:///home/me/test.pdf")),
274 xField
->setPropertyValue("Fields", uno::Any(aFields
));
275 uno::Reference
<text::XTextDocument
> xTextDocument(mxComponent
, uno::UNO_QUERY
);
276 uno::Reference
<text::XText
> xText
= xTextDocument
->getText();
277 uno::Reference
<text::XTextCursor
> xCursor
= xText
->createTextCursor();
278 uno::Reference
<text::XTextContent
> xContent(xField
, uno::UNO_QUERY
);
279 xText
->insertTextContent(xCursor
, xContent
, /*bAbsorb=*/false);
281 // When selecting the field and opening the context menu:
282 SwDocShell
* pDocShell
= pDoc
->GetDocShell();
283 SwWrtShell
* pWrtShell
= pDocShell
->GetWrtShell();
284 pWrtShell
->Left(SwCursorSkipMode::Chars
, /*bSelect=*/true, 1, /*bBasicCall=*/false);
285 SfxDispatcher
* pDispatcher
= pDocShell
->GetViewShell()->GetViewFrame().GetDispatcher();
286 css::uno::Any aState
;
287 SfxItemState eState
= pDispatcher
->QueryState(FN_OPEN_LOCAL_URL
, aState
);
289 // Then the "open local copy" menu item should be visible:
290 // Without the accompanying fix in place, this test would have failed with:
291 // - Expected: 32 (SfxItemState::DEFAULT)
292 // - Actual : 1 (SfxItemState::DISABLED)
293 // i.e. the context menu was disabled all the time, even for biblio fields.
294 CPPUNIT_ASSERT_EQUAL(SfxItemState::DEFAULT
, eState
);
297 CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest
, testContentControlPageBreak
)
299 // Given a document with a content control and a cursor inside the content control:
301 SwDoc
* pDoc
= getSwDoc();
302 uno::Reference
<lang::XMultiServiceFactory
> xMSF(mxComponent
, uno::UNO_QUERY
);
303 uno::Reference
<text::XTextDocument
> xTextDocument(mxComponent
, uno::UNO_QUERY
);
304 uno::Reference
<text::XText
> xText
= xTextDocument
->getText();
305 uno::Reference
<text::XTextCursor
> xCursor
= xText
->createTextCursor();
306 xText
->insertString(xCursor
, "test", /*bAbsorb=*/false);
307 xCursor
->gotoStart(/*bExpand=*/false);
308 xCursor
->gotoEnd(/*bExpand=*/true);
309 uno::Reference
<text::XTextContent
> xContentControl(
310 xMSF
->createInstance("com.sun.star.text.ContentControl"), uno::UNO_QUERY
);
311 xText
->insertTextContent(xCursor
, xContentControl
, /*bAbsorb=*/true);
312 SwWrtShell
* pWrtShell
= pDoc
->GetDocShell()->GetWrtShell();
313 pWrtShell
->SttEndDoc(/*bStt=*/true);
314 pWrtShell
->Right(SwCursorSkipMode::Chars
, /*bSelect=*/false, 1, /*bBasicCall=*/false);
316 // When trying to insert a page break:
317 dispatchCommand(mxComponent
, ".uno:InsertPagebreak", {});
319 // Then make sure that the document still has a single page:
320 // Without the accompanying fix in place, this test would have failed with:
323 // i.e. inline content control had its start and end in different text nodes, which is not
325 CPPUNIT_ASSERT_EQUAL(1, getPages());
328 CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest
, testInsertTextFormField
)
330 // Given an empty document:
332 SwDoc
* pDoc
= getSwDoc();
334 // When inserting an ODF_UNHANDLED fieldmark:
335 OUString
aExpectedCommand("ADDIN ZOTERO_BIBL foo bar");
336 uno::Sequence
<css::beans::PropertyValue
> aArgs
= {
337 comphelper::makePropertyValue("FieldType", uno::Any(OUString(ODF_UNHANDLED
))),
338 comphelper::makePropertyValue("FieldCommand", uno::Any(aExpectedCommand
)),
339 comphelper::makePropertyValue("FieldResult", uno::Any(OUString("<p>aaa</p><p>bbb</p>"))),
341 dispatchCommand(mxComponent
, ".uno:TextFormField", aArgs
);
343 // Then make sure that it's type/name is correct:
344 SwWrtShell
* pWrtShell
= pDoc
->GetDocShell()->GetWrtShell();
345 SwCursor
* pCursor
= pWrtShell
->GetCursor();
346 pCursor
->SttEndDoc(/*bSttDoc=*/true);
347 sw::mark::IFieldmark
* pFieldmark
348 = pDoc
->getIDocumentMarkAccess()->getFieldmarkAt(*pCursor
->GetPoint());
349 CPPUNIT_ASSERT(pFieldmark
);
350 // Without the accompanying fix in place, this test would have failed with:
351 // - Expected: vnd.oasis.opendocument.field.UNHANDLED
352 // - Actual : vnd.oasis.opendocument.field.FORMTEXT
353 // i.e. the custom type parameter was ignored.
354 CPPUNIT_ASSERT_EQUAL(OUString(ODF_UNHANDLED
), pFieldmark
->GetFieldname());
356 auto it
= pFieldmark
->GetParameters()->find(ODF_CODE_PARAM
);
357 CPPUNIT_ASSERT(it
!= pFieldmark
->GetParameters()->end());
358 OUString aActualCommand
;
359 it
->second
>>= aActualCommand
;
360 CPPUNIT_ASSERT_EQUAL(aExpectedCommand
, aActualCommand
);
362 SwPaM
aPam(pFieldmark
->GetMarkStart(), pFieldmark
->GetMarkEnd());
363 // Ignore the leading field start + sep.
364 aPam
.GetMark()->SetContent(aPam
.GetMark()->GetContentIndex() + 2);
365 // Ignore the trailing field end.
366 aPam
.GetPoint()->SetContent(aPam
.GetPoint()->GetContentIndex() - 1);
367 CPPUNIT_ASSERT(aPam
.HasMark());
368 OUString aActualResult
= aPam
.GetText();
369 CPPUNIT_ASSERT_EQUAL(OUString("aaa\nbbb"), aActualResult
);
372 CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest
, testUpdateFieldmarks
)
374 // Given a document with 2 fieldmarks:
377 uno::Sequence
<css::beans::PropertyValue
> aArgs
= {
378 comphelper::makePropertyValue("FieldType", uno::Any(OUString(ODF_UNHANDLED
))),
379 comphelper::makePropertyValue("FieldCommand",
380 uno::Any(OUString("ADDIN ZOTERO_ITEM old command 1"))),
381 comphelper::makePropertyValue("FieldResult", uno::Any(OUString("old result 1"))),
383 dispatchCommand(mxComponent
, ".uno:TextFormField", aArgs
);
386 uno::Sequence
<css::beans::PropertyValue
> aArgs
= {
387 comphelper::makePropertyValue("FieldType", uno::Any(OUString(ODF_UNHANDLED
))),
388 comphelper::makePropertyValue("FieldCommand",
389 uno::Any(OUString("ADDIN ZOTERO_ITEM old command 2"))),
390 comphelper::makePropertyValue("FieldResult", uno::Any(OUString("old result 2"))),
392 dispatchCommand(mxComponent
, ".uno:TextFormField", aArgs
);
395 // When updating those fieldmarks:
396 uno::Sequence
<css::beans::PropertyValue
> aField1
{
397 comphelper::makePropertyValue("FieldType", uno::Any(OUString(ODF_UNHANDLED
))),
398 comphelper::makePropertyValue("FieldCommand",
399 uno::Any(OUString("ADDIN ZOTERO_ITEM new command 1"))),
400 comphelper::makePropertyValue("FieldResult", uno::Any(OUString("new result 1"))),
402 uno::Sequence
<css::beans::PropertyValue
> aField2
{
403 comphelper::makePropertyValue("FieldType", uno::Any(OUString(ODF_UNHANDLED
))),
404 comphelper::makePropertyValue("FieldCommand",
405 uno::Any(OUString("ADDIN ZOTERO_ITEM new command 2"))),
406 comphelper::makePropertyValue("FieldResult", uno::Any(OUString("new result 2"))),
408 uno::Sequence
<uno::Sequence
<css::beans::PropertyValue
>> aFields
= { aField1
, aField2
};
409 uno::Sequence
<css::beans::PropertyValue
> aArgs
= {
410 comphelper::makePropertyValue("FieldType", uno::Any(OUString(ODF_UNHANDLED
))),
411 comphelper::makePropertyValue("FieldCommandPrefix",
412 uno::Any(OUString("ADDIN ZOTERO_ITEM"))),
413 comphelper::makePropertyValue("Fields", uno::Any(aFields
)),
415 dispatchCommand(mxComponent
, ".uno:TextFormFields", aArgs
);
417 // Then make sure that the document text contains the new field results:
418 SwDoc
* pDoc
= getSwDoc();
419 SwWrtShell
* pWrtShell
= pDoc
->GetDocShell()->GetWrtShell();
420 pWrtShell
->SttEndDoc(/*bStt=*/true);
421 SwCursor
* pCursor
= pWrtShell
->GetCursor();
422 OUString aActual
= pCursor
->Start()->GetNode().GetTextNode()->GetText();
423 static sal_Unicode
const aForbidden
[]
424 = { CH_TXT_ATR_FIELDSTART
, CH_TXT_ATR_FIELDSEP
, CH_TXT_ATR_FIELDEND
, 0 };
425 aActual
= comphelper::string::removeAny(aActual
, aForbidden
);
426 // Without the accompanying fix in place, this test would have failed with:
427 // - Expected: new result 1new result 2
428 // - Actual : old result 1old result 2
429 // i.e. the fieldmarks were not updated.
430 CPPUNIT_ASSERT_EQUAL(OUString("new result 1new result 2"), aActual
);
433 CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest
, testInsertBookmark
)
435 // Given an empty document:
437 SwDoc
* pDoc
= getSwDoc();
439 // When inserting a bookmark with text:
440 OUString
aExpectedBookmarkName("ZOTERO_BREF_GiQ7DAWQYWLy");
441 uno::Sequence
<css::beans::PropertyValue
> aArgs
= {
442 comphelper::makePropertyValue("Bookmark", uno::Any(aExpectedBookmarkName
)),
443 comphelper::makePropertyValue("BookmarkText", uno::Any(OUString("<p>aaa</p><p>bbb</p>"))),
445 dispatchCommand(mxComponent
, ".uno:InsertBookmark", aArgs
);
447 // Then make sure that we create a bookmark that covers that text:
448 IDocumentMarkAccess
& rIDMA
= *pDoc
->getIDocumentMarkAccess();
449 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32
>(1), rIDMA
.getBookmarksCount());
450 for (auto it
= rIDMA
.getBookmarksBegin(); it
!= rIDMA
.getBookmarksEnd(); ++it
)
452 sw::mark::IMark
* pMark
= *it
;
453 CPPUNIT_ASSERT_EQUAL(aExpectedBookmarkName
, pMark
->GetName());
454 SwPaM
aPam(pMark
->GetMarkStart(), pMark
->GetMarkEnd());
455 OUString aActualResult
= aPam
.GetText();
456 // Without the accompanying fix in place, this test would have failed with:
457 // - Expected: aaa\nbbb
459 // i.e. no text was inserted, the bookmark was collapsed.
460 CPPUNIT_ASSERT_EQUAL(OUString("aaa\nbbb"), aActualResult
);
464 CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest
, testGotoMark
)
466 // Given a document with 2 paragraphs, a bookmark on the second one:
468 SwDoc
* pDoc
= getSwDoc();
469 SwWrtShell
* pWrtShell
= pDoc
->GetDocShell()->GetWrtShell();
470 pWrtShell
->SplitNode();
471 pWrtShell
->SttEndDoc(/*bStt=*/false);
472 pWrtShell
->SetBookmark(vcl::KeyCode(), "mybookmark");
473 SwNodeOffset nExpected
= pWrtShell
->GetCursor()->GetPointNode().GetIndex();
475 // When jumping to that mark from the doc start:
476 pWrtShell
->SttEndDoc(/*bStt=*/true);
477 uno::Sequence
<css::beans::PropertyValue
> aArgs
= {
478 comphelper::makePropertyValue("GotoMark", uno::Any(OUString("mybookmark"))),
480 dispatchCommand(mxComponent
, ".uno:GotoMark", aArgs
);
482 // Then make sure that the final cursor position is at the bookmark:
483 SwNodeOffset nActual
= pWrtShell
->GetCursor()->GetPointNode().GetIndex();
484 // Without the accompanying fix in place, this test would have failed with:
485 // - Expected: 10 (bookmark)
486 // - Actual : 9 (doc start)
487 // i.e. the actual jump didn't happen.
488 CPPUNIT_ASSERT_EQUAL(nExpected
, nActual
);
491 CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest
, testUpdateBookmarks
)
493 // Given a document with 2 bookmarks, first covering "B" and second covering "D":
495 SwDoc
* pDoc
= getSwDoc();
496 SwWrtShell
* pWrtShell
= pDoc
->GetDocShell()->GetWrtShell();
497 pWrtShell
->Insert("ABCDE");
498 pWrtShell
->SttEndDoc(/*bStt=*/true);
499 pWrtShell
->Right(SwCursorSkipMode::Chars
, /*bSelect=*/false, 1, /*bBasicCall=*/false);
500 pWrtShell
->Right(SwCursorSkipMode::Chars
, /*bSelect=*/true, 1, /*bBasicCall=*/false);
501 pWrtShell
->SetBookmark(vcl::KeyCode(), "ZOTERO_BREF_GiQ7DAWQYWLy");
502 pWrtShell
->Right(SwCursorSkipMode::Chars
, /*bSelect=*/false, 1, /*bBasicCall=*/false);
503 pWrtShell
->Right(SwCursorSkipMode::Chars
, /*bSelect=*/true, 1, /*bBasicCall=*/false);
504 pWrtShell
->SetBookmark(vcl::KeyCode(), "ZOTERO_BREF_PRxDGUb4SWXF");
506 // When updating the content of bookmarks:
507 pWrtShell
->SttEndDoc(/*bStt=*/true);
508 std::vector
<beans::PropertyValue
> aArgsVec
= comphelper::JsonToPropertyValues(R
"json(
510 "BookmarkNamePrefix
": {
512 "value
": "ZOTERO_BREF_
"
515 "type
": "[][]com
.sun
.star
.beans
.PropertyValue
",
520 "value
": "ZOTERO_BREF_new1
"
524 "value
": "new result
1"
530 "value
": "ZOTERO_BREF_new2
"
534 "value
": "new result
2"
541 uno::Sequence
<beans::PropertyValue
> aArgs
= comphelper::containerToSequence(aArgsVec
);
542 dispatchCommand(mxComponent
, ".uno:UpdateBookmarks", aArgs
);
544 // Then make sure that the only paragraph is updated correctly:
545 SwCursor
* pCursor
= pWrtShell
->GetCursor();
546 OUString aActual
= pCursor
->GetPointNode().GetTextNode()->GetText();
547 // Without the accompanying fix in place, this test would have failed with:
548 // - Expected: Anew result 1Cnew result 2E
550 // i.e. the content was not updated.
551 CPPUNIT_ASSERT_EQUAL(OUString("Anew result 1Cnew result 2E"), aActual
);
553 // Without the accompanying fix in place, this test would have failed, ZOTERO_BREF_GiQ7DAWQYWLy
554 // was not renamed to ZOTERO_BREF_new1.
555 auto it
= pDoc
->getIDocumentMarkAccess()->findMark("ZOTERO_BREF_new1");
556 CPPUNIT_ASSERT(it
!= pDoc
->getIDocumentMarkAccess()->getAllMarksEnd());
559 CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest
, testInsertFieldmarkReadonly
)
561 // Given a document with a fieldmark, the cursor inside the fieldmark:
563 uno::Sequence
<css::beans::PropertyValue
> aArgs
= {
564 comphelper::makePropertyValue("FieldType", uno::Any(OUString(ODF_UNHANDLED
))),
565 comphelper::makePropertyValue("FieldCommand", uno::Any(OUString("my command"))),
566 comphelper::makePropertyValue("FieldResult", uno::Any(OUString("my result"))),
568 dispatchCommand(mxComponent
, ".uno:TextFormField", aArgs
);
569 SwDoc
* pDoc
= getSwDoc();
570 SwWrtShell
* pWrtShell
= pDoc
->GetDocShell()->GetWrtShell();
571 SwCursor
* pCursor
= pWrtShell
->GetCursor();
572 pCursor
->SttEndDoc(/*bSttDoc=*/true);
573 pWrtShell
->Right(SwCursorSkipMode::Chars
, /*bSelect=*/false, 1, /*bBasicCall=*/false);
575 // When trying to insert an inner fieldmark:
576 // Without the accompanying fix in place, this test would have crashed.
577 dispatchCommand(mxComponent
, ".uno:TextFormField", aArgs
);
579 // Then make sure the read-only content refuses to accept that inner fieldmark, so we still have
582 IDocumentMarkAccess
& rIDMA
= *pDoc
->getIDocumentMarkAccess();
583 for (auto it
= rIDMA
.getFieldmarksBegin(); it
!= rIDMA
.getFieldmarksEnd(); ++it
)
587 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), nActual
);
590 CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest
, testUpdateRefmarks
)
592 // Given a document with two refmarks, one is not interesting the other is a citation:
594 SwDoc
* pDoc
= getSwDoc();
595 uno::Sequence
<css::beans::PropertyValue
> aArgs
= {
596 comphelper::makePropertyValue("TypeName", uno::Any(OUString("SetRef"))),
597 comphelper::makePropertyValue("Name", uno::Any(OUString("some other old refmark"))),
598 comphelper::makePropertyValue("Content", uno::Any(OUString("some other old content"))),
600 dispatchCommand(mxComponent
, ".uno:InsertField", aArgs
);
601 SwWrtShell
* pWrtShell
= pDoc
->GetDocShell()->GetWrtShell();
602 pWrtShell
->SttEndDoc(/*bStt=*/false);
603 pWrtShell
->SplitNode();
604 pWrtShell
->SttEndDoc(/*bStt=*/false);
606 comphelper::makePropertyValue("TypeName", uno::Any(OUString("SetRef"))),
607 comphelper::makePropertyValue(
608 "Name", uno::Any(OUString("ZOTERO_ITEM CSL_CITATION {} old refmark"))),
609 comphelper::makePropertyValue("Content", uno::Any(OUString("old content"))),
611 dispatchCommand(mxComponent
, ".uno:InsertField", aArgs
);
613 // When updating that refmark:
614 std::vector
<beans::PropertyValue
> aArgsVec
= comphelper::JsonToPropertyValues(R
"json(
622 "value
": "ZOTERO_ITEM CSL_CITATION
"
625 "type
": "[][]com
.sun
.star
.beans
.PropertyValue
",
630 "value
": "ZOTERO_ITEM CSL_CITATION
{} new refmark
"
634 "value
": "new content
"
641 aArgs
= comphelper::containerToSequence(aArgsVec
);
642 dispatchCommand(mxComponent
, ".uno:UpdateFields", aArgs
);
644 // Then make sure that the document text features the new content:
645 SwTextNode
* pTextNode
= pWrtShell
->GetCursor()->GetPointNode().GetTextNode();
646 // Without the accompanying fix in place, this test would have failed with:
647 // - Expected: new content
648 // - Actual : old content
649 // i.e. the doc content was not updated.
650 CPPUNIT_ASSERT_EQUAL(OUString("new content"), pTextNode
->GetText());
653 CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest
, testUpdateFieldmark
)
655 // Given a document with a fieldmark:
657 uno::Sequence
<css::beans::PropertyValue
> aArgs
= {
658 comphelper::makePropertyValue("FieldType", uno::Any(OUString(ODF_UNHANDLED
))),
659 comphelper::makePropertyValue("FieldCommand",
660 uno::Any(OUString("ADDIN ZOTERO_ITEM old command 1"))),
661 comphelper::makePropertyValue("FieldResult", uno::Any(OUString("old result 1"))),
663 dispatchCommand(mxComponent
, ".uno:TextFormField", aArgs
);
665 // When updating that fieldmark to have new field command & result:
666 SwDoc
* pDoc
= getSwDoc();
667 SwWrtShell
* pWrtShell
= pDoc
->GetDocShell()->GetWrtShell();
668 pWrtShell
->SttEndDoc(/*bStt=*/false);
669 pWrtShell
->Left(SwCursorSkipMode::Chars
, /*bSelect=*/false, 1, /*bBasicCall=*/false);
670 std::vector
<beans::PropertyValue
> aArgsVec
= comphelper::JsonToPropertyValues(R
"json(
674 "value
": "vnd
.oasis
.opendocument
.field
.UNHANDLED
"
676 "FieldCommandPrefix
": {
678 "value
": "ADDIN ZOTERO_ITEM
"
681 "type
": "[]com
.sun
.star
.beans
.PropertyValue
",
685 "value
": "vnd
.oasis
.opendocument
.field
.UNHANDLED
"
689 "value
": "ADDIN ZOTERO_ITEM
new command
1"
693 "value
": "new result
1"
699 aArgs
= comphelper::containerToSequence(aArgsVec
);
700 dispatchCommand(mxComponent
, ".uno:UpdateTextFormField", aArgs
);
702 // Then make sure that the document text is updated accordingly:
703 SwCursor
* pCursor
= pWrtShell
->GetCursor();
704 OUString aActual
= pCursor
->Start()->GetNode().GetTextNode()->GetText();
705 static sal_Unicode
const aForbidden
[]
706 = { CH_TXT_ATR_FIELDSTART
, CH_TXT_ATR_FIELDSEP
, CH_TXT_ATR_FIELDEND
, 0 };
707 aActual
= comphelper::string::removeAny(aActual
, aForbidden
);
708 // Without the accompanying fix in place, this test would have failed with:
709 // - Expected: new result 1
710 // - Actual : old result 1
711 // i.e. the document text was not updated.
712 CPPUNIT_ASSERT_EQUAL(OUString("new result 1"), aActual
);
715 CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest
, testUpdateSections
)
717 // Given a document with a section:
719 uno::Sequence
<css::beans::PropertyValue
> aArgs
= {
720 comphelper::makePropertyValue("RegionName",
721 uno::Any(OUString("ZOTERO_BIBL {} CSL_BIBLIOGRAPHY RNDold"))),
722 comphelper::makePropertyValue("Content", uno::Any(OUString("old content"))),
724 dispatchCommand(mxComponent
, ".uno:InsertSection", aArgs
);
726 // When updating that section:
727 std::vector
<beans::PropertyValue
> aArgsVec
= comphelper::JsonToPropertyValues(R
"json(
729 "SectionNamePrefix
": {
731 "value
": "ZOTERO_BIBL
"
734 "type
": "[][]com
.sun
.star
.beans
.PropertyValue
",
739 "value
": "ZOTERO_BIBL
{} CSL_BIBLIOGRAPHY RNDnew
"
743 "value
": "new content
"
750 aArgs
= comphelper::containerToSequence(aArgsVec
);
751 dispatchCommand(mxComponent
, ".uno:UpdateSections", aArgs
);
753 // Then make sure that the section is updated:
754 SwWrtShell
* pWrtShell
= getSwDocShell()->GetWrtShell();
755 pWrtShell
->SttEndDoc(/*bStt=*/true);
756 pWrtShell
->EndOfSection(/*bSelect=*/true);
757 SwCursor
* pCursor
= pWrtShell
->GetCursor();
758 OUString aActualResult
= pCursor
->GetText();
759 // Without the accompanying fix in place, this test would have failed with:
760 // - Expected: new content
761 // - Actual : old content
762 // i.e. the content wasn't updated.
763 CPPUNIT_ASSERT_EQUAL(OUString("new content"), aActualResult
);
766 CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest
, testDeleteFieldmarks
)
768 // Given a document with 2 fieldmarks:
771 uno::Sequence
<css::beans::PropertyValue
> aArgs
= {
772 comphelper::makePropertyValue("FieldType", uno::Any(OUString(ODF_UNHANDLED
))),
773 comphelper::makePropertyValue("FieldCommand",
774 uno::Any(OUString("ADDIN ZOTERO_ITEM old command 1"))),
775 comphelper::makePropertyValue("FieldResult", uno::Any(OUString("result 1"))),
777 dispatchCommand(mxComponent
, ".uno:TextFormField", aArgs
);
780 uno::Sequence
<css::beans::PropertyValue
> aArgs
= {
781 comphelper::makePropertyValue("FieldType", uno::Any(OUString(ODF_UNHANDLED
))),
782 comphelper::makePropertyValue("FieldCommand",
783 uno::Any(OUString("ADDIN ZOTERO_ITEM old command 2"))),
784 comphelper::makePropertyValue("FieldResult", uno::Any(OUString("result 2"))),
786 dispatchCommand(mxComponent
, ".uno:TextFormField", aArgs
);
789 // When deleting those fieldmarks:
790 uno::Sequence
<css::beans::PropertyValue
> aArgs
791 = { comphelper::makePropertyValue("FieldType", uno::Any(OUString(ODF_UNHANDLED
))),
792 comphelper::makePropertyValue("FieldCommandPrefix",
793 uno::Any(OUString("ADDIN ZOTERO_ITEM"))) };
794 dispatchCommand(mxComponent
, ".uno:DeleteTextFormFields", aArgs
);
796 // Then make sure that the document doesn't contain fields anymore:
797 SwDoc
* pDoc
= getSwDoc();
798 // Without the accompanying fix in place, this test would have failed with:
801 // i.e. the fieldmarks were not deleted.
802 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32
>(0),
803 pDoc
->getIDocumentMarkAccess()->getAllMarksCount());
804 SwWrtShell
* pWrtShell
= pDoc
->GetDocShell()->GetWrtShell();
805 pWrtShell
->SttEndDoc(/*bStt=*/true);
806 SwCursor
* pCursor
= pWrtShell
->GetCursor();
807 OUString aActual
= pCursor
->Start()->GetNode().GetTextNode()->GetText();
808 CPPUNIT_ASSERT_EQUAL(OUString("result 1result 2"), aActual
);
811 CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest
, testUpdateBookmark
)
813 // Given a document with a bookmarks, covering "BC":
815 SwDoc
* pDoc
= getSwDoc();
816 SwWrtShell
* pWrtShell
= pDoc
->GetDocShell()->GetWrtShell();
817 pWrtShell
->Insert("ABCD");
818 pWrtShell
->SttEndDoc(/*bStt=*/true);
819 pWrtShell
->Right(SwCursorSkipMode::Chars
, /*bSelect=*/false, 1, /*bBasicCall=*/false);
820 pWrtShell
->Right(SwCursorSkipMode::Chars
, /*bSelect=*/true, 2, /*bBasicCall=*/false);
821 pWrtShell
->SetBookmark(vcl::KeyCode(), "ZOTERO_BREF_old");
823 // When updating the content of the bookmark under the cursor:
824 pWrtShell
->SttEndDoc(/*bStt=*/true);
825 pWrtShell
->Right(SwCursorSkipMode::Chars
, /*bSelect=*/false, 2, /*bBasicCall=*/false);
826 std::vector
<beans::PropertyValue
> aArgsVec
= comphelper::JsonToPropertyValues(R
"json(
828 "BookmarkNamePrefix
": {
830 "value
": "ZOTERO_BREF_
"
833 "type
": "[]com
.sun
.star
.beans
.PropertyValue
",
837 "value
": "ZOTERO_BREF_new
"
841 "value
": "new result
"
847 uno::Sequence
<beans::PropertyValue
> aArgs
= comphelper::containerToSequence(aArgsVec
);
848 dispatchCommand(mxComponent
, ".uno:UpdateBookmark", aArgs
);
850 // Then make sure that the only paragraph is updated correctly:
851 SwCursor
* pCursor
= pWrtShell
->GetCursor();
852 OUString aActual
= pCursor
->GetPointNode().GetTextNode()->GetText();
853 // Without the accompanying fix in place, this test would have failed with:
854 // - Expected: Anew resultD
856 // i.e. it was not possible to update just the bookmark under cursor.
857 CPPUNIT_ASSERT_EQUAL(OUString("Anew resultD"), aActual
);
858 auto it
= pDoc
->getIDocumentMarkAccess()->findMark("ZOTERO_BREF_new");
859 CPPUNIT_ASSERT(it
!= pDoc
->getIDocumentMarkAccess()->getAllMarksEnd());
862 CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest
, testUpdateRefmark
)
864 // Given a document with a refmark:
866 SwDoc
* pDoc
= getSwDoc();
867 uno::Sequence
<css::beans::PropertyValue
> aArgs
= {
868 comphelper::makePropertyValue("TypeName", uno::Any(OUString("SetRef"))),
869 comphelper::makePropertyValue(
870 "Name", uno::Any(OUString("ZOTERO_ITEM CSL_CITATION {} old refmark"))),
871 comphelper::makePropertyValue("Content", uno::Any(OUString("old content"))),
873 dispatchCommand(mxComponent
, ".uno:InsertField", aArgs
);
875 // When updating that refmark:
876 std::vector
<beans::PropertyValue
> aArgsVec
= comphelper::JsonToPropertyValues(R
"json(
884 "value
": "ZOTERO_ITEM CSL_CITATION
"
887 "type
": "[]com
.sun
.star
.beans
.PropertyValue
",
891 "value
": "ZOTERO_ITEM CSL_CITATION
{} new refmark
"
895 "value
": "new content
"
901 aArgs
= comphelper::containerToSequence(aArgsVec
);
902 dispatchCommand(mxComponent
, ".uno:UpdateField", aArgs
);
904 // Then make sure that the document text features the new content:
905 SwWrtShell
* pWrtShell
= pDoc
->GetDocShell()->GetWrtShell();
906 SwTextNode
* pTextNode
= pWrtShell
->GetCursor()->GetPointNode().GetTextNode();
907 // Without the accompanying fix in place, this test would have failed with:
908 // - Expected: new content
909 // - Actual : old content
910 // i.e. the content was not updated.
911 CPPUNIT_ASSERT_EQUAL(OUString("new content"), pTextNode
->GetText());
914 CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest
, testDeleteBookmarks
)
916 // Given a document with 2 bookmarks, first covering "B" and second covering "D":
918 SwDoc
* pDoc
= getSwDoc();
919 SwWrtShell
* pWrtShell
= pDoc
->GetDocShell()->GetWrtShell();
920 pWrtShell
->Insert("ABCDE");
921 pWrtShell
->SttEndDoc(/*bStt=*/true);
922 pWrtShell
->Right(SwCursorSkipMode::Chars
, /*bSelect=*/false, 1, /*bBasicCall=*/false);
923 pWrtShell
->Right(SwCursorSkipMode::Chars
, /*bSelect=*/true, 1, /*bBasicCall=*/false);
924 pWrtShell
->SetBookmark(vcl::KeyCode(), "ZOTERO_BREF_GiQ7DAWQYWLy");
925 pWrtShell
->Right(SwCursorSkipMode::Chars
, /*bSelect=*/false, 1, /*bBasicCall=*/false);
926 pWrtShell
->Right(SwCursorSkipMode::Chars
, /*bSelect=*/true, 1, /*bBasicCall=*/false);
927 pWrtShell
->SetBookmark(vcl::KeyCode(), "other");
929 // When deleting 1 matching bookmark:
930 pWrtShell
->SttEndDoc(/*bStt=*/true);
931 std::vector
<beans::PropertyValue
> aArgsVec
= comphelper::JsonToPropertyValues(R
"json(
933 "BookmarkNamePrefix
": {
935 "value
": "ZOTERO_BREF_
"
939 uno::Sequence
<beans::PropertyValue
> aArgs
= comphelper::containerToSequence(aArgsVec
);
940 dispatchCommand(mxComponent
, ".uno:DeleteBookmarks", aArgs
);
942 // Then make sure that only the other bookmark is kept:
943 auto it
= pDoc
->getIDocumentMarkAccess()->findMark("ZOTERO_BREF_GiQ7DAWQYWLy");
944 // Without the accompanying fix in place, this test would have failed, the matching bookmark was
946 CPPUNIT_ASSERT(bool(it
== pDoc
->getIDocumentMarkAccess()->getAllMarksEnd()));
947 it
= pDoc
->getIDocumentMarkAccess()->findMark("other");
948 CPPUNIT_ASSERT(it
!= pDoc
->getIDocumentMarkAccess()->getAllMarksEnd());
951 CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest
, testDeleteFields
)
953 // Given a document with a refmark:
955 uno::Sequence
<css::beans::PropertyValue
> aArgs
= {
956 comphelper::makePropertyValue("TypeName", uno::Any(OUString("SetRef"))),
957 comphelper::makePropertyValue(
958 "Name", uno::Any(OUString("ZOTERO_ITEM CSL_CITATION {} RNDpyJknp173F"))),
959 comphelper::makePropertyValue("Content", uno::Any(OUString("aaa<b>bbb</b>ccc"))),
961 dispatchCommand(mxComponent
, ".uno:InsertField", aArgs
);
963 // When deleting the refmarks:
964 std::vector
<beans::PropertyValue
> aArgsVec
= comphelper::JsonToPropertyValues(R
"json(
972 "value
": "ZOTERO_ITEM CSL_CITATION
"
976 aArgs
= comphelper::containerToSequence(aArgsVec
);
977 dispatchCommand(mxComponent
, ".uno:DeleteFields", aArgs
);
979 // Then make sure that no refmark is kept:
980 SwDoc
* pDoc
= getSwDoc();
981 // Without the accompanying fix in place, this test would have failed with:
984 // i.e. the refmark was not deleted.
985 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16
>(0), pDoc
->GetRefMarks());
988 CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest
, testInsertTextFormFieldFootnote
)
990 // Given an empty document:
992 SwDoc
* pDoc
= getSwDoc();
994 // When inserting an ODF_UNHANDLED fieldmark inside a footnote:
995 uno::Sequence
<css::beans::PropertyValue
> aArgs
= {
996 comphelper::makePropertyValue("FieldType", uno::Any(OUString(ODF_UNHANDLED
))),
997 comphelper::makePropertyValue("FieldCommand",
998 uno::Any(OUString("ADDIN ZOTERO_BIBL foo bar"))),
999 comphelper::makePropertyValue("FieldResult", uno::Any(OUString("result"))),
1000 comphelper::makePropertyValue("Wrapper", uno::Any(OUString("Footnote"))),
1002 dispatchCommand(mxComponent
, ".uno:TextFormField", aArgs
);
1004 // Then make sure that the footnote is created:
1005 SwFootnoteIdxs
& rFootnotes
= pDoc
->GetFootnoteIdxs();
1006 // Without the accompanying fix in place, this test would have failed with:
1009 // i.e. no footnote was created.
1010 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rFootnotes
.size());
1013 CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest
, testInsertTextFormFieldEndnote
)
1015 // Given an empty document:
1017 SwDoc
* pDoc
= getSwDoc();
1019 // When inserting an ODF_UNHANDLED fieldmark inside an endnote:
1020 uno::Sequence
<css::beans::PropertyValue
> aArgs
= {
1021 comphelper::makePropertyValue("FieldType", uno::Any(OUString(ODF_UNHANDLED
))),
1022 comphelper::makePropertyValue("FieldCommand",
1023 uno::Any(OUString("ADDIN ZOTERO_BIBL foo bar"))),
1024 comphelper::makePropertyValue("FieldResult", uno::Any(OUString("result"))),
1025 comphelper::makePropertyValue("Wrapper", uno::Any(OUString("Endnote"))),
1027 dispatchCommand(mxComponent
, ".uno:TextFormField", aArgs
);
1029 // Then make sure that the endnote is created:
1030 SwFootnoteIdxs
& rFootnotes
= pDoc
->GetFootnoteIdxs();
1031 // Without the accompanying fix in place, this test would have failed with:
1034 // i.e. no endnote was inserted.
1035 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rFootnotes
.size());
1036 SwTextFootnote
* pEndnote
= rFootnotes
[0];
1037 const SwFormatFootnote
& rFormatEndnote
= pEndnote
->GetFootnote();
1038 CPPUNIT_ASSERT(rFormatEndnote
.IsEndNote());
1039 // Also check that the endnote body contains the fieldmark:
1040 SwWrtShell
* pWrtShell
= getSwDocShell()->GetWrtShell();
1041 pWrtShell
->SttEndDoc(/*bStt=*/true);
1042 pWrtShell
->GotoFootnoteText();
1043 pWrtShell
->EndOfSection(/*bSelect=*/true);
1044 SwCursor
* pCursor
= pWrtShell
->GetCursor();
1045 OUString aActual
= pCursor
->GetText();
1046 static sal_Unicode
const aForbidden
[]
1047 = { CH_TXT_ATR_FIELDSTART
, CH_TXT_ATR_FIELDSEP
, CH_TXT_ATR_FIELDEND
, 0 };
1048 aActual
= comphelper::string::removeAny(aActual
, aForbidden
);
1049 // Then this was empty: the fieldmark was inserted before the note anchor, not in the note body.
1050 CPPUNIT_ASSERT_EQUAL(OUString("result"), aActual
);
1053 // Disabled because tdf#139141 was reverted and the default time field inserts a fix value again
1054 // Should be reactivated once a new UNO command is added for variable time fields
1055 CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest, testUpdateSelectedField)
1057 // Given an empty doc:
1059 SwDoc* pDoc = getSwDoc();
1060 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
1061 SwPaM* pCursor = pDoc->GetEditShell()->GetCursor();
1063 // Insert a time field and select it:
1064 dispatchCommand(mxComponent, ".uno:InsertTimeField", {});
1067 pCursor->Move(fnMoveBackward);
1069 OUString aTimeFieldBefore, aTimeFieldAfter;
1070 pWrtShell->GetSelectedText(aTimeFieldBefore);
1072 // Wait for one second:
1073 osl::Thread::wait(std::chrono::seconds(1));
1075 // Update the field at cursor:
1076 dispatchCommand(mxComponent, ".uno:UpdateSelectedField", {});
1077 pWrtShell->GetSelectedText(aTimeFieldAfter);
1079 // Check that the selected field has changed:
1080 CPPUNIT_ASSERT(aTimeFieldAfter != aTimeFieldBefore);
1083 CPPUNIT_PLUGIN_IMPLEMENT();
1085 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */