diff options
Diffstat (limited to 'sw')
-rw-r--r-- | sw/inc/fldref.hrc | 1 | ||||
-rw-r--r-- | sw/inc/reffld.hxx | 28 | ||||
-rw-r--r-- | sw/qa/extras/ooxmlexport/ooxmlexport.cxx | 2 | ||||
-rw-r--r-- | sw/qa/extras/uiwriter/uiwriter7.cxx | 15 | ||||
-rw-r--r-- | sw/source/core/access/accpara.cxx | 3 | ||||
-rw-r--r-- | sw/source/core/crsr/crstrvl.cxx | 10 | ||||
-rw-r--r-- | sw/source/core/fields/reffld.cxx | 497 | ||||
-rw-r--r-- | sw/source/core/text/txtfld.cxx | 15 | ||||
-rw-r--r-- | sw/source/core/unocore/unofield.cxx | 2 | ||||
-rw-r--r-- | sw/source/filter/ww8/wrtww8.hxx | 3 | ||||
-rw-r--r-- | sw/source/filter/ww8/ww8atr.cxx | 87 | ||||
-rw-r--r-- | sw/source/filter/ww8/ww8par5.cxx | 15 | ||||
-rw-r--r-- | sw/source/ui/fldui/fldref.cxx | 70 | ||||
-rw-r--r-- | sw/source/ui/fldui/fldref.hxx | 1 | ||||
-rw-r--r-- | sw/source/uibase/docvw/edtwin2.cxx | 2 | ||||
-rw-r--r-- | sw/source/uibase/fldui/fldmgr.cxx | 16 | ||||
-rw-r--r-- | sw/source/uibase/utlui/content.cxx | 2 |
17 files changed, 623 insertions, 146 deletions
diff --git a/sw/inc/fldref.hrc b/sw/inc/fldref.hrc index 20eae2d31e14..30f3f5ed1554 100644 --- a/sw/inc/fldref.hrc +++ b/sw/inc/fldref.hrc @@ -31,6 +31,7 @@ const TranslateId FLD_REF_PAGE_TYPES[] = NC_("fldrefpage|liststore1", "Endnotes"), NC_("fldrefpage|liststore1", "Headings"), NC_("fldrefpage|liststore1", "Numbered Paragraphs"), + NC_("fldrefpage|liststore1", "Styles"), }; #endif diff --git a/sw/inc/reffld.hxx b/sw/inc/reffld.hxx index 931441d27725..28ced8dcc2cb 100644 --- a/sw/inc/reffld.hxx +++ b/sw/inc/reffld.hxx @@ -26,8 +26,10 @@ class SfxPoolItem; class SwDoc; class SwTextNode; +class SwContentFrame; class SwTextField; class SwRootFrame; +class SwFrame; bool IsFrameBehind( const SwTextNode& rMyNd, sal_Int32 nMySttPos, const SwTextNode& rBehindNd, sal_Int32 nSttPos ); @@ -39,7 +41,8 @@ enum REFERENCESUBTYPE REF_BOOKMARK, REF_OUTLINE, REF_FOOTNOTE, - REF_ENDNOTE + REF_ENDNOTE, + REF_STYLE }; enum REFERENCEMARK @@ -80,7 +83,8 @@ public: static SwTextNode* FindAnchor( SwDoc* pDoc, const OUString& rRefMark, sal_uInt16 nSubType, sal_uInt16 nSeqNo, sal_Int32* pStt, sal_Int32* pEnd = nullptr, - SwRootFrame const* pLayout = nullptr); + SwRootFrame const* pLayout = nullptr, + SwTextNode* pSelf = nullptr, SwFrame* pFrame = nullptr); void UpdateGetReferences(); }; @@ -95,15 +99,22 @@ private: /// reference to either a SwTextFootnote::m_nSeqNo or a SwSetExpField::mnSeqNo sal_uInt16 m_nSeqNo; + SwTextNode* m_pTextNode; ///< a pointer to the text node which contains the field + SwFrame* m_pFrame; ///< a pointer to the frame which contains the field + /* m_pTextNode and m_pFrame are used for STYLEREF, for other subtypes these will often be nullptr */ + virtual OUString ExpandImpl(SwRootFrame const* pLayout) const override; virtual std::unique_ptr<SwField> Copy() const override; public: SwGetRefField( SwGetRefFieldType*, OUString aSetRef, OUString aReferenceLanguage, - sal_uInt16 nSubType, sal_uInt16 nSeqNo, sal_uLong nFormat ); + sal_uInt16 nSubType, sal_uInt16 nSeqNo, sal_uLong nFormat, + SwTextNode* pTextNode, SwFrame* pFrame ); virtual ~SwGetRefField() override; + void ChangeExpansion(SwFrame* pFrame, const SwTextField* pField); + virtual OUString GetFieldName() const override; const OUString& GetSetRefName() const { return m_sSetRefName; } @@ -111,11 +122,13 @@ public: // #i81002# /** The <SwTextField> instance, which represents the text attribute for the <SwGetRefField> instance, has to be passed to the method. - This <SwTextField> instance is needed for the reference format type REF_UPDOWN - and REF_NUMBER. + This <SwTextField> instance is needed for the reference format type REF_UPDOWN, REF_NUMBER + and REF_STYLE. Note: This instance may be NULL (field in Undo/Redo). This will cause no update for these reference format types. */ void UpdateField( const SwTextField* pFieldTextAttr ); + void UpdateField( const SwTextField* pFieldTextAttr, const SwRootFrame* const pLayout, + OUString& rText ); void SetExpand( const OUString& rStr ); @@ -126,9 +139,10 @@ public: // --> #i81002# bool IsRefToHeadingCrossRefBookmark() const; bool IsRefToNumItemCrossRefBookmark() const; - const SwTextNode* GetReferencedTextNode() const; + const SwTextNode* GetReferencedTextNode(SwTextNode* pTextNode) const; // #i85090# OUString GetExpandedTextOfReferencedTextNode(SwRootFrame const& rLayout) const; + OUString GetExpandedTextOfReferencedTextNode(SwRootFrame const& rLayout, SwTextNode* pTextNode) const; /// Get/set SequenceNo (of interest only for REF_SEQUENCEFLD). sal_uInt16 GetSeqNo() const { return m_nSeqNo; } @@ -138,6 +152,8 @@ public: virtual OUString GetPar1() const override; virtual void SetPar1(const OUString& rStr) override; + void SetText(OUString sText, SwRootFrame* pLayout); + virtual OUString GetPar2() const override; virtual bool QueryValue( css::uno::Any& rVal, sal_uInt16 nWhichId ) const override; virtual bool PutValue( const css::uno::Any& rVal, sal_uInt16 nWhichId ) override; diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx index 5b5001878eb1..4fc4b7a218f8 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx @@ -602,7 +602,7 @@ DECLARE_OOXMLEXPORT_TEST(testMultiPageToc, "multi-page-toc.docx") CPPUNIT_ASSERT_EQUAL(OUString("Table of Contents1"), xTextSection->getName()); // There should be a field in the header as well. uno::Reference<text::XText> xHeaderText = getProperty< uno::Reference<text::XText> >(getStyles("PageStyles")->getByName("Standard"), "HeaderText"); - CPPUNIT_ASSERT_EQUAL(OUString("TextFieldStart"), getProperty<OUString>(getRun(getParagraphOfText(1, xHeaderText), 1), "TextPortionType")); + CPPUNIT_ASSERT_EQUAL(OUString("TextField"), getProperty<OUString>(getRun(getParagraphOfText(1, xHeaderText), 1), "TextPortionType")); } DECLARE_OOXMLEXPORT_TEST(testTextboxTable, "textbox-table.docx") diff --git a/sw/qa/extras/uiwriter/uiwriter7.cxx b/sw/qa/extras/uiwriter/uiwriter7.cxx index 697a9defa63c..10cb2ace0179 100644 --- a/sw/qa/extras/uiwriter/uiwriter7.cxx +++ b/sw/qa/extras/uiwriter/uiwriter7.cxx @@ -780,14 +780,16 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest7, testTdf77342) //moving cursor to the starting of document pWrtShell->StartOfSection(); //inserting reference field 1 - SwGetRefField aField1(pRefType, "", "", REF_FOOTNOTE, sal_uInt16(0), REF_CONTENT); + SwGetRefField aField1(pRefType, "", "", REF_FOOTNOTE, sal_uInt16(0), REF_CONTENT, nullptr, + nullptr); pWrtShell->InsertField2(aField1); //inserting second footnote pWrtShell->InsertFootnote(""); pWrtShell->StartOfSection(); pCursor->Move(fnMoveForward); //inserting reference field 2 - SwGetRefField aField2(pRefType, "", "", REF_FOOTNOTE, sal_uInt16(1), REF_CONTENT); + SwGetRefField aField2(pRefType, "", "", REF_FOOTNOTE, sal_uInt16(1), REF_CONTENT, nullptr, + nullptr); pWrtShell->InsertField2(aField2); //inserting third footnote pWrtShell->InsertFootnote(""); @@ -795,7 +797,8 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest7, testTdf77342) pCursor->Move(fnMoveForward); pCursor->Move(fnMoveForward); //inserting reference field 3 - SwGetRefField aField3(pRefType, "", "", REF_FOOTNOTE, sal_uInt16(2), REF_CONTENT); + SwGetRefField aField3(pRefType, "", "", REF_FOOTNOTE, sal_uInt16(2), REF_CONTENT, nullptr, + nullptr); pWrtShell->InsertField2(aField3); //updating the fields IDocumentFieldsAccess& rField(pDoc->getIDocumentFieldsAccess()); @@ -1035,7 +1038,7 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest7, testTdf63553) pWrtShell->StartOfSection(); //inserting reference field 1 SwGetRefField aGetField1(pRefType, "Illustration", "", REF_SEQUENCEFLD, sal_uInt16(0), - REF_CONTENT); + REF_CONTENT, nullptr, nullptr); pWrtShell->InsertField2(aGetField1); //now we have ref1-seq1 //moving the cursor @@ -1048,7 +1051,7 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest7, testTdf63553) pCursor->Move(fnMoveForward); //inserting reference field 2 SwGetRefField aGetField2(pRefType, "Illustration", "", REF_SEQUENCEFLD, sal_uInt16(1), - REF_CONTENT); + REF_CONTENT, nullptr, nullptr); pWrtShell->InsertField2(aGetField2); //now we have ref1-ref2-seq1-seq2 //moving the cursor @@ -1062,7 +1065,7 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest7, testTdf63553) pCursor->Move(fnMoveForward); //inserting reference field 3 SwGetRefField aGetField3(pRefType, "Illustration", "", REF_SEQUENCEFLD, sal_uInt16(2), - REF_CONTENT); + REF_CONTENT, nullptr, nullptr); pWrtShell->InsertField2(aGetField3); //now after insertion we have ref1-ref2-ref3-seq1-seq2-seq3 //updating the fields diff --git a/sw/source/core/access/accpara.cxx b/sw/source/core/access/accpara.cxx index 7ca30145b1d6..3ea06717835c 100644 --- a/sw/source/core/access/accpara.cxx +++ b/sw/source/core/access/accpara.cxx @@ -1229,6 +1229,9 @@ OUString SwAccessibleParagraph::GetFieldTypeNameAtIndex(sal_Int32 nIndex) case REF_SEQUENCEFLD: sEntry = static_cast<const SwGetRefField*>(pField)->GetSetRefName(); break; + case REF_STYLE: + sEntry = "StyleRef"; + break; } //Get format string strTypeName = sEntry; diff --git a/sw/source/core/crsr/crstrvl.cxx b/sw/source/core/crsr/crstrvl.cxx index 471e5d989780..3326648b3a5a 100644 --- a/sw/source/core/crsr/crstrvl.cxx +++ b/sw/source/core/crsr/crstrvl.cxx @@ -1409,8 +1409,14 @@ bool SwCursorShell::GotoRefMark( const OUString& rRefMark, sal_uInt16 nSubType, SwCursorSaveState aSaveState( *m_pCurrentCursor ); sal_Int32 nPos = -1; - SwTextNode* pTextNd = SwGetRefFieldType::FindAnchor( GetDoc(), rRefMark, - nSubType, nSeqNo, &nPos, nullptr, GetLayout()); + + SwPaM* pCursor = GetCursor(); + SwPosition* pPos = pCursor->GetPoint(); + SwTextNode* pRefTextNd = pPos->GetNode().GetTextNode(); + SwContentFrame* pRefFrame = GetCurrFrame(); + + SwTextNode* pTextNd = SwGetRefFieldType::FindAnchor(GetDoc(), rRefMark, + nSubType, nSeqNo, &nPos, nullptr, GetLayout(), pRefTextNd, pRefFrame); if( !pTextNd || !pTextNd->GetNodes().IsDocNodes() ) return false; diff --git a/sw/source/core/fields/reffld.cxx b/sw/source/core/fields/reffld.cxx index c0ed059e2882..9f43ae6b0bca 100644 --- a/sw/source/core/fields/reffld.cxx +++ b/sw/source/core/fields/reffld.cxx @@ -42,6 +42,7 @@ #include <reffld.hxx> #include <expfld.hxx> #include <txtfrm.hxx> +#include <notxtfrm.hxx> #include <flyfrm.hxx> #include <pagedesc.hxx> #include <IMark.hxx> @@ -65,6 +66,7 @@ #include <string_view> #include <map> #include <algorithm> +#include <deque> using namespace ::com::sun::star; using namespace ::com::sun::star::text; @@ -348,12 +350,15 @@ static void lcl_formatReferenceLanguage( OUString& rRefText, /// get references SwGetRefField::SwGetRefField( SwGetRefFieldType* pFieldType, OUString aSetRef, OUString aSetReferenceLanguage, sal_uInt16 nSubTyp, - sal_uInt16 nSequenceNo, sal_uLong nFormat ) - : SwField( pFieldType, nFormat ), - m_sSetRefName( std::move(aSetRef) ), - m_sSetReferenceLanguage( std::move(aSetReferenceLanguage) ), - m_nSubType( nSubTyp ), - m_nSeqNo( nSequenceNo ) + sal_uInt16 nSequenceNo, sal_uLong nFormat, SwTextNode* pTextNode, + SwFrame* pFrame ) + : SwField(pFieldType, nFormat), + m_sSetRefName(std::move(aSetRef)), + m_sSetReferenceLanguage(std::move(aSetReferenceLanguage)), + m_nSubType(nSubTyp), + m_nSeqNo(nSequenceNo), + m_pTextNode(pTextNode), + m_pFrame(pFrame) { } @@ -361,6 +366,24 @@ SwGetRefField::~SwGetRefField() { } +void SwGetRefField::ChangeExpansion(SwFrame* pFrame, const SwTextField* pField) +{ + m_pFrame = pFrame; + m_pTextNode = pField->GetpTextNode(); +} + +void SwGetRefField::SetText(OUString sText, SwRootFrame* pLayout) +{ + if (pLayout->IsHideRedlines()) + { + m_sTextRLHidden = sText; + } + else + { + m_sText = sText; + } +} + OUString SwGetRefField::GetDescription() const { return SwResId(STR_REFERENCE); @@ -389,13 +412,14 @@ bool SwGetRefField::IsRefToNumItemCrossRefBookmark() const ::sw::mark::CrossRefNumItemBookmark::IsLegalName(m_sSetRefName); } -const SwTextNode* SwGetRefField::GetReferencedTextNode() const +const SwTextNode* SwGetRefField::GetReferencedTextNode(SwTextNode* pTextNode) const { SwGetRefFieldType *pTyp = dynamic_cast<SwGetRefFieldType*>(GetTyp()); if (!pTyp) return nullptr; sal_Int32 nDummy = -1; - return SwGetRefFieldType::FindAnchor( &pTyp->GetDoc(), m_sSetRefName, m_nSubType, m_nSeqNo, &nDummy ); + return SwGetRefFieldType::FindAnchor( &pTyp->GetDoc(), m_sSetRefName, m_nSubType, m_nSeqNo, &nDummy, + nullptr, nullptr, pTextNode ? pTextNode : m_pTextNode, m_pFrame ); } // strikethrough for tooltips using Unicode combining character @@ -414,7 +438,13 @@ static OUString lcl_formatStringByCombiningCharacter(std::u16string_view sText, OUString SwGetRefField::GetExpandedTextOfReferencedTextNode( SwRootFrame const& rLayout) const { - const SwTextNode* pReferencedTextNode( GetReferencedTextNode() ); + return GetExpandedTextOfReferencedTextNode(rLayout, m_pTextNode); +} + +OUString SwGetRefField::GetExpandedTextOfReferencedTextNode( + SwRootFrame const& rLayout, SwTextNode* pTextNode) const +{ + const SwTextNode* pReferencedTextNode( GetReferencedTextNode(pTextNode) ); if ( !pReferencedTextNode ) return OUString(); @@ -484,36 +514,41 @@ static void FilterText(OUString & rText, LanguageType const eLang, // #i81002# - parameter <pFieldTextAttr> added void SwGetRefField::UpdateField( const SwTextField* pFieldTextAttr ) { - m_sText.clear(); - m_sTextRLHidden.clear(); + SwDoc& rDoc = static_cast<SwGetRefFieldType*>(GetTyp())->GetDoc(); + + for (SwRootFrame const* const pLay : rDoc.GetAllLayouts()) + { + if (pLay->IsHideRedlines()) + { + UpdateField(pFieldTextAttr, pLay, m_sTextRLHidden); + } + else + { + UpdateField(pFieldTextAttr, pLay, m_sText); + } + } +} +void SwGetRefField::UpdateField(const SwTextField* pFieldTextAttr, const SwRootFrame* const pLayout, + OUString& rText) +{ SwDoc& rDoc = static_cast<SwGetRefFieldType*>(GetTyp())->GetDoc(); + + rText.clear(); + // finding the reference target (the number) sal_Int32 nNumStart = -1; sal_Int32 nNumEnd = -1; SwTextNode* pTextNd = SwGetRefFieldType::FindAnchor( - &rDoc, m_sSetRefName, m_nSubType, m_nSeqNo, &nNumStart, &nNumEnd + &rDoc, m_sSetRefName, m_nSubType, m_nSeqNo, &nNumStart, &nNumEnd, + pLayout, pFieldTextAttr ? &pFieldTextAttr->GetTextNode() : m_pTextNode, m_pFrame ); // not found? if ( !pTextNd ) { - m_sText = SwViewShell::GetShellRes()->aGetRefField_RefItemNotFound; - m_sTextRLHidden = m_sText; - return ; - } + rText = SwViewShell::GetShellRes()->aGetRefField_RefItemNotFound; - SwRootFrame const* pLayout(nullptr); - SwRootFrame const* pLayoutRLHidden(nullptr); - for (SwRootFrame const*const pLay : rDoc.GetAllLayouts()) - { - if (pLay->IsHideRedlines()) - { - pLayoutRLHidden = pLay; - } - else - { - pLayout = pLay; - } + return; } // where is the category name (e.g. "Illustration")? @@ -608,18 +643,21 @@ void SwGetRefField::UpdateField( const SwTextField* pFieldTextAttr ) SwTextFootnote* const pFootnoteIdx = rDoc.GetFootnoteIdxs()[i]; if( m_nSeqNo == pFootnoteIdx->GetSeqRefNo() ) { - m_sText = pFootnoteIdx->GetFootnote().GetViewNumStr(rDoc, nullptr); - m_sTextRLHidden = pFootnoteIdx->GetFootnote().GetViewNumStr(rDoc, pLayoutRLHidden); + rText = pFootnoteIdx->GetFootnote().GetViewNumStr(rDoc, pLayout); if (!m_sSetReferenceLanguage.isEmpty()) { - lcl_formatReferenceLanguage(m_sText, false, GetLanguage(), m_sSetReferenceLanguage); - lcl_formatReferenceLanguage(m_sTextRLHidden, false, GetLanguage(), m_sSetReferenceLanguage); + lcl_formatReferenceLanguage(rText, false, GetLanguage(), m_sSetReferenceLanguage); } break; } } return; + case REF_STYLE: + nStart = 0; + nEnd = nLen; + break; + case REF_SETREFATTR: nStart = nNumStart; nEnd = nNumEnd; @@ -631,26 +669,32 @@ void SwGetRefField::UpdateField( const SwTextField* pFieldTextAttr ) if( nStart != nEnd ) // a section? { - m_sText = pTextNd->GetExpandText(pLayout, nStart, nEnd - nStart, false, false, false, ExpandMode::HideDeletions); - // show the referenced text without the deletions, but if the whole text was - // deleted, show the original text for the sake of the comfortable reviewing - // (with strikethrough in tooltip, see GetExpandedTextOfReferencedTextNode()) - if ( m_sText.isEmpty() ) - m_sText = pTextNd->GetExpandText(pLayout, nStart, nEnd - nStart, false, false, false, ExpandMode(0)); - - if (m_nSubType == REF_OUTLINE - || (m_nSubType == REF_SEQUENCEFLD && REF_CONTENT == GetFormat())) + if (pLayout->IsHideRedlines()) { - m_sTextRLHidden = sw::GetExpandTextMerged( - pLayoutRLHidden, *pTextNd, false, false, ExpandMode(0)); + if (m_nSubType == REF_OUTLINE + || (m_nSubType == REF_SEQUENCEFLD && REF_CONTENT == GetFormat())) + { + rText = sw::GetExpandTextMerged(pLayout, *pTextNd, false, false, + ExpandMode(0)); + } + else + { + rText = pTextNd->GetExpandText(pLayout, nStart, nEnd - nStart, false, false, + false, ExpandMode::HideDeletions); + } } else { - m_sTextRLHidden = pTextNd->GetExpandText(pLayoutRLHidden, - nStart, nEnd - nStart, false, false, false, ExpandMode::HideDeletions); + rText = pTextNd->GetExpandText(pLayout, nStart, nEnd - nStart, false, false, + false, ExpandMode::HideDeletions); + // show the referenced text without the deletions, but if the whole text was + // deleted, show the original text for the sake of the comfortable reviewing + // (with strikethrough in tooltip, see GetExpandedTextOfReferencedTextNode()) + if (rText.isEmpty()) + rText = pTextNd->GetExpandText(pLayout, nStart, nEnd - nStart, false, false, + false, ExpandMode(0)); } FilterText(m_sText, GetLanguage(), m_sSetReferenceLanguage); - FilterText(m_sTextRLHidden, GetLanguage(), m_sSetReferenceLanguage); } } break; @@ -658,10 +702,7 @@ void SwGetRefField::UpdateField( const SwTextField* pFieldTextAttr ) case REF_PAGE: case REF_PAGE_PGDESC: { - auto const func = - [this, pTextNd, nNumStart](OUString & rText, SwRootFrame const*const pLay) - { - SwTextFrame const* pFrame = static_cast<SwTextFrame*>(pTextNd->getLayoutFrame(pLay, nullptr, nullptr)); + SwTextFrame const* pFrame = static_cast<SwTextFrame*>(pTextNd->getLayoutFrame(pLayout, nullptr, nullptr)); SwTextFrame const*const pSave = pFrame; if (pFrame) { @@ -688,35 +729,25 @@ void SwGetRefField::UpdateField( const SwTextField* pFieldTextAttr ) if (!m_sSetReferenceLanguage.isEmpty()) lcl_formatReferenceLanguage(rText, false, GetLanguage(), m_sSetReferenceLanguage); } - }; - // sw_redlinehide: currently only one of these layouts will exist, - // so the getLayoutFrame will use the same frame in both cases - func(m_sText, pLayout); - func(m_sTextRLHidden, pLayoutRLHidden); } break; case REF_CHAPTER: + { + // a bit tricky: search any frame + SwFrame const* const pFrame = pTextNd->getLayoutFrame(pLayout); + if (pFrame) { - auto const func = - [this, pTextNd](OUString & rText, SwRootFrame const*const pLay) - { - // a bit tricky: search any frame - SwFrame const*const pFrame = pTextNd->getLayoutFrame(pLay); - if( pFrame ) - { - SwChapterFieldType aFieldTyp; - SwChapterField aField( &aFieldTyp, 0 ); - aField.SetLevel( MAXLEVEL - 1 ); - aField.ChangeExpansion( *pFrame, pTextNd, true ); - rText = aField.GetNumber(pLay); + SwChapterFieldType aFieldTyp; + SwChapterField aField(&aFieldTyp, 0); + aField.SetLevel(MAXLEVEL - 1); + aField.ChangeExpansion(*pFrame, pTextNd, true); - if (!m_sSetReferenceLanguage.isEmpty()) - lcl_formatReferenceLanguage(rText, false, GetLanguage(), m_sSetReferenceLanguage); - } - }; - func(m_sText, pLayout); - func(m_sTextRLHidden, pLayoutRLHidden); + rText = aField.GetNumber(pLayout); + + if (!m_sSetReferenceLanguage.isEmpty()) + lcl_formatReferenceLanguage(rText, false, GetLanguage(), m_sSetReferenceLanguage); + } } break; @@ -732,22 +763,19 @@ void SwGetRefField::UpdateField( const SwTextField* pFieldTextAttr ) // first a "short" test - in case both are in the same node if( pFieldTextAttr->GetpTextNode() == pTextNd ) { - m_sText = nNumStart < pFieldTextAttr->GetStart() + rText = nNumStart < pFieldTextAttr->GetStart() ? aLocaleData.getAboveWord() : aLocaleData.getBelowWord(); - m_sTextRLHidden = m_sText; break; } - m_sText = ::IsFrameBehind( *pFieldTextAttr->GetpTextNode(), pFieldTextAttr->GetStart(), + rText = ::IsFrameBehind( *pFieldTextAttr->GetpTextNode(), pFieldTextAttr->GetStart(), *pTextNd, nNumStart ) ? aLocaleData.getAboveWord() : aLocaleData.getBelowWord(); if (!m_sSetReferenceLanguage.isEmpty()) - lcl_formatReferenceLanguage(m_sText, false, GetLanguage(), m_sSetReferenceLanguage); - - m_sTextRLHidden = m_sText; + lcl_formatReferenceLanguage(rText, false, GetLanguage(), m_sSetReferenceLanguage); } break; // #i81002# @@ -759,20 +787,12 @@ void SwGetRefField::UpdateField( const SwTextField* pFieldTextAttr ) { auto result = MakeRefNumStr(pLayout, pFieldTextAttr->GetTextNode(), *pTextNd, GetFormat()); - m_sText = result.first; + rText = result.first; // for differentiation of Roman numbers and letters in Hungarian article handling bool bClosingParenthesis = result.second; if (!m_sSetReferenceLanguage.isEmpty()) { - lcl_formatReferenceLanguage(m_sText, bClosingParenthesis, GetLanguage(), m_sSetReferenceLanguage); - } - result = - MakeRefNumStr(pLayoutRLHidden, pFieldTextAttr->GetTextNode(), *pTextNd, GetFormat()); - m_sTextRLHidden = result.first; - bClosingParenthesis = result.second; - if (!m_sSetReferenceLanguage.isEmpty()) - { - lcl_formatReferenceLanguage(m_sTextRLHidden, bClosingParenthesis, GetLanguage(), m_sSetReferenceLanguage); + lcl_formatReferenceLanguage(rText, bClosingParenthesis, GetLanguage(), m_sSetReferenceLanguage); } } } @@ -876,7 +896,7 @@ std::unique_ptr<SwField> SwGetRefField::Copy() const { std::unique_ptr<SwGetRefField> pField( new SwGetRefField( static_cast<SwGetRefFieldType*>(GetTyp()), m_sSetRefName, m_sSetReferenceLanguage, m_nSubType, - m_nSeqNo, GetFormat() ) ); + m_nSeqNo, GetFormat(), m_pTextNode, m_pFrame ) ); pField->m_sText = m_sText; pField->m_sTextRLHidden = m_sTextRLHidden; return std::unique_ptr<SwField>(pField.release()); @@ -935,6 +955,7 @@ bool SwGetRefField::QueryValue( uno::Any& rAny, sal_uInt16 nWhichId ) const case REF_OUTLINE : OSL_FAIL("not implemented"); break; case REF_FOOTNOTE : nSource = ReferenceFieldSource::FOOTNOTE; break; case REF_ENDNOTE : nSource = ReferenceFieldSource::ENDNOTE; break; + case REF_STYLE : nSource = ReferenceFieldSource::STYLE; break; } rAny <<= nSource; } @@ -1019,6 +1040,7 @@ bool SwGetRefField::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId ) case ReferenceFieldSource::BOOKMARK : m_nSubType = REF_BOOKMARK ; break; case ReferenceFieldSource::FOOTNOTE : m_nSubType = REF_FOOTNOTE ; break; case ReferenceFieldSource::ENDNOTE : m_nSubType = REF_ENDNOTE ; break; + case ReferenceFieldSource::STYLE : m_nSubType = REF_STYLE ; break; } } break; @@ -1167,10 +1189,52 @@ bool IsMarkHintHidden(SwRootFrame const& rLayout, } // namespace sw -SwTextNode* SwGetRefFieldType::FindAnchor( SwDoc* pDoc, const OUString& rRefMark, - sal_uInt16 nSubType, sal_uInt16 nSeqNo, - sal_Int32* pStt, sal_Int32* pEnd, - SwRootFrame const*const pLayout) +enum StyleRefElementType +{ + Default, + Reference, /* e.g. footnotes, endnotes */ + Marginal, /* headers, footers */ +}; + +namespace +{ + /// Picks the first text node with a matching style from a double ended queue, starting at the front + /// This allows us to use the deque either as a stack or as a queue depending on whether we want to search up or down + SwTextNode* SearchForStyleAnchor(SwTextNode* pSelf, std::deque<SwNode*> pToSearch, + const OUString& rStyleName, bool bCaseSensitive = true) + { + while (!pToSearch.empty()) + { + SwNode* pCurrent = pToSearch.front(); + pToSearch.pop_front(); + + if (*pCurrent == *pSelf) + continue; + + SwTextNode* pTextNode = pCurrent->GetTextNode(); + if (!pTextNode) + continue; + + if (bCaseSensitive) + { + if (pTextNode->GetFormatColl()->GetName() == rStyleName) + return pTextNode; + } + else + { + if (pTextNode->GetFormatColl()->GetName().equalsIgnoreAsciiCase(rStyleName)) + return pTextNode; + } + } + + return nullptr; + } +} + +SwTextNode* SwGetRefFieldType::FindAnchor(SwDoc* pDoc, const OUString& rRefMark, + sal_uInt16 nSubType, sal_uInt16 nSeqNo, sal_Int32* pStt, + sal_Int32* pEnd, SwRootFrame const* const pLayout, + SwTextNode* pSelf, SwFrame* pContentFrame) { OSL_ENSURE( pStt, "Why did no one check the StartPos?" ); @@ -1285,6 +1349,251 @@ SwTextNode* SwGetRefFieldType::FindAnchor( SwDoc* pDoc, const OUString& rRefMark } } break; + case REF_STYLE: + if (!pSelf) + break; + + const SwNodes& nodes = pDoc->GetNodes(); + + StyleRefElementType elementType = StyleRefElementType::Default; + const SwTextNode* pReference = nullptr; + + { /* Check if we're a footnote/endnote */ + for (SwTextFootnote* pFootnoteIdx : pDoc->GetFootnoteIdxs()) + { + if (pLayout && pLayout->IsHideRedlines() + && sw::IsFootnoteDeleted(rIDRA, *pFootnoteIdx)) + { + continue; + } + const SwNodeIndex* pIdx = pFootnoteIdx->GetStartNode(); + if (pIdx) + { + SwNodeIndex aIdx(*pIdx, 1); + SwTextNode* pFootnoteNode = aIdx.GetNode().GetTextNode(); + if (nullptr == pFootnoteNode) + pFootnoteNode + = static_cast<SwTextNode*>(pDoc->GetNodes().GoNext(&aIdx)); + + if (*pSelf == *pFootnoteNode) + { + elementType = StyleRefElementType::Reference; + pReference = &pFootnoteIdx->GetTextNode(); + } + } + } + } + + if (pDoc->IsInHeaderFooter(*pSelf)) + { + elementType = StyleRefElementType::Marginal; + } + + if (pReference == nullptr) + { + pReference = pSelf; + } + + switch (elementType) + { + case Marginal: + { + // For marginals, styleref tries to act on the current page first + // 1. Get the page we're on, search it from top to bottom + + Point aPt; + std::pair<Point, bool> const tmp(aPt, false); + + if (!pContentFrame) SAL_WARN("<SwGetRefFieldType::FindAnchor(..)>", "Missing content frame for marginal styleref"); + const SwPageFrame* pPageFrame = nullptr; + + if (pContentFrame) + pPageFrame = pContentFrame->FindPageFrame(); + + const SwNode* pPageStart(nullptr); + const SwNode* pPageEnd(nullptr); + + if (pPageFrame) + { + const SwContentFrame* pPageStartFrame = pPageFrame->FindFirstBodyContent(); + const SwContentFrame* pPageEndFrame = pPageFrame->FindLastBodyContent(); + + if (pPageStartFrame) { + if (pPageStartFrame->IsTextFrame()) + { + pPageStart = static_cast<const SwTextFrame*>(pPageStartFrame) + ->GetTextNodeFirst(); + } + else + { + pPageStart + = static_cast<const SwNoTextFrame*>(pPageStartFrame)->GetNode(); + } + } + + if (pPageEndFrame) { + if (pPageEndFrame->IsTextFrame()) + { + pPageEnd = static_cast<const SwTextFrame*>(pPageEndFrame) + ->GetTextNodeFirst(); + } + else + { + pPageEnd = static_cast<const SwNoTextFrame*>(pPageEndFrame)->GetNode(); + } + } + } + + if (!pPageStart || !pPageEnd) + { + pPageStart = pReference; + pPageEnd = pReference; + } + + std::deque<SwNode*> pAbovePage; + std::deque<SwNode*> pInPage; + std::deque<SwNode*> pBelowPage; + + bool beforeStart = true; + bool beforeEnd = true; + + for (SwNodeOffset n(0); n < nodes.Count(); n++) + { + if (beforeStart && *pPageStart == *nodes[n]) + { + beforeStart = false; + } + + if (beforeStart) + { + pAbovePage.push_front(nodes[n]); + } + else if (beforeEnd) + { + pInPage.push_back(nodes[n]); + + if (*pPageEnd == *nodes[n]) + { + beforeEnd = false; + } + } + else + { + pBelowPage.push_back(nodes[n]); + } + } + + pTextNd = SearchForStyleAnchor(pSelf, pInPage, rRefMark); + if (pTextNd) + { + break; + } + + // 2. Search up from the top of the page + pTextNd = SearchForStyleAnchor(pSelf, pAbovePage, rRefMark); + if (pTextNd) + { + break; + } + + // 3. Search down from the bottom of the page + pTextNd = SearchForStyleAnchor(pSelf, pBelowPage, rRefMark); + if (pTextNd) + { + break; + } + + // Word has case insensitive styles. LO has case sensitive styles. If we didn't find + // it yet, maybe we could with a case insensitive search. Let's do that + + pTextNd = SearchForStyleAnchor(pSelf, pInPage, rRefMark, + false /* bCaseSensitive */); + if (pTextNd) + { + break; + } + + pTextNd = SearchForStyleAnchor(pSelf, pAbovePage, rRefMark, + false /* bCaseSensitive */); + if (pTextNd) + { + break; + } + + pTextNd = SearchForStyleAnchor(pSelf, pBelowPage, rRefMark, + false /* bCaseSensitive */); + break; + } + case Reference: + case Default: + { + // Normally, styleref does searches around the field position + // For references, styleref acts from the position of the reference not the field + // Happily, the previous code saves either one into pReference, so the following is generic for both + + std::deque<SwNode*> pNotBelowElement; + std::deque<SwNode*> pBelowElement; + + bool beforeElement = true; + + for (SwNodeOffset n(0); n < nodes.Count(); n++) + { + if (beforeElement) + { + pNotBelowElement.push_front(nodes[n]); + + if (*pReference == *nodes[n]) + { + beforeElement = false; + } + } + else + { + pBelowElement.push_back(nodes[n]); + } + } + + // 1. Search up until we hit the top of the document + + pTextNd = SearchForStyleAnchor(pSelf, pNotBelowElement, rRefMark); + if (pTextNd) + { + break; + } + + // 2. Search down until we hit the bottom of the document + + pTextNd = SearchForStyleAnchor(pSelf, pBelowElement, rRefMark); + if (pTextNd) + { + break; + } + + // Again, we need to remember that Word styles are not case sensitive + + pTextNd = SearchForStyleAnchor(pSelf, pNotBelowElement, rRefMark, + false /* bCaseSensitive */); + if (pTextNd) + { + break; + } + + pTextNd = SearchForStyleAnchor(pSelf, pBelowElement, rRefMark, + false /* bCaseSensitive */); + break; + } + default: + OSL_FAIL("<SwGetRefFieldType::FindAnchor(..)> - unknown getref element type"); + } + + if (pTextNd) + { + *pStt = 0; + if (pEnd) + *pEnd = pTextNd->GetText().getLength(); + } + + break; } return pTextNd; diff --git a/sw/source/core/text/txtfld.cxx b/sw/source/core/text/txtfld.cxx index 5a4e7229334b..aa9cb97ffbad 100644 --- a/sw/source/core/text/txtfld.cxx +++ b/sw/source/core/text/txtfld.cxx @@ -244,7 +244,19 @@ SwExpandPortion *SwTextFormatter::NewFieldPortion( SwTextFormatInfo &rInf, bPlaceHolder = true; break; case SwFieldIds::GetRef: + { subType = static_cast<SwGetRefField*>(pField)->GetSubType(); + if (!bName && subType == REF_STYLE) + { + SwTextNode* pTextNode = pHint->GetFormatField().GetTextField()->GetpTextNode(); + + if (pTextNode) + static_cast<SwGetRefField*>(pField)->ChangeExpansion( + pFrame, static_txtattr_cast<SwTextField const*>(pHint)); + static_cast<SwGetRefField*>(pField)->UpdateField( + static_txtattr_cast<SwTextField const*>(pHint)); + } + { OUString const str( bName ? pField->GetFieldName() @@ -255,7 +267,8 @@ SwExpandPortion *SwTextFormatter::NewFieldPortion( SwTextFormatInfo &rInf, static_cast<SwFieldPortion*>(pRet)->m_nAttrFieldType = ATTR_BOOKMARKFLD; else if( subType == REF_SETREFATTR ) static_cast<SwFieldPortion*>(pRet)->m_nAttrFieldType = ATTR_SETREFATTRFLD; - break; + } + break; case SwFieldIds::DateTime: subType = static_cast<SwDateTimeField*>(pField)->GetSubType(); { diff --git a/sw/source/core/unocore/unofield.cxx b/sw/source/core/unocore/unofield.cxx index f1818c3c088f..76d8a74939f0 100644 --- a/sw/source/core/unocore/unofield.cxx +++ b/sw/source/core/unocore/unofield.cxx @@ -1529,6 +1529,8 @@ void SAL_CALL SwXTextField::attach( m_pImpl->m_pProps->sPar4, 0, 0, + 0, + 0, 0)); if (!m_pImpl->m_pProps->sPar3.isEmpty()) static_cast<SwGetRefField*>(xField.get())->SetExpand(m_pImpl->m_pProps->sPar3); diff --git a/sw/source/filter/ww8/wrtww8.hxx b/sw/source/filter/ww8/wrtww8.hxx index 7f20ed491bc2..c30f0a257286 100644 --- a/sw/source/filter/ww8/wrtww8.hxx +++ b/sw/source/filter/ww8/wrtww8.hxx @@ -642,6 +642,9 @@ public: /// Find the bookmark name. OUString GetBookmarkName( sal_uInt16 nTyp, const OUString* pName, sal_uInt16 nSeqNo ); + /// Find out which style we should use in OOXML + OUString GetStyleRefName(const OUString& rName); + /// Use OutputItem() on an item set according to the parameters. void OutputItemSet( const SfxItemSet& rSet, bool bPapFormat, bool bChpFormat, sal_uInt16 nScript, bool bExportParentItemSet ); diff --git a/sw/source/filter/ww8/ww8atr.cxx b/sw/source/filter/ww8/ww8atr.cxx index 9a561c05dac6..0258ae7f303f 100644 --- a/sw/source/filter/ww8/ww8atr.cxx +++ b/sw/source/filter/ww8/ww8atr.cxx @@ -128,6 +128,7 @@ #include <fmthdft.hxx> #include <authfld.hxx> #include <dbfld.hxx> +#include <docsh.hxx> #include "sprmids.hxx" @@ -1045,6 +1046,18 @@ OUString MSWordExportBase::GetBookmarkName( sal_uInt16 nTyp, const OUString* pNa return BookmarkToWord( sRet ); // #i43956# - encode bookmark accordingly } +OUString MSWordExportBase::GetStyleRefName(const OUString& rName) +{ + SwTextFormatColls* pTextFormatColls = m_rDoc.GetTextFormatColls(); + SwTextFormatColl* pTextFormat = pTextFormatColls->FindFormatByName(rName); + + if (pTextFormat == nullptr) + return "\"" + rName + "\""; + // Didn't find the style, just keep the original name + + return "\"" + m_pStyles->GetStyleWWName(pTextFormat) + "\""; +} + /* File CHRATR.HXX: */ void WW8AttributeOutput::RTLAndCJKState( bool bIsRTL, sal_uInt16 nScript ) { @@ -3293,26 +3306,45 @@ void AttributeOutputBase::TextField( const SwFormatField& rField ) sStr = FieldString(eField) + GetExport().GetBookmarkName(nSubType, nullptr, rRField.GetSeqNo()); break; + case REF_STYLE: + sStr = FieldString(ww::eSTYLEREF) + + GetExport().GetStyleRefName(pField->GetPar1()); + eField = ww::eSTYLEREF; + break; } - if (eField != ww::eNONE) + OUString sExtraFlags = "\\h "; // by default, include a hyperlink + + switch (eField) { - switch (pField->GetFormat()) - { - case REF_UPDOWN: - sStr += " \\p \\h "; // with hyperlink - break; - case REF_CHAPTER: - sStr += " \\n \\h "; // with hyperlink - break; - default: - sStr += " \\h "; // insert hyperlink - break; - } - GetExport().OutputField(pField, eField, sStr); + case ww::eNONE: + bWriteExpand = true; + break; + case ww::eSTYLEREF: + sExtraFlags = ""; // styleref fields do not work if they have a hyperlink + [[fallthrough]]; + default: + switch (pField->GetFormat()) + { + case REF_NUMBER: + sStr += " \\r " + sExtraFlags; + break; + case REF_NUMBER_FULL_CONTEXT: + sStr += " \\w " + sExtraFlags; + break; + case REF_UPDOWN: + sStr += " \\p " + sExtraFlags; + break; + case REF_NUMBER_NO_CONTEXT: + case REF_CHAPTER: + sStr += " \\n " + sExtraFlags; + break; + default: + sStr += " " + sExtraFlags; + break; + } + GetExport().OutputField(pField, eField, sStr); } - else - bWriteExpand = true; } break; case SwFieldIds::CombinedChars: @@ -3362,7 +3394,8 @@ void AttributeOutputBase::TextField( const SwFormatField& rField ) break; case SwFieldIds::Chapter: bWriteExpand = true; - if (GetExport().m_bOutKF && rField.GetTextField()) + + if (rField.GetTextField()) { const SwTextNode *pTextNd = GetExport().GetHdFtPageRoot(); if (!pTextNd) @@ -3374,10 +3407,22 @@ void AttributeOutputBase::TextField( const SwFormatField& rField ) { SwChapterField aCopy(*static_cast<const SwChapterField*>(pField)); aCopy.ChangeExpansion(*pTextNd, false); - const OUString sStr = FieldString(ww::eSTYLEREF) - + " " - + OUString::number(aCopy.GetLevel() + 1) - + " \\* MERGEFORMAT "; + + OUString sStr; + if (GetExport().m_bOutKF) { + // In headers and footers, use the chapter number as the style name + sStr = FieldString(ww::eSTYLEREF) + + " " + + OUString::number(aCopy.GetLevel() + 1) + + " \\* MERGEFORMAT "; + } else { + // Otherwise, get the style of the text and use it as the style name + const SwTextNode* pOutlineNd = pTextNd->FindOutlineNodeOfLevel(aCopy.GetLevel()); + + sStr = FieldString(ww::eSTYLEREF) + + GetExport().GetStyleRefName(pOutlineNd->GetFormatColl()->GetName()); + } + GetExport().OutputField(pField, ww::eSTYLEREF, sStr); bWriteExpand = false; } diff --git a/sw/source/filter/ww8/ww8par5.cxx b/sw/source/filter/ww8/ww8par5.cxx index 7e7cedd3f4b5..e6dcca3f2cae 100644 --- a/sw/source/filter/ww8/ww8par5.cxx +++ b/sw/source/filter/ww8/ww8par5.cxx @@ -953,8 +953,7 @@ tools::Long SwWW8ImplReader::Read_Field(WW8PLCFManResult* pRes) bool bHasHandler = aWW8FieldTab[aF.nId] != nullptr; if (aF.nId == 10) // STYLEREF { - // STYLEREF, by default these are not handled. - bHasHandler = false; + bool bHandledByChapter = false; sal_uInt64 nOldPos = m_pStrm->Tell(); OUString aStr; aF.nLCode = m_xSBase->WW8ReadString(*m_pStrm, aStr, m_xPlcxMan->GetCpOfs() + aF.nSCode, aF.nLCode, m_eTextCharSet); @@ -964,9 +963,9 @@ tools::Long SwWW8ImplReader::Read_Field(WW8PLCFManResult* pRes) sal_Int32 nRet = aReadParam.SkipToNextToken(); if (nRet == -2 && !aReadParam.GetResult().isEmpty()) // Single numeric argument: this can be handled by SwChapterField. - bHasHandler = rtl::isAsciiDigit(aReadParam.GetResult()[0]); + bHandledByChapter = rtl::isAsciiDigit(aReadParam.GetResult()[0]); - if (bHasHandler) + if (bHandledByChapter) { nRet = aReadParam.SkipToNextToken(); // Handle using SwChapterField only in case there is no \[a-z] @@ -2158,7 +2157,7 @@ eF_ResT SwWW8ImplReader::Read_F_Ref( WW8FieldDesc*, OUString& rStr ) SwGetRefField aField( static_cast<SwGetRefFieldType*>(m_rDoc.getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::GetRef )), - sBkmName,"",REF_BOOKMARK,0,eFormat); + sBkmName,"",REF_BOOKMARK,0,eFormat,nullptr,nullptr); if (eFormat == REF_CONTENT) { @@ -2214,14 +2213,14 @@ eF_ResT SwWW8ImplReader::Read_F_NoteReference( WW8FieldDesc*, OUString& rStr ) // (will be corrected in SwGetRefField aField( static_cast<SwGetRefFieldType*>( m_rDoc.getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::GetRef )), aBkmName, "", REF_FOOTNOTE, 0, - REF_ONLYNUMBER ); + REF_ONLYNUMBER, nullptr, nullptr ); m_xReffingStck->NewAttr(*m_pPaM->GetPoint(), SwFormatField(aField)); m_xReffingStck->SetAttr(*m_pPaM->GetPoint(), RES_TXTATR_FIELD); if (bAboveBelow) { SwGetRefField aField2( static_cast<SwGetRefFieldType*>( m_rDoc.getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::GetRef )),aBkmName, "", REF_FOOTNOTE, 0, - REF_UPDOWN ); + REF_UPDOWN, nullptr, nullptr ); m_xReffingStck->NewAttr(*m_pPaM->GetPoint(), SwFormatField(aField2)); m_xReffingStck->SetAttr(*m_pPaM->GetPoint(), RES_TXTATR_FIELD); } @@ -2293,7 +2292,7 @@ eF_ResT SwWW8ImplReader::Read_F_PgRef( WW8FieldDesc*, OUString& rStr ) sPageRefBookmarkName = sName; } SwGetRefField aField( static_cast<SwGetRefFieldType*>(m_rDoc.getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::GetRef )), - sPageRefBookmarkName, "", REF_BOOKMARK, 0, REF_PAGE ); + sPageRefBookmarkName, "", REF_BOOKMARK, 0, REF_PAGE, nullptr, nullptr ); m_rDoc.getIDocumentContentOperations().InsertPoolItem( *m_pPaM, SwFormatField( aField ) ); return eF_ResT::OK; diff --git a/sw/source/ui/fldui/fldref.cxx b/sw/source/ui/fldui/fldref.cxx index ea8e41414d4a..213143ef8bb6 100644 --- a/sw/source/ui/fldui/fldref.cxx +++ b/sw/source/ui/fldui/fldref.cxx @@ -47,6 +47,9 @@ // #i83479# #define REFFLDFLAG_HEADING 0x7100 #define REFFLDFLAG_NUMITEM 0x7200 +#define REFFLDFLAG_STYLE 0xc000 +/* we skip past 0x8000, 0x9000, 0xa000 and 0xb000 as when we bitwise 'and' + with REFFLDFLAG they are false */ static sal_uInt16 nFieldDlgFormatSel = 0; @@ -82,6 +85,7 @@ SwFieldRefPage::SwFieldRefPage(weld::Container* pPage, weld::DialogController* p // #i83479# m_sHeadingText = m_xTypeLB->get_text(3); m_sNumItemText = m_xTypeLB->get_text(4); + m_sStyleText = m_xTypeLB->get_text(5); auto nHeight = m_xTypeLB->get_height_rows(8); auto nWidth = m_xTypeLB->get_approximate_digit_width() * FIELD_COLUMN_WIDTH; @@ -239,6 +243,9 @@ void SwFieldRefPage::Reset(const SfxItemSet* ) m_xTypeLB->append(OUString::number(REFFLDFLAG_ENDNOTE), m_sEndnoteText); } + // stylerefs + m_xTypeLB->append(OUString::number(REFFLDFLAG_STYLE), m_sStyleText); + m_xTypeLB->thaw(); // select old Pos @@ -274,7 +281,7 @@ void SwFieldRefPage::Reset(const SfxItemSet* ) } } TypeHdl(*m_xTypeLB); - if (nFormatBoxPosition < m_xFormatLB->n_children()) + if (!IsFieldEdit() && nFormatBoxPosition < m_xFormatLB->n_children()) { m_xFormatLB->select(nFormatBoxPosition); } @@ -356,6 +363,17 @@ IMPL_LINK_NOARG(SwFieldRefPage, TypeHdl, weld::TreeView&, void) nFlag = REFFLDFLAG; break; } + + case REF_STYLE: + { + SwGetRefField const*const pRefField(dynamic_cast<SwGetRefField*>(GetCurField())); + if (pRefField) + { + sName = pRefField->GetPar1(); + } + nFlag = REFFLDFLAG_STYLE; + break; + } } if (m_xTypeLB->find_text(sName) == -1) // reference to deleted mark @@ -610,7 +628,7 @@ void SwFieldRefPage::UpdateSubType(const OUString& filterString) m_xSelectionToolTipLB->append(sId, pIDoc->getOutlineText(nOutlIdx, pSh->GetLayout(), true, true, false)); if ((IsFieldEdit() && pRefField - && pRefField->GetReferencedTextNode() == maOutlineNodes[nOutlIdx]) + && pRefField->GetReferencedTextNode(nullptr) == maOutlineNodes[nOutlIdx]) || mpSavedSelectedTextNode == maOutlineNodes[nOutlIdx]) { m_sSelectionToolTipLBId = sId; @@ -645,7 +663,7 @@ void SwFieldRefPage::UpdateSubType(const OUString& filterString) m_xSelectionToolTipLB->append(sId, pIDoc->getListItemText(*maNumItems[nNumItemIdx], *pSh->GetLayout())); if ((IsFieldEdit() && pRefField - && pRefField->GetReferencedTextNode() == maNumItems[nNumItemIdx]->GetTextNode()) + && pRefField->GetReferencedTextNode(nullptr) == maNumItems[nNumItemIdx]->GetTextNode()) || mpSavedSelectedTextNode == maNumItems[nNumItemIdx]->GetTextNode()) { m_sSelectionToolTipLBId = sId; @@ -660,6 +678,32 @@ void SwFieldRefPage::UpdateSubType(const OUString& filterString) } } } + else if (nTypeId == REFFLDFLAG_STYLE) + { + const IDocumentOutlineNodes* pIDoc(pSh->getIDocumentOutlineNodesAccess()); + pIDoc->getOutlineNodes(maOutlineNodes); + + SfxStyleSheetBasePool* pStyleSheetPool + = pSh->GetDoc()->GetDocShell()->GetStyleSheetPool(); + auto stylesheetIterator + = pStyleSheetPool->CreateIterator(SfxStyleFamily::Para, SfxStyleSearchBits::Used); + + SfxStyleSheetBase* pStyle = stylesheetIterator->First(); + while (pStyle != nullptr) + { + bool isSubstring = MatchSubstring(pStyle->GetName(), filterString); + + if (isSubstring) + { + m_xSelectionLB->append_text(pStyle->GetName()); + } + + pStyle = stylesheetIterator->Next(); + } + + if (IsFieldEdit() && pRefField) + sOldSel = pRefField->GetPar1(); + } else { // get the fields to Seq-FieldType: @@ -803,6 +847,7 @@ sal_Int32 SwFieldRefPage::FillFormatLB(sal_uInt16 nTypeId) // reference has less that the annotation sal_uInt16 nSize( 0 ); + sal_uInt16 nOffset( 0 ); bool bAddCrossRefFormats( false ); switch (nTypeId) { @@ -818,6 +863,11 @@ sal_Int32 SwFieldRefPage::FillFormatLB(sal_uInt16 nTypeId) case REFFLDFLAG_ENDNOTE: nSize = FMT_REF_PAGE_PGDSC_IDX + 1; break; + case REFFLDFLAG_STYLE: + nOffset = FMT_REF_TEXT_IDX; + nSize = FMT_REF_UPDOWN_IDX + 1 - nOffset; + bAddCrossRefFormats = true; + break; default: // #i83479# @@ -837,7 +887,7 @@ sal_Int32 SwFieldRefPage::FillFormatLB(sal_uInt16 nTypeId) nTypeId = static_cast<sal_uInt16>(SwFieldTypesEnum::GetRef); SwFieldTypesEnum nFieldType = static_cast<SwFieldTypesEnum>(nTypeId); - for (sal_uInt16 i = 0; i < nSize; i++) + for (sal_uInt16 i = nOffset; i < nSize + nOffset; i++) { OUString sId(OUString::number(GetFieldMgr().GetFormatId( nFieldType, i ))); m_xFormatLB->append(sId, GetFieldMgr().GetFormatStr(nFieldType, i)); @@ -1077,6 +1127,18 @@ bool SwFieldRefPage::FillItemSet(SfxItemSet* ) } } } + else if (nTypeId == REFFLDFLAG_STYLE) + { + int nEntry = m_xSelectionLB->get_selected_index(); + if (nEntry != -1) + { + aName = m_xSelectionLB->get_text(nEntry); + nTypeId = static_cast<sal_uInt16>(SwFieldTypesEnum::GetRef); + nSubType = REF_STYLE; + } else { + SAL_WARN("<SwFieldRefPage::FillItemSet(..)>", "no entry selected in selection listbox!"); + } + } else // SequenceFields { // get fields for Seq-FieldType: diff --git a/sw/source/ui/fldui/fldref.hxx b/sw/source/ui/fldui/fldref.hxx index 68dc6f6480be..872e6f526bb6 100644 --- a/sw/source/ui/fldui/fldref.hxx +++ b/sw/source/ui/fldui/fldref.hxx @@ -34,6 +34,7 @@ class SwFieldRefPage : public SwFieldPage // #i83479# OUString m_sHeadingText; OUString m_sNumItemText; + OUString m_sStyleText; IDocumentOutlineNodes::tSortedOutlineNodeList maOutlineNodes; IDocumentListItems::tSortedNodeNumList maNumItems; diff --git a/sw/source/uibase/docvw/edtwin2.cxx b/sw/source/uibase/docvw/edtwin2.cxx index 04a51cfbc7b2..627bd054d586 100644 --- a/sw/source/uibase/docvw/edtwin2.cxx +++ b/sw/source/uibase/docvw/edtwin2.cxx @@ -357,7 +357,7 @@ void SwEditWin::RequestHelp(const HelpEvent &rEvt) if ( pRefField->IsRefToHeadingCrossRefBookmark() || pRefField->IsRefToNumItemCrossRefBookmark() ) { - sText = pRefField->GetExpandedTextOfReferencedTextNode(*rSh.GetLayout()); + sText = pRefField->GetExpandedTextOfReferencedTextNode(*rSh.GetLayout(), nullptr); if ( sText.getLength() > 80 ) { sText = OUString::Concat(sText.subView(0, 80)) + "..."; diff --git a/sw/source/uibase/fldui/fldmgr.cxx b/sw/source/uibase/fldui/fldmgr.cxx index 37c58ae0ee84..cd9f99aa2ad7 100644 --- a/sw/source/uibase/fldui/fldmgr.cxx +++ b/sw/source/uibase/fldui/fldmgr.cxx @@ -66,6 +66,8 @@ #include <authfld.hxx> #include <flddat.hxx> #include <fldmgr.hxx> +#include <ndtxt.hxx> +#include <cntfrm.hxx> #include <flddropdown.hxx> #include <strings.hrc> #include <tox.hxx> @@ -1129,7 +1131,19 @@ bool SwFieldMgr::InsertField( } nFormatId %= SAL_N_ELEMENTS(FMT_REF_ARY); } - pField.reset(new SwGetRefField(pTyp, rData.m_sPar1, sReferenceLanguage, nSubType, nSeqNo, nFormatId)); + + SwPaM* pCursor = nullptr; + SwPosition* pPos = nullptr; + SwTextNode* pTextNode = nullptr; + SwContentFrame* pFrame = nullptr; + if (nSubType == REF_STYLE) { + pCursor = pCurShell->GetCursor(); + pPos = pCursor->GetPoint(); + pTextNode = pPos->GetNode().GetTextNode(); + pFrame = pCurShell->GetCurrFrame(); + } + + pField.reset(new SwGetRefField(pTyp, rData.m_sPar1, sReferenceLanguage, nSubType, nSeqNo, nFormatId, pTextNode, pFrame)); bExp = true; break; } diff --git a/sw/source/uibase/utlui/content.cxx b/sw/source/uibase/utlui/content.cxx index 03d46e4a8cc2..504d17e79ea4 100644 --- a/sw/source/uibase/utlui/content.cxx +++ b/sw/source/uibase/utlui/content.cxx @@ -704,7 +704,7 @@ void SwContentType::FillMemberList(bool* pbContentChanged) { OUString sExpandedTextOfReferencedTextNode = pRefField->GetExpandedTextOfReferencedTextNode( - *m_pWrtShell->GetLayout()); + *m_pWrtShell->GetLayout(), nullptr); if (sExpandedTextOfReferencedTextNode.getLength() > 80) { sExpandedTextOfReferencedTextNode = OUString::Concat( |