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 | |
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.
-rw-r--r-- | avmedia/inc/avmedia/mediaitem.hxx | 7 | ||||
-rw-r--r-- | avmedia/source/framework/mediaitem.cxx | 16 | ||||
-rw-r--r-- | avmedia/source/viewer/mediawindow.cxx | 2 | ||||
-rw-r--r-- | avmedia/source/viewer/mediawindowbase_impl.cxx | 114 | ||||
-rw-r--r-- | avmedia/source/viewer/mediawindowbase_impl.hxx | 15 | ||||
-rw-r--r-- | sc/source/ui/drawfunc/fuins1.cxx | 7 | ||||
-rw-r--r-- | sd/source/ui/view/sdview4.cxx | 8 | ||||
-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 | ||||
-rw-r--r-- | sw/source/ui/shells/grfshex.cxx | 7 | ||||
-rw-r--r-- | xmloff/source/draw/shapeexport2.cxx | 98 |
13 files changed, 242 insertions, 273 deletions
diff --git a/avmedia/inc/avmedia/mediaitem.hxx b/avmedia/inc/avmedia/mediaitem.hxx index 0e4af5c07507..c4121a123921 100644 --- a/avmedia/inc/avmedia/mediaitem.hxx +++ b/avmedia/inc/avmedia/mediaitem.hxx @@ -115,11 +115,10 @@ public: ::com::sun::star::media::ZoomLevel getZoom() const; void setURL( const ::rtl::OUString& rURL, - ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel> - const& xModel); + ::rtl::OUString const*const pTempURL); const ::rtl::OUString& getURL() const; - ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel> - getModel() const; + + const ::rtl::OUString& getTempURL() const; private: diff --git a/avmedia/source/framework/mediaitem.cxx b/avmedia/source/framework/mediaitem.cxx index f5150f659b79..2ec4ae574457 100644 --- a/avmedia/source/framework/mediaitem.cxx +++ b/avmedia/source/framework/mediaitem.cxx @@ -28,7 +28,6 @@ #include <avmedia/mediaitem.hxx> -#include <cppuhelper/weakref.hxx> #include <com/sun/star/uno/Sequence.hxx> #include <com/sun/star/beans/XPropertySet.hpp> @@ -61,8 +60,7 @@ TYPEINIT1_AUTOFACTORY( MediaItem, ::SfxPoolItem ); struct MediaItem::Impl { ::rtl::OUString m_URL; - // store a weak ref to the model so we can get at embedded media - uno::WeakReference<frame::XModel> m_wModel; + ::rtl::OUString m_TempFileURL; sal_uInt32 m_nMaskSet; MediaState m_eState; double m_fTime; @@ -85,7 +83,7 @@ struct MediaItem::Impl } Impl(Impl const& rOther) : m_URL( rOther.m_URL ) - , m_wModel( rOther.m_wModel ) + , m_TempFileURL( rOther.m_TempFileURL ) , m_nMaskSet( rOther.m_nMaskSet ) , m_eState( rOther.m_eState ) , m_fTime( rOther.m_fTime ) @@ -212,7 +210,7 @@ void MediaItem::merge( const MediaItem& rMediaItem ) const sal_uInt32 nMaskSet = rMediaItem.getMaskSet(); if( AVMEDIA_SETMASK_URL & nMaskSet ) - setURL( rMediaItem.getURL(), rMediaItem.getModel() ); + setURL( rMediaItem.getURL(), &rMediaItem.getTempURL() ); if( AVMEDIA_SETMASK_STATE & nMaskSet ) setState( rMediaItem.getState() ); @@ -246,11 +244,11 @@ sal_uInt32 MediaItem::getMaskSet() const //------------------------------------------------------------------------ void MediaItem::setURL( const ::rtl::OUString& rURL, - uno::Reference<frame::XModel> const & xModel) + ::rtl::OUString const*const pTempURL) { m_pImpl->m_URL = rURL; m_pImpl->m_nMaskSet |= AVMEDIA_SETMASK_URL; - m_pImpl->m_wModel = xModel; + m_pImpl->m_TempFileURL = (pTempURL) ? *pTempURL : ::rtl::OUString(); } //------------------------------------------------------------------------ @@ -260,9 +258,9 @@ const ::rtl::OUString& MediaItem::getURL() const return m_pImpl->m_URL; } -uno::Reference<frame::XModel> MediaItem::getModel() const +const ::rtl::OUString& MediaItem::getTempURL() const { - return m_pImpl->m_wModel; + return m_pImpl->m_TempFileURL; } //------------------------------------------------------------------------ diff --git a/avmedia/source/viewer/mediawindow.cxx b/avmedia/source/viewer/mediawindow.cxx index 9a3cab2da97e..713e9e9058e8 100644 --- a/avmedia/source/viewer/mediawindow.cxx +++ b/avmedia/source/viewer/mediawindow.cxx @@ -73,7 +73,7 @@ MediaWindow::~MediaWindow() void MediaWindow::setURL( const ::rtl::OUString& rURL ) { if( mpImpl ) - mpImpl->setURL( rURL, uno::Reference<frame::XModel>() ); + mpImpl->setURL( rURL, ::rtl::OUString() ); } // ------------------------------------------------------------------------- diff --git a/avmedia/source/viewer/mediawindowbase_impl.cxx b/avmedia/source/viewer/mediawindowbase_impl.cxx index d9e8fa60342a..370eb98d14ed 100644 --- a/avmedia/source/viewer/mediawindowbase_impl.cxx +++ b/avmedia/source/viewer/mediawindowbase_impl.cxx @@ -32,16 +32,11 @@ #include "mediawindow.hrc" #include <rtl/oustringostreaminserter.hxx> #include <sal/log.hxx> -#include <osl/file.hxx> #include <tools/urlobj.hxx> -#include <ucbhelper/content.hxx> #include <comphelper/processfactory.hxx> -#include <comphelper/storagehelper.hxx> #include <com/sun/star/lang/XMultiServiceFactory.hpp> #include <com/sun/star/lang/XComponent.hdl> #include <com/sun/star/media/XManager.hpp> -#include <com/sun/star/frame/XModel.hpp> -#include <com/sun/star/document/XStorageBasedDocument.hpp> #define MEDIA_TIMER_TIMEOUT 100 @@ -55,8 +50,7 @@ namespace avmedia { namespace priv { MediaWindowBaseImpl::MediaWindowBaseImpl( MediaWindow* pMediaWindow ) - : mpTempFileURL(0) - , mpMediaWindow( pMediaWindow ) + : mpMediaWindow( pMediaWindow ) { } @@ -106,88 +100,8 @@ uno::Reference< media::XPlayer > MediaWindowBaseImpl::createPlayer( const ::rtl: return xPlayer; } -// --------------------------------------------------------------------- -void MediaWindowBaseImpl::cleanupTempFile() -{ - if (mpTempFileURL) - { - ::osl::File::remove(*mpTempFileURL); - delete mpTempFileURL; - mpTempFileURL = 0; - } -} - -bool -MediaWindowBaseImpl::initPackageURL(::rtl::OUString const & rURL, - uno::Reference<frame::XModel> const& xModel) -{ - uno::Reference<document::XStorageBasedDocument> const xSBD( - xModel, uno::UNO_QUERY); - if (!xSBD.is()) - { - SAL_WARN("avmedia", "cannot get model"); - return false; - } - uno::Reference<embed::XStorage> const xStorage( - xSBD->getDocumentStorage()); - if (!xStorage.is()) - { - SAL_WARN("avmedia", "cannot get storage"); - return false; - } - ::comphelper::LifecycleProxy proxy; - uno::Reference<io::XInputStream> xInStream; - try { - uno::Reference<io::XStream> const xStream( - ::comphelper::OStorageHelper::GetStreamAtPackageURL( - xStorage, rURL, embed::ElementModes::READ, proxy)); - xInStream = (xStream.is()) ? xStream->getInputStream() : 0; - } - catch (container::NoSuchElementException const&) - { - SAL_INFO("avmedia", "not found: '" << ::rtl::OUString(rURL) << "'"); - return false; - } - catch (uno::Exception const& e) - { - SAL_WARN("avmedia", "exception: '" << e.Message << "'"); - return false; - } - if (!xInStream.is()) - { - SAL_WARN("avmedia", "no stream?"); - return false; - } - - mpTempFileURL = new ::rtl::OUString; - ::osl::FileBase::RC const err = - ::osl::FileBase::createTempFile(0, 0, mpTempFileURL); - if (::osl::FileBase::E_None != err) - { - SAL_INFO("avmedia", "cannot create temp file"); - delete mpTempFileURL; - mpTempFileURL = 0; - return false; - } - - try - { - ::ucbhelper::Content tempContent(*mpTempFileURL, - uno::Reference<ucb::XCommandEnvironment>()); - tempContent.writeStream(xInStream, true); // copy stream to file - } - catch (uno::Exception const& e) - { - SAL_WARN("avmedia", "exception: '" << e.Message << "'"); - return false; - } - return true; -} - -static char const s_PkgScheme[] = "vnd.sun.star.Package:"; - void MediaWindowBaseImpl::setURL( const ::rtl::OUString& rURL, - uno::Reference<frame::XModel> const& xModel ) + ::rtl::OUString const& rTempURL) { if( rURL != getURL() ) { @@ -201,16 +115,12 @@ void MediaWindowBaseImpl::setURL( const ::rtl::OUString& rURL, } mxPlayer.clear(); - cleanupTempFile(); + mTempFileURL = ::rtl::OUString(); - bool bSuccess(true); - if (0 == rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( - rURL.getStr(), rURL.getLength(), - s_PkgScheme, SAL_N_ELEMENTS(s_PkgScheme) - 1)) + if (rTempURL.getLength()) { - bSuccess = initPackageURL(rURL, xModel); - - maFileURL = (bSuccess) ? rURL : ::rtl::OUString(); + maFileURL = rURL; + mTempFileURL = rTempURL; } else { @@ -222,11 +132,8 @@ void MediaWindowBaseImpl::setURL( const ::rtl::OUString& rURL, maFileURL = rURL; } - if (bSuccess) - { - mxPlayer = createPlayer( - (mpTempFileURL) ? *mpTempFileURL : maFileURL ); - } + mxPlayer = createPlayer( + (mTempFileURL.getLength()) ? mTempFileURL : maFileURL ); onURLChanged(); } } @@ -304,7 +211,6 @@ void MediaWindowBaseImpl::cleanUp() mxPlayer.clear(); } - cleanupTempFile(); mpMediaWindow = NULL; } @@ -481,7 +387,7 @@ void MediaWindowBaseImpl::updateMediaItem( MediaItem& rItem ) const rItem.setMute( isMute() ); rItem.setVolumeDB( getVolumeDB() ); rItem.setZoom( getZoom() ); - rItem.setURL( getURL(), 0 ); + rItem.setURL( getURL(), &mTempFileURL ); } // ------------------------------------------------------------------------- @@ -492,7 +398,7 @@ void MediaWindowBaseImpl::executeMediaItem( const MediaItem& rItem ) // set URL first if( nMaskSet & AVMEDIA_SETMASK_URL ) - setURL( rItem.getURL(), rItem.getModel() ); + setURL( rItem.getURL(), rItem.getTempURL() ); // set different states next if( nMaskSet & AVMEDIA_SETMASK_TIME ) diff --git a/avmedia/source/viewer/mediawindowbase_impl.hxx b/avmedia/source/viewer/mediawindowbase_impl.hxx index 935b88a2aa65..d8244d90ed7d 100644 --- a/avmedia/source/viewer/mediawindowbase_impl.hxx +++ b/avmedia/source/viewer/mediawindowbase_impl.hxx @@ -35,10 +35,6 @@ #include <com/sun/star/media/XPlayerWindow.hpp> -namespace com { namespace sun { namespace star { - namespace frame { class XModel; } -}}} // namespace com::sun::star - namespace avmedia { namespace priv @@ -70,9 +66,7 @@ namespace avmedia static ::com::sun::star::uno::Reference< ::com::sun::star::media::XPlayer > createPlayer( const ::rtl::OUString& rURL); - void setURL( const ::rtl::OUString& rURL, - ::com::sun::star::uno::Reference< - ::com::sun::star::frame::XModel> const& wModel); + void setURL( const ::rtl::OUString& rURL, ::rtl::OUString const& rTempURL ); const ::rtl::OUString& getURL() const; @@ -128,13 +122,8 @@ namespace avmedia ::com::sun::star::uno::Reference< ::com::sun::star::media::XPlayerWindow > getPlayerWindow() const; private: - void cleanupTempFile(); - bool initPackageURL( const ::rtl::OUString& rPath, - ::com::sun::star::uno::Reference< - ::com::sun::star::frame::XModel> const& wModel); - ::rtl::OUString maFileURL; - ::rtl::OUString * mpTempFileURL; + ::rtl::OUString mTempFileURL; ::com::sun::star::uno::Reference< ::com::sun::star::media::XPlayer > mxPlayer; ::com::sun::star::uno::Reference< ::com::sun::star::media::XPlayerWindow > mxPlayerWindow; MediaWindow* mpMediaWindow; diff --git a/sc/source/ui/drawfunc/fuins1.cxx b/sc/source/ui/drawfunc/fuins1.cxx index 3d5ea7d01f74..10b6661b1680 100644 --- a/sc/source/ui/drawfunc/fuins1.cxx +++ b/sc/source/ui/drawfunc/fuins1.cxx @@ -186,8 +186,6 @@ void lcl_InsertMedia( const ::rtl::OUString& rMediaURL, bool bApi, if( pData->GetDocument()->IsNegativePage( pData->GetTabNo() ) ) aInsertPos.X() -= aSize.Width(); - uno::Reference<frame::XModel> const xModel( - pData->GetDocument()->GetDocumentShell()->GetModel()); ::rtl::OUString realURL; if (bLink) { @@ -195,13 +193,16 @@ void lcl_InsertMedia( const ::rtl::OUString& rMediaURL, bool bApi, } else { + uno::Reference<frame::XModel> const xModel( + pData->GetDocument()->GetDocumentShell()->GetModel()); bool const bRet = ::avmedia::EmbedMedia(xModel, rMediaURL, realURL); if (!bRet) { return; } } SdrMediaObj* pObj = new SdrMediaObj( Rectangle( aInsertPos, aSize ) ); - pObj->setURL( realURL, (bLink) ? 0 : xModel ); + pObj->SetModel(pData->GetDocument()->GetDrawLayer()); // set before setURL + pObj->setURL( realURL ); pView->InsertObjectAtView( pObj, *pPV, bApi ? SDRINSERT_DONTMARK : 0 ); } diff --git a/sd/source/ui/view/sdview4.cxx b/sd/source/ui/view/sdview4.cxx index 4e6218dbeb2e..f42ad34cbc24 100644 --- a/sd/source/ui/view/sdview4.cxx +++ b/sd/source/ui/view/sdview4.cxx @@ -287,8 +287,6 @@ SdrMediaObj* View::InsertMediaURL( const rtl::OUString& rMediaURL, sal_Int8& rAc const Point& rPos, const Size& rSize, bool const bLink ) { - uno::Reference<frame::XModel> const xModel( - GetDoc()->GetObjectShell()->GetModel()); ::rtl::OUString realURL; if (bLink) { @@ -296,6 +294,8 @@ SdrMediaObj* View::InsertMediaURL( const rtl::OUString& rMediaURL, sal_Int8& rAc } else { + uno::Reference<frame::XModel> const xModel( + GetDoc()->GetObjectShell()->GetModel()); bool const bRet = ::avmedia::EmbedMedia(xModel, rMediaURL, realURL); if (!bRet) { return 0; } } @@ -322,7 +322,7 @@ SdrMediaObj* View::InsertMediaURL( const rtl::OUString& rMediaURL, sal_Int8& rAc if( mnAction == DND_ACTION_LINK && pPickObj && pPV && pPickObj->ISA( SdrMediaObj ) ) { pNewMediaObj = static_cast< SdrMediaObj* >( pPickObj->Clone() ); - pNewMediaObj->setURL( realURL, (bLink) ? 0 : xModel ); + pNewMediaObj->setURL( realURL ); BegUndo(String(SdResId(STR_UNDO_DRAGDROP))); ReplaceObjectAtView(pPickObj, *pPV, pNewMediaObj); @@ -353,7 +353,7 @@ SdrMediaObj* View::InsertMediaURL( const rtl::OUString& rMediaURL, sal_Int8& rAc else InsertObjectAtView( pNewMediaObj, *pPV, SDRINSERT_SETDEFLAYER ); - pNewMediaObj->setURL( realURL, (bLink) ? 0 : xModel ); + pNewMediaObj->setURL( realURL ); if( pPickObj ) { 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!"); } diff --git a/sw/source/ui/shells/grfshex.cxx b/sw/source/ui/shells/grfshex.cxx index e3807cba4a78..2fc57e5e0ffb 100644 --- a/sw/source/ui/shells/grfshex.cxx +++ b/sw/source/ui/shells/grfshex.cxx @@ -136,8 +136,6 @@ bool SwTextShell::InsertMediaDlg( SfxRequest& rReq ) else aSize = Size( 2835, 2835 ); - uno::Reference<frame::XModel> const xModel( - rSh.GetDoc()->GetDocShell()->GetModel()); ::rtl::OUString realURL; if (bLink) { @@ -145,13 +143,16 @@ bool SwTextShell::InsertMediaDlg( SfxRequest& rReq ) } else { + uno::Reference<frame::XModel> const xModel( + rSh.GetDoc()->GetDocShell()->GetModel()); bRet = ::avmedia::EmbedMedia(xModel, aURL, realURL); if (!bRet) { return bRet; } } SdrMediaObj* pObj = new SdrMediaObj( Rectangle( aPos, aSize ) ); - pObj->setURL( realURL, (bLink) ? 0 : xModel ); + pObj->SetModel(rSh.GetDoc()->GetDrawModel()); // set before setURL + pObj->setURL( realURL ); rSh.EnterStdMode(); rSh.SwFEShell::InsertDrawObj( *pObj, aPos ); bRet = true; diff --git a/xmloff/source/draw/shapeexport2.cxx b/xmloff/source/draw/shapeexport2.cxx index 5ae32238587b..91c72c3f59eb 100644 --- a/xmloff/source/draw/shapeexport2.cxx +++ b/xmloff/source/draw/shapeexport2.cxx @@ -27,6 +27,7 @@ ************************************************************************/ #include <xmloff/unointerfacetouniqueidentifiermapper.hxx> +#include <rtl/oustringostreaminserter.hxx> #include <com/sun/star/text/XText.hpp> #include <com/sun/star/container/XNamed.hpp> #include <com/sun/star/container/XEnumerationAccess.hpp> @@ -35,7 +36,6 @@ #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> @@ -43,6 +43,8 @@ #include <sax/tools/converter.hxx> +#include <comphelper/storagehelper.hxx> + #include "anim.hxx" #include <xmloff/shapeexport.hxx> @@ -1947,58 +1949,47 @@ 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<io::XInputStream> const& xInStream, uno::Reference<embed::XStorage> const& xTarget, - ::rtl::OUString const& rPath) + ::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 + ::comphelper::LifecycleProxy proxy; + uno::Reference<io::XStream> const xStream( + ::comphelper::OStorageHelper::GetStreamAtPackageURL(xTarget, rPath, + embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE, proxy)); + uno::Reference<io::XOutputStream> const xOutStream( + (xStream.is()) ? xStream->getOutputStream() : 0); + if (!xOutStream.is()) { - 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); + SAL_WARN("xmloff", "no output stream"); + throw uno::Exception( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("no output stream")),0); } - uno::Reference<embed::XTransactedObject> const xTransaction(xTarget, - uno::UNO_QUERY); - if (xTransaction.is()) - { - xTransaction->commit(); + uno::Reference< beans::XPropertySet > const xStreamProps(xStream, + uno::UNO_QUERY); + if (xStreamProps.is()) { // this is NOT supported in FileSystemStorage + xStreamProps->setPropertyValue( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MediaType")), + uno::makeAny(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( + //FIXME how to detect real media type? + //but currently xmloff has this one hardcoded anyway... + "application/vnd.sun.star.media")))); + xStreamProps->setPropertyValue( // turn off compression + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Compressed")), + uno::makeAny(sal_False)); } + ::comphelper::OStorageHelper::CopyInputToOutput(xInStream, xOutStream); + xOutStream->closeOutput(); + proxy.commitStorages(); } static char const s_PkgScheme[] = "vnd.sun.star.Package:"; static ::rtl::OUString -lcl_StoreMediaAndGetURL(SvXMLExport & rExport, ::rtl::OUString const& rURL) +lcl_StoreMediaAndGetURL(SvXMLExport & rExport, + uno::Reference<beans::XPropertySet> const& xPropSet, + ::rtl::OUString const& rURL) { if (0 == rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( rURL.getStr(), rURL.getLength(), @@ -2006,25 +1997,30 @@ lcl_StoreMediaAndGetURL(SvXMLExport & rExport, ::rtl::OUString const& rURL) { 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); + uno::Reference<io::XInputStream> xInStream; + xPropSet->getPropertyValue( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("PrivateStream"))) + >>= xInStream; + + if (!xInStream.is()) + { + SAL_WARN("xmloff", "no input stream"); + return ::rtl::OUString(); + } ::rtl::OUString const urlPath( rURL.copy(SAL_N_ELEMENTS(s_PkgScheme)-1)); - lcl_CopyStream(xSource, xTarget, urlPath); + lcl_CopyStream(xInStream, xTarget, rURL); return urlPath; } catch (uno::Exception const& e) { - SAL_INFO("xmloff", "exception while storing embedded media"); + SAL_INFO("xmloff", "exception while storing embedded media: '" + << e.Message << "'"); } return ::rtl::OUString(); } @@ -2055,7 +2051,7 @@ void XMLShapeExport::ImpExportMediaShape( OUString aMediaURL; xPropSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaURL" ) ) ) >>= aMediaURL; OUString const persistentURL = - lcl_StoreMediaAndGetURL(GetExport(), aMediaURL); + lcl_StoreMediaAndGetURL(GetExport(), xPropSet, 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 ); |