sw/qa/extras/ooxmlexport/data/tdf159897.docx         |binary
 sw/qa/extras/ooxmlexport/ooxmlexport21.cxx           |   11 +++++++++++
 sw/source/filter/ww8/attributeoutputbase.hxx         |    2 +-
 sw/source/filter/ww8/docxattributeoutput.cxx         |    6 +++++-
 sw/source/filter/ww8/docxattributeoutput.hxx         |    2 +-
 sw/source/filter/ww8/rtfattributeoutput.cxx          |    3 ++-
 sw/source/filter/ww8/rtfattributeoutput.hxx          |    3 ++-
 sw/source/filter/ww8/wrtw8nds.cxx                    |    4 ++--
 sw/source/filter/ww8/ww8attributeoutput.hxx          |    2 +-
 sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx |   16 +++++++++++++++-
 sw/source/writerfilter/dmapper/DomainMapper_Impl.hxx |    3 +++
 11 files changed, 43 insertions(+), 9 deletions(-)

New commits:
commit 6c583b38bc96b397f1a742127ea7ac99cadd024f
Author:     Tibor Nagy <tibor.nagy.ext...@allotropia.de>
AuthorDate: Mon May 27 14:56:37 2024 +0200
Commit:     Nagy Tibor <tibor.nagy.ext...@allotropia.de>
CommitDate: Sat Jun 1 13:50:26 2024 +0200

    tdf#159897 docx import: fix ScreenTip of hyperlink
    
    Note: if the ScreenTip contains double quote marks, the link will be
    broken after the import
    
    Change-Id: I4ed3e4e9e87335407e01d50cc5c440d04598a33f
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168105
    Tested-by: Jenkins
    Reviewed-by: Nagy Tibor <tibor.nagy.ext...@allotropia.de>

diff --git a/sw/qa/extras/ooxmlexport/data/tdf159897.docx 
b/sw/qa/extras/ooxmlexport/data/tdf159897.docx
new file mode 100644
index 000000000000..7b3d5c228105
Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/tdf159897.docx differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx
index e487bbf00015..3e1ebb45e24b 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx
@@ -572,6 +572,17 @@ DECLARE_OOXMLEXPORT_TEST(testTdf154369, "tdf154369.docx")
                 "color"_ostr, "00527d55");
 }
 
+CPPUNIT_TEST_FIXTURE(Test, testScreenTip)
+{
+    loadAndSave("tdf159897.docx");
+
+    xmlDocUniquePtr pXmlDocument = parseExport("word/document.xml");
+
+    // Hyperlink with ScreenTip
+    assertXPath(pXmlDocument, "/w:document/w:body/w:p/w:hyperlink"_ostr, 
"tooltip"_ostr,
+                "This is a hyperlink");
+}
+
 CPPUNIT_TEST_FIXTURE(Test, testEmptyObjectRange)
 {
     // Before the fix, this failed an assertion like this:
diff --git a/sw/source/filter/ww8/attributeoutputbase.hxx 
b/sw/source/filter/ww8/attributeoutputbase.hxx
index 4ce7f495cc3b..a6845c56b633 100644
--- a/sw/source/filter/ww8/attributeoutputbase.hxx
+++ b/sw/source/filter/ww8/attributeoutputbase.hxx
@@ -203,7 +203,7 @@ public:
     virtual void EndRuby( const SwTextNode& rNode, sal_Int32 nPos ) = 0;
 
     /// Output URL start.
-    virtual bool StartURL( const OUString& rUrl, const OUString& rTarget ) = 0;
+    virtual bool StartURL(const OUString& rUrl, const OUString& rTarget, const 
OUString& rName = OUString()) = 0;
 
     /// Output URL end.
     virtual bool EndURL(bool isAtEndOfParagraph) = 0;
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx 
b/sw/source/filter/ww8/docxattributeoutput.cxx
index 827d037b274c..97a4c038c736 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -3911,7 +3911,7 @@ void DocxAttributeOutput::WriteBookmarkInActParagraph( 
const OUString& rName, sa
     m_aBookmarksOfParagraphEnd.insert(std::pair<sal_Int32, 
OUString>(nLastRunPos, rName));
 }
 
-bool DocxAttributeOutput::StartURL( const OUString& rUrl, const OUString& 
rTarget )
+bool DocxAttributeOutput::StartURL(const OUString& rUrl, const OUString& 
rTarget, const OUString& rName)
 {
     OUString sMark;
     OUString sUrl;
@@ -3983,6 +3983,10 @@ bool DocxAttributeOutput::StartURL( const OUString& 
rUrl, const OUString& rTarge
         {
             m_pHyperlinkAttrList->add(FSNS(XML_w, XML_tgtFrame), rTarget);
         }
+        else if (!rName.isEmpty())
+        {
+            m_pHyperlinkAttrList->add(FSNS(XML_w, XML_tooltip), rName);
+        }
     }
 
     return true;
diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx 
b/sw/source/filter/ww8/docxattributeoutput.hxx
index 063cb02bbc69..d9cddce059c7 100644
--- a/sw/source/filter/ww8/docxattributeoutput.hxx
+++ b/sw/source/filter/ww8/docxattributeoutput.hxx
@@ -253,7 +253,7 @@ public:
     virtual void EndRuby(const SwTextNode& rNode, sal_Int32 nPos) override;
 
     /// Output URL start.
-    virtual bool StartURL( const OUString& rUrl, const OUString& rTarget ) 
override;
+    virtual bool StartURL( const OUString& rUrl, const OUString& rTarget, 
const OUString& rName = OUString() ) override;
 
     /// Output URL end.
     virtual bool EndURL(bool) override;
diff --git a/sw/source/filter/ww8/rtfattributeoutput.cxx 
b/sw/source/filter/ww8/rtfattributeoutput.cxx
index 5b0e89de1e73..2c9f92aaa245 100644
--- a/sw/source/filter/ww8/rtfattributeoutput.cxx
+++ b/sw/source/filter/ww8/rtfattributeoutput.cxx
@@ -547,7 +547,8 @@ void RtfAttributeOutput::StartRuby(const SwTextNode& rNode, 
sal_Int32 /*nPos*/,
 
 void RtfAttributeOutput::EndRuby(const SwTextNode& /*rNode*/, sal_Int32 
/*nPos*/) {}
 
-bool RtfAttributeOutput::StartURL(const OUString& rUrl, const OUString& 
rTarget)
+bool RtfAttributeOutput::StartURL(const OUString& rUrl, const OUString& 
rTarget,
+                                  const OUString& /*rName*/)
 {
     m_aURLs.push(rUrl);
     // Ignore hyperlink without a URL.
diff --git a/sw/source/filter/ww8/rtfattributeoutput.hxx 
b/sw/source/filter/ww8/rtfattributeoutput.hxx
index 50ca3c0899b2..4309e1f213f3 100644
--- a/sw/source/filter/ww8/rtfattributeoutput.hxx
+++ b/sw/source/filter/ww8/rtfattributeoutput.hxx
@@ -102,7 +102,8 @@ public:
     void EndRuby(const SwTextNode& rNode, sal_Int32 nPos) override;
 
     /// Output URL start.
-    bool StartURL(const OUString& rUrl, const OUString& rTarget) override;
+    bool StartURL(const OUString& rUrl, const OUString& rTarget,
+                  const OUString& rName = OUString()) override;
 
     /// Output URL end.
     bool EndURL(bool isAtEndOfParagraph) override;
diff --git a/sw/source/filter/ww8/wrtw8nds.cxx 
b/sw/source/filter/ww8/wrtw8nds.cxx
index ee561dc129b6..a42fc133ebb3 100644
--- a/sw/source/filter/ww8/wrtw8nds.cxx
+++ b/sw/source/filter/ww8/wrtw8nds.cxx
@@ -1146,7 +1146,7 @@ void WW8AttributeOutput::WriteBookmarkInActParagraph( 
const OUString& rName, sal
     m_aBookmarksOfParagraphEnd.insert(std::pair<sal_Int32, 
OUString>(nLastRunPos, rName));
 }
 
-bool WW8AttributeOutput::StartURL( const OUString &rUrl, const OUString 
&rTarget )
+bool WW8AttributeOutput::StartURL(const OUString& rUrl, const OUString& 
rTarget, const OUString& /*rName*/)
 {
     INetURLObject aURL( rUrl );
     OUString sURL;
@@ -1489,7 +1489,7 @@ int SwWW8AttrIter::OutAttrWithRange(const SwTextNode& 
rNode, sal_Int32 nPos)
                     if ( nPos == pHt->GetStart() )
                     {
                         const SwFormatINetFormat *rINet = static_cast< const 
SwFormatINetFormat* >( pItem );
-                        if ( m_rExport.AttrOutput().StartURL( 
rINet->GetValue(), rINet->GetTargetFrame() ) )
+                        if (m_rExport.AttrOutput().StartURL(rINet->GetValue(), 
rINet->GetTargetFrame(), rINet->GetName()))
                             ++nRet;
                     }
                     pEnd = pHt->End();
diff --git a/sw/source/filter/ww8/ww8attributeoutput.hxx 
b/sw/source/filter/ww8/ww8attributeoutput.hxx
index 7a0d13a2bc62..a103cc4c11ce 100644
--- a/sw/source/filter/ww8/ww8attributeoutput.hxx
+++ b/sw/source/filter/ww8/ww8attributeoutput.hxx
@@ -79,7 +79,7 @@ public:
     virtual void EndRuby(const SwTextNode& rNode, sal_Int32 nPos) override;
 
     /// Output URL start.
-    virtual bool StartURL( const OUString &rUrl, const OUString &rTarget ) 
override;
+    virtual bool StartURL(const OUString& rUrl, const OUString& rTarget, const 
OUString& rName = OUString()) override;
 
     /// Output URL end.
     virtual bool EndURL(bool) override;
diff --git a/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx 
b/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx
index 32d26b03d5bb..25f9e0630083 100644
--- a/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx
+++ b/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx
@@ -7842,6 +7842,7 @@ void DomainMapper_Impl::CloseFieldCommand()
 
                     OUString sURL;
                     OUString sTarget;
+                    OUString sName;
 
                     while (aPartIt != aItEnd)
                     {
@@ -7857,7 +7858,7 @@ void DomainMapper_Impl::CloseFieldCommand()
                         else if (*aPartIt == "\m" || *aPartIt == "\n" || 
*aPartIt == "\h")
                         {
                         }
-                        else if ( *aPartIt == "\o" || *aPartIt == "\t" )
+                        else if (*aPartIt == "\t")
                         {
                             ++aPartIt;
 
@@ -7866,6 +7867,15 @@ void DomainMapper_Impl::CloseFieldCommand()
 
                             sTarget = *aPartIt;
                         }
+                        else if (*aPartIt == "\o")
+                        {
+                            ++aPartIt;
+
+                            if (aPartIt == aItEnd)
+                                break;
+
+                            sName = *aPartIt;
+                        }
                         else
                         {
                             sURL = *aPartIt;
@@ -7905,6 +7915,8 @@ void DomainMapper_Impl::CloseFieldCommand()
 
                     if (!sTarget.isEmpty())
                         pContext->SetHyperlinkTarget(sTarget);
+                    else if (!sName.isEmpty())
+                        pContext->SetHyperlinkName(sName);
                 }
                 break;
                 case FIELD_IF:
@@ -8798,6 +8810,8 @@ void DomainMapper_Impl::PopFieldContext()
 
                                 if (!pContext->GetHyperlinkTarget().isEmpty())
                                     
xCrsrProperties->setPropertyValue(u"HyperLinkTarget"_ustr, 
uno::Any(pContext->GetHyperlinkTarget()));
+                                else if 
(!pContext->GetHyperlinkName().isEmpty())
+                                    
xCrsrProperties->setPropertyValue(u"HyperLinkName"_ustr, 
uno::Any(pContext->GetHyperlinkName()));
 
                                 if (IsInTOC())
                                 {
diff --git a/sw/source/writerfilter/dmapper/DomainMapper_Impl.hxx 
b/sw/source/writerfilter/dmapper/DomainMapper_Impl.hxx
index 7962facc5252..f60411128bcf 100644
--- a/sw/source/writerfilter/dmapper/DomainMapper_Impl.hxx
+++ b/sw/source/writerfilter/dmapper/DomainMapper_Impl.hxx
@@ -307,6 +307,7 @@ private:
     OUString m_sHyperlinkURL;
     /// A frame for the hyperlink when one exists.
     OUString m_sHyperlinkTarget;
+    OUString m_sHyperlinkName;
     OUString m_sHyperlinkStyle;
 
     FFDataHandler::Pointer_t m_pFFDataHandler;
@@ -359,6 +360,8 @@ public:
     const OUString& GetHyperlinkURL() const { return m_sHyperlinkURL; }
     void SetHyperlinkTarget(const OUString& rTarget) { m_sHyperlinkTarget = 
rTarget; }
     const OUString& GetHyperlinkTarget() const { return m_sHyperlinkTarget; }
+    void SetHyperlinkName(const OUString& rName) { m_sHyperlinkName = rName; }
+    const OUString& GetHyperlinkName() const { return m_sHyperlinkName; }
     void  SetHyperlinkStyle(const OUString& rStyle) { m_sHyperlinkStyle = 
rStyle; }
     const OUString& GetHyperlinkStyle() const { return m_sHyperlinkStyle; }
 

Reply via email to