diff options
author | Samuel Mehrbrodt <Samuel.Mehrbrodt@cib.de> | 2016-11-11 12:27:46 +0100 |
---|---|---|
committer | Samuel Mehrbrodt <Samuel.Mehrbrodt@cib.de> | 2016-11-11 12:38:54 +0000 |
commit | 518e1999c4a77e6a8fb7ddf02568461d0343bb9a (patch) | |
tree | ce881743a4c1878065e6089ff68e99df21b31b05 | |
parent | a7e469a286d73440479393f33c05797621d553e8 (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.cxx | 88 | ||||
-rw-r--r-- | xmloff/source/draw/animationimport.cxx | 11 |
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; |