summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--avmedia/Library_avmedia.mk1
-rw-r--r--avmedia/source/framework/mediaitem.cxx11
-rw-r--r--avmedia/source/framework/modeltools.cxx198
-rw-r--r--include/avmedia/mediaitem.hxx5
-rw-r--r--include/avmedia/modeltools.hxx22
-rw-r--r--include/sal/log-areas.dox6
-rw-r--r--sd/source/ui/func/fuinsert.cxx2
-rw-r--r--sd/source/ui/inc/View.hxx7
-rw-r--r--sd/source/ui/view/sdview4.cxx34
9 files changed, 274 insertions, 12 deletions
diff --git a/avmedia/Library_avmedia.mk b/avmedia/Library_avmedia.mk
index 3c723f19e0e7..935222798313 100644
--- a/avmedia/Library_avmedia.mk
+++ b/avmedia/Library_avmedia.mk
@@ -47,6 +47,7 @@ $(eval $(call gb_Library_add_exception_objects,avmedia,\
avmedia/source/framework/mediamisc \
avmedia/source/framework/mediaplayer \
avmedia/source/framework/mediatoolbox \
+ avmedia/source/framework/modeltools \
avmedia/source/framework/soundhandler \
avmedia/source/viewer/mediaevent_impl \
avmedia/source/viewer/mediawindow \
diff --git a/avmedia/source/framework/mediaitem.cxx b/avmedia/source/framework/mediaitem.cxx
index b9ab635cdc72..32f6f043ca0e 100644
--- a/avmedia/source/framework/mediaitem.cxx
+++ b/avmedia/source/framework/mediaitem.cxx
@@ -23,7 +23,6 @@
#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>
@@ -313,7 +312,7 @@ void MediaItem::setZoom( ::com::sun::star::media::ZoomLevel eZoom )
return m_pImpl->m_eZoom;
}
-static OUString lcl_GetFilename(OUString const& rSourceURL)
+OUString GetFilename(OUString const& rSourceURL)
{
uno::Reference<uri::XUriReferenceFactory> const xUriFactory(
uri::UriReferenceFactory::create(
@@ -337,8 +336,8 @@ static OUString lcl_GetFilename(OUString const& rSourceURL)
return filename;
}
-static uno::Reference<io::XStream>
-lcl_CreateStream(uno::Reference<embed::XStorage> const& xStorage,
+uno::Reference<io::XStream>
+CreateStream(uno::Reference<embed::XStorage> const& xStorage,
OUString const& rFilename)
{
OUString filename(rFilename);
@@ -397,10 +396,10 @@ bool EmbedMedia(uno::Reference<frame::XModel> const& xModel,
uno::Reference<embed::XStorage> const xSubStorage(
xStorage->openStorageElement(media, embed::ElementModes::WRITE));
- OUString filename(lcl_GetFilename(rSourceURL));
+ OUString filename(GetFilename(rSourceURL));
uno::Reference<io::XStream> const xStream(
- lcl_CreateStream(xSubStorage, filename), uno::UNO_SET_THROW);
+ CreateStream(xSubStorage, filename), uno::UNO_SET_THROW);
uno::Reference<io::XOutputStream> const xOutStream(
xStream->getOutputStream(), uno::UNO_SET_THROW);
diff --git a/avmedia/source/framework/modeltools.cxx b/avmedia/source/framework/modeltools.cxx
new file mode 100644
index 000000000000..10da986cd803
--- /dev/null
+++ b/avmedia/source/framework/modeltools.cxx
@@ -0,0 +1,198 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <avmedia/modeltools.hxx>
+#include <avmedia/mediaitem.hxx>
+
+#include <com/sun/star/embed/ElementModes.hpp>
+#include <com/sun/star/embed/XTransactedObject.hpp>
+#include <com/sun/star/document/XStorageBasedDocument.hpp>
+#include <com/sun/star/embed/XStorage.hpp>
+#include <osl/file.hxx>
+#include <comphelper/processfactory.hxx>
+#include <tools/urlobj.hxx>
+#include <ucbhelper/content.hxx>
+
+#include <boost/property_tree/ptree.hpp>
+#include <boost/property_tree/json_parser.hpp>
+#include <boost/foreach.hpp>
+
+#include <string>
+#include <vector>
+
+using namespace ::com::sun::star;
+using namespace boost::property_tree;
+
+namespace avmedia {
+
+static void lcl_EmbedExternals(const OUString& rSourceURL, uno::Reference<embed::XStorage> xSubStorage, ::ucbhelper::Content& rContent)
+{
+ // Create a temp file with which json parser can work.
+ OUString sTempFileURL;
+ const ::osl::FileBase::RC aErr =
+ ::osl::FileBase::createTempFile(0, 0, &sTempFileURL);
+ if (::osl::FileBase::E_None != aErr)
+ {
+ SAL_WARN("avmedia.model", "cannot create temp file");
+ return;
+ }
+ try
+ {
+ // Write json content to the temp file
+ ::ucbhelper::Content aTempContent(sTempFileURL,
+ uno::Reference<ucb::XCommandEnvironment>(),
+ comphelper::getProcessComponentContext());
+ aTempContent.writeStream(rContent.openStream(), true);
+ }
+ catch (uno::Exception const& e)
+ {
+ SAL_WARN("avmedia.model", "exception: '" << e.Message << "'");
+ return;
+ }
+
+ // Convert URL to a file path for loading
+ const INetURLObject aURLObj(sTempFileURL);
+ std::string sUrl = OUStringToOString( aURLObj.getFSysPath(INetURLObject::FSYS_DETECT), RTL_TEXTENCODING_UTF8 ).getStr();
+
+ // Parse json, read externals' URI and modify this relative URI's so they remain valid in the new context.
+ std::vector<std::string> vExternals;
+ ptree aTree;
+ try
+ {
+ json_parser::read_json( sUrl, aTree );
+
+ // Buffers for geometry and animations
+ BOOST_FOREACH(ptree::value_type &rVal,aTree.get_child("buffers"))
+ {
+ const std::string sBufferUri(rVal.second.get<std::string>("path"));
+ vExternals.push_back(sBufferUri);
+ // Change path: make it contain only a file name
+ aTree.put("buffers." + rVal.first + ".path.",sBufferUri.substr(sBufferUri.find_last_of('/')+1));
+ }
+ // Images for textures
+ BOOST_FOREACH(ptree::value_type &rVal,aTree.get_child("images"))
+ {
+ const std::string sImageUri(rVal.second.get<std::string>("path"));
+ vExternals.push_back(sImageUri);
+ // Change path: make it contain only a file name
+ aTree.put("images." + rVal.first + ".path.",sImageUri.substr(sImageUri.find_last_of('/')+1));
+ }
+ // Shaders (contains names only)
+ BOOST_FOREACH(ptree::value_type &rVal,aTree.get_child("programs"))
+ {
+ vExternals.push_back(rVal.second.get<std::string>("fragmentShader") + ".glsl");
+ vExternals.push_back(rVal.second.get<std::string>("vertexShader") + ".glsl");
+ }
+
+ // Write out modified json
+ json_parser::write_json( sUrl, aTree );
+ }
+ catch ( boost::exception const& )
+ {
+ SAL_WARN("avmedia.model", "failed to parse json file");
+ return;
+ }
+
+ // Reload json with modified path to external resources
+ rContent = ::ucbhelper::Content("file://" + OUString::createFromAscii(sUrl.c_str()),
+ uno::Reference<ucb::XCommandEnvironment>(),
+ comphelper::getProcessComponentContext());
+
+ // Store all external files next to the json file
+ for( std::vector<std::string>::iterator aCIter = vExternals.begin(); aCIter != vExternals.end(); ++aCIter )
+ {
+ const OUString sAbsURL = INetURLObject::GetAbsURL(rSourceURL,OUString::createFromAscii(aCIter->c_str()));
+
+ ::ucbhelper::Content aContent(sAbsURL,
+ uno::Reference<ucb::XCommandEnvironment>(),
+ comphelper::getProcessComponentContext());
+
+ uno::Reference<io::XStream> const xStream(
+ CreateStream(xSubStorage, GetFilename(sAbsURL)), uno::UNO_SET_THROW);
+ uno::Reference<io::XOutputStream> const xOutStream(
+ xStream->getOutputStream(), uno::UNO_SET_THROW);
+
+ if (!aContent.openStream(xOutStream))
+ {
+ SAL_WARN("avmedia.model", "openStream to storage failed");
+ return;
+ }
+ }
+}
+
+bool Embed3DModel( const uno::Reference<frame::XModel>& xModel,
+ const OUString& rSourceURL, OUString& o_rEmbeddedURL)
+{
+ try
+ {
+ ::ucbhelper::Content aSourceContent(rSourceURL,
+ uno::Reference<ucb::XCommandEnvironment>(),
+ comphelper::getProcessComponentContext());
+
+ // Base storage
+ uno::Reference<document::XStorageBasedDocument> const xSBD(xModel,
+ uno::UNO_QUERY_THROW);
+ uno::Reference<embed::XStorage> const xStorage(
+ xSBD->getDocumentStorage(), uno::UNO_QUERY_THROW);
+
+ // Model storage
+ const OUString sModel("Model");
+ uno::Reference<embed::XStorage> const xModelStorage(
+ xStorage->openStorageElement(sModel, embed::ElementModes::WRITE));
+
+ // Own storage of the corresponding model
+ const OUString sFilename(GetFilename(rSourceURL));
+ const OUString sGLTFDir(sFilename.copy(0,sFilename.lastIndexOf('.')));
+ uno::Reference<embed::XStorage> const xSubStorage(
+ xModelStorage->openStorageElement(sGLTFDir, embed::ElementModes::WRITE));
+
+ // Embed external resources
+ lcl_EmbedExternals(rSourceURL, xSubStorage, aSourceContent);
+
+ // Save model file (.json)
+ uno::Reference<io::XStream> const xStream(
+ CreateStream(xSubStorage, sFilename), uno::UNO_SET_THROW);
+ uno::Reference<io::XOutputStream> const xOutStream(
+ xStream->getOutputStream(), uno::UNO_SET_THROW);
+
+ if (!aSourceContent.openStream(xOutStream))
+ {
+ SAL_INFO("avmedia.model", "openStream to storage failed");
+ return false;
+ }
+
+ const uno::Reference<embed::XTransactedObject> xSubTransaction(xSubStorage, uno::UNO_QUERY);
+ if (xSubTransaction.is())
+ {
+ xSubTransaction->commit();
+ }
+ const uno::Reference<embed::XTransactedObject> xModelTransaction(xModelStorage, uno::UNO_QUERY);
+ if (xModelTransaction.is())
+ {
+ xModelTransaction->commit();
+ }
+ const uno::Reference<embed::XTransactedObject> xTransaction(xStorage, uno::UNO_QUERY);
+ if (xTransaction.is())
+ {
+ xTransaction->commit();
+ }
+
+ o_rEmbeddedURL = "vnd.sun.star.Package:" + sModel + "/" + sGLTFDir + "/" + sFilename;
+ return true;
+ }
+ catch (uno::Exception const&)
+ {
+ SAL_WARN("avmedia.model", "Exception while trying to embed model");
+ }
+ return false;
+}
+
+} // namespace avemdia
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/avmedia/mediaitem.hxx b/include/avmedia/mediaitem.hxx
index 97a63a961597..c512e2654eb9 100644
--- a/include/avmedia/mediaitem.hxx
+++ b/include/avmedia/mediaitem.hxx
@@ -26,6 +26,7 @@
#include <svl/poolitem.hxx>
#include <com/sun/star/media/ZoomLevel.hpp>
#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/embed/XStorage.hpp>
#include <avmedia/avmediadllapi.h>
#define AVMEDIA_SETMASK_NONE ((sal_uInt32)(0x00000000))
@@ -128,6 +129,10 @@ bool AVMEDIA_DLLPUBLIC EmbedMedia(
OUString const& rSourceURL,
OUString & o_rEmbeddedURL);
+OUString GetFilename(OUString const& rSourceURL);
+
+::com::sun::star::uno::Reference<::com::sun::star::io::XStream> CreateStream(
+ ::com::sun::star::uno::Reference<::com::sun::star::embed::XStorage> const& xStorage, OUString const& rFilename);
}
#endif
diff --git a/include/avmedia/modeltools.hxx b/include/avmedia/modeltools.hxx
new file mode 100644
index 000000000000..db9fc139f3f5
--- /dev/null
+++ b/include/avmedia/modeltools.hxx
@@ -0,0 +1,22 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <rtl/ustring.hxx>
+#include <com/sun/star/frame/XModel.hpp>
+#include <avmedia/avmediadllapi.h>
+
+namespace avmedia {
+
+bool AVMEDIA_DLLPUBLIC Embed3DModel(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel>& xModel,
+ const OUString& rSourceURL, OUString& o_rEmbeddedURL);
+
+} // namespace avemdia
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/sal/log-areas.dox b/include/sal/log-areas.dox
index 2d712a6be3d7..f8a29673e095 100644
--- a/include/sal/log-areas.dox
+++ b/include/sal/log-areas.dox
@@ -448,10 +448,14 @@ certain functionality.
@li @c svx
@li @c svx.fmcmop
+@section avmedia
+
+@li @c avmedia
+@li @c avmedia.model - 3D models
+
@section other
@li @c accessibility
-@li @c avmedia
@li @c basebmp
@li @c binaryurp
@li @c configmgr
diff --git a/sd/source/ui/func/fuinsert.cxx b/sd/source/ui/func/fuinsert.cxx
index c1706fc298cf..7e0a0255986f 100644
--- a/sd/source/ui/func/fuinsert.cxx
+++ b/sd/source/ui/func/fuinsert.cxx
@@ -805,7 +805,7 @@ void FuInsert3DModel::DoExecute( SfxRequest& )
aPos.Y() -= aSize.Height() >> 1;
}
- mpView->InsertMediaURL( sURL, nAction, aPos, aSize, false ) ;
+ mpView->Insert3DModelURL( sURL, nAction, aPos, aSize, false ) ;
if( mpWindow )
mpWindow->LeaveWait();
diff --git a/sd/source/ui/inc/View.hxx b/sd/source/ui/inc/View.hxx
index 526298a0aec0..85936ed89196 100644
--- a/sd/source/ui/inc/View.hxx
+++ b/sd/source/ui/inc/View.hxx
@@ -145,6 +145,13 @@ public:
const Point& rPos, const Size& rSize,
bool const bLink );
+ SdrMediaObj* Insert3DModelURL( const OUString& rModelURL, sal_Int8& rAction,
+ const Point& rPos, const Size& rSize,
+ bool const bLink );
+
+ SdrMediaObj* InsertMediaObj( const OUString& rURL, sal_Int8& rAction,
+ const Point& rPos, const Size& rSize );
+
bool PasteRTFTable( SotStorageStreamRef xStm, SdrPage* pPage, sal_uLong nPasteOptions );
sal_Bool IsPresObjSelected(sal_Bool bOnPage=sal_True, sal_Bool bOnMasterPage=sal_True, sal_Bool bCheckPresObjListOnly=sal_False, sal_Bool bCheckLayoutOnly=sal_False) const;
diff --git a/sd/source/ui/view/sdview4.cxx b/sd/source/ui/view/sdview4.cxx
index 7229da7458d9..770d2928c340 100644
--- a/sd/source/ui/view/sdview4.cxx
+++ b/sd/source/ui/view/sdview4.cxx
@@ -35,6 +35,7 @@
#include <sot/storage.hxx>
#include <sfx2/app.hxx>
#include <avmedia/mediawindow.hxx>
+#include <avmedia/modeltools.hxx>
#include <svtools/ehdl.hxx>
#include <svtools/sfxecode.hxx>
#include <vcl/graphicfilter.hxx>
@@ -268,8 +269,6 @@ SdrGrafObj* View::InsertGraphic( const Graphic& rGraphic, sal_Int8& rAction,
return pNewGrafObj;
}
-
-
SdrMediaObj* View::InsertMediaURL( const OUString& rMediaURL, sal_Int8& rAction,
const Point& rPos, const Size& rSize,
bool const bLink )
@@ -287,6 +286,33 @@ SdrMediaObj* View::InsertMediaURL( const OUString& rMediaURL, sal_Int8& rAction,
if (!bRet) { return 0; }
}
+ return InsertMediaObj( realURL, rAction, rPos, rSize );
+}
+
+SdrMediaObj* View::Insert3DModelURL(
+ const OUString& rModelURL, sal_Int8& rAction,
+ const Point& rPos, const Size& rSize,
+ bool const bLink )
+{
+ OUString sRealURL;
+ if (bLink)
+ {
+ sRealURL = rModelURL;
+ }
+ else
+ {
+ uno::Reference<frame::XModel> const xModel(
+ GetDoc().GetObjectShell()->GetModel());
+ bool const bRet = ::avmedia::Embed3DModel(xModel, rModelURL, sRealURL);
+ if (!bRet) { return 0; }
+ }
+
+ return InsertMediaObj( sRealURL, rAction, rPos, rSize );
+}
+
+SdrMediaObj* View::InsertMediaObj( const OUString& rMediaURL, sal_Int8& rAction,
+ const Point& rPos, const Size& rSize )
+{
SdrEndTextEdit();
mnAction = rAction;
@@ -309,7 +335,7 @@ SdrMediaObj* View::InsertMediaURL( const OUString& rMediaURL, sal_Int8& rAction,
if( mnAction == DND_ACTION_LINK && pPickObj && pPV && pPickObj->ISA( SdrMediaObj ) )
{
pNewMediaObj = static_cast< SdrMediaObj* >( pPickObj->Clone() );
- pNewMediaObj->setURL( realURL, ""/*TODO?*/ );
+ pNewMediaObj->setURL( rMediaURL, ""/*TODO?*/ );
BegUndo(SD_RESSTR(STR_UNDO_DRAGDROP));
ReplaceObjectAtView(pPickObj, *pPV, pNewMediaObj);
@@ -345,7 +371,7 @@ SdrMediaObj* View::InsertMediaURL( const OUString& rMediaURL, sal_Int8& rAction,
if (sh != 0 && sh->HasName()) {
referer = sh->GetMedium()->GetName();
}
- pNewMediaObj->setURL( realURL, referer );
+ pNewMediaObj->setURL( rMediaURL, referer );
if( pPickObj )
{