[Libreoffice-commits] core.git: include/vcl officecfg/registry postprocess/Rdb_services.mk Repository.mk ucb/Library_ucpimage.mk ucb/Module_ucb.mk ucb/source vcl/inc vcl/osx vcl/source xmlhelp/source xmlhelp/util

Stephan Bergmann sbergman at redhat.com
Mon Oct 26 17:01:01 UTC 2015


 Repository.mk                                                |    1 
 include/vcl/implimagetree.hxx                                |  121 +++++++
 officecfg/registry/data/org/openoffice/ucb/Configuration.xcu |   11 
 postprocess/Rdb_services.mk                                  |    1 
 ucb/Library_ucpimage.mk                                      |   33 ++
 ucb/Module_ucb.mk                                            |    1 
 ucb/source/ucp/image/ucpimage.component                      |   17 +
 ucb/source/ucp/image/ucpimage.cxx                            |  172 +++++++++++
 vcl/inc/impimagetree.hxx                                     |  117 -------
 vcl/osx/vclnsapp.mm                                          |    4 
 vcl/source/app/settings.cxx                                  |    2 
 vcl/source/app/svmain.cxx                                    |    4 
 vcl/source/control/fixed.cxx                                 |    6 
 vcl/source/gdi/bitmapex.cxx                                  |    6 
 vcl/source/gdi/image.cxx                                     |    6 
 vcl/source/gdi/imagerepository.cxx                           |    8 
 vcl/source/gdi/impimagetree.cxx                              |   71 ++++
 xmlhelp/source/cxxhelp/provider/databases.cxx                |  122 +------
 xmlhelp/source/cxxhelp/provider/databases.hxx                |    6 
 xmlhelp/source/cxxhelp/provider/provider.cxx                 |   14 
 xmlhelp/source/cxxhelp/provider/urlparameter.cxx             |    4 
 xmlhelp/util/main_transform.xsl                              |   53 ---
 22 files changed, 470 insertions(+), 310 deletions(-)

New commits:
commit 6948c546fdc00dddec7d58e03150dcc87921d6b2
Author: Stephan Bergmann <sbergman at redhat.com>
Date:   Mon Oct 26 17:55:14 2015 +0100

    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.
    
    Change-Id: Ic1c15fcacb6596a27a2b051093232902202bf472

diff --git a/Repository.mk b/Repository.mk
index 1a57f30..4399aa5 100644
--- a/Repository.mk
+++ b/Repository.mk
@@ -416,6 +416,7 @@ $(eval $(call gb_Helper_register_libraries_for_install,OOOLIBS,ooo, \
 	$(if $(ENABLE_TELEPATHY),tubes) \
 	ucpexpand1 \
 	ucpext \
+	ucpimage \
 	ucpcmis1 \
 	ucptdoc1 \
 	unordf \
diff --git a/vcl/inc/impimagetree.hxx b/include/vcl/implimagetree.hxx
similarity index 89%
rename from vcl/inc/impimagetree.hxx
rename to include/vcl/implimagetree.hxx
index 2ee52c8..ffab4a8 100644
--- a/vcl/inc/impimagetree.hxx
+++ b/include/vcl/implimagetree.hxx
@@ -17,30 +17,36 @@
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
 
-#ifndef INCLUDED_VCL_INC_IMPIMAGETREE_HXX
-#define INCLUDED_VCL_INC_IMPIMAGETREE_HXX
+#ifndef INCLUDED_INCLUDE_VCL_IMPLIMAGETREE_HXX
+#define INCLUDED_INCLUDE_VCL_IMPLIMAGETREE_HXX
 
-#include "sal/config.h"
+#include <sal/config.h>
 
 #include <memory>
 #include <unordered_map>
+#include <utility>
 #include <vector>
 
-#include "com/sun/star/uno/Reference.hxx"
-#include "rtl/ustring.hxx"
-#include "salhelper/singletonref.hxx"
+#include <com/sun/star/uno/Reference.hxx>
+#include <rtl/ustring.hxx>
+#include <vcl/bitmapex.hxx>
+#include <vcl/dllapi.h>
 
 namespace com { namespace sun { namespace star { namespace container {
     class XNameAccess;
 } } } }
-class BitmapEx;
 
 class ImplImageTree {
 public:
+    VCL_DLLPUBLIC static ImplImageTree & get();
+
     ImplImageTree();
 
     ~ImplImageTree();
 
+    VCL_DLLPUBLIC OUString getImageUrl(
+        OUString const & name, OUString const & style, OUString const & lang);
+
     bool loadImage(
         OUString const & name, OUString const & style,
         BitmapEx & bitmap, bool localized = false, bool loadMissing = false );
@@ -110,8 +116,6 @@ private:
     static OUString fallbackStyle(const OUString &style);
 };
 
-typedef salhelper::SingletonRef< ImplImageTree > ImplImageTreeSingletonRef;
-
 #endif
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/officecfg/registry/data/org/openoffice/ucb/Configuration.xcu b/officecfg/registry/data/org/openoffice/ucb/Configuration.xcu
index f10ddbf..ff38a79 100644
--- a/officecfg/registry/data/org/openoffice/ucb/Configuration.xcu
+++ b/officecfg/registry/data/org/openoffice/ucb/Configuration.xcu
@@ -179,6 +179,17 @@
                 <value/>
               </prop>
             </node>
+            <node oor:name="Provider16" oor:op="replace">
+              <prop oor:name="ServiceName">
+                <value>com.sun.star.ucb.ImageContentProvider</value>
+              </prop>
+              <prop oor:name="URLTemplate">
+                <value>vnd.libreoffice.image</value>
+              </prop>
+              <prop oor:name="Arguments">
+                <value/>
+              </prop>
+            </node>
             <node oor:name="Provider900" oor:op="replace">
               <prop oor:name="ServiceName">
                 <value/>
diff --git a/postprocess/Rdb_services.mk b/postprocess/Rdb_services.mk
index 5e703b2..1974b59 100644
--- a/postprocess/Rdb_services.mk
+++ b/postprocess/Rdb_services.mk
@@ -98,6 +98,7 @@ $(eval $(call gb_Rdb_add_components,services,\
 	ucb/source/ucp/file/ucpfile1 \
 	$(if $(ENABLE_CURL),ucb/source/ucp/ftp/ucpftp1) \
 	ucb/source/ucp/hierarchy/ucphier1 \
+	ucb/source/ucp/image/ucpimage \
 	ucb/source/ucp/package/ucppkg1 \
 	ucb/source/ucp/tdoc/ucptdoc1 \
 	UnoControls/util/ctl \
diff --git a/ucb/Library_ucpimage.mk b/ucb/Library_ucpimage.mk
new file mode 100644
index 0000000..9c683f7
--- /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 a143aca..990161c 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 0000000..6dba0dd
--- /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 0000000..fb3acff
--- /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: */
diff --git a/vcl/osx/vclnsapp.mm b/vcl/osx/vclnsapp.mm
index 2614754..fd0d583 100644
--- a/vcl/osx/vclnsapp.mm
+++ b/vcl/osx/vclnsapp.mm
@@ -24,10 +24,10 @@
 
 #include <sal/main.h>
 #include <vcl/cmdevt.hxx>
+#include <vcl/implimagetree.hxx>
 #include <vcl/svapp.hxx>
 #include <vcl/window.hxx>
 
-#include "impimagetree.hxx"
 #include "osx/saldata.hxx"
 #include "osx/salframe.h"
 #include "osx/salframeview.h"
@@ -412,7 +412,7 @@
         {
             ApplicationEvent aEv(ApplicationEvent::TYPE_PRIVATE_DOSHUTDOWN);
             GetpApp()->AppEvent( aEv );
-            ImplImageTreeSingletonRef()->shutDown();
+            ImplImageTree::get().shutDown();
             // DeInitVCL should be called in ImplSVMain - unless someon _exits first which
             // can occur in Desktop::doShutdown for example
         }
diff --git a/vcl/source/app/settings.cxx b/vcl/source/app/settings.cxx
index a8fb56a..2fd7597 100644
--- a/vcl/source/app/settings.cxx
+++ b/vcl/source/app/settings.cxx
@@ -42,6 +42,7 @@
 #include <vcl/event.hxx>
 #include <vcl/settings.hxx>
 #include <vcl/i18nhelp.hxx>
+#include <vcl/implimagetree.hxx>
 #include <vcl/configsettings.hxx>
 #include <vcl/gradient.hxx>
 #include <vcl/outdev.hxx>
@@ -56,7 +57,6 @@
 using namespace ::com::sun::star;
 
 #include "svdata.hxx"
-#include "impimagetree.hxx"
 
 struct ImplMouseData
 {
diff --git a/vcl/source/app/svmain.cxx b/vcl/source/app/svmain.cxx
index d2fe69a..684546f 100644
--- a/vcl/source/app/svmain.cxx
+++ b/vcl/source/app/svmain.cxx
@@ -35,6 +35,7 @@
 #include "vcl/cvtgrf.hxx"
 #include "vcl/scheduler.hxx"
 #include "vcl/image.hxx"
+#include "vcl/implimagetree.hxx"
 #include "vcl/settings.hxx"
 #include "vcl/unowrap.hxx"
 #include "vcl/configsettings.hxx"
@@ -68,7 +69,6 @@
 #include "salsys.hxx"
 #include "saltimer.hxx"
 #include "salimestatus.hxx"
-#include "impimagetree.hxx"
 #include "xconnection.hxx"
 
 #include "vcl/opengl/OpenGLContext.hxx"
@@ -368,7 +368,7 @@ void DeInitVCL()
     DBG_ASSERT( nBadTopWindows==0, aBuf.getStr() );
 #endif
 
-    ImplImageTreeSingletonRef()->shutDown();
+    ImplImageTree::get().shutDown();
 
     osl_removeSignalHandler( pExceptionHandler);
     pExceptionHandler = NULL;
diff --git a/vcl/source/control/fixed.cxx b/vcl/source/control/fixed.cxx
index 990f1a6..9502c08 100644
--- a/vcl/source/control/fixed.cxx
+++ b/vcl/source/control/fixed.cxx
@@ -23,12 +23,12 @@
 #include "vcl/dialog.hxx"
 #include "vcl/event.hxx"
 #include "vcl/fixed.hxx"
+#include "vcl/implimagetree.hxx"
 #include "vcl/svapp.hxx"
 #include "vcl/settings.hxx"
 
 #include <comphelper/string.hxx>
 #include "controldata.hxx"
-#include "impimagetree.hxx"
 #include "window.h"
 
 #define FIXEDLINE_TEXT_BORDER    4
@@ -1035,12 +1035,12 @@ bool FixedImage::SetModeImage( const Image& rImage )
 
 Image FixedImage::loadThemeImage(const OString &rFileName)
 {
-    static ImplImageTreeSingletonRef aImageTree;
     OUString sIconTheme =
         Application::GetSettings().GetStyleSettings().DetermineIconTheme();
     const OUString sFileName(OStringToOUString(rFileName, RTL_TEXTENCODING_UTF8));
     BitmapEx aBitmap;
-    bool bSuccess = aImageTree->loadImage(sFileName, sIconTheme, aBitmap, true);
+    bool bSuccess = ImplImageTree::get().loadImage(
+        sFileName, sIconTheme, aBitmap, true);
     SAL_WARN_IF(!bSuccess, "vcl.layout", "Unable to load " << sFileName
         << " from theme " << sIconTheme);
     return Image(aBitmap);
diff --git a/vcl/source/gdi/bitmapex.cxx b/vcl/source/gdi/bitmapex.cxx
index 804e646..8fa12114 100644
--- a/vcl/source/gdi/bitmapex.cxx
+++ b/vcl/source/gdi/bitmapex.cxx
@@ -24,6 +24,7 @@
 #include <tools/stream.hxx>
 #include <tools/debug.hxx>
 #include <tools/rc.h>
+#include <vcl/implimagetree.hxx>
 #include <vcl/salbtype.hxx>
 #include <vcl/outdev.hxx>
 #include <vcl/alpha.hxx>
@@ -36,7 +37,6 @@
 #include <vcl/settings.hxx>
 
 #include <image.h>
-#include <impimagetree.hxx>
 #include <basegfx/matrix/b2dhommatrixtools.hxx>
 
 // BitmapEx::Create
@@ -107,11 +107,9 @@ BitmapEx::BitmapEx( const ResId& rResId ) :
 
 void BitmapEx::loadFromIconTheme( const OUString& rIconName )
 {
-    static ImplImageTreeSingletonRef aImageTree;
-
     OUString aIconTheme = Application::GetSettings().GetStyleSettings().DetermineIconTheme();
 
-    if( !aImageTree->loadImage( rIconName, aIconTheme, *this, true ) )
+    if( !ImplImageTree::get().loadImage( rIconName, aIconTheme, *this, true ) )
     {
 #ifdef DBG_UTIL
         OStringBuffer aErrorStr(
diff --git a/vcl/source/gdi/image.cxx b/vcl/source/gdi/image.cxx
index adfec17..f6e70cf 100644
--- a/vcl/source/gdi/image.cxx
+++ b/vcl/source/gdi/image.cxx
@@ -30,7 +30,7 @@
 #include <vcl/svapp.hxx>
 #include <vcl/image.hxx>
 #include <vcl/imagerepository.hxx>
-#include <impimagetree.hxx>
+#include <vcl/implimagetree.hxx>
 #include <image.h>
 
 #if OSL_DEBUG_LEVEL > 0
@@ -370,8 +370,6 @@ void ImageList::ImplInit( sal_uInt16 nItems, const Size &rSize )
 
 void ImageAryData::Load(const OUString &rPrefix)
 {
-    static ImplImageTreeSingletonRef aImageTree;
-
     OUString aIconTheme = Application::GetSettings().GetStyleSettings().DetermineIconTheme();
 
     OUString aFileName = rPrefix;
@@ -379,7 +377,7 @@ void ImageAryData::Load(const OUString &rPrefix)
 #if OSL_DEBUG_LEVEL > 0
     bool bSuccess =
 #endif
-        aImageTree->loadImage( aFileName, aIconTheme, maBitmapEx, true );
+        ImplImageTree::get().loadImage(aFileName, aIconTheme, maBitmapEx, true);
 #if OSL_DEBUG_LEVEL > 0
     if ( !bSuccess )
     {
diff --git a/vcl/source/gdi/imagerepository.cxx b/vcl/source/gdi/imagerepository.cxx
index 66398d9..dadc622 100644
--- a/vcl/source/gdi/imagerepository.cxx
+++ b/vcl/source/gdi/imagerepository.cxx
@@ -19,9 +19,9 @@
 
 #include <vcl/bitmapex.hxx>
 #include <vcl/imagerepository.hxx>
+#include <vcl/implimagetree.hxx>
 #include <vcl/settings.hxx>
 #include <vcl/svapp.hxx>
-#include "impimagetree.hxx"
 
 namespace vcl
 {
@@ -29,15 +29,13 @@ namespace vcl
     {
         OUString sIconTheme = Application::GetSettings().GetStyleSettings().DetermineIconTheme();
 
-        ImplImageTreeSingletonRef aImplImageTree;
-        return aImplImageTree->loadImage( _rName, sIconTheme, _out_rImage, _bSearchLanguageDependent, loadMissing );
+        return ImplImageTree::get().loadImage( _rName, sIconTheme, _out_rImage, _bSearchLanguageDependent, loadMissing );
     }
 
     bool ImageRepository::loadDefaultImage( BitmapEx& _out_rImage)
     {
         OUString sIconTheme = Application::GetSettings().GetStyleSettings().DetermineIconTheme();
-        ImplImageTreeSingletonRef aImplImageTree;
-        return aImplImageTree->loadDefaultImage( sIconTheme,_out_rImage);
+        return ImplImageTree::get().loadDefaultImage( sIconTheme,_out_rImage);
     }
 
 } // namespace vcl
diff --git a/vcl/source/gdi/impimagetree.cxx b/vcl/source/gdi/impimagetree.cxx
index 38cfefd..9bec5dc 100644
--- a/vcl/source/gdi/impimagetree.cxx
+++ b/vcl/source/gdi/impimagetree.cxx
@@ -34,15 +34,16 @@
 #include "osl/file.hxx"
 #include "osl/diagnose.h"
 #include "rtl/bootstrap.hxx"
+#include "rtl/uri.hxx"
 
 #include "tools/stream.hxx"
 #include "tools/urlobj.hxx"
 #include "vcl/bitmapex.hxx"
 #include <vcl/dibtools.hxx>
+#include <vcl/implimagetree.hxx>
 #include "vcl/pngread.hxx"
 #include "vcl/settings.hxx"
 #include "vcl/svapp.hxx"
-#include "impimagetree.hxx"
 #include <vcldemo-debug.hxx>
 
 #include <vcl/BitmapProcessor.hxx>
@@ -93,6 +94,11 @@ static void loadImageFromStream(std::shared_ptr<SvStream> xStream, OUString cons
 
 }
 
+ImplImageTree & ImplImageTree::get() {
+    static ImplImageTree instance;
+    return instance;
+}
+
 ImplImageTree::ImplImageTree()
 {
 }
@@ -101,6 +107,65 @@ ImplImageTree::~ImplImageTree()
 {
 }
 
+OUString ImplImageTree::getImageUrl(
+    OUString const & name, OUString const & style, OUString const & lang)
+{
+    OUString aStyle(style);
+    while (!aStyle.isEmpty())
+    {
+        try {
+            setStyle(aStyle);
+
+            std::vector< OUString > paths;
+            paths.push_back(getRealImageName(name));
+
+            if (!lang.isEmpty())
+            {
+                sal_Int32 pos = name.lastIndexOf('/');
+                if (pos != -1)
+                {
+                    std::vector<OUString> aFallbacks(
+                        LanguageTag(lang).getFallbackStrings(true));
+                    for (std::vector< OUString >::reverse_iterator it( aFallbacks.rbegin());
+                         it != aFallbacks.rend(); ++it)
+                    {
+                        paths.push_back( getRealImageName( createPath(name, pos, *it) ) );
+                    }
+                }
+            }
+
+            try {
+                if (checkPathAccess()) {
+                    const uno::Reference<container::XNameAccess> &rNameAccess = maIconSet[maCurrentStyle].maNameAccess;
+
+                    for (std::vector<OUString>::const_reverse_iterator j(paths.rbegin()); j != paths.rend(); ++j)
+                    {
+                        if (rNameAccess->hasByName(*j))
+                        {
+                            return "vnd.sun.star.zip://"
+                                + rtl::Uri::encode(
+                                    maIconSet[maCurrentStyle].maURL + ".zip",
+                                    rtl_UriCharClassRegName,
+                                    rtl_UriEncodeIgnoreEscapes,
+                                    RTL_TEXTENCODING_UTF8)
+                                + "/" + *j;
+                                // assuming *j contains no problematic chars
+                        }
+                    }
+                }
+            } catch (css::uno::RuntimeException &) {
+                throw;
+            } catch (const css::uno::Exception & e) {
+                SAL_INFO("vcl", "exception " << e.Message);
+            }
+        }
+        catch (css::uno::RuntimeException &) {}
+
+        aStyle = fallbackStyle(aStyle);
+    }
+    return OUString();
+}
+
 OUString ImplImageTree::fallbackStyle(const OUString &style)
 {
     if (style == "galaxy")
@@ -361,9 +426,7 @@ css::uno::Reference<css::container::XNameAccess> ImplImageTree::getNameAccess()
 /// Recursively dump all names ...
 css::uno::Sequence<OUString> ImageTree_getAllImageNames()
 {
-    static ImplImageTreeSingletonRef aImageTree;
-
-    css::uno::Reference<css::container::XNameAccess> xRef(aImageTree->getNameAccess());
+    css::uno::Reference<css::container::XNameAccess> xRef(ImplImageTree::get().getNameAccess());
 
     return xRef->getElementNames();
 }
diff --git a/xmlhelp/source/cxxhelp/provider/databases.cxx b/xmlhelp/source/cxxhelp/provider/databases.cxx
index 908fdab..5f2d0b9 100644
--- a/xmlhelp/source/cxxhelp/provider/databases.cxx
+++ b/xmlhelp/source/cxxhelp/provider/databases.cxx
@@ -120,7 +120,6 @@ OUString Databases::expandURL( const OUString& aURL, Reference< uno::XComponentC
 
 Databases::Databases( bool showBasic,
                       const OUString& instPath,
-                      const com::sun::star::uno::Sequence< OUString >& imagesZipPaths,
                       const OUString& productName,
                       const OUString& productVersion,
                       const OUString& styleSheet,
@@ -137,9 +136,7 @@ Databases::Databases( bool showBasic,
       prodVersion( "%PRODUCTVERSION" ),
       vendName( "%VENDORNAME" ),
       vendVersion( "%VENDORVERSION" ),
-      vendShort( "%VENDORSHORT" ),
-      m_aImagesZipPaths( imagesZipPaths ),
-      m_aSymbolsStyleName( "" )
+      vendShort( "%VENDORSHORT" )
 {
     m_xSMgr = Reference< XMultiComponentFactory >( m_xContext->getServiceManager(), UNO_QUERY );
 
@@ -207,106 +204,33 @@ Databases::~Databases()
     }
 }
 
-static bool impl_getZipFile(
-        Sequence< OUString > & rImagesZipPaths,
-        const OUString & rZipName,
-        OUString & rFileName )
-{
-    OUString aWorkingDir;
-    osl_getProcessWorkingDir( &aWorkingDir.pData );
-    const OUString *pPathArray = rImagesZipPaths.getArray();
-    for ( int i = 0; i < rImagesZipPaths.getLength(); ++i )
-    {
-        OUString aFileName = pPathArray[ i ];
-        if ( !aFileName.isEmpty() )
-        {
-            if ( !aFileName.endsWith("/") )
-            {
-                aFileName += "/";
-            }
-            aFileName += rZipName;
-            // the icons are not read when the URL is a symlink
-            osl::File::getAbsoluteFileURL( aWorkingDir, aFileName, rFileName );
-
-            // test existence
-            osl::DirectoryItem aDirItem;
-            if ( osl::DirectoryItem::get( rFileName, aDirItem ) == osl::FileBase::E_None )
-                return true;
-        }
-    }
-    return false;
-}
-
-OString Databases::getImagesZipFileURL()
+OString Databases::getImageTheme()
 {
+    uno::Reference< lang::XMultiServiceFactory > xConfigProvider =
+        configuration::theDefaultProvider::get(m_xContext);
+
+    // set root path
+    uno::Sequence < uno::Any > lParams(1);
+    beans::PropertyValue                       aParam ;
+    aParam.Name    = "nodepath";
+    aParam.Value <<= OUString("org.openoffice.Office.Common");
+    lParams[0] = uno::makeAny(aParam);
+
+    // open it
+    uno::Reference< uno::XInterface > xCFG( xConfigProvider->createInstanceWithArguments(
+                OUString("com.sun.star.configuration.ConfigurationAccess"),
+                lParams) );
+
+    uno::Reference< container::XHierarchicalNameAccess > xAccess(xCFG, uno::UNO_QUERY_THROW);
+    uno::Any aResult = xAccess->getByHierarchicalName(OUString("Misc/SymbolStyle"));
     OUString aSymbolsStyleName;
-    try
-    {
-        uno::Reference< lang::XMultiServiceFactory > xConfigProvider =
-            configuration::theDefaultProvider::get(m_xContext);
-
-        // set root path
-        uno::Sequence < uno::Any > lParams(1);
-        beans::PropertyValue                       aParam ;
-        aParam.Name    = "nodepath";
-        aParam.Value <<= OUString("org.openoffice.Office.Common");
-        lParams[0] = uno::makeAny(aParam);
-
-        // open it
-        uno::Reference< uno::XInterface > xCFG( xConfigProvider->createInstanceWithArguments(
-                    OUString("com.sun.star.configuration.ConfigurationAccess"),
-                    lParams) );
-
-        bool bChanged = false;
-        uno::Reference< container::XHierarchicalNameAccess > xAccess(xCFG, uno::UNO_QUERY_THROW);
-        uno::Any aResult = xAccess->getByHierarchicalName(OUString("Misc/SymbolStyle"));
-        if ( (aResult >>= aSymbolsStyleName) && m_aSymbolsStyleName != aSymbolsStyleName )
-        {
-            m_aSymbolsStyleName = aSymbolsStyleName;
-            bChanged = true;
-        }
-
-        if ( m_aImagesZipFileURL.isEmpty() || bChanged )
-        {
-            OUString aImageZip;
-            bool bFound = false;
-
-            if ( !aSymbolsStyleName.isEmpty() )
-            {
-                if ( aSymbolsStyleName == "auto" )
-                {
-                    // with the layered images*.zip, tango is the most
-                    // complete theme, so show that one
-                    // FIXME instead of using a general vnd.sun.star.zip://
-                    // for imgrepos, we should have some vnd.sun.star.image://
-                    // so that we don't have to re-open the stream for every
-                    // image in the help
-                    aSymbolsStyleName = "tango";
-                }
-                OUString aZipName = "images_" + aSymbolsStyleName + ".zip";
+    aResult >>= aSymbolsStyleName;
 
-                bFound = impl_getZipFile( m_aImagesZipPaths, aZipName, aImageZip );
-            }
-
-            if ( ! bFound )
-                bFound = impl_getZipFile( m_aImagesZipPaths, OUString( "images.zip" ), aImageZip );
-
-            if ( ! bFound )
-                aImageZip.clear();
-
-            m_aImagesZipFileURL = OUStringToOString(
-                        rtl::Uri::encode(
-                            aImageZip,
-                            rtl_UriCharClassPchar,
-                            rtl_UriEncodeIgnoreEscapes,
-                            RTL_TEXTENCODING_UTF8 ), RTL_TEXTENCODING_UTF8 );
-        }
-    }
-    catch ( NoSuchElementException const & )
+    if ( aSymbolsStyleName.isEmpty() || aSymbolsStyleName == "auto" )
     {
+        aSymbolsStyleName = "tango";
     }
-
-    return m_aImagesZipFileURL;
+    return aSymbolsStyleName.toUtf8();
 }
 
 void Databases::replaceName( OUString& oustring ) const
diff --git a/xmlhelp/source/cxxhelp/provider/databases.hxx b/xmlhelp/source/cxxhelp/provider/databases.hxx
index 9e33a98..9b331cc 100644
--- a/xmlhelp/source/cxxhelp/provider/databases.hxx
+++ b/xmlhelp/source/cxxhelp/provider/databases.hxx
@@ -140,7 +140,6 @@ namespace chelp {
 
         Databases( bool showBasic,
                  const OUString& instPath,
-                 const com::sun::star::uno::Sequence< OUString >& imagesZipPaths,
                  const OUString& productName,
                  const OUString& productVersion,
                  const OUString& styleSheet,
@@ -148,7 +147,7 @@ namespace chelp {
 
         ~Databases();
 
-        OString getImagesZipFileURL();
+        OString getImageTheme();
 
         OUString getInstallPathAsURL();
 
@@ -265,9 +264,6 @@ namespace chelp {
             prodName,prodVersion,vendName,vendVersion,vendShort;
 
         OUString          m_aInstallDirectory;                // Installation directory
-        com::sun::star::uno::Sequence< OUString > m_aImagesZipPaths;
-        OString           m_aImagesZipFileURL;
-        OUString          m_aSymbolsStyleName;
 
         std::vector< OUString >    m_avModules;
 
diff --git a/xmlhelp/source/cxxhelp/provider/provider.cxx b/xmlhelp/source/cxxhelp/provider/provider.cxx
index 781554d..95b1c6d 100644
--- a/xmlhelp/source/cxxhelp/provider/provider.cxx
+++ b/xmlhelp/source/cxxhelp/provider/provider.cxx
@@ -35,7 +35,6 @@
 #include <cppuhelper/supportsservice.hxx>
 #include <unotools/configmgr.hxx>
 #include <unotools/pathoptions.hxx>
-#include <rtl/bootstrap.hxx>
 
 #include "databases.hxx"
 #include "provider.hxx"
@@ -324,22 +323,9 @@ void ContentProvider::init()
     }
 
     OUString productversion( setupversion + " " + setupextension );
-
-    uno::Sequence< OUString > aImagesZipPaths( 2 );
-    xHierAccess = getHierAccess( sProvider,  "org.openoffice.Office.Common" );
-
-    OUString aPath( getKey( xHierAccess, "Path/Current/UserConfig" ) );
-    subst( aPath );
-    aImagesZipPaths[ 0 ] = aPath;
-
-    aPath = "$BRAND_BASE_DIR/$BRAND_SHARE_SUBDIR/config";
-    rtl::Bootstrap::expandMacros(aPath);
-    aImagesZipPaths[ 1 ] = aPath;
-
     bool showBasic = getBooleanKey(xHierAccess,"Help/ShowBasic");
     m_pDatabases = new Databases( showBasic,
                                   instPath,
-                                  aImagesZipPaths,
                                   utl::ConfigManager::getProductName(),
                                   productversion,
                                   stylesheet,
diff --git a/xmlhelp/source/cxxhelp/provider/urlparameter.cxx b/xmlhelp/source/cxxhelp/provider/urlparameter.cxx
index 14f6240..72a57d1 100644
--- a/xmlhelp/source/cxxhelp/provider/urlparameter.cxx
+++ b/xmlhelp/source/cxxhelp/provider/urlparameter.cxx
@@ -890,8 +890,8 @@ InputStreamTransformer::InputStreamTransformer( URLParameter* urlParam,
                           pDatabases->getProductVersion().getLength(),
                           RTL_TEXTENCODING_UTF8 ) + OString('\'');
 
-        parString[last++] = "imgrepos";
-        parString[last++] = OString('\'') + pDatabases->getImagesZipFileURL() + OString('\'');
+        parString[last++] = "imgtheme";
+        parString[last++] = OString('\'') + pDatabases->getImageTheme() + OString('\'');
         parString[last++] = "hp";
         parString[last++] = OString('\'') + urlParam->getByName( "HelpPrefix" ) + OString('\'');
 
diff --git a/xmlhelp/util/main_transform.xsl b/xmlhelp/util/main_transform.xsl
index b6b9c2e..b30effe 100644
--- a/xmlhelp/util/main_transform.xsl
+++ b/xmlhelp/util/main_transform.xsl
@@ -99,7 +99,7 @@
 	<xsl:value-of select="translate($productversion,' ','')"/>
 </xsl:variable>
 <!-- this is were the images are -->
-<xsl:param name="imgrepos" select="''"/>
+<xsl:param name="imgtheme" select="''"/>
 <xsl:param name="Id" />
 <xsl:param name="Language" select="'en-US'"/>
 <xsl:variable name="lang" select="$Language"/>
@@ -110,7 +110,7 @@
 
   <!-- parts of help and image urls -->
 <xsl:variable name="help_url_prefix" select="'vnd.sun.star.help://'"/>
-<xsl:variable name="img_url_prefix" select="concat('vnd.sun.star.zip://',$imgrepos,'/')"/>
+<xsl:variable name="img_url_prefix" select="concat('vnd.libreoffice.image://',$imgtheme,'/')"/>
 <xsl:variable name="urlpost" select="concat('?Language=',$lang,$am,'System=',$System,$am,'UseDB=no')"/>
 <xsl:variable name="urlpre" select="$help_url_prefix" /> 
 <xsl:variable name="linkprefix" select="$urlpre"/>
@@ -801,19 +801,6 @@
 
 <!-- Insert an image -->
 <xsl:template name="insertimage">
-	
-	<xsl:variable name="fpath">
-		<xsl:call-template name="getfpath">
-			<xsl:with-param name="s"><xsl:value-of select="@src"/></xsl:with-param>
-		</xsl:call-template>
-	</xsl:variable>
-	
-	<xsl:variable name="fname">
-		<xsl:call-template name="getfname">
-			<xsl:with-param name="s"><xsl:value-of select="@src"/></xsl:with-param>
-		</xsl:call-template>
-	</xsl:variable>
-
   <xsl:variable name="src">
     <xsl:choose>
       <xsl:when test="not($ExtensionId='') and starts-with(@src,$ExtensionId)">
@@ -821,11 +808,11 @@
       </xsl:when>
       <xsl:otherwise>
         <xsl:choose>
-          <xsl:when test="(@localize='true') and not($lang='en-US')">
-            <xsl:value-of select="concat($img_url_prefix,$fpath,$lang,'/',$fname)"/>
+          <xsl:when test="@localize='true'">
+            <xsl:value-of select="concat($img_url_prefix, at src,'?lang=',$lang)"/>
           </xsl:when>
           <xsl:otherwise>
-            <xsl:value-of select="concat($img_url_prefix,$fpath,$fname)"/>
+            <xsl:value-of select="concat($img_url_prefix, at src)"/>
           </xsl:otherwise>
         </xsl:choose>
       </xsl:otherwise>
@@ -931,36 +918,6 @@
 	</xsl:choose>
 </xsl:template>
 
-<xsl:template name="getfpath">
-	<xsl:param name="s"/>
-	<xsl:param name="p"/>
-	<xsl:choose>
-		<xsl:when test="contains($s,'/')">
-			<xsl:call-template name="getfpath">
-				<xsl:with-param name="p"><xsl:value-of select="concat($p,substring-before($s,'/'),'/')"/></xsl:with-param>
-				<xsl:with-param name="s"><xsl:value-of select="substring-after($s,'/')"/></xsl:with-param>
-			</xsl:call-template>
-		</xsl:when>
-		<xsl:otherwise>
-			<xsl:value-of select="$p"/>
-		</xsl:otherwise>
-	</xsl:choose>
-</xsl:template>
-
-<xsl:template name="getfname">
-	<xsl:param name="s"/>
-	<xsl:choose>
-		<xsl:when test="contains($s,'/')">
-			<xsl:call-template name="getfname">
-				<xsl:with-param name="s"><xsl:value-of select="substring-after($s,'/')"/></xsl:with-param>
-			</xsl:call-template>
-		</xsl:when>
-		<xsl:otherwise>
-			<xsl:value-of select="$s"/>
-		</xsl:otherwise>
-	</xsl:choose>
-</xsl:template>
-
 <xsl:template name="createDBpostfix">
 	<xsl:param name="archive"/>
 	<xsl:variable name="newDB">


More information about the Libreoffice-commits mailing list