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>
This commit is contained in:
parent
b3c965ccaa
commit
855a56fea4
7 changed files with 100 additions and 18 deletions
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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() );
|
||||
|
|
BIN
sd/qa/unit/data/pptx/tdf148965.pptx
Normal file
BIN
sd/qa/unit/data/pptx/tdf148965.pptx
Normal file
Binary file not shown.
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue