diff options
author | Michael Stahl <michael.stahl@allotropia.de> | 2024-05-17 13:58:41 +0200 |
---|---|---|
committer | Caolán McNamara <caolan.mcnamara@collabora.com> | 2024-05-18 22:30:14 +0200 |
commit | b01d89eaf473870281f6ecbdeb12aa3fcd79f9bb (patch) | |
tree | c854a19d005293733e96b7283559ae8eb406765b /sw | |
parent | 2e2ea78e585d469373c038aa12c5b99909a018c8 (diff) |
tdf#161137 sw: AutoText or Paste should copy paragraph indents for lists
The first commit made the start and end node of the paste look like the
list it was inserted into, but the middle nodes may have different
paragraph styles and may have different left margin / first line indent.
In addition to the SwNumRule, also copy any left margin or first line
indent if it is effective on the node that the SwNumRule was taken from.
Now all the list labels should be in the same place.
Change-Id: Ia5794687ea0ff542f23289b1ca63ea99dae85bc3
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167777
Tested-by: Jenkins
Reviewed-by: Michael Stahl <michael.stahl@allotropia.de>
(cherry picked from commit 2bcaa374ea418cd81f9dbf62cd7e896f5977992a)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167810
Reviewed-by: Caolán McNamara <caolan.mcnamara@collabora.com>
Diffstat (limited to 'sw')
-rw-r--r-- | sw/inc/doc.hxx | 8 | ||||
-rw-r--r-- | sw/qa/extras/uiwriter/uiwriter8.cxx | 46 | ||||
-rw-r--r-- | sw/source/core/doc/DocumentContentOperationsManager.cxx | 11 | ||||
-rw-r--r-- | sw/source/core/doc/docnum.cxx | 55 |
4 files changed, 109 insertions, 11 deletions
diff --git a/sw/inc/doc.hxx b/sw/inc/doc.hxx index 84378f8521ea..946c96fd29db 100644 --- a/sw/inc/doc.hxx +++ b/sw/inc/doc.hxx @@ -1073,7 +1073,9 @@ public: const SwNumRule&, SetNumRuleMode mode, SwRootFrame const* pLayout = nullptr, - const OUString& sContinuedListId = OUString()); + const OUString& sContinuedListId = OUString(), + SvxTextLeftMarginItem const* pTextLeftMarginToPropagate = nullptr, + SvxFirstLineIndentItem const* pFirstLineIndentToPropagate = nullptr); void SetCounted(const SwPaM&, bool bCounted, SwRootFrame const* pLayout); void MakeUniqueNumRules(const SwPaM & rPaM); @@ -1150,7 +1152,9 @@ public: int nNonEmptyAllowed, OUString& sListId, SwRootFrame const* pLayout, - const bool bInvestigateStartNode = false ); + const bool bInvestigateStartNode = false, + SvxTextLeftMarginItem const** o_ppTextLeftMargin = nullptr, + SvxFirstLineIndentItem const** o_ppFirstLineIndent = nullptr); // Paragraphs without numbering but with indents. bool NoNum( const SwPaM& ); diff --git a/sw/qa/extras/uiwriter/uiwriter8.cxx b/sw/qa/extras/uiwriter/uiwriter8.cxx index 13e437e68d96..60b1bd8e9ce6 100644 --- a/sw/qa/extras/uiwriter/uiwriter8.cxx +++ b/sw/qa/extras/uiwriter/uiwriter8.cxx @@ -25,6 +25,7 @@ #include <frameformats.hxx> #include <tools/json_writer.hxx> #include <unotools/streamwrap.hxx> +#include <editeng/lrspitem.hxx> #include <sfx2/linkmgr.hxx> #include <wrtsh.hxx> @@ -880,7 +881,7 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testInsertAutoTextIntoListFromParaStyle) pWrtShell->FwdPara(); pWrtShell->EndPara(/*bSelect=*/false); // expands autotext (via F3) - pWrtShell->Insert(" dt"); + pWrtShell->Insert(" jacr"); SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get()); pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_F3); @@ -889,6 +890,10 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testInsertAutoTextIntoListFromParaStyle) pWrtShell->SttEndDoc(/*bStt=*/true); pWrtShell->FwdPara(); + SwNumRule* pNumRule; + SvxTextLeftMarginItem const* pTextLeftMargin; + SvxFirstLineIndentItem const* pFirstLineIndent; + { SwTextNode& rNode{ *pWrtShell->GetCursor()->GetPoint()->GetNode().GetTextNode() }; // numrule from paragraph style, but not from direct formatting @@ -905,7 +910,32 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testInsertAutoTextIntoListFromParaStyle) CPPUNIT_ASSERT_EQUAL(SfxItemState::DEFAULT, pSet->GetItemState(RES_MARGIN_TEXTLEFT, false)); CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, pSet->GetItemState(RES_MARGIN_TEXTLEFT, true)); CPPUNIT_ASSERT_EQUAL(u"ListAndIndents"_ustr, rNode.GetTextColl()->GetName()); - CPPUNIT_ASSERT(rNode.GetText().startsWith("Item He heard quiet steps")); + CPPUNIT_ASSERT_EQUAL(u"Item We confirm receipt of your application material."_ustr, + rNode.GetText()); + pNumRule = rNode.GetNumRule(); + pTextLeftMargin = &rNode.GetAttr(RES_MARGIN_TEXTLEFT); + pFirstLineIndent = &rNode.GetAttr(RES_MARGIN_FIRSTLINE); + } + + pWrtShell->FwdPara(); + + { + SwTextNode& rNode{ *pWrtShell->GetCursor()->GetPoint()->GetNode().GetTextNode() }; + auto pSet{ rNode.GetpSwAttrSet() }; + CPPUNIT_ASSERT(pSet); + // list id was set + CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, pSet->GetItemState(RES_PARATR_LIST_ID, false)); + // middle paragraph was pasted - has numrule and indents applied directly + CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, pSet->GetItemState(RES_PARATR_NUMRULE, false)); + CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, pSet->GetItemState(RES_MARGIN_FIRSTLINE, false)); + CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, pSet->GetItemState(RES_MARGIN_TEXTLEFT, false)); + CPPUNIT_ASSERT_EQUAL(u"Default Paragraph Style"_ustr, rNode.GetTextColl()->GetName()); + CPPUNIT_ASSERT(rNode.GetText().startsWith("As more applicants applied")); + CPPUNIT_ASSERT_EQUAL(pNumRule, rNode.GetNumRule()); + CPPUNIT_ASSERT_EQUAL(pTextLeftMargin->GetTextLeft(), + rNode.GetAttr(RES_MARGIN_TEXTLEFT).GetTextLeft()); + CPPUNIT_ASSERT_EQUAL(pFirstLineIndent->GetTextFirstLineOffset(), + rNode.GetAttr(RES_MARGIN_FIRSTLINE).GetTextFirstLineOffset()); } pWrtShell->FwdPara(); @@ -926,7 +956,12 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testInsertAutoTextIntoListFromParaStyle) CPPUNIT_ASSERT_EQUAL(SfxItemState::DEFAULT, pSet->GetItemState(RES_MARGIN_TEXTLEFT, false)); CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, pSet->GetItemState(RES_MARGIN_TEXTLEFT, true)); CPPUNIT_ASSERT_EQUAL(u"ListAndIndents"_ustr, rNode.GetTextColl()->GetName()); - CPPUNIT_ASSERT_EQUAL(u""_ustr, rNode.GetText()); // this is a new empty paragraph + CPPUNIT_ASSERT(rNode.GetText().endsWith("as soon as we have come to a decision.")); + CPPUNIT_ASSERT_EQUAL(pNumRule, rNode.GetNumRule()); + CPPUNIT_ASSERT_EQUAL(pTextLeftMargin->GetTextLeft(), + rNode.GetAttr(RES_MARGIN_TEXTLEFT).GetTextLeft()); + CPPUNIT_ASSERT_EQUAL(pFirstLineIndent->GetTextFirstLineOffset(), + rNode.GetAttr(RES_MARGIN_FIRSTLINE).GetTextFirstLineOffset()); } pWrtShell->FwdPara(); @@ -948,6 +983,11 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testInsertAutoTextIntoListFromParaStyle) CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, pSet->GetItemState(RES_MARGIN_TEXTLEFT, true)); CPPUNIT_ASSERT_EQUAL(u"ListAndIndents"_ustr, rNode.GetTextColl()->GetName()); CPPUNIT_ASSERT_EQUAL(u"more"_ustr, rNode.GetText()); // pre-exising list item + CPPUNIT_ASSERT_EQUAL(pNumRule, rNode.GetNumRule()); + CPPUNIT_ASSERT_EQUAL(pTextLeftMargin->GetTextLeft(), + rNode.GetAttr(RES_MARGIN_TEXTLEFT).GetTextLeft()); + CPPUNIT_ASSERT_EQUAL(pFirstLineIndent->GetTextFirstLineOffset(), + rNode.GetAttr(RES_MARGIN_FIRSTLINE).GetTextFirstLineOffset()); } } diff --git a/sw/source/core/doc/DocumentContentOperationsManager.cxx b/sw/source/core/doc/DocumentContentOperationsManager.cxx index 832d03d67c1e..234d73aecb05 100644 --- a/sw/source/core/doc/DocumentContentOperationsManager.cxx +++ b/sw/source/core/doc/DocumentContentOperationsManager.cxx @@ -5107,12 +5107,16 @@ bool DocumentContentOperationsManager::CopyImplImpl(SwPaM& rPam, SwPosition& rPo // bullet list. // Keep also the <ListId> value for possible propagation. OUString aListIdToPropagate; + SvxTextLeftMarginItem const* pTextLeftMarginToPropagate{nullptr}; + SvxFirstLineIndentItem const* pFirstLineIndentToPropagate{nullptr}; const SwNumRule* pNumRuleToPropagate = - rDoc.SearchNumRule( rPos, false, true, false, 0, aListIdToPropagate, nullptr, true ); + rDoc.SearchNumRule(rPos, false, true, false, 0, aListIdToPropagate, nullptr, + true, &pTextLeftMarginToPropagate, &pFirstLineIndentToPropagate); if ( !pNumRuleToPropagate ) { pNumRuleToPropagate = - rDoc.SearchNumRule( rPos, false, false, false, 0, aListIdToPropagate, nullptr, true ); + rDoc.SearchNumRule(rPos, false, false, false, 0, aListIdToPropagate, nullptr, + true, &pTextLeftMarginToPropagate, &pFirstLineIndentToPropagate); } // #i86492# // Do not propagate previous found list, if @@ -5522,7 +5526,8 @@ bool DocumentContentOperationsManager::CopyImplImpl(SwPaM& rPam, SwPosition& rPo // the paragraph style, in that case applying it again in mpAttrSet could // override indents, so avoid that. rDoc.SetNumRule(*pCopyPam, *pNumRuleToPropagate, - SwDoc::SetNumRuleMode::DontSetIfAlreadyApplied, nullptr, aListIdToPropagate); + SwDoc::SetNumRuleMode::DontSetIfAlreadyApplied, nullptr, aListIdToPropagate, + pTextLeftMarginToPropagate, pFirstLineIndentToPropagate); } rDoc.getIDocumentRedlineAccess().SetRedlineFlags_intern( eOld ); diff --git a/sw/source/core/doc/docnum.cxx b/sw/source/core/doc/docnum.cxx index 2a777528f4e9..01c4a1b3874a 100644 --- a/sw/source/core/doc/docnum.cxx +++ b/sw/source/core/doc/docnum.cxx @@ -46,6 +46,7 @@ #include <SwNodeNum.hxx> #include <list.hxx> #include <calbck.hxx> +#include <editeng/lrspitem.hxx> #include <comphelper/string.hxx> #include <comphelper/random.hxx> #include <o3tl/safeint.hxx> @@ -862,7 +863,9 @@ OUString SwDoc::SetNumRule( const SwPaM& rPam, const SwNumRule& rRule, SetNumRuleMode eMode, SwRootFrame const*const pLayout, - const OUString& sContinuedListId) + const OUString& sContinuedListId, + SvxTextLeftMarginItem const*const pTextLeftMarginToPropagate, + SvxFirstLineIndentItem const*const pFirstLineIndentToPropagate) { OUString sListId; @@ -982,6 +985,19 @@ OUString SwDoc::SetNumRule( const SwPaM& rPam, getIDocumentContentOperations().InsertPoolItem(temp, SwNumRuleItem(pNewOrChangedNumRule->GetName()), SetAttrMode::DEFAULT, pLayout); + // apply provided margins to get visually same result + if (pTextLeftMarginToPropagate) + { + getIDocumentContentOperations().InsertPoolItem(temp, + *pTextLeftMarginToPropagate, + SetAttrMode::DEFAULT, pLayout); + } + if (pFirstLineIndentToPropagate) + { + getIDocumentContentOperations().InsertPoolItem(temp, + *pFirstLineIndentToPropagate, + SetAttrMode::DEFAULT, pLayout); + } } } } @@ -991,6 +1007,18 @@ OUString SwDoc::SetNumRule( const SwPaM& rPam, getIDocumentContentOperations().InsertPoolItem(aPam, SwNumRuleItem(pNewOrChangedNumRule->GetName()), SetAttrMode::DEFAULT, pLayout); + if (pTextLeftMarginToPropagate) + { + getIDocumentContentOperations().InsertPoolItem(aPam, + *pTextLeftMarginToPropagate, + SetAttrMode::DEFAULT, pLayout); + } + if (pFirstLineIndentToPropagate) + { + getIDocumentContentOperations().InsertPoolItem(aPam, + *pFirstLineIndentToPropagate, + SetAttrMode::DEFAULT, pLayout); + } } } @@ -1643,7 +1671,9 @@ const SwNumRule * SwDoc::SearchNumRule(const SwPosition & rPos, int nNonEmptyAllowed, OUString& sListId, SwRootFrame const* pLayout, - const bool bInvestigateStartNode) + const bool bInvestigateStartNode, + SvxTextLeftMarginItem const** o_ppTextLeftMargin, + SvxFirstLineIndentItem const** o_ppFirstLineIndent) { const SwNumRule * pResult = nullptr; SwTextNode * pTextNd = rPos.GetNode().GetTextNode(); @@ -1680,9 +1710,28 @@ const SwNumRule * SwDoc::SearchNumRule(const SwPosition & rPos, ( ( bNum && pNumRule->Get(0).IsEnumeration()) || ( !bNum && pNumRule->Get(0).IsItemize() ) ) ) // #i22362#, #i29560# { - pResult = pTextNd->GetNumRule(); + pResult = pNumRule; // provide also the list id, to which the text node belongs. sListId = pTextNd->GetListId(); + // also get the margins that override the numrule + int const nListLevel{pTextNd->GetActualListLevel()}; + if ((o_ppTextLeftMargin || o_ppFirstLineIndent) + && 0 <= nListLevel + && pNumRule->Get(o3tl::narrowing<sal_uInt16>(nListLevel)) + .GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT) + { + ::sw::ListLevelIndents const indents{pTextNd->AreListLevelIndentsApplicable()}; + if (!(indents & ::sw::ListLevelIndents::LeftMargin) + && o_ppTextLeftMargin) + { + *o_ppTextLeftMargin = &pTextNd->SwContentNode::GetAttr(RES_MARGIN_TEXTLEFT); + } + if (!(indents & ::sw::ListLevelIndents::FirstLine) + && o_ppFirstLineIndent) + { + *o_ppFirstLineIndent = &pTextNd->SwContentNode::GetAttr(RES_MARGIN_FIRSTLINE); + } + } } break; |