include/oox/export/chartexport.hxx        |    3 ++
 include/oox/export/drawingml.hxx          |   10 ++++++++
 include/oox/export/shapes.hxx             |   10 --------
 oox/source/export/chartexport.cxx         |   26 +++++++++++++++++++++-
 oox/source/export/drawingml.cxx           |   14 ++++++++++++
 oox/source/export/shapes.cxx              |   24 ++++----------------
 sc/qa/unit/data/xlsx/chart_hyperlink.xlsx |binary
 sc/qa/unit/subsequent_export-test.cxx     |   24 ++++++++++++++++++++
 sc/source/filter/excel/xeescher.cxx       |    7 ++++--
 sc/source/filter/inc/xcl97rec.hxx         |   14 ++++++++++++
 sc/source/filter/inc/xeescher.hxx         |    4 ++-
 sc/source/filter/xcl97/xcl97esc.cxx       |    2 -
 sc/source/filter/xcl97/xcl97rec.cxx       |   35 ++++++++++++------------------
 13 files changed, 118 insertions(+), 55 deletions(-)

New commits:
commit dc091e7fd952b0530db8583247c2f910d627700a
Author:     tundet <tund...@gmail.com>
AuthorDate: Fri Apr 12 10:21:42 2019 +0200
Commit:     László Németh <nem...@numbertext.org>
CommitDate: Wed Apr 17 10:17:47 2019 +0200

    tdf#123645 XLSX export: fix hyperlink inserted to chart
    
    Hyperlink inserted to chart lost after export.
    
    chart_hyperlink.xlsx: Test file from Excel 2016.
    
    Change-Id: Ideca10e544193ba43d7c2ef6e9dd8e393383edc1
    Reviewed-on: https://gerrit.libreoffice.org/70648
    Tested-by: Jenkins
    Reviewed-by: László Németh <nem...@numbertext.org>

diff --git a/include/oox/export/chartexport.hxx 
b/include/oox/export/chartexport.hxx
index c5f9e6ebd188..b39b3f52b455 100644
--- a/include/oox/export/chartexport.hxx
+++ b/include/oox/export/chartexport.hxx
@@ -101,6 +101,7 @@ private:
     css::uno::Reference< css::frame::XModel > mxChartModel;
     css::uno::Reference< css::chart::XDiagram > mxDiagram;
     css::uno::Reference< css::chart2::XDiagram > mxNewDiagram;
+    std::shared_ptr<URLTransformer> mpURLTransformer;
 
     // members filled by InitRangeSegmentationProperties (retrieved from 
DataProvider)
     bool mbHasCategoryLabels; //if the categories are only automatically 
generated this will be false
@@ -214,6 +215,8 @@ public:
                  ::oox::core::XmlFilterBase* pFB, DocumentType eDocumentType );
     virtual ~ChartExport() {}
 
+    void SetURLTranslator(const std::shared_ptr<URLTransformer>& pTransformer);
+
     const css::uno::Reference< css::frame::XModel >& getModel(){ return 
mxChartModel; }
 
     void WriteChartObj( const css::uno::Reference< css::drawing::XShape >& 
xShape, sal_Int32 nID, sal_Int32 nChartCount );
diff --git a/include/oox/export/drawingml.hxx b/include/oox/export/drawingml.hxx
index b3cdbb3600ba..8ed1aaf0d702 100644
--- a/include/oox/export/drawingml.hxx
+++ b/include/oox/export/drawingml.hxx
@@ -96,6 +96,16 @@ namespace core {
 
 namespace drawingml {
 
+class OOX_DLLPUBLIC URLTransformer
+{
+public:
+    virtual ~URLTransformer();
+
+    virtual OUString getTransformedString(const OUString& rURL) const;
+
+    virtual bool isExternalURL(const OUString& rURL) const;
+};
+
 // Our rotation is counter-clockwise and is in 100ths of a degree.
 // drawingML rotation is clockwise and is in 60000ths of a degree.
 template <typename T> T ExportRotateClockwisify(T input)
diff --git a/include/oox/export/shapes.hxx b/include/oox/export/shapes.hxx
index aa0ca2cd1a62..b7755ccee9d2 100644
--- a/include/oox/export/shapes.hxx
+++ b/include/oox/export/shapes.hxx
@@ -78,16 +78,6 @@ OOX_DLLPUBLIC css::uno::Reference<css::io::XInputStream> 
GetOLEObjectStream(
 
 namespace oox { namespace drawingml {
 
-class OOX_DLLPUBLIC URLTransformer
-{
-public:
-    virtual ~URLTransformer();
-
-    virtual OUString getTransformedString(const OUString& rURL) const;
-
-    virtual bool isExternalURL(const OUString& rURL) const;
-};
-
 class OOX_DLLPUBLIC ShapeExport : public DrawingML {
 
 private:
diff --git a/oox/source/export/chartexport.cxx 
b/oox/source/export/chartexport.cxx
index 15e9bca1c1c9..672ae2579d99 100644
--- a/oox/source/export/chartexport.cxx
+++ b/oox/source/export/chartexport.cxx
@@ -376,6 +376,7 @@ ChartExport::ChartExport( sal_Int32 nXmlNamespace, 
FSHelperPtr pFS, Reference< f
     , mnXmlNamespace( nXmlNamespace )
     , mnSeriesCount(0)
     , mxChartModel( xModel )
+    , mpURLTransformer(new URLTransformer)
     , mbHasCategoryLabels( false )
     , mbHasZAxis( false )
     , mbIs3DChart( false )
@@ -384,6 +385,11 @@ ChartExport::ChartExport( sal_Int32 nXmlNamespace, 
FSHelperPtr pFS, Reference< f
 {
 }
 
+void ChartExport::SetURLTranslator(const std::shared_ptr<URLTransformer>& 
pTransformer)
+{
+    mpURLTransformer = pTransformer;
+}
+
 sal_Int32 ChartExport::getChartType( )
 {
     OUString sChartType = mxDiagram->getDiagramType();
@@ -445,6 +451,8 @@ void ChartExport::WriteChartObj( const Reference< XShape >& 
xShape, sal_Int32 nI
 {
     FSHelperPtr pFS = GetFS();
 
+    Reference< XPropertySet > xShapeProps( xShape, UNO_QUERY );
+
     pFS->startElementNS( mnXmlNamespace, XML_graphicFrame, FSEND );
 
     pFS->startElementNS( mnXmlNamespace, XML_nvGraphicFramePr, FSEND );
@@ -455,11 +463,27 @@ void ChartExport::WriteChartObj( const Reference< XShape 
>& xShape, sal_Int32 nI
     if (xNamed.is())
         sName = xNamed->getName();
 
-    pFS->singleElementNS( mnXmlNamespace, XML_cNvPr,
+    pFS->startElementNS( mnXmlNamespace, XML_cNvPr,
                           XML_id,     I32S( nID ),
                           XML_name,   sName.toUtf8(),
                           FSEND );
 
+    OUString sURL;
+    if ( GetProperty( xShapeProps, "URL" ) )
+        mAny >>= sURL;
+    if( !sURL.isEmpty() )
+    {
+        OUString sRelId = mpFB->addRelation( mpFS->getOutputStream(),
+                oox::getRelationship(Relationship::HYPERLINK),
+                mpURLTransformer->getTransformedString(sURL),
+                mpURLTransformer->isExternalURL(sURL));
+
+        mpFS->singleElementNS( XML_a, XML_hlinkClick,
+                FSNS( XML_r,XML_id ), sRelId.toUtf8(),
+                FSEND );
+    }
+    pFS->endElementNS(mnXmlNamespace, XML_cNvPr);
+
     pFS->singleElementNS( mnXmlNamespace, XML_cNvGraphicFramePr,
                           FSEND );
 
diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx
index a5e8f48f6dff..15eeda16f4c6 100644
--- a/oox/source/export/drawingml.cxx
+++ b/oox/source/export/drawingml.cxx
@@ -133,6 +133,20 @@ using ::sax_fastparser::FastSerializerHelper;
 namespace oox {
 namespace drawingml {
 
+URLTransformer::~URLTransformer()
+{
+}
+
+OUString URLTransformer::getTransformedString(const OUString& rString) const
+{
+    return rString;
+}
+
+bool URLTransformer::isExternalURL(const OUString& /*rURL*/) const
+{
+    return true;
+}
+
 static css::uno::Any getLineDash( const 
css::uno::Reference<css::frame::XModel>& xModel, const OUString& rDashName )
     {
         css::uno::Reference<css::lang::XMultiServiceFactory> xFact(xModel, 
css::uno::UNO_QUERY);
diff --git a/oox/source/export/shapes.cxx b/oox/source/export/shapes.cxx
index ecc14705a75b..b89f1d966868 100644
--- a/oox/source/export/shapes.cxx
+++ b/oox/source/export/shapes.cxx
@@ -338,20 +338,6 @@ uno::Reference<io::XInputStream> GetOLEObjectStream(
 
 namespace oox { namespace drawingml {
 
-URLTransformer::~URLTransformer()
-{
-}
-
-OUString URLTransformer::getTransformedString(const OUString& rString) const
-{
-    return rString;
-}
-
-bool URLTransformer::isExternalURL(const OUString& /*rURL*/) const
-{
-    return true;
-}
-
 #define GETA(propName) \
     GetProperty( rXPropSet, #propName)
 
@@ -1160,13 +1146,13 @@ void ShapeExport::WriteGraphicObjectShapePart( const 
Reference< XShape >& xShape
     if( !sURL.isEmpty() )
     {
         OUString sRelId = mpFB->addRelation( mpFS->getOutputStream(),
-        oox::getRelationship(Relationship::HYPERLINK),
-        mpURLTransformer->getTransformedString(sURL),
-        mpURLTransformer->isExternalURL(sURL));
+                oox::getRelationship(Relationship::HYPERLINK),
+                mpURLTransformer->getTransformedString(sURL),
+                mpURLTransformer->isExternalURL(sURL));
 
         mpFS->singleElementNS( XML_a, XML_hlinkClick,
-        FSNS( XML_r,XML_id ), sRelId.toUtf8(),
-        FSEND );
+                FSNS( XML_r,XML_id ), sRelId.toUtf8(),
+                FSEND );
     }
     pFS->endElementNS(mnXmlNamespace, XML_cNvPr);
 
diff --git a/sc/qa/unit/data/xlsx/chart_hyperlink.xlsx 
b/sc/qa/unit/data/xlsx/chart_hyperlink.xlsx
new file mode 100644
index 000000000000..95d48266f0fb
Binary files /dev/null and b/sc/qa/unit/data/xlsx/chart_hyperlink.xlsx differ
diff --git a/sc/qa/unit/subsequent_export-test.cxx 
b/sc/qa/unit/subsequent_export-test.cxx
index 17158933ec34..57c4469355f7 100644
--- a/sc/qa/unit/subsequent_export-test.cxx
+++ b/sc/qa/unit/subsequent_export-test.cxx
@@ -214,6 +214,7 @@ public:
     void testTdf115192XLSX();
     void testTdf91634XLSX();
     void testTdf115159();
+    void testTdf123645XLSX();
 
     void testXltxExport();
 
@@ -335,6 +336,7 @@ public:
     CPPUNIT_TEST(testTdf115192XLSX);
     CPPUNIT_TEST(testTdf91634XLSX);
     CPPUNIT_TEST(testTdf115159);
+    CPPUNIT_TEST(testTdf123645XLSX);
 
     CPPUNIT_TEST(testXltxExport);
 
@@ -4225,6 +4227,28 @@ void ScExportTest::testTdf115159()
     xDocSh->DoClose();
 }
 
+void ScExportTest::testTdf123645XLSX()
+{
+    ScDocShellRef xDocSh = loadDoc("chart_hyperlink.", FORMAT_XLSX);
+    CPPUNIT_ASSERT(xDocSh.is());
+    std::shared_ptr<utl::TempFile> pXPathFile = 
ScBootstrapFixture::exportTo(&(*xDocSh), FORMAT_XLSX);
+
+    xmlDocPtr pDoc = XPathHelper::parseExport(pXPathFile, m_xSFactory, 
"xl/drawings/drawing1.xml");
+    CPPUNIT_ASSERT(pDoc);
+    assertXPath(pDoc, 
"/xdr:wsDr/xdr:twoCellAnchor[1]/xdr:graphicFrame/xdr:nvGraphicFramePr/xdr:cNvPr/a:hlinkClick",
 1);
+    assertXPath(pDoc, 
"/xdr:wsDr/xdr:twoCellAnchor[2]/xdr:graphicFrame/xdr:nvGraphicFramePr/xdr:cNvPr/a:hlinkClick",
 1);
+    assertXPath(pDoc, 
"/xdr:wsDr/xdr:twoCellAnchor[3]/xdr:graphicFrame/xdr:nvGraphicFramePr/xdr:cNvPr/a:hlinkClick",
 1);
+
+    xmlDocPtr pXmlRels = XPathHelper::parseExport(pXPathFile, m_xSFactory, 
"xl/drawings/_rels/drawing1.xml.rels");
+    CPPUNIT_ASSERT(pXmlRels);
+    assertXPath(pXmlRels, "/r:Relationships/r:Relationship[@Id='rId1']", 
"TargetMode", "External");
+    assertXPathNoAttribute(pXmlRels, 
"/r:Relationships/r:Relationship[@Id='rId3']", "TargetMode");
+    assertXPath(pXmlRels, "/r:Relationships/r:Relationship[@Id='rId5']", 
"TargetMode", "External");
+    assertXPath(pXmlRels, "/r:Relationships/r:Relationship[@Id='rId1']", 
"Target", "file:///C:/TEMP/test.xlsx");
+    assertXPath(pXmlRels, "/r:Relationships/r:Relationship[@Id='rId3']", 
"Target", "#Sheet2!A1");
+    assertXPath(pXmlRels, "/r:Relationships/r:Relationship[@Id='rId5']", 
"Target", "https://bugs.documentfoundation.org/show_bug.cgi?id=123645";);
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(ScExportTest);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sc/source/filter/excel/xeescher.cxx 
b/sc/source/filter/excel/xeescher.cxx
index 1780e00efc9e..f1d41f7a7f7e 100644
--- a/sc/source/filter/excel/xeescher.cxx
+++ b/sc/source/filter/excel/xeescher.cxx
@@ -1059,9 +1059,10 @@ void XclExpTbxControlObj::WriteSbs( XclExpStream& rStrm )
 
 //#endif
 
-XclExpChartObj::XclExpChartObj( XclExpObjectManager& rObjMgr, Reference< 
XShape > const & xShape, const tools::Rectangle* pChildAnchor ) :
+XclExpChartObj::XclExpChartObj( XclExpObjectManager& rObjMgr, Reference< 
XShape > const & xShape, const tools::Rectangle* pChildAnchor, ScDocument* pDoc 
) :
     XclObj( rObjMgr, EXC_OBJTYPE_CHART ),
-    XclExpRoot( rObjMgr.GetRoot() ), mxShape( xShape )
+    XclExpRoot( rObjMgr.GetRoot() ), mxShape( xShape ),
+    mpDoc(pDoc)
 {
     // create the MSODRAWING record contents for the chart object
     mrEscherEx.OpenContainer( ESCHER_SpContainer );
@@ -1128,6 +1129,8 @@ void XclExpChartObj::SaveXml( XclExpXmlStream& rStrm )
         XclObjAny::WriteFromTo( rStrm, mxShape, GetTab() );
         Reference< XModel > xModel( mxChartDoc, UNO_QUERY );
         ChartExport aChartExport(XML_xdr, pDrawing, xModel, &rStrm, 
drawingml::DOCUMENT_XLSX);
+        std::shared_ptr<oox::drawingml::URLTransformer> pURLTransformer(new 
ScURLTransformer(*mpDoc));
+        aChartExport.SetURLTranslator(pURLTransformer);
         static sal_Int32 nChartCount = 0;
         nChartCount++;
         sal_Int32 nID = rStrm.GetUniqueId();
diff --git a/sc/source/filter/inc/xcl97rec.hxx 
b/sc/source/filter/inc/xcl97rec.hxx
index 1c8fa1903e33..0999f0ea3dd2 100644
--- a/sc/source/filter/inc/xcl97rec.hxx
+++ b/sc/source/filter/inc/xcl97rec.hxx
@@ -26,6 +26,7 @@
 #include "xestring.hxx"
 #include <tabprotection.hxx>
 #include <svx/svdobj.hxx>
+#include <oox/export/drawingml.hxx>
 
 class XclObj;
 class XclExpMsoDrawing;
@@ -34,6 +35,19 @@ class SdrTextObj;
 class XclTxo;
 class XclEscherEx;
 
+class ScURLTransformer : public oox::drawingml::URLTransformer
+{
+public:
+    explicit ScURLTransformer(ScDocument& rDoc);
+
+    virtual OUString getTransformedString(const OUString& rURL) const override;
+
+    virtual bool isExternalURL(const OUString& rURL) const override;
+
+private:
+    ScDocument& mrDoc;
+};
+
 class XclExpObjList : public ExcEmptyRec, protected XclExpRoot
 {
 public:
diff --git a/sc/source/filter/inc/xeescher.hxx 
b/sc/source/filter/inc/xeescher.hxx
index f45ebbf79bcf..05491a3b2127 100644
--- a/sc/source/filter/inc/xeescher.hxx
+++ b/sc/source/filter/inc/xeescher.hxx
@@ -294,7 +294,8 @@ public:
     explicit            XclExpChartObj(
                             XclExpObjectManager& rObjMgr,
                             css::uno::Reference< css::drawing::XShape > const 
& xShape,
-                            const tools::Rectangle* pChildAnchor );
+                            const tools::Rectangle* pChildAnchor,
+                            ScDocument* pDoc );
     virtual             ~XclExpChartObj() override;
 
     /** Writes the OBJ record and the entire chart substream. */
@@ -308,6 +309,7 @@ private:
     XclExpChartRef                                    mxChart;        /// The 
chart itself (BOF/EOF substream data).
     css::uno::Reference< css::drawing::XShape >       mxShape;
     css::uno::Reference< css::chart::XChartDocument > mxChartDoc;
+    ScDocument*                                       mpDoc;
 };
 
 /** Represents a NOTE record containing the relevant data of a cell note.
diff --git a/sc/source/filter/xcl97/xcl97esc.cxx 
b/sc/source/filter/xcl97/xcl97esc.cxx
index f987d336e1b4..9ca76ae49c58 100644
--- a/sc/source/filter/xcl97/xcl97esc.cxx
+++ b/sc/source/filter/xcl97/xcl97esc.cxx
@@ -215,7 +215,7 @@ EscherExHostAppData* XclEscherEx::StartShape( const 
Reference< XShape >& rxShape
                     SvGlobalName aObjClsId( xObj->getClassID() );
                     if ( SotExchange::IsChart( aObjClsId ) )
                     {   // yes, it's a chart diagram
-                        mrObjMgr.AddObj( std::make_unique<XclExpChartObj>( 
mrObjMgr, rxShape, pChildAnchor ) );
+                        mrObjMgr.AddObj( std::make_unique<XclExpChartObj>( 
mrObjMgr, rxShape, pChildAnchor, &GetDocRef() ) );
                         pCurrXclObj = nullptr;     // no metafile or whatsoever
                     }
                     else    // metafile and OLE object
diff --git a/sc/source/filter/xcl97/xcl97rec.cxx 
b/sc/source/filter/xcl97/xcl97rec.cxx
index 38fd9c27103e..4c55ed88ec03 100644
--- a/sc/source/filter/xcl97/xcl97rec.cxx
+++ b/sc/source/filter/xcl97/xcl97rec.cxx
@@ -1129,30 +1129,23 @@ void transformURL(const OUString& rOldURL, OUString& 
rNewURL, const ScDocument*
     rNewURL = rOldURL;
 }
 
-class ScURLTransformer : public oox::drawingml::URLTransformer
-{
-public:
-    explicit ScURLTransformer(ScDocument& rDoc)
-        : mrDoc(rDoc)
-    {
-    }
-
-    virtual OUString getTransformedString(const OUString& rURL) const override
-    {
-        OUString aNewURL;
-        transformURL(rURL, aNewURL, &mrDoc);
-        return aNewURL;
-    }
+}
 
-    virtual bool isExternalURL(const OUString& rURL) const override
-    {
-        return !rURL.startsWith("#");
-    }
+ScURLTransformer::ScURLTransformer(ScDocument& rDoc)
+    : mrDoc(rDoc)
+{
+}
 
-private:
-    ScDocument& mrDoc;
-};
+OUString ScURLTransformer::getTransformedString(const OUString& rURL) const
+{
+    OUString aNewURL;
+    transformURL(rURL, aNewURL, &mrDoc);
+    return aNewURL;
+}
 
+bool ScURLTransformer::isExternalURL(const OUString& rURL) const
+{
+    return !rURL.startsWith("#");
 }
 
 void XclObjAny::SaveXml( XclExpXmlStream& rStrm )
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to