[Libreoffice-commits] core.git: 7 commits - avmedia/Library_avmedia.mk avmedia/source external/boost include/avmedia include/sal sd/source svx/source xmloff/source
Zolnai Tamás
tamas.zolnai at collabora.com
Wed Apr 2 03:23:58 PDT 2014
avmedia/Library_avmedia.mk | 1
avmedia/source/framework/mediaitem.cxx | 11 -
avmedia/source/framework/modeltools.cxx | 198 +++++++++++++++++++++++
external/boost/UnpackedTarball_boost.mk | 1
external/boost/boost.jsonparser.warnings.patch.0 | 58 ++++++
external/boost/boost.libcdr.warnings.patch.1 | 97 -----------
include/avmedia/mediaitem.hxx | 5
include/avmedia/modeltools.hxx | 22 ++
include/sal/log-areas.dox | 6
sd/source/ui/func/fuinsert.cxx | 4
sd/source/ui/inc/View.hxx | 7
sd/source/ui/view/sdview4.cxx | 34 +++
svx/source/svdraw/svdomedia.cxx | 70 +++++++-
xmloff/source/draw/shapeexport.cxx | 64 +++++++
xmloff/source/draw/ximpshap.cxx | 3
15 files changed, 466 insertions(+), 115 deletions(-)
New commits:
commit e341ea3863bd19a2884083d2957273cc3572f989
Author: Zolnai Tamás <tamas.zolnai at collabora.com>
Date: Tue Apr 1 19:22:52 2014 +0200
ODF import of glTF 3D models
Change-Id: I42f7bc63c1f75592ab628407b40d40536e58f18c
diff --git a/xmloff/source/draw/ximpshap.cxx b/xmloff/source/draw/ximpshap.cxx
index df6b191..aefffce 100644
--- a/xmloff/source/draw/ximpshap.cxx
+++ b/xmloff/source/draw/ximpshap.cxx
@@ -3062,7 +3062,8 @@ void SdXMLPluginShapeContext::StartElement( const ::com::sun::star::uno::Referen
if( nPrefix == XML_NAMESPACE_DRAW && IsXMLToken( aLocalName, XML_MIME_TYPE ) )
{
- if( xAttrList->getValueByIndex( n ).equalsAscii( "application/vnd.sun.star.media" ) )
+ if( xAttrList->getValueByIndex( n ).equalsAscii( "application/vnd.sun.star.media" ) ||
+ xAttrList->getValueByIndex( n ).equalsAscii( "application/vnd.gltf+json" ))
mbMedia = true;
// leave this loop
commit f7a5ed9b4b34264252be48488cf23c052a2276c2
Author: Zolnai Tamás <tamas.zolnai at collabora.com>
Date: Wed Apr 2 11:58:11 2014 +0200
Store glTF related files in a temp folder which URL can be given to the player
media::XPlayer is constructed by media::XManager with
only one URL parameter.
Change-Id: I3693bce5386ea7f75fa7d9f1a7d744f90440d62b
diff --git a/svx/source/svdraw/svdomedia.cxx b/svx/source/svdraw/svdomedia.cxx
index 24199a9..e60b446 100644
--- a/svx/source/svdraw/svdomedia.cxx
+++ b/svx/source/svdraw/svdomedia.cxx
@@ -38,7 +38,9 @@
#include <svx/sdr/contact/viewcontactofsdrmediaobj.hxx>
#include <avmedia/mediawindow.hxx>
-
+// For handling of glTF models
+#include <unotools/tempfile.hxx>
+#include <tools/urlobj.hxx>
using namespace ::com::sun::star;
@@ -294,6 +296,65 @@ uno::Reference<io::XInputStream> SdrMediaObj::GetInputStream()
return tempFile.openStream();
}
+static bool lcl_HandleJsonPackageURL(
+ const OUString& rURL,
+ SdrModel* const pModel,
+ OUString& o_rTempFileURL)
+{
+ // Create a temporary folder which will contain all files of glTF model
+ const OUString sTempFolder = ::utl::TempFile( NULL, true ).GetURL();
+
+ const sal_uInt16 nPackageLength = OString("vnd.sun.star.Package:").getLength();
+ const OUString sUrlPath = rURL.copy(nPackageLength,rURL.lastIndexOf("/")-nPackageLength);
+ try
+ {
+ // Base storage:
+ uno::Reference<document::XStorageBasedDocument> const xSBD(
+ pModel->getUnoModel(), uno::UNO_QUERY_THROW);
+ const uno::Reference<embed::XStorage> xStorage(
+ xSBD->getDocumentStorage(), uno::UNO_QUERY_THROW);
+
+ // Model source
+ ::comphelper::LifecycleProxy proxy;
+ const uno::Reference<embed::XStorage> xModelStorage(
+ ::comphelper::OStorageHelper::GetStorageAtPath(xStorage, sUrlPath,
+ embed::ElementModes::READ, proxy));
+
+ // Copy all files of glTF model from storage to the temp folder
+ uno::Reference< container::XNameAccess > xNameAccess( xModelStorage, uno::UNO_QUERY );
+ const uno::Sequence< OUString > aFilenames = xNameAccess->getElementNames();
+ for( sal_Int32 nFileIndex = 0; nFileIndex < aFilenames.getLength(); ++nFileIndex )
+ {
+ // Generate temp file path
+ const OUString& rFilename = aFilenames[nFileIndex];
+ INetURLObject aUrlObj(sTempFolder);
+ aUrlObj.insertName(rFilename);
+ const OUString sFilepath = aUrlObj.GetMainURL( INetURLObject::NO_DECODE );
+
+ // Media URL will point at json file
+ if( rFilename.endsWith(".json") )
+ o_rTempFileURL = sFilepath;
+
+ // Create temp file and fill it from storage
+ ::ucbhelper::Content aTargetContent(sFilepath,
+ uno::Reference<ucb::XCommandEnvironment>(), comphelper::getProcessComponentContext());
+
+ uno::Reference<io::XStream> const xStream(
+ xModelStorage->openStreamElement(rFilename,embed::ElementModes::READ), uno::UNO_SET_THROW);
+ uno::Reference<io::XInputStream> const xInputStream(
+ xStream->getInputStream(), uno::UNO_SET_THROW);
+
+ aTargetContent.writeStream(xInputStream,true);
+ }
+
+ }
+ catch (uno::Exception const& e)
+ {
+ SAL_INFO("svx", "exception while copying glTF related files to temp directory '" << e.Message << "'");
+ }
+ return true;
+}
+
/// copy a stream from XStorage to temp file
static bool lcl_HandlePackageURL(
OUString const & rURL,
@@ -369,8 +430,11 @@ void SdrMediaObj::mediaPropertiesChanged( const ::avmedia::MediaItem& rNewProper
rNewProperties.getTempURL()))
{
OUString tempFileURL;
- bool const bSuccess = lcl_HandlePackageURL(
- url, GetModel(), tempFileURL);
+ bool bSuccess;
+ if( url.endsWith(".json") )
+ bSuccess = lcl_HandleJsonPackageURL(url, GetModel(), tempFileURL);
+ else
+ bSuccess = lcl_HandlePackageURL( url, GetModel(), tempFileURL);
if (bSuccess)
{
m_pImpl->m_pTempFile.reset(new MediaTempFile(tempFileURL));
commit 9220939537bf1041b2cb3b119c2156ba1f432632
Author: Zolnai Tamás <tamas.zolnai at collabora.com>
Date: Tue Apr 1 19:14:16 2014 +0200
Use "Insert" instead of "Open" in title of 3D Model insertion file dialog
Change-Id: Ibb6a7df3bf25f7006b71deeebd5abb842a628a46
diff --git a/sd/source/ui/func/fuinsert.cxx b/sd/source/ui/func/fuinsert.cxx
index 7e0a025..6146ba7 100644
--- a/sd/source/ui/func/fuinsert.cxx
+++ b/sd/source/ui/func/fuinsert.cxx
@@ -776,7 +776,7 @@ void FuInsert3DModel::DoExecute( SfxRequest& )
{
sfx2::FileDialogHelper aDlg( ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE, 0 );
- aDlg.SetTitle( "Open 3DModel" );
+ aDlg.SetTitle( "Insert 3D Model" );
aDlg.AddFilter( "GL Transmission Format", "*.json" );
aDlg.AddFilter( "All files", "*.*" );
commit f388519b2cc6cfcabf2ec51955d06717e7f6b46b
Author: Zolnai Tamás <tamas.zolnai at collabora.com>
Date: Wed Apr 2 11:59:42 2014 +0200
ODF export of glTF 3D models
Change-Id: Iea06ea7359b859144df338e1e22675e05bf4a2d7
diff --git a/xmloff/source/draw/shapeexport.cxx b/xmloff/source/draw/shapeexport.cxx
index eaa06d3..3a24c71 100644
--- a/xmloff/source/draw/shapeexport.cxx
+++ b/xmloff/source/draw/shapeexport.cxx
@@ -78,6 +78,7 @@
#include <com/sun/star/style/XStyle.hpp>
#include <com/sun/star/table/XColumnRowRange.hpp>
#include <com/sun/star/text/XText.hpp>
+#include <com/sun/star/document/XStorageBasedDocument.hpp>
#include <comphelper/classids.hxx>
#include <comphelper/processfactory.hxx>
@@ -91,6 +92,7 @@
#include <tools/debug.hxx>
#include <tools/globname.hxx>
#include <tools/helpers.hxx>
+#include <tools/urlobj.hxx>
#include <xmloff/contextid.hxx>
#include <xmloff/families.hxx>
@@ -3155,6 +3157,63 @@ lcl_StoreMediaAndGetURL(SvXMLExport & rExport,
}
}
+static void lcl_StoreJsonExternals(
+ SvXMLExport& rExport, const OUString& rURL)
+{
+ OUString sUrlPath;
+ if (rURL.startsWithIgnoreAsciiCase("vnd.sun.star.Package:", &sUrlPath))
+ {
+ sUrlPath = sUrlPath.copy(0,sUrlPath.lastIndexOf("/"));
+ try
+ {
+ // Base storage
+ uno::Reference<document::XStorageBasedDocument> const xSBD(
+ rExport.GetModel(), uno::UNO_QUERY_THROW);
+ const uno::Reference<embed::XStorage> xStorage(
+ xSBD->getDocumentStorage(), uno::UNO_QUERY_THROW);
+
+ // Model source
+ ::comphelper::LifecycleProxy proxy;
+ const uno::Reference<embed::XStorage> xModelStorage(
+ ::comphelper::OStorageHelper::GetStorageAtPath(xStorage, sUrlPath,
+ embed::ElementModes::READ, proxy));
+
+ // Target storage
+ uno::Reference<embed::XStorage> const xTarget(
+ rExport.GetTargetStorage(), uno::UNO_QUERY_THROW);
+
+ // Target of all models
+ const uno::Reference<embed::XStorage> xModelsTarget(
+ xTarget->openStorageElement(sUrlPath.copy(0,sUrlPath.lastIndexOf("/")), embed::ElementModes::WRITE));
+
+ // Target of current model
+ const uno::Reference<embed::XStorage> xModelTarget(
+ xModelsTarget->openStorageElement(sUrlPath.copy(sUrlPath.lastIndexOf("/")+1), embed::ElementModes::WRITE));
+
+ xModelStorage->copyToStorage(xModelTarget);
+
+ uno::Reference<embed::XTransactedObject> const xTransaction(xModelsTarget, uno::UNO_QUERY);
+ if (xTransaction.is())
+ {
+ xTransaction->commit();
+ }
+ }
+ catch (uno::Exception const& e)
+ {
+ SAL_INFO("xmloff", "exception while storing embedded model: '" << e.Message << "'");
+ }
+ }
+}
+
+static OUString lcl_GetMimeType(const OUString& aMediaURL)
+{
+ // TODO: Find a better way to find out the mime type, maybe via propset
+ if( aMediaURL.endsWith(".json") )
+ return OUString("application/vnd.gltf+json");
+ else
+ return OUString("application/vnd.sun.star.media");
+}
+
void XMLShapeExport::ImpExportMediaShape(
const uno::Reference< drawing::XShape >& xShape,
XmlShapeType eShapeType, sal_Int32 nFeatures, com::sun::star::awt::Point* pRefPoint)
@@ -3177,13 +3236,16 @@ void XMLShapeExport::ImpExportMediaShape(
xPropSet->getPropertyValue("MediaURL") >>= aMediaURL;
OUString const persistentURL =
lcl_StoreMediaAndGetURL(GetExport(), xPropSet, aMediaURL);
+ if( aMediaURL.endsWith(".json") )
+ lcl_StoreJsonExternals(GetExport(), 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 );
mrExport.AddAttribute ( XML_NAMESPACE_XLINK, XML_ACTUATE, XML_ONLOAD );
// export mime-type
- mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_MIME_TYPE, OUString( "application/vnd.sun.star.media" ) );
+ mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_MIME_TYPE, lcl_GetMimeType(aMediaURL) );
// write plugin
SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_PLUGIN, !( nFeatures & SEF_EXPORT_NO_WS ), true);
commit 414ff5650a810be807fed61ded1b9d6a23aa720b
Author: Zolnai Tamás <tamas.zolnai at collabora.com>
Date: Wed Apr 2 11:41:59 2014 +0200
Avoid Wsahdow warnings related to boost json parser
Problematic variable: separator -> separator_
Change-Id: Ia4e1b1543f61b03e029e1bc4151ec58334e8df57
diff --git a/external/boost/UnpackedTarball_boost.mk b/external/boost/UnpackedTarball_boost.mk
index d73ee50..b3ffa7e 100644
--- a/external/boost/UnpackedTarball_boost.mk
+++ b/external/boost/UnpackedTarball_boost.mk
@@ -49,6 +49,7 @@ boost_patches += boost.wuninitialized.patch
boost_patches += boost.wdeprecated-auto_ptr.patch.0
#https://svn.boost.org/trac/boost/ticket/9397
boost_patches += boost.9397.warnings.patch.0
+boost_patches += boost.jsonparser.warnings.patch.0
$(eval $(call gb_UnpackedTarball_UnpackedTarball,boost))
diff --git a/external/boost/boost.jsonparser.warnings.patch.0 b/external/boost/boost.jsonparser.warnings.patch.0
new file mode 100644
index 0000000..4a71b3b
--- /dev/null
+++ b/external/boost/boost.jsonparser.warnings.patch.0
@@ -0,0 +1,58 @@
+--- boost/property_tree/string_path.hpp
++++ boost/property_tree/string_path.hpp
+@@ -88,14 +88,14 @@ namespace boost { namespace property_tree
+ typedef typename String::value_type char_type;
+
+ /// Create an empty path.
+- explicit string_path(char_type separator = char_type('.'));
++ explicit string_path(char_type separator_ = char_type('.'));
+ /// Create a path by parsing the given string.
+ /// @param value A sequence, possibly with separators, that describes
+ /// the path, e.g. "one.two.three".
+ /// @param separator The separator used in parsing. Defaults to '.'.
+ /// @param tr The translator used by this path to convert the individual
+ /// parts to keys.
+- string_path(const String &value, char_type separator = char_type('.'),
++ string_path(const String &value, char_type separator_ = char_type('.'),
+ Translator tr = Translator());
+ /// Create a path by parsing the given string.
+ /// @param value A zero-terminated array of values. Only use if zero-
+@@ -106,7 +106,7 @@ namespace boost { namespace property_tree
+ /// @param tr The translator used by this path to convert the individual
+ /// parts to keys.
+ string_path(const char_type *value,
+- char_type separator = char_type('.'),
++ char_type separator_ = char_type('.'),
+ Translator tr = Translator());
+
+ // Default copying doesn't do the right thing with the iterator
+@@ -162,23 +162,23 @@ namespace boost { namespace property_tree
+ };
+
+ template <typename String, typename Translator> inline
+- string_path<String, Translator>::string_path(char_type separator)
+- : m_separator(separator), m_start(m_value.begin())
++ string_path<String, Translator>::string_path(char_type separator_)
++ : m_separator(separator_), m_start(m_value.begin())
+ {}
+
+ template <typename String, typename Translator> inline
+ string_path<String, Translator>::string_path(const String &value,
+- char_type separator,
++ char_type separator_,
+ Translator tr)
+- : m_value(value), m_separator(separator),
++ : m_value(value), m_separator(separator_),
+ m_tr(tr), m_start(m_value.begin())
+ {}
+
+ template <typename String, typename Translator> inline
+ string_path<String, Translator>::string_path(const char_type *value,
+- char_type separator,
++ char_type separator_,
+ Translator tr)
+- : m_value(value), m_separator(separator),
++ : m_value(value), m_separator(separator_),
+ m_tr(tr), m_start(m_value.begin())
+ {}
+
commit c3986c90e329af98520bda1ad11ecf6d059d50e1
Author: Zolnai Tamás <tamas.zolnai at collabora.com>
Date: Wed Apr 2 11:40:45 2014 +0200
These changes are not needed any more
Moreover these line causes the same Wshadow warning
which was the reason of adding them.
Change-Id: I6b5793b66db26720626b7924d59e9283168f8abe
diff --git a/external/boost/boost.libcdr.warnings.patch.1 b/external/boost/boost.libcdr.warnings.patch.1
index 22888c4..12a7ea2 100644
--- a/external/boost/boost.libcdr.warnings.patch.1
+++ b/external/boost/boost.libcdr.warnings.patch.1
@@ -1,100 +1,3 @@
---- boost/boost/multi_index/detail/index_matcher.hpp 2008-07-03 18:51:53.000000000 +0200
-+++ boost/boost/multi_index/detail/index_matcher.hpp 2013-05-17 15:30:12.539099597 +0200
-@@ -132,17 +132,17 @@
- entries(),entries()+size_,
- entry(node),entry::less_by_node()); /* localize entry */
- ent->ordered=false;
-- std::size_t n=ent->pos; /* get its position */
-+ std::size_t n_=ent->pos; /* get its position */
-
- entry dummy(0);
-- dummy.pile_top=n;
-+ dummy.pile_top=n_;
-
- entry* pile_ent= /* find the first available pile */
- std::lower_bound( /* to stack the entry */
- entries(),entries()+num_piles,
- dummy,entry::less_by_pile_top());
-
-- pile_ent->pile_top=n; /* stack the entry */
-+ pile_ent->pile_top=n_; /* stack the entry */
- pile_ent->pile_top_entry=ent;
-
- /* if not the first pile, link entry to top of the preceding pile */
-@@ -164,7 +164,7 @@
- */
-
- entry* ent=entries()[num_piles-1].pile_top_entry;
-- for(std::size_t n=num_piles;n--;){
-+ for(std::size_t n_=num_piles;n_--;){
- ent->ordered=true;
- ent=ent->previous;
- }
---- boost/boost/multi_index/ordered_index.hpp 2010-07-25 12:44:55.000000000 +0200
-+++ boost/boost/multi_index/ordered_index.hpp 2013-05-17 15:33:42.785182819 +0200
-@@ -436,9 +436,9 @@
-
- template<typename CompatibleKey,typename CompatibleCompare>
- iterator find(
-- const CompatibleKey& x,const CompatibleCompare& comp)const
-+ const CompatibleKey& x,const CompatibleCompare& comp_)const
- {
-- return make_iterator(ordered_index_find(root(),header(),key,x,comp));
-+ return make_iterator(ordered_index_find(root(),header(),key,x,comp_));
- }
-
- template<typename CompatibleKey>
-@@ -448,9 +448,9 @@
- }
-
- template<typename CompatibleKey,typename CompatibleCompare>
-- size_type count(const CompatibleKey& x,const CompatibleCompare& comp)const
-+ size_type count(const CompatibleKey& x,const CompatibleCompare& comp_)const
- {
-- std::pair<iterator,iterator> p=equal_range(x,comp);
-+ std::pair<iterator,iterator> p=equal_range(x,comp_);
- size_type n=std::distance(p.first,p.second);
- return n;
- }
-@@ -464,10 +464,10 @@
-
- template<typename CompatibleKey,typename CompatibleCompare>
- iterator lower_bound(
-- const CompatibleKey& x,const CompatibleCompare& comp)const
-+ const CompatibleKey& x,const CompatibleCompare& comp_)const
- {
- return make_iterator(
-- ordered_index_lower_bound(root(),header(),key,x,comp));
-+ ordered_index_lower_bound(root(),header(),key,x,comp_));
- }
-
- template<typename CompatibleKey>
-@@ -479,10 +479,10 @@
-
- template<typename CompatibleKey,typename CompatibleCompare>
- iterator upper_bound(
-- const CompatibleKey& x,const CompatibleCompare& comp)const
-+ const CompatibleKey& x,const CompatibleCompare& comp_)const
- {
- return make_iterator(
-- ordered_index_upper_bound(root(),header(),key,x,comp));
-+ ordered_index_upper_bound(root(),header(),key,x,comp_));
- }
-
- template<typename CompatibleKey>
-@@ -497,10 +497,10 @@
-
- template<typename CompatibleKey,typename CompatibleCompare>
- std::pair<iterator,iterator> equal_range(
-- const CompatibleKey& x,const CompatibleCompare& comp)const
-+ const CompatibleKey& x,const CompatibleCompare& comp_)const
- {
- std::pair<node_type*,node_type*> p=
-- ordered_index_equal_range(root(),header(),key,x,comp);
-+ ordered_index_equal_range(root(),header(),key,x,comp_);
- return std::pair<iterator,iterator>(
- make_iterator(p.first),make_iterator(p.second));
- }
--- boost/boost/multi_index/sequenced_index.hpp 2008-07-03 18:51:53.000000000 +0200
+++ boost/boost/multi_index/sequenced_index.hpp 2013-05-17 15:44:15.265289335 +0200
@@ -346,7 +346,7 @@
commit edb4c11b074e486a4fc071ea94c9c4a1c83e84a3
Author: Zolnai Tamás <tamas.zolnai at collabora.com>
Date: Wed Apr 2 11:34:03 2014 +0200
glTF 3D model embedding: Embed all external resources of *.json file
Store them under /Model/<json_file_name_without_extension>/
modeltools: functions for handling 3D models inside avmedia
Change-Id: Ia2bdad6064db372e1c946b6ab02c434545d1ed45
diff --git a/avmedia/Library_avmedia.mk b/avmedia/Library_avmedia.mk
index 3c723f1..9352227 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 b9ab635..32f6f04 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 0000000..10da986
--- /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 97a63a9..c512e26 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 0000000..db9fc13
--- /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 2d712a6..f8a2967 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
+ at section avmedia
+
+ at li @c avmedia
+ at li @c avmedia.model - 3D models
+
@section other
@li @c accessibility
- at 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 c1706fc..7e0a025 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 526298a..85936ed 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 7229da7..770d292 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 )
{
More information about the Libreoffice-commits
mailing list