[Libreoffice-commits] core.git: xmloff/source

Samuel Mehrbrodt Samuel.Mehrbrodt at cib.de
Fri Nov 11 12:39:19 UTC 2016


 xmloff/source/draw/animationexport.cxx |   88 ++++++++++++++++++++++++++++++++-
 xmloff/source/draw/animationimport.cxx |   11 +++-
 2 files changed, 97 insertions(+), 2 deletions(-)

New commits:
commit 518e1999c4a77e6a8fb7ddf02568461d0343bb9a
Author: Samuel Mehrbrodt <Samuel.Mehrbrodt at cib.de>
Date:   Fri Nov 11 12:27:46 2016 +0100

    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 at cib.de>
    Tested-by: Samuel Mehrbrodt <Samuel.Mehrbrodt at cib.de>

diff --git a/xmloff/source/draw/animationexport.cxx b/xmloff/source/draw/animationexport.cxx
index 3b36471..a2aae4d 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 13e67c3..2b350ef 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;


More information about the Libreoffice-commits mailing list