summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTibor Nagy <nagy.tibor2@nisz.hu>2022-05-13 08:12:17 +0200
committerLászló Németh <nemeth@numbertext.org>2022-05-27 18:32:38 +0200
commit855a56fea4561135a63cb729d7a625a950b210e7 (patch)
tree96dd057f2ab6917041ee43e943c321880e57a5bf
parentb3c965ccaa896b12b33ff5b7ccea0eb20d560116 (diff)
tdf#148965 PPTX import: fix internal hyperlinks on shapes
Locale dependent code path resulted broken hyperlinks on shapes in a non-English build. Change-Id: I045bbe4246ab5336e2b967bf252b5fbca5b17706 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134266 Tested-by: László Németh <nemeth@numbertext.org> Reviewed-by: László Németh <nemeth@numbertext.org>
-rw-r--r--include/oox/drawingml/shape.hxx6
-rw-r--r--include/oox/ppt/slidepersist.hxx4
-rw-r--r--oox/source/ppt/pptshape.cxx23
-rw-r--r--oox/source/ppt/presentationfragmenthandler.cxx46
-rw-r--r--oox/source/ppt/slidepersist.cxx2
-rw-r--r--sd/qa/unit/data/pptx/tdf148965.pptxbin0 -> 19068 bytes
-rw-r--r--sd/qa/unit/import-tests.cxx37
7 files changed, 100 insertions, 18 deletions
diff --git a/include/oox/drawingml/shape.hxx b/include/oox/drawingml/shape.hxx
index 4318c1e24d2d..e845b399f5f8 100644
--- a/include/oox/drawingml/shape.hxx
+++ b/include/oox/drawingml/shape.hxx
@@ -140,6 +140,9 @@ public:
void setConnectorShape(bool bConnector) { mbConnector = bConnector; }
bool isConnectorShape() const { return mbConnector; }
+ void setBookmark(bool bBookmark) { mbHasBookmark = bBookmark; }
+ bool hasBookmark() const { return mbHasBookmark; }
+
Shape3DProperties& get3DProperties() { return *mp3DPropertiesPtr; }
const Shape3DProperties& get3DProperties() const { return *mp3DPropertiesPtr; }
@@ -410,6 +413,9 @@ private:
// Is this a connector shape?
bool mbConnector = false;
+ // Is shape has bookmark?
+ bool mbHasBookmark = false;
+
// temporary space for DiagramHelper in preparation for collecting data
// Note: I tried to use a unique_ptr here, but existing constructor func does not allow that
svx::diagram::IDiagramHelper* mpDiagramHelper;
diff --git a/include/oox/ppt/slidepersist.hxx b/include/oox/ppt/slidepersist.hxx
index 1b0a92c70783..4ba48637c66a 100644
--- a/include/oox/ppt/slidepersist.hxx
+++ b/include/oox/ppt/slidepersist.hxx
@@ -127,6 +127,9 @@ public:
void createConnectorShapeConnection();
+ void addURLShapeId(const OUString& rShapeId) { maURLShapeId.push_back(rShapeId); }
+ std::vector<OUString>& getURLShapeId() { return maURLShapeId; }
+
private:
OUString maPath;
OUString maLayoutPath;
@@ -160,6 +163,7 @@ private:
CommentAuthorList maCommentAuthors;
std::vector<OUString> maConnectorShapeId;
+ std::vector<OUString> maURLShapeId;
};
}
diff --git a/oox/source/ppt/pptshape.cxx b/oox/source/ppt/pptshape.cxx
index d83737250550..2ec4a3fbe327 100644
--- a/oox/source/ppt/pptshape.cxx
+++ b/oox/source/ppt/pptshape.cxx
@@ -613,27 +613,14 @@ void PPTShape::addShape(
// so check here if it's a bookmark or a document
if (meClickAction == ClickAction_BOOKMARK)
{
+ sal_Int32 nSplitPos;
if (!sURL.startsWith("#"))
meClickAction = ClickAction_DOCUMENT;
- else
+ else if (-1 != (nSplitPos = sURL.indexOf( ' ' )))
{
- sURL = sURL.copy(1);
- sal_Int32 nPageNumber = 0;
- static const OUStringLiteral sSlide = u"Slide ";
- if (sURL.match(sSlide))
- nPageNumber = o3tl::toInt32(sURL.subView(sSlide.getLength()));
- Reference<drawing::XDrawPagesSupplier> xDPS(rFilterBase.getModel(),
- uno::UNO_QUERY_THROW);
- Reference<drawing::XDrawPages> xDrawPages(xDPS->getDrawPages(),
- uno::UNO_SET_THROW);
- sal_Int32 nMaxPages = xDrawPages->getCount();
- if (nPageNumber && nPageNumber <= nMaxPages)
- {
- Reference<XDrawPage> xDrawPage;
- xDrawPages->getByIndex(nPageNumber - 1) >>= xDrawPage;
- Reference<container::XNamed> xNamed(xDrawPage, UNO_QUERY);
- sURL = xNamed->getName();
- }
+ setBookmark(true);
+ // reuse slide number from '#Slide [Num]' or "#Notes [Num]"
+ sURL = OUString::Concat("#page") + sURL.subView(nSplitPos);
}
nPropertyCount += 1;
}
diff --git a/oox/source/ppt/presentationfragmenthandler.cxx b/oox/source/ppt/presentationfragmenthandler.cxx
index 64aaf62f9a71..c9deec076edc 100644
--- a/oox/source/ppt/presentationfragmenthandler.cxx
+++ b/oox/source/ppt/presentationfragmenthandler.cxx
@@ -106,6 +106,51 @@ PresentationFragmentHandler::~PresentationFragmentHandler() noexcept
{
}
+static void lcl_setBookmark(uno::Reference<drawing::XShape>& rShape,
+ std::vector<SlidePersistPtr>& rSlidePersist)
+{
+ OUString aBookmark;
+ sal_Int32 nPageNumber;
+ static const OUStringLiteral sSlideName = u"#page";
+ uno::Reference<beans::XPropertySet> xPropSet(rShape, uno::UNO_QUERY);
+ xPropSet->getPropertyValue("Bookmark") >>= aBookmark;
+ nPageNumber = o3tl::toInt32(aBookmark.subView(sSlideName.getLength()));
+ Reference<XDrawPage> xDrawPage(rSlidePersist[nPageNumber - 1]->getPage());
+ Reference<container::XNamed> xNamed(xDrawPage, UNO_QUERY_THROW);
+ aBookmark = xNamed->getName();
+ xPropSet->setPropertyValue("Bookmark", Any(aBookmark));
+}
+
+static void ResolveShapeBookmark(std::vector<SlidePersistPtr>& rSlidePersist)
+{
+ sal_Int32 nPageCount = rSlidePersist.size();
+ for (sal_Int32 nPage = 0; nPage < nPageCount; ++nPage)
+ {
+ if (!rSlidePersist[nPage]->getURLShapeId().empty())
+ {
+ auto aShapeMap = rSlidePersist[nPage]->getShapeMap();
+ sal_Int32 nCount = rSlidePersist[nPage]->getURLShapeId().size();
+ for (sal_Int32 i = 0; i < nCount; i++)
+ {
+ OUString sId = rSlidePersist[nPage]->getURLShapeId()[i];
+ uno::Reference<drawing::XShape> xShape(aShapeMap[sId]->getXShape(), uno::UNO_QUERY);
+ Reference<XShapes> xShapes(xShape, UNO_QUERY);
+ if (xShapes.is()) // group shape
+ {
+ for (sal_Int32 j = 0; j < xShapes->getCount(); j++)
+ {
+ uno::Reference<drawing::XShape> xGroupedShape(xShapes->getByIndex(j),
+ uno::UNO_QUERY);
+ lcl_setBookmark(xGroupedShape, rSlidePersist);
+ }
+ }
+ else
+ lcl_setBookmark(xShape, rSlidePersist);
+ }
+ }
+ }
+}
+
static void ResolveTextFields( XmlFilterBase const & rFilter )
{
const oox::core::TextFieldStack& rTextFields = rFilter.getTextFieldStack();
@@ -551,6 +596,7 @@ void PresentationFragmentHandler::finalizeImport()
nPagesImported++;
}
ResolveTextFields( rFilter );
+ ResolveShapeBookmark(rFilter.getDrawPages());
if (!maCustomShowList.empty())
importCustomSlideShow(maCustomShowList);
}
diff --git a/oox/source/ppt/slidepersist.cxx b/oox/source/ppt/slidepersist.cxx
index 24ce2f9da464..8d45bcdb7947 100644
--- a/oox/source/ppt/slidepersist.cxx
+++ b/oox/source/ppt/slidepersist.cxx
@@ -158,6 +158,8 @@ void SlidePersist::createXShapes( XmlFilterBase& rFilterBase )
maConnectorShapeId.push_back(pPPTShape->getChildren()[i]->getId());
}
}
+ if (pPPTShape->hasBookmark())
+ addURLShapeId(pPPTShape->getId());
}
else
child->addShape( rFilterBase, getTheme().get(), xShapes, aTransformation, maShapesPtr->getFillProperties(), &getShapeMap() );
diff --git a/sd/qa/unit/data/pptx/tdf148965.pptx b/sd/qa/unit/data/pptx/tdf148965.pptx
new file mode 100644
index 000000000000..5b7b9f098d0b
--- /dev/null
+++ b/sd/qa/unit/data/pptx/tdf148965.pptx
Binary files differ
diff --git a/sd/qa/unit/import-tests.cxx b/sd/qa/unit/import-tests.cxx
index 9e60c8886dec..aa329dfddec6 100644
--- a/sd/qa/unit/import-tests.cxx
+++ b/sd/qa/unit/import-tests.cxx
@@ -55,6 +55,8 @@
#include <com/sun/star/drawing/ConnectorType.hpp>
#include <stlpool.hxx>
+#include <unotools/syslocaleoptions.hxx>
+#include <comphelper/scopeguard.hxx>
#include <comphelper/sequenceashashmap.hxx>
#include <comphelper/lok.hxx>
#include <svx/svdograf.hxx>
@@ -82,6 +84,7 @@ public:
void testDocumentLayout();
void testTdf149124();
+ void testTdf148965();
void testTdf89449();
void testTdf147459();
void testTdf146223();
@@ -151,6 +154,7 @@ public:
CPPUNIT_TEST(testDocumentLayout);
CPPUNIT_TEST(testTdf149124);
+ CPPUNIT_TEST(testTdf148965);
CPPUNIT_TEST(testTdf89449);
CPPUNIT_TEST(testTdf147459);
CPPUNIT_TEST(testTdf146223);
@@ -309,7 +313,40 @@ void SdImportTest::testTdf149124()
CPPUNIT_ASSERT_EQUAL(sal_Int32(2), nStartGlueId);
sal_Int32 nEndGlueId = xStandardConnector->getPropertyValue("EndGluePointIndex").get<sal_Int32>();
CPPUNIT_ASSERT_EQUAL(sal_Int32(0), nEndGlueId);
+}
+
+void SdImportTest::testTdf148965()
+{
+ // Set the system user interface to Hungarian
+ SvtSysLocaleOptions aOptions;
+ OUString sUIConfigString = aOptions.GetLanguageTag().getBcp47();
+ aOptions.SetUILocaleConfigString("hu-HU");
+ aOptions.Commit();
+ comphelper::ScopeGuard g([&aOptions, &sUIConfigString] {
+ aOptions.SetUILocaleConfigString(sUIConfigString);
+ aOptions.Commit();
+ });
+
+ sd::DrawDocShellRef xDocShRef
+ = loadURL(m_directories.getURLFromSrc(u"sd/qa/unit/data/pptx/tdf148965.pptx"), PPTX);
+ uno::Reference<beans::XPropertySet> xShape1(getShapeFromPage(0, 1, xDocShRef));
+ uno::Reference<document::XEventsSupplier> xEventsSupplier1(xShape1, uno::UNO_QUERY);
+ uno::Reference<container::XNameAccess> xEvents1(xEventsSupplier1->getEvents());
+ uno::Sequence<beans::PropertyValue> props1;
+ xEvents1->getByName("OnClick") >>= props1;
+ comphelper::SequenceAsHashMap map1(props1);
+ auto iter1(map1.find("Bookmark"));
+ CPPUNIT_ASSERT_EQUAL(OUString("page1"), iter1->second.get<OUString>());
+
+ uno::Reference<beans::XPropertySet> xShape2(getShapeFromPage(1, 1, xDocShRef));
+ uno::Reference<document::XEventsSupplier> xEventsSupplier2(xShape2, uno::UNO_QUERY);
+ uno::Reference<container::XNameAccess> xEvents2(xEventsSupplier2->getEvents());
+ uno::Sequence<beans::PropertyValue> props2;
+ xEvents2->getByName("OnClick") >>= props2;
+ comphelper::SequenceAsHashMap map2(props2);
+ auto iter2(map2.find("Bookmark"));
+ CPPUNIT_ASSERT_EQUAL(OUString("page3"), iter2->second.get<OUString>());
xDocShRef->DoClose();
}