scripting: Add script provider helpers for files with single macros

Adds a set of helpers to implement a script provider where the script
files are the entire macro. The provider only needs to make a subclass
of the abstract SingleScriptFactory class to provide the filename
extension, language name and a method to convert the contents of a file
to an XScript. The parts about handling file browsing and reading the
file contents are in the shared helper code.

This is based on the script provider from Luno.

Change-Id: Id39f3a07e887898650b0d77ec493011fb5acc858
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/203216
Tested-by: Jenkins
Reviewed-by: Neil Roberts <nroberts@libreoffice.org>
This commit is contained in:
Neil Roberts
2026-04-30 10:36:31 +02:00
parent 7b2006f800
commit e5900bee28
17 changed files with 1027 additions and 0 deletions
+1
View File
@@ -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) \
+35
View File
@@ -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:
+1
View File
@@ -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 \
+5
View File
@@ -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
@@ -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 <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/script/browse/XBrowseNode.hpp>
#include <com/sun/star/script/provider/XScriptProvider.hpp>
#include <com/sun/star/script/XInvocation.hpp>
#include <com/sun/star/lang/XInitialization.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/lang/XSingleComponentFactory.hpp>
#include <cppuhelper/implbase.hxx>
#include <memory>
namespace singleprovider
{
class ProviderContext;
class ScriptBrowser;
class SingleScriptFactory;
class ScriptProvider
: public cppu::WeakImplHelper<css::lang::XInitialization, css::script::browse::XBrowseNode,
css::beans::XPropertySet, css::script::XInvocation,
css::script::provider::XScriptProvider, css::lang::XServiceInfo>
{
public:
// XInitialization
void SAL_CALL initialize(const css::uno::Sequence<css::uno::Any>& aArguments) override;
// XServiceInfo
OUString SAL_CALL getImplementationName() override;
sal_Bool SAL_CALL supportsService(OUString const& serviceName) override;
css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override;
// XBrowseNode
OUString SAL_CALL getName() override;
css::uno::Sequence<css::uno::Reference<css::script::browse::XBrowseNode>>
SAL_CALL getChildNodes() override;
sal_Bool SAL_CALL hasChildNodes() override;
sal_Int16 SAL_CALL getType() override;
// XScriptProvider
css::uno::Reference<css::script::provider::XScript>
SAL_CALL getScript(const OUString& sScriptUri) override;
// XPropertySet
css::uno::Reference<css::beans::XPropertySetInfo> 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<css::beans::XPropertyChangeListener>& xListener) override;
void SAL_CALL removePropertyChangeListener(
const OUString& aPropertyName,
const css::uno::Reference<css::beans::XPropertyChangeListener>& aListener) override;
void SAL_CALL addVetoableChangeListener(
const OUString& PropertyName,
const css::uno::Reference<css::beans::XVetoableChangeListener>& aListener) override;
void SAL_CALL removeVetoableChangeListener(
const OUString& PropertyName,
const css::uno::Reference<css::beans::XVetoableChangeListener>& aListener) override;
// XInvocation
css::uno::Reference<css::beans::XIntrospectionAccess> SAL_CALL getIntrospection() override;
css::uno::Any SAL_CALL invoke(const OUString& sFunctionName,
const css::uno::Sequence<css::uno::Any>& aParams,
css::uno::Sequence<sal_Int16>& aOutParamIndex,
css::uno::Sequence<css::uno::Any>& 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<OUString>
getSupportedServiceNamesStatic(std::u16string_view sLanguageName);
static SAL_DLLPUBLIC_EXPORT css::uno::Reference<css::uno::XInterface>
create(const css::uno::Reference<css::uno::XComponentContext>& xContext,
const std::shared_ptr<SingleScriptFactory>& pSingleScriptFactory);
private:
ScriptProvider(const css::uno::Reference<css::uno::XComponentContext>& xContext,
const std::shared_ptr<SingleScriptFactory>& pSingleScriptFactory);
void setLocation(const OUString& sLocation);
std::shared_ptr<ProviderContext> m_pProviderContext;
css::uno::Reference<css::script::browse::XBrowseNode> m_xRootBrowser;
};
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
@@ -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 <com/sun/star/uno/Reference.hxx>
#include <rtl/ustring.hxx>
#include <string_view>
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<css::script::provider::XScript>
getScript(css::uno::Reference<css::uno::XComponentContext> xContext, const OUString& sName,
std::string_view sSource) const = 0;
virtual ~SingleScriptFactory() = default;
};
}
@@ -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 <com/sun/star/ucb/SimpleFileAccess.hpp>
namespace singleprovider
{
ProviderContext::ProviderContext(const css::uno::Reference<css::uno::XComponentContext>& xContext,
const std::shared_ptr<SingleScriptFactory>& 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: */
@@ -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 <com/sun/star/uno/Reference.hxx>
#include <memory>
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<css::uno::XComponentContext>& xContext,
const std::shared_ptr<SingleScriptFactory>& pSingleScriptFactory);
css::uno::Reference<css::uno::XComponentContext> m_xContext;
std::shared_ptr<SingleScriptFactory> m_pSingleScriptFactory;
css::uno::Reference<css::script::provider::XScriptURIHelper> m_xUriHelper;
css::uno::Reference<css::ucb::XSimpleFileAccess3> m_xFileAccess;
};
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
@@ -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 <com/sun/star/script/browse/BrowseNodeTypes.hpp>
#include <singleprov/singlescriptfactory.hxx>
#include "provcontext.hxx"
namespace singleprovider
{
ScriptBrowser::ScriptBrowser(const std::shared_ptr<ProviderContext>& 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<css::beans::XPropertySetInfo> 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<css::beans::XPropertyChangeListener>&)
{
}
void SAL_CALL ScriptBrowser::removePropertyChangeListener(
const OUString&, const css::uno::Reference<css::beans::XPropertyChangeListener>&)
{
}
void SAL_CALL ScriptBrowser::addVetoableChangeListener(
const OUString&, const css::uno::Reference<css::beans::XVetoableChangeListener>&)
{
}
void SAL_CALL ScriptBrowser::removeVetoableChangeListener(
const OUString&, const css::uno::Reference<css::beans::XVetoableChangeListener>&)
{
}
css::uno::Sequence<css::beans::Property> SAL_CALL ScriptBrowser::getProperties()
{
return css::uno::Sequence<css::beans::Property>();
}
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<css::beans::XIntrospectionAccess> SAL_CALL ScriptBrowser::getIntrospection()
{
return css::uno::Reference<css::beans::XIntrospectionAccess>();
}
css::uno::Any SAL_CALL ScriptBrowser::invoke(const OUString& sMethodName,
const css::uno::Sequence<css::uno::Any>&,
css::uno::Sequence<sal_Int16>&,
css::uno::Sequence<css::uno::Any>&)
{
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: */
@@ -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 <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/beans/XPropertySetInfo.hpp>
#include <com/sun/star/script/browse/XBrowseNode.hpp>
#include <com/sun/star/script/XInvocation.hpp>
#include <cppuhelper/implbase.hxx>
#include <memory>
namespace singleprovider
{
class ProviderContext;
class ScriptBrowser
: public cppu::WeakImplHelper<css::script::browse::XBrowseNode, css::beans::XPropertySet,
css::beans::XPropertySetInfo, css::script::XInvocation>
{
public:
// XBrowseNode
OUString SAL_CALL getName() override;
// XPropertySet
css::uno::Reference<css::beans::XPropertySetInfo> 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<css::beans::XPropertyChangeListener>& xListener) override;
void SAL_CALL removePropertyChangeListener(
const OUString& aPropertyName,
const css::uno::Reference<css::beans::XPropertyChangeListener>& aListener) override;
void SAL_CALL addVetoableChangeListener(
const OUString& PropertyName,
const css::uno::Reference<css::beans::XVetoableChangeListener>& aListener) override;
void SAL_CALL removeVetoableChangeListener(
const OUString& PropertyName,
const css::uno::Reference<css::beans::XVetoableChangeListener>& aListener) override;
// XPropertySetInfo
css::uno::Sequence<css::beans::Property> 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<css::beans::XIntrospectionAccess> SAL_CALL getIntrospection() override;
css::uno::Any SAL_CALL invoke(const OUString& sFunctionName,
const css::uno::Sequence<css::uno::Any>& aParams,
css::uno::Sequence<sal_Int16>& aOutParamIndex,
css::uno::Sequence<css::uno::Any>& 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<ProviderContext>& pProviderContext, const OUString& sName,
const OUString& sBaseUri);
std::shared_ptr<ProviderContext> m_pProviderContext;
OUString m_sName;
OUString m_sBaseUri;
};
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
+109
View File
@@ -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 <com/sun/star/script/browse/BrowseNodeTypes.hpp>
#include <com/sun/star/script/provider/XScriptURIHelper.hpp>
#include <com/sun/star/ucb/SimpleFileAccess.hpp>
#include <rtl/uri.hxx>
#include <vector>
#include <singleprov/singlescriptfactory.hxx>
#include "provcontext.hxx"
#include "scriptfile.hxx"
namespace singleprovider
{
ScriptDir::ScriptDir(const std::shared_ptr<ProviderContext>& pProviderContext)
: ScriptDir(pProviderContext, pProviderContext->m_pSingleScriptFactory->getLanguageName(),
pProviderContext->m_xUriHelper->getRootStorageURI())
{
}
ScriptDir::ScriptDir(const std::shared_ptr<ProviderContext>& pProviderContext,
const OUString& sName, const OUString& sBaseUri)
: ScriptBrowser(pProviderContext, sName, sBaseUri)
{
}
css::uno::Sequence<css::uno::Reference<css::script::browse::XBrowseNode>>
SAL_CALL ScriptDir::getChildNodes()
{
const css::uno::Reference<css::ucb::XSimpleFileAccess3>& xFileAccess
= m_pProviderContext->m_xFileAccess;
try
{
css::uno::Sequence<OUString> aChildren = xFileAccess->getFolderContents(m_sBaseUri, true);
std::vector<css::uno::Reference<css::script::browse::XBrowseNode>> 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<css::uno::Reference<css::script::browse::XBrowseNode>> aNodesSequence(
aNodes.size());
css::uno::Reference<css::script::browse::XBrowseNode>* 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<css::uno::Reference<css::script::browse::XBrowseNode>>();
}
}
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: */
+34
View File
@@ -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<ProviderContext>& pProviderContext);
ScriptDir(const std::shared_ptr<ProviderContext>& pProviderContext, const OUString& sName,
const OUString& sBaseUri);
// XBrowseNode
css::uno::Sequence<css::uno::Reference<css::script::browse::XBrowseNode>>
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: */
@@ -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 <com/sun/star/script/browse/BrowseNodeTypes.hpp>
#include <com/sun/star/ucb/SimpleFileAccess.hpp>
#include <singleprov/singlescriptfactory.hxx>
#include "provcontext.hxx"
#include "scriptmacro.hxx"
namespace singleprovider
{
ScriptFile::ScriptFile(const std::shared_ptr<ProviderContext>& pProviderContext,
const OUString& sName, const OUString& sBaseUri)
: ScriptBrowser(pProviderContext, sName, sBaseUri)
{
}
css::uno::Sequence<css::uno::Reference<css::script::browse::XBrowseNode>>
SAL_CALL ScriptFile::getChildNodes()
{
// Each file is treated as a container with a single macro inside it
css::uno::Sequence<css::uno::Reference<css::script::browse::XBrowseNode>> 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: */
@@ -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<ProviderContext>& pProviderContext, const OUString& sName,
const OUString& sBaseUri);
// XBrowseNode
css::uno::Sequence<css::uno::Reference<css::script::browse::XBrowseNode>>
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: */
@@ -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 <com/sun/star/script/browse/BrowseNodeTypes.hpp>
#include <com/sun/star/script/provider/XScriptURIHelper.hpp>
#include <singleprov/singlescriptfactory.hxx>
#include "provcontext.hxx"
namespace singleprovider
{
ScriptMacro::ScriptMacro(const std::shared_ptr<ProviderContext>& pProviderContext,
const OUString& sName, const OUString& sUri)
: ScriptBrowser(pProviderContext, sName, sUri)
{
}
css::uno::Sequence<css::uno::Reference<css::script::browse::XBrowseNode>>
SAL_CALL ScriptMacro::getChildNodes()
{
return css::uno::Sequence<css::uno::Reference<css::script::browse::XBrowseNode>>();
}
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<css::beans::Property> SAL_CALL ScriptMacro::getProperties()
{
const css::uno::Sequence<css::beans::Property> aParentProperties
= ScriptBrowser::getProperties();
css::uno::Sequence<css::beans::Property> 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<OUString>::get(), 0);
}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
@@ -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<ProviderContext>& pProviderContext, const OUString& sName,
const OUString& sUri);
// XBrowseNode
css::uno::Sequence<css::uno::Reference<css::script::browse::XBrowseNode>>
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<css::beans::Property> 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: */
@@ -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 <singleprov/scriptprovider.hxx>
#include <com/sun/star/script/provider/ScriptFrameworkErrorException.hpp>
#include <com/sun/star/script/provider/ScriptFrameworkErrorType.hpp>
#include <com/sun/star/script/provider/ScriptURIHelper.hpp>
#include <com/sun/star/ucb/SimpleFileAccess.hpp>
#include <vector>
#include <singleprov/singlescriptfactory.hxx>
#include "provcontext.hxx"
#include "scriptdir.hxx"
namespace singleprovider
{
ScriptProvider::ScriptProvider(const css::uno::Reference<css::uno::XComponentContext>& xContext,
const std::shared_ptr<SingleScriptFactory>& pSingleScriptFactory)
: m_pProviderContext(std::make_shared<ProviderContext>(xContext, pSingleScriptFactory))
{
}
void SAL_CALL ScriptProvider::initialize(const css::uno::Sequence<css::uno::Any>& 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<css::script::browse::XBrowseNode>(new ScriptDir(m_pProviderContext));
}
OUString SAL_CALL ScriptProvider::getName()
{
return m_pProviderContext->m_pSingleScriptFactory->getLanguageName();
}
css::uno::Sequence<css::uno::Reference<css::script::browse::XBrowseNode>>
SAL_CALL ScriptProvider::getChildNodes()
{
if (m_xRootBrowser.is())
return m_xRootBrowser->getChildNodes();
else
return css::uno::Sequence<css::uno::Reference<css::script::browse::XBrowseNode>>();
}
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<css::script::provider::XScript>
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<char> aSource;
constexpr sal_Int32 nBufSize = 1024;
css::uno::Sequence<sal_Int8> aBuf(nBufSize);
css::uno::Reference<css::io::XInputStream> xIn
= m_pProviderContext->m_xFileAccess->openFileRead(sStorageUri);
while (true)
{
sal_Int32 nBytesRead = xIn->readBytes(aBuf, aBuf.getLength());
const char* pBuf = reinterpret_cast<const char*>(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<css::uno::XWeak*>(this), sName,
m_pProviderContext->m_pSingleScriptFactory->getLanguageName(),
css::script::provider::ScriptFrameworkErrorType::UNKNOWN);
}
}
css::uno::Reference<css::beans::XPropertySetInfo> SAL_CALL ScriptProvider::getPropertySetInfo()
{
css::uno::Reference<css::beans::XPropertySetInfo> xPropertySetInfo;
css::uno::Reference<css::beans::XPropertySet> 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<css::beans::XPropertySet> 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<css::beans::XPropertyChangeListener>&)
{
}
void SAL_CALL ScriptProvider::removePropertyChangeListener(
const OUString&, const css::uno::Reference<css::beans::XPropertyChangeListener>&)
{
}
void SAL_CALL ScriptProvider::addVetoableChangeListener(
const OUString&, const css::uno::Reference<css::beans::XVetoableChangeListener>&)
{
}
void SAL_CALL ScriptProvider::removeVetoableChangeListener(
const OUString&, const css::uno::Reference<css::beans::XVetoableChangeListener>&)
{
}
css::uno::Reference<css::beans::XIntrospectionAccess> SAL_CALL ScriptProvider::getIntrospection()
{
return css::uno::Reference<css::beans::XIntrospectionAccess>();
}
css::uno::Any SAL_CALL ScriptProvider::invoke(const OUString& sFunctionName,
const css::uno::Sequence<css::uno::Any>& aParams,
css::uno::Sequence<sal_Int16>& aOutParamIndex,
css::uno::Sequence<css::uno::Any>& aOutParam)
{
css::uno::Any xRet;
css::uno::Reference<css::script::XInvocation> 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<css::script::XInvocation> 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<OUString> 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<OUString> 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<OUString>
ScriptProvider::getSupportedServiceNamesStatic(std::u16string_view sLanguageName)
{
css::uno::Sequence<OUString> 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<css::uno::XInterface>
ScriptProvider::create(const css::uno::Reference<css::uno::XComponentContext>& xContext,
const std::shared_ptr<SingleScriptFactory>& pSingleScriptFactory)
{
return static_cast<css::lang::XTypeProvider*>(
new ScriptProvider(xContext, pSingleScriptFactory));
}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */