summaryrefslogtreecommitdiffstats
path: root/scripting/source/dlgprov
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:06:44 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:06:44 +0000
commited5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch)
tree7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /scripting/source/dlgprov
parentInitial commit. (diff)
downloadlibreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.tar.xz
libreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.zip
Adding upstream version 4:7.4.7.upstream/4%7.4.7upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'scripting/source/dlgprov')
-rw-r--r--scripting/source/dlgprov/DialogModelProvider.cxx166
-rw-r--r--scripting/source/dlgprov/DialogModelProvider.hxx87
-rw-r--r--scripting/source/dlgprov/dlgevtatt.cxx658
-rw-r--r--scripting/source/dlgprov/dlgevtatt.hxx130
-rw-r--r--scripting/source/dlgprov/dlgprov.component32
-rw-r--r--scripting/source/dlgprov/dlgprov.cxx702
-rw-r--r--scripting/source/dlgprov/dlgprov.hxx148
7 files changed, 1923 insertions, 0 deletions
diff --git a/scripting/source/dlgprov/DialogModelProvider.cxx b/scripting/source/dlgprov/DialogModelProvider.cxx
new file mode 100644
index 000000000..e49ed058d
--- /dev/null
+++ b/scripting/source/dlgprov/DialogModelProvider.cxx
@@ -0,0 +1,166 @@
+/* -*- 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 "DialogModelProvider.hxx"
+#include "dlgprov.hxx"
+#include <com/sun/star/resource/XStringResourceManager.hpp>
+#include <com/sun/star/ucb/SimpleFileAccess.hpp>
+
+#include <cppuhelper/supportsservice.hxx>
+
+/// anonymous implementation namespace
+namespace dlgprov {
+
+using namespace ::com::sun::star;
+using namespace awt;
+using namespace lang;
+using namespace uno;
+using namespace script;
+using namespace beans;
+
+
+DialogModelProvider::DialogModelProvider(Reference< XComponentContext > const & context) :
+ m_xContext(context)
+{}
+
+// lang::XInitialization:
+void SAL_CALL DialogModelProvider::initialize(const css::uno::Sequence< uno::Any > & aArguments)
+{
+ if ( aArguments.getLength() != 1 )
+ return;
+
+ OUString sURL;
+ if ( !( aArguments[ 0 ] >>= sURL ))
+ throw css::lang::IllegalArgumentException();
+ // Try any other URL with SimpleFileAccess
+ Reference< ucb::XSimpleFileAccess3 > xSFI = ucb::SimpleFileAccess::create(m_xContext);
+
+ try
+ {
+ Reference< io::XInputStream > xInput = xSFI->openFileRead( sURL );
+ Reference< resource::XStringResourceManager > xStringResourceManager;
+ if ( xInput.is() )
+ {
+ xStringResourceManager = dlgprov::lcl_getStringResourceManager(m_xContext,sURL);
+ Any aDialogSourceURLAny;
+ aDialogSourceURLAny <<= sURL;
+
+ Reference< frame::XModel > xModel;
+ m_xDialogModel.set( dlgprov::lcl_createDialogModel( m_xContext, xInput , xModel, xStringResourceManager, aDialogSourceURLAny ), UNO_SET_THROW);
+ m_xDialogModelProp.set(m_xDialogModel, UNO_QUERY_THROW);
+ }
+ }
+ catch( Exception& )
+ {}
+ //m_sURL = sURL;
+}
+
+// container::XElementAccess:
+uno::Type SAL_CALL DialogModelProvider::getElementType()
+{
+ return m_xDialogModel->getElementType();
+}
+
+sal_Bool SAL_CALL DialogModelProvider::hasElements()
+{
+ return m_xDialogModel->hasElements();
+}
+
+// container::XNameAccess:
+uno::Any SAL_CALL DialogModelProvider::getByName(const OUString & aName)
+{
+ return m_xDialogModel->getByName(aName);
+}
+
+css::uno::Sequence< OUString > SAL_CALL DialogModelProvider::getElementNames()
+{
+ return m_xDialogModel->getElementNames();
+}
+
+sal_Bool SAL_CALL DialogModelProvider::hasByName(const OUString & aName)
+{
+ return m_xDialogModel->hasByName(aName);
+}
+
+// container::XNameReplace:
+void SAL_CALL DialogModelProvider::replaceByName(const OUString & aName, const uno::Any & aElement)
+{
+ m_xDialogModel->replaceByName(aName,aElement);
+}
+
+// container::XNameContainer:
+void SAL_CALL DialogModelProvider::insertByName(const OUString & aName, const uno::Any & aElement)
+{
+ m_xDialogModel->insertByName(aName,aElement);
+}
+
+void SAL_CALL DialogModelProvider::removeByName(const OUString & aName)
+{
+ m_xDialogModel->removeByName(aName);
+}
+uno::Reference< beans::XPropertySetInfo > SAL_CALL DialogModelProvider::getPropertySetInfo( )
+{
+ return m_xDialogModelProp->getPropertySetInfo();
+}
+void SAL_CALL DialogModelProvider::setPropertyValue( const OUString&, const uno::Any& )
+{
+}
+uno::Any SAL_CALL DialogModelProvider::getPropertyValue( const OUString& PropertyName )
+{
+ return m_xDialogModelProp->getPropertyValue(PropertyName);
+}
+void SAL_CALL DialogModelProvider::addPropertyChangeListener( const OUString& , const uno::Reference< beans::XPropertyChangeListener >& )
+{
+}
+void SAL_CALL DialogModelProvider::removePropertyChangeListener( const OUString& , const uno::Reference< beans::XPropertyChangeListener >& )
+{
+}
+void SAL_CALL DialogModelProvider::addVetoableChangeListener( const OUString& , const uno::Reference< beans::XVetoableChangeListener >& )
+{
+}
+void SAL_CALL DialogModelProvider::removeVetoableChangeListener( const OUString& ,const uno::Reference< beans::XVetoableChangeListener >& )
+{
+}
+
+// com.sun.star.uno.XServiceInfo:
+OUString SAL_CALL DialogModelProvider::getImplementationName()
+{
+ return "com.sun.star.comp.scripting.DialogModelProvider";
+}
+
+sal_Bool SAL_CALL DialogModelProvider::supportsService(OUString const & serviceName)
+{
+ return cppu::supportsService(this, serviceName);
+}
+
+css::uno::Sequence< OUString > SAL_CALL DialogModelProvider::getSupportedServiceNames()
+{
+ return { "com.sun.star.awt.UnoControlDialogModelProvider" };
+}
+
+} // closing anonymous implementation namespace
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
+scripting_DialogModelProvider_get_implementation(
+ css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const&)
+{
+ return cppu::acquire(new dlgprov::DialogModelProvider(context));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/scripting/source/dlgprov/DialogModelProvider.hxx b/scripting/source/dlgprov/DialogModelProvider.hxx
new file mode 100644
index 000000000..d9a41ef64
--- /dev/null
+++ b/scripting/source/dlgprov/DialogModelProvider.hxx
@@ -0,0 +1,87 @@
+/* -*- 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 <sal/config.h>
+#include <cppuhelper/factory.hxx>
+#include <cppuhelper/implbase.hxx>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+/// anonymous implementation namespace
+namespace dlgprov{
+
+class DialogModelProvider:
+ public ::cppu::WeakImplHelper<
+ css::lang::XInitialization,
+ css::container::XNameContainer,
+ css::beans::XPropertySet,
+ css::lang::XServiceInfo>
+{
+public:
+ explicit DialogModelProvider(css::uno::Reference< css::uno::XComponentContext > const & context);
+private:
+ // css::lang::XInitialization:
+ virtual void SAL_CALL initialize(const css::uno::Sequence< css::uno::Any > & aArguments) override;
+
+ // css::container::XElementAccess:
+ virtual css::uno::Type SAL_CALL getElementType() override;
+ virtual sal_Bool SAL_CALL hasElements() override;
+
+ // css::container::XNameAccess:
+ virtual css::uno::Any SAL_CALL getByName(const OUString & aName) override;
+ virtual css::uno::Sequence< OUString > SAL_CALL getElementNames() override;
+ virtual sal_Bool SAL_CALL hasByName(const OUString & aName) override;
+
+ // css::container::XNameReplace:
+ virtual void SAL_CALL replaceByName(const OUString & aName, const css::uno::Any & aElement) override;
+
+ // css::container::XNameContainer:
+ virtual void SAL_CALL insertByName(const OUString & aName, const css::uno::Any & aElement) override;
+ virtual void SAL_CALL removeByName(const OUString & Name) override;
+
+ // css::lang::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;
+
+ virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) override;
+ virtual void SAL_CALL setPropertyValue( const OUString& aPropertyName, const css::uno::Any& aValue ) override;
+ virtual css::uno::Any SAL_CALL getPropertyValue( const OUString& PropertyName ) override;
+ virtual void SAL_CALL addPropertyChangeListener( const OUString& aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener >& xListener ) override;
+ virtual void SAL_CALL removePropertyChangeListener( const OUString& aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener >& aListener ) override;
+ virtual void SAL_CALL addVetoableChangeListener( const OUString& PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener >& aListener ) override;
+ virtual void SAL_CALL removeVetoableChangeListener( const OUString& PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener >& aListener ) override;
+
+private:
+ DialogModelProvider(const DialogModelProvider &) = delete;
+ DialogModelProvider& operator=(const DialogModelProvider &) = delete;
+
+ // destructor is private and will be called indirectly by the release call virtual ~DialogModelProvider() {}
+
+ css::uno::Reference< css::uno::XComponentContext > m_xContext;
+ css::uno::Reference< css::container::XNameContainer> m_xDialogModel;
+ css::uno::Reference< css::beans::XPropertySet> m_xDialogModelProp;
+};
+} // closing anonymous implementation namespace
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/scripting/source/dlgprov/dlgevtatt.cxx b/scripting/source/dlgprov/dlgevtatt.cxx
new file mode 100644
index 000000000..704518e07
--- /dev/null
+++ b/scripting/source/dlgprov/dlgevtatt.cxx
@@ -0,0 +1,658 @@
+/* -*- 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 "dlgevtatt.hxx"
+
+#include "dlgprov.hxx"
+
+#include <sfx2/strings.hrc>
+#include <sfx2/sfxresid.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <tools/diagnose_ex.h>
+
+#include <com/sun/star/awt/XControl.hpp>
+#include <com/sun/star/awt/XControlContainer.hpp>
+#include <com/sun/star/awt/XDialogEventHandler.hpp>
+#include <com/sun/star/awt/XContainerWindowEventHandler.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/script/ScriptEventDescriptor.hpp>
+#include <com/sun/star/script/XScriptEventsSupplier.hpp>
+#include <com/sun/star/script/provider/XScriptProvider.hpp>
+#include <com/sun/star/script/provider/theMasterScriptProviderFactory.hpp>
+#include <com/sun/star/script/provider/XScriptProviderSupplier.hpp>
+#include <com/sun/star/script/vba/XVBACompatibility.hpp>
+#include <com/sun/star/lang/ServiceNotRegisteredException.hpp>
+#include <com/sun/star/reflection/XIdlMethod.hpp>
+#include <com/sun/star/beans/MethodConcept.hpp>
+#include <com/sun/star/beans/XMaterialHolder.hpp>
+
+#include <ooo/vba/XVBAToOOEventDescGen.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::script;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::reflection;
+
+
+namespace dlgprov
+{
+ namespace {
+
+ class DialogSFScriptListenerImpl : public DialogScriptListenerImpl
+ {
+ protected:
+ Reference< frame::XModel > m_xModel;
+ virtual void firing_impl( const script::ScriptEvent& aScriptEvent, uno::Any* pRet ) override;
+ public:
+ DialogSFScriptListenerImpl( const Reference< XComponentContext >& rxContext, const Reference< frame::XModel >& rxModel ) : DialogScriptListenerImpl( rxContext ), m_xModel( rxModel ) {}
+ };
+
+ class DialogLegacyScriptListenerImpl : public DialogSFScriptListenerImpl
+ {
+ protected:
+ virtual void firing_impl( const script::ScriptEvent& aScriptEvent, uno::Any* pRet ) override;
+ public:
+ DialogLegacyScriptListenerImpl( const Reference< XComponentContext >& rxContext, const Reference< frame::XModel >& rxModel ) : DialogSFScriptListenerImpl( rxContext, rxModel ){}
+ };
+
+ class DialogUnoScriptListenerImpl : public DialogSFScriptListenerImpl
+ {
+ Reference< awt::XControl > m_xControl;
+ Reference< XInterface > m_xHandler;
+ Reference< beans::XIntrospectionAccess > m_xIntrospectionAccess;
+ bool m_bDialogProviderMode;
+
+ virtual void firing_impl( const script::ScriptEvent& aScriptEvent, uno::Any* pRet ) override;
+
+ public:
+ DialogUnoScriptListenerImpl( const Reference< XComponentContext >& rxContext,
+ const Reference< frame::XModel >& rxModel,
+ const Reference< awt::XControl >& rxControl,
+ const Reference< XInterface >& rxHandler,
+ const Reference< beans::XIntrospectionAccess >& rxIntrospectionAccess,
+ bool bDialogProviderMode ); // false: ContainerWindowProvider mode
+
+ };
+
+ class DialogVBAScriptListenerImpl : public DialogScriptListenerImpl
+ {
+ protected:
+ OUString msDialogCodeName;
+ OUString msDialogLibName;
+ Reference< script::XScriptListener > mxListener;
+ virtual void firing_impl( const script::ScriptEvent& aScriptEvent, uno::Any* pRet ) override;
+ public:
+ DialogVBAScriptListenerImpl( const Reference< XComponentContext >& rxContext, const Reference< awt::XControl >& rxControl, const Reference< frame::XModel >& xModel, const OUString& sDialogLibName );
+ };
+
+ }
+
+ DialogVBAScriptListenerImpl::DialogVBAScriptListenerImpl( const Reference< XComponentContext >& rxContext, const Reference< awt::XControl >& rxControl, const Reference< frame::XModel >& xModel, const OUString& sDialogLibName ) : DialogScriptListenerImpl( rxContext ), msDialogLibName( sDialogLibName )
+ {
+ Reference< XMultiComponentFactory > xSMgr( m_xContext->getServiceManager() );
+ Sequence< Any > args(1);
+ if ( xSMgr.is() )
+ {
+ args.getArray()[0] <<= xModel;
+ mxListener.set( xSMgr->createInstanceWithArgumentsAndContext( "ooo.vba.EventListener", args, m_xContext ), UNO_QUERY );
+ }
+ if ( !rxControl.is() )
+ return;
+
+ try
+ {
+ Reference< XPropertySet > xProps( rxControl->getModel(), UNO_QUERY_THROW );
+ xProps->getPropertyValue("Name") >>= msDialogCodeName;
+ xProps.set( mxListener, UNO_QUERY_THROW );
+ xProps->setPropertyValue("Model", args[ 0 ] );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("scripting");
+ }
+
+ }
+
+ void DialogVBAScriptListenerImpl::firing_impl( const script::ScriptEvent& aScriptEvent, uno::Any* )
+ {
+ if ( !(aScriptEvent.ScriptType == "VBAInterop" && mxListener.is()) )
+ return;
+
+ ScriptEvent aScriptEventCopy( aScriptEvent );
+ aScriptEventCopy.ScriptCode = msDialogLibName + "." + msDialogCodeName;
+ try
+ {
+ mxListener->firing( aScriptEventCopy );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("scripting");
+ }
+ }
+
+
+ // DialogEventsAttacherImpl
+
+
+ DialogEventsAttacherImpl::DialogEventsAttacherImpl( const Reference< XComponentContext >& rxContext, const Reference< frame::XModel >& rxModel, const Reference< awt::XControl >& rxControl, const Reference< XInterface >& rxHandler, const Reference< beans::XIntrospectionAccess >& rxIntrospect, bool bProviderMode, const Reference< script::XScriptListener >& rxRTLListener, const OUString& sDialogLibName )
+ :mbUseFakeVBAEvents( false ), m_xContext( rxContext )
+ {
+ // key listeners by protocol when ScriptType = 'Script'
+ // otherwise key is the ScriptType e.g. StarBasic
+ if ( rxRTLListener.is() ) // set up handler for RTL_BASIC
+ listenersForTypes[ OUString("StarBasic") ] = rxRTLListener;
+ else
+ listenersForTypes[ OUString("StarBasic") ] = new DialogLegacyScriptListenerImpl( rxContext, rxModel );
+ // handler for Script & OUString("vnd.sun.star.UNO:")
+ listenersForTypes[ OUString("vnd.sun.star.UNO") ] = new DialogUnoScriptListenerImpl( rxContext, rxModel, rxControl, rxHandler, rxIntrospect, bProviderMode );
+ listenersForTypes[ OUString("vnd.sun.star.script") ] = new DialogSFScriptListenerImpl( rxContext, rxModel );
+
+ // determine the VBA compatibility mode from the Basic library container
+ try
+ {
+ uno::Reference< beans::XPropertySet > xModelProps( rxModel, uno::UNO_QUERY_THROW );
+ uno::Reference< script::vba::XVBACompatibility > xVBACompat(
+ xModelProps->getPropertyValue("BasicLibraries"), uno::UNO_QUERY_THROW );
+ mbUseFakeVBAEvents = xVBACompat->getVBACompatibilityMode();
+ }
+ catch( uno::Exception& )
+ {
+ }
+ if ( mbUseFakeVBAEvents )
+ listenersForTypes[ OUString("VBAInterop") ] = new DialogVBAScriptListenerImpl( rxContext, rxControl, rxModel, sDialogLibName );
+ }
+
+
+ DialogEventsAttacherImpl::~DialogEventsAttacherImpl()
+ {
+ }
+
+
+ Reference< script::XScriptListener > const &
+ DialogEventsAttacherImpl::getScriptListenerForKey( const OUString& sKey )
+ {
+ ListenerHash::iterator it = listenersForTypes.find( sKey );
+ if ( it == listenersForTypes.end() )
+ throw RuntimeException(); // more text info here please
+ return it->second;
+ }
+ Reference< XScriptEventsSupplier > DialogEventsAttacherImpl::getFakeVbaEventsSupplier( const Reference< XControl >& xControl, OUString const & sControlName )
+ {
+ Reference< XScriptEventsSupplier > xEventsSupplier;
+ Reference< XMultiComponentFactory > xSMgr( m_xContext->getServiceManager() );
+ if ( xSMgr.is() )
+ {
+ Reference< ooo::vba::XVBAToOOEventDescGen > xVBAToOOEvtDesc( xSMgr->createInstanceWithContext("ooo.vba.VBAToOOEventDesc", m_xContext ), UNO_QUERY );
+ if ( xVBAToOOEvtDesc.is() )
+ xEventsSupplier = xVBAToOOEvtDesc->getEventSupplier( xControl, sControlName );
+
+ }
+ return xEventsSupplier;
+ }
+
+
+ void DialogEventsAttacherImpl::attachEventsToControl( const Reference< XControl>& xControl, const Reference< XScriptEventsSupplier >& xEventsSupplier, const Any& Helper )
+ {
+ if ( !xEventsSupplier.is() )
+ return;
+
+ Reference< container::XNameContainer > xEventCont = xEventsSupplier->getEvents();
+
+ Reference< XControlModel > xControlModel = xControl->getModel();
+ if ( !xEventCont.is() )
+ return;
+
+ const Sequence< OUString > aNames = xEventCont->getElementNames();
+
+ for ( const OUString& rName : aNames )
+ {
+ ScriptEventDescriptor aDesc;
+
+ Any aElement = xEventCont->getByName( rName );
+ aElement >>= aDesc;
+ OUString sKey = aDesc.ScriptType;
+ if ( aDesc.ScriptType == "Script" || aDesc.ScriptType == "UNO" )
+ {
+ sal_Int32 nIndex = aDesc.ScriptCode.indexOf( ':' );
+ sKey = aDesc.ScriptCode.copy( 0, nIndex );
+ }
+ Reference< XAllListener > xAllListener =
+ new DialogAllListenerImpl( getScriptListenerForKey( sKey ), aDesc.ScriptType, aDesc.ScriptCode );
+
+ // try first to attach event to the ControlModel
+ bool bSuccess = false;
+ try
+ {
+ Reference< XEventListener > xListener_ = m_xEventAttacher->attachSingleEventListener(
+ xControlModel, xAllListener, Helper, aDesc.ListenerType,
+ aDesc.AddListenerParam, aDesc.EventMethod );
+
+ if ( xListener_.is() )
+ bSuccess = true;
+ }
+ catch ( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("scripting");
+ }
+
+ try
+ {
+ // if we had no success, try to attach to the control
+ if ( !bSuccess )
+ {
+ m_xEventAttacher->attachSingleEventListener(
+ xControl, xAllListener, Helper, aDesc.ListenerType,
+ aDesc.AddListenerParam, aDesc.EventMethod );
+ }
+ }
+ catch ( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("scripting");
+ }
+ }
+ }
+
+
+ void DialogEventsAttacherImpl::nestedAttachEvents( const Sequence< Reference< XInterface > >& Objects, const Any& Helper, OUString& sDialogCodeName )
+ {
+ for ( const Reference< XInterface >& rObject : Objects )
+ {
+ // We know that we have to do with instances of XControl.
+ // Otherwise this is not the right implementation for
+ // XScriptEventsAttacher and we have to give up.
+ Reference< XControl > xControl( rObject, UNO_QUERY );
+ Reference< XControlContainer > xControlContainer( xControl, UNO_QUERY );
+ Reference< XDialog > xDialog( xControl, UNO_QUERY );
+ if ( !xControl.is() )
+ throw IllegalArgumentException();
+
+ // get XEventsSupplier from control model
+ Reference< XControlModel > xControlModel = xControl->getModel();
+ Reference< XScriptEventsSupplier > xEventsSupplier( xControlModel, UNO_QUERY );
+ attachEventsToControl( xControl, xEventsSupplier, Helper );
+ if ( mbUseFakeVBAEvents )
+ {
+ xEventsSupplier.set( getFakeVbaEventsSupplier( xControl, sDialogCodeName ) );
+ Any newHelper(xControl );
+ attachEventsToControl( xControl, xEventsSupplier, newHelper );
+ }
+ if ( xControlContainer.is() && !xDialog.is() )
+ {
+ Sequence< Reference< XControl > > aControls = xControlContainer->getControls();
+ sal_Int32 nControlCount = aControls.getLength();
+
+ Sequence< Reference< XInterface > > aObjects( nControlCount );
+ Reference< XInterface >* pObjects2 = aObjects.getArray();
+ const Reference< XControl >* pControls = aControls.getConstArray();
+
+ for ( sal_Int32 i2 = 0; i2 < nControlCount; ++i2 )
+ {
+ pObjects2[i2].set( pControls[i2], UNO_QUERY );
+ }
+ nestedAttachEvents( aObjects, Helper, sDialogCodeName );
+ }
+ }
+ }
+
+
+ // XScriptEventsAttacher
+
+
+ void SAL_CALL DialogEventsAttacherImpl::attachEvents( const Sequence< Reference< XInterface > >& Objects,
+ const css::uno::Reference<css::script::XScriptListener>&,
+ const Any& Helper )
+ {
+ // get EventAttacher
+ {
+ ::osl::MutexGuard aGuard( getMutex() );
+
+ if ( !m_xEventAttacher.is() )
+ {
+ Reference< XMultiComponentFactory > xSMgr( m_xContext->getServiceManager() );
+ if ( !xSMgr.is() )
+ throw RuntimeException();
+
+ m_xEventAttacher.set( xSMgr->createInstanceWithContext(
+ "com.sun.star.script.EventAttacher", m_xContext ), UNO_QUERY );
+
+ if ( !m_xEventAttacher.is() )
+ throw ServiceNotRegisteredException();
+ }
+ }
+ OUString sDialogCodeName;
+ sal_Int32 nObjCount = Objects.getLength();
+ Reference< awt::XControl > xDlgControl( Objects[ nObjCount - 1 ], uno::UNO_QUERY ); // last object is the dialog
+ if ( xDlgControl.is() )
+ {
+ Reference< XPropertySet > xProps( xDlgControl->getModel(), UNO_QUERY );
+ try
+ {
+ xProps->getPropertyValue("Name") >>= sDialogCodeName;
+ }
+ catch( Exception& ){}
+ }
+ // go over all objects
+ nestedAttachEvents( Objects, Helper, sDialogCodeName );
+ }
+
+
+ // DialogAllListenerImpl
+
+
+ DialogAllListenerImpl::DialogAllListenerImpl( const Reference< XScriptListener >& rxListener,
+ const OUString& rScriptType, const OUString& rScriptCode )
+ :m_xScriptListener( rxListener )
+ ,m_sScriptType( rScriptType )
+ ,m_sScriptCode( rScriptCode )
+ {
+ }
+
+
+ DialogAllListenerImpl::~DialogAllListenerImpl()
+ {
+ }
+
+
+ void DialogAllListenerImpl::firing_impl( const AllEventObject& Event, Any* pRet )
+ {
+ ScriptEvent aScriptEvent;
+ aScriptEvent.Source = static_cast<OWeakObject *>(this); // get correct XInterface
+ aScriptEvent.ListenerType = Event.ListenerType;
+ aScriptEvent.MethodName = Event.MethodName;
+ aScriptEvent.Arguments = Event.Arguments;
+ aScriptEvent.Helper = Event.Helper;
+ aScriptEvent.ScriptType = m_sScriptType;
+ aScriptEvent.ScriptCode = m_sScriptCode;
+
+ if ( m_xScriptListener.is() )
+ {
+ if ( pRet )
+ *pRet = m_xScriptListener->approveFiring( aScriptEvent );
+ else
+ m_xScriptListener->firing( aScriptEvent );
+ }
+ }
+
+
+ // XEventListener
+
+
+ void DialogAllListenerImpl::disposing(const EventObject& )
+ {
+ }
+
+
+ // XAllListener
+
+
+ void DialogAllListenerImpl::firing( const AllEventObject& Event )
+ {
+ //::osl::MutexGuard aGuard( getMutex() );
+
+ firing_impl( Event, nullptr );
+ }
+
+
+ Any DialogAllListenerImpl::approveFiring( const AllEventObject& Event )
+ {
+ //::osl::MutexGuard aGuard( getMutex() );
+
+ Any aReturn;
+ firing_impl( Event, &aReturn );
+ return aReturn;
+ }
+
+
+ // DialogScriptListenerImpl
+
+
+ DialogUnoScriptListenerImpl::DialogUnoScriptListenerImpl( const Reference< XComponentContext >& rxContext,
+ const Reference< css::frame::XModel >& rxModel,
+ const Reference< css::awt::XControl >& rxControl,
+ const Reference< css::uno::XInterface >& rxHandler,
+ const Reference< css::beans::XIntrospectionAccess >& rxIntrospectionAccess,
+ bool bDialogProviderMode )
+ : DialogSFScriptListenerImpl( rxContext, rxModel )
+ ,m_xControl( rxControl )
+ ,m_xHandler( rxHandler )
+ ,m_xIntrospectionAccess( rxIntrospectionAccess )
+ ,m_bDialogProviderMode( bDialogProviderMode )
+ {
+ }
+
+
+ DialogScriptListenerImpl::~DialogScriptListenerImpl()
+ {
+ }
+
+
+ void DialogSFScriptListenerImpl::firing_impl( const ScriptEvent& aScriptEvent, Any* pRet )
+ {
+ try
+ {
+ Reference< provider::XScriptProvider > xScriptProvider;
+ if ( m_xModel.is() )
+ {
+ Reference< provider::XScriptProviderSupplier > xSupplier( m_xModel, UNO_QUERY );
+ OSL_ENSURE( xSupplier.is(), "DialogScriptListenerImpl::firing_impl: failed to get script provider supplier" );
+ if ( xSupplier.is() )
+ xScriptProvider.set( xSupplier->getScriptProvider() );
+ }
+ else
+ {
+ OSL_ASSERT( m_xContext.is() );
+ if ( m_xContext.is() )
+ {
+ Reference< provider::XScriptProviderFactory > xFactory =
+ provider::theMasterScriptProviderFactory::get( m_xContext );
+
+ Any aCtx;
+ aCtx <<= OUString("user");
+ xScriptProvider = xFactory->createScriptProvider( aCtx );
+ }
+ }
+
+ OSL_ENSURE( xScriptProvider.is(), "DialogScriptListenerImpl::firing_impl: failed to get script provider" );
+
+ if ( xScriptProvider.is() )
+ {
+ Reference< provider::XScript > xScript = xScriptProvider->getScript( aScriptEvent.ScriptCode );
+ OSL_ENSURE( xScript.is(), "DialogScriptListenerImpl::firing_impl: failed to get script" );
+
+ if ( xScript.is() )
+ {
+ Sequence< Any > aInParams;
+ Sequence< sal_Int16 > aOutParamsIndex;
+ Sequence< Any > aOutParams;
+
+ // get arguments for script
+ aInParams = aScriptEvent.Arguments;
+
+ Any aResult = xScript->invoke( aInParams, aOutParamsIndex, aOutParams );
+ if ( pRet )
+ *pRet = aResult;
+ }
+ }
+ }
+ catch ( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("scripting");
+ }
+ }
+
+ void DialogLegacyScriptListenerImpl::firing_impl( const ScriptEvent& aScriptEvent, Any* pRet )
+ {
+ OUString sScriptURL;
+ OUString sScriptCode( aScriptEvent.ScriptCode );
+
+ if ( aScriptEvent.ScriptType != "StarBasic" )
+ return;
+
+ // StarBasic script: convert ScriptCode to scriptURL
+ sal_Int32 nIndex = sScriptCode.indexOf( ':' );
+ if ( nIndex >= 0 && nIndex < sScriptCode.getLength() )
+ {
+ sScriptURL = OUString::Concat("vnd.sun.star.script:") +
+ sScriptCode.subView( nIndex + 1 ) +
+ "?language=Basic&location=" +
+ sScriptCode.subView( 0, nIndex );
+ }
+ ScriptEvent aSFScriptEvent( aScriptEvent );
+ aSFScriptEvent.ScriptCode = sScriptURL;
+ DialogSFScriptListenerImpl::firing_impl( aSFScriptEvent, pRet );
+ }
+
+ void DialogUnoScriptListenerImpl::firing_impl( const ScriptEvent& aScriptEvent, Any* pRet )
+ {
+ OUString aMethodName = aScriptEvent.ScriptCode.copy( strlen("vnd.sun.star.UNO:") );
+
+ const Any* pArguments = aScriptEvent.Arguments.getConstArray();
+ Any aEventObject = pArguments[0];
+
+ bool bHandled = false;
+ if( m_xHandler.is() )
+ {
+ if( m_bDialogProviderMode )
+ {
+ Reference< XDialogEventHandler > xDialogEventHandler( m_xHandler, UNO_QUERY );
+ if( xDialogEventHandler.is() )
+ {
+ Reference< XDialog > xDialog( m_xControl, UNO_QUERY );
+ bHandled = xDialogEventHandler->callHandlerMethod( xDialog, aEventObject, aMethodName );
+ }
+ }
+ else
+ {
+ Reference< XContainerWindowEventHandler > xContainerWindowEventHandler( m_xHandler, UNO_QUERY );
+ if( xContainerWindowEventHandler.is() )
+ {
+ Reference< XWindow > xWindow( m_xControl, UNO_QUERY );
+ bHandled = xContainerWindowEventHandler->callHandlerMethod( xWindow, aEventObject, aMethodName );
+ }
+ }
+ }
+
+ Any aRet;
+ if( !bHandled && m_xIntrospectionAccess.is() )
+ {
+ try
+ {
+ // call method
+ const Reference< XIdlMethod >& rxMethod = m_xIntrospectionAccess->
+ getMethod( aMethodName, MethodConcept::ALL - MethodConcept::DANGEROUS );
+
+ Reference< XMaterialHolder > xMaterialHolder =
+ Reference< XMaterialHolder >::query( m_xIntrospectionAccess );
+ Any aHandlerObject = xMaterialHolder->getMaterial();
+
+ Sequence< Reference< XIdlClass > > aParamTypeSeq = rxMethod->getParameterTypes();
+ sal_Int32 nParamCount = aParamTypeSeq.getLength();
+ if( nParamCount == 0 )
+ {
+ Sequence<Any> args;
+ rxMethod->invoke( aHandlerObject, args );
+ bHandled = true;
+ }
+ else if( nParamCount == 2 )
+ {
+ // Signature check automatically done by reflection
+ Sequence<Any> Args(2);
+ Any* pArgs = Args.getArray();
+ if( m_bDialogProviderMode )
+ {
+ Reference< XDialog > xDialog( m_xControl, UNO_QUERY );
+ pArgs[0] <<= xDialog;
+ }
+ else
+ {
+ Reference< XWindow > xWindow( m_xControl, UNO_QUERY );
+ pArgs[0] <<= xWindow;
+ }
+ pArgs[1] = aEventObject;
+ aRet = rxMethod->invoke( aHandlerObject, Args );
+ bHandled = true;
+ }
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("scripting");
+ }
+ }
+
+ if( bHandled )
+ {
+ if( pRet )
+ *pRet = aRet;
+ }
+ else
+ {
+ OUString aRes(SfxResId(STR_ERRUNOEVENTBINDUNG));
+ OUString aQuoteChar( "\"" );
+
+ sal_Int32 nIndex = aRes.indexOf( '%' );
+
+ OUString aOUFinal =
+ aRes.subView( 0, nIndex ) +
+ aQuoteChar + aMethodName + aQuoteChar +
+ aRes.subView( nIndex + 2 );
+
+ std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(nullptr,
+ VclMessageType::Warning, VclButtonsType::Ok, aOUFinal));
+ xBox->run();
+ }
+ }
+
+
+ // XEventListener
+
+
+ void DialogScriptListenerImpl::disposing(const EventObject& )
+ {
+ }
+
+
+ // XScriptListener
+
+
+ void DialogScriptListenerImpl::firing( const ScriptEvent& aScriptEvent )
+ {
+ //::osl::MutexGuard aGuard( getMutex() );
+
+ firing_impl( aScriptEvent, nullptr );
+ }
+
+
+ Any DialogScriptListenerImpl::approveFiring( const ScriptEvent& aScriptEvent )
+ {
+ //::osl::MutexGuard aGuard( getMutex() );
+
+ Any aReturn;
+ firing_impl( aScriptEvent, &aReturn );
+ return aReturn;
+ }
+
+
+} // namespace dlgprov
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/scripting/source/dlgprov/dlgevtatt.hxx b/scripting/source/dlgprov/dlgevtatt.hxx
new file mode 100644
index 000000000..239cb6530
--- /dev/null
+++ b/scripting/source/dlgprov/dlgevtatt.hxx
@@ -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 .
+ */
+
+#pragma once
+
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/script/XAllListener.hpp>
+#include <com/sun/star/script/XEventAttacher.hpp>
+#include <com/sun/star/script/XScriptEventsAttacher.hpp>
+#include <com/sun/star/script/XScriptListener.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/awt/XControl.hpp>
+#include <com/sun/star/beans/XIntrospectionAccess.hpp>
+#include <cppuhelper/implbase.hxx>
+
+#include <com/sun/star/script/XScriptEventsSupplier.hpp>
+
+#include <unordered_map>
+
+namespace dlgprov
+{
+ typedef std::unordered_map< OUString,
+ css::uno::Reference< css::script::XScriptListener > > ListenerHash;
+
+ typedef ::cppu::WeakImplHelper<
+ css::script::XScriptEventsAttacher > DialogEventsAttacherImpl_BASE;
+
+
+ class DialogEventsAttacherImpl : public DialogEventsAttacherImpl_BASE
+ {
+ private:
+ bool mbUseFakeVBAEvents;
+ ListenerHash listenersForTypes;
+ css::uno::Reference< css::uno::XComponentContext > m_xContext;
+ css::uno::Reference< css::script::XEventAttacher > m_xEventAttacher;
+ /// @throws css::uno::RuntimeException
+ css::uno::Reference< css::script::XScriptListener > const & getScriptListenerForKey( const OUString& sScriptName );
+ css::uno::Reference< css::script::XScriptEventsSupplier > getFakeVbaEventsSupplier( const css::uno::Reference< css::awt::XControl>& xControl, OUString const & sCodeName );
+ void nestedAttachEvents( const css::uno::Sequence< css::uno::Reference< css::uno::XInterface > >& Objects, const css::uno::Any& Helper, OUString& sDialogCodeName );
+ void attachEventsToControl( const css::uno::Reference< css::awt::XControl>& xControl, const css::uno::Reference< css::script::XScriptEventsSupplier >& events, const css::uno::Any& Helper );
+ public:
+ DialogEventsAttacherImpl( const css::uno::Reference< css::uno::XComponentContext >& rxContext,
+ const css::uno::Reference< css::frame::XModel >& xModel,
+ const css::uno::Reference< css::awt::XControl >& xControl,
+ const css::uno::Reference< css::uno::XInterface >& xHandler,
+ const css::uno::Reference< css::beans::XIntrospectionAccess >& xIntrospect,
+ bool bProviderMode,
+ const css::uno::Reference< css::script::XScriptListener >& xRTLListener ,const OUString& sDialogLibName );
+ virtual ~DialogEventsAttacherImpl() override;
+
+ // XScriptEventsAttacher
+ virtual void SAL_CALL attachEvents( const css::uno::Sequence<
+ css::uno::Reference< css::uno::XInterface > >& Objects,
+ const css::uno::Reference<css::script::XScriptListener>&,
+ const css::uno::Any& Helper ) override;
+ };
+
+
+
+
+ typedef ::cppu::WeakImplHelper<
+ css::script::XAllListener > DialogAllListenerImpl_BASE;
+
+
+ class DialogAllListenerImpl : public DialogAllListenerImpl_BASE
+ {
+ private:
+ css::uno::Reference< css::script::XScriptListener > m_xScriptListener;
+ OUString m_sScriptType;
+ OUString m_sScriptCode;
+
+ void firing_impl( const css::script::AllEventObject& Event, css::uno::Any* pRet );
+
+ public:
+ DialogAllListenerImpl( const css::uno::Reference< css::script::XScriptListener >& rxListener,
+ const OUString& rScriptType, const OUString& rScriptCode );
+ virtual ~DialogAllListenerImpl() override;
+
+ // XEventListener
+ virtual void SAL_CALL disposing( const css::lang::EventObject& Source ) override;
+
+ // XAllListener
+ virtual void SAL_CALL firing( const css::script::AllEventObject& Event ) override;
+ virtual css::uno::Any SAL_CALL approveFiring( const css::script::AllEventObject& Event ) override;
+ };
+
+
+
+
+ typedef ::cppu::WeakImplHelper<
+ css::script::XScriptListener > DialogScriptListenerImpl_BASE;
+
+
+ class DialogScriptListenerImpl : public DialogScriptListenerImpl_BASE
+ {
+ protected:
+ css::uno::Reference< css::uno::XComponentContext > m_xContext;
+ virtual void firing_impl( const css::script::ScriptEvent& aScriptEvent, css::uno::Any* pRet ) = 0;
+ public:
+ explicit DialogScriptListenerImpl( const css::uno::Reference< css::uno::XComponentContext >& rxContext ) : m_xContext( rxContext ) {}
+ virtual ~DialogScriptListenerImpl() override;
+
+ // XEventListener
+ virtual void SAL_CALL disposing( const css::lang::EventObject& Source ) override;
+
+ // XScriptListener
+ virtual void SAL_CALL firing( const css::script::ScriptEvent& aScriptEvent ) override;
+ virtual css::uno::Any SAL_CALL approveFiring( const css::script::ScriptEvent& aScriptEvent ) override;
+ };
+
+
+} // namespace dlgprov
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/scripting/source/dlgprov/dlgprov.component b/scripting/source/dlgprov/dlgprov.component
new file mode 100644
index 000000000..35203afb8
--- /dev/null
+++ b/scripting/source/dlgprov/dlgprov.component
@@ -0,0 +1,32 @@
+<?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.DialogProvider"
+ constructor="scripting_DialogProviderImpl_get_implementation">
+ <service name="com.sun.star.awt.ContainerWindowProvider"/>
+ <service name="com.sun.star.awt.DialogProvider"/>
+ <service name="com.sun.star.awt.DialogProvider2"/>
+ </implementation>
+ <implementation name="com.sun.star.comp.scripting.DialogModelProvider"
+ constructor="scripting_DialogModelProvider_get_implementation">
+ <service name="com.sun.star.awt.UnoControlDialogModelProvider"/>
+ </implementation>
+</component>
diff --git a/scripting/source/dlgprov/dlgprov.cxx b/scripting/source/dlgprov/dlgprov.cxx
new file mode 100644
index 000000000..18815f499
--- /dev/null
+++ b/scripting/source/dlgprov/dlgprov.cxx
@@ -0,0 +1,702 @@
+/* -*- 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 "dlgprov.hxx"
+#include "dlgevtatt.hxx"
+#include <com/sun/star/awt/UnoControlDialog.hpp>
+#include <com/sun/star/awt/Toolkit.hpp>
+#include <com/sun/star/awt/XControlContainer.hpp>
+#include <com/sun/star/awt/XWindowPeer.hpp>
+#include <com/sun/star/beans/theIntrospection.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/document/XEmbeddedScripts.hpp>
+#include <com/sun/star/lang/XMultiComponentFactory.hpp>
+#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
+#include <com/sun/star/io/XInputStreamProvider.hpp>
+#include <com/sun/star/resource/XStringResourceSupplier.hpp>
+#include <com/sun/star/resource/XStringResourceManager.hpp>
+#include <com/sun/star/script/XLibraryContainer.hpp>
+#include <com/sun/star/ucb/SimpleFileAccess.hpp>
+#include <com/sun/star/uri/XUriReference.hpp>
+#include <com/sun/star/uri/UriReferenceFactory.hpp>
+#include <com/sun/star/uri/XVndSunStarScriptUrl.hpp>
+#include <com/sun/star/uri/XVndSunStarExpandUrl.hpp>
+#include <com/sun/star/util/theMacroExpander.hpp>
+
+#include <cppuhelper/exc_hlp.hxx>
+#include <cppuhelper/supportsservice.hxx>
+#include <sfx2/app.hxx>
+#include <xmlscript/xmldlg_imexp.hxx>
+#include <tools/urlobj.hxx>
+#include <comphelper/namedvaluecollection.hxx>
+#include <util/MiscUtils.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/svapp.hxx>
+#include <i18nlangtag/languagetag.hxx>
+
+using namespace ::com::sun::star;
+using namespace awt;
+using namespace lang;
+using namespace uno;
+using namespace script;
+using namespace beans;
+using namespace document;
+using namespace ::sf_misc;
+
+namespace dlgprov
+{
+
+ Reference< resource::XStringResourceManager > lcl_getStringResourceManager(const Reference< XComponentContext >& i_xContext, std::u16string_view i_sURL)
+ {
+ INetURLObject aInetObj( i_sURL );
+ OUString aDlgName = aInetObj.GetBase();
+ aInetObj.removeSegment();
+ OUString aDlgLocation = aInetObj.GetMainURL( INetURLObject::DecodeMechanism::NONE );
+ css::lang::Locale aLocale = Application::GetSettings().GetUILanguageTag().getLocale();
+
+ Reference< task::XInteractionHandler > xDummyHandler;
+
+ Sequence<Any> aArgs{ Any(aDlgLocation),
+ Any(true), // bReadOnly
+ Any(aLocale),
+ Any(aDlgName),
+ Any(OUString()),
+ Any(xDummyHandler) };
+
+ Reference< XMultiComponentFactory > xSMgr_( i_xContext->getServiceManager(), UNO_SET_THROW );
+ // TODO: Ctor
+ Reference< resource::XStringResourceManager > xStringResourceManager( xSMgr_->createInstanceWithContext
+ ( "com.sun.star.resource.StringResourceWithLocation",
+ i_xContext ), UNO_QUERY );
+ if( xStringResourceManager.is() )
+ {
+ Reference< XInitialization > xInit( xStringResourceManager, UNO_QUERY );
+ if( xInit.is() )
+ xInit->initialize( aArgs );
+ }
+ return xStringResourceManager;
+ }
+ Reference< container::XNameContainer > lcl_createControlModel(const Reference< XComponentContext >& i_xContext)
+ {
+ Reference< XMultiComponentFactory > xSMgr_( i_xContext->getServiceManager(), UNO_SET_THROW );
+ Reference< container::XNameContainer > xControlModel( xSMgr_->createInstanceWithContext("com.sun.star.awt.UnoControlDialogModel", i_xContext ), UNO_QUERY_THROW );
+ return xControlModel;
+ }
+ Reference< container::XNameContainer > lcl_createDialogModel( const Reference< XComponentContext >& i_xContext,
+ const Reference< io::XInputStream >& xInput,
+ const Reference< frame::XModel >& xModel,
+ const Reference< resource::XStringResourceManager >& xStringResourceManager,
+ const Any &aDialogSourceURL)
+ {
+ Reference< container::XNameContainer > xDialogModel( lcl_createControlModel(i_xContext) );
+
+ Reference< beans::XPropertySet > xDlgPropSet( xDialogModel, UNO_QUERY );
+ xDlgPropSet->setPropertyValue( "DialogSourceURL", aDialogSourceURL );
+
+ // #TODO we really need to detect the source of the Dialog, is it
+ // the dialog. E.g. if the dialog was created from basic ( then we just
+ // can't tell where its from )
+ // If we are happy to always substitute the form model for the awt
+ // one then maybe the presence of a document model is enough to trigger
+ // swapping out the models ( or perhaps we only want to do this
+ // for vba mode ) there are a number of feasible and valid possibilities
+ ::xmlscript::importDialogModel( xInput, xDialogModel, i_xContext, xModel );
+
+ // Set resource property
+ if( xStringResourceManager.is() )
+ {
+ Reference< beans::XPropertySet > xDlgPSet( xDialogModel, UNO_QUERY );
+ Any aStringResourceManagerAny;
+ aStringResourceManagerAny <<= xStringResourceManager;
+ xDlgPSet->setPropertyValue( "ResourceResolver", aStringResourceManagerAny );
+ }
+
+ return xDialogModel;
+ }
+
+ // mutex
+
+
+ ::osl::Mutex& getMutex()
+ {
+ static ::osl::Mutex s_aMutex;
+
+ return s_aMutex;
+ }
+
+
+ // DialogProviderImpl
+
+
+ DialogProviderImpl::DialogProviderImpl( const Reference< XComponentContext >& rxContext )
+ :m_xContext( rxContext )
+ {
+ }
+
+
+ DialogProviderImpl::~DialogProviderImpl()
+ {
+ }
+
+
+ static Reference< resource::XStringResourceManager > getStringResourceFromDialogLibrary
+ ( const Reference< container::XNameContainer >& xDialogLib )
+ {
+ Reference< resource::XStringResourceManager > xStringResourceManager;
+ if( xDialogLib.is() )
+ {
+ Reference< resource::XStringResourceSupplier > xStringResourceSupplier( xDialogLib, UNO_QUERY );
+ if( xStringResourceSupplier.is() )
+ {
+ Reference< resource::XStringResourceResolver >
+ xStringResourceResolver = xStringResourceSupplier->getStringResource();
+
+ xStringResourceManager =
+ Reference< resource::XStringResourceManager >( xStringResourceResolver, UNO_QUERY );
+ }
+ }
+ return xStringResourceManager;
+ }
+
+ Reference< container::XNameContainer > DialogProviderImpl::createDialogModel(
+ const Reference< io::XInputStream >& xInput,
+ const Reference< resource::XStringResourceManager >& xStringResourceManager,
+ const Any &aDialogSourceURL)
+ {
+ return lcl_createDialogModel(m_xContext,xInput,m_xModel,xStringResourceManager,aDialogSourceURL);
+ }
+
+ Reference< XControlModel > DialogProviderImpl::createDialogModelForBasic()
+ {
+ if (!m_BasicInfo)
+ // shouldn't get here
+ throw RuntimeException("No information to create dialog" );
+ Reference< resource::XStringResourceManager > xStringResourceManager = getStringResourceFromDialogLibrary( m_BasicInfo->mxDlgLib );
+
+ Any aDialogSourceURL((OUString()));
+ Reference< XControlModel > xCtrlModel( createDialogModel( m_BasicInfo->mxInput, xStringResourceManager, aDialogSourceURL ), UNO_QUERY_THROW );
+ return xCtrlModel;
+ }
+
+ Reference< XControlModel > DialogProviderImpl::createDialogModel( const OUString& sURL )
+ {
+
+ OUString aURL( sURL );
+
+ // parse URL
+ // TODO: use URL parsing class
+ // TODO: decoding of location
+
+ Reference< uri::XUriReferenceFactory > xFac ( uri::UriReferenceFactory::create( m_xContext ) );
+
+ // i75778: Support non-script URLs
+ Reference< io::XInputStream > xInput;
+ Reference< container::XNameContainer > xDialogLib;
+
+ // Accept file URL to single dialog
+ bool bSingleDialog = false;
+
+ Reference< util::XMacroExpander > xMacroExpander =
+ util::theMacroExpander::get(m_xContext);
+
+ Reference< uri::XUriReference > uriRef;
+ for (;;)
+ {
+ uriRef = xFac->parse( aURL );
+ if ( !uriRef.is() )
+ {
+ OUString errorMsg = "DialogProviderImpl::getDialogModel: failed to parse URI: " + aURL;
+ throw IllegalArgumentException( errorMsg, Reference< XInterface >(), 1 );
+ }
+ Reference < uri::XVndSunStarExpandUrl > sxUri( uriRef, UNO_QUERY );
+ if( !sxUri.is() )
+ break;
+
+ aURL = sxUri->expand( xMacroExpander );
+ }
+
+ Reference < uri::XVndSunStarScriptUrl > sfUri( uriRef, UNO_QUERY );
+ if( !sfUri.is() )
+ {
+ bSingleDialog = true;
+
+ // Try any other URL with SimpleFileAccess
+ Reference< ucb::XSimpleFileAccess3 > xSFI = ucb::SimpleFileAccess::create(m_xContext);
+
+ try
+ {
+ xInput = xSFI->openFileRead( aURL );
+ }
+ catch( Exception& )
+ {}
+ }
+ else
+ {
+ OUString sDescription = sfUri->getName();
+
+ sal_Int32 nIndex = 0;
+
+ OUString sLibName = sDescription.getToken( 0, '.', nIndex );
+ OUString sDlgName;
+ if ( nIndex != -1 )
+ sDlgName = sDescription.getToken( 0, '.', nIndex );
+
+ OUString sLocation = sfUri->getParameter( "location" );
+
+
+ // get dialog library container
+ // TODO: dialogs in packages
+ Reference< XLibraryContainer > xLibContainer;
+
+ if ( sLocation == "application" )
+ {
+ xLibContainer = SfxGetpApp()->GetDialogContainer();
+ }
+ else if ( sLocation == "document" )
+ {
+ Reference< XEmbeddedScripts > xDocumentScripts( m_xModel, UNO_QUERY );
+ if ( xDocumentScripts.is() )
+ {
+ xLibContainer = xDocumentScripts->getDialogLibraries();
+ OSL_ENSURE( xLibContainer.is(),
+ "DialogProviderImpl::createDialogModel: invalid dialog container!" );
+ }
+ }
+ else
+ {
+ const Sequence< OUString > aOpenDocsTdocURLs( MiscUtils::allOpenTDocUrls( m_xContext ) );
+ for ( auto const & tdocURL : aOpenDocsTdocURLs )
+ {
+ Reference< frame::XModel > xModel( MiscUtils::tDocUrlToModel( tdocURL ) );
+ OSL_ENSURE( xModel.is(), "DialogProviderImpl::createDialogModel: invalid document model!" );
+ if ( !xModel.is() )
+ continue;
+
+ OUString sDocURL = xModel->getURL();
+ if ( sDocURL.isEmpty() )
+ {
+ sDocURL = ::comphelper::NamedValueCollection::getOrDefault( xModel->getArgs(), u"Title", sDocURL );
+ }
+
+ if ( sLocation != sDocURL )
+ continue;
+
+ Reference< XEmbeddedScripts > xDocumentScripts( m_xModel, UNO_QUERY );
+ if ( !xDocumentScripts.is() )
+ continue;
+
+ xLibContainer = xDocumentScripts->getDialogLibraries();
+ OSL_ENSURE( xLibContainer.is(),
+ "DialogProviderImpl::createDialogModel: invalid dialog container!" );
+ }
+ }
+
+ // get input stream provider
+ Reference< io::XInputStreamProvider > xISP;
+ if ( !xLibContainer.is() )
+ {
+ throw IllegalArgumentException(
+ "DialogProviderImpl::getDialog: library container not found!",
+ Reference< XInterface >(), 1 );
+ }
+
+ // load dialog library
+ if ( !xLibContainer->isLibraryLoaded( sLibName ) )
+ xLibContainer->loadLibrary( sLibName );
+
+ // get dialog library
+ if ( xLibContainer->hasByName( sLibName ) )
+ {
+ Any aElement = xLibContainer->getByName( sLibName );
+ aElement >>= xDialogLib;
+ }
+
+ if ( !xDialogLib.is() )
+ {
+ throw IllegalArgumentException(
+ "DialogProviderImpl::getDialogModel: library not found!",
+ Reference< XInterface >(), 1 );
+ }
+
+ // get input stream provider
+ if ( xDialogLib->hasByName( sDlgName ) )
+ {
+ Any aElement = xDialogLib->getByName( sDlgName );
+ aElement >>= xISP;
+ }
+
+ if ( !xISP.is() )
+ {
+ throw IllegalArgumentException(
+ "DialogProviderImpl::getDialogModel: dialog not found!",
+ Reference< XInterface >(), 1 );
+ }
+
+
+
+ if ( xISP.is() )
+ xInput = xISP->createInputStream();
+ msDialogLibName = sLibName;
+ }
+
+ // import dialog model
+ Reference< XControlModel > xCtrlModel;
+ if ( xInput.is() && m_xContext.is() )
+ {
+ Reference< resource::XStringResourceManager > xStringResourceManager;
+ if( bSingleDialog )
+ {
+ xStringResourceManager = lcl_getStringResourceManager(m_xContext,aURL);
+ }
+ else if( xDialogLib.is() )
+ {
+ xStringResourceManager = getStringResourceFromDialogLibrary( xDialogLib );
+ }
+
+ Any aDialogSourceURLAny;
+ aDialogSourceURLAny <<= aURL;
+
+ Reference< container::XNameContainer > xDialogModel( createDialogModel( xInput , xStringResourceManager, aDialogSourceURLAny ), UNO_SET_THROW);
+
+ xCtrlModel.set( xDialogModel, UNO_QUERY );
+ }
+ return xCtrlModel;
+ }
+
+
+ Reference< XUnoControlDialog > DialogProviderImpl::createDialogControl
+ ( const Reference< XControlModel >& rxDialogModel, const Reference< XWindowPeer >& xParent )
+ {
+ OSL_ENSURE( rxDialogModel.is(), "DialogProviderImpl::getDialogControl: no dialog model" );
+
+ Reference< XUnoControlDialog > xDialogControl;
+
+ if ( m_xContext.is() )
+ {
+ xDialogControl = UnoControlDialog::create( m_xContext );
+
+ // set the model
+ if ( rxDialogModel.is() )
+ xDialogControl->setModel( rxDialogModel );
+
+ // set visible
+ xDialogControl->setVisible( false );
+
+ // get the parent of the dialog control
+ Reference< XWindowPeer > xPeer;
+ if( xParent.is() )
+ {
+ xPeer = xParent;
+ }
+ else if ( m_xModel.is() )
+ {
+ Reference< frame::XController > xController = m_xModel->getCurrentController();
+ if ( xController.is() )
+ {
+ Reference< frame::XFrame > xFrame = xController->getFrame();
+ if ( xFrame.is() )
+ xPeer.set( xFrame->getContainerWindow(), UNO_QUERY );
+ }
+ }
+
+ // create a peer
+ Reference< XToolkit> xToolkit( Toolkit::create( m_xContext ), UNO_QUERY_THROW );
+ xDialogControl->createPeer( xToolkit, xPeer );
+ }
+
+ return xDialogControl;
+ }
+
+
+ void DialogProviderImpl::attachControlEvents(
+ const Reference< XControl >& rxControl,
+ const Reference< XInterface >& rxHandler,
+ const Reference< XIntrospectionAccess >& rxIntrospectionAccess,
+ bool bDialogProviderMode )
+ {
+ if ( !rxControl.is() )
+ return;
+
+ Reference< XControlContainer > xControlContainer( rxControl, UNO_QUERY );
+
+ if ( !xControlContainer.is() )
+ return;
+
+ Sequence< Reference< XControl > > aControls = xControlContainer->getControls();
+ const Reference< XControl >* pControls = aControls.getConstArray();
+ sal_Int32 nControlCount = aControls.getLength();
+
+ Sequence< Reference< XInterface > > aObjects( nControlCount + 1 );
+ Reference< XInterface >* pObjects = aObjects.getArray();
+ for ( sal_Int32 i = 0; i < nControlCount; ++i )
+ {
+ pObjects[i].set( pControls[i], UNO_QUERY );
+ }
+
+ // also add the dialog control itself to the sequence
+ pObjects[nControlCount].set( rxControl, UNO_QUERY );
+
+ Reference<XScriptEventsAttacher> xScriptEventsAttacher
+ = new DialogEventsAttacherImpl(
+ m_xContext, m_xModel, rxControl, rxHandler, rxIntrospectionAccess,
+ bDialogProviderMode,
+ (m_BasicInfo ? m_BasicInfo->mxBasicRTLListener : nullptr), msDialogLibName);
+
+ Any aHelper;
+ xScriptEventsAttacher->attachEvents( aObjects, Reference< XScriptListener >(), aHelper );
+ }
+
+ Reference< XIntrospectionAccess > DialogProviderImpl::inspectHandler( const Reference< XInterface >& rxHandler )
+ {
+ Reference< XIntrospectionAccess > xIntrospectionAccess;
+ static Reference< XIntrospection > xIntrospection;
+
+ if( !rxHandler.is() )
+ return xIntrospectionAccess;
+
+ if( !xIntrospection.is() )
+ {
+ // Get introspection service
+ xIntrospection = theIntrospection::get( m_xContext );
+ }
+
+ // Do introspection
+ try
+ {
+ Any aHandlerAny;
+ aHandlerAny <<= rxHandler;
+ xIntrospectionAccess = xIntrospection->inspect( aHandlerAny );
+ }
+ catch( RuntimeException& )
+ {
+ xIntrospectionAccess.clear();
+ }
+ return xIntrospectionAccess;
+ }
+
+
+ // XServiceInfo
+
+
+ OUString DialogProviderImpl::getImplementationName( )
+ {
+ return "com.sun.star.comp.scripting.DialogProvider";
+ }
+
+ sal_Bool DialogProviderImpl::supportsService( const OUString& rServiceName )
+ {
+ return cppu::supportsService(this, rServiceName);
+ }
+
+ Sequence< OUString > DialogProviderImpl::getSupportedServiceNames( )
+ {
+ return { "com.sun.star.awt.DialogProvider",
+ "com.sun.star.awt.DialogProvider2",
+ "com.sun.star.awt.ContainerWindowProvider" };
+ }
+
+
+ // XInitialization
+
+
+ void DialogProviderImpl::initialize( const Sequence< Any >& aArguments )
+ {
+ ::osl::MutexGuard aGuard( getMutex() );
+
+ if ( aArguments.getLength() == 1 )
+ {
+ aArguments[0] >>= m_xModel;
+
+ if ( !m_xModel.is() )
+ {
+ throw RuntimeException( "DialogProviderImpl::initialize: invalid argument format!" );
+ }
+ }
+ else if ( aArguments.getLength() == 4 )
+ {
+ // call from RTL_Impl_CreateUnoDialog
+ aArguments[0] >>= m_xModel;
+ m_BasicInfo.reset( new BasicRTLParams );
+ m_BasicInfo->mxInput.set( aArguments[ 1 ], UNO_QUERY_THROW );
+ // allow null mxDlgLib, a document dialog instantiated from
+ // from application basic is unable to provide ( or find ) it's
+ // Library
+ aArguments[ 2 ] >>= m_BasicInfo->mxDlgLib;
+ // leave the possibility to optionally allow the old dialog creation
+ // to use the new XScriptListener ( which converts the old style macro
+ // to a SF url )
+ m_BasicInfo->mxBasicRTLListener.set( aArguments[ 3 ], UNO_QUERY);
+ }
+ else if ( aArguments.getLength() > 4 )
+ {
+ throw RuntimeException( "DialogProviderImpl::initialize: invalid number of arguments!" );
+ }
+ }
+
+
+ // XDialogProvider
+
+
+ constexpr OUStringLiteral aDecorationPropName = u"Decoration";
+
+ Reference < XControl > DialogProviderImpl::createDialogImpl(
+ const OUString& URL, const Reference< XInterface >& xHandler,
+ const Reference< XWindowPeer >& xParent, bool bDialogProviderMode )
+ {
+ // if the dialog is located in a document, the document must already be open!
+
+ ::osl::MutexGuard aGuard( getMutex() );
+
+
+ // m_xHandler = xHandler;
+
+ //Reference< XDialog > xDialog;
+ Reference< XControl > xCtrl;
+ Reference< XControlModel > xCtrlMod;
+ try
+ {
+ // add support for basic RTL_FUNCTION
+ if (m_BasicInfo)
+ xCtrlMod = createDialogModelForBasic();
+ else
+ {
+ OSL_ENSURE( !URL.isEmpty(), "DialogProviderImpl::getDialog: no URL!" );
+ xCtrlMod = createDialogModel( URL );
+ }
+ }
+ catch ( const RuntimeException& ) { throw; }
+ catch ( const Exception& )
+ {
+ const Any aError( ::cppu::getCaughtException() );
+ throw WrappedTargetRuntimeException( OUString(), *this, aError );
+ }
+ if ( xCtrlMod.is() )
+ {
+ // i83963 Force decoration
+ if( bDialogProviderMode )
+ {
+ uno::Reference< beans::XPropertySet > xDlgModPropSet( xCtrlMod, uno::UNO_QUERY );
+ if( xDlgModPropSet.is() )
+ {
+ try
+ {
+ bool bDecoration = true;
+ Any aDecorationAny = xDlgModPropSet->getPropertyValue( aDecorationPropName );
+ aDecorationAny >>= bDecoration;
+ if( !bDecoration )
+ {
+ xDlgModPropSet->setPropertyValue( aDecorationPropName, Any( true ) );
+ xDlgModPropSet->setPropertyValue( "Title", Any( OUString() ) );
+ }
+ }
+ catch( UnknownPropertyException& )
+ {}
+ }
+ }
+
+ xCtrl.set( createDialogControl( xCtrlMod, xParent ) );
+ if ( xCtrl.is() )
+ {
+ Reference< XIntrospectionAccess > xIntrospectionAccess = inspectHandler( xHandler );
+ attachControlEvents( xCtrl, xHandler, xIntrospectionAccess, bDialogProviderMode );
+ }
+ }
+
+ return xCtrl;
+ }
+
+ Reference < XDialog > DialogProviderImpl::createDialog( const OUString& URL )
+ {
+ Reference< XInterface > xDummyHandler;
+ Reference< XWindowPeer > xDummyPeer;
+ Reference < XControl > xControl = DialogProviderImpl::createDialogImpl( URL, xDummyHandler, xDummyPeer, true );
+ Reference< XDialog > xDialog( xControl, UNO_QUERY );
+ return xDialog;
+ }
+
+ Reference < XDialog > DialogProviderImpl::createDialogWithHandler(
+ const OUString& URL, const Reference< XInterface >& xHandler )
+ {
+ if( !xHandler.is() )
+ {
+ throw IllegalArgumentException(
+ "DialogProviderImpl::createDialogWithHandler: Invalid xHandler!",
+ Reference< XInterface >(), 1 );
+ }
+ Reference< XWindowPeer > xDummyPeer;
+ Reference < XControl > xControl = DialogProviderImpl::createDialogImpl( URL, xHandler, xDummyPeer, true );
+ Reference< XDialog > xDialog( xControl, UNO_QUERY );
+ return xDialog;
+ }
+
+ Reference < XDialog > DialogProviderImpl::createDialogWithArguments(
+ const OUString& URL, const Sequence< NamedValue >& Arguments )
+ {
+ ::comphelper::NamedValueCollection aArguments( Arguments );
+
+ Reference< XWindowPeer > xParentPeer;
+ if ( aArguments.has( "ParentWindow" ) )
+ {
+ const Any& aParentWindow( aArguments.get( "ParentWindow" ) );
+ if ( !( aParentWindow >>= xParentPeer ) )
+ {
+ const Reference< XControl > xParentControl( aParentWindow, UNO_QUERY );
+ if ( xParentControl.is() )
+ xParentPeer = xParentControl->getPeer();
+ }
+ }
+
+ const Reference< XInterface > xHandler( aArguments.get( "EventHandler" ), UNO_QUERY );
+
+ Reference < XControl > xControl = DialogProviderImpl::createDialogImpl( URL, xHandler, xParentPeer, true );
+ Reference< XDialog > xDialog( xControl, UNO_QUERY );
+ return xDialog;
+ }
+
+ Reference< XWindow > DialogProviderImpl::createContainerWindow(
+ const OUString& URL, const OUString&,
+ const Reference< XWindowPeer >& xParent, const Reference< XInterface >& xHandler )
+ {
+ if( !xParent.is() )
+ {
+ throw IllegalArgumentException(
+ "DialogProviderImpl::createContainerWindow: Invalid xParent!",
+ Reference< XInterface >(), 1 );
+ }
+ Reference < XControl > xControl = DialogProviderImpl::createDialogImpl( URL, xHandler, xParent, false );
+ Reference< XWindow> xWindow( xControl, UNO_QUERY );
+ return xWindow;
+ }
+
+
+ // component operations
+
+
+ extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
+ scripting_DialogProviderImpl_get_implementation(
+ css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const&)
+ {
+ return cppu::acquire(new DialogProviderImpl(context));
+ }
+
+} // namespace dlgprov
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/scripting/source/dlgprov/dlgprov.hxx b/scripting/source/dlgprov/dlgprov.hxx
new file mode 100644
index 000000000..0a5d4483a
--- /dev/null
+++ b/scripting/source/dlgprov/dlgprov.hxx
@@ -0,0 +1,148 @@
+/* -*- 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/awt/XControl.hpp>
+#include <com/sun/star/awt/XDialog.hpp>
+#include <com/sun/star/awt/XDialogProvider2.hpp>
+#include <com/sun/star/awt/XContainerWindowProvider.hpp>
+#include <com/sun/star/awt/XUnoControlDialog.hpp>
+#include <com/sun/star/beans/XIntrospectionAccess.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/resource/XStringResourceManager.hpp>
+#include <com/sun/star/script/XScriptListener.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+
+#include <cppuhelper/implbase.hxx>
+#include <osl/mutex.hxx>
+#include <memory>
+
+
+namespace dlgprov
+{
+
+
+ // mutex
+
+
+ ::osl::Mutex& getMutex();
+
+
+
+ css::uno::Reference< css::container::XNameContainer > lcl_createControlModel(const css::uno::Reference< css::uno::XComponentContext >& i_xContext);
+ css::uno::Reference< css::resource::XStringResourceManager > lcl_getStringResourceManager(const css::uno::Reference< css::uno::XComponentContext >& i_xContext, std::u16string_view i_sURL);
+ /// @throws css::uno::Exception
+ css::uno::Reference< css::container::XNameContainer > lcl_createDialogModel(
+ const css::uno::Reference< css::uno::XComponentContext >& i_xContext,
+ const css::uno::Reference< css::io::XInputStream >& xInput,
+ const css::uno::Reference< css::frame::XModel >& xModel,
+ const css::uno::Reference< css::resource::XStringResourceManager >& xStringResourceManager,
+ const css::uno::Any &aDialogSourceURL);
+
+ typedef ::cppu::WeakImplHelper<
+ css::lang::XServiceInfo,
+ css::lang::XInitialization,
+ css::awt::XDialogProvider2,
+ css::awt::XContainerWindowProvider > DialogProviderImpl_BASE;
+
+ class DialogProviderImpl : public DialogProviderImpl_BASE
+ {
+ private:
+ struct BasicRTLParams
+ {
+ css::uno::Reference< css::io::XInputStream > mxInput;
+ css::uno::Reference< css::container::XNameContainer > mxDlgLib;
+ css::uno::Reference< css::script::XScriptListener > mxBasicRTLListener;
+ };
+ std::unique_ptr< BasicRTLParams > m_BasicInfo;
+ css::uno::Reference< css::uno::XComponentContext > m_xContext;
+ css::uno::Reference< css::frame::XModel > m_xModel;
+
+ OUString msDialogLibName;
+ css::uno::Reference< css::awt::XControlModel > createDialogModel( const OUString& sURL );
+
+ css::uno::Reference< css::awt::XUnoControlDialog > createDialogControl(
+ const css::uno::Reference< css::awt::XControlModel >& rxDialogModel,
+ const css::uno::Reference< css::awt::XWindowPeer >& xParent );
+
+ void attachControlEvents( const css::uno::Reference< css::awt::XControl >& rxControlContainer,
+ const css::uno::Reference< css::uno::XInterface >& rxHandler,
+ const css::uno::Reference< css::beans::XIntrospectionAccess >& rxIntrospectionAccess,
+ bool bDialogProviderMode );
+ css::uno::Reference< css::beans::XIntrospectionAccess > inspectHandler(
+ const css::uno::Reference< css::uno::XInterface >& rxHandler );
+ // helper methods
+ /// @throws css::uno::Exception
+ css::uno::Reference< css::container::XNameContainer > createDialogModel(
+ const css::uno::Reference< css::io::XInputStream >& xInput,
+ const css::uno::Reference< css::resource::XStringResourceManager >& xStringResourceManager,
+ const css::uno::Any &aDialogSourceURL);
+ /// @throws css::uno::Exception
+ css::uno::Reference< css::awt::XControlModel > createDialogModelForBasic();
+
+ // XDialogProvider / XDialogProvider2 impl method
+ /// @throws css::lang::IllegalArgumentException
+ /// @throws css::uno::RuntimeException
+ css::uno::Reference < css::awt::XControl > createDialogImpl(
+ const OUString& URL,
+ const css::uno::Reference< css::uno::XInterface >& xHandler,
+ const css::uno::Reference< css::awt::XWindowPeer >& xParent,
+ bool bDialogProviderMode );
+
+ public:
+ explicit DialogProviderImpl(
+ const css::uno::Reference< css::uno::XComponentContext >& rxContext );
+ virtual ~DialogProviderImpl() 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;
+
+ // XDialogProvider
+ virtual css::uno::Reference < css::awt::XDialog > SAL_CALL createDialog(
+ const OUString& URL ) override;
+
+ // XDialogProvider2
+ virtual css::uno::Reference < css::awt::XDialog > SAL_CALL createDialogWithHandler(
+ const OUString& URL,
+ const css::uno::Reference< css::uno::XInterface >& xHandler ) override;
+
+ virtual css::uno::Reference < css::awt::XDialog > SAL_CALL createDialogWithArguments(
+ const OUString& URL,
+ const css::uno::Sequence< css::beans::NamedValue >& Arguments ) override;
+
+ virtual css::uno::Reference< css::awt::XWindow > SAL_CALL createContainerWindow(
+ const OUString& URL, const OUString& WindowType,
+ const css::uno::Reference< css::awt::XWindowPeer >& xParent,
+ const css::uno::Reference< css::uno::XInterface >& xHandler ) override;
+ };
+
+
+} // namespace dlgprov
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */