sw/qa/core/unocore/unocore.cxx | 20 ++++++++++++++++++++ sw/source/core/txtnode/thints.cxx | 25 +++++++++++++++++++++++++ 2 files changed, 45 insertions(+)
New commits: commit 1dce9ee7e12871ee63434499db805e806b9e9d3c Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Thu Jul 21 08:07:27 2022 +0200 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Thu Jul 21 11:18:36 2022 +0200 sw content controls, plain text: apply formatting to the entire contents The difference between normal (rich text) content control and a plain text one is that if you try to format a subset of the contents, that's possible in the rich text case, but the plain text case extends the formatted range to the entire content control. Handle this in SwTextNode::InsertHint(), similar to how it's done for input fields. Change-Id: I9a1ad0095f0ca810da24d5c4ce4aa48d1ac59225 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/137280 Reviewed-by: Miklos Vajna <vmik...@collabora.com> Tested-by: Jenkins diff --git a/sw/qa/core/unocore/unocore.cxx b/sw/qa/core/unocore/unocore.cxx index 9ec8b0a340b1..f588821181c0 100644 --- a/sw/qa/core/unocore/unocore.cxx +++ b/sw/qa/core/unocore/unocore.cxx @@ -19,6 +19,7 @@ #include <comphelper/propertyvalue.hxx> #include <comphelper/sequenceashashmap.hxx> #include <vcl/errinf.hxx> +#include <editeng/wghtitem.hxx> #include <wrtsh.hxx> #include <unotextrange.hxx> @@ -710,6 +711,25 @@ CPPUNIT_TEST_FIXTURE(SwCoreUnocoreTest, testContentControlPlainText) = static_cast<SwFormatContentControl&>(pTextContentControl->GetAttr()); std::shared_ptr<SwContentControl> pContentControl = rFormatContentControl.GetContentControl(); CPPUNIT_ASSERT(pContentControl->GetPlainText()); + + // Now check if the char index range 2-4 is extended to 0-6 when we apply formatting: + pWrtShell->SttEndDoc(/*bStt=*/true); + // Select "es" from "<dummy>test<dummy>". + pWrtShell->Right(CRSR_SKIP_CHARS, /*bSelect=*/false, 2, /*bBasicCall=*/false); + pWrtShell->Right(CRSR_SKIP_CHARS, /*bSelect=*/true, 2, /*bBasicCall=*/false); + SfxItemSetFixed<RES_CHRATR_WEIGHT, RES_CHRATR_WEIGHT> aSet(pWrtShell->GetAttrPool()); + SvxWeightItem aItem(WEIGHT_BOLD, RES_CHRATR_WEIGHT); + aSet.Put(aItem); + pWrtShell->SetAttrSet(aSet); + pAttr = pTextNode->GetTextAttrAt(2, RES_TXTATR_AUTOFMT); + // Without the accompanying fix in place, this test would have failed with: + // - Expected: 0 + // - Actual : 2 + // i.e. the plain text content control now had 3 portions (<dummy>t<b>es</b>t<dummy>), instead + // of one (<b><dummy>test<dummy></b>). + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), pAttr->GetStart()); + CPPUNIT_ASSERT(pAttr->End()); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(6), *pAttr->End()); } CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sw/source/core/txtnode/thints.cxx b/sw/source/core/txtnode/thints.cxx index f14c7d5ea5ed..3fade71120d2 100644 --- a/sw/source/core/txtnode/thints.cxx +++ b/sw/source/core/txtnode/thints.cxx @@ -1684,6 +1684,31 @@ bool SwTextNode::InsertHint( SwTextAttr * const pAttr, const SetAttrMode nMode ) } } + { + // Handle the invariant that a plain text content control has the same character formatting + // for all of its content. + auto* pTextContentControl = static_txtattr_cast<SwTextContentControl*>( + GetTextAttrAt(pAttr->GetStart(), RES_TXTATR_CONTENTCONTROL, PARENT)); + if (pTextContentControl) + { + auto& rFormatContentControl + = static_cast<SwFormatContentControl&>(pTextContentControl->GetAttr()); + std::shared_ptr<SwContentControl> pContentControl + = rFormatContentControl.GetContentControl(); + if (pAttr->End() != nullptr && pContentControl->GetPlainText()) + { + if (pAttr->GetStart() > pTextContentControl->GetStart()) + { + pAttr->SetStart(pTextContentControl->GetStart()); + } + if (*pAttr->End() < *pTextContentControl->End()) + { + pAttr->SetEnd(*pTextContentControl->End()); + } + } + } + } + const bool bRet = bInsertHint && m_pSwpHints->TryInsertHint( pAttr, *this, nMode );