sw/qa/extras/ooxmlexport/ooxmlexport17.cxx         |    4 -
 sw/source/core/fields/reffld.cxx                   |   66 +++++++++++++--------
 sw/source/writerfilter/dmapper/StyleSheetTable.cxx |   14 ++++
 3 files changed, 58 insertions(+), 26 deletions(-)

New commits:
commit d4fdafa103bfea94a279d7069ddc50ba92f67d01
Author:     Michael Stahl <michael.st...@allotropia.de>
AuthorDate: Fri May 3 19:31:20 2024 +0200
Commit:     Michael Stahl <michael.st...@allotropia.de>
CommitDate: Mon May 6 18:49:58 2024 +0200

    tdf#160402 writerfilter,sw: STYLEREF field can refer to character style
    
    Adapt SwGetRefFieldType::FindAnchor() to search for SwTextCharFormat,
    and ApplyClonedTOCStylesToXText() to replace "CharStyleName".
    
    Works for the "Intensive Hervorhebung" field in bugdoc.
    
    Change-Id: Iee126eeb4cc2ff1c570941e3beefd93527c56fee
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167098
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>
    Tested-by: Jenkins

diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx
index e84bb352f639..74f83e105c67 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx
@@ -746,9 +746,9 @@ DECLARE_OOXMLEXPORT_TEST(testTdf160402, "StyleRef-DE.docx")
     xmlDocUniquePtr pLayout = parseLayoutDump();
     assertXPath(pLayout, 
"/root/page[1]/header/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion"_ostr, 
"expand"_ostr, "Heading 1");
     assertXPath(pLayout, 
"/root/page[2]/header/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion"_ostr, 
"expand"_ostr, "Nunc viverra imperdiet enim. Fusce est. Vivamus a tellus.");
-    assertXPath(pLayout, 
"/root/page[3]/header/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion"_ostr, 
"expand"_ostr, "Error: Reference source not found"); // TODO
+    assertXPath(pLayout, 
"/root/page[3]/header/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion"_ostr, 
"expand"_ostr, "Cras faucibus condimentum odio. Sed ac ligula. Aliquam at 
eros.");
     assertXPath(pLayout, 
"/root/page[4]/header/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion"_ostr, 
"expand"_ostr, "Nunc viverra imperdiet enim. Fusce est. Vivamus a tellus.");
-    assertXPath(pLayout, 
"/root/page[5]/header/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion"_ostr, 
"expand"_ostr, "Error: Reference source not found"); // TODO
+    assertXPath(pLayout, 
"/root/page[5]/header/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion"_ostr, 
"expand"_ostr, "Aenean nec lorem. In porttitor. Donec laoreet nonummy augue.");
 }
 
 DECLARE_OOXMLEXPORT_TEST(testTdf142407, "tdf142407.docx")
diff --git a/sw/source/core/fields/reffld.cxx b/sw/source/core/fields/reffld.cxx
index 3d592f5c9403..4c03b26960a9 100644
--- a/sw/source/core/fields/reffld.cxx
+++ b/sw/source/core/fields/reffld.cxx
@@ -1219,7 +1219,9 @@ 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, const 
std::deque<SwNode*>& pToSearch,
-                                    std::u16string_view rStyleName, bool 
bCaseSensitive = true)
+                                    std::u16string_view rStyleName,
+                                    sal_Int32 *const pStart, sal_Int32 *const 
pEnd,
+                                    bool bCaseSensitive = true)
     {
         std::deque<SwNode*> pSearching(pToSearch);
         while (!pSearching.empty())
@@ -1234,15 +1236,38 @@ namespace
             if (!pTextNode)
                 continue;
 
-            if (bCaseSensitive)
+            if (bCaseSensitive
+                ? pTextNode->GetFormatColl()->GetName() == rStyleName
+                : 
pTextNode->GetFormatColl()->GetName().equalsIgnoreAsciiCase(rStyleName))
             {
-                if (pTextNode->GetFormatColl()->GetName() == rStyleName)
-                    return pTextNode;
+                *pStart = 0;
+                if (pEnd)
+                {
+                    *pEnd = pTextNode->GetText().getLength();
+                }
+                return pTextNode;
             }
-            else
+
+            if (auto const pHints = pTextNode->GetpSwpHints())
             {
-                if 
(pTextNode->GetFormatColl()->GetName().equalsIgnoreAsciiCase(rStyleName))
-                    return pTextNode;
+                for (size_t i = 0; i < pHints->Count(); ++i)
+                {
+                    auto const*const pHint(pHints->Get(i));
+                    if (pHint->Which() == RES_TXTATR_CHARFMT)
+                    {
+                        if (bCaseSensitive
+                            ? 
pHint->GetCharFormat().GetCharFormat()->HasName(rStyleName)
+                            : 
pHint->GetCharFormat().GetCharFormat()->GetName().equalsIgnoreAsciiCase(rStyleName))
+                        {
+                            *pStart = pHint->GetStart();
+                            if (pEnd)
+                            {
+                                *pEnd = *pHint->End();
+                            }
+                            return pTextNode;
+                        }
+                    }
+                }
             }
         }
 
@@ -1503,21 +1528,21 @@ SwTextNode* SwGetRefFieldType::FindAnchor(SwDoc* pDoc, 
const OUString& rRefMark,
                             pSearchThird.push_back(nodes[n]);
                     }
 
-                    pTextNd = SearchForStyleAnchor(pSelf, pInPage, rRefMark);
+                    pTextNd = SearchForStyleAnchor(pSelf, pInPage, rRefMark, 
pStt, pEnd);
                     if (pTextNd)
                     {
                         break;
                     }
 
                     // 2. Search up from the top of the page
-                    pTextNd = SearchForStyleAnchor(pSelf, pSearchSecond, 
rRefMark);
+                    pTextNd = SearchForStyleAnchor(pSelf, pSearchSecond, 
rRefMark, pStt, pEnd);
                     if (pTextNd)
                     {
                         break;
                     }
 
                     // 3. Search down from the bottom of the page
-                    pTextNd = SearchForStyleAnchor(pSelf, pSearchThird, 
rRefMark);
+                    pTextNd = SearchForStyleAnchor(pSelf, pSearchThird, 
rRefMark, pStt, pEnd);
                     if (pTextNd)
                     {
                         break;
@@ -1526,21 +1551,21 @@ SwTextNode* SwGetRefFieldType::FindAnchor(SwDoc* pDoc, 
const OUString& rRefMark,
                     // 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,
+                    pTextNd = SearchForStyleAnchor(pSelf, pInPage, rRefMark, 
pStt, pEnd,
                                                    false /* bCaseSensitive */);
                     if (pTextNd)
                     {
                         break;
                     }
 
-                    pTextNd = SearchForStyleAnchor(pSelf, pSearchSecond, 
rRefMark,
+                    pTextNd = SearchForStyleAnchor(pSelf, pSearchSecond, 
rRefMark, pStt, pEnd,
                                                    false /* bCaseSensitive */);
                     if (pTextNd)
                     {
                         break;
                     }
 
-                    pTextNd = SearchForStyleAnchor(pSelf, pSearchThird, 
rRefMark,
+                    pTextNd = SearchForStyleAnchor(pSelf, pSearchThird, 
rRefMark, pStt, pEnd,
                                                    false /* bCaseSensitive */);
                     break;
                 }
@@ -1572,7 +1597,7 @@ SwTextNode* SwGetRefFieldType::FindAnchor(SwDoc* pDoc, 
const OUString& rRefMark,
 
                     // 1. Search up until we hit the top of the document
 
-                    pTextNd = SearchForStyleAnchor(pSelf, pSearchFirst, 
rRefMark);
+                    pTextNd = SearchForStyleAnchor(pSelf, pSearchFirst, 
rRefMark, pStt, pEnd);
                     if (pTextNd)
                     {
                         break;
@@ -1580,7 +1605,7 @@ SwTextNode* SwGetRefFieldType::FindAnchor(SwDoc* pDoc, 
const OUString& rRefMark,
 
                     // 2. Search down until we hit the bottom of the document
 
-                    pTextNd = SearchForStyleAnchor(pSelf, pSearchSecond, 
rRefMark);
+                    pTextNd = SearchForStyleAnchor(pSelf, pSearchSecond, 
rRefMark, pStt, pEnd);
                     if (pTextNd)
                     {
                         break;
@@ -1588,14 +1613,14 @@ SwTextNode* SwGetRefFieldType::FindAnchor(SwDoc* pDoc, 
const OUString& rRefMark,
 
                     // Again, we need to remember that Word styles are not 
case sensitive
 
-                    pTextNd = SearchForStyleAnchor(pSelf, pSearchFirst, 
rRefMark,
+                    pTextNd = SearchForStyleAnchor(pSelf, pSearchFirst, 
rRefMark, pStt, pEnd,
                                                    false /* bCaseSensitive */);
                     if (pTextNd)
                     {
                         break;
                     }
 
-                    pTextNd = SearchForStyleAnchor(pSelf, pSearchSecond, 
rRefMark,
+                    pTextNd = SearchForStyleAnchor(pSelf, pSearchSecond, 
rRefMark, pStt, pEnd,
                                                    false /* bCaseSensitive */);
                     break;
                 }
@@ -1603,13 +1628,6 @@ SwTextNode* SwGetRefFieldType::FindAnchor(SwDoc* pDoc, 
const OUString& rRefMark,
                     OSL_FAIL("<SwGetRefFieldType::FindAnchor(..)> - unknown 
getref element type");
             }
 
-            if (pTextNd)
-            {
-                *pStt = 0;
-                if (pEnd)
-                    *pEnd = pTextNd->GetText().getLength();
-            }
-
             break;
     }
 
diff --git a/sw/source/writerfilter/dmapper/StyleSheetTable.cxx 
b/sw/source/writerfilter/dmapper/StyleSheetTable.cxx
index 2d8ff27fd206..eac2585bb6ca 100644
--- a/sw/source/writerfilter/dmapper/StyleSheetTable.cxx
+++ b/sw/source/writerfilter/dmapper/StyleSheetTable.cxx
@@ -1030,6 +1030,20 @@ void 
StyleSheetTable_Impl::ApplyClonedTOCStylesToXText(uno::Reference<text::XTex
                     xPara->setPropertyValue(u"ParaStyleName"_ustr, 
uno::Any(it->second));
                 }
             }
+            uno::Reference<container::XEnumerationAccess> const xParaEA{xPara, 
uno::UNO_QUERY_THROW};
+            uno::Reference<container::XEnumeration> const 
xEnum{xParaEA->createEnumeration()};
+            while (xEnum->hasMoreElements())
+            {
+                uno::Reference<beans::XPropertySet> const 
xPortion{xEnum->nextElement(), uno::UNO_QUERY_THROW};
+                if (xPortion->getPropertyValue(u"CharStyleName"_ustr) >>= 
styleName)
+                {
+                    auto const it{m_ClonedTOCStylesMap.find(styleName)};
+                    if (it != m_ClonedTOCStylesMap.end())
+                    {
+                        xPortion->setPropertyValue(u"CharStyleName"_ustr, 
uno::Any(it->second));
+                    }
+                }
+            }
         }
         else if (xElem->supportsService(u"com.sun.star.text.TextTable"_ustr))
         {

Reply via email to