summaryrefslogtreecommitdiffstats
path: root/shell/source/backends
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 05:54:39 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 05:54:39 +0000
commit267c6f2ac71f92999e969232431ba04678e7437e (patch)
tree358c9467650e1d0a1d7227a21dac2e3d08b622b2 /shell/source/backends
parentInitial commit. (diff)
downloadlibreoffice-267c6f2ac71f92999e969232431ba04678e7437e.tar.xz
libreoffice-267c6f2ac71f92999e969232431ba04678e7437e.zip
Adding upstream version 4:24.2.0.upstream/4%24.2.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--shell/source/backends/desktopbe/desktopbackend.cxx299
-rw-r--r--shell/source/backends/desktopbe/desktopbe1.component26
-rw-r--r--shell/source/backends/kf5be/kf5access.cxx261
-rw-r--r--shell/source/backends/kf5be/kf5access.hxx41
-rw-r--r--shell/source/backends/kf5be/kf5backend.cxx257
-rw-r--r--shell/source/backends/kf5be/kf5be1.component26
-rw-r--r--shell/source/backends/localebe/localebackend.cxx332
-rw-r--r--shell/source/backends/localebe/localebackend.hxx106
-rw-r--r--shell/source/backends/localebe/localebe1.component26
-rw-r--r--shell/source/backends/macbe/macbackend.hxx90
-rw-r--r--shell/source/backends/macbe/macbackend.mm359
-rw-r--r--shell/source/backends/macbe/macbe1.component26
-rw-r--r--shell/source/backends/wininetbe/wininetbackend.cxx338
-rw-r--r--shell/source/backends/wininetbe/wininetbackend.hxx110
-rw-r--r--shell/source/backends/wininetbe/wininetbe1.component26
15 files changed, 2323 insertions, 0 deletions
diff --git a/shell/source/backends/desktopbe/desktopbackend.cxx b/shell/source/backends/desktopbe/desktopbackend.cxx
new file mode 100644
index 0000000000..c9a9d8dafc
--- /dev/null
+++ b/shell/source/backends/desktopbe/desktopbackend.cxx
@@ -0,0 +1,299 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+#include <sal/log.hxx>
+
+#include <com/sun/star/beans/Optional.hpp>
+#include <com/sun/star/beans/UnknownPropertyException.hpp>
+#include <com/sun/star/beans/XPropertyChangeListener.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/XPropertySetInfo.hpp>
+#include <com/sun/star/beans/XVetoableChangeListener.hpp>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <com/sun/star/lang/XMultiComponentFactory.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Exception.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/RuntimeException.hpp>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/uno/XCurrentContext.hpp>
+#include <cppuhelper/implbase.hxx>
+#include <cppuhelper/weak.hxx>
+#include <osl/file.hxx>
+#include <osl/security.hxx>
+#include <rtl/byteseq.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <rtl/ustring.hxx>
+#include <sal/types.h>
+#include <comphelper/diagnose_ex.hxx>
+#include <uno/current_context.hxx>
+
+namespace {
+
+class Default:
+ public cppu::WeakImplHelper<
+ css::lang::XServiceInfo, css::beans::XPropertySet >
+{
+public:
+ Default() {}
+ Default(const Default&) = delete;
+ Default& operator=(const Default&) = delete;
+
+private:
+ virtual ~Default() override {}
+
+ virtual OUString SAL_CALL getImplementationName() override
+ { return "com.sun.star.comp.configuration.backend.DesktopBackend"; }
+
+ virtual sal_Bool SAL_CALL supportsService(OUString const & ServiceName) override
+ { return ServiceName == getSupportedServiceNames()[0]; }
+
+ virtual css::uno::Sequence< OUString > SAL_CALL
+ getSupportedServiceNames() override
+ { return { "com.sun.star.configuration.backend.DesktopBackend" }; }
+
+ virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL
+ getPropertySetInfo() override
+ { return css::uno::Reference< css::beans::XPropertySetInfo >(); }
+
+ virtual void SAL_CALL setPropertyValue(
+ OUString const &, css::uno::Any const &) override;
+
+ virtual css::uno::Any SAL_CALL getPropertyValue(
+ OUString const & PropertyName) override;
+
+ virtual void SAL_CALL addPropertyChangeListener(
+ OUString const &,
+ css::uno::Reference< css::beans::XPropertyChangeListener > const &) override
+ {}
+
+ virtual void SAL_CALL removePropertyChangeListener(
+ OUString const &,
+ css::uno::Reference< css::beans::XPropertyChangeListener > const &) override
+ {}
+
+ virtual void SAL_CALL addVetoableChangeListener(
+ OUString const &,
+ css::uno::Reference< css::beans::XVetoableChangeListener > const &) override
+ {}
+
+ virtual void SAL_CALL removeVetoableChangeListener(
+ OUString const &,
+ css::uno::Reference< css::beans::XVetoableChangeListener > const &) override
+ {}
+};
+
+void Default::setPropertyValue(OUString const &, css::uno::Any const &)
+{
+ throw css::lang::IllegalArgumentException(
+ "setPropertyValue not supported",
+ getXWeak(), -1);
+}
+
+OUString xdg_user_dir_lookup (const char *type, bool bAllowHomeDir)
+{
+ size_t nLenType = strlen(type);
+ char *config_home;
+ char *p;
+ bool bError = false;
+
+ osl::Security aSecurity;
+ oslFileHandle handle;
+ OUString aHomeDirURL;
+ OUString aDocumentsDirURL;
+ OUString aConfigFileURL;
+ OUStringBuffer aUserDirBuf;
+
+ if (!aSecurity.getHomeDir( aHomeDirURL ) )
+ {
+ osl::FileBase::getFileURLFromSystemPath("/tmp", aDocumentsDirURL);
+ return aDocumentsDirURL;
+ }
+
+ config_home = getenv ("XDG_CONFIG_HOME");
+ if (config_home == nullptr || config_home[0] == 0)
+ {
+ aConfigFileURL = aHomeDirURL + "/.config/user-dirs.dirs";
+ }
+ else
+ {
+ aConfigFileURL = OUString::createFromAscii(config_home) + "/user-dirs.dirs";
+ }
+
+ if(osl_File_E_None == osl_openFile(aConfigFileURL.pData, &handle, osl_File_OpenFlag_Read))
+ {
+ rtl::ByteSequence seq;
+ while (osl_File_E_None == osl_readLine(handle , reinterpret_cast<sal_Sequence **>(&seq)))
+ {
+ int relative = 0;
+ int len = seq.getLength();
+ seq.realloc(len + 1);
+ seq[len] = 0;
+
+ p = reinterpret_cast<char *>(seq.getArray());
+ while (*p == ' ' || *p == '\t')
+ p++;
+ if (strncmp (p, "XDG_", 4) != 0)
+ continue;
+ p += 4;
+ if (strncmp (p, OString(type, nLenType).toAsciiUpperCase().getStr(), nLenType) != 0)
+ continue;
+ p += nLenType;
+ if (strncmp (p, "_DIR", 4) != 0)
+ continue;
+ p += 4;
+ while (*p == ' ' || *p == '\t')
+ p++;
+ if (*p != '=')
+ continue;
+ p++;
+ while (*p == ' ' || *p == '\t')
+ p++;
+ if (*p != '"')
+ continue;
+ p++;
+ if (strncmp (p, "$HOME/", 6) == 0)
+ {
+ p += 6;
+ relative = 1;
+ }
+ else if (*p != '/')
+ continue;
+ if (relative)
+ {
+ aUserDirBuf = aHomeDirURL + "/";
+ }
+ else
+ {
+ aUserDirBuf.truncate();
+ }
+ while (*p && *p != '"')
+ {
+ if ((*p == '\\') && (*(p+1) != 0))
+ p++;
+ aUserDirBuf.append(static_cast<sal_Unicode>(*p++));
+ }
+ }//end of while
+ osl_closeFile(handle);
+ }
+ else
+ bError = true;
+ if (aUserDirBuf.getLength()>0 && !bError)
+ {
+ aDocumentsDirURL = aUserDirBuf.makeStringAndClear();
+ if ( bAllowHomeDir ||
+ (aDocumentsDirURL != aHomeDirURL && aDocumentsDirURL != Concat2View(aHomeDirURL + "/")) )
+ {
+ osl::Directory aDocumentsDir( aDocumentsDirURL );
+ if( osl::FileBase::E_None == aDocumentsDir.open() )
+ return aDocumentsDirURL;
+ }
+ }
+ /* Use fallbacks historical compatibility if nothing else exists */
+ return aHomeDirURL + "/" + OUString::createFromAscii(type);
+}
+
+css::uno::Any xdgDirectoryIfExists(char const * type, bool bAllowHomeDir) {
+ auto url = xdg_user_dir_lookup(type, bAllowHomeDir);
+ return css::uno::Any(
+ osl::Directory(url).open() == osl::FileBase::E_None
+ ? css::beans::Optional<css::uno::Any>(true, css::uno::Any(url))
+ : css::beans::Optional<css::uno::Any>(false, css::uno::Any()));
+}
+
+css::uno::Any Default::getPropertyValue(OUString const & PropertyName)
+{
+ if (PropertyName == "TemplatePathVariable")
+ {
+ // Never pick up the HOME directory as the default location of user's templates
+ return xdgDirectoryIfExists("Templates", false);
+ }
+
+ if (PropertyName == "WorkPathVariable")
+ {
+ return xdgDirectoryIfExists("Documents", true);
+ }
+
+ if ( PropertyName == "EnableATToolSupport" ||
+ PropertyName == "ExternalMailer" ||
+ PropertyName == "SourceViewFontHeight" ||
+ PropertyName == "SourceViewFontName" ||
+ PropertyName == "ooInetHTTPProxyName" ||
+ PropertyName == "ooInetHTTPProxyPort" ||
+ PropertyName == "ooInetHTTPSProxyName" ||
+ PropertyName == "ooInetHTTPSProxyPort" ||
+ PropertyName == "ooInetNoProxy" ||
+ PropertyName == "ooInetProxyType" ||
+ PropertyName == "givenname" ||
+ PropertyName == "sn" )
+ {
+ return css::uno::Any(css::beans::Optional< css::uno::Any >());
+ }
+
+ throw css::beans::UnknownPropertyException(
+ PropertyName, getXWeak());
+}
+
+css::uno::Reference< css::uno::XInterface > createBackend(
+ css::uno::Reference< css::uno::XComponentContext > const & context,
+ OUString const & name)
+{
+ try {
+ return css::uno::Reference< css::lang::XMultiComponentFactory >(
+ context->getServiceManager(), css::uno::UNO_SET_THROW)->
+ createInstanceWithContext(name, context);
+ } catch (css::uno::RuntimeException &) {
+ // Assuming these exceptions are real errors:
+ throw;
+ } catch (const css::uno::Exception &) {
+ // Assuming these exceptions indicate that the service is not installed:
+ TOOLS_WARN_EXCEPTION("shell", "createInstance(" << name << ") failed");
+ return css::uno::Reference< css::uno::XInterface >();
+ }
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
+shell_DesktopBackend_get_implementation(
+ css::uno::XComponentContext* context , css::uno::Sequence<css::uno::Any> const&)
+{
+ OUString desktop;
+ css::uno::Reference< css::uno::XCurrentContext > current(
+ css::uno::getCurrentContext());
+ if (current.is()) {
+ current->getValueByName("system.desktop-environment") >>= desktop;
+ }
+
+ // Fall back to the default if the specific backend is not available:
+ css::uno::Reference< css::uno::XInterface > backend;
+ if (desktop == "PLASMA5")
+ backend = createBackend(context,
+ "com.sun.star.configuration.backend.KF5Backend");
+ if (!backend)
+ backend = getXWeak(new Default);
+ backend->acquire();
+ return backend.get();
+}
+
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/shell/source/backends/desktopbe/desktopbe1.component b/shell/source/backends/desktopbe/desktopbe1.component
new file mode 100644
index 0000000000..abc47f0425
--- /dev/null
+++ b/shell/source/backends/desktopbe/desktopbe1.component
@@ -0,0 +1,26 @@
+<?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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-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.configuration.backend.DesktopBackend"
+ constructor="shell_DesktopBackend_get_implementation">
+ <service name="com.sun.star.configuration.backend.DesktopBackend"/>
+ </implementation>
+</component>
diff --git a/shell/source/backends/kf5be/kf5access.cxx b/shell/source/backends/kf5be/kf5access.cxx
new file mode 100644
index 0000000000..d266f147d6
--- /dev/null
+++ b/shell/source/backends/kf5be/kf5access.cxx
@@ -0,0 +1,261 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include "kf5access.hxx"
+
+#include <QtGui/QFont>
+#include <QtCore/QString>
+#include <QtGui/QFontDatabase>
+#include <QtCore/QStandardPaths>
+#include <QtCore/QDir>
+#include <QtCore/QUrl>
+
+#include <kprotocolmanager.h>
+
+#include <kemailsettings.h>
+// #include <kglobalsettings.h>
+
+#include <com/sun/star/uno/Any.hxx>
+#include <osl/diagnose.h>
+#include <osl/file.h>
+#include <rtl/ustring.hxx>
+
+namespace kf5access
+{
+namespace
+{
+namespace uno = css::uno;
+}
+
+namespace
+{
+OUString fromQStringToOUString(QString const& s)
+{
+ // Conversion from QString size()'s int to OUString's sal_Int32 should be non-narrowing:
+ return { reinterpret_cast<char16_t const*>(s.utf16()), s.size() };
+}
+}
+
+css::beans::Optional<css::uno::Any> getValue(std::u16string_view id)
+{
+ if (id == u"ExternalMailer")
+ {
+ KEMailSettings aEmailSettings;
+ QString aClientProgram;
+ OUString sClientProgram;
+
+ aClientProgram = aEmailSettings.getSetting(KEMailSettings::ClientProgram);
+ if (aClientProgram.isEmpty())
+ aClientProgram = QStringLiteral("kmail");
+ else
+ aClientProgram = aClientProgram.section(QLatin1Char(' '), 0, 0);
+ sClientProgram = fromQStringToOUString(aClientProgram);
+ return css::beans::Optional<css::uno::Any>(true, uno::Any(sClientProgram));
+ }
+ else if (id == u"SourceViewFontHeight")
+ {
+ const QFont aFixedFont = QFontDatabase::systemFont(QFontDatabase::FixedFont);
+ const short nFontHeight = aFixedFont.pointSize();
+ return css::beans::Optional<css::uno::Any>(true, uno::Any(nFontHeight));
+ }
+ else if (id == u"SourceViewFontName")
+ {
+ const QFont aFixedFont = QFontDatabase::systemFont(QFontDatabase::FixedFont);
+ const QString aFontName = aFixedFont.family();
+ const OUString sFontName = fromQStringToOUString(aFontName);
+ return css::beans::Optional<css::uno::Any>(true, uno::Any(sFontName));
+ }
+ else if (id == u"EnableATToolSupport")
+ {
+ /* does not make much sense without an accessibility bridge */
+ bool ATToolSupport = false;
+ return css::beans::Optional<css::uno::Any>(true,
+ uno::Any(OUString::boolean(ATToolSupport)));
+ }
+ else if (id == u"WorkPathVariable")
+ {
+ QString aDocumentsDir(QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation));
+ if (aDocumentsDir.isEmpty())
+ aDocumentsDir = QDir::homePath();
+ OUString sDocumentsDir;
+ OUString sDocumentsURL;
+ if (aDocumentsDir.endsWith(QLatin1Char('/')))
+ aDocumentsDir.truncate(aDocumentsDir.length() - 1);
+ sDocumentsDir = fromQStringToOUString(aDocumentsDir);
+ osl_getFileURLFromSystemPath(sDocumentsDir.pData, &sDocumentsURL.pData);
+ return css::beans::Optional<css::uno::Any>(true, uno::Any(sDocumentsURL));
+ }
+ else if (id == u"ooInetHTTPProxyName")
+ {
+ QString aHTTPProxy;
+ switch (KProtocolManager::proxyType())
+ {
+ case KProtocolManager::ManualProxy: // Proxies are manually configured
+ aHTTPProxy = KProtocolManager::proxyFor(QStringLiteral("HTTP"));
+ break;
+ case KProtocolManager::PACProxy: // A proxy configuration URL has been given
+ case KProtocolManager::WPADProxy: // A proxy should be automatically discovered
+ case KProtocolManager::EnvVarProxy: // Proxy values set through environment variables
+ // In such cases, the proxy address is not stored in KDE, but determined dynamically.
+ // The proxy address may depend on the requested address, on the time of the day, on the speed of the wind...
+ // The best we can do here is to ask the current value for a given address.
+ aHTTPProxy = KProtocolManager::proxyForUrl(
+ QUrl(QStringLiteral("http://www.libreoffice.org")));
+ break;
+ default: // No proxy is used
+ break;
+ }
+ if (!aHTTPProxy.isEmpty())
+ {
+ QUrl aProxy(aHTTPProxy);
+ OUString sProxy = fromQStringToOUString(aProxy.host());
+ return css::beans::Optional<css::uno::Any>(true, uno::Any(sProxy));
+ }
+ }
+ else if (id == u"ooInetHTTPProxyPort")
+ {
+ QString aHTTPProxy;
+ switch (KProtocolManager::proxyType())
+ {
+ case KProtocolManager::ManualProxy: // Proxies are manually configured
+ aHTTPProxy = KProtocolManager::proxyFor(QStringLiteral("HTTP"));
+ break;
+ case KProtocolManager::PACProxy: // A proxy configuration URL has been given
+ case KProtocolManager::WPADProxy: // A proxy should be automatically discovered
+ case KProtocolManager::EnvVarProxy: // Proxy values set through environment variables
+ // In such cases, the proxy address is not stored in KDE, but determined dynamically.
+ // The proxy address may depend on the requested address, on the time of the day, on the speed of the wind...
+ // The best we can do here is to ask the current value for a given address.
+ aHTTPProxy = KProtocolManager::proxyForUrl(
+ QUrl(QStringLiteral("http://www.libreoffice.org")));
+ break;
+ default: // No proxy is used
+ break;
+ }
+ if (!aHTTPProxy.isEmpty())
+ {
+ QUrl aProxy(aHTTPProxy);
+ sal_Int32 nPort = aProxy.port();
+ return css::beans::Optional<css::uno::Any>(true, uno::Any(nPort));
+ }
+ }
+ else if (id == u"ooInetHTTPSProxyName")
+ {
+ QString aHTTPSProxy;
+ switch (KProtocolManager::proxyType())
+ {
+ case KProtocolManager::ManualProxy: // Proxies are manually configured
+ aHTTPSProxy = KProtocolManager::proxyFor(QStringLiteral("HTTPS"));
+ break;
+ case KProtocolManager::PACProxy: // A proxy configuration URL has been given
+ case KProtocolManager::WPADProxy: // A proxy should be automatically discovered
+ case KProtocolManager::EnvVarProxy: // Proxy values set through environment variables
+ // In such cases, the proxy address is not stored in KDE, but determined dynamically.
+ // The proxy address may depend on the requested address, on the time of the day, on the speed of the wind...
+ // The best we can do here is to ask the current value for a given address.
+ aHTTPSProxy = KProtocolManager::proxyForUrl(
+ QUrl(QStringLiteral("https://www.libreoffice.org")));
+ break;
+ default: // No proxy is used
+ break;
+ }
+ if (!aHTTPSProxy.isEmpty())
+ {
+ QUrl aProxy(aHTTPSProxy);
+ OUString sProxy = fromQStringToOUString(aProxy.host());
+ return css::beans::Optional<css::uno::Any>(true, uno::Any(sProxy));
+ }
+ }
+ else if (id == u"ooInetHTTPSProxyPort")
+ {
+ QString aHTTPSProxy;
+ switch (KProtocolManager::proxyType())
+ {
+ case KProtocolManager::ManualProxy: // Proxies are manually configured
+ aHTTPSProxy = KProtocolManager::proxyFor(QStringLiteral("HTTPS"));
+ break;
+ case KProtocolManager::PACProxy: // A proxy configuration URL has been given
+ case KProtocolManager::WPADProxy: // A proxy should be automatically discovered
+ case KProtocolManager::EnvVarProxy: // Proxy values set through environment variables
+ // In such cases, the proxy address is not stored in KDE, but determined dynamically.
+ // The proxy address may depend on the requested address, on the time of the day, on the speed of the wind...
+ // The best we can do here is to ask the current value for a given address.
+ aHTTPSProxy = KProtocolManager::proxyForUrl(
+ QUrl(QStringLiteral("https://www.libreoffice.org")));
+ break;
+ default: // No proxy is used
+ break;
+ }
+ if (!aHTTPSProxy.isEmpty())
+ {
+ QUrl aProxy(aHTTPSProxy);
+ sal_Int32 nPort = aProxy.port();
+ return css::beans::Optional<css::uno::Any>(true, uno::Any(nPort));
+ }
+ }
+ else if (id == u"ooInetNoProxy")
+ {
+ QString aNoProxyFor;
+ switch (KProtocolManager::proxyType())
+ {
+ case KProtocolManager::ManualProxy: // Proxies are manually configured
+ case KProtocolManager::PACProxy: // A proxy configuration URL has been given
+ case KProtocolManager::WPADProxy: // A proxy should be automatically discovered
+ case KProtocolManager::EnvVarProxy: // Proxy values set through environment variables
+ aNoProxyFor = KProtocolManager::noProxyFor();
+ break;
+ default: // No proxy is used
+ break;
+ }
+ if (!aNoProxyFor.isEmpty())
+ {
+ OUString sNoProxyFor;
+
+ aNoProxyFor = aNoProxyFor.replace(QLatin1Char(','), QLatin1Char(';'));
+ sNoProxyFor = fromQStringToOUString(aNoProxyFor);
+ return css::beans::Optional<css::uno::Any>(true, uno::Any(sNoProxyFor));
+ }
+ }
+ else if (id == u"ooInetProxyType")
+ {
+ sal_Int32 nProxyType;
+ switch (KProtocolManager::proxyType())
+ {
+ case KProtocolManager::ManualProxy: // Proxies are manually configured
+ case KProtocolManager::PACProxy: // A proxy configuration URL has been given
+ case KProtocolManager::WPADProxy: // A proxy should be automatically discovered
+ case KProtocolManager::EnvVarProxy: // Proxy values set through environment variables
+ nProxyType = 1;
+ break;
+ default: // No proxy is used
+ nProxyType = 0;
+ }
+ return css::beans::Optional<css::uno::Any>(true, uno::Any(nProxyType));
+ }
+ else
+ {
+ OSL_ASSERT(false); // this cannot happen
+ }
+ return css::beans::Optional<css::uno::Any>();
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/shell/source/backends/kf5be/kf5access.hxx b/shell/source/backends/kf5be/kf5access.hxx
new file mode 100644
index 0000000000..765d9c706d
--- /dev/null
+++ b/shell/source/backends/kf5be/kf5access.hxx
@@ -0,0 +1,41 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_SHELL_SOURCE_BACKENDS_KF5BE_KF5ACCESS_HXX
+#define INCLUDED_SHELL_SOURCE_BACKENDS_KF5BE_KF5ACCESS_HXX
+
+#include <sal/config.h>
+
+#include <string_view>
+
+#include <com/sun/star/beans/Optional.hpp>
+
+namespace com::sun::star::uno
+{
+class Any;
+}
+
+namespace kf5access
+{
+css::beans::Optional<css::uno::Any> getValue(std::u16string_view id);
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/shell/source/backends/kf5be/kf5backend.cxx b/shell/source/backends/kf5be/kf5backend.cxx
new file mode 100644
index 0000000000..9802d0796a
--- /dev/null
+++ b/shell/source/backends/kf5be/kf5backend.cxx
@@ -0,0 +1,257 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <memory>
+
+#include <QtWidgets/QApplication>
+
+#include <com/sun/star/beans/Optional.hpp>
+#include <com/sun/star/beans/UnknownPropertyException.hpp>
+#include <com/sun/star/beans/XPropertyChangeListener.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/XPropertySetInfo.hpp>
+#include <com/sun/star/beans/XVetoableChangeListener.hpp>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/uno/XCurrentContext.hpp>
+#include <cppuhelper/implbase.hxx>
+#include <cppuhelper/weak.hxx>
+#include <rtl/ustring.hxx>
+#include <sal/types.h>
+#include <uno/current_context.hxx>
+#include <vcl/svapp.hxx>
+
+#include <osl/process.h>
+#include <osl/thread.h>
+
+#include "kf5access.hxx"
+
+namespace
+{
+class Service : public cppu::WeakImplHelper<css::lang::XServiceInfo, css::beans::XPropertySet>
+{
+public:
+ Service();
+
+private:
+ // noncopyable until we have good reasons...
+ Service(const Service&) = delete;
+ Service& operator=(const Service&) = delete;
+
+ virtual ~Service() override {}
+
+ virtual OUString SAL_CALL getImplementationName() override
+ {
+ return "com.sun.star.comp.configuration.backend.KF5Backend";
+ }
+
+ virtual sal_Bool SAL_CALL supportsService(OUString const& ServiceName) override
+ {
+ return ServiceName == getSupportedServiceNames()[0];
+ }
+
+ virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override
+ {
+ return { "com.sun.star.configuration.backend.KF5Backend" };
+ }
+
+ virtual css::uno::Reference<css::beans::XPropertySetInfo> SAL_CALL getPropertySetInfo() override
+ {
+ return css::uno::Reference<css::beans::XPropertySetInfo>();
+ }
+
+ virtual void SAL_CALL setPropertyValue(OUString const&, css::uno::Any const&) override;
+
+ virtual css::uno::Any SAL_CALL getPropertyValue(OUString const& PropertyName) override;
+
+ virtual void SAL_CALL addPropertyChangeListener(
+ OUString const&, css::uno::Reference<css::beans::XPropertyChangeListener> const&) override
+ {
+ }
+
+ virtual void SAL_CALL removePropertyChangeListener(
+ OUString const&, css::uno::Reference<css::beans::XPropertyChangeListener> const&) override
+ {
+ }
+
+ virtual void SAL_CALL addVetoableChangeListener(
+ OUString const&, css::uno::Reference<css::beans::XVetoableChangeListener> const&) override
+ {
+ }
+
+ virtual void SAL_CALL removeVetoableChangeListener(
+ OUString const&, css::uno::Reference<css::beans::XVetoableChangeListener> const&) override
+ {
+ }
+
+ std::map<OUString, css::beans::Optional<css::uno::Any>> m_KDESettings;
+};
+
+OString getDisplayArg()
+{
+ OUString aParam;
+ const sal_uInt32 nParams = osl_getCommandArgCount();
+ for (sal_uInt32 nIdx = 0; nIdx < nParams; ++nIdx)
+ {
+ osl_getCommandArg(nIdx, &aParam.pData);
+ if (aParam != "-display")
+ continue;
+
+ ++nIdx;
+ osl_getCommandArg(nIdx, &aParam.pData);
+ return OUStringToOString(aParam, osl_getThreadTextEncoding());
+ }
+ return {};
+}
+
+OString getExecutable()
+{
+ OUString aParam, aBin;
+ osl_getExecutableFile(&aParam.pData);
+ osl_getSystemPathFromFileURL(aParam.pData, &aBin.pData);
+ return OUStringToOString(aBin, osl_getThreadTextEncoding());
+}
+
+void readKDESettings(std::map<OUString, css::beans::Optional<css::uno::Any>>& rSettings)
+{
+ const std::vector<OUString> aKeys
+ = { "EnableATToolSupport", "ExternalMailer", "SourceViewFontHeight",
+ "SourceViewFontName", "WorkPathVariable", "ooInetHTTPProxyName",
+ "ooInetHTTPProxyPort", "ooInetHTTPSProxyName", "ooInetHTTPSProxyPort",
+ "ooInetNoProxy", "ooInetProxyType" };
+
+ for (const OUString& aKey : aKeys)
+ {
+ css::beans::Optional<css::uno::Any> aValue = kf5access::getValue(aKey);
+ std::pair<OUString, css::beans::Optional<css::uno::Any>> elem
+ = std::make_pair(aKey, aValue);
+ rSettings.insert(elem);
+ }
+}
+
+// init the QApplication when we load the kf5backend into a non-Qt vclplug (e.g. gtk3_kde5)
+// TODO: use a helper process to read these values without linking to Qt directly?
+// TODO: share this code somehow with Qt5Instance.cxx?
+void initQApp(std::map<OUString, css::beans::Optional<css::uno::Any>>& rSettings)
+{
+ const auto aDisplay = getDisplayArg();
+ int nFakeArgc = aDisplay.isEmpty() ? 2 : 3;
+ char** pFakeArgv = new char*[nFakeArgc];
+
+ pFakeArgv[0] = strdup(getExecutable().getStr());
+ pFakeArgv[1] = strdup("--nocrashhandler");
+ if (!aDisplay.isEmpty())
+ pFakeArgv[2] = strdup(aDisplay.getStr());
+
+ char* session_manager = nullptr;
+ if (auto* session_manager_env = getenv("SESSION_MANAGER"))
+ {
+ session_manager = strdup(session_manager_env);
+ unsetenv("SESSION_MANAGER");
+ }
+
+ {
+ // rhbz#2047319 drop the SolarMutex during the execution of QApplication::init()
+ // https://invent.kde.org/qt/qt/qtwayland/-/merge_requests/24#note_383915
+ SolarMutexReleaser aReleaser; // rhbz#2047319 drop the SolarMutex during the execution
+
+ std::unique_ptr<QApplication> app(new QApplication(nFakeArgc, pFakeArgv));
+ QObject::connect(app.get(), &QObject::destroyed, app.get(), [nFakeArgc, pFakeArgv]() {
+ for (int i = 0; i < nFakeArgc; ++i)
+ free(pFakeArgv[i]);
+ delete[] pFakeArgv;
+ });
+
+ readKDESettings(rSettings);
+ }
+
+ if (session_manager != nullptr)
+ {
+ // coverity[tainted_string] - trusted source for setenv
+ setenv("SESSION_MANAGER", session_manager, 1);
+ free(session_manager);
+ }
+}
+
+Service::Service()
+{
+ css::uno::Reference<css::uno::XCurrentContext> context(css::uno::getCurrentContext());
+ if (!context.is())
+ return;
+
+ OUString desktop;
+ context->getValueByName("system.desktop-environment") >>= desktop;
+
+ if (desktop == "PLASMA5")
+ {
+ if (!qApp) // no qt event loop yet
+ {
+ // so we start one and read KDE settings
+ initQApp(m_KDESettings);
+ }
+ else // someone else (most likely kde/qt vclplug) has started qt event loop
+ // all that is left to do is to read KDE settings
+ readKDESettings(m_KDESettings);
+ }
+}
+
+void Service::setPropertyValue(OUString const&, css::uno::Any const&)
+{
+ throw css::lang::IllegalArgumentException("setPropertyValue not supported", getXWeak(), -1);
+}
+
+css::uno::Any Service::getPropertyValue(OUString const& PropertyName)
+{
+ if (PropertyName == "EnableATToolSupport" || PropertyName == "ExternalMailer"
+ || PropertyName == "SourceViewFontHeight" || PropertyName == "SourceViewFontName"
+ || PropertyName == "WorkPathVariable" || PropertyName == "ooInetHTTPProxyName"
+ || PropertyName == "ooInetHTTPProxyPort" || PropertyName == "ooInetHTTPSProxyName"
+ || PropertyName == "ooInetHTTPSProxyPort" || PropertyName == "ooInetNoProxy"
+ || PropertyName == "ooInetProxyType")
+ {
+ std::map<OUString, css::beans::Optional<css::uno::Any>>::iterator it
+ = m_KDESettings.find(PropertyName);
+ if (it != m_KDESettings.end())
+ return css::uno::Any(it->second);
+ else
+ return css::uno::Any(css::beans::Optional<css::uno::Any>());
+ }
+ else if (PropertyName == "givenname" || PropertyName == "sn"
+ || PropertyName == "TemplatePathVariable")
+ {
+ return css::uno::Any(css::beans::Optional<css::uno::Any>());
+ //TODO: obtain values from KDE?
+ }
+ throw css::beans::UnknownPropertyException(PropertyName, getXWeak());
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
+shell_kf5desktop_get_implementation(css::uno::XComponentContext*,
+ css::uno::Sequence<css::uno::Any> const&)
+{
+ return cppu::acquire(new Service());
+}
+}
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/shell/source/backends/kf5be/kf5be1.component b/shell/source/backends/kf5be/kf5be1.component
new file mode 100644
index 0000000000..dd893bcb67
--- /dev/null
+++ b/shell/source/backends/kf5be/kf5be1.component
@@ -0,0 +1,26 @@
+<?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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-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.configuration.backend.KF5Backend"
+ constructor="shell_kf5desktop_get_implementation">
+ <service name="com.sun.star.configuration.backend.KF5Backend"/>
+ </implementation>
+</component>
diff --git a/shell/source/backends/localebe/localebackend.cxx b/shell/source/backends/localebe/localebackend.cxx
new file mode 100644
index 0000000000..d34c3441e6
--- /dev/null
+++ b/shell/source/backends/localebe/localebackend.cxx
@@ -0,0 +1,332 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+#include <sal/log.hxx>
+
+#include <cassert>
+#include <limits>
+
+#include "localebackend.hxx"
+#include <com/sun/star/beans/Optional.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <cppuhelper/supportsservice.hxx>
+#include <rtl/character.hxx>
+#include <o3tl/char16_t2wchar_t.hxx>
+#include <i18nlangtag/languagetag.hxx>
+#include <i18nlangtag/mslangid.hxx>
+
+#ifdef _WIN32
+#if !defined WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+#endif
+#include <windows.h>
+
+static css::beans::Optional<css::uno::Any> ImplGetLocale(LCID lcid)
+{
+ WCHAR buffer[8];
+ PWSTR cp = buffer;
+
+ cp += GetLocaleInfoW( lcid, LOCALE_SISO639LANGNAME, buffer, 4 );
+ if( cp > buffer )
+ {
+ if( 0 < GetLocaleInfoW( lcid, LOCALE_SISO3166CTRYNAME, cp, buffer + 8 - cp) )
+ // #i50822# minus character must be written before cp
+ *(cp - 1) = '-';
+
+ return {true, css::uno::Any(OUString(o3tl::toU(buffer)))};
+ }
+
+ return {false, {}};
+}
+
+#elif defined(MACOSX)
+
+#include <rtl/ustrbuf.hxx>
+#include <locale.h>
+#include <string.h>
+
+#include <premac.h>
+#include <CoreServices/CoreServices.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <postmac.h>
+
+namespace /* private */
+{
+
+ void OUStringBufferAppendCFString(OUStringBuffer& buffer, const CFStringRef s)
+ {
+ CFIndex lstr = CFStringGetLength(s);
+ for (CFIndex i = 0; i < lstr; i++)
+ buffer.append(sal_Unicode(CFStringGetCharacterAtIndex(s, i)));
+ }
+
+ template <typename T>
+ class CFGuard
+ {
+ public:
+ explicit CFGuard(T& rT) : rT_(rT) {}
+ ~CFGuard() { if (rT_) CFRelease(rT_); }
+ private:
+ T& rT_;
+ };
+
+ typedef CFGuard<CFArrayRef> CFArrayGuard;
+ typedef CFGuard<CFStringRef> CFStringGuard;
+ typedef CFGuard<CFTypeRef> CFTypeRefGuard;
+
+ /* For more information on the Apple locale concept please refer to
+ http://developer.apple.com/documentation/CoreFoundation/Conceptual/CFLocales/Articles/CFLocaleConcepts.html
+ According to this documentation a locale identifier has the format: language[_country][_variant]*
+ e.g. es_ES_PREEURO -> spain prior Euro support
+ Note: The calling code should be able to handle locales with only language information e.g. 'en' for certain
+ UI languages just the language code will be returned.
+ */
+
+ CFStringRef ImplGetAppPreference(const char* pref)
+ {
+ CFStringRef csPref = CFStringCreateWithCString(nullptr, pref, kCFStringEncodingASCII);
+ CFStringGuard csRefGuard(csPref);
+
+ CFTypeRef ref = CFPreferencesCopyAppValue(csPref, kCFPreferencesCurrentApplication);
+ CFTypeRefGuard refGuard(ref);
+
+ if (ref == nullptr)
+ return nullptr;
+
+ CFStringRef sref = (CFGetTypeID(ref) == CFArrayGetTypeID()) ? static_cast<CFStringRef>(CFArrayGetValueAtIndex(static_cast<CFArrayRef>(ref), 0)) : static_cast<CFStringRef>(ref);
+
+ // NOTE: this API is only available with macOS >=10.3. We need to use it because
+ // Apple used non-ISO values on systems <10.2 like "German" for instance but didn't
+ // upgrade those values during upgrade to newer macOS versions. See also #i54337#
+ return CFLocaleCreateCanonicalLocaleIdentifierFromString(kCFAllocatorDefault, sref);
+ }
+
+ css::beans::Optional<css::uno::Any> ImplGetLocale(const char* pref)
+ {
+ CFStringRef sref = ImplGetAppPreference(pref);
+ CFStringGuard srefGuard(sref);
+
+ OUStringBuffer aLocaleBuffer("en-US"); // initialize with fallback value
+
+ if (sref != nullptr)
+ {
+ // split the string into substrings; the first two (if there are two) substrings
+ // are language and country
+ CFArrayRef subs = CFStringCreateArrayBySeparatingStrings(nullptr, sref, CFSTR("_"));
+ CFArrayGuard subsGuard(subs);
+
+ if (subs != nullptr)
+ {
+ aLocaleBuffer.setLength(0); // clear buffer which still contains fallback value
+
+ CFStringRef lang = static_cast<CFStringRef>(CFArrayGetValueAtIndex(subs, 0));
+ OUStringBufferAppendCFString(aLocaleBuffer, lang);
+
+ // country also available? Assumption: if the array contains more than one
+ // value the second value is always the country!
+ if (CFArrayGetCount(subs) > 1)
+ {
+ aLocaleBuffer.append("-");
+ CFStringRef country = static_cast<CFStringRef>(CFArrayGetValueAtIndex(subs, 1));
+ OUStringBufferAppendCFString(aLocaleBuffer, country);
+ }
+ }
+ }
+ return {true, css::uno::Any(aLocaleBuffer.makeStringAndClear())};
+ }
+
+} // namespace /* private */
+
+#else
+
+#include <rtl/ustrbuf.hxx>
+#include <cstdlib>
+#include <cstring>
+
+static css::beans::Optional<css::uno::Any> ImplGetLocale(char const * category)
+{
+ const char *locale = std::getenv("LC_ALL");
+ if (locale == nullptr || *locale == '\0') {
+ locale = std::getenv(category);
+ if (locale == nullptr || *locale == '\0') {
+ locale = std::getenv("LANG");
+ }
+ }
+
+ // Return "en-US" for C locales
+ if( (locale == nullptr) || *locale == '\0' || std::strcmp(locale, "C") == 0
+ || std::strcmp(locale, "POSIX") == 0 )
+ return {true, css::uno::Any(OUString("en-US"))};
+
+
+ const char *cp;
+ const char *uscore = nullptr;
+ const char *end = nullptr;
+
+ // locale string have the format lang[_ctry][.encoding][@modifier]
+ // Let LanguageTag handle all conversion, but do a sanity and length check
+ // first.
+ // For the fallback we are only interested in the first two items, so we
+ // handle '.' and '@' as string end for that.
+ for (cp = locale; *cp; cp++)
+ {
+ if (*cp == '_' && !uscore)
+ uscore = cp;
+ if ((*cp == '.' || *cp == '@') && !end)
+ end = cp;
+ if (!rtl::isAscii(static_cast<unsigned char>(*cp))) {
+ SAL_INFO("shell", "locale env var with non-ASCII content");
+ return {false, {}};
+ }
+ }
+ assert(cp >= locale);
+ if (cp - locale > std::numeric_limits<sal_Int32>::max()) {
+ SAL_INFO("shell", "locale env var content too long");
+ return {false, {}};
+ }
+
+ // This is a tad awkward... but the easiest way to obtain what we're
+ // actually interested in. For example this also converts
+ // "ca_ES.UTF-8@valencia" to "ca-ES-valencia".
+ const OString aLocaleStr(locale);
+ const LanguageType nLang = MsLangId::convertUnxByteStringToLanguage( aLocaleStr);
+ if (nLang != LANGUAGE_DONTKNOW)
+ {
+ const OUString aLangTagStr( LanguageTag::convertToBcp47( nLang));
+ return {true, css::uno::Any(aLangTagStr)};
+ }
+
+ // As a fallback, strip encoding and modifier and return just a
+ // language-country combination and let the caller handle unknowns.
+ OUStringBuffer aLocaleBuffer;
+ if (!end)
+ end = cp;
+ if( uscore != nullptr )
+ {
+ aLocaleBuffer.appendAscii(locale, uscore++ - locale);
+ aLocaleBuffer.append("-");
+ aLocaleBuffer.appendAscii(uscore, end - uscore);
+ }
+ else
+ {
+ aLocaleBuffer.appendAscii(locale, end - locale);
+ }
+
+ return {true, css::uno::Any(aLocaleBuffer.makeStringAndClear())};
+}
+
+#endif
+
+
+LocaleBackend::LocaleBackend()
+{
+}
+
+
+LocaleBackend::~LocaleBackend()
+{
+}
+
+
+
+css::beans::Optional<css::uno::Any> LocaleBackend::getLocale()
+{
+#if defined(_WIN32)
+ return ImplGetLocale( GetUserDefaultLCID() );
+#elif defined (MACOSX)
+ return ImplGetLocale("AppleLocale");
+#else
+ return ImplGetLocale("LC_CTYPE");
+#endif
+}
+
+
+css::beans::Optional<css::uno::Any> LocaleBackend::getUILocale()
+{
+#if defined(_WIN32)
+ return ImplGetLocale( MAKELCID(GetUserDefaultUILanguage(), SORT_DEFAULT) );
+#elif defined(MACOSX)
+ return ImplGetLocale("AppleLanguages");
+#else
+ return ImplGetLocale("LC_MESSAGES");
+#endif
+}
+
+
+css::beans::Optional<css::uno::Any> LocaleBackend::getSystemLocale()
+{
+// note: the implementation differs from getLocale() only on Windows
+#if defined(_WIN32)
+ return ImplGetLocale( GetSystemDefaultLCID() );
+#else
+ return getLocale();
+#endif
+}
+
+
+void LocaleBackend::setPropertyValue(
+ OUString const &, css::uno::Any const &)
+{
+ throw css::lang::IllegalArgumentException(
+ "setPropertyValue not supported",
+ getXWeak(), -1);
+}
+
+css::uno::Any LocaleBackend::getPropertyValue(
+ OUString const & PropertyName)
+{
+ if ( PropertyName == "Locale" ) {
+ return css::uno::Any(getLocale());
+ } else if (PropertyName == "SystemLocale")
+ {
+ return css::uno::Any(getSystemLocale());
+ } else if (PropertyName == "UILocale")
+ {
+ return css::uno::Any(getUILocale());
+ } else {
+ throw css::beans::UnknownPropertyException(
+ PropertyName, getXWeak());
+ }
+}
+
+
+OUString SAL_CALL LocaleBackend::getImplementationName()
+{
+ return "com.sun.star.comp.configuration.backend.LocaleBackend" ;
+}
+
+sal_Bool SAL_CALL LocaleBackend::supportsService(const OUString& aServiceName)
+{
+ return cppu::supportsService(this, aServiceName);
+}
+
+uno::Sequence<OUString> SAL_CALL LocaleBackend::getSupportedServiceNames()
+{
+ return { "com.sun.star.configuration.backend.LocaleBackend" };
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
+shell_LocaleBackend_get_implementation(
+ css::uno::XComponentContext* , css::uno::Sequence<css::uno::Any> const&)
+{
+ return cppu::acquire(new LocaleBackend());
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/shell/source/backends/localebe/localebackend.hxx b/shell/source/backends/localebe/localebackend.hxx
new file mode 100644
index 0000000000..e2e4a0b362
--- /dev/null
+++ b/shell/source/backends/localebe/localebackend.hxx
@@ -0,0 +1,106 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_SHELL_SOURCE_BACKENDS_LOCALEBE_LOCALEBACKEND_HXX
+#define INCLUDED_SHELL_SOURCE_BACKENDS_LOCALEBE_LOCALEBACKEND_HXX
+
+#include <sal/config.h>
+
+#include <com/sun/star/beans/Optional.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <cppuhelper/implbase.hxx>
+
+
+namespace uno = css::uno ;
+namespace lang = css::lang ;
+
+class LocaleBackend final : public ::cppu::WeakImplHelper <
+ css::beans::XPropertySet,
+ lang::XServiceInfo >
+{
+
+ public:
+
+ // XServiceInfo
+ virtual OUString SAL_CALL
+ getImplementationName( ) override ;
+
+ virtual sal_Bool SAL_CALL
+ supportsService( const OUString& aServiceName ) override ;
+
+ virtual uno::Sequence<OUString> SAL_CALL
+ getSupportedServiceNames( ) override ;
+
+ // XPropertySet
+ virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL
+ getPropertySetInfo() override
+ { return css::uno::Reference< css::beans::XPropertySetInfo >(); }
+
+ virtual void SAL_CALL setPropertyValue(
+ OUString const &, css::uno::Any const &) override;
+
+ virtual css::uno::Any SAL_CALL getPropertyValue(
+ OUString const & PropertyName) override;
+
+ virtual void SAL_CALL addPropertyChangeListener(
+ OUString const &,
+ css::uno::Reference< css::beans::XPropertyChangeListener > const &) override
+ {}
+
+ virtual void SAL_CALL removePropertyChangeListener(
+ OUString const &,
+ css::uno::Reference< css::beans::XPropertyChangeListener > const &) override
+ {}
+
+ virtual void SAL_CALL addVetoableChangeListener(
+ OUString const &,
+ css::uno::Reference< css::beans::XVetoableChangeListener > const &) override
+ {}
+
+ virtual void SAL_CALL removeVetoableChangeListener(
+ OUString const &,
+ css::uno::Reference< css::beans::XVetoableChangeListener > const &) override
+ {}
+
+ /**
+ Service constructor from a service factory.
+
+ @param xContext component context
+ */
+ LocaleBackend();
+
+ /** Destructor */
+ virtual ~LocaleBackend() override ;
+
+ private:
+ // Returns the user locale
+ static css::beans::Optional<css::uno::Any> getLocale();
+
+ // Returns the user UI locale
+ static css::beans::Optional<css::uno::Any> getUILocale();
+
+ // Returns the system default locale
+ static css::beans::Optional<css::uno::Any> getSystemLocale();
+} ;
+
+
+#endif // INCLUDED_SHELL_SOURCE_BACKENDS_LOCALEBE_LOCALEBACKEND_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/shell/source/backends/localebe/localebe1.component b/shell/source/backends/localebe/localebe1.component
new file mode 100644
index 0000000000..f19a3f9e8e
--- /dev/null
+++ b/shell/source/backends/localebe/localebe1.component
@@ -0,0 +1,26 @@
+<?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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-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.configuration.backend.LocaleBackend"
+ constructor="shell_LocaleBackend_get_implementation">
+ <service name="com.sun.star.configuration.backend.LocaleBackend"/>
+ </implementation>
+</component>
diff --git a/shell/source/backends/macbe/macbackend.hxx b/shell/source/backends/macbe/macbackend.hxx
new file mode 100644
index 0000000000..9a19a30021
--- /dev/null
+++ b/shell/source/backends/macbe/macbackend.hxx
@@ -0,0 +1,90 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_SHELL_SOURCE_BACKENDS_MACBE_MACBACKEND_HXX
+#define INCLUDED_SHELL_SOURCE_BACKENDS_MACBE_MACBACKEND_HXX
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <cppuhelper/implbase.hxx>
+#include <rtl/string.hxx>
+
+// FIXME: stdio.h only for debugging...
+#include <stdio.h>
+
+namespace uno = css::uno;
+namespace lang = css::lang;
+
+class MacOSXBackend : public ::cppu::WeakImplHelper <css::beans::XPropertySet, lang::XServiceInfo >
+{
+
+public:
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName() override;
+
+ virtual sal_Bool SAL_CALL supportsService(const OUString& aServiceName) override;
+
+ virtual uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override;
+
+ // XPropertySet
+ virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL
+ getPropertySetInfo() override
+ { return css::uno::Reference< css::beans::XPropertySetInfo >(); }
+
+ virtual void SAL_CALL setPropertyValue(
+ OUString const &, css::uno::Any const &) override;
+
+ virtual css::uno::Any SAL_CALL getPropertyValue(
+ OUString const & PropertyName) override;
+
+ virtual void SAL_CALL addPropertyChangeListener(
+ OUString const &,
+ css::uno::Reference< css::beans::XPropertyChangeListener > const &) override
+ {}
+
+ virtual void SAL_CALL removePropertyChangeListener(
+ OUString const &,
+ css::uno::Reference< css::beans::XPropertyChangeListener > const &) override
+ {}
+
+ virtual void SAL_CALL addVetoableChangeListener(
+ OUString const &,
+ css::uno::Reference< css::beans::XVetoableChangeListener > const &) override
+ {}
+
+ virtual void SAL_CALL removeVetoableChangeListener(
+ OUString const &,
+ css::uno::Reference< css::beans::XVetoableChangeListener > const &) override
+ {}
+
+ /**
+ Service constructor from a service factory.
+
+ @param xContext component context
+ */
+ MacOSXBackend();
+
+ /** Destructor */
+ virtual ~MacOSXBackend() override;
+};
+
+#endif // INCLUDED_SHELL_SOURCE_BACKENDS_MACBE_MACBACKEND_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/shell/source/backends/macbe/macbackend.mm b/shell/source/backends/macbe/macbackend.mm
new file mode 100644
index 0000000000..51a11a7a85
--- /dev/null
+++ b/shell/source/backends/macbe/macbackend.mm
@@ -0,0 +1,359 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <memory>
+
+// For MAXHOSTNAMELEN constant
+#include <sys/param.h>
+
+#include <premac.h>
+#include <SystemConfiguration/SystemConfiguration.h>
+#include <Foundation/NSPathUtilities.h>
+#include <postmac.h>
+
+#include "macbackend.hxx"
+
+#include <com/sun/star/beans/Optional.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <cppuhelper/supportsservice.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <sal/log.hxx>
+#include <osl/diagnose.h>
+#include <osl/file.h>
+
+#define SPACE ' '
+#define SEMI_COLON ';'
+
+namespace
+{
+
+typedef enum {
+ sHTTP,
+ sHTTPS,
+} ServiceType;
+
+/*
+ * Returns current proxy settings for selected service type (HTTP or
+ * HTTPS) as a C string (in the buffer specified by host and hostSize)
+ * and a port number.
+ */
+
+bool GetProxySetting(ServiceType sType, char *host, size_t hostSize, UInt16 *port)
+{
+ bool result;
+ CFDictionaryRef proxyDict;
+ CFNumberRef enableNum;
+ int enable;
+ CFStringRef hostStr;
+ CFNumberRef portNum;
+ int portInt;
+
+ proxyDict = SCDynamicStoreCopyProxies(nullptr);
+
+ if (!proxyDict)
+ return false;
+
+ CFStringRef proxiesEnable;
+ CFStringRef proxiesProxy;
+ CFStringRef proxiesPort;
+
+ switch ( sType )
+ {
+ case sHTTP : proxiesEnable = kSCPropNetProxiesHTTPEnable;
+ proxiesProxy = kSCPropNetProxiesHTTPProxy;
+ proxiesPort = kSCPropNetProxiesHTTPPort;
+ break;
+ case sHTTPS: proxiesEnable = kSCPropNetProxiesHTTPSEnable;
+ proxiesProxy = kSCPropNetProxiesHTTPSProxy;
+ proxiesPort = kSCPropNetProxiesHTTPSPort;
+ break;
+ }
+ // Proxy enabled?
+ enableNum = static_cast<CFNumberRef>(CFDictionaryGetValue( proxyDict,
+ proxiesEnable ));
+
+ result = (enableNum != nullptr) && (CFGetTypeID(enableNum) == CFNumberGetTypeID());
+
+ if (result)
+ result = CFNumberGetValue(enableNum, kCFNumberIntType, &enable) && (enable != 0);
+
+ // Proxy enabled -> get hostname
+ if (result)
+ {
+ hostStr = static_cast<CFStringRef>(CFDictionaryGetValue( proxyDict,
+ proxiesProxy ));
+
+ result = (hostStr != nullptr) && (CFGetTypeID(hostStr) == CFStringGetTypeID());
+ }
+
+ if (result)
+ result = CFStringGetCString(hostStr, host, static_cast<CFIndex>(hostSize), kCFStringEncodingASCII);
+
+ // Get proxy port
+ if (result)
+ {
+ portNum = static_cast<CFNumberRef>(CFDictionaryGetValue( proxyDict,
+ proxiesPort ));
+
+ result = (portNum != nullptr) && (CFGetTypeID(portNum) == CFNumberGetTypeID());
+ }
+ else
+ {
+ CFRelease(proxyDict);
+ return false;
+ }
+
+ if (result)
+ result = CFNumberGetValue(portNum, kCFNumberIntType, &portInt);
+
+ if (result)
+ *port = static_cast<UInt16>(portInt);
+
+ if (proxyDict)
+ CFRelease(proxyDict);
+
+ if (!result)
+ {
+ *host = 0;
+ *port = 0;
+ }
+
+ return result;
+}
+
+} // unnamed namespace
+
+MacOSXBackend::MacOSXBackend()
+{
+}
+
+MacOSXBackend::~MacOSXBackend(void)
+{
+}
+
+static OUString CFStringToOUString(const CFStringRef sOrig) {
+ CFRetain(sOrig);
+
+ CFIndex nStringLen = CFStringGetLength(sOrig)+1;
+
+ // Allocate a c string buffer
+ auto const sBuffer = std::make_unique<char[]>(nStringLen);
+
+ CFStringGetCString(sOrig, sBuffer.get(), nStringLen, kCFStringEncodingASCII);
+
+ CFRelease(sOrig);
+
+ return OUString::createFromAscii(sBuffer.get());
+}
+
+static OUString GetOUString( NSString* pStr )
+{
+ if( ! pStr )
+ return OUString();
+ int nLen = [pStr length];
+ if( nLen == 0 )
+ return OUString();
+
+ OUStringBuffer aBuf( nLen+1 );
+ aBuf.setLength( nLen );
+ [pStr getCharacters:
+ reinterpret_cast<unichar *>(const_cast<sal_Unicode*>(aBuf.getStr()))];
+ return aBuf.makeStringAndClear();
+}
+
+void MacOSXBackend::setPropertyValue(
+ OUString const &, css::uno::Any const &)
+{
+ throw css::lang::IllegalArgumentException(
+ "setPropertyValue not supported",
+ getXWeak(), -1);
+}
+
+css::uno::Any MacOSXBackend::getPropertyValue(
+ OUString const & PropertyName)
+{
+ if ( PropertyName == "WorkPathVariable" )
+ {
+ OUString aDocDir;
+ NSArray* pPaths = NSSearchPathForDirectoriesInDomains( NSDocumentDirectory, NSUserDomainMask, true );
+ if( pPaths && [pPaths count] > 0 )
+ {
+ aDocDir = GetOUString( [pPaths objectAtIndex: 0] );
+
+ OUString aDocURL;
+ if( aDocDir.getLength() > 0 &&
+ osl_getFileURLFromSystemPath( aDocDir.pData, &aDocURL.pData ) == osl_File_E_None )
+ {
+ return css::uno::Any(
+ css::beans::Optional< css::uno::Any >(
+ true, css::uno::Any( aDocURL ) ) );
+ }
+ else
+ {
+ SAL_WARN("shell", "user documents list contains empty file path or conversion failed" );
+ }
+ }
+ else
+ {
+ SAL_WARN("shell", "Got nil or empty list of user document directories" );
+ }
+ return css::uno::Any(css::beans::Optional< css::uno::Any >());
+ } else if ( PropertyName == "ooInetHTTPProxyName" )
+ {
+ char host[MAXHOSTNAMELEN];
+ UInt16 port;
+ bool retVal;
+
+ retVal = GetProxySetting(sHTTP, host, 100, &port);
+
+ if (retVal)
+ {
+ auto const Server = OUString::createFromAscii( host );
+ if( Server.getLength() > 0 )
+ {
+ return css::uno::Any(
+ css::beans::Optional< css::uno::Any >(
+ true, uno::Any( Server ) ) );
+ }
+ }
+ return css::uno::Any(css::beans::Optional< css::uno::Any >());
+ } else if ( PropertyName == "ooInetHTTPProxyPort" )
+ {
+ char host[MAXHOSTNAMELEN];
+ UInt16 port;
+ bool retVal;
+
+ retVal = GetProxySetting(sHTTP, host, 100, &port);
+
+ if (retVal && port > 0)
+ {
+ return css::uno::Any(
+ css::beans::Optional< css::uno::Any >(
+ true, uno::Any( sal_Int32(port) ) ) );
+ }
+ return css::uno::Any(css::beans::Optional< css::uno::Any >());
+ } else if ( PropertyName == "ooInetHTTPSProxyName" )
+ {
+ char host[MAXHOSTNAMELEN];
+ UInt16 port;
+ bool retVal;
+
+ retVal = GetProxySetting(sHTTPS, host, 100, &port);
+
+ if (retVal)
+ {
+ auto const Server = OUString::createFromAscii( host );
+ if( Server.getLength() > 0 )
+ {
+ return css::uno::Any(
+ css::beans::Optional< css::uno::Any >(
+ true, uno::Any( Server ) ) );
+ }
+ }
+ return css::uno::Any(css::beans::Optional< css::uno::Any >());
+ } else if ( PropertyName == "ooInetHTTPSProxyPort" )
+ {
+ char host[MAXHOSTNAMELEN];
+ UInt16 port;
+ bool retVal;
+
+ retVal = GetProxySetting(sHTTPS, host, 100, &port);
+
+ if (retVal && port > 0)
+ {
+ return css::uno::Any(
+ css::beans::Optional< css::uno::Any >(
+ true, uno::Any( sal_Int32(port) ) ) );
+ }
+ return css::uno::Any(css::beans::Optional< css::uno::Any >());
+ } else if ( PropertyName == "ooInetProxyType" )
+ {
+ // override default for ProxyType, which is "0" meaning "No proxies".
+ return css::uno::Any(
+ css::beans::Optional< css::uno::Any >(
+ true, uno::Any( sal_Int32(1) ) ) );
+ } else if ( PropertyName == "ooInetNoProxy" )
+ {
+ OUString aProxyBypassList;
+
+ CFArrayRef rExceptionsList;
+ CFDictionaryRef rProxyDict = SCDynamicStoreCopyProxies(nullptr);
+
+ if (!rProxyDict)
+ rExceptionsList = nullptr;
+ else
+ rExceptionsList = static_cast<CFArrayRef>(CFDictionaryGetValue(rProxyDict, kSCPropNetProxiesExceptionsList));
+
+ if (rExceptionsList)
+ {
+ for (CFIndex idx = 0; idx < CFArrayGetCount(rExceptionsList); idx++)
+ {
+ CFStringRef rException = static_cast<CFStringRef>(CFArrayGetValueAtIndex(rExceptionsList, idx));
+
+ if (idx>0)
+ aProxyBypassList += ";";
+
+ aProxyBypassList += CFStringToOUString(rException);
+ }
+ }
+
+ if (rProxyDict)
+ CFRelease(rProxyDict);
+
+ // fill proxy bypass list
+ if( aProxyBypassList.getLength() > 0 )
+ {
+ return css::uno::Any(
+ css::beans::Optional< css::uno::Any >(
+ true,
+ uno::Any( aProxyBypassList.replace( SPACE, SEMI_COLON ) ) ) );
+ }
+ return css::uno::Any(css::beans::Optional< css::uno::Any >());
+ } else {
+ throw css::beans::UnknownPropertyException(
+ PropertyName, getXWeak());
+ }
+}
+
+OUString SAL_CALL MacOSXBackend::getImplementationName(void)
+{
+ return "com.sun.star.comp.configuration.backend.MacOSXBackend";
+}
+
+sal_Bool SAL_CALL MacOSXBackend::supportsService(const OUString& aServiceName)
+{
+ return cppu::supportsService(this, aServiceName);
+}
+
+uno::Sequence<OUString> SAL_CALL MacOSXBackend::getSupportedServiceNames(void)
+{
+ return { "com.sun.star.configuration.backend.MacOSXBackend" };
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
+shell_MacOSXBackend_get_implementation(
+ css::uno::XComponentContext* , css::uno::Sequence<css::uno::Any> const&)
+{
+ return cppu::acquire(new MacOSXBackend());
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/shell/source/backends/macbe/macbe1.component b/shell/source/backends/macbe/macbe1.component
new file mode 100644
index 0000000000..8b42dc2e44
--- /dev/null
+++ b/shell/source/backends/macbe/macbe1.component
@@ -0,0 +1,26 @@
+<?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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-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.configuration.backend.MacOSXBackend"
+ constructor="shell_MacOSXBackend_get_implementation">
+ <service name="com.sun.star.configuration.backend.MacOSXBackend"/>
+ </implementation>
+</component>
diff --git a/shell/source/backends/wininetbe/wininetbackend.cxx b/shell/source/backends/wininetbe/wininetbackend.cxx
new file mode 100644
index 0000000000..35303bd695
--- /dev/null
+++ b/shell/source/backends/wininetbe/wininetbackend.cxx
@@ -0,0 +1,338 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <cstddef>
+#include <string_view>
+
+#include <cppuhelper/supportsservice.hxx>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <o3tl/string_view.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <sal/log.hxx>
+
+#include "wininetbackend.hxx"
+
+#if !defined WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+#endif
+#include <windows.h>
+#include <wininet.h>
+#include <sal/alloca.h>
+
+#define WININET_DLL_NAME L"wininet.dll"
+#define EQUAL_SIGN '='
+#define COLON ':'
+#define SPACE ' '
+#define SEMI_COLON ';'
+
+namespace {
+
+struct Library {
+ HMODULE module;
+
+ explicit Library(HMODULE theModule): module(theModule) {}
+
+ ~Library() { if (module) FreeLibrary(module); }
+};
+
+struct ProxyEntry
+{
+ OUString Server;
+ OUString Port;
+};
+
+ ProxyEntry ReadProxyEntry(std::u16string_view aProxy, std::size_t& i)
+ {
+ ProxyEntry aProxyEntry;
+
+ aProxyEntry.Server = o3tl::getToken( aProxy, COLON, i );
+ if ( i != std::u16string_view::npos )
+ aProxyEntry.Port = o3tl::getToken( aProxy, COLON, i );
+
+ return aProxyEntry;
+ }
+
+ ProxyEntry FindProxyEntry(std::u16string_view aProxyList, std::u16string_view aType)
+ {
+ std::size_t nIndex = 0;
+
+ do
+ {
+ // get the next token, e.g. ftp=server:port
+ std::u16string_view nextToken = o3tl::getToken( aProxyList, SPACE, nIndex );
+
+ // split the next token again into the parts separated
+ // through '=', e.g. ftp=server:port -> ftp and server:port
+ std::size_t i = 0;
+ if( nextToken.find( EQUAL_SIGN ) != std::u16string_view::npos )
+ {
+ if( aType == o3tl::getToken( nextToken, EQUAL_SIGN, i ) )
+ return ReadProxyEntry(nextToken, i);
+ }
+ else if( aType.empty())
+ return ReadProxyEntry(nextToken, i);
+
+ } while ( nIndex != std::u16string_view::npos );
+
+ return ProxyEntry();
+ }
+
+} // unnamed namespace
+
+WinInetBackend::WinInetBackend()
+{
+ Library hWinInetDll( LoadLibraryW( WININET_DLL_NAME ) );
+ if( hWinInetDll.module )
+ {
+ typedef BOOL ( WINAPI *InternetQueryOption_Proc_T )( HINTERNET, DWORD, LPVOID, LPDWORD );
+
+ InternetQueryOption_Proc_T lpfnInternetQueryOption =
+ reinterpret_cast< InternetQueryOption_Proc_T >(
+ GetProcAddress( hWinInetDll.module, "InternetQueryOptionW" ) );
+ if (lpfnInternetQueryOption)
+ {
+ // Some Windows versions would fail the InternetQueryOption call
+ // with ERROR_OUTOFMEMORY when the initial dwLength were zero (and
+ // are apparently fine with the initial sizeof (INTERNET_PROXY_INFO)
+ // and need no reallocation), while other versions fail with
+ // ERROR_INSUFFICIENT_BUFFER upon that initial dwLength and need a
+ // reallocation:
+ INTERNET_PROXY_INFO pi;
+ LPINTERNET_PROXY_INFO lpi = &pi;
+ DWORD dwLength = sizeof (pi);
+ bool ok = lpfnInternetQueryOption(
+ nullptr,
+ INTERNET_OPTION_PROXY,
+ lpi,
+ &dwLength );
+ if (!ok)
+ {
+ DWORD err = GetLastError();
+ if (err == ERROR_INSUFFICIENT_BUFFER)
+ {
+ // allocate sufficient space on the stack
+ // insufficient space on the stack results
+ // in a stack overflow exception, we assume
+ // this never happens, because of the relatively
+ // small amount of memory we need
+ // alloca is nice because it is fast and we don't
+ // have to free the allocated memory, it will be
+ // automatically done
+ lpi = static_cast< LPINTERNET_PROXY_INFO >(
+ alloca( dwLength ) );
+ ok = lpfnInternetQueryOption(
+ nullptr,
+ INTERNET_OPTION_PROXY,
+ lpi,
+ &dwLength );
+ if (!ok)
+ {
+ err = GetLastError();
+ }
+ }
+ if (!ok)
+ {
+ SAL_WARN(
+ "shell",
+ "InternetQueryOption INTERNET_OPTION_PROXY"
+ " GetLastError=" << err);
+ return;
+ }
+ }
+
+ // if a proxy is disabled, InternetQueryOption returns
+ // an empty proxy list, so we don't have to check if
+ // proxy is enabled or not
+
+ // We use InternetQueryOptionW (see https://msdn.microsoft.com/en-us/library/aa385101);
+ // it fills INTERNET_PROXY_INFO struct which is defined in WinInet.h to have LPCTSTR
+ // (i.e., the UNICODE-dependent generic string type expanding to const wchar_t* when
+ // UNICODE is defined, and InternetQueryOption macro expands to InternetQueryOptionW).
+ // Thus, it's natural to expect that W version would return wide strings. But it's not
+ // true. The W version still returns const char* in INTERNET_PROXY_INFO.
+ OUString aProxyList = OUString::createFromAscii( lpi->lpszProxy );
+ OUString aProxyBypassList = OUString::createFromAscii( lpi->lpszProxyBypass );
+
+ // override default for ProxyType, which is "0" meaning "No proxies".
+ valueProxyType_.IsPresent = true;
+ valueProxyType_.Value <<= sal_Int32(1);
+
+ // fill proxy bypass list
+ if( aProxyBypassList.getLength() > 0 )
+ {
+ OUStringBuffer aReverseList;
+ sal_Int32 nIndex = 0;
+ do
+ {
+ OUString aToken = aProxyBypassList.getToken( 0, SPACE, nIndex );
+ if ( aProxyList.indexOf( aToken ) == -1 )
+ {
+ if ( aReverseList.getLength() )
+ {
+ aReverseList.insert( 0, sal_Unicode( SEMI_COLON ) );
+ aReverseList.insert( 0, aToken );
+ }
+ else
+ aReverseList = aToken;
+ }
+ }
+ while ( nIndex >= 0 );
+
+ aProxyBypassList = aReverseList.makeStringAndClear();
+
+ valueNoProxy_.IsPresent = true;
+ valueNoProxy_.Value <<= aProxyBypassList.replace( SPACE, SEMI_COLON );
+ }
+
+ if( aProxyList.getLength() > 0 )
+ {
+
+ // this implementation follows the algorithm
+ // of the internet explorer
+ // if there are type-dependent proxy settings
+ // and type independent proxy settings in the
+ // registry the internet explorer chooses the
+ // type independent proxy for all settings
+ // e.g. imagine the following registry entry
+ // ftp=server:port;http=server:port;server:port
+ // the last token server:port is type independent
+ // so the ie chooses this proxy server
+
+ // if there is no port specified for a type independent
+ // server the ie uses the port of an http server if
+ // there is one and it has a port
+
+
+ ProxyEntry aTypeIndepProxy = FindProxyEntry( aProxyList, u"");
+ ProxyEntry aHttpProxy = FindProxyEntry( aProxyList, u"http" );
+ ProxyEntry aHttpsProxy = FindProxyEntry( aProxyList, u"https" );
+
+ if( aTypeIndepProxy.Server.getLength() )
+ {
+ aHttpProxy.Server = aTypeIndepProxy.Server;
+ aHttpsProxy.Server = aTypeIndepProxy.Server;
+
+ if( aTypeIndepProxy.Port.getLength() )
+ {
+ aHttpProxy.Port = aTypeIndepProxy.Port;
+ aHttpsProxy.Port = aTypeIndepProxy.Port;
+ }
+ else
+ {
+ aHttpsProxy.Port = aHttpProxy.Port;
+ }
+ }
+
+ // http proxy name
+ if( aHttpProxy.Server.getLength() > 0 )
+ {
+ valueHttpProxyName_.IsPresent = true;
+ valueHttpProxyName_.Value <<= aHttpProxy.Server;
+ }
+
+ // http proxy port
+ if( aHttpProxy.Port.getLength() > 0 )
+ {
+ valueHttpProxyPort_.IsPresent = true;
+ valueHttpProxyPort_.Value <<= aHttpProxy.Port.toInt32();
+ }
+
+ // https proxy name
+ if( aHttpsProxy.Server.getLength() > 0 )
+ {
+ valueHttpsProxyName_.IsPresent = true;
+ valueHttpsProxyName_.Value <<= aHttpsProxy.Server;
+ }
+
+ // https proxy port
+ if( aHttpsProxy.Port.getLength() > 0 )
+ {
+ valueHttpsProxyPort_.IsPresent = true;
+ valueHttpsProxyPort_.Value <<= aHttpsProxy.Port.toInt32();
+ }
+ }
+ }
+ }
+}
+
+WinInetBackend::~WinInetBackend()
+{
+}
+
+void WinInetBackend::setPropertyValue(
+ OUString const &, css::uno::Any const &)
+{
+ throw css::lang::IllegalArgumentException(
+ "setPropertyValue not supported",
+ getXWeak(), -1);
+}
+
+css::uno::Any WinInetBackend::getPropertyValue(
+ OUString const & PropertyName)
+{
+ if (PropertyName == "ooInetHTTPProxyName")
+ {
+ return css::uno::Any(valueHttpProxyName_);
+ } else if ( PropertyName == "ooInetHTTPProxyPort" )
+ {
+ return css::uno::Any(valueHttpProxyPort_);
+ } else if ( PropertyName == "ooInetHTTPSProxyName" )
+ {
+ return css::uno::Any(valueHttpsProxyName_);
+ } else if ( PropertyName == "ooInetHTTPSProxyPort" )
+ {
+ return css::uno::Any(valueHttpsProxyPort_);
+ } else if ( PropertyName == "ooInetNoProxy" )
+ {
+ return css::uno::Any(valueNoProxy_);
+ } else if ( PropertyName == "ooInetProxyType" )
+ {
+ return css::uno::Any(valueProxyType_);
+ } else {
+ throw css::beans::UnknownPropertyException(
+ PropertyName, getXWeak());
+ }
+}
+
+OUString SAL_CALL WinInetBackend::getImplementationName()
+{
+ return "com.sun.star.comp.configuration.backend.WinInetBackend" ;
+}
+
+sal_Bool SAL_CALL WinInetBackend::supportsService(const OUString& aServiceName)
+{
+ return cppu::supportsService(this, aServiceName);
+}
+
+uno::Sequence<OUString> SAL_CALL WinInetBackend::getSupportedServiceNames()
+{
+ return { "com.sun.star.configuration.backend.WinInetBackend" };
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
+shell_WinInetBackend_get_implementation(
+ css::uno::XComponentContext* , css::uno::Sequence<css::uno::Any> const&)
+{
+ return cppu::acquire(new WinInetBackend);
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/shell/source/backends/wininetbe/wininetbackend.hxx b/shell/source/backends/wininetbe/wininetbackend.hxx
new file mode 100644
index 0000000000..1b5f4ecbfe
--- /dev/null
+++ b/shell/source/backends/wininetbe/wininetbackend.hxx
@@ -0,0 +1,110 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_SHELL_SOURCE_BACKENDS_WININETBE_WININETBACKEND_HXX
+#define INCLUDED_SHELL_SOURCE_BACKENDS_WININETBE_WININETBACKEND_HXX
+
+#include <com/sun/star/beans/Optional.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <cppuhelper/implbase.hxx>
+
+namespace uno = css::uno ;
+namespace lang = css::lang ;
+
+class WinInetBackend : public ::cppu::WeakImplHelper <
+ css::beans::XPropertySet,
+ lang::XServiceInfo > {
+
+ public:
+
+ // XServiceInfo
+ virtual OUString SAL_CALL
+ getImplementationName( ) override;
+
+ virtual sal_Bool SAL_CALL
+ supportsService( const OUString& aServiceName ) override;
+
+ virtual uno::Sequence<OUString> SAL_CALL
+ getSupportedServiceNames( ) override;
+
+ // XPropertySet
+ virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL
+ getPropertySetInfo() override
+ { return css::uno::Reference< css::beans::XPropertySetInfo >(); }
+
+ virtual void SAL_CALL setPropertyValue(
+ OUString const &, css::uno::Any const &) override;
+
+ virtual css::uno::Any SAL_CALL getPropertyValue(
+ OUString const & PropertyName) override;
+
+ virtual void SAL_CALL addPropertyChangeListener(
+ OUString const &,
+ css::uno::Reference< css::beans::XPropertyChangeListener > const &) override
+ {}
+
+ virtual void SAL_CALL removePropertyChangeListener(
+ OUString const &,
+ css::uno::Reference< css::beans::XPropertyChangeListener > const &) override
+ {}
+
+ virtual void SAL_CALL addVetoableChangeListener(
+ OUString const &,
+ css::uno::Reference< css::beans::XVetoableChangeListener > const &) override
+ {}
+
+ virtual void SAL_CALL removeVetoableChangeListener(
+ OUString const &,
+ css::uno::Reference< css::beans::XVetoableChangeListener > const &) override
+ {}
+
+ /**
+ Service constructor from a service factory.
+
+ @param xContext component context
+ */
+ WinInetBackend();
+
+ /** Destructor */
+ ~WinInetBackend() override;
+
+ private:
+ css::beans::Optional< css::uno::Any >
+ valueProxyType_;
+ css::beans::Optional< css::uno::Any >
+ valueNoProxy_;
+ css::beans::Optional< css::uno::Any >
+ valueHttpProxyName_;
+ css::beans::Optional< css::uno::Any >
+ valueHttpProxyPort_;
+ css::beans::Optional< css::uno::Any >
+ valueHttpsProxyName_;
+ css::beans::Optional< css::uno::Any >
+ valueHttpsProxyPort_;
+ css::beans::Optional< css::uno::Any >
+ valueFtpProxyName_;
+ css::beans::Optional< css::uno::Any >
+ valueFtpProxyPort_;
+} ;
+
+
+#endif // INCLUDED_SHELL_SOURCE_BACKENDS_WININETBE_WININETBACKEND_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/shell/source/backends/wininetbe/wininetbe1.component b/shell/source/backends/wininetbe/wininetbe1.component
new file mode 100644
index 0000000000..1acdee781f
--- /dev/null
+++ b/shell/source/backends/wininetbe/wininetbe1.component
@@ -0,0 +1,26 @@
+<?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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-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.configuration.backend.WinInetBackend"
+ constructor="shell_WinInetBackend_get_implementation">
+ <service name="com.sun.star.configuration.backend.WinInetBackend"/>
+ </implementation>
+</component>