summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Stahl <mstahl@redhat.com>2014-10-13 19:01:12 +0200
committerMichael Stahl <mstahl@redhat.com>2014-10-13 19:23:41 +0200
commit220a3686921847b71dc72b69ce98ba260b951610 (patch)
treec10fc83c4abc99dd1685a7542f954ce9f6f3388c
parent8b7f96d257724656ac4a4303b17285be2ed13886 (diff)
oox: refactor embedded media import
Currently the oox import creates a temp file and leaks it, and there is no way to clean it up afterwards. Unfortunately it turns out that SdrModel has no way to access the imported OOXML storage, so add a really ugly hack to get the embedded media into the SdrMediaObj by setting both MediaURL and PrivateStream properties (currently oox really wants to set the properties in alphabetical order too...) Change-Id: I5a235fbeb08e7bc17faf066de52b94867e9a79a2
-rw-r--r--include/svx/svdomedia.hxx1
-rw-r--r--oox/inc/drawingml/graphicproperties.hxx5
-rw-r--r--oox/source/drawingml/fillproperties.cxx8
-rw-r--r--oox/source/drawingml/graphicshapecontext.cxx32
-rw-r--r--oox/source/drawingml/shape.cxx2
-rw-r--r--sd/qa/unit/import-tests.cxx2
-rw-r--r--svx/source/svdraw/svdomedia.cxx76
-rw-r--r--svx/source/unodraw/unoprov.cxx2
-rw-r--r--svx/source/unodraw/unoshap4.cxx26
9 files changed, 111 insertions, 43 deletions
diff --git a/include/svx/svdomedia.hxx b/include/svx/svdomedia.hxx
index b8c4c672927e..224f11742cdc 100644
--- a/include/svx/svdomedia.hxx
+++ b/include/svx/svdomedia.hxx
@@ -72,6 +72,7 @@ public:
getSnapshot();
::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream>
GetInputStream();
+ void SetInputStream(css::uno::Reference<css::io::XInputStream> const&);
protected:
diff --git a/oox/inc/drawingml/graphicproperties.hxx b/oox/inc/drawingml/graphicproperties.hxx
index 27644cd683d6..b89d3b95a80f 100644
--- a/oox/inc/drawingml/graphicproperties.hxx
+++ b/oox/inc/drawingml/graphicproperties.hxx
@@ -22,6 +22,8 @@
#include <sal/config.h>
+#include <com/sun/star/io/XInputStream.hpp>
+
#include <oox/drawingml/fillproperties.hxx>
#include <oox/helper/helper.hxx>
@@ -36,7 +38,8 @@ namespace drawingml {
struct GraphicProperties
{
BlipFillProperties maBlipProps; ///< Properties for the graphic.
- OUString msMediaTempFile; ///< Audio/Video temporary file.
+ OUString m_sMediaPackageURL; ///< Audio/Video URL.
+ css::uno::Reference<css::io::XInputStream> m_xMediaStream; ///< Audio/Video input stream.
/** Overwrites all members that are explicitly set in rSourceProps. */
void assignUsed( const GraphicProperties& rSourceProps );
diff --git a/oox/source/drawingml/fillproperties.cxx b/oox/source/drawingml/fillproperties.cxx
index 80e2c25109da..fd45658d63e2 100644
--- a/oox/source/drawingml/fillproperties.cxx
+++ b/oox/source/drawingml/fillproperties.cxx
@@ -753,8 +753,12 @@ void GraphicProperties::pushToPropMap( PropertyMap& rPropMap, const GraphicHelpe
rPropMap.setProperty(PROP_AdjustContrast, nContrast);
// Media content
- if( !msMediaTempFile.isEmpty() )
- rPropMap.setProperty(PROP_MediaURL, msMediaTempFile);
+ assert(m_xMediaStream.is() != m_sMediaPackageURL.isEmpty());
+ if (m_xMediaStream.is() && !m_sMediaPackageURL.isEmpty())
+ {
+ rPropMap.setProperty(PROP_PrivateStream, m_xMediaStream);
+ rPropMap.setProperty(PROP_MediaURL, m_sMediaPackageURL);
+ }
}
bool ArtisticEffectProperties::isEmpty() const
diff --git a/oox/source/drawingml/graphicshapecontext.cxx b/oox/source/drawingml/graphicshapecontext.cxx
index a2eac1638308..7c82395f822d 100644
--- a/oox/source/drawingml/graphicshapecontext.cxx
+++ b/oox/source/drawingml/graphicshapecontext.cxx
@@ -49,20 +49,19 @@ using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::xml::sax;
using namespace ::oox::core;
-static OUString lcl_CopyToTempFile(const OUString& rStream, const oox::core::XmlFilterBase& rFilter)
+static uno::Reference<io::XInputStream>
+lcl_GetMediaStream(const OUString& rStream, const oox::core::XmlFilterBase& rFilter)
{
if (rStream.isEmpty())
- return OUString();
+ return nullptr;
Reference< XInputStream > xInStrm( rFilter.openInputStream(rStream), UNO_SET_THROW );
- Reference< XTempFile > xTempFile( TempFile::create(rFilter.getComponentContext()) );
- Reference< XOutputStream > xOutStrm( xTempFile->getOutputStream(), UNO_SET_THROW );
- oox::BinaryXOutputStream aOutStrm( xOutStrm, false );
- oox::BinaryXInputStream aInStrm( xInStrm, false );
- aInStrm.copyToStream( aOutStrm );
-
- xTempFile->setRemoveFile( false );
- return xTempFile->getUri();
+ return xInStrm;
+}
+
+static OUString lcl_GetMediaReference(const OUString& rStream)
+{
+ return rStream.isEmpty() ? OUString() : "vnd.sun.star.Package:" + rStream;
}
namespace oox {
@@ -86,8 +85,11 @@ ContextHandlerRef GraphicShapeContext::onCreateContext( sal_Int32 aElementToken,
return new BlipFillContext( *this, rAttribs, mpShapePtr->getGraphicProperties().maBlipProps );
case XML_wavAudioFile:
{
- mpShapePtr->getGraphicProperties().msMediaTempFile =
- lcl_CopyToTempFile( getEmbeddedWAVAudioFile(getRelations(), rAttribs), getFilter() );
+ OUString const path(getEmbeddedWAVAudioFile(getRelations(), rAttribs));
+ mpShapePtr->getGraphicProperties().m_xMediaStream =
+ lcl_GetMediaStream(path, getFilter());
+ mpShapePtr->getGraphicProperties().m_sMediaPackageURL =
+ lcl_GetMediaReference(path);
}
break;
case XML_audioFile:
@@ -95,8 +97,10 @@ ContextHandlerRef GraphicShapeContext::onCreateContext( sal_Int32 aElementToken,
{
OUString rPath = getRelations().getFragmentPathFromRelId(
rAttribs.getString(R_TOKEN(link)).get() );
- mpShapePtr->getGraphicProperties().msMediaTempFile =
- lcl_CopyToTempFile( rPath, getFilter() );
+ mpShapePtr->getGraphicProperties().m_xMediaStream =
+ lcl_GetMediaStream(rPath, getFilter());
+ mpShapePtr->getGraphicProperties().m_sMediaPackageURL =
+ lcl_GetMediaReference(rPath);
}
break;
}
diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx
index 1aa23f78a08e..b635ed404706 100644
--- a/oox/source/drawingml/shape.cxx
+++ b/oox/source/drawingml/shape.cxx
@@ -405,7 +405,7 @@ Reference< XShape > Shape::createAndInsert(
OUString aServiceName;
if( rServiceName == "com.sun.star.drawing.GraphicObjectShape" &&
- mpGraphicPropertiesPtr && !mpGraphicPropertiesPtr->msMediaTempFile.isEmpty() )
+ mpGraphicPropertiesPtr && !mpGraphicPropertiesPtr->m_sMediaPackageURL.isEmpty())
{
aServiceName = finalizeServiceName( rFilterBase, "com.sun.star.presentation.MediaShape", aShapeRectHmm );
bIsEmbMedia = true;
diff --git a/sd/qa/unit/import-tests.cxx b/sd/qa/unit/import-tests.cxx
index 21448253b39e..141db84478c1 100644
--- a/sd/qa/unit/import-tests.cxx
+++ b/sd/qa/unit/import-tests.cxx
@@ -808,6 +808,7 @@ void SdImportTest::testBnc591147()
OUString sVideoURL("emptyURL");
bool bSucess = xPropSet->getPropertyValue("MediaURL") >>= sVideoURL;
CPPUNIT_ASSERT_MESSAGE( "MediaURL property is not set", bSucess );
+ CPPUNIT_ASSERT_MESSAGE("MediaURL is empty", !sVideoURL.isEmpty());
// Second page has audio file inserted
xPage.set( xDoc->getDrawPages()->getByIndex(1), uno::UNO_QUERY_THROW );
@@ -818,6 +819,7 @@ void SdImportTest::testBnc591147()
OUString sAudioURL("emptyURL");
bSucess = xPropSet->getPropertyValue("MediaURL") >>= sAudioURL;
CPPUNIT_ASSERT_MESSAGE( "MediaURL property is not set", bSucess );
+ CPPUNIT_ASSERT_MESSAGE("MediaURL is empty", !sAudioURL.isEmpty());
CPPUNIT_ASSERT_MESSAGE( "sAudioURL and sVideoURL should not be equal", sAudioURL != sVideoURL );
diff --git a/svx/source/svdraw/svdomedia.cxx b/svx/source/svdraw/svdomedia.cxx
index e34a7285c90e..da5860b9c91f 100644
--- a/svx/source/svdraw/svdomedia.cxx
+++ b/svx/source/svdraw/svdomedia.cxx
@@ -66,6 +66,7 @@ struct SdrMediaObj::Impl
::avmedia::MediaItem m_MediaProperties;
::boost::shared_ptr< MediaTempFile > m_pTempFile;
uno::Reference< graphic::XGraphic > m_xCachedSnapshot;
+ OUString m_LastFailedPkgURL;
};
TYPEINIT1( SdrMediaObj, SdrRectObj );
@@ -326,6 +327,53 @@ static bool lcl_HandleJsonPackageURL(
}
#endif
+static bool lcl_CopyToTempFile(
+ uno::Reference<io::XInputStream> const& xInStream,
+ OUString & o_rTempFileURL)
+{
+ OUString tempFileURL;
+ ::osl::FileBase::RC const err =
+ ::osl::FileBase::createTempFile(0, 0, & tempFileURL);
+ if (::osl::FileBase::E_None != err)
+ {
+ SAL_INFO("svx", "cannot create temp file");
+ return false;
+ }
+
+ try
+ {
+ ::ucbhelper::Content tempContent(tempFileURL,
+ uno::Reference<ucb::XCommandEnvironment>(),
+ comphelper::getProcessComponentContext());
+ tempContent.writeStream(xInStream, true); // copy stream to file
+ }
+ catch (uno::Exception const& e)
+ {
+ SAL_WARN("svx", "exception: '" << e.Message << "'");
+ return false;
+ }
+ o_rTempFileURL = tempFileURL;
+ return true;
+}
+
+void SdrMediaObj::SetInputStream(uno::Reference<io::XInputStream> const& xStream)
+{
+ if (m_pImpl->m_pTempFile || m_pImpl->m_LastFailedPkgURL.isEmpty())
+ {
+ SAL_WARN("svx", "this is only intended for embedded media");
+ return;
+ }
+ OUString tempFileURL;
+ bool const bSuccess = lcl_CopyToTempFile(xStream, tempFileURL);
+ if (bSuccess)
+ {
+ m_pImpl->m_pTempFile.reset(new MediaTempFile(tempFileURL));
+ m_pImpl->m_MediaProperties.setURL(
+ m_pImpl->m_LastFailedPkgURL, tempFileURL, "");
+ }
+ m_pImpl->m_LastFailedPkgURL = ""; // once only
+}
+
/// copy a stream from XStorage to temp file
static bool lcl_HandlePackageURL(
OUString const & rURL,
@@ -357,30 +405,7 @@ static bool lcl_HandlePackageURL(
SAL_WARN("svx", "no stream?");
return false;
}
-
- OUString tempFileURL;
- ::osl::FileBase::RC const err =
- ::osl::FileBase::createTempFile(0, 0, & tempFileURL);
- if (::osl::FileBase::E_None != err)
- {
- SAL_INFO("svx", "cannot create temp file");
- return false;
- }
-
- try
- {
- ::ucbhelper::Content tempContent(tempFileURL,
- uno::Reference<ucb::XCommandEnvironment>(),
- comphelper::getProcessComponentContext());
- tempContent.writeStream(xInStream, true); // copy stream to file
- }
- catch (uno::Exception const& e)
- {
- SAL_WARN("svx", "exception: '" << e.Message << "'");
- return false;
- }
- o_rTempFileURL = tempFileURL;
- return true;
+ return lcl_CopyToTempFile(xInStream, o_rTempFileURL);
}
void SdrMediaObj::mediaPropertiesChanged( const ::avmedia::MediaItem& rNewProperties )
@@ -420,6 +445,9 @@ void SdrMediaObj::mediaPropertiesChanged( const ::avmedia::MediaItem& rNewProper
{
m_pImpl->m_pTempFile.reset();
m_pImpl->m_MediaProperties.setURL("", "", "");
+ // UGLY: oox import also gets here, because unlike ODF
+ // getDocumentStorage() is not the imported file...
+ m_pImpl->m_LastFailedPkgURL = url;
}
}
else
diff --git a/svx/source/unodraw/unoprov.cxx b/svx/source/unodraw/unoprov.cxx
index 655fa27d0089..92460cd80beb 100644
--- a/svx/source/unodraw/unoprov.cxx
+++ b/svx/source/unodraw/unoprov.cxx
@@ -730,7 +730,7 @@ SfxItemPropertyMapEntry const * ImplGetSvxMediaShapePropertyMap()
// #i68101#
{ OUString(UNO_NAME_MISC_OBJ_TITLE), OWN_ATTR_MISC_OBJ_TITLE , cppu::UnoType<OUString>::get(), 0, 0},
{ OUString(UNO_NAME_MISC_OBJ_DESCRIPTION), OWN_ATTR_MISC_OBJ_DESCRIPTION , cppu::UnoType<OUString>::get(), 0, 0},
- {OUString("PrivateStream"), OWN_ATTR_MEDIA_STREAM, cppu::UnoType<css::io::XInputStream>::get(), ::com::sun::star::beans::PropertyAttribute::READONLY, 0},
+ {OUString("PrivateStream"), OWN_ATTR_MEDIA_STREAM, cppu::UnoType<css::io::XInputStream>::get(), 0, 0},
{OUString("PrivateTempFileURL"), OWN_ATTR_MEDIA_TEMPFILEURL, cppu::UnoType<OUString>::get(), ::com::sun::star::beans::PropertyAttribute::READONLY, 0},
{ OUString("MediaMimeType"), OWN_ATTR_MEDIA_MIMETYPE, cppu::UnoType<OUString>::get(), 0, 0},
{ OUString("FallbackGraphic"), OWN_ATTR_FALLBACK_GRAPHIC, cppu::UnoType<css::graphic::XGraphic>::get(), ::com::sun::star::beans::PropertyAttribute::READONLY, 0},
diff --git a/svx/source/unodraw/unoshap4.cxx b/svx/source/unodraw/unoshap4.cxx
index 3fac4a0d2f7b..b78d3629b5e0 100644
--- a/svx/source/unodraw/unoshap4.cxx
+++ b/svx/source/unodraw/unoshap4.cxx
@@ -808,6 +808,7 @@ SvxMediaShape::~SvxMediaShape() throw()
bool SvxMediaShape::setPropertyValueImpl( const OUString& rName, const SfxItemPropertySimpleEntry* pProperty, const ::com::sun::star::uno::Any& rValue ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
{
if( ((pProperty->nWID >= OWN_ATTR_MEDIA_URL) && (pProperty->nWID <= OWN_ATTR_MEDIA_ZOOM))
+ || (pProperty->nWID == OWN_ATTR_MEDIA_STREAM)
|| (pProperty->nWID == OWN_ATTR_MEDIA_MIMETYPE) )
{
SdrMediaObj* pMedia = static_cast< SdrMediaObj* >( mpObj.get() );
@@ -886,6 +887,31 @@ bool SvxMediaShape::setPropertyValueImpl( const OUString& rName, const SfxItemPr
}
break;
+ case OWN_ATTR_MEDIA_STREAM:
+ try
+ {
+ uno::Reference<io::XInputStream> xStream;
+ if (rValue >>= xStream)
+ {
+ pMedia->SetInputStream(xStream);
+ }
+ }
+ catch (const css::ucb::ContentCreationException& e)
+ {
+ throw css::lang::WrappedTargetException(
+ "ContentCreationException Setting InputStream!",
+ static_cast<OWeakObject *>(this),
+ makeAny(e));
+ }
+ catch (const css::ucb::CommandFailedException& e)
+ {
+ throw css::lang::WrappedTargetException(
+ "CommandFailedException Setting InputStream!",
+ static_cast<OWeakObject *>(this),
+ makeAny(e));
+ }
+ break;
+
default:
OSL_FAIL("SvxMediaShape::setPropertyValueImpl(), unknown argument!");
}