summaryrefslogtreecommitdiff
path: root/svx
diff options
context:
space:
mode:
authorMichael Stahl <mstahl@redhat.com>2011-12-06 04:36:22 +0100
committerMichael Stahl <mstahl@redhat.com>2011-12-06 04:36:22 +0100
commit431604f9fa603a7acf67985c9e4851f37d9cd580 (patch)
tree2dbbe2e40af935229dbc8f2738dc446ab18a93b8 /svx
parentf3c19f8263f3352ce4efff0965f8000d8347f6a5 (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.hxx19
-rw-r--r--svx/source/svdraw/svdomedia.cxx209
-rw-r--r--svx/source/unodraw/unoprov.cxx1
-rw-r--r--svx/source/unodraw/unoshap4.cxx12
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!");
}