diff --git a/Repository.mk b/Repository.mk index 295e24404a4a..19853c205686 100644 --- a/Repository.mk +++ b/Repository.mk @@ -470,6 +470,7 @@ $(eval $(call gb_Helper_register_libraries_for_install,OOOLIBS,ooo, \ sd \ sdd \ sfx \ + singleprov \ slideshow \ sot \ $(if $(or $(DISABLE_GUI),$(ENABLE_WASM_STRIP_SPLASH)),,spl) \ diff --git a/scripting/Library_singleprov.mk b/scripting/Library_singleprov.mk new file mode 100644 index 000000000000..c1e7c88d913d --- /dev/null +++ b/scripting/Library_singleprov.mk @@ -0,0 +1,35 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t; fill-column: 100 -*- +# +# 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,singleprov)) + +$(eval $(call gb_Library_use_sdk_api,singleprov)) + +$(eval $(call gb_Library_set_include,singleprov,\ + $$(INCLUDE) \ + -I$(SRCDIR)/scripting/source/inc \ +)) + +$(eval $(call gb_Library_use_libraries,singleprov,\ + comphelper \ + cppu \ + cppuhelper \ + sal \ +)) + +$(eval $(call gb_Library_add_exception_objects,singleprov,\ + scripting/source/singleprov/provcontext \ + scripting/source/singleprov/scriptbrowser \ + scripting/source/singleprov/scriptdir \ + scripting/source/singleprov/scriptfile \ + scripting/source/singleprov/scriptmacro \ + scripting/source/singleprov/scriptprovider \ +)) + +# vim: set noet sw=4 ts=4: diff --git a/scripting/Module_scripting.mk b/scripting/Module_scripting.mk index 1d974e8e7c26..2c52f6656b03 100644 --- a/scripting/Module_scripting.mk +++ b/scripting/Module_scripting.mk @@ -40,6 +40,7 @@ $(eval $(call gb_Module_add_targets,scripting,\ Library_basprov \ Library_dlgprov \ Library_protocolhandler \ + Library_singleprov \ Library_scriptframe \ Library_stringresource \ Library_vbaevents \ diff --git a/scripting/README.md b/scripting/README.md index 0560a73b9786..0bfe4d184572 100644 --- a/scripting/README.md +++ b/scripting/README.md @@ -27,6 +27,11 @@ browsing and executing scripts. C++ for a `ProtocolHandler` implementation that handles `vnd.sun.star.script` URIs and dispatches them for execution to the Scripting Framework. +- `source/singleprov` + +A base helper class for C++ implementations of LanguageScriptProviders +that store a single macro in a source file. + - `source/basprov` C++ implementation of the `LanguageScriptProvider` UNO service for Basic diff --git a/scripting/source/inc/singleprov/scriptprovider.hxx b/scripting/source/inc/singleprov/scriptprovider.hxx new file mode 100644 index 000000000000..b6f0110ef704 --- /dev/null +++ b/scripting/source/inc/singleprov/scriptprovider.hxx @@ -0,0 +1,101 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * 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/. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace singleprovider +{ +class ProviderContext; +class ScriptBrowser; +class SingleScriptFactory; + +class ScriptProvider + : public cppu::WeakImplHelper +{ +public: + // XInitialization + void SAL_CALL initialize(const css::uno::Sequence& aArguments) override; + + // XServiceInfo + OUString SAL_CALL getImplementationName() override; + sal_Bool SAL_CALL supportsService(OUString const& serviceName) override; + css::uno::Sequence SAL_CALL getSupportedServiceNames() override; + + // XBrowseNode + OUString SAL_CALL getName() override; + css::uno::Sequence> + SAL_CALL getChildNodes() override; + sal_Bool SAL_CALL hasChildNodes() override; + sal_Int16 SAL_CALL getType() override; + + // XScriptProvider + css::uno::Reference + SAL_CALL getScript(const OUString& sScriptUri) override; + + // XPropertySet + css::uno::Reference SAL_CALL getPropertySetInfo() override; + void SAL_CALL setPropertyValue(const OUString& aPropertyName, + const css::uno::Any& aValue) override; + css::uno::Any SAL_CALL getPropertyValue(const OUString& sPropertyName) override; + void SAL_CALL addPropertyChangeListener( + const OUString& aPropertyName, + const css::uno::Reference& xListener) override; + void SAL_CALL removePropertyChangeListener( + const OUString& aPropertyName, + const css::uno::Reference& aListener) override; + void SAL_CALL addVetoableChangeListener( + const OUString& PropertyName, + const css::uno::Reference& aListener) override; + void SAL_CALL removeVetoableChangeListener( + const OUString& PropertyName, + const css::uno::Reference& aListener) override; + + // XInvocation + css::uno::Reference SAL_CALL getIntrospection() override; + css::uno::Any SAL_CALL invoke(const OUString& sFunctionName, + const css::uno::Sequence& aParams, + css::uno::Sequence& aOutParamIndex, + css::uno::Sequence& aOutParam) override; + void SAL_CALL setValue(const OUString& sPropertyName, const css::uno::Any& aValue) override; + css::uno::Any SAL_CALL getValue(const OUString& sPropertyName) override; + sal_Bool SAL_CALL hasMethod(const OUString& sName) override; + sal_Bool SAL_CALL hasProperty(const OUString& sName) override; + + static SAL_DLLPUBLIC_EXPORT OUString + getImplementationNameStatic(std::u16string_view sLanguageName); + static SAL_DLLPUBLIC_EXPORT css::uno::Sequence + getSupportedServiceNamesStatic(std::u16string_view sLanguageName); + static SAL_DLLPUBLIC_EXPORT css::uno::Reference + create(const css::uno::Reference& xContext, + const std::shared_ptr& pSingleScriptFactory); + +private: + ScriptProvider(const css::uno::Reference& xContext, + const std::shared_ptr& pSingleScriptFactory); + + void setLocation(const OUString& sLocation); + + std::shared_ptr m_pProviderContext; + css::uno::Reference m_xRootBrowser; +}; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/scripting/source/inc/singleprov/singlescriptfactory.hxx b/scripting/source/inc/singleprov/singlescriptfactory.hxx new file mode 100644 index 000000000000..c8332f4edb71 --- /dev/null +++ b/scripting/source/inc/singleprov/singlescriptfactory.hxx @@ -0,0 +1,43 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * 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/. + */ + +#pragma once + +#include +#include +#include + +namespace com::sun::star::script::provider +{ +class XScript; +} + +namespace com::sun::star::uno +{ +class XComponentContext; +} + +namespace singleprovider +{ +// Abstract class to provide callbacks into the real script provider. The provider should be able to +// just provide an implementation of the class and pass it to singleprov::ScriptBrowser. +class SingleScriptFactory +{ +public: + virtual OUString getLanguageName() const = 0; + // Gets the extensions (including the ‘.’) for files that this factory is interested in + virtual OUString getExtension() const = 0; + // Given the source code, returns the XScript for the macro contained within + virtual css::uno::Reference + getScript(css::uno::Reference xContext, const OUString& sName, + std::string_view sSource) const = 0; + + virtual ~SingleScriptFactory() = default; +}; +} diff --git a/scripting/source/singleprov/provcontext.cxx b/scripting/source/singleprov/provcontext.cxx new file mode 100644 index 000000000000..ac750804c3d0 --- /dev/null +++ b/scripting/source/singleprov/provcontext.cxx @@ -0,0 +1,25 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * 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 "provcontext.hxx" + +#include + +namespace singleprovider +{ +ProviderContext::ProviderContext(const css::uno::Reference& xContext, + const std::shared_ptr& pSingleScriptFactory) + : m_xContext(xContext) + , m_pSingleScriptFactory(pSingleScriptFactory) + , m_xFileAccess(css::ucb::SimpleFileAccess::create(xContext)) +{ +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/scripting/source/singleprov/provcontext.hxx b/scripting/source/singleprov/provcontext.hxx new file mode 100644 index 000000000000..14d7c7e19e01 --- /dev/null +++ b/scripting/source/singleprov/provcontext.hxx @@ -0,0 +1,47 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * 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/. + */ + +#pragma once + +#include +#include + +namespace com::sun::star::script::provider +{ +class XScriptURIHelper; +} + +namespace com::sun::star::uno +{ +class XComponentContext; +} + +namespace com::sun::star::ucb +{ +class XSimpleFileAccess3; +} + +namespace singleprovider +{ +class SingleScriptFactory; + +class ProviderContext +{ +public: + ProviderContext(const css::uno::Reference& xContext, + const std::shared_ptr& pSingleScriptFactory); + + css::uno::Reference m_xContext; + std::shared_ptr m_pSingleScriptFactory; + css::uno::Reference m_xUriHelper; + css::uno::Reference m_xFileAccess; +}; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/scripting/source/singleprov/scriptbrowser.cxx b/scripting/source/singleprov/scriptbrowser.cxx new file mode 100644 index 000000000000..c9676016e80d --- /dev/null +++ b/scripting/source/singleprov/scriptbrowser.cxx @@ -0,0 +1,100 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * 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 "scriptbrowser.hxx" + +#include + +#include + +#include "provcontext.hxx" + +namespace singleprovider +{ +ScriptBrowser::ScriptBrowser(const std::shared_ptr& pProviderContext, + const OUString& sName, const OUString& sBaseUri) + : m_pProviderContext(pProviderContext) + , m_sName(sName) + , m_sBaseUri(sBaseUri) +{ +} + +OUString SAL_CALL ScriptBrowser::getName() { return m_sName; } + +css::uno::Reference SAL_CALL ScriptBrowser::getPropertySetInfo() +{ + return this; +} + +void SAL_CALL ScriptBrowser::setPropertyValue(const OUString&, const css::uno::Any&) {} + +css::uno::Any SAL_CALL ScriptBrowser::getPropertyValue(const OUString& sPropertyName) +{ + throw css::beans::UnknownPropertyException("Tried to get unknown property " + sPropertyName); +} + +void SAL_CALL ScriptBrowser::addPropertyChangeListener( + const OUString&, const css::uno::Reference&) +{ +} + +void SAL_CALL ScriptBrowser::removePropertyChangeListener( + const OUString&, const css::uno::Reference&) +{ +} + +void SAL_CALL ScriptBrowser::addVetoableChangeListener( + const OUString&, const css::uno::Reference&) +{ +} + +void SAL_CALL ScriptBrowser::removeVetoableChangeListener( + const OUString&, const css::uno::Reference&) +{ +} + +css::uno::Sequence SAL_CALL ScriptBrowser::getProperties() +{ + return css::uno::Sequence(); +} + +css::beans::Property SAL_CALL ScriptBrowser::getPropertyByName(const OUString& sName) +{ + throw css::beans::UnknownPropertyException("Tried to retrieve unknown property " + sName); +} + +sal_Bool SAL_CALL ScriptBrowser::hasPropertyByName(const OUString&) { return false; } + +css::uno::Reference SAL_CALL ScriptBrowser::getIntrospection() +{ + return css::uno::Reference(); +} + +css::uno::Any SAL_CALL ScriptBrowser::invoke(const OUString& sMethodName, + const css::uno::Sequence&, + css::uno::Sequence&, + css::uno::Sequence&) +{ + throw css::lang::IllegalArgumentException("Tried to invoke unknown method " + sMethodName, + getXWeak(), 0); +} + +void SAL_CALL ScriptBrowser::setValue(const OUString&, const css::uno::Any&) {} + +css::uno::Any SAL_CALL ScriptBrowser::getValue(const OUString& sName) +{ + throw css::beans::UnknownPropertyException("Tried to get unknown property " + sName); +} + +sal_Bool SAL_CALL ScriptBrowser::hasMethod(const OUString&) { return false; } + +sal_Bool SAL_CALL ScriptBrowser::hasProperty(const OUString&) { return false; } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/scripting/source/singleprov/scriptbrowser.hxx b/scripting/source/singleprov/scriptbrowser.hxx new file mode 100644 index 000000000000..981220d0bb6c --- /dev/null +++ b/scripting/source/singleprov/scriptbrowser.hxx @@ -0,0 +1,76 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * 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/. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace singleprovider +{ +class ProviderContext; + +class ScriptBrowser + : public cppu::WeakImplHelper +{ +public: + // XBrowseNode + OUString SAL_CALL getName() override; + + // XPropertySet + css::uno::Reference SAL_CALL getPropertySetInfo() override; + void SAL_CALL setPropertyValue(const OUString& aPropertyName, + const css::uno::Any& aValue) override; + css::uno::Any SAL_CALL getPropertyValue(const OUString& sPropertyName) override; + void SAL_CALL addPropertyChangeListener( + const OUString& aPropertyName, + const css::uno::Reference& xListener) override; + void SAL_CALL removePropertyChangeListener( + const OUString& aPropertyName, + const css::uno::Reference& aListener) override; + void SAL_CALL addVetoableChangeListener( + const OUString& PropertyName, + const css::uno::Reference& aListener) override; + void SAL_CALL removeVetoableChangeListener( + const OUString& PropertyName, + const css::uno::Reference& aListener) override; + + // XPropertySetInfo + css::uno::Sequence SAL_CALL getProperties() override; + css::beans::Property SAL_CALL getPropertyByName(const OUString& sName) override; + sal_Bool SAL_CALL hasPropertyByName(const OUString& sName) override; + + // XInvocation + css::uno::Reference SAL_CALL getIntrospection() override; + css::uno::Any SAL_CALL invoke(const OUString& sFunctionName, + const css::uno::Sequence& aParams, + css::uno::Sequence& aOutParamIndex, + css::uno::Sequence& aOutParam) override; + void SAL_CALL setValue(const OUString& sPropertyName, const css::uno::Any& aValue) override; + css::uno::Any SAL_CALL getValue(const OUString& sPropertyName) override; + sal_Bool SAL_CALL hasMethod(const OUString& sName) override; + sal_Bool SAL_CALL hasProperty(const OUString& sName) override; + +protected: + ScriptBrowser(const std::shared_ptr& pProviderContext, const OUString& sName, + const OUString& sBaseUri); + + std::shared_ptr m_pProviderContext; + + OUString m_sName; + OUString m_sBaseUri; +}; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/scripting/source/singleprov/scriptdir.cxx b/scripting/source/singleprov/scriptdir.cxx new file mode 100644 index 000000000000..f6a5bd1f9dce --- /dev/null +++ b/scripting/source/singleprov/scriptdir.cxx @@ -0,0 +1,109 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * 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 "scriptdir.hxx" + +#include +#include +#include +#include +#include + +#include + +#include "provcontext.hxx" +#include "scriptfile.hxx" + +namespace singleprovider +{ +ScriptDir::ScriptDir(const std::shared_ptr& pProviderContext) + : ScriptDir(pProviderContext, pProviderContext->m_pSingleScriptFactory->getLanguageName(), + pProviderContext->m_xUriHelper->getRootStorageURI()) +{ +} + +ScriptDir::ScriptDir(const std::shared_ptr& pProviderContext, + const OUString& sName, const OUString& sBaseUri) + : ScriptBrowser(pProviderContext, sName, sBaseUri) +{ +} + +css::uno::Sequence> + SAL_CALL ScriptDir::getChildNodes() +{ + const css::uno::Reference& xFileAccess + = m_pProviderContext->m_xFileAccess; + + try + { + css::uno::Sequence aChildren = xFileAccess->getFolderContents(m_sBaseUri, true); + + std::vector> aNodes; + aNodes.reserve(aChildren.getLength()); + + OUString sExtension = m_pProviderContext->m_pSingleScriptFactory->getExtension(); + + for (int i = 0, nCount = aChildren.getLength(); i < nCount; ++i) + { + if (xFileAccess->isFolder(aChildren[i])) + { + OUString sName = nameFromUrl(aChildren[i]); + + aNodes.emplace_back(new ScriptDir(m_pProviderContext, sName, aChildren[i])); + } + else if (aChildren[i].endsWith(sExtension)) + { + OUString sName = nameFromUrl(aChildren[i]); + + aNodes.emplace_back(new ScriptFile(m_pProviderContext, sName, aChildren[i])); + } + } + + css::uno::Sequence> aNodesSequence( + aNodes.size()); + css::uno::Reference* pNodesSequence + = aNodesSequence.getArray(); + + for (int i = 0, nCount = aNodes.size(); i < nCount; ++i) + pNodesSequence[i] = std::move(aNodes[i]); + + return aNodesSequence; + } + catch (const css::uno::RuntimeException&) + { + throw; + } + catch (const css::uno::Exception&) + { + return css::uno::Sequence>(); + } +} + +sal_Bool SAL_CALL ScriptDir::hasChildNodes() { return true; } + +sal_Int16 SAL_CALL ScriptDir::getType() { return css::script::browse::BrowseNodeTypes::CONTAINER; } + +OUString ScriptDir::nameFromUrl(const OUString& sUrl) +{ + sal_Int32 nSlashPos = sUrl.lastIndexOf('/'); + sal_Int32 nStart = nSlashPos == -1 ? 0 : nSlashPos + 1; + + sal_Int32 nCount = sUrl.getLength() - nStart; + + OUString sExtension = m_pProviderContext->m_pSingleScriptFactory->getExtension(); + + if (sUrl.endsWith(sExtension)) + nCount -= sExtension.getLength(); + + return rtl::Uri::decode(sUrl.copy(nStart, nCount), rtl_UriDecodeWithCharset, + RTL_TEXTENCODING_UTF8); +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/scripting/source/singleprov/scriptdir.hxx b/scripting/source/singleprov/scriptdir.hxx new file mode 100644 index 000000000000..4100e4accdbc --- /dev/null +++ b/scripting/source/singleprov/scriptdir.hxx @@ -0,0 +1,34 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * 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/. + */ + +#pragma once + +#include "scriptbrowser.hxx" + +namespace singleprovider +{ +class ScriptDir : public ScriptBrowser +{ +public: + ScriptDir(const std::shared_ptr& pProviderContext); + ScriptDir(const std::shared_ptr& pProviderContext, const OUString& sName, + const OUString& sBaseUri); + + // XBrowseNode + css::uno::Sequence> + SAL_CALL getChildNodes() override; + sal_Bool SAL_CALL hasChildNodes() override; + sal_Int16 SAL_CALL getType() override; + +private: + OUString nameFromUrl(const OUString& sUrl); +}; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/scripting/source/singleprov/scriptfile.cxx b/scripting/source/singleprov/scriptfile.cxx new file mode 100644 index 000000000000..d085d870bb95 --- /dev/null +++ b/scripting/source/singleprov/scriptfile.cxx @@ -0,0 +1,44 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * 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 "scriptfile.hxx" + +#include +#include + +#include + +#include "provcontext.hxx" +#include "scriptmacro.hxx" + +namespace singleprovider +{ +ScriptFile::ScriptFile(const std::shared_ptr& pProviderContext, + const OUString& sName, const OUString& sBaseUri) + : ScriptBrowser(pProviderContext, sName, sBaseUri) +{ +} + +css::uno::Sequence> + SAL_CALL ScriptFile::getChildNodes() +{ + // Each file is treated as a container with a single macro inside it + css::uno::Sequence> aChild(1); + + aChild.getArray()[0].set(new ScriptMacro(m_pProviderContext, m_sName, m_sBaseUri)); + + return aChild; +} + +sal_Bool SAL_CALL ScriptFile::hasChildNodes() { return true; } + +sal_Int16 SAL_CALL ScriptFile::getType() { return css::script::browse::BrowseNodeTypes::CONTAINER; } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/scripting/source/singleprov/scriptfile.hxx b/scripting/source/singleprov/scriptfile.hxx new file mode 100644 index 000000000000..ebf5b75c4a82 --- /dev/null +++ b/scripting/source/singleprov/scriptfile.hxx @@ -0,0 +1,30 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * 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/. + */ + +#pragma once + +#include "scriptbrowser.hxx" + +namespace singleprovider +{ +class ScriptFile : public ScriptBrowser +{ +public: + ScriptFile(const std::shared_ptr& pProviderContext, const OUString& sName, + const OUString& sBaseUri); + + // XBrowseNode + css::uno::Sequence> + SAL_CALL getChildNodes() override; + sal_Bool SAL_CALL hasChildNodes() override; + sal_Int16 SAL_CALL getType() override; +}; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/scripting/source/singleprov/scriptmacro.cxx b/scripting/source/singleprov/scriptmacro.cxx new file mode 100644 index 000000000000..fcf6575fd8c8 --- /dev/null +++ b/scripting/source/singleprov/scriptmacro.cxx @@ -0,0 +1,85 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * 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 "scriptmacro.hxx" + +#include +#include +#include + +#include "provcontext.hxx" + +namespace singleprovider +{ +ScriptMacro::ScriptMacro(const std::shared_ptr& pProviderContext, + const OUString& sName, const OUString& sUri) + : ScriptBrowser(pProviderContext, sName, sUri) +{ +} + +css::uno::Sequence> + SAL_CALL ScriptMacro::getChildNodes() +{ + return css::uno::Sequence>(); +} + +sal_Bool SAL_CALL ScriptMacro::hasChildNodes() { return false; } + +sal_Int16 SAL_CALL ScriptMacro::getType() { return css::script::browse::BrowseNodeTypes::SCRIPT; } + +css::uno::Any SAL_CALL ScriptMacro::getPropertyValue(const OUString& sPropertyName) +{ + if (sPropertyName == "URI") + { + css::uno::Any xRet; + + xRet <<= m_pProviderContext->m_xUriHelper->getScriptURI(m_sBaseUri); + + return xRet; + } + else + return ScriptBrowser::getPropertyValue(sPropertyName); +} + +css::uno::Sequence SAL_CALL ScriptMacro::getProperties() +{ + const css::uno::Sequence aParentProperties + = ScriptBrowser::getProperties(); + + css::uno::Sequence aProperties(aParentProperties.getLength() + 1); + aProperties.getArray()[0] = getUriProperty(); + + std::copy(aParentProperties.begin(), aParentProperties.end(), aProperties.getArray() + 1); + + return aProperties; +} + +css::beans::Property SAL_CALL ScriptMacro::getPropertyByName(const OUString& sName) +{ + if (sName == "URI") + return getUriProperty(); + else + return ScriptBrowser::getPropertyByName(sName); +} + +sal_Bool SAL_CALL ScriptMacro::hasPropertyByName(const OUString& sName) +{ + if (sName == "URI") + return true; + else + return ScriptBrowser::hasPropertyByName(sName); +} + +css::beans::Property ScriptMacro::getUriProperty() +{ + return css::beans::Property("URI", 0, cppu::UnoType::get(), 0); +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/scripting/source/singleprov/scriptmacro.hxx b/scripting/source/singleprov/scriptmacro.hxx new file mode 100644 index 000000000000..dd12b7185926 --- /dev/null +++ b/scripting/source/singleprov/scriptmacro.hxx @@ -0,0 +1,43 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * 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/. + */ + +#pragma once + +#include "scriptbrowser.hxx" + +namespace singleprovider +{ +class ProviderContext; + +class ScriptMacro : public ScriptBrowser +{ +public: + ScriptMacro(const std::shared_ptr& pProviderContext, const OUString& sName, + const OUString& sUri); + + // XBrowseNode + css::uno::Sequence> + SAL_CALL getChildNodes() override; + sal_Bool SAL_CALL hasChildNodes() override; + sal_Int16 SAL_CALL getType() override; + + // XPropertySet + css::uno::Any SAL_CALL getPropertyValue(const OUString& sPropertyName) override; + + // XPropertySetInfo + css::uno::Sequence SAL_CALL getProperties() override; + css::beans::Property SAL_CALL getPropertyByName(const OUString& sName) override; + sal_Bool SAL_CALL hasPropertyByName(const OUString& sName) override; + +private: + static css::beans::Property getUriProperty(); +}; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/scripting/source/singleprov/scriptprovider.cxx b/scripting/source/singleprov/scriptprovider.cxx new file mode 100644 index 000000000000..eda1edd9032a --- /dev/null +++ b/scripting/source/singleprov/scriptprovider.cxx @@ -0,0 +1,248 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * 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 + +#include +#include +#include +#include +#include + +#include + +#include "provcontext.hxx" +#include "scriptdir.hxx" + +namespace singleprovider +{ +ScriptProvider::ScriptProvider(const css::uno::Reference& xContext, + const std::shared_ptr& pSingleScriptFactory) + : m_pProviderContext(std::make_shared(xContext, pSingleScriptFactory)) +{ +} + +void SAL_CALL ScriptProvider::initialize(const css::uno::Sequence& aArguments) +{ + if (aArguments.getLength() > 0) + { + OUString sLocation; + if (aArguments[0] >>= sLocation) + setLocation(sLocation); + } +} + +void ScriptProvider::setLocation(const OUString& sLocation) +{ + OUString sLanguageName = m_pProviderContext->m_pSingleScriptFactory->getLanguageName(); + + m_pProviderContext->m_xUriHelper = css::script::provider::ScriptURIHelper::create( + m_pProviderContext->m_xContext, sLanguageName, sLocation); + m_xRootBrowser + = css::uno::Reference(new ScriptDir(m_pProviderContext)); +} + +OUString SAL_CALL ScriptProvider::getName() +{ + return m_pProviderContext->m_pSingleScriptFactory->getLanguageName(); +} + +css::uno::Sequence> + SAL_CALL ScriptProvider::getChildNodes() +{ + if (m_xRootBrowser.is()) + return m_xRootBrowser->getChildNodes(); + else + return css::uno::Sequence>(); +} + +sal_Bool SAL_CALL ScriptProvider::hasChildNodes() +{ + return m_xRootBrowser.is() && m_xRootBrowser->hasChildNodes(); +} + +sal_Int16 SAL_CALL ScriptProvider::getType() +{ + return m_xRootBrowser.is() ? m_xRootBrowser->getType() : 0; +} + +css::uno::Reference + SAL_CALL ScriptProvider::getScript(const OUString& sScriptUri) +{ + OUString sStorageUri = m_pProviderContext->m_xUriHelper->getStorageURI(sScriptUri); + + sal_Int32 nSlashPos = sStorageUri.lastIndexOf('/'); + OUString sName = sStorageUri.copy(nSlashPos == -1 ? 0 : nSlashPos + 1); + + try + { + std::vector aSource; + constexpr sal_Int32 nBufSize = 1024; + css::uno::Sequence aBuf(nBufSize); + + css::uno::Reference xIn + = m_pProviderContext->m_xFileAccess->openFileRead(sStorageUri); + + while (true) + { + sal_Int32 nBytesRead = xIn->readBytes(aBuf, aBuf.getLength()); + const char* pBuf = reinterpret_cast(aBuf.getConstArray()); + aSource.insert(aSource.end(), pBuf, pBuf + nBytesRead); + + if (nBytesRead < nBufSize) + break; + } + + return m_pProviderContext->m_pSingleScriptFactory->getScript( + m_pProviderContext->m_xContext, sName, + std::string_view(aSource.begin(), aSource.end())); + } + catch (const css::uno::Exception& e) + { + throw css::script::provider::ScriptFrameworkErrorException( + e.Message, static_cast(this), sName, + m_pProviderContext->m_pSingleScriptFactory->getLanguageName(), + css::script::provider::ScriptFrameworkErrorType::UNKNOWN); + } +} + +css::uno::Reference SAL_CALL ScriptProvider::getPropertySetInfo() +{ + css::uno::Reference xPropertySetInfo; + + css::uno::Reference xPropertySet(m_xRootBrowser, css::uno::UNO_QUERY); + + if (xPropertySet.is()) + xPropertySetInfo = xPropertySet->getPropertySetInfo(); + + return xPropertySetInfo; +} + +void SAL_CALL ScriptProvider::setPropertyValue(const OUString&, const css::uno::Any&) {} + +css::uno::Any SAL_CALL ScriptProvider::getPropertyValue(const OUString& sPropertyName) +{ + css::uno::Any xRet; + + css::uno::Reference xPropertySet(m_xRootBrowser, css::uno::UNO_QUERY); + + if (xPropertySet.is()) + xRet = xPropertySet->getPropertyValue(sPropertyName); + + return xRet; +} + +void SAL_CALL ScriptProvider::addPropertyChangeListener( + const OUString&, const css::uno::Reference&) +{ +} + +void SAL_CALL ScriptProvider::removePropertyChangeListener( + const OUString&, const css::uno::Reference&) +{ +} + +void SAL_CALL ScriptProvider::addVetoableChangeListener( + const OUString&, const css::uno::Reference&) +{ +} + +void SAL_CALL ScriptProvider::removeVetoableChangeListener( + const OUString&, const css::uno::Reference&) +{ +} + +css::uno::Reference SAL_CALL ScriptProvider::getIntrospection() +{ + return css::uno::Reference(); +} + +css::uno::Any SAL_CALL ScriptProvider::invoke(const OUString& sFunctionName, + const css::uno::Sequence& aParams, + css::uno::Sequence& aOutParamIndex, + css::uno::Sequence& aOutParam) +{ + css::uno::Any xRet; + + css::uno::Reference xInvocation(m_xRootBrowser, css::uno::UNO_QUERY); + + if (xInvocation.is()) + xRet = xInvocation->invoke(sFunctionName, aParams, aOutParamIndex, aOutParam); + + return xRet; +} + +void SAL_CALL ScriptProvider::setValue(const OUString&, const css::uno::Any&) {} + +css::uno::Any SAL_CALL ScriptProvider::getValue(const OUString&) { return css::uno::Any(); } + +sal_Bool SAL_CALL ScriptProvider::hasMethod(const OUString& sName) +{ + css::uno::Reference xInvocation(m_xRootBrowser, css::uno::UNO_QUERY); + + if (xInvocation.is()) + return xInvocation->hasMethod(sName); + else + return false; +} + +sal_Bool SAL_CALL ScriptProvider::hasProperty(const OUString&) { return false; } + +OUString SAL_CALL ScriptProvider::getImplementationName() +{ + return getImplementationNameStatic( + m_pProviderContext->m_pSingleScriptFactory->getLanguageName()); +} + +sal_Bool SAL_CALL ScriptProvider::supportsService(OUString const& serviceName) +{ + const css::uno::Sequence names = getSupportedServiceNames(); + const OUString* pNames = names.getConstArray(); + + for (sal_Int32 i = 0, count = names.getLength(); i < count; i++) + { + if (pNames[i] == serviceName) + return true; + } + + return false; +} + +css::uno::Sequence SAL_CALL ScriptProvider::getSupportedServiceNames() +{ + return getSupportedServiceNamesStatic( + m_pProviderContext->m_pSingleScriptFactory->getLanguageName()); +} + +SAL_DLLPUBLIC_EXPORT OUString +ScriptProvider::getImplementationNameStatic(std::u16string_view sLanguageName) +{ + return u"com.sun.star.singleprov.ScriptProviderFor"_ustr + sLanguageName; +} + +SAL_DLLPUBLIC_EXPORT css::uno::Sequence +ScriptProvider::getSupportedServiceNamesStatic(std::u16string_view sLanguageName) +{ + css::uno::Sequence names(2); + OUString* pNames = names.getArray(); + pNames[0] = u"com.sun.star.script.provider.ScriptProviderFor"_ustr + sLanguageName; + pNames[1] = "com.sun.star.script.provider.LanguageScriptProvider"; + return names; +} + +SAL_DLLPUBLIC_EXPORT css::uno::Reference +ScriptProvider::create(const css::uno::Reference& xContext, + const std::shared_ptr& pSingleScriptFactory) +{ + return static_cast( + new ScriptProvider(xContext, pSingleScriptFactory)); +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */