summaryrefslogtreecommitdiff
path: root/avmedia
diff options
context:
space:
mode:
authorMichael Stahl <mstahl@redhat.com>2011-12-02 23:54:33 +0100
committerMichael Stahl <mstahl@redhat.com>2011-12-03 00:48:15 +0100
commite8a54ef88dacccb9759dd394473d52b53ff1cbd7 (patch)
tree6b6a18d6d11b365a46de3359e49f8ea2b2fd562e /avmedia
parent51ea69880ca32220fa1c6b3e95c8916e3409184c (diff)
add avmedia::EmbedMedia
This new function is used by sc,sd,sw to embed media in the document storage.
Diffstat (limited to 'avmedia')
-rw-r--r--avmedia/Library_avmedia.mk1
-rw-r--r--avmedia/inc/avmedia/mediaitem.hxx7
-rw-r--r--avmedia/source/framework/mediaitem.cxx147
3 files changed, 155 insertions, 0 deletions
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 <tools/rtti.hxx>
#include <svl/poolitem.hxx>
#include <com/sun/star/media/ZoomLevel.hpp>
+#include <com/sun/star/frame/XModel.hpp>
#include <avmedia/avmediadllapi.h>
#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 <avmedia/mediaitem.hxx>
#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/embed/ElementModes.hpp>
+#include <com/sun/star/embed/XStorage.hpp>
+#include <com/sun/star/embed/XTransactedObject.hpp>
+#include <com/sun/star/document/XStorageBasedDocument.hpp>
+#include <com/sun/star/ucb/XCommandEnvironment.hpp>
+#include <com/sun/star/uri/XUriReference.hpp>
+#include <com/sun/star/uri/XUriReferenceFactory.hpp>
+
+#include <rtl/ustrbuf.hxx>
+
+#include <ucbhelper/content.hxx>
+
+#include <comphelper/processfactory.hxx>
+#include <comphelper/storagehelper.hxx>
+
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<uri::XUriReferenceFactory> const xUriFactory(
+ ::comphelper::createProcessComponent(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.uri.UriReferenceFactory"))),
+ uno::UNO_QUERY_THROW);
+
+ uno::Reference<uri::XUriReference> 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<io::XStream>
+lcl_CreateStream(uno::Reference<embed::XStorage> 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<io::XStream> 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<frame::XModel> const& xModel,
+ ::rtl::OUString const& rSourceURL, ::rtl::OUString & o_rEmbeddedURL)
+{
+ try
+ {
+ ::ucbhelper::Content sourceContent(rSourceURL,
+ uno::Reference<ucb::XCommandEnvironment>());
+
+ uno::Reference<document::XStorageBasedDocument> const xSBD(xModel,
+ uno::UNO_QUERY_THROW);
+ uno::Reference<embed::XStorage> const xStorage(
+ xSBD->getDocumentStorage(), uno::UNO_QUERY_THROW);
+
+ ::rtl::OUString const media(RTL_CONSTASCII_USTRINGPARAM("Media"));
+ uno::Reference<embed::XStorage> const xSubStorage(
+ xStorage->openStorageElement(media, embed::ElementModes::WRITE));
+
+ ::rtl::OUString filename(lcl_GetFilename(rSourceURL));
+
+ uno::Reference<io::XStream> const xStream(
+ lcl_CreateStream(xSubStorage, filename), uno::UNO_SET_THROW);
+ uno::Reference<io::XOutputStream> 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<embed::XTransactedObject> const xSubTransaction(
+ xSubStorage, uno::UNO_QUERY);
+ if (xSubTransaction.is()) {
+ xSubTransaction->commit();
+ }
+ uno::Reference<embed::XTransactedObject> 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: */