[Libreoffice-commits] .: 3 commits - avmedia/inc avmedia/source comphelper/inc comphelper/source sc/source sd/source svx/inc svx/source sw/source xmloff/source

Michael Stahl mst at kemper.freedesktop.org
Mon Dec 5 19:38:58 PST 2011


 avmedia/inc/avmedia/mediaitem.hxx              |    7 -
 avmedia/source/framework/mediaitem.cxx         |   19 +-
 avmedia/source/viewer/mediawindow.cxx          |    2 
 avmedia/source/viewer/mediawindowbase_impl.cxx |  114 +---------------
 avmedia/source/viewer/mediawindowbase_impl.hxx |   15 --
 comphelper/inc/comphelper/storagehelper.hxx    |    2 
 comphelper/source/misc/storagehelper.cxx       |   15 ++
 sc/source/ui/drawfunc/fuins1.cxx               |    7 -
 sd/source/ui/view/sdview4.cxx                  |    8 -
 svx/inc/svx/svdomedia.hxx                      |   17 +-
 svx/source/svdraw/svdmodel.cxx                 |    5 
 svx/source/svdraw/svdomedia.cxx                |  171 ++++++++++++++++++++++---
 svx/source/unodraw/unoprov.cxx                 |    1 
 svx/source/unodraw/unoshap4.cxx                |   12 +
 sw/source/ui/shells/grfshex.cxx                |    7 -
 xmloff/source/draw/shapeexport2.cxx            |   98 ++++++--------
 16 files changed, 273 insertions(+), 227 deletions(-)

New commits:
commit 431604f9fa603a7acf67985c9e4851f37d9cd580
Author: Michael Stahl <mstahl at redhat.com>
Date:   Tue Dec 6 04:36:22 2011 +0100

    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.

diff --git a/avmedia/inc/avmedia/mediaitem.hxx b/avmedia/inc/avmedia/mediaitem.hxx
index 0e4af5c..c4121a1 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 f5150f6..2ec4ae5 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 9a3cab2..713e9e9 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 d9e8fa6..370eb98 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 935b88a..d8244d9 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 3d5ea7d..10b6661 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 4e6218d..f42ad34 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 bc832c0..e3e2f42 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 c40d130..f75fb3e 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 e210952..f800afb 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 ebbbe38..c4c7e68 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 e3807cb..2fc57e5 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 5ae3223..91c72c3 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 );
commit f3c19f8263f3352ce4efff0965f8000d8347f6a5
Author: Michael Stahl <mstahl at redhat.com>
Date:   Tue Dec 6 04:36:21 2011 +0100

    SdrMediaObj: copy/paste support
    
    This only works properly in Impress, because Calc and Writer lack
    a SfxBaseModel on their clipboard document.

diff --git a/avmedia/source/framework/mediaitem.cxx b/avmedia/source/framework/mediaitem.cxx
index cb29637..f5150f6 100644
--- a/avmedia/source/framework/mediaitem.cxx
+++ b/avmedia/source/framework/mediaitem.cxx
@@ -250,10 +250,7 @@ void MediaItem::setURL( const ::rtl::OUString& rURL,
 {
     m_pImpl->m_URL = rURL;
     m_pImpl->m_nMaskSet |= AVMEDIA_SETMASK_URL;
-    if (xModel.is())
-    {
-        m_pImpl->m_wModel = xModel;
-    }
+    m_pImpl->m_wModel = xModel;
 }
 
 //------------------------------------------------------------------------
diff --git a/svx/inc/svx/svdomedia.hxx b/svx/inc/svx/svdomedia.hxx
index ffb2d9b..bc832c0 100644
--- a/svx/inc/svx/svdomedia.hxx
+++ b/svx/inc/svx/svdomedia.hxx
@@ -54,6 +54,8 @@ public:
 
         virtual                     ~SdrMediaObj();
 
+        virtual void SetModel(SdrModel* pNewModel);
+
         virtual bool                HasTextEdit() const;
 
         virtual void                TakeObjInfo(SdrObjTransformInfoRec& rInfo) const;
diff --git a/svx/source/svdraw/svdmodel.cxx b/svx/source/svdraw/svdmodel.cxx
index df94366..20f19d5 100644
--- a/svx/source/svdraw/svdmodel.cxx
+++ b/svx/source/svdraw/svdmodel.cxx
@@ -34,6 +34,7 @@
 #include <osl/endian.h>
 #include <rtl/logfile.hxx>
 #include <rtl/strbuf.hxx>
+#include <rtl/oustringostreaminserter.hxx>
 
 #include <com/sun/star/lang/XComponent.hpp>
 #include <com/sun/star/document/XStorageBasedDocument.hpp>
@@ -924,9 +925,9 @@ SdrModel::GetDocumentStream( ::rtl::OUString const& rURL,
     {
         SAL_INFO("svx", "not found");
     }
-    catch (uno::Exception const&)
+    catch (uno::Exception const& e)
     {
-        SAL_WARN("svx", "exception");
+        SAL_WARN("svx", "exception: '" << e.Message << "'");
     }
     return 0;
 }
diff --git a/svx/source/svdraw/svdomedia.cxx b/svx/source/svdraw/svdomedia.cxx
index 526d30f..c40d130 100644
--- a/svx/source/svdraw/svdomedia.cxx
+++ b/svx/source/svdraw/svdomedia.cxx
@@ -27,15 +27,25 @@
  ************************************************************************/
 
 
+#include <svx/svdomedia.hxx>
+
+#include <rtl/oustringostreaminserter.hxx>
+
+#include <com/sun/star/document/XStorageBasedDocument.hpp>
+#include <com/sun/star/embed/XStorage.hpp>
+
+#include <comphelper/storagehelper.hxx>
+
 #include <vcl/svapp.hxx>
 
-#include <svx/svdomedia.hxx>
+#include <svx/svdmodel.hxx>
 #include "svx/svdglob.hxx"
 #include "svx/svdstr.hrc"
 #include <svx/sdr/contact/viewcontactofsdrmediaobj.hxx>
 #include <avmedia/mediawindow.hxx>
 
 
+
 using namespace ::com::sun::star;
 
 // ---------------
@@ -79,6 +89,56 @@ 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;
commit f014ea59e9e6e24ffead1961e8b689237b3927f0
Author: Michael Stahl <mstahl at redhat.com>
Date:   Tue Dec 6 04:36:21 2011 +0100

    comphelper::LifecycleProxy: make writing work:
    
    The storage implementation forgets any writes unless all storages are
    committed.

diff --git a/comphelper/inc/comphelper/storagehelper.hxx b/comphelper/inc/comphelper/storagehelper.hxx
index 36ff795..8bf26de 100644
--- a/comphelper/inc/comphelper/storagehelper.hxx
+++ b/comphelper/inc/comphelper/storagehelper.hxx
@@ -65,6 +65,8 @@ public:
     ::boost::scoped_ptr<Impl> m_pBadness;
     LifecycleProxy();
     ~LifecycleProxy();
+    // commit the storages: necessary for writes to streams to take effect!
+    void commitStorages();
 };
 
 class COMPHELPER_DLLPUBLIC OStorageHelper
diff --git a/comphelper/source/misc/storagehelper.cxx b/comphelper/source/misc/storagehelper.cxx
index e429f22..773ec55 100644
--- a/comphelper/source/misc/storagehelper.cxx
+++ b/comphelper/source/misc/storagehelper.cxx
@@ -28,6 +28,7 @@
 
 #include <com/sun/star/embed/ElementModes.hpp>
 #include <com/sun/star/embed/XEncryptionProtectedSource2.hpp>
+#include <com/sun/star/embed/XTransactedObject.hpp>
 #include <com/sun/star/ucb/XSimpleFileAccess.hpp>
 #include <com/sun/star/beans/XPropertySet.hpp>
 #include <com/sun/star/beans/PropertyValue.hpp>
@@ -551,6 +552,20 @@ LifecycleProxy::LifecycleProxy()
     : m_pBadness( new Impl() ) { }
 LifecycleProxy::~LifecycleProxy() { }
 
+void LifecycleProxy::commitStorages()
+{
+    for (Impl::reverse_iterator iter = m_pBadness->rbegin();
+            iter != m_pBadness->rend(); ++iter) // reverse order (outwards)
+    {
+        uno::Reference<embed::XTransactedObject> const xTransaction(*iter,
+                uno::UNO_QUERY);
+        if (xTransaction.is())
+        {
+            xTransaction->commit();
+        }
+    }
+}
+
 static void splitPath( std::vector<rtl::OUString> &rElems,
                        const ::rtl::OUString& rPath )
 {


More information about the Libreoffice-commits mailing list