From e8a54ef88dacccb9759dd394473d52b53ff1cbd7 Mon Sep 17 00:00:00 2001 From: Michael Stahl Date: Fri, 2 Dec 2011 23:54:33 +0100 Subject: add avmedia::EmbedMedia This new function is used by sc,sd,sw to embed media in the document storage. --- avmedia/Library_avmedia.mk | 1 + avmedia/inc/avmedia/mediaitem.hxx | 7 ++ avmedia/source/framework/mediaitem.cxx | 147 +++++++++++++++++++++++++++++++++ 3 files changed, 155 insertions(+) (limited to 'avmedia') diff --git a/avmedia/Library_avmedia.mk b/avmedia/Library_avmedia.mk index 9f6bd523f1ed..2c1c42f2fc5e 100644 --- a/avmedia/Library_avmedia.mk +++ b/avmedia/Library_avmedia.mk @@ -49,6 +49,7 @@ $(eval $(call gb_Library_add_defs,avmedia,\ $(eval $(call gb_Library_add_linked_libs,avmedia,\ comphelper \ + ucbhelper \ cppu \ cppuhelper \ sal \ diff --git a/avmedia/inc/avmedia/mediaitem.hxx b/avmedia/inc/avmedia/mediaitem.hxx index cf9f09b01702..a1908105e235 100644 --- a/avmedia/inc/avmedia/mediaitem.hxx +++ b/avmedia/inc/avmedia/mediaitem.hxx @@ -34,6 +34,7 @@ #include #include #include +#include #include #define AVMEDIA_SETMASK_NONE ((sal_uInt32)(0x00000000)) @@ -124,6 +125,12 @@ private: typedef ::avmedia::MediaItem avmedia_MediaItem; +bool AVMEDIA_DLLPUBLIC EmbedMedia( + ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel> + const& xModel, + ::rtl::OUString const& rSourceURL, + ::rtl::OUString & o_rEmbeddedURL); + } #endif diff --git a/avmedia/source/framework/mediaitem.cxx b/avmedia/source/framework/mediaitem.cxx index 756c869769c7..afda0ab81651 100644 --- a/avmedia/source/framework/mediaitem.cxx +++ b/avmedia/source/framework/mediaitem.cxx @@ -29,6 +29,22 @@ #include #include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include + using namespace ::com::sun::star; namespace avmedia @@ -342,6 +358,137 @@ void MediaItem::setZoom( ::com::sun::star::media::ZoomLevel eZoom ) return m_pImpl->m_eZoom; } +//------------------------------------------------------------------------ + +static ::rtl::OUString lcl_GetFilename(::rtl::OUString const& rSourceURL) +{ + uno::Reference const xUriFactory( + ::comphelper::createProcessComponent( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.uri.UriReferenceFactory"))), + uno::UNO_QUERY_THROW); + + uno::Reference const xSourceURI( + xUriFactory->parse(rSourceURL), uno::UNO_SET_THROW); + + ::rtl::OUString filename; + { + sal_Int32 const nSegments(xSourceURI->getPathSegmentCount()); + if (0 < nSegments) + { + filename = xSourceURI->getPathSegment(nSegments - 1); + } + } + if (!::comphelper::OStorageHelper::IsValidZipEntryFileName( + filename, false) || !filename.getLength()) + { + filename = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("media")); + } + return filename; +} + +static uno::Reference +lcl_CreateStream(uno::Reference const& xStorage, + ::rtl::OUString const& rFilename) +{ + ::rtl::OUString filename(rFilename); + + if (xStorage->hasByName(filename)) + { + ::rtl::OUString basename; + ::rtl::OUString suffix; + sal_Int32 const nIndex(rFilename.lastIndexOf(sal_Unicode('.'))); + if (0 < nIndex) + { + basename = rFilename.copy(0, nIndex); + suffix = rFilename.copy(nIndex); + } + int count(0); // sigh... try to generate non-existent name + do + { + ++count; + filename = basename + ::rtl::OUString::valueOf(count) + suffix; + } + while (xStorage->hasByName(filename)); + } + + uno::Reference const xStream( + xStorage->openStreamElement(filename, + embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE), + uno::UNO_SET_THROW); + uno::Reference< beans::XPropertySet > const xStreamProps(xStream, + uno::UNO_QUERY); + if (xStreamProps.is()) { // this is NOT supported in FileSystemStorage + xStreamProps->setPropertyValue( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MediaType")), + uno::makeAny(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( + //FIXME how to detect real media type? + //but currently xmloff has this one hardcoded anyway... + "application/vnd.sun.star.media")))); + xStreamProps->setPropertyValue( // turn off compression + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Compressed")), + uno::makeAny(sal_False)); + } + return xStream; +} + +bool EmbedMedia(uno::Reference const& xModel, + ::rtl::OUString const& rSourceURL, ::rtl::OUString & o_rEmbeddedURL) +{ + try + { + ::ucbhelper::Content sourceContent(rSourceURL, + uno::Reference()); + + uno::Reference const xSBD(xModel, + uno::UNO_QUERY_THROW); + uno::Reference const xStorage( + xSBD->getDocumentStorage(), uno::UNO_QUERY_THROW); + + ::rtl::OUString const media(RTL_CONSTASCII_USTRINGPARAM("Media")); + uno::Reference const xSubStorage( + xStorage->openStorageElement(media, embed::ElementModes::WRITE)); + + ::rtl::OUString filename(lcl_GetFilename(rSourceURL)); + + uno::Reference const xStream( + lcl_CreateStream(xSubStorage, filename), uno::UNO_SET_THROW); + uno::Reference const xOutStream( + xStream->getOutputStream(), uno::UNO_SET_THROW); + + if (!sourceContent.openStream(xOutStream)) // copy file to storage + { + SAL_INFO("avmedia", "openStream to storage failed"); + return false; + } + + uno::Reference const xSubTransaction( + xSubStorage, uno::UNO_QUERY); + if (xSubTransaction.is()) { + xSubTransaction->commit(); + } + uno::Reference const xTransaction( + xStorage, uno::UNO_QUERY); + if (xTransaction.is()) { + xTransaction->commit(); + } + + ::rtl::OUStringBuffer buf(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( + "vnd.sun.star.Package:"))); + buf.append(media); + buf.append(sal_Unicode('/')); + buf.append(filename); + o_rEmbeddedURL = buf.makeStringAndClear(); + return true; + } + catch (uno::Exception const& e) + { + SAL_WARN("avmedia", + "Exception while trying to embed media"); + } + return false; +} + } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ -- cgit