From e17187c323428b7edea425278ea33bca77db12b5 Mon Sep 17 00:00:00 2001 From: Katarina Behrens Date: Wed, 26 Aug 2015 18:05:08 +0200 Subject: tdf#91293: Preserve hyperlink on URL field OOXML export The fix is twofold: 1.Get URL property from the underlying text field, not from the text run -- put text field properties into rXPropSet (that's what GETA macro later queries), not into rRun 6a043e9c0acff20e1618ca8ec15c21d5d0fd0d37 does s/rXPropSet/rRun/ afaics for no good reason 2. Retrieve string content from URL field early, so that the test for empty text content doesn't fire Reviewed-on: https://gerrit.libreoffice.org/18031 Tested-by: Jenkins Reviewed-by: Markus Mohrhard Tested-by: Markus Mohrhard Conflicts: sd/qa/unit/export-tests.cxx Change-Id: I4317e4a2f6f2e6f15c30932adc80f1227e010af0 Reviewed-on: https://gerrit.libreoffice.org/18706 Tested-by: Jenkins Reviewed-by: Miklos Vajna --- include/oox/export/drawingml.hxx | 2 +- oox/source/export/drawingml.cxx | 40 ++++++++++++++------------- sd/qa/unit/data/pptx/hyperlinktest.pptx | Bin 0 -> 33633 bytes sd/qa/unit/export-tests.cxx | 46 ++++++++++++++++++++++++++++++++ 4 files changed, 69 insertions(+), 19 deletions(-) create mode 100644 sd/qa/unit/data/pptx/hyperlinktest.pptx diff --git a/include/oox/export/drawingml.hxx b/include/oox/export/drawingml.hxx index fff1e2cacf8d..bf5669a71b83 100644 --- a/include/oox/export/drawingml.hxx +++ b/include/oox/export/drawingml.hxx @@ -108,7 +108,7 @@ protected: bool GetPropertyAndState( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > rXPropSet, ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyState > rXPropState, const OUString& aName, ::com::sun::star::beans::PropertyState& eState ); - const char* GetFieldType( ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > rRun, bool& bIsField ); + OUString GetFieldValue( ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > rRun, bool& bIsURLField ); /// If bRelPathToMedia is true add "../" to image folder path while adding the image relationship diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx index 878276a531ff..ecb66e365313 100644 --- a/oox/source/export/drawingml.cxx +++ b/oox/source/export/drawingml.cxx @@ -1438,7 +1438,7 @@ void DrawingML::WriteRunProperties( Reference< XPropertySet > rRun, bool bIsFiel Reference< XTextField > rXTextField; GET( rXTextField, TextField ); if( rXTextField.is() ) - rRun.set( rXTextField, UNO_QUERY ); + rXPropSet.set( rXTextField, UNO_QUERY ); } // field properties starts here @@ -1461,11 +1461,10 @@ void DrawingML::WriteRunProperties( Reference< XPropertySet > rRun, bool bIsFiel mpFS->endElementNS( XML_a, nElement ); } -const char* DrawingML::GetFieldType( ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > rRun, bool& bIsField ) +OUString DrawingML::GetFieldValue( ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > rRun, bool& bIsURLField ) { - const char* sType = NULL; Reference< XPropertySet > rXPropSet( rRun, UNO_QUERY ); - OUString aFieldType; + OUString aFieldType, aFieldValue; if( GETA( TextPortionType ) ) { @@ -1479,7 +1478,6 @@ const char* DrawingML::GetFieldType( ::com::sun::star::uno::Reference< ::com::su GET( rXTextField, TextField ); if( rXTextField.is() ) { - bIsField = true; rXPropSet.set( rXTextField, UNO_QUERY ); if( rXPropSet.is() ) { @@ -1487,17 +1485,19 @@ const char* DrawingML::GetFieldType( ::com::sun::star::uno::Reference< ::com::su DBG(fprintf (stderr, "field kind: %s\n", USS(aFieldKind) )); if( aFieldKind == "Page" ) { - return "slidenum"; + aFieldValue = OUString("slidenum"); + } + else if( aFieldKind == "URL" ) + { + bIsURLField = true; + GET( aFieldValue, Representation) + } - // else if( aFieldKind == "URL" ) { - // do not return here - // and make URL field text run with hyperlink property later - // } } } } - return sType; + return aFieldValue; } void DrawingML::GetUUID( OStringBuffer& rBuffer ) @@ -1546,14 +1546,19 @@ void DrawingML::WriteRun( Reference< XTextRange > rRun ) sal_Int16 nLevel = -1; GET( nLevel, NumberingLevel ); - const char* sFieldType; - bool bIsField = false; + bool bIsURLField = false; + OUString sFieldValue = GetFieldValue( rRun, bIsURLField ); + bool bWriteField = !( sFieldValue.isEmpty() || bIsURLField ); + OUString sText = rRun->getString(); //if there is no text following the bullet, add a space after the bullet if (nLevel !=-1 && sText.isEmpty() ) sText=" "; + if ( bIsURLField ) + sText = sFieldValue; + if( sText.isEmpty()) { Reference< XPropertySet > xPropSet( rRun, UNO_QUERY ); @@ -1571,15 +1576,14 @@ void DrawingML::WriteRun( Reference< XTextRange > rRun ) } } - sFieldType = GetFieldType( rRun, bIsField ); - if( ( sFieldType != NULL ) ) + if( ( bWriteField ) ) { OStringBuffer sUUID(39); GetUUID( sUUID ); mpFS->startElementNS( XML_a, XML_fld, XML_id, sUUID.getStr(), - XML_type, sFieldType, + XML_type, OUStringToOString( sFieldValue, RTL_TEXTENCODING_UTF8 ).getStr(), FSEND ); } else @@ -1588,13 +1592,13 @@ void DrawingML::WriteRun( Reference< XTextRange > rRun ) } Reference< XPropertySet > xPropSet( rRun, uno::UNO_QUERY ); - WriteRunProperties( xPropSet, bIsField ); + WriteRunProperties( xPropSet, bIsURLField ); mpFS->startElementNS( XML_a, XML_t, FSEND ); mpFS->writeEscaped( sText ); mpFS->endElementNS( XML_a, XML_t ); - if( sFieldType ) + if( bWriteField ) mpFS->endElementNS( XML_a, XML_fld ); else mpFS->endElementNS( XML_a, XML_r ); diff --git a/sd/qa/unit/data/pptx/hyperlinktest.pptx b/sd/qa/unit/data/pptx/hyperlinktest.pptx new file mode 100644 index 000000000000..dac61c023dd3 Binary files /dev/null and b/sd/qa/unit/data/pptx/hyperlinktest.pptx differ diff --git a/sd/qa/unit/export-tests.cxx b/sd/qa/unit/export-tests.cxx index 0bb364ed80f6..2bb3473d569b 100644 --- a/sd/qa/unit/export-tests.cxx +++ b/sd/qa/unit/export-tests.cxx @@ -61,6 +61,7 @@ #include #include #include +#include #include #include #include @@ -99,6 +100,7 @@ public: void testLineStyle(); void testCellLeftAndRightMargin(); void testRightToLeftParaghraph(); + void testTextboxWithHyperlink(); void testTableCellBorder(); void testBulletColor(); void testBulletCharAndFont(); @@ -134,6 +136,7 @@ public: CPPUNIT_TEST(testLineStyle); CPPUNIT_TEST(testCellLeftAndRightMargin); CPPUNIT_TEST(testRightToLeftParaghraph); + CPPUNIT_TEST(testTextboxWithHyperlink); CPPUNIT_TEST(testTableCellBorder); CPPUNIT_TEST(testBulletColor); CPPUNIT_TEST(testBulletCharAndFont); @@ -914,6 +917,49 @@ void SdExportTest::testRightToLeftParaghraph() xDocShRef->DoClose(); } +void SdExportTest::testTextboxWithHyperlink() +{ + ::sd::DrawDocShellRef xDocShRef = loadURL(getURLFromSrc("/sd/qa/unit/data/pptx/hyperlinktest.pptx"), PPTX); + + xDocShRef = saveAndReload( xDocShRef, PPTX ); + + uno::Reference< drawing::XDrawPagesSupplier > xDoc( + xDocShRef->GetDoc()->getUnoModel(), uno::UNO_QUERY_THROW ); + + uno::Reference< drawing::XDrawPage > xPage( + xDoc->getDrawPages()->getByIndex(0), uno::UNO_QUERY_THROW ); + + uno::Reference< beans::XPropertySet > xShape( + xPage->getByIndex(0), uno::UNO_QUERY ); + CPPUNIT_ASSERT_MESSAGE( "no shape", xShape.is() ); + + // Get first paragraph + uno::Reference xText = uno::Reference(xShape, uno::UNO_QUERY)->getText(); + CPPUNIT_ASSERT_MESSAGE( "not a text shape", xText.is() ); + uno::Reference paraEnumAccess; + paraEnumAccess.set(xText, uno::UNO_QUERY); + uno::Reference paraEnum = paraEnumAccess->createEnumeration(); + uno::Reference const xParagraph(paraEnum->nextElement(), + uno::UNO_QUERY_THROW); + + // first chunk of text + uno::Reference xRunEnumAccess(xParagraph, uno::UNO_QUERY); + uno::Reference xRunEnum = xRunEnumAccess->createEnumeration(); + uno::Reference xRun(xRunEnum->nextElement(), uno::UNO_QUERY); + uno::Reference< beans::XPropertySet > xPropSet( xRun, uno::UNO_QUERY_THROW ); + + uno::Reference xField; + xPropSet->getPropertyValue("TextField") >>= xField; + CPPUNIT_ASSERT_MESSAGE("Where is the text field?", xField.is() ); + + xPropSet.set(xField, uno::UNO_QUERY); + OUString aURL; + xPropSet->getPropertyValue("URL") >>= aURL; + CPPUNIT_ASSERT_EQUAL_MESSAGE("URLs don't match", OUString("http://www.xkcd.com/"), aURL); + + xDocShRef->DoClose(); +} + void SdExportTest::testBulletColor() { ::sd::DrawDocShellRef xDocShRef = loadURL( getURLFromSrc("/sd/qa/unit/data/pptx/bulletColor.pptx"), PPTX ); -- cgit v1.2.3