diff options
author | Michael Stahl <mstahl@redhat.com> | 2011-12-03 00:00:08 +0100 |
---|---|---|
committer | Michael Stahl <mstahl@redhat.com> | 2011-12-03 00:48:15 +0100 |
commit | 116ad02ae89a0036a223ef943352587119a47f65 (patch) | |
tree | cc00bbc8d6e6b644c5f1becff615aff9fbc236d8 | |
parent | e8a54ef88dacccb9759dd394473d52b53ff1cbd7 (diff) |
xmloff: load and store embedded media
-rw-r--r-- | xmloff/source/draw/shapeexport2.cxx | 94 | ||||
-rw-r--r-- | xmloff/source/draw/ximpshap.cxx | 31 |
2 files changed, 111 insertions, 14 deletions
diff --git a/xmloff/source/draw/shapeexport2.cxx b/xmloff/source/draw/shapeexport2.cxx index 297bff39fdfc..5ae32238587b 100644 --- a/xmloff/source/draw/shapeexport2.cxx +++ b/xmloff/source/draw/shapeexport2.cxx @@ -35,7 +35,10 @@ #include <com/sun/star/drawing/XControlShape.hpp> #include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp> #include <com/sun/star/document/XEventsSupplier.hpp> +#include <com/sun/star/document/XStorageBasedDocument.hpp> #include <com/sun/star/drawing/HomogenMatrix3.hpp> +#include <com/sun/star/embed/ElementModes.hpp> +#include <com/sun/star/embed/XTransactedObject.hpp> #include <com/sun/star/media/ZoomLevel.hpp> #include <sax/tools/converter.hxx> @@ -1944,6 +1947,93 @@ void XMLShapeExport::ImpExportPluginShape( ////////////////////////////////////////////////////////////////////////////// +/** 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 (0 == dir.getLength()) + { + 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 ::rtl::OUString +lcl_StoreMediaAndGetURL(SvXMLExport & rExport, ::rtl::OUString const& rURL) +{ + if (0 == rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( + rURL.getStr(), rURL.getLength(), + s_PkgScheme, SAL_N_ELEMENTS(s_PkgScheme) - 1)) + { + 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); + + ::rtl::OUString const 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"); + } + return ::rtl::OUString(); + } + else + { + return rExport.GetRelativeReference(rURL); // linked + } +} + void XMLShapeExport::ImpExportMediaShape( const uno::Reference< drawing::XShape >& xShape, XmlShapeType eShapeType, sal_Int32 nFeatures, com::sun::star::awt::Point* pRefPoint) @@ -1964,7 +2054,9 @@ void XMLShapeExport::ImpExportMediaShape( // export media url OUString aMediaURL; xPropSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaURL" ) ) ) >>= aMediaURL; - mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_HREF, GetExport().GetRelativeReference( aMediaURL ) ); + OUString const persistentURL = + lcl_StoreMediaAndGetURL(GetExport(), aMediaURL); + mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_HREF, persistentURL ); mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE ); mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_SHOW, XML_EMBED ); mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_ACTUATE, XML_ONLOAD ); diff --git a/xmloff/source/draw/ximpshap.cxx b/xmloff/source/draw/ximpshap.cxx index fec93a9ff922..24824d91ec7c 100644 --- a/xmloff/source/draw/ximpshap.cxx +++ b/xmloff/source/draw/ximpshap.cxx @@ -3047,6 +3047,20 @@ void SdXMLPluginShapeContext::StartElement( const ::com::sun::star::uno::Referen } } +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; + } + else + { + return rImport.GetAbsoluteReference(rURL); + } +} + // this is called from the parent group for each unparsed attribute in the attribute list void SdXMLPluginShapeContext::processAttribute( sal_uInt16 nPrefix, const ::rtl::OUString& rLocalName, const ::rtl::OUString& rValue ) { @@ -3062,7 +3076,7 @@ void SdXMLPluginShapeContext::processAttribute( sal_uInt16 nPrefix, const ::rtl: case XML_NAMESPACE_XLINK: if( IsXMLToken( rLocalName, XML_HREF ) ) { - maHref = GetImport().GetAbsoluteReference(rValue); + maHref = lcl_GetMediaReference(GetImport(), rValue); return; } break; @@ -3116,18 +3130,9 @@ void SdXMLPluginShapeContext::EndElement() else { // in case we have a media object - - OUString sTempRef; - - // check for package URL - if( GetImport().IsPackageURL( maHref ) ) - { - sTempRef = OUString( RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.Package:" ) ); - } - - sTempRef += maHref; - - xProps->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaURL" ) ), uno::makeAny( sTempRef ) ); + xProps->setPropertyValue( + OUString(RTL_CONSTASCII_USTRINGPARAM("MediaURL")), + uno::makeAny(maHref)); for( sal_Int32 nParam = 0; nParam < maParams.getLength(); ++nParam ) { |