summaryrefslogtreecommitdiffstats
path: root/sfx2/source/dialog/backingcomp.cxx
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 05:54:39 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 05:54:39 +0000
commit267c6f2ac71f92999e969232431ba04678e7437e (patch)
tree358c9467650e1d0a1d7227a21dac2e3d08b622b2 /sfx2/source/dialog/backingcomp.cxx
parentInitial commit. (diff)
downloadlibreoffice-267c6f2ac71f92999e969232431ba04678e7437e.tar.xz
libreoffice-267c6f2ac71f92999e969232431ba04678e7437e.zip
Adding upstream version 4:24.2.0.upstream/4%24.2.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'sfx2/source/dialog/backingcomp.cxx')
-rw-r--r--sfx2/source/dialog/backingcomp.cxx736
1 files changed, 736 insertions, 0 deletions
diff --git a/sfx2/source/dialog/backingcomp.cxx b/sfx2/source/dialog/backingcomp.cxx
new file mode 100644
index 0000000000..2f3dc01744
--- /dev/null
+++ b/sfx2/source/dialog/backingcomp.cxx
@@ -0,0 +1,736 @@
+/* -*- 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 "backingwindow.hxx"
+
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/awt/KeyEvent.hpp>
+#include <com/sun/star/frame/XLayoutManager.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/awt/XWindow.hpp>
+#include <com/sun/star/awt/XKeyListener.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/frame/XDispatch.hpp>
+#include <com/sun/star/lang/XEventListener.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/lang/XTypeProvider.hpp>
+
+#include <cppuhelper/supportsservice.hxx>
+#include <cppuhelper/queryinterface.hxx>
+#include <cppuhelper/typeprovider.hxx>
+#include <cppuhelper/weak.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <vcl/wrkwin.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/syswin.hxx>
+
+#include <sfx2/notebookbar/SfxNotebookBar.hxx>
+
+namespace {
+
+/**
+ implements the backing component.
+
+ This component is a special one, which doesn't provide a controller
+ nor a model. It supports the following features:
+ - Drag & Drop
+ - Key Accelerators
+ - Simple Menu
+ - Progress Bar
+ - Background
+ */
+class BackingComp : public css::lang::XTypeProvider
+ , public css::lang::XServiceInfo
+ , public css::lang::XInitialization
+ , public css::frame::XController // => XComponent
+ , public css::awt::XKeyListener // => XEventListener
+ , public css::frame::XDispatchProvider
+ , public css::frame::XDispatch
+ , public ::cppu::OWeakObject
+{
+private:
+ /** reference to the component window. */
+ css::uno::Reference< css::awt::XWindow > m_xWindow;
+
+ /** the owner frame of this component. */
+ css::uno::Reference< css::frame::XFrame > m_xFrame;
+
+ Size m_aInitialWindowMinSize;
+
+public:
+
+ explicit BackingComp();
+
+ // XInterface
+ virtual css::uno::Any SAL_CALL queryInterface( const css::uno::Type& aType ) override;
+ virtual void SAL_CALL acquire ( ) noexcept override;
+ virtual void SAL_CALL release ( ) noexcept override;
+
+ // XTypeProvide
+ virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes () override;
+ virtual css::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() override;
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName ( ) override;
+ virtual sal_Bool SAL_CALL supportsService ( const OUString& sServiceName ) override;
+ virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames( ) override;
+
+ // XInitialization
+ virtual void SAL_CALL initialize( const css::uno::Sequence< css::uno::Any >& lArgs ) override;
+
+ // XController
+ virtual void SAL_CALL attachFrame( const css::uno::Reference< css::frame::XFrame >& xFrame ) override;
+ virtual sal_Bool SAL_CALL attachModel( const css::uno::Reference< css::frame::XModel >& xModel ) override;
+ virtual sal_Bool SAL_CALL suspend( sal_Bool bSuspend ) override;
+ virtual css::uno::Any SAL_CALL getViewData() override;
+ virtual void SAL_CALL restoreViewData( const css::uno::Any& aData ) override;
+ virtual css::uno::Reference< css::frame::XModel > SAL_CALL getModel() override;
+ virtual css::uno::Reference< css::frame::XFrame > SAL_CALL getFrame() override;
+
+ // XKeyListener
+ virtual void SAL_CALL keyPressed ( const css::awt::KeyEvent& aEvent ) override;
+ virtual void SAL_CALL keyReleased( const css::awt::KeyEvent& aEvent ) override;
+
+ // XEventListener
+ virtual void SAL_CALL disposing( const css::lang::EventObject& aEvent ) override;
+
+ // XComponent
+ virtual void SAL_CALL dispose ( ) override;
+ virtual void SAL_CALL addEventListener ( const css::uno::Reference< css::lang::XEventListener >& xListener ) override;
+ virtual void SAL_CALL removeEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener ) override;
+
+ // XDispatchProvider
+ virtual css::uno::Reference< css::frame::XDispatch > SAL_CALL queryDispatch( const css::util::URL& aURL, const OUString& sTargetFrameName , sal_Int32 nSearchFlags ) override;
+ virtual css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > SAL_CALL queryDispatches( const css::uno::Sequence< css::frame::DispatchDescriptor >& lDescriptions ) override;
+
+ // XDispatch
+ virtual void SAL_CALL dispatch( const css::util::URL& aURL, const css::uno::Sequence< css::beans::PropertyValue >& lArguments ) override;
+ virtual void SAL_CALL addStatusListener( const css::uno::Reference< css::frame::XStatusListener >& xListener, const css::util::URL& aURL ) override;
+ virtual void SAL_CALL removeStatusListener( const css::uno::Reference< css::frame::XStatusListener >& xListener, const css::util::URL& aURL ) override;
+};
+
+BackingComp::BackingComp()
+{
+}
+
+/** return information about supported interfaces.
+
+ Some interfaces are supported by his class directly, but some other ones are
+ used by aggregation. An instance of this class must provide some window interfaces.
+ But it must represent a VCL window behind such interfaces too! So we use an internal
+ saved window member to ask it for its interfaces and return it. But we must be aware then,
+ that it can be destroyed from outside too ...
+
+ @param aType
+ describe the required interface type
+
+ @return An Any holding the instance, which provides the queried interface.
+ Note: There exist two possible results ... this instance itself and her window member!
+ */
+
+css::uno::Any SAL_CALL BackingComp::queryInterface( /*IN*/ const css::uno::Type& aType )
+{
+ // first look for own supported interfaces
+ css::uno::Any aResult = ::cppu::queryInterface(
+ aType,
+ static_cast< css::lang::XTypeProvider* >(this),
+ static_cast< css::lang::XServiceInfo* >(this),
+ static_cast< css::lang::XInitialization* >(this),
+ static_cast< css::frame::XController* >(this),
+ static_cast< css::lang::XComponent* >(this),
+ static_cast< css::lang::XEventListener* >(this),
+ static_cast< css::awt::XKeyListener* >(static_cast< css::lang::XEventListener* >(this)),
+ static_cast< css::frame::XDispatchProvider* >(this),
+ static_cast< css::frame::XDispatch* >(this) );
+
+ // then look for supported window interfaces
+ // Note: They exist only, if this instance was initialized
+ // with a valid window reference. It's aggregation on demand ...
+ if (!aResult.hasValue())
+ {
+ /* SAFE { */
+ SolarMutexGuard aGuard;
+ if (m_xWindow.is())
+ aResult = m_xWindow->queryInterface(aType);
+ /* } SAFE */
+ }
+
+ // look for XWeak and XInterface
+ if (!aResult.hasValue())
+ aResult = OWeakObject::queryInterface(aType);
+
+ return aResult;
+}
+
+
+/** increase ref count of this instance.
+ */
+
+void SAL_CALL BackingComp::acquire()
+ noexcept
+{
+ OWeakObject::acquire();
+}
+
+
+/** decrease ref count of this instance.
+ */
+
+void SAL_CALL BackingComp::release()
+ noexcept
+{
+ OWeakObject::release();
+}
+
+
+/** return collection about all supported interfaces.
+
+ Optimize this method !
+ We initialize a static variable only one time.
+ And we don't must use a mutex at every call!
+ For the first call; pTypeCollection is NULL -
+ for the second call pTypeCollection is different from NULL!
+
+ @return A list of all supported interface types.
+*/
+
+css::uno::Sequence< css::uno::Type > SAL_CALL BackingComp::getTypes()
+{
+ static cppu::OTypeCollection aTypeCollection = [this]() {
+ SolarMutexGuard aGuard;
+ css::uno::Reference<css::lang::XTypeProvider> xProvider(m_xWindow, css::uno::UNO_QUERY);
+
+ css::uno::Sequence<css::uno::Type> lWindowTypes;
+ if (xProvider.is())
+ lWindowTypes = xProvider->getTypes();
+
+ return cppu::OTypeCollection(
+ cppu::UnoType<css::lang::XInitialization>::get(),
+ cppu::UnoType<css::lang::XTypeProvider>::get(),
+ cppu::UnoType<css::lang::XServiceInfo>::get(),
+ cppu::UnoType<css::frame::XController>::get(),
+ cppu::UnoType<css::lang::XComponent>::get(),
+ cppu::UnoType<css::frame::XDispatchProvider>::get(),
+ cppu::UnoType<css::frame::XDispatch>::get(), lWindowTypes);
+ }();
+
+ return aTypeCollection.getTypes();
+}
+
+
+/** create one unique Id for all instances of this class.
+
+ Optimize this method
+ We initialize a static variable only one time. And we don't must use a mutex at every call!
+ For the first call; pID is NULL - for the second call pID is different from NULL!
+
+ @return A byte array, which represent the unique id.
+*/
+
+css::uno::Sequence< sal_Int8 > SAL_CALL BackingComp::getImplementationId()
+{
+ return css::uno::Sequence<sal_Int8>();
+}
+
+OUString SAL_CALL BackingComp::getImplementationName()
+{
+ return "com.sun.star.comp.sfx2.BackingComp";
+}
+
+sal_Bool SAL_CALL BackingComp::supportsService( /*IN*/ const OUString& sServiceName )
+{
+ return cppu::supportsService(this, sServiceName);
+}
+
+css::uno::Sequence< OUString > SAL_CALL BackingComp::getSupportedServiceNames()
+{
+ return { "com.sun.star.frame.StartModule", "com.sun.star.frame.ProtocolHandler" };
+}
+
+
+/**
+ attach this component to a target frame.
+
+ We have to use the container window of this frame as parent window of our own component window.
+ But it's not allowed to work with it really. May another component used it too.
+ Currently we need it only to create our child component window and support it's
+ interfaces inside our queryInterface() method. The user of us must have e.g. the
+ XWindow interface of it to be able to call setComponent(xWindow,xController) at the
+ frame!
+
+ May he will do the following things:
+
+ <listing>
+ XController xBackingComp = (XController)UnoRuntime.queryInterface(
+ XController.class,
+ xSMGR.createInstance(SERVICENAME_STARTMODULE));
+
+ // at this time XWindow isn't present at this instance!
+ XWindow xBackingComp = (XWindow)UnoRuntime.queryInterface(
+ XWindow.class,
+ xBackingComp);
+
+ // attach controller to the frame
+ // We will use its container window, to create
+ // the component window. From now we offer the window interfaces!
+ xBackingComp.attachFrame(xFrame);
+
+ XWindow xBackingComp = (XWindow)UnoRuntime.queryInterface(
+ XWindow.class,
+ xBackingComp);
+
+ // Our user can set us at the frame as new component
+ xFrame.setComponent(xBackingWin, xBackingComp);
+
+ // But that had no effect to our view state.
+ // We must be started to create our UI elements like e.g. menu, title, background ...
+ XInitialization xBackingInit = (XInitialization)UnoRuntime.queryInterface(
+ XInitialization.class,
+ xBackingComp);
+
+ xBackingInit.initialize(lArgs);
+ </listing>
+
+ @param xFrame
+ reference to our new target frame
+
+ @throw css::uno::RuntimeException
+ if the given frame reference is wrong or component window couldn't be created
+ successfully.
+ We throw it too, if we already attached to a frame. Because we don't support
+ reparenting of our component window on demand!
+*/
+
+void SAL_CALL BackingComp::attachFrame( /*IN*/ const css::uno::Reference< css::frame::XFrame >& xFrame )
+{
+ /* SAFE */
+ SolarMutexGuard aGuard;
+
+ // check some required states
+ if (m_xFrame.is())
+ throw css::uno::RuntimeException(
+ "already attached",
+ getXWeak());
+
+ if (!xFrame.is())
+ throw css::uno::RuntimeException(
+ "invalid frame reference",
+ getXWeak());
+
+ if (!m_xWindow.is())
+ return; // disposed
+
+ // safe the frame reference
+ m_xFrame = xFrame;
+
+ // initialize the component and its parent window
+ css::uno::Reference< css::awt::XWindow > xParentWindow = xFrame->getContainerWindow();
+ VclPtr< WorkWindow > pParent = static_cast<WorkWindow*>(VCLUnoHelper::GetWindow(xParentWindow));
+ VclPtr< vcl::Window > pWindow = VCLUnoHelper::GetWindow(m_xWindow);
+
+ // disable full screen mode of the frame!
+ if (pParent && pParent->IsFullScreenMode())
+ {
+ pParent->ShowFullScreenMode(false);
+ pParent->SetMenuBarMode(MenuBarMode::Normal);
+ }
+
+ // create the menu bar for the backing component
+ css::uno::Reference< css::beans::XPropertySet > xPropSet(m_xFrame, css::uno::UNO_QUERY_THROW);
+ css::uno::Reference< css::frame::XLayoutManager > xLayoutManager;
+ xPropSet->getPropertyValue("LayoutManager") >>= xLayoutManager;
+ if (xLayoutManager.is())
+ {
+ xLayoutManager->lock();
+ xLayoutManager->createElement("private:resource/menubar/menubar");
+ xLayoutManager->unlock();
+ }
+
+ if (pWindow)
+ {
+ // set help ID for our canvas
+ pWindow->SetHelpId("FWK_HID_BACKINGWINDOW");
+ }
+
+ // inform BackingWindow about frame
+ BackingWindow* pBack = dynamic_cast<BackingWindow*>(pWindow.get());
+ if( pBack )
+ pBack->setOwningFrame( m_xFrame );
+
+ // Set a minimum size for Start Center
+ if( !pParent || !pBack )
+ return;
+
+ tools::Long nMenuHeight = 0;
+ vcl::Window* pMenu = pParent->GetWindow(GetWindowType::Next);
+ if( pMenu )
+ nMenuHeight = pMenu->GetSizePixel().Height();
+
+ m_aInitialWindowMinSize = pParent->GetMinOutputSizePixel();
+ if (!m_aInitialWindowMinSize.Width())
+ m_aInitialWindowMinSize.AdjustWidth(1);
+ if (!m_aInitialWindowMinSize.Height())
+ m_aInitialWindowMinSize.AdjustHeight(1);
+
+ pParent->SetMinOutputSizePixel(
+ Size(
+ pBack->get_width_request(),
+ pBack->get_height_request() + nMenuHeight));
+
+ /* } SAFE */
+}
+
+
+/** not supported.
+
+ This component does not know any model. It will be represented by a window and
+ its controller only.
+
+ return <FALSE/> every time.
+ */
+
+sal_Bool SAL_CALL BackingComp::attachModel( /*IN*/ const css::uno::Reference< css::frame::XModel >& )
+{
+ return false;
+}
+
+
+/** not supported.
+
+ This component does not know any model. It will be represented by a window and
+ its controller only.
+
+ return An empty reference every time.
+ */
+
+css::uno::Reference< css::frame::XModel > SAL_CALL BackingComp::getModel()
+{
+ return css::uno::Reference< css::frame::XModel >();
+}
+
+
+/** not supported.
+
+ return An empty value.
+ */
+
+css::uno::Any SAL_CALL BackingComp::getViewData()
+{
+ return css::uno::Any();
+}
+
+
+/** not supported.
+
+ @param aData
+ not used.
+ */
+
+void SAL_CALL BackingComp::restoreViewData( /*IN*/ const css::uno::Any& )
+{
+}
+
+
+/** returns the attached frame for this component.
+
+ @see attachFrame()
+
+ @return The internally saved frame reference.
+ Can be null, if attachFrame() was not called before.
+ */
+
+css::uno::Reference< css::frame::XFrame > SAL_CALL BackingComp::getFrame()
+{
+ /* SAFE { */
+ SolarMutexGuard aGuard;
+ return m_xFrame;
+ /* } SAFE */
+}
+
+
+/** ask controller for its current working state.
+
+ If someone wishes to close this component, it must suspend the controller before.
+ That will be a chance for it to disagree with that AND show any UI for a possible
+ UI user.
+
+ @param bSuspend
+ If it's set to sal_True this controller should be suspended.
+ sal_False will resuspend it.
+
+ @return sal_True if the request could be finished successfully; sal_False otherwise.
+ */
+
+sal_Bool SAL_CALL BackingComp::suspend( /*IN*/ sal_Bool )
+{
+ /* FIXME ... implemented by using default :-( */
+ return true;
+}
+
+
+/** callback from our window member.
+
+ Our internal saved window wish to die. It will be disposed from outside (may be the frame)
+ and inform us. We must release its reference only here. Of course we check the given reference
+ here and reject callback from unknown sources.
+
+ Note: deregistration as listener isn't necessary here. The broadcaster do it automatically.
+
+ @param aEvent
+ describe the broadcaster of this callback
+
+ @throw css::uno::RuntimeException
+ if the broadcaster doesn't represent the expected window reference.
+*/
+
+void SAL_CALL BackingComp::disposing( /*IN*/ const css::lang::EventObject& aEvent )
+{
+ // Attention: don't free m_pAccExec here! see comments inside dtor and
+ // keyPressed() for further details.
+
+ /* SAFE { */
+ SolarMutexGuard aGuard;
+
+ if (!aEvent.Source.is() || aEvent.Source!=m_xWindow || !m_xWindow.is())
+ throw css::uno::RuntimeException(
+ "unexpected source or called twice",
+ getXWeak());
+
+ m_xWindow.clear();
+
+ /* } SAFE */
+}
+
+
+/** kill this instance.
+
+ It can be called from our owner frame only. But there is no possibility to check the caller.
+ We have to release all our internal used resources and die. From this point we can throw
+ DisposedExceptions for every further interface request... but current implementation doesn't do so...
+
+*/
+
+void SAL_CALL BackingComp::dispose()
+{
+ /* SAFE { */
+ SolarMutexGuard aGuard;
+
+ if (m_xFrame.is())
+ {
+ css::uno::Reference< css::awt::XWindow > xParentWindow = m_xFrame->getContainerWindow();
+ VclPtr< WorkWindow > pParent = static_cast<WorkWindow*>(VCLUnoHelper::GetWindow(xParentWindow));
+ if (pParent)
+ {
+ pParent->SetMinOutputSizePixel(m_aInitialWindowMinSize);
+ // hide NotebookBar
+ sfx2::SfxNotebookBar::CloseMethod(static_cast<SystemWindow*>(pParent));
+ }
+ }
+
+ // stop listening at the window
+ if (m_xWindow.is())
+ {
+ m_xWindow->removeEventListener(this);
+ m_xWindow->removeKeyListener(this);
+ m_xWindow.clear();
+ }
+
+ // forget all other used references
+ m_xFrame.clear();
+
+ /* } SAFE */
+}
+
+
+/** not supported.
+
+ @param xListener
+ not used.
+
+ @throw css::uno::RuntimeException
+ because the listener expect to be holded alive by this container.
+ We must inform it about this unsupported feature.
+ */
+
+void SAL_CALL BackingComp::addEventListener( /*IN*/ const css::uno::Reference< css::lang::XEventListener >& )
+{
+ throw css::uno::RuntimeException(
+ "not supported",
+ getXWeak());
+}
+
+
+/** not supported.
+
+ Because registration is not supported too, we must do nothing here. Nobody can call this method really.
+
+ @param xListener
+ not used.
+ */
+
+void SAL_CALL BackingComp::removeEventListener( /*IN*/ const css::uno::Reference< css::lang::XEventListener >& )
+{
+}
+
+
+/**
+ force initialization for this component.
+
+ Inside attachFrame() we created our component window. But it was not allowed there, to
+ initialize it. E.g. the menu must be set at the container window of the frame, which
+ is our parent window. But may at that time another component used it.
+ That's why our creator has to inform us, when it's time to initialize us really.
+ Currently only calling of this method must be done. But further implementations
+ can use special in parameter to configure this initialization...
+
+ @param lArgs
+ currently not used
+
+ @throw css::uno::RuntimeException
+ if some resources are missing
+ Means if may be attachedFrame() wasn't called before.
+ */
+
+void SAL_CALL BackingComp::initialize( /*IN*/ const css::uno::Sequence< css::uno::Any >& lArgs )
+{
+ /* SAFE { */
+ SolarMutexGuard aGuard;
+
+ if (m_xWindow.is())
+ throw css::uno::Exception(
+ "already initialized",
+ getXWeak());
+
+ css::uno::Reference< css::awt::XWindow > xParentWindow;
+ if (
+ (lArgs.getLength()!=1 ) ||
+ (!(lArgs[0] >>= xParentWindow)) ||
+ (!xParentWindow.is() )
+ )
+ {
+ throw css::uno::Exception(
+ "wrong or corrupt argument list",
+ getXWeak());
+ }
+
+ // create the component window
+ VclPtr<vcl::Window> pParent = VCLUnoHelper::GetWindow(xParentWindow);
+ VclPtr<vcl::Window> pWindow = VclPtr<BackingWindow>::Create(pParent);
+ m_xWindow = VCLUnoHelper::GetInterface(pWindow);
+
+ if (!m_xWindow.is())
+ throw css::uno::RuntimeException(
+ "couldn't create component window",
+ getXWeak());
+
+ // start listening for window disposing
+ // It's set at our owner frame as component window later too. So it will may be disposed there ...
+ m_xWindow->addEventListener(static_cast< css::lang::XEventListener* >(this));
+
+ m_xWindow->setVisible(true);
+
+ /* } SAFE */
+}
+
+
+void SAL_CALL BackingComp::keyPressed( /*IN*/ const css::awt::KeyEvent& )
+{
+}
+
+
+void SAL_CALL BackingComp::keyReleased( /*IN*/ const css::awt::KeyEvent& )
+{
+ /* Attention
+ Please use keyPressed() instead of this method. Otherwise it would be possible, that
+ - a key input may be first switch to the backing mode
+ - and this component register itself as key listener too
+ - and it's first event will be a keyReleased() for the already well known event, which switched to the backing mode!
+ So it will be handled twice! document => backing mode => exit app...
+ */
+}
+
+// XDispatchProvider
+css::uno::Reference< css::frame::XDispatch > SAL_CALL BackingComp::queryDispatch( const css::util::URL& aURL, const OUString& /*sTargetFrameName*/, sal_Int32 /*nSearchFlags*/ )
+{
+ css::uno::Reference< css::frame::XDispatch > xDispatch;
+ if ( aURL.Protocol == "vnd.org.libreoffice.recentdocs:" )
+ xDispatch = this;
+
+ return xDispatch;
+}
+
+css::uno::Sequence < css::uno::Reference< css::frame::XDispatch > > SAL_CALL BackingComp::queryDispatches( const css::uno::Sequence < css::frame::DispatchDescriptor >& seqDescripts )
+{
+ sal_Int32 nCount = seqDescripts.getLength();
+ css::uno::Sequence < css::uno::Reference < XDispatch > > lDispatcher( nCount );
+
+ std::transform(seqDescripts.begin(), seqDescripts.end(), lDispatcher.getArray(),
+ [this](const css::frame::DispatchDescriptor& rDesc) -> css::uno::Reference<XDispatch> {
+ return queryDispatch(rDesc.FeatureURL, rDesc.FrameName, rDesc.SearchFlags); });
+
+ return lDispatcher;
+}
+
+// XDispatch
+void SAL_CALL BackingComp::dispatch( const css::util::URL& aURL, const css::uno::Sequence < css::beans::PropertyValue >& /*lArgs*/ )
+{
+ // vnd.org.libreoffice.recentdocs:ClearRecentFileList - clear recent files
+ if ( aURL.Path != "ClearRecentFileList" )
+ return;
+
+ VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow(m_xWindow);
+ BackingWindow* pBack = dynamic_cast<BackingWindow*>(pWindow.get());
+ if( !pBack )
+ return;
+
+ pBack->clearRecentFileList();
+
+ // Recalculate minimum width
+ css::uno::Reference< css::awt::XWindow > xParentWindow = m_xFrame->getContainerWindow();
+ VclPtr< WorkWindow > pParent = static_cast<WorkWindow*>(VCLUnoHelper::GetWindow(xParentWindow));
+ if( pParent )
+ {
+ pParent->SetMinOutputSizePixel( Size(
+ pBack->get_width_request(),
+ pParent->GetMinOutputSizePixel().Height()) );
+ }
+}
+
+void SAL_CALL BackingComp::addStatusListener( const css::uno::Reference< css::frame::XStatusListener >& /*xControl*/, const css::util::URL& /*aURL*/ )
+{
+}
+
+void SAL_CALL BackingComp::removeStatusListener( const css::uno::Reference< css::frame::XStatusListener >& /*xControl*/, const css::util::URL& /*aURL*/ )
+{
+}
+
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
+com_sun_star_comp_sfx2_BackingComp_get_implementation(
+ css::uno::XComponentContext *,
+ css::uno::Sequence<css::uno::Any> const &)
+{
+ return cppu::acquire(new BackingComp);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */