summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Stahl <mstahl@redhat.com>2011-12-02 23:54:33 +0100
committerMichael Stahl <mstahl@redhat.com>2011-12-03 00:48:15 +0100
commite8a54ef88dacccb9759dd394473d52b53ff1cbd7 (patch)
tree6b6a18d6d11b365a46de3359e49f8ea2b2fd562e
parent51ea69880ca32220fa1c6b3e95c8916e3409184c (diff)
add avmedia::EmbedMedia
This new function is used by sc,sd,sw to embed media in the document storage.
-rw-r--r--avmedia/Library_avmedia.mk1
-rw-r--r--avmedia/inc/avmedia/mediaitem.hxx7
-rw-r--r--avmedia/source/framework/mediaitem.cxx147
-rw-r--r--sc/source/ui/drawfunc/fuins1.cxx23
-rw-r--r--sd/source/ui/func/fuinsert.cxx2
-rw-r--r--sd/source/ui/inc/View.hxx3
-rw-r--r--sd/source/ui/view/sdview4.cxx22
-rw-r--r--sw/source/ui/shells/grfshex.cxx17
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 <tools/rtti.hxx>
#include <svl/poolitem.hxx>
#include <com/sun/star/media/ZoomLevel.hpp>
+#include <com/sun/star/frame/XModel.hpp>
#include <avmedia/avmediadllapi.h>
#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 <avmedia/mediaitem.hxx>
#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/embed/ElementModes.hpp>
+#include <com/sun/star/embed/XStorage.hpp>
+#include <com/sun/star/embed/XTransactedObject.hpp>
+#include <com/sun/star/document/XStorageBasedDocument.hpp>
+#include <com/sun/star/ucb/XCommandEnvironment.hpp>
+#include <com/sun/star/uri/XUriReference.hpp>
+#include <com/sun/star/uri/XUriReferenceFactory.hpp>
+
+#include <rtl/ustrbuf.hxx>
+
+#include <ucbhelper/content.hxx>
+
+#include <comphelper/processfactory.hxx>
+#include <comphelper/storagehelper.hxx>
+
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<uri::XUriReferenceFactory> const xUriFactory(
+ ::comphelper::createProcessComponent(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.uri.UriReferenceFactory"))),
+ uno::UNO_QUERY_THROW);
+
+ uno::Reference<uri::XUriReference> 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<io::XStream>
+lcl_CreateStream(uno::Reference<embed::XStorage> 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<io::XStream> 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<frame::XModel> const& xModel,
+ ::rtl::OUString const& rSourceURL, ::rtl::OUString & o_rEmbeddedURL)
+{
+ try
+ {
+ ::ucbhelper::Content sourceContent(rSourceURL,
+ uno::Reference<ucb::XCommandEnvironment>());
+
+ uno::Reference<document::XStorageBasedDocument> const xSBD(xModel,
+ uno::UNO_QUERY_THROW);
+ uno::Reference<embed::XStorage> const xStorage(
+ xSBD->getDocumentStorage(), uno::UNO_QUERY_THROW);
+
+ ::rtl::OUString const media(RTL_CONSTASCII_USTRINGPARAM("Media"));
+ uno::Reference<embed::XStorage> const xSubStorage(
+ xStorage->openStorageElement(media, embed::ElementModes::WRITE));
+
+ ::rtl::OUString filename(lcl_GetFilename(rSourceURL));
+
+ uno::Reference<io::XStream> const xStream(
+ lcl_CreateStream(xSubStorage, filename), uno::UNO_SET_THROW);
+ uno::Reference<io::XOutputStream> 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<embed::XTransactedObject> const xSubTransaction(
+ xSubStorage, uno::UNO_QUERY);
+ if (xSubTransaction.is()) {
+ xSubTransaction->commit();
+ }
+ uno::Reference<embed::XTransactedObject> 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<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( 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<frame::XModel> 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 <svl/svstdarr.hxx>
#include <svtools/filter.hxx>
#include <svx/htmlmode.hxx>
+#include <doc.hxx>
#include <docsh.hxx>
#include <frmfmt.hxx>
#include <frmmgr.hxx>
@@ -66,6 +67,7 @@
#include <comcore.hrc>
// <- #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<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( aURL );
+ pObj->setURL( realURL );
rSh.EnterStdMode();
rSh.SwFEShell::InsertDrawObj( *pObj, aPos );
bRet = true;