summaryrefslogtreecommitdiff
path: root/ucb
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2015-10-26 17:55:14 +0100
committerMichael Stahl <mstahl@redhat.com>2015-10-28 16:21:26 +0000
commit74453dbed460c0c428ce989b07a65d5cac5db49a (patch)
tree9bd0b80d60d8e4ce27fc1df2fd475bea060c5a3d /ucb
parent4df5049cb5e6cf8c31861d8ab4a4a49e5167efee (diff)
tdf#75637: Resolve help images via a vnd.libreoffice.image UCP
...which uses the logic already available in VCL's ImplImageTree to locate the image zip files and find fallbacks for incomplete themes and for localized images. (cherry picked from commit 6948c546fdc00dddec7d58e03150dcc87921d6b2, plus f5174c89cd037d35b975590083cf91b36633808d "...but do not erase localize attributes from image elements," which is needed to make localized image references work again) Conflicts: vcl/osx/vclnsapp.mm Change-Id: Ic1c15fcacb6596a27a2b051093232902202bf472 Reviewed-on: https://gerrit.libreoffice.org/19644 Reviewed-by: Michael Stahl <mstahl@redhat.com> Tested-by: Michael Stahl <mstahl@redhat.com>
Diffstat (limited to 'ucb')
-rw-r--r--ucb/Library_ucpimage.mk33
-rw-r--r--ucb/Module_ucb.mk1
-rw-r--r--ucb/source/ucp/image/ucpimage.component17
-rw-r--r--ucb/source/ucp/image/ucpimage.cxx172
4 files changed, 223 insertions, 0 deletions
diff --git a/ucb/Library_ucpimage.mk b/ucb/Library_ucpimage.mk
new file mode 100644
index 000000000000..9c683f748f75
--- /dev/null
+++ b/ucb/Library_ucpimage.mk
@@ -0,0 +1,33 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# 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/.
+#
+
+$(eval $(call gb_Library_Library,ucpimage))
+
+$(eval $(call gb_Library_add_exception_objects,ucpimage, \
+ ucb/source/ucp/image/ucpimage \
+))
+
+$(eval $(call gb_Library_set_componentfile,ucpimage,ucb/source/ucp/image/ucpimage))
+
+$(eval $(call gb_Library_use_externals,ucpimage, \
+ boost_headers \
+))
+
+$(eval $(call gb_Library_use_libraries,ucpimage, \
+ cppu \
+ cppuhelper \
+ sal \
+ ucbhelper \
+ vcl \
+ $(gb_UWINAPI) \
+))
+
+$(eval $(call gb_Library_use_sdk_api,ucpimage))
+
+# vim: set noet sw=4 ts=4:
diff --git a/ucb/Module_ucb.mk b/ucb/Module_ucb.mk
index c07d751014a0..d46dc7469c35 100644
--- a/ucb/Module_ucb.mk
+++ b/ucb/Module_ucb.mk
@@ -20,6 +20,7 @@ $(eval $(call gb_Module_add_targets,ucb,\
Library_ucpfile1 \
$(if $(ENABLE_CURL),Library_ucpftp1) \
Library_ucphier1 \
+ Library_ucpimage \
Library_ucppkg1 \
Library_ucptdoc1 \
))
diff --git a/ucb/source/ucp/image/ucpimage.component b/ucb/source/ucp/image/ucpimage.component
new file mode 100644
index 000000000000..6dba0ddc211e
--- /dev/null
+++ b/ucb/source/ucp/image/ucpimage.component
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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/.
+ *
+-->
+
+<component loader="com.sun.star.loader.SharedLibrary" environment="@CPPU_ENV@"
+ xmlns="http://openoffice.org/2010/uno-components">
+ <implementation name="com.sun.star.comp.ucb.ImageContentProvider"
+ constructor="com_sun_star_comp_ucb_ImageContentProvider_get_implementation">
+ <service name="com.sun.star.ucb.ImageContentProvider"/>
+ </implementation>
+</component>
diff --git a/ucb/source/ucp/image/ucpimage.cxx b/ucb/source/ucp/image/ucpimage.cxx
new file mode 100644
index 000000000000..fb3acff4e4ae
--- /dev/null
+++ b/ucb/source/ucp/image/ucpimage.cxx
@@ -0,0 +1,172 @@
+/* -*- 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 <sal/config.h>
+
+#include <cassert>
+
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/ucb/XContentProvider.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/uri/UriReferenceFactory.hpp>
+#include <cppuhelper/compbase.hxx>
+#include <cppuhelper/supportsservice.hxx>
+#include <osl/mutex.hxx>
+#include <rtl/uri.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <vcl/implimagetree.hxx>
+#include <vcl/svapp.hxx>
+#include <ucbhelper/content.hxx>
+
+// A LO-private ("implementation detail") UCP used to access images from help
+// content, with theme fallback and localization support as provided by VCL's
+// ImplImageTree.
+//
+// The URL scheme is
+//
+// "vnd.libreoffice.image://"<theme><path>["?lang="<language-tag>]
+
+namespace {
+
+class Provider final:
+ private osl::Mutex,
+ public cppu::WeakComponentImplHelper<
+ css::lang::XServiceInfo, css::ucb::XContentProvider>
+{
+public:
+ explicit Provider(
+ css::uno::Reference<css::uno::XComponentContext> const & context):
+ WeakComponentImplHelper(*static_cast<Mutex *>(this)), context_(context)
+ {}
+
+private:
+ OUString SAL_CALL getImplementationName()
+ throw (css::uno::RuntimeException, std::exception) override
+ { return OUString("com.sun.star.comp.ucb.ImageContentProvider"); }
+
+ sal_Bool SAL_CALL supportsService(OUString const & ServiceName)
+ throw (css::uno::RuntimeException, std::exception) override
+ { return cppu::supportsService(this, ServiceName); }
+
+ css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames()
+ throw (css::uno::RuntimeException, std::exception) override
+ {
+ return css::uno::Sequence<OUString>{
+ "com.sun.star.ucb.ImageContentProvider"};
+ }
+
+ css::uno::Reference<css::ucb::XContent> SAL_CALL queryContent(
+ css::uno::Reference<css::ucb::XContentIdentifier> const & Identifier)
+ throw (
+ css::ucb::IllegalIdentifierException, css::uno::RuntimeException,
+ std::exception)
+ override
+ {
+ css::uno::Reference<css::uno::XComponentContext> context;
+ {
+ osl::MutexGuard g(*this);
+ context = context_;
+ }
+ if (!context.is()) {
+ throw css::lang::DisposedException();
+ }
+ auto url(Identifier->getContentIdentifier());
+ auto uri(css::uri::UriReferenceFactory::create(context)->parse(url));
+ if (!(uri.is()
+ && uri->getScheme().equalsIgnoreAsciiCase(
+ "vnd.libreoffice.image")))
+ {
+ throw css::ucb::IllegalIdentifierException(url);
+ }
+ auto auth(
+ rtl::Uri::decode(
+ uri->getAuthority(), rtl_UriDecodeStrict,
+ RTL_TEXTENCODING_UTF8));
+ if (auth.isEmpty()) {
+ throw css::ucb::IllegalIdentifierException(url);
+ }
+ auto path(uri->getPath());
+ if (path.isEmpty()) {
+ throw css::ucb::IllegalIdentifierException(url);
+ }
+ OUStringBuffer buf;
+ assert(path[0] == '/');
+ for (sal_Int32 i = 1;;) {
+ auto j = path.indexOf('/', i);
+ if (j == -1) {
+ j = path.getLength();
+ }
+ auto seg(
+ rtl::Uri::decode(
+ path.copy(i, j - i), rtl_UriDecodeStrict,
+ RTL_TEXTENCODING_UTF8));
+ if (seg.isEmpty()) {
+ throw css::ucb::IllegalIdentifierException(url);
+ }
+ if (i != 1) {
+ buf.append('/');
+ }
+ buf.append(seg);
+ if (j == path.getLength()) {
+ break;
+ }
+ i = j + 1;
+ }
+ auto decPath(buf.makeStringAndClear());
+ OUString lang;
+ if (uri->hasQuery()) {
+ if (!uri->getQuery().startsWith("lang=", &lang)) {
+ throw css::ucb::IllegalIdentifierException(url);
+ }
+ lang = rtl::Uri::decode(
+ lang, rtl_UriDecodeStrict, RTL_TEXTENCODING_UTF8);
+ if (lang.isEmpty()) {
+ throw css::ucb::IllegalIdentifierException(url);
+ }
+ }
+ OUString newUrl;
+ {
+ SolarMutexGuard g;
+ newUrl = ImplImageTree::get().getImageUrl(decPath, auth, lang);
+ }
+ ucbhelper::Content content;
+ return
+ ucbhelper::Content::create(
+ newUrl, css::uno::Reference<css::ucb::XCommandEnvironment>(),
+ context, content)
+ ? content.get() : css::uno::Reference<css::ucb::XContent>();
+ }
+
+ sal_Int32 SAL_CALL compareContentIds(
+ css::uno::Reference<css::ucb::XContentIdentifier> const & Id1,
+ css::uno::Reference<css::ucb::XContentIdentifier> const & Id2)
+ throw (css::uno::RuntimeException, std::exception) override
+ {
+ return Id1->getContentIdentifier().compareTo(
+ Id2->getContentIdentifier());
+ }
+
+ void SAL_CALL disposing() override {
+ context_.clear();
+ }
+
+ css::uno::Reference<css::uno::XComponentContext> context_;
+};
+
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
+com_sun_star_comp_ucb_ImageContentProvider_get_implementation(
+ css::uno::XComponentContext * context,
+ css::uno::Sequence<css::uno::Any> const &)
+{
+ return cppu::acquire(new Provider(context));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */