summaryrefslogtreecommitdiffstats
path: root/scripting/source/basprov
diff options
context:
space:
mode:
Diffstat (limited to 'scripting/source/basprov')
-rw-r--r--scripting/source/basprov/baslibnode.cxx130
-rw-r--r--scripting/source/basprov/baslibnode.hxx70
-rw-r--r--scripting/source/basprov/basmethnode.cxx291
-rw-r--r--scripting/source/basprov/basmethnode.hxx108
-rw-r--r--scripting/source/basprov/basmodnode.cxx134
-rw-r--r--scripting/source/basprov/basmodnode.hxx64
-rw-r--r--scripting/source/basprov/basprov.component29
-rw-r--r--scripting/source/basprov/basprov.cxx477
-rw-r--r--scripting/source/basprov/basprov.hxx97
-rw-r--r--scripting/source/basprov/basscript.cxx314
-rw-r--r--scripting/source/basprov/basscript.hxx103
11 files changed, 1817 insertions, 0 deletions
diff --git a/scripting/source/basprov/baslibnode.cxx b/scripting/source/basprov/baslibnode.cxx
new file mode 100644
index 000000000..33942c6b2
--- /dev/null
+++ b/scripting/source/basprov/baslibnode.cxx
@@ -0,0 +1,130 @@
+/* -*- 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 "baslibnode.hxx"
+#include "basmodnode.hxx"
+#include <com/sun/star/script/browse/BrowseNodeTypes.hpp>
+#include <comphelper/sequence.hxx>
+#include <vcl/svapp.hxx>
+#include <basic/basmgr.hxx>
+#include <basic/sbstar.hxx>
+
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::script;
+
+
+namespace basprov
+{
+
+
+ // BasicLibraryNodeImpl
+
+
+ BasicLibraryNodeImpl::BasicLibraryNodeImpl( const Reference< XComponentContext >& rxContext,
+ const OUString& sScriptingContext, BasicManager* pBasicManager,
+ const Reference< script::XLibraryContainer >& xLibContainer, const OUString& sLibName, bool isAppScript )
+ :m_xContext( rxContext )
+ ,m_sScriptingContext( sScriptingContext )
+ ,m_pBasicManager( pBasicManager )
+ ,m_xLibContainer( xLibContainer )
+ ,m_sLibName( sLibName )
+ ,m_bIsAppScript( isAppScript )
+ {
+ if ( m_xLibContainer.is() )
+ {
+ Any aElement = m_xLibContainer->getByName( m_sLibName );
+ aElement >>= m_xLibrary;
+ }
+ }
+
+
+ BasicLibraryNodeImpl::~BasicLibraryNodeImpl()
+ {
+ }
+
+
+ // XBrowseNode
+
+
+ OUString BasicLibraryNodeImpl::getName( )
+ {
+ SolarMutexGuard aGuard;
+
+ return m_sLibName;
+ }
+
+
+ Sequence< Reference< browse::XBrowseNode > > BasicLibraryNodeImpl::getChildNodes( )
+ {
+ SolarMutexGuard aGuard;
+
+ std::vector< Reference< browse::XBrowseNode > > aChildNodes;
+
+ if ( m_xLibContainer.is() && m_xLibContainer->hasByName( m_sLibName ) && !m_xLibContainer->isLibraryLoaded( m_sLibName ) )
+ m_xLibContainer->loadLibrary( m_sLibName );
+
+ if ( m_pBasicManager )
+ {
+ StarBASIC* pBasic = m_pBasicManager->GetLib( m_sLibName );
+ if ( pBasic && m_xLibrary.is() )
+ {
+ Sequence< OUString > aNames = m_xLibrary->getElementNames();
+ sal_Int32 nCount = aNames.getLength();
+ const OUString* pNames = aNames.getConstArray();
+ aChildNodes.resize( nCount );
+
+ for ( sal_Int32 i = 0 ; i < nCount ; ++i )
+ {
+ SbModule* pModule = pBasic->FindModule( pNames[i] );
+ if ( pModule )
+ aChildNodes[i] = new BasicModuleNodeImpl(m_xContext, m_sScriptingContext,
+ pModule, m_bIsAppScript);
+ }
+ }
+ }
+
+ return comphelper::containerToSequence(aChildNodes);
+ }
+
+
+ sal_Bool BasicLibraryNodeImpl::hasChildNodes( )
+ {
+ SolarMutexGuard aGuard;
+
+ bool bReturn = false;
+ if ( m_xLibrary.is() )
+ bReturn = m_xLibrary->hasElements();
+
+ return bReturn;
+ }
+
+
+ sal_Int16 BasicLibraryNodeImpl::getType( )
+ {
+ return browse::BrowseNodeTypes::CONTAINER;
+ }
+
+
+} // namespace basprov
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/scripting/source/basprov/baslibnode.hxx b/scripting/source/basprov/baslibnode.hxx
new file mode 100644
index 000000000..46d31aae5
--- /dev/null
+++ b/scripting/source/basprov/baslibnode.hxx
@@ -0,0 +1,70 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <com/sun/star/script/XLibraryContainer.hpp>
+#include <com/sun/star/script/browse/XBrowseNode.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <cppuhelper/implbase.hxx>
+
+class BasicManager;
+
+
+namespace basprov
+{
+
+
+
+
+ typedef ::cppu::WeakImplHelper<
+ css::script::browse::XBrowseNode > BasicLibraryNodeImpl_BASE;
+
+
+ class BasicLibraryNodeImpl : public BasicLibraryNodeImpl_BASE
+ {
+ private:
+ css::uno::Reference< css::uno::XComponentContext > m_xContext;
+ OUString m_sScriptingContext;
+ BasicManager* m_pBasicManager;
+ css::uno::Reference< css::script::XLibraryContainer > m_xLibContainer;
+ css::uno::Reference< css::container::XNameContainer > m_xLibrary;
+ OUString m_sLibName;
+ bool m_bIsAppScript;
+
+ public:
+ BasicLibraryNodeImpl( const css::uno::Reference< css::uno::XComponentContext >& rxContext,
+ const OUString& sScriptingContext,
+ BasicManager* pBasicManager,
+ const css::uno::Reference< css::script::XLibraryContainer >& xLibContainer,
+ const OUString& sLibName, bool isAppScript );
+ virtual ~BasicLibraryNodeImpl() override;
+
+ // XBrowseNode
+ virtual OUString SAL_CALL getName( ) override;
+ virtual css::uno::Sequence< css::uno::Reference< css::script::browse::XBrowseNode > > SAL_CALL getChildNodes( ) override;
+ virtual sal_Bool SAL_CALL hasChildNodes( ) override;
+ virtual sal_Int16 SAL_CALL getType( ) override;
+ };
+
+
+} // namespace basprov
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/scripting/source/basprov/basmethnode.cxx b/scripting/source/basprov/basmethnode.cxx
new file mode 100644
index 000000000..fca2cafe8
--- /dev/null
+++ b/scripting/source/basprov/basmethnode.cxx
@@ -0,0 +1,291 @@
+/* -*- 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 "basmethnode.hxx"
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/frame/DispatchHelper.hpp>
+#include <com/sun/star/frame/Desktop.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/script/browse/BrowseNodeTypes.hpp>
+
+#include <comphelper/propertyvalue.hxx>
+#include <vcl/svapp.hxx>
+#include <basic/sbstar.hxx>
+#include <basic/sbmeth.hxx>
+#include <basic/sbmod.hxx>
+
+#include <util/MiscUtils.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::comphelper;
+using namespace ::com::sun::star::script;
+using namespace ::sf_misc;
+
+#define BASPROV_PROPERTY_ID_URI 1
+#define BASPROV_PROPERTY_ID_EDITABLE 2
+
+constexpr OUStringLiteral BASPROV_PROPERTY_URI = u"URI";
+constexpr OUStringLiteral BASPROV_PROPERTY_EDITABLE = u"Editable";
+
+#define BASPROV_DEFAULT_ATTRIBS() PropertyAttribute::BOUND | PropertyAttribute::TRANSIENT | PropertyAttribute::READONLY
+
+
+namespace basprov
+{
+
+
+ // BasicMethodNodeImpl
+
+
+ BasicMethodNodeImpl::BasicMethodNodeImpl( const Reference< XComponentContext >& rxContext,
+ const OUString& sScriptingContext, SbMethod* pMethod, bool isAppScript )
+ : ::scripting_helper::OBroadcastHelperHolder( m_aMutex )
+ ,OPropertyContainer( GetBroadcastHelper() )
+ ,m_xContext( rxContext )
+ ,m_sScriptingContext( sScriptingContext )
+ ,m_pMethod( pMethod )
+ ,m_bIsAppScript( isAppScript )
+ ,m_bEditable( true )
+ {
+ if ( m_pMethod )
+ {
+ SbModule* pModule = m_pMethod->GetModule();
+ if ( pModule )
+ {
+ StarBASIC* pBasic = static_cast< StarBASIC* >( pModule->GetParent() );
+ if ( pBasic )
+ {
+ m_sURI = "vnd.sun.star.script:";
+ m_sURI += pBasic->GetName();
+ m_sURI += ".";
+ m_sURI += pModule->GetName();
+ m_sURI += ".";
+ m_sURI += m_pMethod->GetName();
+ m_sURI += "?language=Basic&location=";
+ if ( m_bIsAppScript )
+ m_sURI += "application";
+ else
+ m_sURI += "document";
+ }
+ }
+ }
+
+ registerProperty( BASPROV_PROPERTY_URI, BASPROV_PROPERTY_ID_URI, BASPROV_DEFAULT_ATTRIBS(), &m_sURI, cppu::UnoType<decltype(m_sURI)>::get() );
+ registerProperty( BASPROV_PROPERTY_EDITABLE, BASPROV_PROPERTY_ID_EDITABLE, BASPROV_DEFAULT_ATTRIBS(), &m_bEditable, cppu::UnoType<decltype(m_bEditable)>::get() );
+ }
+
+
+ BasicMethodNodeImpl::~BasicMethodNodeImpl()
+ {
+ }
+
+
+ // XInterface
+
+
+ IMPLEMENT_FORWARD_XINTERFACE2( BasicMethodNodeImpl, BasicMethodNodeImpl_BASE, OPropertyContainer )
+
+
+ // XTypeProvider
+
+
+ IMPLEMENT_FORWARD_XTYPEPROVIDER2( BasicMethodNodeImpl, BasicMethodNodeImpl_BASE, OPropertyContainer )
+
+
+ // XBrowseNode
+
+
+ OUString BasicMethodNodeImpl::getName( )
+ {
+ SolarMutexGuard aGuard;
+
+ OUString sMethodName;
+ if ( m_pMethod )
+ sMethodName = m_pMethod->GetName();
+
+ return sMethodName;
+ }
+
+
+ Sequence< Reference< browse::XBrowseNode > > BasicMethodNodeImpl::getChildNodes( )
+ {
+ return Sequence< Reference< browse::XBrowseNode > >();
+ }
+
+
+ sal_Bool BasicMethodNodeImpl::hasChildNodes( )
+ {
+ return false;
+ }
+
+
+ sal_Int16 BasicMethodNodeImpl::getType( )
+ {
+ return browse::BrowseNodeTypes::SCRIPT;
+ }
+
+
+ // OPropertySetHelper
+
+
+ ::cppu::IPropertyArrayHelper& BasicMethodNodeImpl::getInfoHelper( )
+ {
+ return *getArrayHelper();
+ }
+
+
+ // OPropertyArrayUsageHelper
+
+
+ ::cppu::IPropertyArrayHelper* BasicMethodNodeImpl::createArrayHelper( ) const
+ {
+ Sequence< Property > aProps;
+ describeProperties( aProps );
+ return new ::cppu::OPropertyArrayHelper( aProps );
+ }
+
+
+ // XPropertySet
+
+
+ Reference< XPropertySetInfo > BasicMethodNodeImpl::getPropertySetInfo( )
+ {
+ Reference< XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) );
+ return xInfo;
+ }
+
+
+ // XInvocation
+
+
+ Reference< XIntrospectionAccess > BasicMethodNodeImpl::getIntrospection( )
+ {
+ return Reference< XIntrospectionAccess >();
+ }
+
+
+ Any BasicMethodNodeImpl::invoke( const OUString& aFunctionName, const Sequence< Any >&,
+ Sequence< sal_Int16 >&, Sequence< Any >& )
+ {
+ if ( aFunctionName != BASPROV_PROPERTY_EDITABLE )
+ {
+ throw IllegalArgumentException(
+ "BasicMethodNodeImpl::invoke: function name not supported!",
+ Reference< XInterface >(), 1 );
+ }
+
+ OUString sDocURL, sLibName, sModName;
+ sal_uInt16 nLine1 = 0;
+
+ if ( !m_bIsAppScript )
+ {
+ Reference< frame::XModel > xModel = MiscUtils::tDocUrlToModel( m_sScriptingContext );
+
+ if ( xModel.is() )
+ {
+ sDocURL = xModel->getURL();
+ if ( sDocURL.isEmpty() )
+ {
+ const Sequence < PropertyValue > aProps = xModel->getArgs();
+ // TODO: according to MBA the property 'Title' may change in future
+ const PropertyValue* pProp = std::find_if(aProps.begin(), aProps.end(),
+ [](const PropertyValue& rProp) { return rProp.Name == "Title"; });
+ if (pProp != aProps.end())
+ pProp->Value >>= sDocURL;
+ }
+ }
+ }
+
+ if ( m_pMethod )
+ {
+ sal_uInt16 nLine2;
+ m_pMethod->GetLineRange( nLine1, nLine2 );
+ SbModule* pModule = m_pMethod->GetModule();
+ if ( pModule )
+ {
+ sModName = pModule->GetName();
+ StarBASIC* pBasic = static_cast< StarBASIC* >( pModule->GetParent() );
+ if ( pBasic )
+ sLibName = pBasic->GetName();
+ }
+ }
+
+ if ( m_xContext.is() )
+ {
+ Reference< frame::XDesktop2 > xDesktop = frame::Desktop::create( m_xContext );
+
+ Reference < frame::XDispatchProvider > xProv( xDesktop->getCurrentFrame(), UNO_QUERY );
+
+ if ( xProv.is() )
+ {
+ Reference< frame::XDispatchHelper > xHelper( frame::DispatchHelper::create( m_xContext ) );
+
+ Sequence < PropertyValue > aArgs{
+ comphelper::makePropertyValue("Document", sDocURL),
+ comphelper::makePropertyValue("LibName", sLibName),
+ comphelper::makePropertyValue("Name", sModName),
+ comphelper::makePropertyValue("Type", OUString("Module")),
+ comphelper::makePropertyValue("Line", static_cast< sal_uInt32 >( nLine1 ))
+ };
+ xHelper->executeDispatch( xProv, ".uno:BasicIDEAppear", OUString(), 0, aArgs );
+ }
+ }
+
+
+ return Any();
+ }
+
+
+ void BasicMethodNodeImpl::setValue( const OUString&, const Any& )
+ {
+ throw UnknownPropertyException(
+ "BasicMethodNodeImpl::setValue: property name is unknown!" );
+ }
+
+
+ Any BasicMethodNodeImpl::getValue( const OUString& )
+ {
+ throw UnknownPropertyException(
+ "BasicMethodNodeImpl::getValue: property name is unknown!" );
+ }
+
+
+ sal_Bool BasicMethodNodeImpl::hasMethod( const OUString& aName )
+ {
+ bool bReturn = false;
+ if ( aName == BASPROV_PROPERTY_EDITABLE )
+ bReturn = true;
+
+ return bReturn;
+ }
+
+
+ sal_Bool BasicMethodNodeImpl::hasProperty( const OUString& )
+ {
+ return false;
+ }
+
+
+} // namespace basprov
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/scripting/source/basprov/basmethnode.hxx b/scripting/source/basprov/basmethnode.hxx
new file mode 100644
index 000000000..d1eddada0
--- /dev/null
+++ b/scripting/source/basprov/basmethnode.hxx
@@ -0,0 +1,108 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <bcholder.hxx>
+#include <com/sun/star/beans/XPropertySetInfo.hpp>
+#include <com/sun/star/script/XInvocation.hpp>
+#include <com/sun/star/script/browse/XBrowseNode.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <comphelper/proparrhlp.hxx>
+#include <comphelper/propertycontainer.hxx>
+#include <comphelper/uno3.hxx>
+#include <cppuhelper/basemutex.hxx>
+#include <cppuhelper/implbase.hxx>
+
+
+class SbMethod;
+
+
+namespace basprov
+{
+
+
+
+
+ typedef ::cppu::WeakImplHelper<
+ css::script::browse::XBrowseNode,
+ css::script::XInvocation > BasicMethodNodeImpl_BASE;
+
+ class BasicMethodNodeImpl : public BasicMethodNodeImpl_BASE,
+ public cppu::BaseMutex,
+ public ::scripting_helper::OBroadcastHelperHolder,
+ public ::comphelper::OPropertyContainer,
+ public ::comphelper::OPropertyArrayUsageHelper< BasicMethodNodeImpl >
+ {
+ private:
+ css::uno::Reference< css::uno::XComponentContext > m_xContext;
+ OUString m_sScriptingContext;
+ SbMethod* m_pMethod;
+ bool m_bIsAppScript;
+
+ // properties
+ OUString m_sURI;
+ bool m_bEditable;
+
+ protected:
+ // OPropertySetHelper
+ virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper( ) override;
+
+ // OPropertyArrayUsageHelper
+ virtual ::cppu::IPropertyArrayHelper* createArrayHelper( ) const override;
+
+ public:
+ BasicMethodNodeImpl( const css::uno::Reference< css::uno::XComponentContext >& rxContext,
+ const OUString& sScriptingContext,
+ SbMethod* pMethod, bool isAppScript );
+ virtual ~BasicMethodNodeImpl() override;
+
+ // XInterface
+ DECLARE_XINTERFACE()
+
+ // XTypeProvider
+ DECLARE_XTYPEPROVIDER()
+
+ // XBrowseNode
+ virtual OUString SAL_CALL getName( ) override;
+ virtual css::uno::Sequence< css::uno::Reference< css::script::browse::XBrowseNode > > SAL_CALL getChildNodes( ) override;
+ virtual sal_Bool SAL_CALL hasChildNodes( ) override;
+ virtual sal_Int16 SAL_CALL getType( ) override;
+
+ // XPropertySet
+ virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) override;
+
+ // XInvocation
+ virtual css::uno::Reference< css::beans::XIntrospectionAccess > SAL_CALL getIntrospection( ) override;
+ virtual css::uno::Any SAL_CALL invoke(
+ const OUString& aFunctionName,
+ const css::uno::Sequence< css::uno::Any >& aParams,
+ css::uno::Sequence< sal_Int16 >& aOutParamIndex,
+ css::uno::Sequence< css::uno::Any >& aOutParam ) override;
+ virtual void SAL_CALL setValue( const OUString& aPropertyName, const css::uno::Any& aValue ) override;
+ virtual css::uno::Any SAL_CALL getValue( const OUString& aPropertyName ) override;
+ virtual sal_Bool SAL_CALL hasMethod( const OUString& aName ) override;
+ virtual sal_Bool SAL_CALL hasProperty( const OUString& aName ) override;
+ };
+
+
+} // namespace basprov
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/scripting/source/basprov/basmodnode.cxx b/scripting/source/basprov/basmodnode.cxx
new file mode 100644
index 000000000..986e3062d
--- /dev/null
+++ b/scripting/source/basprov/basmodnode.cxx
@@ -0,0 +1,134 @@
+/* -*- 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 "basmodnode.hxx"
+#include "basmethnode.hxx"
+#include <com/sun/star/script/browse/BrowseNodeTypes.hpp>
+#include <vcl/svapp.hxx>
+#include <basic/sbx.hxx>
+#include <basic/sbmod.hxx>
+#include <basic/sbmeth.hxx>
+
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::script;
+
+
+namespace basprov
+{
+
+
+ // BasicModuleNodeImpl
+
+
+ BasicModuleNodeImpl::BasicModuleNodeImpl( const Reference< XComponentContext >& rxContext,
+ const OUString& sScriptingContext, SbModule* pModule, bool isAppScript )
+ :m_xContext( rxContext )
+ ,m_sScriptingContext( sScriptingContext )
+ ,m_pModule( pModule )
+ ,m_bIsAppScript( isAppScript )
+ {
+ }
+
+
+ BasicModuleNodeImpl::~BasicModuleNodeImpl()
+ {
+ }
+
+
+ // XBrowseNode
+
+
+ OUString BasicModuleNodeImpl::getName( )
+ {
+ SolarMutexGuard aGuard;
+
+ OUString sModuleName;
+ if ( m_pModule )
+ sModuleName = m_pModule->GetName();
+
+ return sModuleName;
+ }
+
+
+ Sequence< Reference< browse::XBrowseNode > > BasicModuleNodeImpl::getChildNodes( )
+ {
+ SolarMutexGuard aGuard;
+
+ Sequence< Reference< browse::XBrowseNode > > aChildNodes;
+
+ if ( m_pModule )
+ {
+ SbxArray* pMethods = m_pModule->GetMethods().get();
+ if ( pMethods )
+ {
+ sal_uInt32 nCount = pMethods->Count();
+ sal_Int32 nRealCount = 0;
+ for ( sal_uInt32 i = 0; i < nCount; ++i )
+ {
+ SbMethod* pMethod = static_cast<SbMethod*>(pMethods->Get(i));
+ if ( pMethod && !pMethod->IsHidden() )
+ ++nRealCount;
+ }
+ aChildNodes.realloc( nRealCount );
+ Reference< browse::XBrowseNode >* pChildNodes = aChildNodes.getArray();
+
+ sal_Int32 iTarget = 0;
+ for ( sal_uInt32 i = 0; i < nCount; ++i )
+ {
+ SbMethod* pMethod = static_cast<SbMethod*>(pMethods->Get(i));
+ if ( pMethod && !pMethod->IsHidden() )
+ pChildNodes[iTarget++] = new BasicMethodNodeImpl(
+ m_xContext, m_sScriptingContext, pMethod, m_bIsAppScript);
+ }
+ }
+ }
+
+ return aChildNodes;
+ }
+
+
+ sal_Bool BasicModuleNodeImpl::hasChildNodes( )
+ {
+ SolarMutexGuard aGuard;
+
+ bool bReturn = false;
+ if ( m_pModule )
+ {
+ SbxArray* pMethods = m_pModule->GetMethods().get();
+ if (pMethods && pMethods->Count() > 0)
+ bReturn = true;
+ }
+
+ return bReturn;
+ }
+
+
+ sal_Int16 BasicModuleNodeImpl::getType( )
+ {
+ return browse::BrowseNodeTypes::CONTAINER;
+ }
+
+
+} // namespace basprov
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/scripting/source/basprov/basmodnode.hxx b/scripting/source/basprov/basmodnode.hxx
new file mode 100644
index 000000000..ebf0957ef
--- /dev/null
+++ b/scripting/source/basprov/basmodnode.hxx
@@ -0,0 +1,64 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <com/sun/star/script/browse/XBrowseNode.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <cppuhelper/implbase.hxx>
+
+class SbModule;
+
+
+namespace basprov
+{
+
+
+
+
+ typedef ::cppu::WeakImplHelper<
+ css::script::browse::XBrowseNode > BasicModuleNodeImpl_BASE;
+
+
+ class BasicModuleNodeImpl : public BasicModuleNodeImpl_BASE
+ {
+ private:
+ css::uno::Reference< css::uno::XComponentContext > m_xContext;
+ OUString m_sScriptingContext;
+ SbModule* m_pModule;
+ bool m_bIsAppScript;
+
+ public:
+ BasicModuleNodeImpl( const css::uno::Reference< css::uno::XComponentContext >& rxContext,
+ const OUString& sScriptingContext,
+ SbModule* pModule, bool isAppScript );
+ virtual ~BasicModuleNodeImpl() override;
+
+ // XBrowseNode
+ virtual OUString SAL_CALL getName( ) override;
+ virtual css::uno::Sequence< css::uno::Reference< css::script::browse::XBrowseNode > > SAL_CALL getChildNodes( ) override;
+ virtual sal_Bool SAL_CALL hasChildNodes( ) override;
+ virtual sal_Int16 SAL_CALL getType( ) override;
+ };
+
+
+} // namespace basprov
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/scripting/source/basprov/basprov.component b/scripting/source/basprov/basprov.component
new file mode 100644
index 000000000..d0d6bf974
--- /dev/null
+++ b/scripting/source/basprov/basprov.component
@@ -0,0 +1,29 @@
+<?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.scripting.ScriptProviderForBasic"
+ constructor="scripting_BasicProviderImpl_get_implementation">
+ <service name="com.sun.star.script.browse.BrowseNode"/>
+ <service name="com.sun.star.script.provider.LanguageScriptProvider"/>
+ <service name="com.sun.star.script.provider.ScriptProvider"/>
+ <service name="com.sun.star.script.provider.ScriptProviderForBasic"/>
+ </implementation>
+</component>
diff --git a/scripting/source/basprov/basprov.cxx b/scripting/source/basprov/basprov.cxx
new file mode 100644
index 000000000..d4afb41ea
--- /dev/null
+++ b/scripting/source/basprov/basprov.cxx
@@ -0,0 +1,477 @@
+/* -*- 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 "basprov.hxx"
+#include "basscript.hxx"
+#include "baslibnode.hxx"
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/script/browse/BrowseNodeTypes.hpp>
+#include <com/sun/star/script/provider/ScriptFrameworkErrorException.hpp>
+#include <com/sun/star/script/provider/ScriptFrameworkErrorType.hpp>
+#include <com/sun/star/document/XEmbeddedScripts.hpp>
+#include <com/sun/star/uri/UriReferenceFactory.hpp>
+
+#include <cppuhelper/supportsservice.hxx>
+#include <rtl/uri.hxx>
+#include <sal/log.hxx>
+#include <osl/file.hxx>
+#include <vcl/svapp.hxx>
+#include <basic/basmgr.hxx>
+#include <basic/basicmanagerrepository.hxx>
+#include <basic/sbstar.hxx>
+#include <basic/sbmod.hxx>
+#include <basic/sbmeth.hxx>
+#include <sfx2/app.hxx>
+
+#include <com/sun/star/util/theMacroExpander.hpp>
+#include <com/sun/star/script/XLibraryContainer2.hpp>
+#include <com/sun/star/uri/XUriReference.hpp>
+#include <com/sun/star/uri/XUriReferenceFactory.hpp>
+#include <com/sun/star/uri/XVndSunStarScriptUrl.hpp>
+
+#include <util/MiscUtils.hxx>
+
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::script;
+using namespace ::com::sun::star::document;
+using namespace ::sf_misc;
+
+
+namespace basprov
+{
+
+ // BasicProviderImpl
+
+
+ BasicProviderImpl::BasicProviderImpl( const Reference< XComponentContext >& xContext )
+ :m_pAppBasicManager( nullptr )
+ ,m_pDocBasicManager( nullptr )
+ ,m_xContext( xContext )
+ ,m_bIsAppScriptCtx( true )
+ ,m_bIsUserCtx(true)
+ {
+ }
+
+
+ BasicProviderImpl::~BasicProviderImpl()
+ {
+ SolarMutexGuard aGuard;
+ EndListeningAll();
+ }
+
+
+ bool BasicProviderImpl::isLibraryShared( const Reference< script::XLibraryContainer >& rxLibContainer, const OUString& rLibName )
+ {
+ bool bIsShared = false;
+
+ Reference< script::XLibraryContainer2 > xLibContainer( rxLibContainer, UNO_QUERY );
+ if ( xLibContainer.is() && xLibContainer->hasByName( rLibName ) && xLibContainer->isLibraryLink( rLibName ) )
+ {
+ OUString aFileURL;
+ if ( m_xContext.is() )
+ {
+ Reference< uri::XUriReferenceFactory > xUriFac( uri::UriReferenceFactory::create( m_xContext ) );
+
+ OUString aLinkURL( xLibContainer->getLibraryLinkURL( rLibName ) );
+ Reference< uri::XUriReference > xUriRef = xUriFac->parse( aLinkURL );
+
+ if ( xUriRef.is() )
+ {
+ OUString aScheme = xUriRef->getScheme();
+ if ( aScheme.equalsIgnoreAsciiCase("file") )
+ {
+ aFileURL = aLinkURL;
+ }
+ else if ( aScheme.equalsIgnoreAsciiCase("vnd.sun.star.pkg") )
+ {
+ OUString aAuthority = xUriRef->getAuthority();
+ if ( aAuthority.matchIgnoreAsciiCase( "vnd.sun.star.expand:" ) )
+ {
+ OUString aDecodedURL( aAuthority.copy( sizeof ( "vnd.sun.star.expand:" ) - 1 ) );
+ aDecodedURL = ::rtl::Uri::decode( aDecodedURL, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 );
+ Reference<util::XMacroExpander> xMacroExpander =
+ util::theMacroExpander::get(m_xContext);
+ aFileURL = xMacroExpander->expandMacros( aDecodedURL );
+ }
+ }
+ }
+ }
+
+ if ( !aFileURL.isEmpty() )
+ {
+ osl::DirectoryItem aFileItem;
+ osl::FileStatus aFileStatus( osl_FileStatus_Mask_FileURL );
+ OSL_VERIFY( osl::DirectoryItem::get( aFileURL, aFileItem ) == osl::FileBase::E_None );
+ OSL_VERIFY( aFileItem.getFileStatus( aFileStatus ) == osl::FileBase::E_None );
+ OUString aCanonicalFileURL( aFileStatus.getFileURL() );
+
+ if( aCanonicalFileURL.indexOf( "share/basic" ) != -1
+ || aCanonicalFileURL.indexOf( "share/uno_packages" ) != -1 )
+ bIsShared = true;
+ }
+ }
+
+ return bIsShared;
+ }
+
+ // SfxListener
+ void BasicProviderImpl::Notify(SfxBroadcaster& rBC, const SfxHint& rHint)
+ {
+ if (auto pManager = dynamic_cast<const BasicManager*>(&rBC))
+ if (pManager == m_pAppBasicManager && rHint.GetId() == SfxHintId::Dying)
+ {
+ EndListening(*m_pAppBasicManager);
+ m_pAppBasicManager = nullptr;
+ }
+ }
+
+ // XServiceInfo
+ OUString BasicProviderImpl::getImplementationName( )
+ {
+ return "com.sun.star.comp.scripting.ScriptProviderForBasic";
+ }
+
+ sal_Bool BasicProviderImpl::supportsService( const OUString& rServiceName )
+ {
+ return cppu::supportsService(this, rServiceName);
+ }
+
+ Sequence< OUString > BasicProviderImpl::getSupportedServiceNames( )
+ {
+ return {
+ "com.sun.star.script.provider.ScriptProviderForBasic",
+ "com.sun.star.script.provider.LanguageScriptProvider",
+ "com.sun.star.script.provider.ScriptProvider",
+ "com.sun.star.script.browse.BrowseNode"};
+ }
+
+
+ // XInitialization
+
+
+ void BasicProviderImpl::initialize( const Sequence< Any >& aArguments )
+ {
+ // TODO
+
+ SolarMutexGuard aGuard;
+
+ if ( aArguments.getLength() != 1 )
+ {
+ throw IllegalArgumentException(
+ "BasicProviderImpl::initialize: incorrect argument count.",
+ *this,
+ 1
+ );
+ }
+
+ Reference< frame::XModel > xModel;
+
+ m_xInvocationContext.set( aArguments[0], UNO_QUERY );
+ if ( m_xInvocationContext.is() )
+ {
+ xModel.set( m_xInvocationContext->getScriptContainer(), UNO_QUERY );
+ if ( !xModel.is() )
+ {
+ throw IllegalArgumentException(
+ "BasicProviderImpl::initialize: unable to determine the document model from the script invocation context.",
+ *this,
+ 1
+ );
+ }
+ }
+ else
+ {
+ if ( !( aArguments[0] >>= m_sScriptingContext ) )
+ {
+ throw IllegalArgumentException(
+ "BasicProviderImpl::initialize: incorrect argument type " + aArguments[0].getValueTypeName(),
+ *this,
+ 1
+ );
+ }
+
+ if ( m_sScriptingContext.startsWith( "vnd.sun.star.tdoc" ) )
+ {
+ xModel = MiscUtils::tDocUrlToModel( m_sScriptingContext );
+ }
+ }
+
+ if ( xModel.is() )
+ {
+ Reference< XEmbeddedScripts > xDocumentScripts( xModel, UNO_QUERY );
+ if ( xDocumentScripts.is() )
+ {
+ m_pDocBasicManager = ::basic::BasicManagerRepository::getDocumentBasicManager( xModel );
+ m_xLibContainerDoc = xDocumentScripts->getBasicLibraries();
+ OSL_ENSURE( m_pDocBasicManager && m_xLibContainerDoc.is(),
+ "BasicProviderImpl::initialize: invalid BasicManager, or invalid script container!" );
+ }
+ m_bIsAppScriptCtx = false;
+ }
+ else
+ {
+ // Provider has been created with application context for user
+ // or share
+ if ( m_sScriptingContext != "user" )
+ {
+ m_bIsUserCtx = false;
+ }
+ else
+ {
+ /*
+ throw RuntimeException(
+ "BasicProviderImpl::initialize: no scripting context!" );
+ */
+ }
+ }
+
+ // TODO
+ if ( !m_pAppBasicManager )
+ {
+ m_pAppBasicManager = SfxApplication::GetBasicManager();
+ if (m_pAppBasicManager)
+ StartListening(*m_pAppBasicManager);
+ }
+
+ if ( !m_xLibContainerApp.is() )
+ m_xLibContainerApp = SfxGetpApp()->GetBasicContainer();
+ }
+
+
+ // XScriptProvider
+
+
+ Reference < provider::XScript > BasicProviderImpl::getScript( const OUString& scriptURI )
+ {
+ // TODO
+
+ SolarMutexGuard aGuard;
+
+ Reference< provider::XScript > xScript;
+ Reference< uri::XUriReferenceFactory > xFac ( uri::UriReferenceFactory::create( m_xContext ) );
+
+ Reference< uri::XUriReference > uriRef = xFac->parse( scriptURI );
+
+ Reference < uri::XVndSunStarScriptUrl > sfUri( uriRef, UNO_QUERY );
+
+ if ( !uriRef.is() || !sfUri.is() )
+ {
+ throw provider::ScriptFrameworkErrorException(
+ "BasicProviderImpl::getScript: failed to parse URI: " + scriptURI,
+ Reference< XInterface >(),
+ scriptURI, "Basic",
+ provider::ScriptFrameworkErrorType::MALFORMED_URL );
+ }
+
+
+ OUString aDescription = sfUri->getName();
+ OUString aLocation = sfUri->getParameter( "location" );
+
+ sal_Int32 nIndex = 0;
+ // In some strange circumstances the Library name can have an
+ // apparently illegal '.' in it ( in imported VBA )
+
+ BasicManager* pBasicMgr = nullptr;
+ if ( aLocation == "document" )
+ {
+ pBasicMgr = m_pDocBasicManager;
+ }
+ else if ( aLocation == "application" )
+ {
+ pBasicMgr = m_pAppBasicManager;
+ }
+ OUString sProjectName;
+ if ( pBasicMgr )
+ sProjectName = pBasicMgr->GetName();
+
+ OUString aLibrary;
+ if ( !sProjectName.isEmpty() && aDescription.match( sProjectName ) )
+ {
+ SAL_WARN("scripting", "LibraryName " << sProjectName << " is part of the url " << aDescription );
+ aLibrary = sProjectName;
+ nIndex = sProjectName.getLength() + 1;
+ }
+ else
+ aLibrary = aDescription.getToken( 0, '.', nIndex );
+ OUString aModule;
+ if ( nIndex != -1 )
+ aModule = aDescription.getToken( 0, '.', nIndex );
+ OUString aMethod;
+ if ( nIndex != -1 )
+ aMethod = aDescription.getToken( 0, '.', nIndex );
+
+ if ( !aLibrary.isEmpty() && !aModule.isEmpty() && !aMethod.isEmpty() && !aLocation.isEmpty() )
+ {
+
+ if ( pBasicMgr )
+ {
+ StarBASIC* pBasic = pBasicMgr->GetLib( aLibrary );
+ if ( !pBasic )
+ {
+ sal_uInt16 nId = pBasicMgr->GetLibId( aLibrary );
+ if ( nId != LIB_NOTFOUND )
+ {
+ pBasicMgr->LoadLib( nId );
+ pBasic = pBasicMgr->GetLib( aLibrary );
+ }
+ }
+ if ( pBasic )
+ {
+ SbModule* pModule = pBasic->FindModule( aModule );
+ if ( pModule )
+ {
+ SbMethod* pMethod = pModule->FindMethod( aMethod, SbxClassType::Method );
+ if ( pMethod && !pMethod->IsHidden() )
+ {
+ if ( m_pDocBasicManager == pBasicMgr )
+ xScript = new BasicScriptImpl( aDescription, pMethod, *m_pDocBasicManager, m_xInvocationContext );
+ else
+ xScript = new BasicScriptImpl( aDescription, pMethod );
+ }
+ }
+ }
+ }
+ }
+
+ if ( !xScript.is() )
+ {
+ throw provider::ScriptFrameworkErrorException(
+ "The following Basic script could not be found:\n"
+ "library: '" + aLibrary + "'\n"
+ "module: '" + aModule + "'\n"
+ "method: '" + aMethod + "'\n"
+ "location: '" + aLocation + "'\n",
+ Reference< XInterface >(),
+ scriptURI, "Basic",
+ provider::ScriptFrameworkErrorType::NO_SUCH_SCRIPT );
+ }
+
+ return xScript;
+ }
+
+
+ // XBrowseNode
+
+
+ OUString BasicProviderImpl::getName( )
+ {
+ return "Basic";
+ }
+
+
+ Sequence< Reference< browse::XBrowseNode > > BasicProviderImpl::getChildNodes( )
+ {
+ SolarMutexGuard aGuard;
+
+ Reference< script::XLibraryContainer > xLibContainer;
+ BasicManager* pBasicManager = nullptr;
+
+ if ( m_bIsAppScriptCtx )
+ {
+ xLibContainer = m_xLibContainerApp;
+ pBasicManager = m_pAppBasicManager;
+ }
+ else
+ {
+ xLibContainer = m_xLibContainerDoc;
+ pBasicManager = m_pDocBasicManager;
+ }
+
+ Sequence< Reference< browse::XBrowseNode > > aChildNodes;
+
+ if ( pBasicManager && xLibContainer.is() )
+ {
+ const Sequence< OUString > aLibNames = xLibContainer->getElementNames();
+ sal_Int32 nLibCount = aLibNames.getLength();
+ aChildNodes.realloc( nLibCount );
+ Reference< browse::XBrowseNode >* pChildNodes = aChildNodes.getArray();
+ sal_Int32 childrenFound = 0;
+
+ for ( const OUString& rLibName : aLibNames )
+ {
+ bool bCreate = false;
+ if ( m_bIsAppScriptCtx )
+ {
+ const bool bShared = isLibraryShared( xLibContainer, rLibName );
+ if (m_bIsUserCtx != bShared)
+ bCreate = true;
+ }
+ else
+ {
+ bCreate = true;
+ }
+ if ( bCreate )
+ {
+ pChildNodes[childrenFound++]
+ = new BasicLibraryNodeImpl(m_xContext, m_sScriptingContext, pBasicManager,
+ xLibContainer, rLibName, m_bIsAppScriptCtx);
+ }
+ }
+
+ if ( childrenFound != nLibCount )
+ aChildNodes.realloc( childrenFound );
+ }
+
+ return aChildNodes;
+ }
+
+
+ sal_Bool BasicProviderImpl::hasChildNodes( )
+ {
+ SolarMutexGuard aGuard;
+
+ bool bReturn = false;
+ Reference< script::XLibraryContainer > xLibContainer;
+ if ( m_bIsAppScriptCtx )
+ {
+ xLibContainer = m_xLibContainerApp;
+ }
+ else
+ {
+ xLibContainer = m_xLibContainerDoc;
+ }
+ if ( xLibContainer.is() )
+ bReturn = xLibContainer->hasElements();
+
+ return bReturn;
+ }
+
+
+ sal_Int16 BasicProviderImpl::getType( )
+ {
+ return browse::BrowseNodeTypes::CONTAINER;
+ }
+
+
+ // component operations
+
+ extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
+ scripting_BasicProviderImpl_get_implementation(
+ css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const&)
+ {
+ return cppu::acquire(new BasicProviderImpl(context));
+ }
+
+
+} // namespace basprov
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/scripting/source/basprov/basprov.hxx b/scripting/source/basprov/basprov.hxx
new file mode 100644
index 000000000..994113b62
--- /dev/null
+++ b/scripting/source/basprov/basprov.hxx
@@ -0,0 +1,97 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/script/XLibraryContainer.hpp>
+#include <com/sun/star/script/browse/XBrowseNode.hpp>
+#include <com/sun/star/script/provider/XScriptProvider.hpp>
+#include <com/sun/star/document/XScriptInvocationContext.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <cppuhelper/implbase.hxx>
+#include <svl/lstner.hxx>
+
+class BasicManager;
+
+
+namespace basprov
+{
+
+
+
+
+ typedef ::cppu::WeakImplHelper<
+ css::lang::XServiceInfo,
+ css::lang::XInitialization,
+ css::script::provider::XScriptProvider,
+ css::script::browse::XBrowseNode > BasicProviderImpl_BASE;
+
+
+ class BasicProviderImpl : public BasicProviderImpl_BASE, public SfxListener
+ {
+ private:
+ BasicManager* m_pAppBasicManager;
+ BasicManager* m_pDocBasicManager;
+ css::uno::Reference< css::script::XLibraryContainer > m_xLibContainerApp;
+ css::uno::Reference< css::script::XLibraryContainer > m_xLibContainerDoc;
+ css::uno::Reference< css::uno::XComponentContext > m_xContext;
+ css::uno::Reference< css::document::XScriptInvocationContext > m_xInvocationContext;
+ OUString m_sScriptingContext;
+ bool m_bIsAppScriptCtx;
+ bool m_bIsUserCtx;
+
+ bool isLibraryShared(
+ const css::uno::Reference< css::script::XLibraryContainer >& rxLibContainer,
+ const OUString& rLibName );
+
+ public:
+ explicit BasicProviderImpl(
+ const css::uno::Reference< css::uno::XComponentContext >& xContext );
+ virtual ~BasicProviderImpl() override;
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName( ) override;
+ virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
+ virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames( ) override;
+
+ // XInitialization
+ virtual void SAL_CALL initialize( const css::uno::Sequence< css::uno::Any >& aArguments ) override;
+
+ // XScriptProvider
+ virtual css::uno::Reference < css::script::provider::XScript > SAL_CALL getScript(
+ const OUString& scriptURI ) override;
+
+ // XBrowseNode
+ virtual OUString SAL_CALL getName( ) override;
+ virtual css::uno::Sequence< css::uno::Reference< css::script::browse::XBrowseNode > > SAL_CALL getChildNodes( ) override;
+ virtual sal_Bool SAL_CALL hasChildNodes( ) override;
+ virtual sal_Int16 SAL_CALL getType( ) override;
+
+ protected:
+ // SfxListener
+ virtual void Notify(SfxBroadcaster& rBC, const SfxHint& rHint) override;
+ };
+
+
+} // namespace basprov
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/scripting/source/basprov/basscript.cxx b/scripting/source/basprov/basscript.cxx
new file mode 100644
index 000000000..b5a3f6136
--- /dev/null
+++ b/scripting/source/basprov/basscript.cxx
@@ -0,0 +1,314 @@
+/* -*- 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 "basscript.hxx"
+#include <vcl/svapp.hxx>
+#include <basic/sbx.hxx>
+#include <basic/sbmod.hxx>
+#include <basic/sbmeth.hxx>
+#include <basic/sbuno.hxx>
+#include <basic/basmgr.hxx>
+#include <com/sun/star/script/provider/ScriptFrameworkErrorException.hpp>
+#include <com/sun/star/script/provider/ScriptFrameworkErrorType.hpp>
+#include <bcholder.hxx>
+#include <comphelper/propertycontainer.hxx>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <map>
+
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::script;
+using namespace ::com::sun::star::document;
+using namespace ::com::sun::star::beans;
+
+
+namespace basprov
+{
+
+#define BASSCRIPT_PROPERTY_ID_CALLER 1
+constexpr OUStringLiteral BASSCRIPT_PROPERTY_CALLER = u"Caller";
+
+#define BASSCRIPT_DEFAULT_ATTRIBS() PropertyAttribute::BOUND | PropertyAttribute::TRANSIENT
+
+ typedef ::std::map< sal_Int16, Any > OutParamMap;
+
+
+ // BasicScriptImpl
+
+
+ BasicScriptImpl::BasicScriptImpl( const OUString& funcName, SbMethodRef const & xMethod )
+ : ::scripting_helper::OBroadcastHelperHolder( m_aMutex )
+ ,OPropertyContainer( GetBroadcastHelper() )
+ ,m_xMethod( xMethod )
+ ,m_funcName( funcName )
+ ,m_documentBasicManager( nullptr )
+ ,m_xDocumentScriptContext()
+ {
+ registerProperty( BASSCRIPT_PROPERTY_CALLER, BASSCRIPT_PROPERTY_ID_CALLER, BASSCRIPT_DEFAULT_ATTRIBS(), &m_caller, cppu::UnoType<decltype(m_caller)>::get() );
+ }
+
+
+ BasicScriptImpl::BasicScriptImpl( const OUString& funcName, SbMethodRef const & xMethod,
+ BasicManager& documentBasicManager, const Reference< XScriptInvocationContext >& documentScriptContext ) : ::scripting_helper::OBroadcastHelperHolder( m_aMutex )
+ ,OPropertyContainer( GetBroadcastHelper() )
+ ,m_xMethod( xMethod )
+ ,m_funcName( funcName )
+ ,m_documentBasicManager( &documentBasicManager )
+ ,m_xDocumentScriptContext( documentScriptContext )
+ {
+ StartListening( *m_documentBasicManager );
+ registerProperty( BASSCRIPT_PROPERTY_CALLER, BASSCRIPT_PROPERTY_ID_CALLER, BASSCRIPT_DEFAULT_ATTRIBS(), &m_caller, cppu::UnoType<decltype(m_caller)>::get() );
+ }
+
+
+ BasicScriptImpl::~BasicScriptImpl()
+ {
+ SolarMutexGuard g;
+
+ if ( m_documentBasicManager )
+ EndListening( *m_documentBasicManager );
+ }
+
+
+ // SfxListener
+
+ void BasicScriptImpl::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
+ {
+ if ( &rBC != m_documentBasicManager )
+ {
+ OSL_ENSURE( false, "BasicScriptImpl::Notify: where does this come from?" );
+ // not interested in
+ return;
+ }
+ if ( rHint.GetId() == SfxHintId::Dying )
+ {
+ m_documentBasicManager = nullptr;
+ EndListening( rBC ); // prevent multiple notifications
+ }
+ }
+
+
+ // XInterface
+
+
+ IMPLEMENT_FORWARD_XINTERFACE2( BasicScriptImpl, BasicScriptImpl_BASE, OPropertyContainer )
+
+
+ // XTypeProvider
+
+
+ IMPLEMENT_FORWARD_XTYPEPROVIDER2( BasicScriptImpl, BasicScriptImpl_BASE, OPropertyContainer )
+
+
+ // OPropertySetHelper
+
+
+ ::cppu::IPropertyArrayHelper& BasicScriptImpl::getInfoHelper( )
+ {
+ return *getArrayHelper();
+ }
+
+
+ // OPropertyArrayUsageHelper
+
+
+ ::cppu::IPropertyArrayHelper* BasicScriptImpl::createArrayHelper( ) const
+ {
+ Sequence< Property > aProps;
+ describeProperties( aProps );
+ return new ::cppu::OPropertyArrayHelper( aProps );
+ }
+
+
+ // XPropertySet
+
+
+ Reference< XPropertySetInfo > BasicScriptImpl::getPropertySetInfo( )
+ {
+ Reference< XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) );
+ return xInfo;
+ }
+
+
+ // XScript
+
+
+ Any BasicScriptImpl::invoke( const Sequence< Any >& aParams, Sequence< sal_Int16 >& aOutParamIndex, Sequence< Any >& aOutParam )
+ {
+ // TODO: throw CannotConvertException
+ // TODO: check length of aOutParamIndex, aOutParam
+
+ SolarMutexGuard aGuard;
+
+ Any aReturn;
+
+ if ( m_xMethod.is() )
+ {
+ // check if compiled
+ SbModule* pModule = static_cast< SbModule* >( m_xMethod->GetParent() );
+ if ( pModule && !pModule->IsCompiled() )
+ pModule->Compile();
+
+ // check number of parameters
+ sal_Int32 nParamsCount = aParams.getLength();
+ SbxInfo* pInfo = m_xMethod->GetInfo();
+ if ( pInfo )
+ {
+ sal_Int32 nSbxOptional = 0;
+ sal_uInt16 n = 1;
+ for ( const SbxParamInfo* pParamInfo = pInfo->GetParam( n ); pParamInfo; pParamInfo = pInfo->GetParam( ++n ) )
+ {
+ if ( pParamInfo->nFlags & SbxFlagBits::Optional )
+ ++nSbxOptional;
+ else
+ nSbxOptional = 0;
+ }
+ sal_Int32 nSbxCount = n - 1;
+ if ( nParamsCount < nSbxCount - nSbxOptional )
+ {
+ throw provider::ScriptFrameworkErrorException(
+ "wrong number of parameters!",
+ Reference< XInterface >(),
+ m_funcName,
+ "Basic",
+ provider::ScriptFrameworkErrorType::NO_SUCH_SCRIPT );
+ }
+ }
+
+ // set parameters
+ SbxArrayRef xSbxParams;
+ if ( nParamsCount > 0 )
+ {
+ xSbxParams = new SbxArray;
+ const Any* pParams = aParams.getConstArray();
+ for ( sal_Int32 i = 0; i < nParamsCount; ++i )
+ {
+ SbxVariableRef xSbxVar = new SbxVariable( SbxVARIANT );
+ unoToSbxValue( xSbxVar.get(), pParams[i] );
+ xSbxParams->Put(xSbxVar.get(), static_cast<sal_uInt32>(i) + 1);
+
+ if (pInfo)
+ {
+ if (auto* p = pInfo->GetParam(static_cast<sal_uInt16>(i) + 1))
+ {
+ SbxDataType t = static_cast<SbxDataType>(p->eType & 0x0FFF);
+ // tdf#133889 Revert the downcasting performed in sbxToUnoValueImpl
+ // to allow passing by reference.
+ SbxDataType a = xSbxVar->GetType();
+ if (t == SbxSINGLE && (a == SbxINTEGER || a == SbxLONG))
+ {
+ sal_Int32 val = xSbxVar->GetLong();
+ if (val >= -16777216 && val <= 16777215)
+ xSbxVar->SetType(t);
+ }
+ else if (t == SbxDOUBLE && (a == SbxINTEGER || a == SbxLONG))
+ xSbxVar->SetType(t);
+ else if (t == SbxLONG && a == SbxINTEGER)
+ xSbxVar->SetType(t);
+ else if (t == SbxULONG && a == SbxUSHORT)
+ xSbxVar->SetType(t);
+ // Enable passing by ref
+ if (t != SbxVARIANT)
+ xSbxVar->SetFlag(SbxFlagBits::Fixed);
+ }
+ }
+ }
+ }
+ if ( xSbxParams.is() )
+ m_xMethod->SetParameters( xSbxParams.get() );
+
+ // call method
+ SbxVariableRef xReturn = new SbxVariable;
+ ErrCode nErr = ERRCODE_NONE;
+
+ // if it's a document-based script, temporarily reset ThisComponent to the script invocation context
+ Any aOldThisComponent;
+ if ( m_documentBasicManager && m_xDocumentScriptContext.is() )
+ m_documentBasicManager->SetGlobalUNOConstant( "ThisComponent", Any( m_xDocumentScriptContext ), &aOldThisComponent );
+
+ if ( m_caller.hasElements() && m_caller[ 0 ].hasValue() )
+ {
+ SbxVariableRef xCallerVar = new SbxVariable( SbxVARIANT );
+ unoToSbxValue( xCallerVar.get(), m_caller[ 0 ] );
+ nErr = m_xMethod->Call( xReturn.get(), xCallerVar.get() );
+ }
+ else
+ nErr = m_xMethod->Call( xReturn.get() );
+
+ if ( m_documentBasicManager && m_xDocumentScriptContext.is() )
+ m_documentBasicManager->SetGlobalUNOConstant( "ThisComponent", aOldThisComponent );
+
+ if ( nErr != ERRCODE_NONE )
+ {
+ // TODO: throw InvocationTargetException ?
+ }
+
+ // get output parameters
+ if ( xSbxParams.is() )
+ {
+ SbxInfo* pInfo_ = m_xMethod->GetInfo();
+ if ( pInfo_ )
+ {
+ OutParamMap aOutParamMap;
+ for (sal_uInt32 n = 1, nCount = xSbxParams->Count(); n < nCount; ++n)
+ {
+ assert(nCount <= std::numeric_limits<sal_uInt16>::max());
+ const SbxParamInfo* pParamInfo = pInfo_->GetParam( sal::static_int_cast<sal_uInt16>(n) );
+ if ( pParamInfo && ( pParamInfo->eType & SbxBYREF ) != 0 )
+ {
+ SbxVariable* pVar = xSbxParams->Get(n);
+ if ( pVar )
+ {
+ SbxVariableRef xVar = pVar;
+ aOutParamMap.emplace( n - 1, sbxToUnoValue( xVar.get() ) );
+ }
+ }
+ }
+ sal_Int32 nOutParamCount = aOutParamMap.size();
+ aOutParamIndex.realloc( nOutParamCount );
+ aOutParam.realloc( nOutParamCount );
+ sal_Int16* pOutParamIndex = aOutParamIndex.getArray();
+ Any* pOutParam = aOutParam.getArray();
+ for ( const auto& rEntry : aOutParamMap )
+ {
+ *pOutParamIndex = rEntry.first;
+ ++pOutParamIndex;
+ *pOutParam = rEntry.second;
+ ++pOutParam;
+ }
+ }
+ }
+
+ // get return value
+ aReturn = sbxToUnoValue( xReturn.get() );
+
+ // reset parameters
+ m_xMethod->SetParameters( nullptr );
+ }
+
+ return aReturn;
+ }
+
+
+} // namespace basprov
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/scripting/source/basprov/basscript.hxx b/scripting/source/basprov/basscript.hxx
new file mode 100644
index 000000000..d0f9e6e7a
--- /dev/null
+++ b/scripting/source/basprov/basscript.hxx
@@ -0,0 +1,103 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <bcholder.hxx>
+#include <com/sun/star/script/provider/XScript.hpp>
+#include <com/sun/star/document/XScriptInvocationContext.hpp>
+#include <cppuhelper/basemutex.hxx>
+#include <cppuhelper/implbase.hxx>
+#include <comphelper/proparrhlp.hxx>
+#include <comphelper/propertycontainer.hxx>
+#include <basic/sbmeth.hxx>
+#include <svl/lstner.hxx>
+
+class BasicManager;
+
+
+namespace basprov
+{
+
+
+
+
+ typedef ::cppu::WeakImplHelper<
+ css::script::provider::XScript > BasicScriptImpl_BASE;
+
+
+ class BasicScriptImpl : public BasicScriptImpl_BASE, public SfxListener,
+ public cppu::BaseMutex,
+ public ::scripting_helper::OBroadcastHelperHolder,
+ public ::comphelper::OPropertyContainer,
+ public ::comphelper::OPropertyArrayUsageHelper< BasicScriptImpl >
+ {
+ private:
+ SbMethodRef m_xMethod;
+ OUString m_funcName;
+ BasicManager* m_documentBasicManager;
+ css::uno::Reference< css::document::XScriptInvocationContext >
+ m_xDocumentScriptContext;
+ // hack, OPropertyContainer doesn't allow you to define a property of unknown
+ // type ( I guess because an Any can't contain an Any... I've always wondered why?
+ // as it's not unusual to do that in corba )
+ css::uno::Sequence< css::uno::Any > m_caller;
+ protected:
+ // OPropertySetHelper
+ virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper( ) override;
+
+ // OPropertyArrayUsageHelper
+ virtual ::cppu::IPropertyArrayHelper* createArrayHelper( ) const override;
+
+ public:
+ BasicScriptImpl(
+ const OUString& funcName,
+ SbMethodRef const & xMethod
+ );
+ BasicScriptImpl(
+ const OUString& funcName,
+ SbMethodRef const & xMethod,
+ BasicManager& documentBasicManager,
+ const css::uno::Reference< css::document::XScriptInvocationContext >& documentScriptContext
+ );
+ virtual ~BasicScriptImpl() override;
+
+ // XInterface
+ DECLARE_XINTERFACE()
+
+ // XTypeProvider
+ DECLARE_XTYPEPROVIDER()
+
+ // XScript
+ virtual css::uno::Any SAL_CALL invoke(
+ const css::uno::Sequence< css::uno::Any >& aParams,
+ css::uno::Sequence< sal_Int16 >& aOutParamIndex,
+ css::uno::Sequence< css::uno::Any >& aOutParam ) override;
+ // XPropertySet
+ virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) override;
+
+ // SfxListener
+ virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) override;
+ };
+
+
+} // namespace basprov
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */