summaryrefslogtreecommitdiffstats
path: root/framework/source/uifactory
diff options
context:
space:
mode:
Diffstat (limited to 'framework/source/uifactory')
-rw-r--r--framework/source/uifactory/addonstoolbarfactory.cxx212
-rw-r--r--framework/source/uifactory/factoryconfiguration.cxx285
-rw-r--r--framework/source/uifactory/menubarfactory.cxx171
-rw-r--r--framework/source/uifactory/statusbarfactory.cxx85
-rw-r--r--framework/source/uifactory/toolbarfactory.cxx85
-rw-r--r--framework/source/uifactory/uicontrollerfactory.cxx397
-rw-r--r--framework/source/uifactory/uielementfactorymanager.cxx569
-rw-r--r--framework/source/uifactory/windowcontentfactorymanager.cxx223
8 files changed, 2027 insertions, 0 deletions
diff --git a/framework/source/uifactory/addonstoolbarfactory.cxx b/framework/source/uifactory/addonstoolbarfactory.cxx
new file mode 100644
index 000000000..021d3dc02
--- /dev/null
+++ b/framework/source/uifactory/addonstoolbarfactory.cxx
@@ -0,0 +1,212 @@
+/* -*- 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 <uielement/addonstoolbarwrapper.hxx>
+
+#include <com/sun/star/frame/ModuleManager.hpp>
+#include <com/sun/star/frame/XModuleManager2.hpp>
+#include <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/ui/XUIElementFactory.hpp>
+
+#include <cppuhelper/implbase.hxx>
+#include <cppuhelper/supportsservice.hxx>
+#include <o3tl/safeint.hxx>
+#include <vcl/svapp.hxx>
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::frame;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::util;
+using namespace ::com::sun::star::ui;
+using namespace framework;
+
+namespace {
+
+class AddonsToolBarFactory : public ::cppu::WeakImplHelper< css::lang::XServiceInfo ,
+ css::ui::XUIElementFactory >
+{
+public:
+ explicit AddonsToolBarFactory( const css::uno::Reference< css::uno::XComponentContext >& xContext );
+
+ virtual OUString SAL_CALL getImplementationName() override
+ {
+ return "com.sun.star.comp.framework.AddonsToolBarFactory";
+ }
+
+ virtual sal_Bool SAL_CALL supportsService(OUString const & ServiceName) override
+ {
+ return cppu::supportsService(this, ServiceName);
+ }
+
+ virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override
+ {
+ return {"com.sun.star.ui.ToolBarFactory"};
+ }
+
+ // XUIElementFactory
+ virtual css::uno::Reference< css::ui::XUIElement > SAL_CALL createUIElement( const OUString& ResourceURL, const css::uno::Sequence< css::beans::PropertyValue >& Args ) override;
+
+ bool hasButtonsInContext( const css::uno::Sequence< css::uno::Sequence< css::beans::PropertyValue > >& rPropSeq,
+ const css::uno::Reference< css::frame::XFrame >& rFrame );
+
+private:
+ css::uno::Reference< css::uno::XComponentContext > m_xContext;
+ css::uno::Reference< css::frame::XModuleManager2 > m_xModuleManager;
+};
+
+AddonsToolBarFactory::AddonsToolBarFactory(
+ const css::uno::Reference< css::uno::XComponentContext >& xContext ) :
+ m_xContext( xContext )
+ , m_xModuleManager( ModuleManager::create( xContext ) )
+{
+}
+
+bool IsCorrectContext( const OUString& rModuleIdentifier, const OUString& aContextList )
+{
+ if ( aContextList.isEmpty() )
+ return true;
+
+ if ( !rModuleIdentifier.isEmpty() )
+ {
+ sal_Int32 nIndex = aContextList.indexOf( rModuleIdentifier );
+ return ( nIndex >= 0 );
+ }
+
+ return false;
+}
+
+bool AddonsToolBarFactory::hasButtonsInContext(
+ const Sequence< Sequence< PropertyValue > >& rPropSeqSeq,
+ const Reference< XFrame >& rFrame )
+{
+ OUString aModuleIdentifier;
+ try
+ {
+ aModuleIdentifier = m_xModuleManager->identify( rFrame );
+ }
+ catch ( const RuntimeException& )
+ {
+ throw;
+ }
+ catch ( const Exception& )
+ {
+ }
+
+ // Check before we create a toolbar that we have at least one button in
+ // the current frame context.
+ for ( Sequence<PropertyValue> const & props : rPropSeqSeq )
+ {
+ bool bIsButton( true );
+ bool bIsCorrectContext( false );
+ sal_uInt32 nPropChecked( 0 );
+
+ for ( PropertyValue const & prop : props )
+ {
+ if ( prop.Name == "Context" )
+ {
+ OUString aContextList;
+ if ( prop.Value >>= aContextList )
+ bIsCorrectContext = IsCorrectContext( aModuleIdentifier, aContextList );
+ nPropChecked++;
+ }
+ else if ( prop.Name == "URL" )
+ {
+ OUString aURL;
+ prop.Value >>= aURL;
+ bIsButton = aURL != "private:separator";
+ nPropChecked++;
+ }
+
+ if ( nPropChecked == 2 )
+ break;
+ }
+
+ if ( bIsButton && bIsCorrectContext )
+ return true;
+ }
+
+ return false;
+}
+
+// XUIElementFactory
+Reference< XUIElement > SAL_CALL AddonsToolBarFactory::createUIElement(
+ const OUString& ResourceURL,
+ const Sequence< PropertyValue >& Args )
+{
+ SolarMutexGuard g;
+
+ Sequence< Sequence< PropertyValue > > aConfigData;
+ Reference< XFrame > xFrame;
+ OUString aResourceURL( ResourceURL );
+
+ for ( PropertyValue const & arg : Args )
+ {
+ if ( arg.Name == "ConfigurationData" )
+ arg.Value >>= aConfigData;
+ else if ( arg.Name == "Frame" )
+ arg.Value >>= xFrame;
+ else if ( arg.Name == "ResourceURL" )
+ arg.Value >>= aResourceURL;
+ }
+
+ if ( !aResourceURL.startsWith("private:resource/toolbar/addon_") )
+ throw IllegalArgumentException();
+
+ // Identify frame and determine module identifier to look for context based buttons
+ Reference< css::ui::XUIElement > xToolBar;
+ if ( xFrame.is() &&
+ aConfigData.hasElements() &&
+ hasButtonsInContext( aConfigData, xFrame ))
+ {
+ PropertyValue aPropValue;
+ Sequence< Any > aPropSeq( 3 );
+ aPropValue.Name = "Frame";
+ aPropValue.Value <<= xFrame;
+ aPropSeq[0] <<= aPropValue;
+ aPropValue.Name = "ConfigurationData";
+ aPropValue.Value <<= aConfigData;
+ aPropSeq[1] <<= aPropValue;
+ aPropValue.Name = "ResourceURL";
+ aPropValue.Value <<= aResourceURL;
+ aPropSeq[2] <<= aPropValue;
+
+ SolarMutexGuard aGuard;
+ AddonsToolBarWrapper* pToolBarWrapper = new AddonsToolBarWrapper( m_xContext );
+ xToolBar.set( static_cast<OWeakObject *>(pToolBarWrapper), UNO_QUERY );
+ Reference< XInitialization > xInit( xToolBar, UNO_QUERY );
+ xInit->initialize( aPropSeq );
+ }
+
+ return xToolBar;
+}
+
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
+com_sun_star_comp_framework_AddonsToolBarFactory_get_implementation(
+ css::uno::XComponentContext *context,
+ css::uno::Sequence<css::uno::Any> const &)
+{
+ return cppu::acquire(new AddonsToolBarFactory(context));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uifactory/factoryconfiguration.cxx b/framework/source/uifactory/factoryconfiguration.cxx
new file mode 100644
index 000000000..485b5a0a9
--- /dev/null
+++ b/framework/source/uifactory/factoryconfiguration.cxx
@@ -0,0 +1,285 @@
+/* -*- 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 <uifactory/factoryconfiguration.hxx>
+#include <services.h>
+
+#include <helper/mischelper.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/configuration/theDefaultProvider.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/container/XContainer.hpp>
+
+#include <comphelper/propertysequence.hxx>
+
+// Defines
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::container;
+
+// Namespace
+
+namespace framework
+{
+static OUString getHashKeyFromStrings( const OUString& aCommandURL, const OUString& aModuleName )
+{
+ return aCommandURL + "-" + aModuleName;
+}
+
+// XInterface, XTypeProvider
+
+ConfigurationAccess_ControllerFactory::ConfigurationAccess_ControllerFactory( const Reference< XComponentContext >& rxContext, const OUString& _sRoot ) :
+ m_aPropCommand( "Command" ),
+ m_aPropModule( "Module" ),
+ m_aPropController( "Controller" ),
+ m_aPropValue( "Value" ),
+ m_sRoot(_sRoot),
+ m_bConfigAccessInitialized( false )
+{
+ m_xConfigProvider = configuration::theDefaultProvider::get( rxContext );
+}
+
+ConfigurationAccess_ControllerFactory::~ConfigurationAccess_ControllerFactory()
+{
+ osl::MutexGuard g(m_mutex);
+
+ Reference< XContainer > xContainer( m_xConfigAccess, UNO_QUERY );
+ if ( xContainer.is() )
+ xContainer->removeContainerListener(m_xConfigAccessListener);
+}
+
+OUString ConfigurationAccess_ControllerFactory::getServiceFromCommandModule( const OUString& rCommandURL, const OUString& rModule ) const
+{
+ osl::MutexGuard g(m_mutex);
+ MenuControllerMap::const_iterator pIter = m_aMenuControllerMap.find( getHashKeyFromStrings( rCommandURL, rModule ));
+
+ if ( pIter != m_aMenuControllerMap.end() )
+ return pIter->second.m_aImplementationName;
+ else if ( !rModule.isEmpty() )
+ {
+ // Try to detect if we have a generic popup menu controller
+ pIter = m_aMenuControllerMap.find( getHashKeyFromStrings( rCommandURL, OUString() ));
+
+ if ( pIter != m_aMenuControllerMap.end() )
+ return pIter->second.m_aImplementationName;
+ }
+
+ return OUString();
+}
+OUString ConfigurationAccess_ControllerFactory::getValueFromCommandModule( const OUString& rCommandURL, const OUString& rModule ) const
+{
+ osl::MutexGuard g(m_mutex);
+
+ MenuControllerMap::const_iterator pIter = m_aMenuControllerMap.find( getHashKeyFromStrings( rCommandURL, rModule ));
+
+ if ( pIter != m_aMenuControllerMap.end() )
+ return pIter->second.m_aValue;
+ else if ( !rModule.isEmpty() )
+ {
+ // Try to detect if we have a generic popup menu controller
+ pIter = m_aMenuControllerMap.find( getHashKeyFromStrings( rCommandURL, OUString() ));
+
+ if ( pIter != m_aMenuControllerMap.end() )
+ return pIter->second.m_aValue;
+ }
+
+ return OUString();
+}
+
+void ConfigurationAccess_ControllerFactory::addServiceToCommandModule(
+ const OUString& rCommandURL,
+ const OUString& rModule,
+ const OUString& rServiceSpecifier )
+{
+ osl::MutexGuard g(m_mutex);
+
+ OUString aHashKey = getHashKeyFromStrings( rCommandURL, rModule );
+ m_aMenuControllerMap.emplace( aHashKey,ControllerInfo(rServiceSpecifier,OUString()) );
+}
+
+void ConfigurationAccess_ControllerFactory::removeServiceFromCommandModule(
+ const OUString& rCommandURL,
+ const OUString& rModule )
+{
+ osl::MutexGuard g(m_mutex);
+
+ OUString aHashKey = getHashKeyFromStrings( rCommandURL, rModule );
+ m_aMenuControllerMap.erase( aHashKey );
+}
+
+// container.XContainerListener
+void SAL_CALL ConfigurationAccess_ControllerFactory::elementInserted( const ContainerEvent& aEvent )
+{
+ OUString aCommand;
+ OUString aModule;
+ OUString aService;
+ OUString aValue;
+
+ osl::MutexGuard g(m_mutex);
+
+ if ( impl_getElementProps( aEvent.Element, aCommand, aModule, aService, aValue ))
+ {
+ // Create hash key from command and module as they are together a primary key to
+ // the UNO service that implements the popup menu controller.
+ OUString aHashKey( getHashKeyFromStrings( aCommand, aModule ));
+ ControllerInfo& rControllerInfo = m_aMenuControllerMap[ aHashKey ];
+ rControllerInfo.m_aImplementationName = aService;
+ rControllerInfo.m_aValue = aValue;
+ }
+}
+
+void SAL_CALL ConfigurationAccess_ControllerFactory::elementRemoved ( const ContainerEvent& aEvent )
+{
+ OUString aCommand;
+ OUString aModule;
+ OUString aService;
+ OUString aValue;
+
+ osl::MutexGuard g(m_mutex);
+
+ if ( impl_getElementProps( aEvent.Element, aCommand, aModule, aService, aValue ))
+ {
+ // Create hash key from command and module as they are together a primary key to
+ // the UNO service that implements the popup menu controller.
+ OUString aHashKey( getHashKeyFromStrings( aCommand, aModule ));
+ m_aMenuControllerMap.erase( aHashKey );
+ }
+}
+
+void SAL_CALL ConfigurationAccess_ControllerFactory::elementReplaced( const ContainerEvent& aEvent )
+{
+ elementInserted(aEvent);
+}
+
+// lang.XEventListener
+void SAL_CALL ConfigurationAccess_ControllerFactory::disposing( const EventObject& )
+{
+ // remove our reference to the config access
+ osl::MutexGuard g(m_mutex);
+ m_xConfigAccess.clear();
+}
+
+void ConfigurationAccess_ControllerFactory::readConfigurationData()
+{
+ // SAFE
+ osl::ClearableMutexGuard aLock( m_mutex );
+
+ if ( !m_bConfigAccessInitialized )
+ {
+ uno::Sequence<uno::Any> aArgs(comphelper::InitAnyPropertySequence(
+ {
+ {"nodepath", uno::Any(m_sRoot)}
+ }));
+ try
+ {
+ m_xConfigAccess.set( m_xConfigProvider->createInstanceWithArguments(SERVICENAME_CFGREADACCESS,aArgs ), UNO_QUERY );
+ }
+ catch ( const WrappedTargetException& )
+ {
+ }
+
+ m_bConfigAccessInitialized = true;
+ }
+
+ if ( !m_xConfigAccess.is() )
+ return;
+
+ // Read and update configuration data
+ updateConfigurationData();
+
+ uno::Reference< container::XContainer > xContainer( m_xConfigAccess, uno::UNO_QUERY );
+ // UNSAFE
+ aLock.clear();
+
+ if ( xContainer.is() )
+ {
+ m_xConfigAccessListener = new WeakContainerListener(this);
+ xContainer->addContainerListener(m_xConfigAccessListener);
+ }
+}
+
+void ConfigurationAccess_ControllerFactory::updateConfigurationData()
+{
+ osl::MutexGuard g(m_mutex);
+ if ( !m_xConfigAccess.is() )
+ return;
+
+ const Sequence< OUString > aPopupMenuControllers = m_xConfigAccess->getElementNames();
+
+ OUString aCommand;
+ OUString aModule;
+ OUString aService;
+ OUString aHashKey;
+ OUString aValue;
+
+ m_aMenuControllerMap.clear();
+ for ( OUString const & name : aPopupMenuControllers )
+ {
+ try
+ {
+ if ( impl_getElementProps( m_xConfigAccess->getByName( name ), aCommand, aModule, aService,aValue ))
+ {
+ // Create hash key from command and module as they are together a primary key to
+ // the UNO service that implements the popup menu controller.
+ aHashKey = getHashKeyFromStrings( aCommand, aModule );
+ m_aMenuControllerMap.emplace( aHashKey, ControllerInfo(aService,aValue) );
+ }
+ }
+ catch ( const NoSuchElementException& )
+ {
+ }
+ catch ( const WrappedTargetException& )
+ {
+ }
+ }
+}
+
+bool ConfigurationAccess_ControllerFactory::impl_getElementProps( const Any& aElement, OUString& aCommand, OUString& aModule, OUString& aServiceSpecifier,OUString& aValue ) const
+{
+ Reference< XPropertySet > xPropertySet;
+ aElement >>= xPropertySet;
+
+ if ( xPropertySet.is() )
+ {
+ try
+ {
+ xPropertySet->getPropertyValue( m_aPropCommand ) >>= aCommand;
+ xPropertySet->getPropertyValue( m_aPropModule ) >>= aModule;
+ xPropertySet->getPropertyValue( m_aPropController ) >>= aServiceSpecifier;
+ xPropertySet->getPropertyValue( m_aPropValue ) >>= aValue;
+ }
+ catch ( const css::beans::UnknownPropertyException& )
+ {
+ return false;
+ }
+ catch ( const css::lang::WrappedTargetException& )
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uifactory/menubarfactory.cxx b/framework/source/uifactory/menubarfactory.cxx
new file mode 100644
index 000000000..2899b6428
--- /dev/null
+++ b/framework/source/uifactory/menubarfactory.cxx
@@ -0,0 +1,171 @@
+/* -*- 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 <uifactory/menubarfactory.hxx>
+
+#include <uielement/menubarwrapper.hxx>
+
+#include <com/sun/star/frame/ModuleManager.hpp>
+#include <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/ui/theModuleUIConfigurationManagerSupplier.hpp>
+#include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+
+#include <vcl/svapp.hxx>
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::frame;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::util;
+using namespace ::com::sun::star::ui;
+
+namespace framework
+{
+
+MenuBarFactory::MenuBarFactory( const css::uno::Reference< css::uno::XComponentContext >& xContext )
+ : m_xContext( xContext )
+{
+}
+
+MenuBarFactory::~MenuBarFactory()
+{
+}
+
+// XUIElementFactory
+Reference< XUIElement > SAL_CALL MenuBarFactory::createUIElement(
+ const OUString& ResourceURL,
+ const Sequence< PropertyValue >& Args )
+{
+ Reference< css::ui::XUIElement > xMenuBar(
+ static_cast<OWeakObject *>(new MenuBarWrapper(m_xContext)), UNO_QUERY);
+ CreateUIElement(ResourceURL, Args, "private:resource/menubar/", xMenuBar, m_xContext);
+ return xMenuBar;
+}
+
+void MenuBarFactory::CreateUIElement(const OUString& ResourceURL
+ ,const Sequence< PropertyValue >& Args
+ ,const OUString& ResourceType
+ ,const Reference< css::ui::XUIElement >& _xMenuBar
+ ,const css::uno::Reference< css::uno::XComponentContext >& _rxContext)
+{
+ sal_Int32 nConfigPropertyIndex( Args.getLength() );
+ sal_Int32 nURLPropertyIndex( Args.getLength() );
+ Reference< XUIConfigurationManager > xCfgMgr;
+ Reference< XFrame > xFrame;
+ OUString aResourceURL( ResourceURL );
+
+ for ( sal_Int32 n = 0; n < Args.getLength(); n++ )
+ {
+ if ( Args[n].Name == "ConfigurationSource" )
+ {
+ nConfigPropertyIndex = n;
+ Args[n].Value >>= xCfgMgr;
+ }
+ else if ( Args[n].Name == "ResourceURL" )
+ {
+ nURLPropertyIndex = n;
+ Args[n].Value >>= aResourceURL;
+ }
+ else if ( Args[n].Name == "Frame" )
+ Args[n].Value >>= xFrame;
+ }
+ if (!aResourceURL.startsWith(ResourceType))
+ throw IllegalArgumentException();
+
+ // Identify frame and determine document based ui configuration manager/module ui configuration manager
+ if ( xFrame.is() && !xCfgMgr.is() )
+ {
+ bool bHasSettings( false );
+ Reference< XModel > xModel;
+
+ Reference< XController > xController = xFrame->getController();
+ if ( xController.is() )
+ xModel = xController->getModel();
+
+ if ( xModel.is() )
+ {
+ Reference< XUIConfigurationManagerSupplier > xUIConfigurationManagerSupplier( xModel, UNO_QUERY );
+ if ( xUIConfigurationManagerSupplier.is() )
+ {
+ xCfgMgr = xUIConfigurationManagerSupplier->getUIConfigurationManager();
+ bHasSettings = xCfgMgr->hasSettings( aResourceURL );
+ }
+ }
+
+ if ( !bHasSettings )
+ {
+ Reference< css::frame::XModuleManager2 > xModuleManager =
+ ModuleManager::create( _rxContext );
+ OUString aModuleIdentifier = xModuleManager->identify( Reference<XInterface>( xFrame, UNO_QUERY ) );
+ if ( !aModuleIdentifier.isEmpty() )
+ {
+ Reference< XModuleUIConfigurationManagerSupplier > xModuleCfgSupplier =
+ theModuleUIConfigurationManagerSupplier::get( _rxContext );
+ xCfgMgr = xModuleCfgSupplier->getUIConfigurationManager( aModuleIdentifier );
+ }
+ }
+ }
+
+ sal_Int32 nSeqLength( Args.getLength() );
+ if ( Args.getLength() == nConfigPropertyIndex )
+ nSeqLength++;
+ if ( Args.getLength() == nURLPropertyIndex )
+ nSeqLength++;
+ if ( nConfigPropertyIndex == nURLPropertyIndex )
+ nURLPropertyIndex++;
+
+ Sequence< Any > aPropSeq( nSeqLength );
+ for ( sal_Int32 n = 0; n < aPropSeq.getLength(); n++ )
+ {
+ PropertyValue aPropValue;
+ if ( n == nURLPropertyIndex )
+ {
+ aPropValue.Name = "ResourceURL";
+ aPropValue.Value <<= aResourceURL;
+ }
+ else if ( n == nConfigPropertyIndex )
+ {
+ aPropValue.Name = "ConfigurationSource";
+ aPropValue.Value <<= xCfgMgr;
+ }
+ else
+ aPropValue = Args[n];
+
+ aPropSeq[n] <<= aPropValue;
+ }
+
+ SolarMutexGuard aGuard;
+ Reference< XInitialization > xInit( _xMenuBar, UNO_QUERY );
+ xInit->initialize( aPropSeq );
+}
+
+} // namespace framework
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
+com_sun_star_comp_framework_MenuBarFactory_get_implementation(
+ css::uno::XComponentContext *context,
+ css::uno::Sequence<css::uno::Any> const &)
+{
+ return cppu::acquire(new framework::MenuBarFactory(context));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uifactory/statusbarfactory.cxx b/framework/source/uifactory/statusbarfactory.cxx
new file mode 100644
index 000000000..6791db896
--- /dev/null
+++ b/framework/source/uifactory/statusbarfactory.cxx
@@ -0,0 +1,85 @@
+/* -*- 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 <uifactory/menubarfactory.hxx>
+#include <uielement/statusbarwrapper.hxx>
+
+#include <cppuhelper/supportsservice.hxx>
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::util;
+using namespace ::com::sun::star::ui;
+
+using namespace framework;
+
+namespace {
+
+class StatusBarFactory : public MenuBarFactory
+{
+public:
+ explicit StatusBarFactory( const css::uno::Reference< css::uno::XComponentContext >& xContext );
+
+ virtual OUString SAL_CALL getImplementationName() override
+ {
+ return "com.sun.star.comp.framework.StatusBarFactory";
+ }
+
+ virtual sal_Bool SAL_CALL supportsService(OUString const & ServiceName) override
+ {
+ return cppu::supportsService(this, ServiceName);
+ }
+
+ virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override
+ {
+ return {"com.sun.star.ui.StatusBarFactory"};
+ }
+
+ // XUIElementFactory
+ virtual css::uno::Reference< css::ui::XUIElement > SAL_CALL createUIElement( const OUString& ResourceURL, const css::uno::Sequence< css::beans::PropertyValue >& Args ) override;
+};
+
+StatusBarFactory::StatusBarFactory( const css::uno::Reference< css::uno::XComponentContext >& xContext ) :
+ MenuBarFactory( xContext )
+{
+}
+
+// XUIElementFactory
+Reference< XUIElement > SAL_CALL StatusBarFactory::createUIElement(
+ const OUString& ResourceURL,
+ const Sequence< PropertyValue >& Args )
+{
+ Reference< css::ui::XUIElement > xStatusBar(
+ static_cast<OWeakObject *>(new StatusBarWrapper(m_xContext)), UNO_QUERY);
+ MenuBarFactory::CreateUIElement(ResourceURL, Args, "private:resource/statusbar/", xStatusBar, m_xContext);
+ return xStatusBar;
+}
+
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
+com_sun_star_comp_framework_StatusBarFactory_get_implementation(
+ css::uno::XComponentContext *context,
+ css::uno::Sequence<css::uno::Any> const &)
+{
+ return cppu::acquire(new StatusBarFactory(context));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uifactory/toolbarfactory.cxx b/framework/source/uifactory/toolbarfactory.cxx
new file mode 100644
index 000000000..f797ab2e6
--- /dev/null
+++ b/framework/source/uifactory/toolbarfactory.cxx
@@ -0,0 +1,85 @@
+/* -*- 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 <cppuhelper/supportsservice.hxx>
+#include <vcl/svapp.hxx>
+#include <uielement/toolbarwrapper.hxx>
+#include <uifactory/menubarfactory.hxx>
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::util;
+using namespace ::com::sun::star::ui;
+using namespace framework;
+
+namespace {
+
+class ToolBarFactory : public MenuBarFactory
+{
+public:
+ explicit ToolBarFactory( const css::uno::Reference< css::uno::XComponentContext >& xContext );
+
+ virtual OUString SAL_CALL getImplementationName() override
+ {
+ return "com.sun.star.comp.framework.ToolBarFactory";
+ }
+
+ virtual sal_Bool SAL_CALL supportsService(OUString const & ServiceName) override
+ {
+ return cppu::supportsService(this, ServiceName);
+ }
+
+ virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override
+ {
+ return {"com.sun.star.ui.ToolBarFactory"};
+ }
+
+ // XUIElementFactory
+ virtual css::uno::Reference< css::ui::XUIElement > SAL_CALL createUIElement(
+ const OUString& ResourceURL, const css::uno::Sequence< css::beans::PropertyValue >& Args ) override;
+};
+
+ToolBarFactory::ToolBarFactory( const css::uno::Reference< css::uno::XComponentContext >& xContext ) :
+ MenuBarFactory( xContext )
+{
+}
+
+// XUIElementFactory
+Reference< XUIElement > SAL_CALL ToolBarFactory::createUIElement(
+ const OUString& ResourceURL,
+ const Sequence< PropertyValue >& Args )
+{
+ Reference< css::ui::XUIElement > xToolBar(
+ static_cast<OWeakObject *>(new ToolBarWrapper(m_xContext)), UNO_QUERY);
+ CreateUIElement(ResourceURL, Args, "private:resource/toolbar/", xToolBar, m_xContext);
+ return xToolBar;
+}
+
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
+com_sun_star_comp_framework_ToolBarFactory_get_implementation(
+ css::uno::XComponentContext *context,
+ css::uno::Sequence<css::uno::Any> const &)
+{
+ return cppu::acquire(new ToolBarFactory(context));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uifactory/uicontrollerfactory.cxx b/framework/source/uifactory/uicontrollerfactory.cxx
new file mode 100644
index 000000000..35d883a4c
--- /dev/null
+++ b/framework/source/uifactory/uicontrollerfactory.cxx
@@ -0,0 +1,397 @@
+/* -*- 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 <uifactory/factoryconfiguration.hxx>
+
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/frame/XUIControllerFactory.hpp>
+
+#include <rtl/ref.hxx>
+#include <cppuhelper/basemutex.hxx>
+#include <cppuhelper/compbase.hxx>
+#include <cppuhelper/supportsservice.hxx>
+
+using namespace css::uno;
+using namespace css::lang;
+using namespace css::beans;
+using namespace css::container;
+using namespace css::frame;
+using namespace framework;
+
+namespace {
+
+typedef ::cppu::WeakComponentImplHelper<
+ css::lang::XServiceInfo,
+ css::frame::XUIControllerFactory > UIControllerFactory_BASE;
+
+class UIControllerFactory : private cppu::BaseMutex,
+ public UIControllerFactory_BASE
+{
+public:
+ virtual ~UIControllerFactory() override;
+
+ // XMultiComponentFactory
+ virtual css::uno::Reference< css::uno::XInterface > SAL_CALL createInstanceWithContext( const OUString& aServiceSpecifier, const css::uno::Reference< css::uno::XComponentContext >& Context ) override;
+ virtual css::uno::Reference< css::uno::XInterface > SAL_CALL createInstanceWithArgumentsAndContext( const OUString& ServiceSpecifier, const css::uno::Sequence< css::uno::Any >& Arguments, const css::uno::Reference< css::uno::XComponentContext >& Context ) override;
+ virtual css::uno::Sequence< OUString > SAL_CALL getAvailableServiceNames() override;
+
+ // XUIControllerRegistration
+ virtual sal_Bool SAL_CALL hasController( const OUString& aCommandURL, const OUString& aModuleName ) override;
+ virtual void SAL_CALL registerController( const OUString& aCommandURL, const OUString& aModuleName, const OUString& aControllerImplementationName ) override;
+ virtual void SAL_CALL deregisterController( const OUString& aCommandURL, const OUString& aModuleName ) override;
+
+protected:
+ UIControllerFactory( const css::uno::Reference< css::uno::XComponentContext >& xContext, const OUString &rUINode );
+ bool m_bConfigRead;
+ css::uno::Reference< css::uno::XComponentContext > m_xContext;
+ rtl::Reference<ConfigurationAccess_ControllerFactory> m_pConfigAccess;
+
+private:
+ virtual void SAL_CALL disposing() final override;
+};
+
+UIControllerFactory::UIControllerFactory(
+ const Reference< XComponentContext >& xContext,
+ const OUString &rConfigurationNode )
+ : UIControllerFactory_BASE(m_aMutex)
+ , m_bConfigRead( false )
+ , m_xContext( xContext )
+ , m_pConfigAccess()
+{
+ m_pConfigAccess = new ConfigurationAccess_ControllerFactory(m_xContext,
+ "/org.openoffice.Office.UI.Controller/Registered/" + rConfigurationNode);
+}
+
+UIControllerFactory::~UIControllerFactory()
+{
+ disposing();
+}
+
+void SAL_CALL UIControllerFactory::disposing()
+{
+ osl::MutexGuard g(rBHelper.rMutex);
+ m_pConfigAccess.clear();
+}
+
+// XMultiComponentFactory
+Reference< XInterface > SAL_CALL UIControllerFactory::createInstanceWithContext(
+ const OUString& aServiceSpecifier,
+ const Reference< XComponentContext >& )
+{
+ // SAFE
+ osl::MutexGuard g(rBHelper.rMutex);
+
+ if ( !m_bConfigRead )
+ {
+ m_bConfigRead = true;
+ m_pConfigAccess->readConfigurationData();
+ }
+
+ OUString aServiceName = m_pConfigAccess->getServiceFromCommandModule( aServiceSpecifier, OUString() );
+ if ( !aServiceName.isEmpty() )
+ return m_xContext->getServiceManager()->createInstanceWithContext( aServiceName, m_xContext );
+ else
+ return Reference< XInterface >();
+ // SAFE
+}
+
+Reference< XInterface > SAL_CALL UIControllerFactory::createInstanceWithArgumentsAndContext(
+ const OUString& ServiceSpecifier,
+ const Sequence< Any >& Arguments,
+ const Reference< XComponentContext >& )
+{
+ const OUString aPropModuleName( "ModuleIdentifier" );
+ const OUString aPropValueName( "Value" );
+
+ OUString aPropName;
+ PropertyValue aPropValue;
+
+ // Retrieve the optional module name from the Arguments sequence. It is used as a part of
+ // the hash map key to support different controller implementation for the same URL but different
+ // module!!
+ for ( Any const & arg : Arguments )
+ {
+ if (( arg >>= aPropValue ) && ( aPropValue.Name == aPropModuleName ))
+ {
+ aPropValue.Value >>= aPropName;
+ break;
+ }
+ }
+
+ Sequence< Any > aNewArgs( Arguments );
+
+ sal_Int32 nAppendIndex = aNewArgs.getLength();
+ aNewArgs.realloc( aNewArgs.getLength() + 2 );
+
+ // Append the command URL to the Arguments sequence so that one controller can be
+ // used for more than one command URL.
+ aPropValue.Name = "CommandURL";
+ aPropValue.Value <<= ServiceSpecifier;
+ aNewArgs[nAppendIndex] <<= aPropValue;
+
+ // Append the optional value argument. It's an empty string if no additional info
+ // is provided to the controller.
+ OUString aValue = m_pConfigAccess->getValueFromCommandModule( ServiceSpecifier, aPropName );
+ aPropValue.Name = aPropValueName;
+ aPropValue.Value <<= aValue;
+ aNewArgs[nAppendIndex+1] <<= aPropValue;
+
+ {
+ OUString aServiceName;
+ { // SAFE
+ osl::MutexGuard g(rBHelper.rMutex);
+
+ if ( !m_bConfigRead )
+ {
+ m_bConfigRead = true;
+ m_pConfigAccess->readConfigurationData();
+ }
+
+ aServiceName = m_pConfigAccess->getServiceFromCommandModule( ServiceSpecifier, aPropName );
+ } // SAFE
+
+ if ( !aServiceName.isEmpty() )
+ return m_xContext->getServiceManager()->createInstanceWithArgumentsAndContext( aServiceName, aNewArgs, m_xContext );
+ else
+ return Reference< XInterface >();
+ }
+}
+
+Sequence< OUString > SAL_CALL UIControllerFactory::getAvailableServiceNames()
+{
+ return Sequence< OUString >();
+}
+
+// XUIControllerRegistration
+sal_Bool SAL_CALL UIControllerFactory::hasController(
+ const OUString& aCommandURL,
+ const OUString& aModuleName )
+{
+ osl::MutexGuard g(rBHelper.rMutex);
+
+ if ( !m_bConfigRead )
+ {
+ m_bConfigRead = true;
+ m_pConfigAccess->readConfigurationData();
+ }
+
+ return ( !m_pConfigAccess->getServiceFromCommandModule( aCommandURL, aModuleName ).isEmpty() );
+}
+
+void SAL_CALL UIControllerFactory::registerController(
+ const OUString& aCommandURL,
+ const OUString& aModuleName,
+ const OUString& aControllerImplementationName )
+{
+ // SAFE
+ osl::MutexGuard g(rBHelper.rMutex);
+
+ if ( !m_bConfigRead )
+ {
+ m_bConfigRead = true;
+ m_pConfigAccess->readConfigurationData();
+ }
+
+ m_pConfigAccess->addServiceToCommandModule( aCommandURL, aModuleName, aControllerImplementationName );
+ // SAFE
+}
+
+void SAL_CALL UIControllerFactory::deregisterController(
+ const OUString& aCommandURL,
+ const OUString& aModuleName )
+{
+ // SAFE
+ osl::MutexGuard g(rBHelper.rMutex);
+
+ if ( !m_bConfigRead )
+ {
+ m_bConfigRead = true;
+ m_pConfigAccess->readConfigurationData();
+ }
+
+ m_pConfigAccess->removeServiceFromCommandModule( aCommandURL, aModuleName );
+ // SAFE
+}
+
+class PopupMenuControllerFactory : public UIControllerFactory
+{
+public:
+ explicit PopupMenuControllerFactory( const css::uno::Reference< css::uno::XComponentContext >& xContext );
+
+ virtual OUString SAL_CALL getImplementationName() override
+ {
+ return "com.sun.star.comp.framework.PopupMenuControllerFactory";
+ }
+
+ virtual sal_Bool SAL_CALL supportsService(OUString const & ServiceName) override
+ {
+ return cppu::supportsService(this, ServiceName);
+ }
+
+ virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override
+ {
+ return {"com.sun.star.frame.PopupMenuControllerFactory"};
+ }
+
+};
+
+PopupMenuControllerFactory::PopupMenuControllerFactory( const Reference< XComponentContext >& xContext ) :
+ UIControllerFactory( xContext, "PopupMenu" )
+{
+}
+
+struct PopupMenuControllerFactoryInstance {
+ explicit PopupMenuControllerFactoryInstance(
+ css::uno::Reference<css::uno::XComponentContext> const & context):
+ instance(static_cast<cppu::OWeakObject *>(
+ new PopupMenuControllerFactory(context)))
+ {
+ }
+
+ css::uno::Reference<css::uno::XInterface> instance;
+};
+
+struct PopupMenuControllerFactorySingleton:
+ public rtl::StaticWithArg<
+ PopupMenuControllerFactoryInstance,
+ css::uno::Reference<css::uno::XComponentContext>,
+ PopupMenuControllerFactorySingleton>
+{};
+
+class ToolbarControllerFactory : public UIControllerFactory
+{
+public:
+ explicit ToolbarControllerFactory( const css::uno::Reference< css::uno::XComponentContext >& xContext );
+
+ virtual OUString SAL_CALL getImplementationName() override
+ {
+ return "com.sun.star.comp.framework.ToolBarControllerFactory";
+ }
+
+ virtual sal_Bool SAL_CALL supportsService(OUString const & ServiceName) override
+ {
+ return cppu::supportsService(this, ServiceName);
+ }
+
+ virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override
+ {
+ return {"com.sun.star.frame.ToolbarControllerFactory"};
+ }
+
+};
+
+ToolbarControllerFactory::ToolbarControllerFactory( const Reference< XComponentContext >& xContext ) :
+ UIControllerFactory( xContext, "ToolBar" )
+{
+}
+
+struct ToolbarControllerFactoryInstance {
+ explicit ToolbarControllerFactoryInstance(
+ css::uno::Reference<css::uno::XComponentContext> const & context):
+ instance(static_cast<cppu::OWeakObject *>(
+ new ToolbarControllerFactory(context)))
+ {
+ }
+
+ css::uno::Reference<css::uno::XInterface> instance;
+};
+
+struct ToolbarControllerFactorySingleton:
+ public rtl::StaticWithArg<
+ ToolbarControllerFactoryInstance,
+ css::uno::Reference<css::uno::XComponentContext>,
+ ToolbarControllerFactorySingleton>
+{};
+
+class StatusbarControllerFactory : public UIControllerFactory
+{
+public:
+ explicit StatusbarControllerFactory( const css::uno::Reference< css::uno::XComponentContext >& xContext );
+
+ virtual OUString SAL_CALL getImplementationName() override
+ {
+ return "com.sun.star.comp.framework.StatusBarControllerFactory";
+ }
+
+ virtual sal_Bool SAL_CALL supportsService(OUString const & ServiceName) override
+ {
+ return cppu::supportsService(this, ServiceName);
+ }
+
+ virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override
+ {
+ return {"com.sun.star.frame.StatusbarControllerFactory"};
+ }
+
+};
+
+StatusbarControllerFactory::StatusbarControllerFactory( const Reference< XComponentContext >& xContext ) :
+ UIControllerFactory( xContext, "StatusBar" )
+{
+}
+
+struct StatusbarControllerFactoryInstance {
+ explicit StatusbarControllerFactoryInstance(
+ css::uno::Reference<css::uno::XComponentContext> const & context):
+ instance(static_cast<cppu::OWeakObject *>(
+ new StatusbarControllerFactory(context)))
+ {
+ }
+
+ css::uno::Reference<css::uno::XInterface> instance;
+};
+
+struct StatusbarControllerFactorySingleton:
+ public rtl::StaticWithArg<
+ StatusbarControllerFactoryInstance,
+ css::uno::Reference<css::uno::XComponentContext>,
+ StatusbarControllerFactorySingleton>
+{};
+
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
+com_sun_star_comp_framework_PopupMenuControllerFactory_get_implementation(
+ css::uno::XComponentContext *context,
+ css::uno::Sequence<css::uno::Any> const &)
+{
+ return cppu::acquire(static_cast<cppu::OWeakObject *>(
+ PopupMenuControllerFactorySingleton::get(context).instance.get()));
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
+com_sun_star_comp_framework_ToolBarControllerFactory_get_implementation(
+ css::uno::XComponentContext *context,
+ css::uno::Sequence<css::uno::Any> const &)
+{
+ return cppu::acquire(static_cast<cppu::OWeakObject *>(
+ ToolbarControllerFactorySingleton::get(context).instance.get()));
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
+com_sun_star_comp_framework_StatusBarControllerFactory_get_implementation(
+ css::uno::XComponentContext *context,
+ css::uno::Sequence<css::uno::Any> const &)
+{
+ return cppu::acquire(static_cast<cppu::OWeakObject *>(
+ StatusbarControllerFactorySingleton::get(context).instance.get()));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uifactory/uielementfactorymanager.cxx b/framework/source/uifactory/uielementfactorymanager.cxx
new file mode 100644
index 000000000..68e228683
--- /dev/null
+++ b/framework/source/uifactory/uielementfactorymanager.cxx
@@ -0,0 +1,569 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <uifactory/configurationaccessfactorymanager.hxx>
+#include <helper/mischelper.hxx>
+
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/configuration/theDefaultProvider.hpp>
+#include <com/sun/star/container/ElementExistException.hpp>
+#include <com/sun/star/container/XContainer.hpp>
+#include <com/sun/star/container/XContainerListener.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/loader/CannotActivateFactoryException.hpp>
+#include <com/sun/star/frame/ModuleManager.hpp>
+#include <com/sun/star/frame/UnknownModuleException.hpp>
+#include <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/frame/XModuleManager2.hpp>
+#include <com/sun/star/ui/XUIElementFactoryManager.hpp>
+
+#include <rtl/ref.hxx>
+#include <sal/log.hxx>
+#include <comphelper/propertysequence.hxx>
+#include <cppuhelper/basemutex.hxx>
+#include <cppuhelper/compbase.hxx>
+#include <cppuhelper/supportsservice.hxx>
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::frame;
+using namespace com::sun::star::configuration;
+using namespace com::sun::star::container;
+using namespace ::com::sun::star::ui;
+using namespace framework;
+
+namespace framework
+{
+
+// global function needed by both implementations
+static OUString getHashKeyFromStrings( const OUString& aType, const OUString& aName, const OUString& aModuleName )
+{
+ return aType + "^" + aName + "^" + aModuleName;
+}
+
+ConfigurationAccess_FactoryManager::ConfigurationAccess_FactoryManager( const Reference< XComponentContext >& rxContext, const OUString& _sRoot ) :
+ m_aPropType( "Type" ),
+ m_aPropName( "Name" ),
+ m_aPropModule( "Module" ),
+ m_aPropFactory( "FactoryImplementation" ),
+ m_sRoot(_sRoot),
+ m_bConfigAccessInitialized( false )
+{
+ m_xConfigProvider = theDefaultProvider::get( rxContext );
+}
+
+ConfigurationAccess_FactoryManager::~ConfigurationAccess_FactoryManager()
+{
+ // SAFE
+ osl::MutexGuard g(m_aMutex);
+
+ Reference< XContainer > xContainer( m_xConfigAccess, UNO_QUERY );
+ if ( xContainer.is() )
+ xContainer->removeContainerListener(m_xConfigListener);
+}
+
+OUString ConfigurationAccess_FactoryManager::getFactorySpecifierFromTypeNameModule( const OUString& rType, const OUString& rName, const OUString& rModule ) const
+{
+ // SAFE
+ osl::MutexGuard g(m_aMutex);
+
+ FactoryManagerMap::const_iterator pIter =
+ m_aFactoryManagerMap.find( getHashKeyFromStrings( rType, rName, rModule ));
+ if ( pIter != m_aFactoryManagerMap.end() )
+ return pIter->second;
+ else
+ {
+ pIter = m_aFactoryManagerMap.find( getHashKeyFromStrings( rType, rName, OUString() ));
+ if ( pIter != m_aFactoryManagerMap.end() )
+ return pIter->second;
+ else
+ {
+ // Support factories which uses a defined prefix before the ui name.
+ sal_Int32 nIndex = rName.indexOf( '_' );
+ if ( nIndex > 0 )
+ {
+ OUString aName = rName.copy( 0, nIndex+1 );
+ pIter = m_aFactoryManagerMap.find( getHashKeyFromStrings( rType, aName, OUString() ));
+ if ( pIter != m_aFactoryManagerMap.end() )
+ return pIter->second;
+ }
+
+ pIter = m_aFactoryManagerMap.find( getHashKeyFromStrings( rType, OUString(), OUString() ));
+ if ( pIter != m_aFactoryManagerMap.end() )
+ return pIter->second;
+ }
+ }
+
+ return OUString();
+}
+
+void ConfigurationAccess_FactoryManager::addFactorySpecifierToTypeNameModule( const OUString& rType, const OUString& rName, const OUString& rModule, const OUString& rServiceSpecifier )
+{
+ // SAFE
+ osl::MutexGuard g(m_aMutex);
+
+ OUString aHashKey = getHashKeyFromStrings( rType, rName, rModule );
+
+ FactoryManagerMap::const_iterator pIter = m_aFactoryManagerMap.find( aHashKey );
+
+ if ( pIter != m_aFactoryManagerMap.end() )
+ throw ElementExistException();
+ m_aFactoryManagerMap.emplace( aHashKey, rServiceSpecifier );
+}
+
+void ConfigurationAccess_FactoryManager::removeFactorySpecifierFromTypeNameModule( const OUString& rType, const OUString& rName, const OUString& rModule )
+{
+ // SAFE
+ osl::MutexGuard g(m_aMutex);
+
+ OUString aHashKey = getHashKeyFromStrings( rType, rName, rModule );
+
+ FactoryManagerMap::const_iterator pIter = m_aFactoryManagerMap.find( aHashKey );
+
+ if ( pIter == m_aFactoryManagerMap.end() )
+ throw NoSuchElementException();
+ m_aFactoryManagerMap.erase( aHashKey );
+}
+
+Sequence< Sequence< PropertyValue > > ConfigurationAccess_FactoryManager::getFactoriesDescription() const
+{
+ // SAFE
+ osl::MutexGuard g(m_aMutex);
+
+ Sequence< Sequence< PropertyValue > > aSeqSeq;
+
+ sal_Int32 nIndex( 0 );
+ for ( const auto& rEntry : m_aFactoryManagerMap )
+ {
+ OUString aFactory = rEntry.first;
+ if ( !aFactory.isEmpty() )
+ {
+ sal_Int32 nToken = 0;
+ Sequence< PropertyValue > aSeq( 1 );
+
+ aSeqSeq.realloc( aSeqSeq.getLength() + 1 );
+ aSeq[0].Name = m_aPropType;
+ aSeq[0].Value <<= aFactory.getToken( 0, '^', nToken );
+ if ( nToken > 0 )
+ {
+ aSeq.realloc( 2 );
+ aSeq[1].Name = m_aPropName;
+ aSeq[1].Value <<= aFactory.getToken( 0, '^', nToken );
+ if ( nToken > 0 )
+ {
+ aSeq.realloc( 3 );
+ aSeq[2].Name = m_aPropModule;
+ aSeq[2].Value <<= aFactory.getToken( 0, '^', nToken );
+ }
+ }
+
+ aSeqSeq[nIndex++] = aSeq;
+ }
+ }
+
+ return aSeqSeq;
+}
+
+// container.XContainerListener
+void SAL_CALL ConfigurationAccess_FactoryManager::elementInserted( const ContainerEvent& aEvent )
+{
+ OUString aType;
+ OUString aName;
+ OUString aModule;
+ OUString aService;
+
+ // SAFE
+ osl::MutexGuard g(m_aMutex);
+
+ if ( impl_getElementProps( aEvent.Element, aType, aName, aModule, aService ))
+ {
+ // Create hash key from type, name and module as they are together a primary key to
+ // the UNO service that implements a user interface factory.
+ OUString aHashKey( getHashKeyFromStrings( aType, aName, aModule ));
+ m_aFactoryManagerMap.emplace( aHashKey, aService );
+ }
+}
+
+void SAL_CALL ConfigurationAccess_FactoryManager::elementRemoved ( const ContainerEvent& aEvent )
+{
+ OUString aType;
+ OUString aName;
+ OUString aModule;
+ OUString aService;
+
+ // SAFE
+ osl::MutexGuard g(m_aMutex);
+
+ if ( impl_getElementProps( aEvent.Element, aType, aName, aModule, aService ))
+ {
+ // Create hash key from command and model as they are together a primary key to
+ // the UNO service that implements the popup menu controller.
+ OUString aHashKey( getHashKeyFromStrings( aType, aName, aModule ));
+ m_aFactoryManagerMap.erase( aHashKey );
+ }
+}
+
+void SAL_CALL ConfigurationAccess_FactoryManager::elementReplaced( const ContainerEvent& aEvent )
+{
+ OUString aType;
+ OUString aName;
+ OUString aModule;
+ OUString aService;
+
+ // SAFE
+ osl::MutexGuard g(m_aMutex);
+
+ if ( impl_getElementProps( aEvent.Element, aType, aName, aModule, aService ))
+ {
+ // Create hash key from command and model as they are together a primary key to
+ // the UNO service that implements the popup menu controller.
+ OUString aHashKey( getHashKeyFromStrings( aType, aName, aModule ));
+ m_aFactoryManagerMap.erase( aHashKey );
+ m_aFactoryManagerMap.emplace( aHashKey, aService );
+ }
+}
+
+// lang.XEventListener
+void SAL_CALL ConfigurationAccess_FactoryManager::disposing( const EventObject& )
+{
+ // SAFE
+ // remove our reference to the config access
+ osl::MutexGuard g(m_aMutex);
+ m_xConfigAccess.clear();
+}
+
+void ConfigurationAccess_FactoryManager::readConfigurationData()
+{
+ // SAFE
+ osl::MutexGuard g(m_aMutex);
+
+ if ( !m_bConfigAccessInitialized )
+ {
+ Sequence<Any> aArgs(comphelper::InitAnyPropertySequence(
+ {
+ {"nodepath", Any(m_sRoot)}
+ }));
+
+ try
+ {
+ m_xConfigAccess.set( m_xConfigProvider->createInstanceWithArguments(
+ "com.sun.star.configuration.ConfigurationAccess", aArgs ), UNO_QUERY );
+ }
+ catch ( const WrappedTargetException& )
+ {
+ }
+
+ m_bConfigAccessInitialized = true;
+ }
+
+ if ( !m_xConfigAccess.is() )
+ return;
+
+ const Sequence< OUString > aUIElementFactories = m_xConfigAccess->getElementNames();
+
+ OUString aType;
+ OUString aName;
+ OUString aModule;
+ OUString aService;
+ OUString aHashKey;
+ for ( OUString const & factoryName : aUIElementFactories )
+ {
+ if ( impl_getElementProps( m_xConfigAccess->getByName( factoryName ), aType, aName, aModule, aService ))
+ {
+ // Create hash key from type, name and module as they are together a primary key to
+ // the UNO service that implements the user interface element factory.
+ aHashKey = getHashKeyFromStrings( aType, aName, aModule );
+ m_aFactoryManagerMap.emplace( aHashKey, aService );
+ }
+ }
+
+ Reference< XContainer > xContainer( m_xConfigAccess, UNO_QUERY );
+ if ( xContainer.is() )
+ {
+ m_xConfigListener = new WeakContainerListener(this);
+ xContainer->addContainerListener(m_xConfigListener);
+ }
+}
+
+bool ConfigurationAccess_FactoryManager::impl_getElementProps( const Any& aElement, OUString& rType, OUString& rName, OUString& rModule, OUString& rServiceSpecifier ) const
+{
+ Reference< XPropertySet > xPropertySet;
+ aElement >>= xPropertySet;
+
+ if ( xPropertySet.is() )
+ {
+ try
+ {
+ xPropertySet->getPropertyValue( m_aPropType ) >>= rType;
+ xPropertySet->getPropertyValue( m_aPropName ) >>= rName;
+ xPropertySet->getPropertyValue( m_aPropModule ) >>= rModule;
+ xPropertySet->getPropertyValue( m_aPropFactory ) >>= rServiceSpecifier;
+ }
+ catch ( const css::beans::UnknownPropertyException& )
+ {
+ return false;
+ }
+ catch ( const css::lang::WrappedTargetException& )
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+} // framework
+
+namespace {
+
+typedef ::cppu::WeakComponentImplHelper<
+ css::lang::XServiceInfo,
+ css::ui::XUIElementFactoryManager> UIElementFactoryManager_BASE;
+
+class UIElementFactoryManager : private cppu::BaseMutex,
+ public UIElementFactoryManager_BASE
+{
+ virtual void SAL_CALL disposing() override;
+public:
+ explicit UIElementFactoryManager( const css::uno::Reference< css::uno::XComponentContext >& rxContext );
+
+ virtual OUString SAL_CALL getImplementationName() override
+ {
+ return "com.sun.star.comp.framework.UIElementFactoryManager";
+ }
+
+ virtual sal_Bool SAL_CALL supportsService(OUString const & ServiceName) override
+ {
+ return cppu::supportsService(this, ServiceName);
+ }
+
+ virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override
+ {
+ return {"com.sun.star.ui.UIElementFactoryManager"};
+ }
+
+ // XUIElementFactory
+ virtual css::uno::Reference< css::ui::XUIElement > SAL_CALL createUIElement( const OUString& ResourceURL, const css::uno::Sequence< css::beans::PropertyValue >& Args ) override;
+
+ // XUIElementFactoryRegistration
+ virtual css::uno::Sequence< css::uno::Sequence< css::beans::PropertyValue > > SAL_CALL getRegisteredFactories( ) override;
+ virtual css::uno::Reference< css::ui::XUIElementFactory > SAL_CALL getFactory( const OUString& ResourceURL, const OUString& ModuleIdentifier ) override;
+ virtual void SAL_CALL registerFactory( const OUString& aType, const OUString& aName, const OUString& aModuleIdentifier, const OUString& aFactoryImplementationName ) override;
+ virtual void SAL_CALL deregisterFactory( const OUString& aType, const OUString& aName, const OUString& aModuleIdentifier ) override;
+
+private:
+ bool m_bConfigRead;
+ css::uno::Reference< css::uno::XComponentContext > m_xContext;
+ rtl::Reference<ConfigurationAccess_FactoryManager> m_pConfigAccess;
+};
+
+UIElementFactoryManager::UIElementFactoryManager( const Reference< XComponentContext >& rxContext ) :
+ UIElementFactoryManager_BASE(m_aMutex),
+ m_bConfigRead( false ),
+ m_xContext(rxContext),
+ m_pConfigAccess(
+ new ConfigurationAccess_FactoryManager(
+ rxContext,
+ "/org.openoffice.Office.UI.Factories/Registered/UIElementFactories"))
+{}
+
+void SAL_CALL UIElementFactoryManager::disposing()
+{
+ m_pConfigAccess.clear();
+}
+
+// XUIElementFactory
+Reference< XUIElement > SAL_CALL UIElementFactoryManager::createUIElement(
+ const OUString& ResourceURL,
+ const Sequence< PropertyValue >& Args )
+{
+ Reference< XFrame > xFrame;
+ OUString aModuleId;
+ { // SAFE
+ osl::MutexGuard g(rBHelper.rMutex);
+ if (rBHelper.bDisposed) {
+ throw css::lang::DisposedException(
+ "disposed", static_cast<OWeakObject *>(this));
+ }
+
+ if ( !m_bConfigRead )
+ {
+ m_bConfigRead = true;
+ m_pConfigAccess->readConfigurationData();
+ }
+
+ // Retrieve the frame instance from the arguments to determine the module identifier. This must be provided
+ // to the search function. An empty module identifier is provided if the frame is missing or the module id cannot
+ // retrieve from it.
+ for ( auto const & arg : Args )
+ {
+ if ( arg.Name == "Frame")
+ arg.Value >>= xFrame;
+ if (arg.Name == "Module")
+ arg.Value >>= aModuleId;
+ }
+ } // SAFE
+
+ Reference< XModuleManager2 > xManager = ModuleManager::create( m_xContext );
+
+ // Determine the module identifier
+ try
+ {
+ if ( aModuleId.isEmpty() && xFrame.is() && xManager.is() )
+ aModuleId = xManager->identify( Reference<XInterface>( xFrame, UNO_QUERY ) );
+
+ Reference< XUIElementFactory > xUIElementFactory = getFactory( ResourceURL, aModuleId );
+ if ( xUIElementFactory.is() )
+ return xUIElementFactory->createUIElement( ResourceURL, Args );
+ }
+ catch ( const UnknownModuleException& )
+ {
+ }
+
+ throw NoSuchElementException();
+}
+
+// XUIElementFactoryRegistration
+Sequence< Sequence< PropertyValue > > SAL_CALL UIElementFactoryManager::getRegisteredFactories()
+{
+ // SAFE
+ osl::MutexGuard g(rBHelper.rMutex);
+ if (rBHelper.bDisposed) {
+ throw css::lang::DisposedException(
+ "disposed", static_cast<OWeakObject *>(this));
+ }
+
+ if ( !m_bConfigRead )
+ {
+ m_bConfigRead = true;
+ m_pConfigAccess->readConfigurationData();
+ }
+
+ return m_pConfigAccess->getFactoriesDescription();
+}
+
+Reference< XUIElementFactory > SAL_CALL UIElementFactoryManager::getFactory( const OUString& aResourceURL, const OUString& aModuleId )
+{
+ OUString aServiceSpecifier;
+ { // SAFE
+ osl::MutexGuard g(rBHelper.rMutex);
+ if (rBHelper.bDisposed) {
+ throw css::lang::DisposedException(
+ "disposed", static_cast<OWeakObject *>(this));
+ }
+
+ if ( !m_bConfigRead )
+ {
+ m_bConfigRead = true;
+ m_pConfigAccess->readConfigurationData();
+ }
+
+ OUString aType;
+ OUString aName;
+
+ RetrieveTypeNameFromResourceURL( aResourceURL, aType, aName );
+
+ aServiceSpecifier = m_pConfigAccess->getFactorySpecifierFromTypeNameModule( aType, aName, aModuleId );
+ } // SAFE
+
+ if ( !aServiceSpecifier.isEmpty() ) try
+ {
+ Reference< XUIElementFactory > xFactory(m_xContext->getServiceManager()->
+ createInstanceWithContext(aServiceSpecifier, m_xContext), UNO_QUERY);
+ SAL_WARN_IF(!xFactory.is(), "fwk.uielement", "could not create factory: " << aServiceSpecifier);
+ return xFactory;
+ }
+ catch ( const css::loader::CannotActivateFactoryException& )
+ {
+ SAL_WARN("fwk.uielement", aServiceSpecifier <<
+ " not available. This should happen only on mobile platforms.");
+ }
+ return Reference< XUIElementFactory >();
+}
+
+void SAL_CALL UIElementFactoryManager::registerFactory( const OUString& aType, const OUString& aName, const OUString& aModuleId, const OUString& aFactoryImplementationName )
+{
+ // SAFE
+ osl::MutexGuard g(rBHelper.rMutex);
+ if (rBHelper.bDisposed) {
+ throw css::lang::DisposedException(
+ "disposed", static_cast<OWeakObject *>(this));
+ }
+
+ if ( !m_bConfigRead )
+ {
+ m_bConfigRead = true;
+ m_pConfigAccess->readConfigurationData();
+ }
+
+ m_pConfigAccess->addFactorySpecifierToTypeNameModule( aType, aName, aModuleId, aFactoryImplementationName );
+ // SAFE
+}
+
+void SAL_CALL UIElementFactoryManager::deregisterFactory( const OUString& aType, const OUString& aName, const OUString& aModuleId )
+{
+ // SAFE
+ osl::MutexGuard g(rBHelper.rMutex);
+ if (rBHelper.bDisposed) {
+ throw css::lang::DisposedException(
+ "disposed", static_cast<OWeakObject *>(this));
+ }
+
+ if ( !m_bConfigRead )
+ {
+ m_bConfigRead = true;
+ m_pConfigAccess->readConfigurationData();
+ }
+
+ m_pConfigAccess->removeFactorySpecifierFromTypeNameModule( aType, aName, aModuleId );
+ // SAFE
+}
+
+struct Instance {
+ explicit Instance(
+ css::uno::Reference<css::uno::XComponentContext> const & context):
+ instance(static_cast<cppu::OWeakObject *>(
+ new UIElementFactoryManager(context)))
+ {
+ }
+
+ css::uno::Reference<css::uno::XInterface> instance;
+};
+
+struct Singleton:
+ public rtl::StaticWithArg<
+ Instance, css::uno::Reference<css::uno::XComponentContext>, Singleton>
+{};
+
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
+com_sun_star_comp_framework_UIElementFactoryManager_get_implementation(
+ css::uno::XComponentContext *context,
+ css::uno::Sequence<css::uno::Any> const &)
+{
+ return cppu::acquire(static_cast<cppu::OWeakObject *>(
+ Singleton::get(context).instance.get()));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uifactory/windowcontentfactorymanager.cxx b/framework/source/uifactory/windowcontentfactorymanager.cxx
new file mode 100644
index 000000000..996fae5f4
--- /dev/null
+++ b/framework/source/uifactory/windowcontentfactorymanager.cxx
@@ -0,0 +1,223 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <uifactory/configurationaccessfactorymanager.hxx>
+#include <helper/mischelper.hxx>
+
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/frame/ModuleManager.hpp>
+#include <com/sun/star/frame/UnknownModuleException.hpp>
+#include <com/sun/star/frame/XModuleManager2.hpp>
+#include <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XSingleComponentFactory.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+
+#include <cppuhelper/basemutex.hxx>
+#include <cppuhelper/compbase.hxx>
+#include <cppuhelper/supportsservice.hxx>
+#include <rtl/ref.hxx>
+#include <tools/diagnose_ex.h>
+
+using namespace ::com::sun::star;
+using namespace framework;
+
+namespace {
+
+typedef ::cppu::WeakComponentImplHelper<
+ css::lang::XServiceInfo,
+ css::lang::XSingleComponentFactory > WindowContentFactoryManager_BASE;
+
+class WindowContentFactoryManager : private cppu::BaseMutex,
+ public WindowContentFactoryManager_BASE
+{
+public:
+ explicit WindowContentFactoryManager( const css::uno::Reference< css::uno::XComponentContext>& rxContext );
+
+ virtual OUString SAL_CALL getImplementationName() override
+ {
+ return "com.sun.star.comp.framework.WindowContentFactoryManager";
+ }
+
+ virtual sal_Bool SAL_CALL supportsService(OUString const & ServiceName) override
+ {
+ return cppu::supportsService(this, ServiceName);
+ }
+
+ virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override
+ {
+ return {"com.sun.star.ui.WindowContentFactoryManager"};
+ }
+
+ // XSingleComponentFactory
+ virtual css::uno::Reference< css::uno::XInterface > SAL_CALL createInstanceWithContext( const css::uno::Reference< css::uno::XComponentContext >& Context ) override;
+ virtual css::uno::Reference< css::uno::XInterface > SAL_CALL createInstanceWithArgumentsAndContext( const css::uno::Sequence< css::uno::Any >& Arguments, const css::uno::Reference< css::uno::XComponentContext >& Context ) override;
+
+private:
+ virtual void SAL_CALL disposing() override;
+
+ css::uno::Reference< css::uno::XComponentContext > m_xContext;
+ bool m_bConfigRead;
+ rtl::Reference<ConfigurationAccess_FactoryManager> m_pConfigAccess;
+};
+
+WindowContentFactoryManager::WindowContentFactoryManager( const uno::Reference< uno::XComponentContext >& rxContext ) :
+ WindowContentFactoryManager_BASE(m_aMutex),
+ m_xContext( rxContext ),
+ m_bConfigRead( false ),
+ m_pConfigAccess(
+ new ConfigurationAccess_FactoryManager(
+ m_xContext,
+ "/org.openoffice.Office.UI.WindowContentFactories/Registered/ContentFactories"))
+{}
+
+void SAL_CALL WindowContentFactoryManager::disposing()
+{
+ m_pConfigAccess.clear();
+}
+
+// XSingleComponentFactory
+uno::Reference< uno::XInterface > SAL_CALL WindowContentFactoryManager::createInstanceWithContext(
+ const uno::Reference< uno::XComponentContext >& /*xContext*/ )
+{
+ uno::Reference< uno::XInterface > xWindow;
+ return xWindow;
+}
+
+uno::Reference< uno::XInterface > SAL_CALL WindowContentFactoryManager::createInstanceWithArgumentsAndContext(
+ const uno::Sequence< uno::Any >& Arguments, const uno::Reference< uno::XComponentContext >& Context )
+{
+ uno::Reference< uno::XInterface > xWindow;
+ uno::Reference< frame::XFrame > xFrame;
+ OUString aResourceURL;
+
+ for (auto const & arg : Arguments )
+ {
+ beans::PropertyValue aPropValue;
+ if ( arg >>= aPropValue )
+ {
+ if ( aPropValue.Name == "Frame" )
+ aPropValue.Value >>= xFrame;
+ else if ( aPropValue.Name == "ResourceURL" )
+ aPropValue.Value >>= aResourceURL;
+ }
+ }
+
+ // Determine the module identifier
+ OUString aType;
+ OUString aName;
+ OUString aModuleId;
+ uno::Reference< frame::XModuleManager2 > xModuleManager =
+ frame::ModuleManager::create( m_xContext );
+ try
+ {
+ if ( xFrame.is() && xModuleManager.is() )
+ aModuleId = xModuleManager->identify( uno::Reference< uno::XInterface >( xFrame, uno::UNO_QUERY ) );
+ }
+ catch ( const frame::UnknownModuleException& )
+ {
+ }
+
+ RetrieveTypeNameFromResourceURL( aResourceURL, aType, aName );
+ if ( !aType.isEmpty() &&
+ !aName.isEmpty() &&
+ !aModuleId.isEmpty() )
+ {
+ OUString aImplementationName;
+ uno::Reference< uno::XInterface > xHolder( static_cast<cppu::OWeakObject*>(this), uno::UNO_QUERY );
+
+ // Determine the implementation name of the window content factory dependent on the
+ // module identifier, user interface element type and name
+ { // SAFE
+ osl::MutexGuard g(rBHelper.rMutex);
+ if (rBHelper.bDisposed) {
+ throw css::lang::DisposedException(
+ "disposed", static_cast<OWeakObject *>(this));
+ }
+ if ( !m_bConfigRead )
+ {
+ m_bConfigRead = true;
+ m_pConfigAccess->readConfigurationData();
+ }
+ aImplementationName = m_pConfigAccess->getFactorySpecifierFromTypeNameModule( aType, aName, aModuleId );
+ } // SAFE
+
+ if ( !aImplementationName.isEmpty() )
+ {
+ uno::Reference< lang::XMultiServiceFactory > xServiceManager( Context->getServiceManager(), uno::UNO_QUERY );
+ if ( xServiceManager.is() )
+ {
+ uno::Reference< lang::XSingleComponentFactory > xFactory(
+ xServiceManager->createInstance( aImplementationName ), uno::UNO_QUERY );
+ if ( xFactory.is() )
+ {
+ // Be careful: We call external code. Therefore here we have to catch all exceptions
+ try
+ {
+ xWindow = xFactory->createInstanceWithArgumentsAndContext( Arguments, Context );
+ }
+ catch ( uno::Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("fwk");
+ }
+ }
+ }
+ }
+ }
+
+ // UNSAFE
+ if ( !xWindow.is())
+ {
+ // Fallback: Use internal factory code to create a toolkit dialog as a content window
+ xWindow = createInstanceWithContext(Context);
+ }
+
+ return xWindow;
+}
+
+struct Instance {
+ explicit Instance(
+ css::uno::Reference<css::uno::XComponentContext> const & context):
+ instance(static_cast<cppu::OWeakObject *>(
+ new WindowContentFactoryManager(context)))
+ {
+ }
+
+ css::uno::Reference<css::uno::XInterface> instance;
+};
+
+struct Singleton:
+ public rtl::StaticWithArg<
+ Instance, css::uno::Reference<css::uno::XComponentContext>, Singleton>
+{};
+
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
+com_sun_star_comp_framework_WindowContentFactoryManager_get_implementation(
+ css::uno::XComponentContext *context,
+ css::uno::Sequence<css::uno::Any> const &)
+{
+ return cppu::acquire(static_cast<cppu::OWeakObject *>(
+ Singleton::get(context).instance.get()));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */