diff options
author | Michael Stahl <mstahl@redhat.com> | 2011-12-06 04:36:22 +0100 |
---|---|---|
committer | Michael Stahl <mstahl@redhat.com> | 2011-12-06 04:36:22 +0100 |
commit | 431604f9fa603a7acf67985c9e4851f37d9cd580 (patch) | |
tree | 2dbbe2e40af935229dbc8f2738dc446ab18a93b8 /svx | |
parent | f3c19f8263f3352ce4efff0965f8000d8347f6a5 (diff) |
refactor media embedding completely:
Do the tempfile handling in SdrMediaObj, not in the window;
this has the advantage that it works even in the presence of clipboard
documents without SfxBaseModels and thus without storage (sc, sw).
The SdrMediaObj instances share ownership of a temp file.
Diffstat (limited to 'svx')
-rw-r--r-- | svx/inc/svx/svdomedia.hxx | 19 | ||||
-rw-r--r-- | svx/source/svdraw/svdomedia.cxx | 209 | ||||
-rw-r--r-- | svx/source/unodraw/unoprov.cxx | 1 | ||||
-rw-r--r-- | svx/source/unodraw/unoshap4.cxx | 12 |
4 files changed, 160 insertions, 81 deletions
diff --git a/svx/inc/svx/svdomedia.hxx b/svx/inc/svx/svdomedia.hxx index bc832c0de11e..e3e2f4248877 100644 --- a/svx/inc/svx/svdomedia.hxx +++ b/svx/inc/svx/svdomedia.hxx @@ -26,8 +26,8 @@ * ************************************************************************/ -#ifndef _SVDOMEDIA_HXX -#define _SVDOMEDIA_HXX +#ifndef SVDOMEDIA_HXX +#define SVDOMEDIA_HXX #include <svx/svdorect.hxx> #include <avmedia/mediaitem.hxx> @@ -54,8 +54,6 @@ public: virtual ~SdrMediaObj(); - virtual void SetModel(SdrModel* pNewModel); - virtual bool HasTextEdit() const; virtual void TakeObjInfo(SdrObjTransformInfoRec& rInfo) const; @@ -71,9 +69,7 @@ public: public: - void setURL( const ::rtl::OUString& rURL, - ::com::sun::star::uno::Reference< - ::com::sun::star::frame::XModel> const& xModel = 0); + void setURL( const ::rtl::OUString& rURL ); const ::rtl::OUString& getURL() const; void setMediaProperties( const ::avmedia::MediaItem& rState ); @@ -82,6 +78,8 @@ public: Size getPreferredSize() const; void setGraphic( const Graphic* pGraphic = NULL ); + ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream> + GetInputStream(); protected: @@ -89,11 +87,10 @@ protected: virtual ::sdr::contact::ViewContact* CreateObjectSpecificViewContact(); private: - - ::avmedia::MediaItem maMediaProperties; - ::std::auto_ptr< Graphic > mapGraphic; + struct Impl; + ::boost::scoped_ptr<Impl> m_pImpl; }; -#endif //_SVDOMEDIA_HXX +#endif // SVDOMEDIA_HXX /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/svdraw/svdomedia.cxx b/svx/source/svdraw/svdomedia.cxx index c40d130ac8e7..f75fb3e68672 100644 --- a/svx/source/svdraw/svdomedia.cxx +++ b/svx/source/svdraw/svdomedia.cxx @@ -30,10 +30,13 @@ #include <svx/svdomedia.hxx> #include <rtl/oustringostreaminserter.hxx> +#include <osl/file.hxx> #include <com/sun/star/document/XStorageBasedDocument.hpp> #include <com/sun/star/embed/XStorage.hpp> +#include <ucbhelper/content.hxx> + #include <comphelper/storagehelper.hxx> #include <vcl/svapp.hxx> @@ -52,18 +55,41 @@ using namespace ::com::sun::star; // - SdrMediaObj - // --------------- +// Note: the temp file is read only, until it is deleted! +// It may be shared between multiple documents in case of copy/paste, +// hence the shared_ptr. +struct MediaTempFile +{ + ::rtl::OUString const m_TempFileURL; + MediaTempFile(::rtl::OUString const& rURL) : m_TempFileURL(rURL) {} + ~MediaTempFile() + { + ::osl::File::remove(m_TempFileURL); + } +}; + +struct SdrMediaObj::Impl +{ + ::avmedia::MediaItem m_MediaProperties; + ::boost::scoped_ptr<Graphic> m_pGraphic; + ::boost::shared_ptr<MediaTempFile> m_pTempFile; +}; + TYPEINIT1( SdrMediaObj, SdrRectObj ); // ------------------------------------------------------------------------------ SdrMediaObj::SdrMediaObj() + : SdrRectObj() + , m_pImpl( new Impl() ) { } // ------------------------------------------------------------------------------ -SdrMediaObj::SdrMediaObj( const Rectangle& rRect ) : - SdrRectObj( rRect ) +SdrMediaObj::SdrMediaObj( const Rectangle& rRect ) + : SdrRectObj( rRect ) + , m_pImpl( new Impl() ) { } @@ -89,56 +115,6 @@ sdr::contact::ViewContact* SdrMediaObj::CreateObjectSpecificViewContact() // ------------------------------------------------------------------------------ -void SdrMediaObj::SetModel(SdrModel *const pNewModel) -{ - SdrModel *const pOldModel(GetModel()); - SdrRectObj::SetModel(pNewModel); - if (pOldModel && pNewModel && (pNewModel != pOldModel)) // copy/paste - { - try - { - ::rtl::OUString const& url(getURL()); - // overwrite the model reference: it should point to the target doc - uno::Reference<frame::XModel> const xTarget( - pNewModel->getUnoModel(), uno::UNO_QUERY); - setURL(url, xTarget); - // try to copy the media to target document - uno::Reference<embed::XStorage> const xTargetStorage( - pNewModel->GetDocumentStorage()); - if (!xTargetStorage.is()) - { - SAL_INFO("svx", "no target storage"); - return; - } - ::comphelper::LifecycleProxy sourceProxy; - uno::Reference<io::XInputStream> const xInStream( - pOldModel->GetDocumentStream(url, sourceProxy)); - if (!xInStream.is()) - { - SAL_INFO("svx", "no stream"); - return; // for linked media we should return here - } - ::comphelper::LifecycleProxy targetProxy; - uno::Reference<io::XStream> const xStream( - ::comphelper::OStorageHelper::GetStreamAtPackageURL( - xTargetStorage, url, embed::ElementModes::WRITE, - targetProxy)); - uno::Reference<io::XOutputStream> const xOutStream( - (xStream.is()) ? xStream->getOutputStream() : 0); - ::comphelper::OStorageHelper::CopyInputToOutput( - xInStream, xOutStream); - xOutStream->closeOutput(); - targetProxy.commitStorages(); - } - catch (uno::Exception const& e) - { - SAL_WARN("svx", "exception: '" << e.Message << "'"); - } - } -} - -// ------------------------------------------------------------------------------ - void SdrMediaObj::TakeObjInfo( SdrObjTransformInfoRec& rInfo ) const { rInfo.bSelectAllowed = true; @@ -207,8 +183,9 @@ SdrMediaObj& SdrMediaObj::operator=(const SdrMediaObj& rObj) return *this; SdrRectObj::operator=( rObj ); + m_pImpl->m_pTempFile = rObj.m_pImpl->m_pTempFile; // before props setMediaProperties( rObj.getMediaProperties() ); - setGraphic( rObj.mapGraphic.get() ); + setGraphic( rObj.m_pImpl->m_pGraphic.get() ); return *this; } @@ -261,12 +238,11 @@ void SdrMediaObj::AdjustToMaxRect( const Rectangle& rMaxRect, bool bShrinkOnly / // ------------------------------------------------------------------------------ -void SdrMediaObj::setURL( const ::rtl::OUString& rURL, - uno::Reference<frame::XModel> const& xModel ) +void SdrMediaObj::setURL( const ::rtl::OUString& rURL) { ::avmedia::MediaItem aURLItem; - aURLItem.setURL( rURL, xModel ); + aURLItem.setURL( rURL, 0 ); setMediaProperties( aURLItem ); } @@ -274,7 +250,7 @@ void SdrMediaObj::setURL( const ::rtl::OUString& rURL, const ::rtl::OUString& SdrMediaObj::getURL() const { - return getMediaProperties().getURL(); + return m_pImpl->m_MediaProperties.getURL(); } // ------------------------------------------------------------------------------ @@ -289,7 +265,7 @@ void SdrMediaObj::setMediaProperties( const ::avmedia::MediaItem& rState ) const ::avmedia::MediaItem& SdrMediaObj::getMediaProperties() const { - return maMediaProperties; + return m_pImpl->m_MediaProperties; } // ------------------------------------------------------------------------------ @@ -303,10 +279,79 @@ Size SdrMediaObj::getPreferredSize() const void SdrMediaObj::setGraphic( const Graphic* pGraphic ) { - mapGraphic.reset( pGraphic ? new Graphic( *pGraphic ) : NULL ); + m_pImpl->m_pGraphic.reset( pGraphic ? new Graphic( *pGraphic ) : NULL ); } // ------------------------------------------------------------------------------ +uno::Reference<io::XInputStream> SdrMediaObj::GetInputStream() +{ + if (!m_pImpl->m_pTempFile) + { + SAL_WARN("svx", "this is only intended for embedded media"); + return 0; + } + ucbhelper::Content tempFile(m_pImpl->m_pTempFile->m_TempFileURL, + uno::Reference<ucb::XCommandEnvironment>()); + return tempFile.openStream(); +} + +/// copy a stream from XStorage to temp file +bool lcl_HandlePackageURL( + ::rtl::OUString const & rURL, + SdrModel *const pModel, + ::rtl::OUString & o_rTempFileURL) +{ + if (!pModel) + { + SAL_WARN("svx", "no model"); + return false; + } + ::comphelper::LifecycleProxy sourceProxy; + uno::Reference<io::XInputStream> xInStream; + try { + xInStream = pModel->GetDocumentStream(rURL, sourceProxy); + } + catch (container::NoSuchElementException const&) + { + SAL_INFO("svx", "not found: '" << ::rtl::OUString(rURL) << "'"); + return false; + } + catch (uno::Exception const& e) + { + SAL_WARN("svx", "exception: '" << e.Message << "'"); + return false; + } + if (!xInStream.is()) + { + SAL_WARN("svx", "no stream?"); + return false; + } + + ::rtl::OUString tempFileURL; + ::osl::FileBase::RC const err = + ::osl::FileBase::createTempFile(0, 0, & tempFileURL); + if (::osl::FileBase::E_None != err) + { + SAL_INFO("svx", "cannot create temp file"); + return false; + } + + try + { + ::ucbhelper::Content tempContent(tempFileURL, + uno::Reference<ucb::XCommandEnvironment>()); + tempContent.writeStream(xInStream, true); // copy stream to file + } + catch (uno::Exception const& e) + { + SAL_WARN("svx", "exception: '" << e.Message << "'"); + return false; + } + o_rTempFileURL = tempFileURL; + return true; +} + +static char const s_PkgScheme[] = "vnd.sun.star.Package:"; void SdrMediaObj::mediaPropertiesChanged( const ::avmedia::MediaItem& rNewProperties ) { @@ -314,24 +359,56 @@ void SdrMediaObj::mediaPropertiesChanged( const ::avmedia::MediaItem& rNewProper // use only a subset of MediaItem properties for own own properties if( ( AVMEDIA_SETMASK_URL & nMaskSet ) && - ( rNewProperties.getURL() != getURL() ) ) + ( rNewProperties.getURL() != getURL() )) { setGraphic(); - maMediaProperties.setURL(rNewProperties.getURL(), - rNewProperties.getModel()); + ::rtl::OUString const url(rNewProperties.getURL()); + if ((0 == rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( + url.getStr(), url.getLength(), + s_PkgScheme, SAL_N_ELEMENTS(s_PkgScheme) - 1))) + { + if ( !m_pImpl->m_pTempFile + || (m_pImpl->m_pTempFile->m_TempFileURL != + rNewProperties.getTempURL())) + { + ::rtl::OUString tempFileURL; + bool const bSuccess = lcl_HandlePackageURL( + url, GetModel(), tempFileURL); + if (bSuccess) + { + m_pImpl->m_pTempFile.reset(new MediaTempFile(tempFileURL)); + m_pImpl->m_MediaProperties.setURL(url, & tempFileURL); + } + else // this case is for Clone via operator= + { + m_pImpl->m_pTempFile.reset(); + m_pImpl->m_MediaProperties.setURL(::rtl::OUString(), 0); + } + } + else + { + m_pImpl->m_MediaProperties.setURL(url, + &rNewProperties.getTempURL()); + } + } + else + { + m_pImpl->m_pTempFile.reset(); + m_pImpl->m_MediaProperties.setURL(url, 0); + } } if( AVMEDIA_SETMASK_LOOP & nMaskSet ) - maMediaProperties.setLoop( rNewProperties.isLoop() ); + m_pImpl->m_MediaProperties.setLoop( rNewProperties.isLoop() ); if( AVMEDIA_SETMASK_MUTE & nMaskSet ) - maMediaProperties.setMute( rNewProperties.isMute() ); + m_pImpl->m_MediaProperties.setMute( rNewProperties.isMute() ); if( AVMEDIA_SETMASK_VOLUMEDB & nMaskSet ) - maMediaProperties.setVolumeDB( rNewProperties.getVolumeDB() ); + m_pImpl->m_MediaProperties.setVolumeDB( rNewProperties.getVolumeDB() ); if( AVMEDIA_SETMASK_ZOOM & nMaskSet ) - maMediaProperties.setZoom( rNewProperties.getZoom() ); + m_pImpl->m_MediaProperties.setZoom( rNewProperties.getZoom() ); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/unodraw/unoprov.cxx b/svx/source/unodraw/unoprov.cxx index e210952bdf11..f800afba3c34 100644 --- a/svx/source/unodraw/unoprov.cxx +++ b/svx/source/unodraw/unoprov.cxx @@ -761,6 +761,7 @@ SfxItemPropertyMapEntry* ImplGetSvxMediaShapePropertyMap() // #i68101# { MAP_CHAR_LEN(UNO_NAME_MISC_OBJ_TITLE), OWN_ATTR_MISC_OBJ_TITLE , &::getCppuType((const ::rtl::OUString*)0), 0, 0}, { MAP_CHAR_LEN(UNO_NAME_MISC_OBJ_DESCRIPTION), OWN_ATTR_MISC_OBJ_DESCRIPTION , &::getCppuType((const ::rtl::OUString*)0), 0, 0}, + {MAP_CHAR_LEN("PrivateStream"), OWN_ATTR_GRAPHIC_STREAM, &::com::sun::star::io::XInputStream::static_type(), ::com::sun::star::beans::PropertyAttribute::READONLY, 0}, {0,0,0,0,0,0} }; diff --git a/svx/source/unodraw/unoshap4.cxx b/svx/source/unodraw/unoshap4.cxx index ebbbe38bcb15..c4c7e687df2c 100644 --- a/svx/source/unodraw/unoshap4.cxx +++ b/svx/source/unodraw/unoshap4.cxx @@ -878,9 +878,7 @@ bool SvxMediaShape::setPropertyValueImpl( const ::rtl::OUString& rName, const Sf if( rValue >>= aURL ) { bOk = true; - uno::Reference<frame::XModel> const xModel( - mpModel->getUnoModel(), uno::UNO_QUERY_THROW); - aItem.setURL( aURL, xModel); + aItem.setURL( aURL, 0 ); } } break; @@ -955,7 +953,9 @@ bool SvxMediaShape::setPropertyValueImpl( const ::rtl::OUString& rName, const Sf bool SvxMediaShape::getPropertyValueImpl( const ::rtl::OUString& rName, const SfxItemPropertySimpleEntry* pProperty, ::com::sun::star::uno::Any& rValue ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) { - if( ( pProperty->nWID >= OWN_ATTR_MEDIA_URL ) && ( pProperty->nWID <= OWN_ATTR_MEDIA_ZOOM ) ) + if ( ((pProperty->nWID >= OWN_ATTR_MEDIA_URL) && + (pProperty->nWID <= OWN_ATTR_MEDIA_ZOOM)) + || (pProperty->nWID == OWN_ATTR_GRAPHIC_STREAM)) { SdrMediaObj* pMedia = static_cast< SdrMediaObj* >( mpObj.get() ); const ::avmedia::MediaItem aItem( pMedia->getMediaProperties() ); @@ -982,6 +982,10 @@ bool SvxMediaShape::getPropertyValueImpl( const ::rtl::OUString& rName, const Sf rValue <<= aItem.getZoom(); break; + case OWN_ATTR_GRAPHIC_STREAM: + rValue <<= pMedia->GetInputStream(); + break; + default: OSL_FAIL("SvxMediaShape::getPropertyValueImpl(), unknown property!"); } |