diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2015-10-26 17:55:14 +0100 |
---|---|---|
committer | Michael Stahl <mstahl@redhat.com> | 2015-10-28 16:21:26 +0000 |
commit | 74453dbed460c0c428ce989b07a65d5cac5db49a (patch) | |
tree | 9bd0b80d60d8e4ce27fc1df2fd475bea060c5a3d /ucb | |
parent | 4df5049cb5e6cf8c31861d8ab4a4a49e5167efee (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.mk | 33 | ||||
-rw-r--r-- | ucb/Module_ucb.mk | 1 | ||||
-rw-r--r-- | ucb/source/ucp/image/ucpimage.component | 17 | ||||
-rw-r--r-- | ucb/source/ucp/image/ucpimage.cxx | 172 |
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: */ |