sw/CppunitTest_sw_uibase_shells.mk | 1 sw/qa/core/layout/layout.cxx | 63 +++++++++++++++++++++++++ sw/qa/uibase/shells/textfld.cxx | 90 ++++++++++++++++++++++++++++++++++++ sw/sdi/swriter.sdi | 2 sw/source/core/crsr/bookmark.cxx | 3 + sw/source/core/layout/paintfrm.cxx | 9 +++ sw/source/uibase/shells/textfld.cxx | 14 +++++ 7 files changed, 180 insertions(+), 2 deletions(-)
New commits: commit ecaba3a739a3173da607faa8c392d5fd6a462c35 Author: Pranam Lashkari <lpra...@collabora.com> AuthorDate: Fri Jan 20 16:49:57 2023 +0530 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Wed Feb 8 08:32:21 2023 +0100 sw: send field mark delete call back only on deletion previously command call back was also sent when field was selected Signed-off-by: Pranam Lashkari <lpra...@collabora.com> Change-Id: If0768180e81c47a738225e693b07441cf25906b6 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/145884 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> Reviewed-by: Miklos Vajna <vmik...@collabora.com> diff --git a/sw/source/core/crsr/bookmark.cxx b/sw/source/core/crsr/bookmark.cxx index b7e5b4a7850b..8165b30a98b1 100644 --- a/sw/source/core/crsr/bookmark.cxx +++ b/sw/source/core/crsr/bookmark.cxx @@ -565,6 +565,9 @@ namespace sw::mark TextFieldmark::~TextFieldmark() { + if (GetMarkPos().GetDoc().IsClipBoard()) + return; + SfxViewShell* pViewShell = SfxViewShell::Current(); if (!pViewShell) return; commit 3c359d925104095cf9c754f296be4aa34ad74cde Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Thu Jan 19 08:19:46 2023 +0100 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Wed Feb 8 08:30:13 2023 +0100 sw, .uno:InsertField: handle Endnote as a value for the Wrapper parameter This is similar to commit 43d80906c8693ca27c5b3077fbaa259df4004924 (sw: .uno:TextFormField: handle Endnote as a value for the Wrapper parameter, 2023-01-17), but that was for fieldmarks & endnotes, this is for refmarks & endnotes. (cherry picked from commit 04d988d3c368fe07ae3c44c536a4513e424f104e) Change-Id: I46512dd973508f51f7093521c40ad4100dd39ae6 diff --git a/sw/qa/uibase/shells/textfld.cxx b/sw/qa/uibase/shells/textfld.cxx index ef4da3aa65b1..6f9fa0c1c2f6 100644 --- a/sw/qa/uibase/shells/textfld.cxx +++ b/sw/qa/uibase/shells/textfld.cxx @@ -58,4 +58,33 @@ CPPUNIT_TEST_FIXTURE(Test, testInsertRefmarkFootnote) CPPUNIT_ASSERT_EQUAL(OUString("content"), rFormatNote.GetFootnoteText(*pWrtShell->GetLayout())); } +CPPUNIT_TEST_FIXTURE(Test, testInsertRefmarkEndnote) +{ + // Given an empty document: + createSwDoc(); + + // When inserting a refmark inside an endnote: + uno::Sequence<css::beans::PropertyValue> aArgs = { + comphelper::makePropertyValue("TypeName", uno::Any(OUString("SetRef"))), + comphelper::makePropertyValue("Name", uno::Any(OUString("myref"))), + comphelper::makePropertyValue("Content", uno::Any(OUString("content"))), + comphelper::makePropertyValue("Wrapper", uno::Any(OUString("Endnote"))), + }; + dispatchCommand(mxComponent, ".uno:InsertField", aArgs); + + // Then make sure that the note body contains the refmark: + SwDoc* pDoc = getSwDoc(); + SwFootnoteIdxs& rNotes = pDoc->GetFootnoteIdxs(); + // Without the accompanying fix in place, this test would have failed with: + // - Expected: 1 + // - Actual : 0 + // i.e. no endnote was inserted. + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rNotes.size()); + SwTextFootnote* pNote = rNotes[0]; + const SwFormatFootnote& rNote = pNote->GetFootnote(); + CPPUNIT_ASSERT(rNote.IsEndNote()); + SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell(); + CPPUNIT_ASSERT_EQUAL(OUString("content"), rNote.GetFootnoteText(*pWrtShell->GetLayout())); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/uibase/shells/textfld.cxx b/sw/source/uibase/shells/textfld.cxx index ec06575a7cd0..df96cdd189ac 100644 --- a/sw/source/uibase/shells/textfld.cxx +++ b/sw/source/uibase/shells/textfld.cxx @@ -301,13 +301,17 @@ void SwTextShell::ExecField(SfxRequest &rReq) } if (pArgs->GetItemState(FN_PARAM_5, false, &pItem) == SfxItemState::SET) { + // Wrap the field in the requested container instead of inserting it + // directly at the cursor position. const OUString& rWrapper = static_cast<const SfxStringItem *>(pItem)->GetValue(); if (rWrapper == "Footnote") { - // Wrap the field in the requested container instead of inserting it - // directly at the cursor position. GetShellPtr()->InsertFootnote(OUString()); } + else if (rWrapper == "Endnote") + { + GetShellPtr()->InsertFootnote(OUString(), /*bEndNote=*/true); + } } SwInsertField_Data aData(nType, nSubType, aPar1, aPar2, nFormat, GetShellPtr(), cSeparator ); bRes = aFieldMgr.InsertField( aData ); commit f0bc2ef40dd72b0418b7841e1d1afb54028713ee Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Wed Jan 18 08:20:24 2023 +0100 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Wed Feb 8 08:28:22 2023 +0100 sw, .uno:InsertField: add a new Wrapper parameter This is similar to ceea8f3924f26d5f10adc41b9ea587c77c2fda74 (sw: .uno:TextFormField: add new Wrapper parameter, 2023-01-16), but that was for fieldmarks & footnotes, while this is for refmarks & footnotes. Also start a new test file as the one for the entire directory starts to grow too long. (cherry picked from commit e9d5ccd5a0822969412dbddf0191e28703e72e82) Change-Id: Ib7c0e03d6686a8a52a5691a4e2dbf97dcc2facba diff --git a/sw/CppunitTest_sw_uibase_shells.mk b/sw/CppunitTest_sw_uibase_shells.mk index 14e961f4725d..932769a421e6 100644 --- a/sw/CppunitTest_sw_uibase_shells.mk +++ b/sw/CppunitTest_sw_uibase_shells.mk @@ -14,6 +14,7 @@ $(eval $(call gb_CppunitTest_CppunitTest,sw_uibase_shells)) $(eval $(call gb_CppunitTest_use_common_precompiled_header,sw_uibase_shells)) $(eval $(call gb_CppunitTest_add_exception_objects,sw_uibase_shells, \ + sw/qa/uibase/shells/textfld \ sw/qa/uibase/shells/shells \ )) diff --git a/sw/qa/uibase/shells/textfld.cxx b/sw/qa/uibase/shells/textfld.cxx new file mode 100644 index 000000000000..ef4da3aa65b1 --- /dev/null +++ b/sw/qa/uibase/shells/textfld.cxx @@ -0,0 +1,61 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <swmodeltestbase.hxx> + +#include <comphelper/propertyvalue.hxx> + +#include <wrtsh.hxx> +#include <docsh.hxx> +#include <ftnidx.hxx> +#include <txtftn.hxx> + +namespace +{ +/// Covers sw/source/uibase/shells/textfld.cxx fixes. +class Test : public SwModelTestBase +{ +public: + Test() + : SwModelTestBase("/sw/qa/uibase/shells/data/") + { + } +}; +} + +CPPUNIT_TEST_FIXTURE(Test, testInsertRefmarkFootnote) +{ + // Given an empty document: + createSwDoc(); + + // When inserting a refmark inside a footnote: + uno::Sequence<css::beans::PropertyValue> aArgs = { + comphelper::makePropertyValue("TypeName", uno::Any(OUString("SetRef"))), + comphelper::makePropertyValue("Name", uno::Any(OUString("myref"))), + comphelper::makePropertyValue("Content", uno::Any(OUString("content"))), + comphelper::makePropertyValue("Wrapper", uno::Any(OUString("Footnote"))), + }; + dispatchCommand(mxComponent, ".uno:InsertField", aArgs); + + // Then make sure that the note body contains the refmark: + SwDoc* pDoc = getSwDoc(); + SwFootnoteIdxs& rNotes = pDoc->GetFootnoteIdxs(); + // Without the accompanying fix in place, this test would have failed with: + // - Expected: 1 + // - Actual : 0 + // i.e. no note was inserted. + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rNotes.size()); + SwTextFootnote* pNote = rNotes[0]; + const SwFormatFootnote& rFormatNote = pNote->GetFootnote(); + CPPUNIT_ASSERT(!rFormatNote.IsEndNote()); + SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell(); + CPPUNIT_ASSERT_EQUAL(OUString("content"), rFormatNote.GetFootnoteText(*pWrtShell->GetLayout())); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/sdi/swriter.sdi b/sw/sdi/swriter.sdi index 8303ebec1da2..da00008b80e9 100644 --- a/sw/sdi/swriter.sdi +++ b/sw/sdi/swriter.sdi @@ -2943,7 +2943,7 @@ SfxVoidItem InsertEnvelope FN_ENVELOP ] SfxVoidItem InsertField FN_INSERT_FIELD -(SfxUInt16Item Type FN_PARAM_FIELD_TYPE,SfxUInt16Item SubType FN_PARAM_FIELD_SUBTYPE,SfxStringItem Name FN_INSERT_FIELD,SfxStringItem Content FN_PARAM_FIELD_CONTENT,SfxUInt32Item Format FN_PARAM_FIELD_FORMAT,SfxStringItem Separator FN_PARAM_3, SfxStringItem TypeName FN_PARAM_4) +(SfxUInt16Item Type FN_PARAM_FIELD_TYPE,SfxUInt16Item SubType FN_PARAM_FIELD_SUBTYPE,SfxStringItem Name FN_INSERT_FIELD,SfxStringItem Content FN_PARAM_FIELD_CONTENT,SfxUInt32Item Format FN_PARAM_FIELD_FORMAT,SfxStringItem Separator FN_PARAM_3, SfxStringItem TypeName FN_PARAM_4, SfxStringItem Wrapper FN_PARAM_5) [ AutoUpdate = FALSE, FastCall = FALSE, diff --git a/sw/source/uibase/shells/textfld.cxx b/sw/source/uibase/shells/textfld.cxx index 073e0625a770..ec06575a7cd0 100644 --- a/sw/source/uibase/shells/textfld.cxx +++ b/sw/source/uibase/shells/textfld.cxx @@ -299,6 +299,16 @@ void SwTextShell::ExecField(SfxRequest &rReq) if(!sTmp.isEmpty()) cSeparator = sTmp[0]; } + if (pArgs->GetItemState(FN_PARAM_5, false, &pItem) == SfxItemState::SET) + { + const OUString& rWrapper = static_cast<const SfxStringItem *>(pItem)->GetValue(); + if (rWrapper == "Footnote") + { + // Wrap the field in the requested container instead of inserting it + // directly at the cursor position. + GetShellPtr()->InsertFootnote(OUString()); + } + } SwInsertField_Data aData(nType, nSubType, aPar1, aPar2, nFormat, GetShellPtr(), cSeparator ); bRes = aFieldMgr.InsertField( aData ); } commit 585b9c7728ef5e13d7a1c24a1455f4e605db89d3 Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Mon Feb 6 14:48:37 2023 +0100 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Wed Feb 8 08:26:59 2023 +0100 tdf#152669 sw: fix missing table borders in the non-Word-table-cell case A 4x4 table had partially missing inner borders when the page's writing mode was set to vertical, for a newly created document. This went wrong with commit 526c8bdb54eff942d5213030d1455f97720a1ba7 (sw: fix too long inner borders intersecting with outer borders for Word cells, 2022-01-06), which forgot to make changes in SwTabFramePainter::Insert() conditional on bWordTableCell. Fix the problem by making the SwTabFramePainter::Insert() changes conditional, similar to how SwTabFramePainter::FindStylesForLine() already did this. Note how the DocumentSettingId::TABLE_ROW_KEEP compat setting is off for new documents. Change-Id: Ie29d1613251d869e7ae78ea7dab3e75f0e6de229 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/146585 Reviewed-by: Miklos Vajna <vmik...@collabora.com> Tested-by: Jenkins (cherry picked from commit 1f373260cf25ca2f36a929e1a27fde00641e5c09) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/146526 Reviewed-by: Michael Stahl <michael.st...@allotropia.de> diff --git a/sw/qa/core/layout/layout.cxx b/sw/qa/core/layout/layout.cxx index c47bec8dfc6c..8a5c90a972b8 100644 --- a/sw/qa/core/layout/layout.cxx +++ b/sw/qa/core/layout/layout.cxx @@ -16,6 +16,7 @@ #include <o3tl/string_view.hxx> #include <sfx2/viewfrm.hxx> #include <sfx2/dispatch.hxx> +#include <editeng/frmdiritem.hxx> #include <wrtsh.hxx> #include <docsh.hxx> @@ -604,6 +605,68 @@ CPPUNIT_TEST_FIXTURE(SwCoreLayoutTest, testInnerCellBorderIntersect) CPPUNIT_ASSERT_LESS(aBorderStartEnds[0].second, aBorderStartEnds[1].second); } +CPPUNIT_TEST_FIXTURE(SwCoreLayoutTest, testInnerCellBorderNocompatIntersect) +{ + // Given a table with both outer and inner borders: + createSwDoc(); + SwDocShell* pShell = getSwDocShell(); + SwDoc* pDoc = pShell->GetDoc(); + // Set the default page style's writing direction to vertical: + SwPageDesc aStandard(pDoc->GetPageDesc(0)); + SvxFrameDirectionItem aDirection(SvxFrameDirection::Vertical_RL_TB, RES_FRAMEDIR); + aStandard.GetMaster().SetFormatAttr(aDirection); + pDoc->ChgPageDesc(0, aStandard); + // Insert a 4x4 table: + SwWrtShell* pWrtShell = pShell->GetWrtShell(); + SwInsertTableOptions aTableOptions(SwInsertTableFlags::DefaultBorder, 0); + pWrtShell->InsertTable(aTableOptions, 4, 4); + + // When rendering table borders: + std::shared_ptr<GDIMetaFile> xMetaFile = pShell->GetPreviewMetaFile(); + + // Then make sure that all horizontal lines have the same length: + MetafileXmlDump dumper; + xmlDocUniquePtr pXmlDoc = dumpAndParse(dumper, *xMetaFile); + // Collect start/end (vertical) positions of horizontal borders. + xmlXPathObjectPtr pXmlObj = getXPathNode(pXmlDoc, "//polyline[@style='solid']/point"); + xmlNodeSetPtr pXmlNodes = pXmlObj->nodesetval; + std::vector<std::pair<sal_Int32, sal_Int32>> aBorderStartEnds; + for (int i = 0; i < xmlXPathNodeSetGetLength(pXmlNodes); i += 2) + { + xmlNodePtr pStart = pXmlNodes->nodeTab[i]; + xmlNodePtr pEnd = pXmlNodes->nodeTab[i + 1]; + xmlChar* pStartY = xmlGetProp(pStart, BAD_CAST("y")); + xmlChar* pEndY = xmlGetProp(pEnd, BAD_CAST("y")); + sal_Int32 nStartY = o3tl::toInt32(reinterpret_cast<char const*>(pStartY)); + sal_Int32 nEndY = o3tl::toInt32(reinterpret_cast<char const*>(pEndY)); + if (nStartY != nEndY) + { + // Vertical border. + continue; + } + xmlChar* pStartX = xmlGetProp(pStart, BAD_CAST("x")); + xmlChar* pEndX = xmlGetProp(pEnd, BAD_CAST("x")); + sal_Int32 nStartX = o3tl::toInt32(reinterpret_cast<char const*>(pStartX)); + sal_Int32 nEndX = o3tl::toInt32(reinterpret_cast<char const*>(pEndX)); + aBorderStartEnds.emplace_back(nStartX, nEndX); + } + xmlXPathFreeObject(pXmlObj); + // We have 5 lines: top of 4 cells + bottom. + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(5), aBorderStartEnds.size()); + // Without the accompanying fix in place, this test would have failed with: + // - Expected: 9719 + // - Actual : 10064 + // i.e. the 2nd line started later than the first one, which is incorrect. + CPPUNIT_ASSERT_EQUAL(aBorderStartEnds[0].first, aBorderStartEnds[1].first); + CPPUNIT_ASSERT_EQUAL(aBorderStartEnds[0].first, aBorderStartEnds[2].first); + CPPUNIT_ASSERT_EQUAL(aBorderStartEnds[0].first, aBorderStartEnds[3].first); + CPPUNIT_ASSERT_EQUAL(aBorderStartEnds[0].first, aBorderStartEnds[4].first); + CPPUNIT_ASSERT_EQUAL(aBorderStartEnds[0].second, aBorderStartEnds[1].second); + CPPUNIT_ASSERT_EQUAL(aBorderStartEnds[0].second, aBorderStartEnds[2].second); + CPPUNIT_ASSERT_EQUAL(aBorderStartEnds[0].second, aBorderStartEnds[3].second); + CPPUNIT_ASSERT_EQUAL(aBorderStartEnds[0].second, aBorderStartEnds[4].second); +} + CPPUNIT_TEST_FIXTURE(SwCoreLayoutTest, testDoubleBorderVertical) { // Given a table with a left and right double border, outer is thick, inner is thin: diff --git a/sw/source/core/layout/paintfrm.cxx b/sw/source/core/layout/paintfrm.cxx index 5127624df73c..dbb1272efa9e 100644 --- a/sw/source/core/layout/paintfrm.cxx +++ b/sw/source/core/layout/paintfrm.cxx @@ -2919,11 +2919,18 @@ void SwTabFramePainter::Insert( SwLineEntry& rNew, bool bHori ) } SwLineEntrySet::iterator aIter = pLineSet->begin(); + bool bWordTableCell = false; + SwViewShell* pShell = mrTabFrame.getRootFrame()->GetCurrShell(); + if (pShell) + { + const IDocumentSettingAccess& rIDSA = pShell->GetDoc()->getIDocumentSettingAccess(); + bWordTableCell = rIDSA.get(DocumentSettingId::TABLE_ROW_KEEP); + } while ( aIter != pLineSet->end() && rNew.mnStartPos < rNew.mnEndPos ) { const SwLineEntry& rOld = *aIter; - if (rOld.mnLimitedEndPos || rOld.mbOuter != rNew.mbOuter) + if (rOld.mnLimitedEndPos || (bWordTableCell && (rOld.mbOuter != rNew.mbOuter))) { // Don't merge with this line entry as it ends sooner than mnEndPos. ++aIter;