oox/source/ppt/pptshape.cxx         |  143 ++++++++++++++++++++----------------
 sd/qa/unit/data/pptx/tdf144917.pptx |binary
 sd/qa/unit/import-tests.cxx         |   21 +++++
 3 files changed, 101 insertions(+), 63 deletions(-)

New commits:
commit 378e8396223a80b96262d7b638a066eb83ba88d6
Author:     Tibor Nagy <nagy.tib...@nisz.hu>
AuthorDate: Wed Oct 6 09:31:37 2021 +0200
Commit:     László Németh <nem...@numbertext.org>
CommitDate: Wed Oct 20 12:30:21 2021 +0200

    tdf#144917 PPTX import: fix hyperlinks on grouped shapes
    
    Hyperlinks on the shapes of a group shape weren't imported.
    Now all of them are imported correctly.
    
    Change-Id: Ic42892650a3492958600232bd7038585f9aa6ae1
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/123127
    Tested-by: László Németh <nem...@numbertext.org>
    Reviewed-by: László Németh <nem...@numbertext.org>

diff --git a/oox/source/ppt/pptshape.cxx b/oox/source/ppt/pptshape.cxx
index bbc7d2585fd8..2a134ada4a0c 100644
--- a/oox/source/ppt/pptshape.cxx
+++ b/oox/source/ppt/pptshape.cxx
@@ -518,6 +518,8 @@ void PPTShape::addShape(
                 }
             }
 
+            OUString sURL;
+            std::vector<std::pair<OUString, Reference<XShape>>> aURLShapes;
             // if this is a group shape, we have to add also each child shape
             Reference<XShapes> xShapes(xShape, UNO_QUERY);
             if (xShapes.is())
@@ -531,6 +533,15 @@ void PPTShape::addShape(
                 {
                     rFilterBase.setDiagramFontHeights(nullptr);
                 }
+                for (size_t i = 0; i < this->getChildren().size(); i++)
+                {
+                    
this->getChildren()[i]->getShapeProperties().getProperty(PROP_URL) >>= sURL;
+                    if (!sURL.isEmpty())
+                    {
+                        Reference<XShape> xChild = 
this->getChildren()[i]->getXShape();
+                        aURLShapes.push_back({ sURL, xChild });
+                    }
+                }
             }
 
             if (meFrameType == FRAMETYPE_DIAGRAM)
@@ -539,77 +550,83 @@ void PPTShape::addShape(
                 syncDiagramFontHeights();
             }
 
-            OUString sURL;
             getShapeProperties().getProperty(PROP_URL) >>= sURL;
-            if (!sURL.isEmpty())
+            if (!sURL.isEmpty() && !xShapes.is())
+                aURLShapes.push_back({ sURL, xShape });
+
+            if (!aURLShapes.empty())
             {
-                Reference<XEventsSupplier> xEventsSupplier(xShape, UNO_QUERY);
-                if (!xEventsSupplier.is())
-                    return;
-
-                Reference<XNameReplace> xEvents(xEventsSupplier->getEvents());
-                if (!xEvents.is())
-                    return;
-
-                OUString sAPIEventName;
-                sal_Int32 nPropertyCount = 2;
-                css::presentation::ClickAction meClickAction;
-                uno::Sequence<beans::PropertyValue> aProperties;
-
-                std::map<OUString, css::presentation::ClickAction> ActionMap = 
{
-                    { "#action?jump=nextslide", ClickAction_NEXTPAGE },
-                    { "#action?jump=previousslide", ClickAction_PREVPAGE },
-                    { "#action?jump=firstslide", ClickAction_FIRSTPAGE },
-                    { "#action?jump=lastslide", ClickAction_LASTPAGE },
-                    { "#action?jump=endshow", ClickAction_STOPPRESENTATION },
-                };
-
-                std::map<OUString, 
css::presentation::ClickAction>::const_iterator aIt
-                    = ActionMap.find(sURL);
-                aIt != ActionMap.end() ? meClickAction = aIt->second
-                                       : meClickAction = ClickAction_BOOKMARK;
-
-                // ClickAction_BOOKMARK and ClickAction_DOCUMENT share the 
same event
-                // so check here if it's a bookmark or a document
-                if (meClickAction == ClickAction_BOOKMARK)
+                for (auto const& URLShape : aURLShapes)
                 {
-                    if (!sURL.startsWith("#"))
-                        meClickAction = ClickAction_DOCUMENT;
-                    else
-                        sURL = sURL.copy(1);
-                    nPropertyCount += 1;
-                }
+                    Reference<XEventsSupplier> 
xEventsSupplier(URLShape.second, UNO_QUERY);
+                    if (!xEventsSupplier.is())
+                        return;
+
+                    Reference<XNameReplace> 
xEvents(xEventsSupplier->getEvents());
+                    if (!xEvents.is())
+                        return;
+
+                    OUString sAPIEventName;
+                    sal_Int32 nPropertyCount = 2;
+                    css::presentation::ClickAction meClickAction;
+                    uno::Sequence<beans::PropertyValue> aProperties;
+
+                    std::map<OUString, css::presentation::ClickAction> 
ActionMap = {
+                        { "#action?jump=nextslide", ClickAction_NEXTPAGE },
+                        { "#action?jump=previousslide", ClickAction_PREVPAGE },
+                        { "#action?jump=firstslide", ClickAction_FIRSTPAGE },
+                        { "#action?jump=lastslide", ClickAction_LASTPAGE },
+                        { "#action?jump=endshow", ClickAction_STOPPRESENTATION 
},
+                    };
+
+                    sURL = URLShape.first;
+                    std::map<OUString, 
css::presentation::ClickAction>::const_iterator aIt
+                        = ActionMap.find(sURL);
+                    aIt != ActionMap.end() ? meClickAction = aIt->second
+                                           : meClickAction = 
ClickAction_BOOKMARK;
+
+                    // ClickAction_BOOKMARK and ClickAction_DOCUMENT share the 
same event
+                    // so check here if it's a bookmark or a document
+                    if (meClickAction == ClickAction_BOOKMARK)
+                    {
+                        if (!sURL.startsWith("#"))
+                            meClickAction = ClickAction_DOCUMENT;
+                        else
+                            sURL = sURL.copy(1);
+                        nPropertyCount += 1;
+                    }
 
-                aProperties.realloc(nPropertyCount);
-                beans::PropertyValue* pProperties = aProperties.getArray();
+                    aProperties.realloc(nPropertyCount);
+                    beans::PropertyValue* pProperties = aProperties.getArray();
 
-                pProperties->Name = "EventType";
-                pProperties->Handle = -1;
-                pProperties->Value <<= OUString("Presentation");
-                pProperties->State = beans::PropertyState_DIRECT_VALUE;
-                pProperties++;
+                    pProperties->Name = "EventType";
+                    pProperties->Handle = -1;
+                    pProperties->Value <<= OUString("Presentation");
+                    pProperties->State = beans::PropertyState_DIRECT_VALUE;
+                    pProperties++;
 
-                pProperties->Name = "ClickAction";
-                pProperties->Handle = -1;
-                pProperties->Value <<= meClickAction;
-                pProperties->State = beans::PropertyState_DIRECT_VALUE;
-                pProperties++;
+                    pProperties->Name = "ClickAction";
+                    pProperties->Handle = -1;
+                    pProperties->Value <<= meClickAction;
+                    pProperties->State = beans::PropertyState_DIRECT_VALUE;
+                    pProperties++;
 
-                switch (meClickAction)
-                {
-                    case ClickAction_BOOKMARK:
-                    case ClickAction_DOCUMENT:
-                        pProperties->Name = "Bookmark";
-                        pProperties->Handle = -1;
-                        pProperties->Value <<= sURL;
-                        pProperties->State = beans::PropertyState_DIRECT_VALUE;
-                        break;
-                    default:
-                        break;
-                }
+                    switch (meClickAction)
+                    {
+                        case ClickAction_BOOKMARK:
+                        case ClickAction_DOCUMENT:
+                            pProperties->Name = "Bookmark";
+                            pProperties->Handle = -1;
+                            pProperties->Value <<= sURL;
+                            pProperties->State = 
beans::PropertyState_DIRECT_VALUE;
+                            break;
+                        default:
+                            break;
+                    }
 
-                sAPIEventName = "OnClick";
-                xEvents->replaceByName(sAPIEventName, uno::Any(aProperties));
+                    sAPIEventName = "OnClick";
+                    xEvents->replaceByName(sAPIEventName, 
uno::Any(aProperties));
+                }
             }
         }
     }
diff --git a/sd/qa/unit/data/pptx/tdf144917.pptx 
b/sd/qa/unit/data/pptx/tdf144917.pptx
new file mode 100644
index 000000000000..654b17a432cd
Binary files /dev/null and b/sd/qa/unit/data/pptx/tdf144917.pptx differ
diff --git a/sd/qa/unit/import-tests.cxx b/sd/qa/unit/import-tests.cxx
index 36b3886d852f..580cb527e85f 100644
--- a/sd/qa/unit/import-tests.cxx
+++ b/sd/qa/unit/import-tests.cxx
@@ -122,6 +122,7 @@ public:
     virtual void setUp() override;
 
     void testDocumentLayout();
+    void testTdf144917();
     void testHyperlinkOnImage();
     void testTdf142645();
     void testTdf141704();
@@ -248,6 +249,7 @@ public:
     CPPUNIT_TEST_SUITE(SdImportTest);
 
     CPPUNIT_TEST(testDocumentLayout);
+    CPPUNIT_TEST(testTdf144917);
     CPPUNIT_TEST(testHyperlinkOnImage);
     CPPUNIT_TEST(testTdf142645);
     CPPUNIT_TEST(testTdf141704);
@@ -450,6 +452,25 @@ void SdImportTest::testDocumentLayout()
     }
 }
 
+void SdImportTest::testTdf144917()
+{
+    sd::DrawDocShellRef xDocShRef
+        = 
loadURL(m_directories.getURLFromSrc(u"/sd/qa/unit/data/pptx/tdf144917.pptx"), 
PPTX);
+
+    uno::Reference<container::XIndexAccess> xGroupShape(getShapeFromPage(0, 0, 
xDocShRef),
+                                                        uno::UNO_QUERY_THROW);
+    uno::Reference<beans::XPropertySet> xShape(xGroupShape->getByIndex(1), 
uno::UNO_QUERY_THROW);
+    uno::Reference<document::XEventsSupplier> xEventsSupplier(xShape, 
uno::UNO_QUERY);
+    uno::Reference<container::XNameAccess> 
xEvents(xEventsSupplier->getEvents());
+    uno::Sequence<beans::PropertyValue> props;
+    xEvents->getByName("OnClick") >>= props;
+    comphelper::SequenceAsHashMap map(props);
+    auto iter(map.find("Bookmark"));
+    CPPUNIT_ASSERT_EQUAL(OUString("http://www.example.com/";), 
iter->second.get<OUString>());
+
+    xDocShRef->DoClose();
+}
+
 void SdImportTest::testHyperlinkOnImage()
 {
     sd::DrawDocShellRef xDocShRef

Reply via email to