From e8a54ef88dacccb9759dd394473d52b53ff1cbd7 Mon Sep 17 00:00:00 2001 From: Michael Stahl Date: Fri, 2 Dec 2011 23:54:33 +0100 Subject: add avmedia::EmbedMedia This new function is used by sc,sd,sw to embed media in the document storage. --- avmedia/Library_avmedia.mk | 1 + avmedia/inc/avmedia/mediaitem.hxx | 7 ++ avmedia/source/framework/mediaitem.cxx | 147 +++++++++++++++++++++++++++++++++ sc/source/ui/drawfunc/fuins1.cxx | 23 +++++- sd/source/ui/func/fuinsert.cxx | 2 +- sd/source/ui/inc/View.hxx | 3 +- sd/source/ui/view/sdview4.cxx | 22 ++++- sw/source/ui/shells/grfshex.cxx | 17 +++- 8 files changed, 212 insertions(+), 10 deletions(-) diff --git a/avmedia/Library_avmedia.mk b/avmedia/Library_avmedia.mk index 9f6bd523f1ed..2c1c42f2fc5e 100644 --- a/avmedia/Library_avmedia.mk +++ b/avmedia/Library_avmedia.mk @@ -49,6 +49,7 @@ $(eval $(call gb_Library_add_defs,avmedia,\ $(eval $(call gb_Library_add_linked_libs,avmedia,\ comphelper \ + ucbhelper \ cppu \ cppuhelper \ sal \ diff --git a/avmedia/inc/avmedia/mediaitem.hxx b/avmedia/inc/avmedia/mediaitem.hxx index cf9f09b01702..a1908105e235 100644 --- a/avmedia/inc/avmedia/mediaitem.hxx +++ b/avmedia/inc/avmedia/mediaitem.hxx @@ -34,6 +34,7 @@ #include #include #include +#include #include #define AVMEDIA_SETMASK_NONE ((sal_uInt32)(0x00000000)) @@ -124,6 +125,12 @@ private: typedef ::avmedia::MediaItem avmedia_MediaItem; +bool AVMEDIA_DLLPUBLIC EmbedMedia( + ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel> + const& xModel, + ::rtl::OUString const& rSourceURL, + ::rtl::OUString & o_rEmbeddedURL); + } #endif diff --git a/avmedia/source/framework/mediaitem.cxx b/avmedia/source/framework/mediaitem.cxx index 756c869769c7..afda0ab81651 100644 --- a/avmedia/source/framework/mediaitem.cxx +++ b/avmedia/source/framework/mediaitem.cxx @@ -29,6 +29,22 @@ #include #include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include + using namespace ::com::sun::star; namespace avmedia @@ -342,6 +358,137 @@ void MediaItem::setZoom( ::com::sun::star::media::ZoomLevel eZoom ) return m_pImpl->m_eZoom; } +//------------------------------------------------------------------------ + +static ::rtl::OUString lcl_GetFilename(::rtl::OUString const& rSourceURL) +{ + uno::Reference const xUriFactory( + ::comphelper::createProcessComponent( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.uri.UriReferenceFactory"))), + uno::UNO_QUERY_THROW); + + uno::Reference const xSourceURI( + xUriFactory->parse(rSourceURL), uno::UNO_SET_THROW); + + ::rtl::OUString filename; + { + sal_Int32 const nSegments(xSourceURI->getPathSegmentCount()); + if (0 < nSegments) + { + filename = xSourceURI->getPathSegment(nSegments - 1); + } + } + if (!::comphelper::OStorageHelper::IsValidZipEntryFileName( + filename, false) || !filename.getLength()) + { + filename = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("media")); + } + return filename; +} + +static uno::Reference +lcl_CreateStream(uno::Reference const& xStorage, + ::rtl::OUString const& rFilename) +{ + ::rtl::OUString filename(rFilename); + + if (xStorage->hasByName(filename)) + { + ::rtl::OUString basename; + ::rtl::OUString suffix; + sal_Int32 const nIndex(rFilename.lastIndexOf(sal_Unicode('.'))); + if (0 < nIndex) + { + basename = rFilename.copy(0, nIndex); + suffix = rFilename.copy(nIndex); + } + int count(0); // sigh... try to generate non-existent name + do + { + ++count; + filename = basename + ::rtl::OUString::valueOf(count) + suffix; + } + while (xStorage->hasByName(filename)); + } + + uno::Reference const xStream( + xStorage->openStreamElement(filename, + embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE), + uno::UNO_SET_THROW); + 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)); + } + return xStream; +} + +bool EmbedMedia(uno::Reference const& xModel, + ::rtl::OUString const& rSourceURL, ::rtl::OUString & o_rEmbeddedURL) +{ + try + { + ::ucbhelper::Content sourceContent(rSourceURL, + uno::Reference()); + + uno::Reference const xSBD(xModel, + uno::UNO_QUERY_THROW); + uno::Reference const xStorage( + xSBD->getDocumentStorage(), uno::UNO_QUERY_THROW); + + ::rtl::OUString const media(RTL_CONSTASCII_USTRINGPARAM("Media")); + uno::Reference const xSubStorage( + xStorage->openStorageElement(media, embed::ElementModes::WRITE)); + + ::rtl::OUString filename(lcl_GetFilename(rSourceURL)); + + uno::Reference const xStream( + lcl_CreateStream(xSubStorage, filename), uno::UNO_SET_THROW); + uno::Reference const xOutStream( + xStream->getOutputStream(), uno::UNO_SET_THROW); + + if (!sourceContent.openStream(xOutStream)) // copy file to storage + { + SAL_INFO("avmedia", "openStream to storage failed"); + return false; + } + + uno::Reference const xSubTransaction( + xSubStorage, uno::UNO_QUERY); + if (xSubTransaction.is()) { + xSubTransaction->commit(); + } + uno::Reference const xTransaction( + xStorage, uno::UNO_QUERY); + if (xTransaction.is()) { + xTransaction->commit(); + } + + ::rtl::OUStringBuffer buf(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( + "vnd.sun.star.Package:"))); + buf.append(media); + buf.append(sal_Unicode('/')); + buf.append(filename); + o_rEmbeddedURL = buf.makeStringAndClear(); + return true; + } + catch (uno::Exception const& e) + { + SAL_WARN("avmedia", + "Exception while trying to embed media"); + } + return false; +} + } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/ui/drawfunc/fuins1.cxx b/sc/source/ui/drawfunc/fuins1.cxx index dca4491ca8ad..7b29e9a223f1 100644 --- a/sc/source/ui/drawfunc/fuins1.cxx +++ b/sc/source/ui/drawfunc/fuins1.cxx @@ -51,6 +51,9 @@ #include "progress.hxx" #include "sc.hrc" + +using namespace ::com::sun::star; + //------------------------------------------------------------------------ void SC_DLLPUBLIC ScLimitSizeOnDrawPage( Size& rSize, Point& rPos, const Size& rPage ) @@ -160,7 +163,7 @@ void lcl_InsertGraphic( const Graphic& rGraphic, void lcl_InsertMedia( const ::rtl::OUString& rMediaURL, bool bApi, ScTabViewShell* pViewSh, Window* pWindow, SdrView* pView, - const Size& rPrefSize ) + const Size& rPrefSize, bool const bLink ) { SdrPageView* pPV = pView->GetSdrPageView(); SdrPage* pPage = pPV->GetPage(); @@ -183,9 +186,22 @@ void lcl_InsertMedia( const ::rtl::OUString& rMediaURL, bool bApi, if( pData->GetDocument()->IsNegativePage( pData->GetTabNo() ) ) aInsertPos.X() -= aSize.Width(); + ::rtl::OUString realURL; + if (bLink) + { + realURL = rMediaURL; + } + else + { + uno::Reference 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( rMediaURL ); + pObj->setURL( realURL ); pView->InsertObjectAtView( pObj, *pPV, bApi ? SDRINSERT_DONTMARK : 0 ); } @@ -345,7 +361,8 @@ FuInsertMedia::FuInsertMedia( ScTabViewShell* pViewSh, } else { - lcl_InsertMedia( aURL, bAPI, pViewSh, pWindow, pView, aPrefSize ); + lcl_InsertMedia( aURL, bAPI, pViewSh, pWindow, pView, aPrefSize, + bLink ); if( pWin ) pWin->LeaveWait(); diff --git a/sd/source/ui/func/fuinsert.cxx b/sd/source/ui/func/fuinsert.cxx index 184248dc228a..0ca60db2bfa7 100644 --- a/sd/source/ui/func/fuinsert.cxx +++ b/sd/source/ui/func/fuinsert.cxx @@ -768,7 +768,7 @@ void FuInsertAVMedia::DoExecute( SfxRequest& rReq ) aPos.Y() -= aSize.Height() >> 1; } - mpView->InsertMediaURL( aURL, nAction, aPos, aSize ) ; + mpView->InsertMediaURL( aURL, nAction, aPos, aSize, bLink ) ; if( mpWindow ) mpWindow->LeaveWait(); diff --git a/sd/source/ui/inc/View.hxx b/sd/source/ui/inc/View.hxx index 1387f461cc36..6816ef6e0d4a 100644 --- a/sd/source/ui/inc/View.hxx +++ b/sd/source/ui/inc/View.hxx @@ -152,7 +152,8 @@ public: sal_Int8& rAction, const Point& rPos, SdrObject* pSelectedObj, ImageMap* pImageMap ); SdrMediaObj* InsertMediaURL( const rtl::OUString& rMediaURL, sal_Int8& rAction, - const Point& rPos, const Size& rSize ); + const Point& rPos, const Size& rSize, + bool const bLink ); bool PasteRTFTable( SotStorageStreamRef xStm, SdrPage* pPage, sal_uLong nPasteOptions ); diff --git a/sd/source/ui/view/sdview4.cxx b/sd/source/ui/view/sdview4.cxx index 2e8663f90b74..f42ad34cbc24 100644 --- a/sd/source/ui/view/sdview4.cxx +++ b/sd/source/ui/view/sdview4.cxx @@ -284,8 +284,22 @@ SdrGrafObj* View::InsertGraphic( const Graphic& rGraphic, sal_Int8& rAction, // ----------------------------------------------------------------------------- SdrMediaObj* View::InsertMediaURL( const rtl::OUString& rMediaURL, sal_Int8& rAction, - const Point& rPos, const Size& rSize ) + const Point& rPos, const Size& rSize, + bool const bLink ) { + ::rtl::OUString realURL; + if (bLink) + { + realURL = rMediaURL; + } + else + { + uno::Reference const xModel( + GetDoc()->GetObjectShell()->GetModel()); + bool const bRet = ::avmedia::EmbedMedia(xModel, rMediaURL, realURL); + if (!bRet) { return 0; } + } + SdrEndTextEdit(); mnAction = rAction; @@ -308,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( rMediaURL ); + pNewMediaObj->setURL( realURL ); BegUndo(String(SdResId(STR_UNDO_DRAGDROP))); ReplaceObjectAtView(pPickObj, *pPV, pNewMediaObj); @@ -339,7 +353,7 @@ SdrMediaObj* View::InsertMediaURL( const rtl::OUString& rMediaURL, sal_Int8& rAc else InsertObjectAtView( pNewMediaObj, *pPV, SDRINSERT_SETDEFLAYER ); - pNewMediaObj->setURL( rMediaURL ); + pNewMediaObj->setURL( realURL ); if( pPickObj ) { @@ -461,7 +475,7 @@ IMPL_LINK( View, DropInsertFileHdl, Timer*, EMPTYARG ) else aPrefSize = Size( 5000, 5000 ); - InsertMediaURL( aCurrentDropFile, mnAction, maDropPos, aPrefSize ) ; + InsertMediaURL( aCurrentDropFile, mnAction, maDropPos, aPrefSize, true ) ; } else if( mnAction & DND_ACTION_LINK ) static_cast< DrawViewShell* >( mpViewSh )->InsertURLButton( aCurrentDropFile, aCurrentDropFile, String(), &maDropPos ); diff --git a/sw/source/ui/shells/grfshex.cxx b/sw/source/ui/shells/grfshex.cxx index 834057916f00..4b98002c3b57 100644 --- a/sw/source/ui/shells/grfshex.cxx +++ b/sw/source/ui/shells/grfshex.cxx @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -66,6 +67,7 @@ #include // <- #111827# +using namespace ::com::sun::star; using namespace ::com::sun::star::uno; using namespace ::com::sun::star::ui::dialogs; using namespace ::sfx2; @@ -134,9 +136,22 @@ bool SwTextShell::InsertMediaDlg( SfxRequest& rReq ) else aSize = Size( 2835, 2835 ); + ::rtl::OUString realURL; + if (bLink) + { + realURL = aURL; + } + else + { + uno::Reference 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( aURL ); + pObj->setURL( realURL ); rSh.EnterStdMode(); rSh.SwFEShell::InsertDrawObj( *pObj, aPos ); bRet = true; -- cgit