summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Mehrbrodt <Samuel.Mehrbrodt@cib.de>2016-11-11 12:27:46 +0100
committerSamuel Mehrbrodt <Samuel.Mehrbrodt@cib.de>2016-11-11 12:38:54 +0000
commit518e1999c4a77e6a8fb7ddf02568461d0343bb9a (patch)
treece881743a4c1878065e6089ff68e99df21b31b05
parenta7e469a286d73440479393f33c05797621d553e8 (diff)
tdf#67544 Embed slide transition sound in the presentation
This is only the filter part, UI is still missing Change-Id: Ic2ee0196c6b501abb244397cb14bb70626b45ae8 Reviewed-on: https://gerrit.libreoffice.org/30772 Reviewed-by: Samuel Mehrbrodt <Samuel.Mehrbrodt@cib.de> Tested-by: Samuel Mehrbrodt <Samuel.Mehrbrodt@cib.de>
-rw-r--r--xmloff/source/draw/animationexport.cxx88
-rw-r--r--xmloff/source/draw/animationimport.cxx11
2 files changed, 97 insertions, 2 deletions
diff --git a/xmloff/source/draw/animationexport.cxx b/xmloff/source/draw/animationexport.cxx
index 3b36471bafc4..a2aae4d72e10 100644
--- a/xmloff/source/draw/animationexport.cxx
+++ b/xmloff/source/draw/animationexport.cxx
@@ -42,6 +42,8 @@
#include <com/sun/star/animations/ValuePair.hpp>
#include <com/sun/star/container/XEnumerationAccess.hpp>
#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/document/XStorageBasedDocument.hpp>
+#include <com/sun/star/embed/XTransactedObject.hpp>
#include <com/sun/star/presentation/EffectNodeType.hpp>
#include <com/sun/star/presentation/EffectPresetClass.hpp>
#include <com/sun/star/presentation/ParagraphTarget.hpp>
@@ -67,8 +69,10 @@
#include "animations.hxx"
#include <xmloff/animationexport.hxx>
+#include <comphelper/storagehelper.hxx>
+using namespace css;
using namespace ::std;
using namespace ::cppu;
using namespace ::com::sun::star::animations;
@@ -554,6 +558,87 @@ AnimationsExporterImpl::~AnimationsExporterImpl()
{
}
+
+/** split a uri hierarchy into first segment and rest */
+static bool splitPath(::rtl::OUString const & i_rPath,
+ ::rtl::OUString & o_rDir, ::rtl::OUString& o_rRest)
+{
+ const sal_Int32 idx(i_rPath.indexOf(static_cast<sal_Unicode>('/')));
+ if (idx < 0 || idx >= i_rPath.getLength()) {
+ o_rDir = ::rtl::OUString();
+ o_rRest = i_rPath;
+ return true;
+ } else if (idx == 0 || idx == i_rPath.getLength() - 1) {
+ // input must not start or end with '/'
+ return false;
+ } else {
+ o_rDir = (i_rPath.copy(0, idx));
+ o_rRest = (i_rPath.copy(idx+1));
+ return true;
+ }
+}
+
+static void lcl_CopyStream(
+ uno::Reference<embed::XStorage> const& xSource,
+ uno::Reference<embed::XStorage> const& xTarget,
+ ::rtl::OUString const& rPath)
+{
+ ::rtl::OUString dir;
+ ::rtl::OUString rest;
+ if (!splitPath(rPath, dir, rest))
+ throw uno::RuntimeException();
+
+ if (dir.getLength() == 0)
+ xSource->copyElementTo(rPath, xTarget, rPath);
+ else
+ {
+ uno::Reference<embed::XStorage> const xSubSource(
+ xSource->openStorageElement(dir, embed::ElementModes::READ));
+ uno::Reference<embed::XStorage> const xSubTarget(
+ xTarget->openStorageElement(dir, embed::ElementModes::WRITE));
+ lcl_CopyStream(xSubSource, xSubTarget, rest);
+ }
+ uno::Reference<embed::XTransactedObject> const xTransaction(xTarget, uno::UNO_QUERY);
+ if (xTransaction.is())
+ xTransaction->commit();
+}
+
+static char const s_PkgScheme[] = "vnd.sun.star.Package:";
+
+static OUString lcl_StoreMediaAndGetURL(SvXMLExport & rExport, OUString const& rURL)
+{
+ OUString urlPath;
+ if (rURL.startsWithIgnoreAsciiCase(s_PkgScheme, &urlPath))
+ {
+ try // video is embedded
+ {
+ // copy the media stream from document storage to target storage
+ // (not sure if this is the best way to store these?)
+ uno::Reference<document::XStorageBasedDocument> const xSBD(
+ rExport.GetModel(), uno::UNO_QUERY_THROW);
+ uno::Reference<embed::XStorage> const xSource(
+ xSBD->getDocumentStorage(), uno::UNO_QUERY_THROW);
+ uno::Reference<embed::XStorage> const xTarget(
+ rExport.GetTargetStorage(), uno::UNO_QUERY_THROW);
+
+ urlPath = rURL.copy(SAL_N_ELEMENTS(s_PkgScheme)-1);
+
+ lcl_CopyStream(xSource, xTarget, urlPath);
+
+ return urlPath;
+ }
+ catch (uno::Exception const& e)
+ {
+ SAL_INFO("xmloff", "exception while storing embedded media: '" << e.Message << "'");
+ }
+ return OUString();
+ }
+ else
+ {
+ return rExport.GetRelativeReference(rURL); // linked
+ }
+}
+
void AnimationsExporterImpl::exportTransitionNode()
{
if( mbHasTransition && mxPageProps.is() )
@@ -625,7 +710,8 @@ void AnimationsExporterImpl::exportTransitionNode()
}
else if( !sSoundURL.isEmpty())
{
- mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, mrExport.GetRelativeReference( sSoundURL ) );
+ sSoundURL = lcl_StoreMediaAndGetURL(mrExport, sSoundURL);
+ mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, sSoundURL );
bool bLoopSound = false;
mxPageProps->getPropertyValue("LoopSound") >>= bLoopSound;
diff --git a/xmloff/source/draw/animationimport.cxx b/xmloff/source/draw/animationimport.cxx
index 13e67c357b80..2b350ef379f0 100644
--- a/xmloff/source/draw/animationimport.cxx
+++ b/xmloff/source/draw/animationimport.cxx
@@ -101,6 +101,15 @@ OUString SAL_CALL AnimationsImport_getImplementationName() throw()
return OUString( "xmloff::AnimationsImport" );
}
+static ::rtl::OUString
+lcl_GetMediaReference(SvXMLImport const& rImport, ::rtl::OUString const& rURL)
+{
+ if (rImport.IsPackageURL(rURL))
+ return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("vnd.sun.star.Package:")) + rURL;
+
+ return rImport.GetAbsoluteReference(rURL);
+}
+
namespace xmloff
{
@@ -860,7 +869,7 @@ void AnimationNodeContext::init_node( const css::uno::Reference< css::xml::sax:
if( nNodeType == AnimationNodeType::AUDIO )
{
Reference< XAudio > xAudio( mxNode, UNO_QUERY_THROW );
- xAudio->setSource( makeAny( GetImport().GetAbsoluteReference( rValue ) ) );
+ xAudio->setSource( makeAny(lcl_GetMediaReference(GetImport(), rValue)) );
break;
}
SAL_FALLTHROUGH;