diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
commit | ed5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch) | |
tree | 7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /sd/source/ui/unoidl | |
parent | Initial commit. (diff) | |
download | libreoffice-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 'sd/source/ui/unoidl')
27 files changed, 15490 insertions, 0 deletions
diff --git a/sd/source/ui/unoidl/DrawController.cxx b/sd/source/ui/unoidl/DrawController.cxx new file mode 100644 index 000000000..e4afc842a --- /dev/null +++ b/sd/source/ui/unoidl/DrawController.cxx @@ -0,0 +1,815 @@ +/* -*- 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 <DrawController.hxx> + +#include <sdpage.hxx> +#include <ViewShell.hxx> +#include <ViewShellBase.hxx> +#include <ViewShellManager.hxx> +#include <FormShellManager.hxx> +#include <Window.hxx> + +#include <comphelper/processfactory.hxx> +#include <comphelper/sequence.hxx> +#include <comphelper/servicehelper.hxx> +#include <cppuhelper/supportsservice.hxx> +#include <cppuhelper/typeprovider.hxx> + +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <com/sun/star/drawing/framework/ConfigurationController.hpp> +#include <com/sun/star/drawing/framework/ModuleController.hpp> +#include <com/sun/star/drawing/XDrawSubController.hpp> +#include <com/sun/star/drawing/XLayer.hpp> + +#include <slideshow.hxx> + +#include <sal/log.hxx> +#include <svx/fmshell.hxx> +#include <vcl/svapp.hxx> +#include <vcl/EnumContext.hxx> +#include <svx/sidebar/ContextChangeEventMultiplexer.hxx> +#include <tools/diagnose_ex.h> + +#include <memory> + +using namespace ::std; +using namespace ::cppu; +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::drawing::framework; +using vcl::EnumContext; + +namespace sd { + +DrawController::DrawController (ViewShellBase& rBase) noexcept + : DrawControllerInterfaceBase(&rBase), + BroadcastHelperOwner(SfxBaseController::m_aMutex), + OPropertySetHelper(BroadcastHelperOwner::maBroadcastHelper), + mpCurrentLayer(nullptr), + m_aSelectionTypeIdentifier( + cppu::UnoType<view::XSelectionChangeListener>::get()), + mpBase(&rBase), + mpCurrentPage(nullptr), + mbMasterPageMode(false), + mbLayerMode(false), + mbDisposing(false) +{ + ProvideFrameworkControllers(); +} + +DrawController::~DrawController() noexcept +{ +} + +void DrawController::SetSubController ( + const Reference<drawing::XDrawSubController>& rxSubController) +{ + // Update the internal state. + mxSubController = rxSubController; + mpPropertyArrayHelper.reset(); + maLastVisArea = ::tools::Rectangle(); + + // Inform listeners about the changed state. + FireSelectionChangeListener(); +} + +// XInterface + +IMPLEMENT_FORWARD_XINTERFACE2( + DrawController, + DrawControllerInterfaceBase, + OPropertySetHelper); + +// XTypeProvider + +Sequence<Type> SAL_CALL DrawController::getTypes() +{ + ThrowIfDisposed(); + // OPropertySetHelper does not provide getTypes, so we have to + // implement this method manually and list its three interfaces. + OTypeCollection aTypeCollection ( + cppu::UnoType<beans::XMultiPropertySet>::get(), + cppu::UnoType<beans::XFastPropertySet>::get(), + cppu::UnoType<beans::XPropertySet>::get()); + + return ::comphelper::concatSequences( + SfxBaseController::getTypes(), + aTypeCollection.getTypes(), + DrawControllerInterfaceBase::getTypes()); +} + +IMPLEMENT_GET_IMPLEMENTATION_ID(DrawController); + +// XComponent + +void SAL_CALL DrawController::dispose() +{ + if( mbDisposing ) + return; + + SolarMutexGuard aGuard; + + if( mbDisposing ) + return; + + mbDisposing = true; + + std::shared_ptr<ViewShell> pViewShell; + if (mpBase) + pViewShell = mpBase->GetMainViewShell(); + if ( pViewShell ) + { + pViewShell->DeactivateCurrentFunction(); + auto* pView = pViewShell->GetView(); + if (pView) + pView->getSearchContext().resetSearchFunction(); + } + pViewShell.reset(); + + // When the controller has not been detached from its view + // shell, i.e. mpViewShell is not NULL, then tell PaneManager + // and ViewShellManager to clear the shell stack. + if (mxSubController.is() && mpBase!=nullptr) + { + mpBase->DisconnectAllClients(); + mpBase->GetViewShellManager()->Shutdown(); + } + + OPropertySetHelper::disposing(); + + DisposeFrameworkControllers(); + + SfxBaseController::dispose(); +} + +void SAL_CALL DrawController::addEventListener( + const Reference<lang::XEventListener >& xListener) +{ + ThrowIfDisposed(); + SfxBaseController::addEventListener( xListener ); +} + +void SAL_CALL DrawController::removeEventListener ( + const Reference<lang::XEventListener >& aListener) +{ + if(!rBHelper.bDisposed && !rBHelper.bInDispose && !mbDisposing) + SfxBaseController::removeEventListener( aListener ); +} + +// XController +sal_Bool SAL_CALL DrawController::suspend( sal_Bool Suspend ) +{ + if( Suspend ) + { + ViewShellBase* pViewShellBase = GetViewShellBase(); + if( pViewShellBase ) + { + // do not allow suspend if a slideshow needs this controller! + rtl::Reference< SlideShow > xSlideShow( SlideShow::GetSlideShow( *pViewShellBase ) ); + if( xSlideShow.is() && xSlideShow->dependsOn(pViewShellBase) ) + return false; + } + } + + return SfxBaseController::suspend( Suspend ); +} + +// XServiceInfo +OUString SAL_CALL DrawController::getImplementationName( ) +{ + // Do not throw an exception at the moment. This leads to a crash + // under Solaris on reload. See issue i70929 for details. + // ThrowIfDisposed(); + return "DrawController" ; +} + +constexpr OUStringLiteral ssServiceName = u"com.sun.star.drawing.DrawingDocumentDrawView"; + +sal_Bool SAL_CALL DrawController::supportsService (const OUString& rsServiceName) +{ + return cppu::supportsService(this, rsServiceName); +} + +Sequence<OUString> SAL_CALL DrawController::getSupportedServiceNames() +{ + ThrowIfDisposed(); + Sequence<OUString> aSupportedServices { ssServiceName }; + return aSupportedServices; +} + +//------ XSelectionSupplier -------------------------------------------- +sal_Bool SAL_CALL DrawController::select (const Any& aSelection) +{ + ThrowIfDisposed(); + SolarMutexGuard aGuard; + + if (mxSubController.is()) + return mxSubController->select(aSelection); + else + return false; +} + +Any SAL_CALL DrawController::getSelection() +{ + ThrowIfDisposed(); + SolarMutexGuard aGuard; + + if (mxSubController.is()) + return mxSubController->getSelection(); + else + return Any(); +} + +void SAL_CALL DrawController::addSelectionChangeListener( + const Reference< view::XSelectionChangeListener >& xListener) +{ + if( mbDisposing ) + throw lang::DisposedException(); + + BroadcastHelperOwner::maBroadcastHelper.addListener (m_aSelectionTypeIdentifier, xListener); +} + +void SAL_CALL DrawController::removeSelectionChangeListener( + const Reference< view::XSelectionChangeListener >& xListener ) +{ + if (rBHelper.bDisposed) + throw lang::DisposedException(); + + BroadcastHelperOwner::maBroadcastHelper.removeListener (m_aSelectionTypeIdentifier, xListener); +} + +//===== lang::XEventListener ================================================ + +void SAL_CALL + DrawController::disposing (const lang::EventObject& ) +{ +} + +//===== view::XSelectionChangeListener ====================================== + +void SAL_CALL + DrawController::selectionChanged (const lang::EventObject& rEvent) +{ + ThrowIfDisposed(); + // Have to forward the event to our selection change listeners. + OInterfaceContainerHelper* pListeners = BroadcastHelperOwner::maBroadcastHelper.getContainer( + cppu::UnoType<view::XSelectionChangeListener>::get()); + if (!pListeners) + return; + + // Re-send the event to all of our listeners. + OInterfaceIteratorHelper aIterator (*pListeners); + while (aIterator.hasMoreElements()) + { + try + { + view::XSelectionChangeListener* pListener = + static_cast<view::XSelectionChangeListener*>( + aIterator.next()); + if (pListener != nullptr) + pListener->selectionChanged (rEvent); + } + catch (const RuntimeException&) + { + } + } +} + +// XDrawView + +void SAL_CALL DrawController::setCurrentPage( const Reference< drawing::XDrawPage >& xPage ) +{ + ThrowIfDisposed(); + SolarMutexGuard aGuard; + + if (mxSubController.is()) + mxSubController->setCurrentPage(xPage); +} + +Reference< drawing::XDrawPage > SAL_CALL DrawController::getCurrentPage() +{ + ThrowIfDisposed(); + SolarMutexGuard aGuard; + Reference<drawing::XDrawPage> xPage; + + // Get current page from sub controller. + if (mxSubController.is()) + xPage = mxSubController->getCurrentPage(); + + // When there is not yet a sub controller (during initialization) then fall back + // to the current page in mpCurrentPage. + if ( ! xPage.is() ) + if (rtl::Reference<SdPage> pPage = mpCurrentPage.get()) + xPage.set(pPage->getUnoPage(), UNO_QUERY); + + return xPage; +} + +void DrawController::FireVisAreaChanged (const ::tools::Rectangle& rVisArea) noexcept +{ + if( maLastVisArea == rVisArea ) + return; + + Any aNewValue; + aNewValue <<= awt::Rectangle( + rVisArea.Left(), + rVisArea.Top(), + rVisArea.GetWidth(), + rVisArea.GetHeight() ); + + Any aOldValue; + aOldValue <<= awt::Rectangle( + maLastVisArea.Left(), + maLastVisArea.Top(), + maLastVisArea.GetWidth(), + maLastVisArea.GetHeight() ); + + FirePropertyChange (PROPERTY_WORKAREA, aNewValue, aOldValue); + + maLastVisArea = rVisArea; +} + +void DrawController::FireSelectionChangeListener() noexcept +{ + OInterfaceContainerHelper * pLC = BroadcastHelperOwner::maBroadcastHelper.getContainer( + m_aSelectionTypeIdentifier); + if( !pLC ) + return; + + Reference< XInterface > xSource( static_cast<XWeak*>(this) ); + const lang::EventObject aEvent( xSource ); + + // iterate over all listeners and send events + OInterfaceIteratorHelper aIt( *pLC); + while( aIt.hasMoreElements() ) + { + try + { + view::XSelectionChangeListener * pL = + static_cast<view::XSelectionChangeListener*>(aIt.next()); + if (pL != nullptr) + pL->selectionChanged( aEvent ); + } + catch (const RuntimeException&) + { + } + } +} + +void DrawController::FireChangeEditMode (bool bMasterPageMode) noexcept +{ + if (bMasterPageMode != mbMasterPageMode ) + { + FirePropertyChange( + PROPERTY_MASTERPAGEMODE, + Any(bMasterPageMode), + Any(mbMasterPageMode)); + + mbMasterPageMode = bMasterPageMode; + } +} + +void DrawController::FireChangeLayerMode (bool bLayerMode) noexcept +{ + if (bLayerMode != mbLayerMode) + { + FirePropertyChange( + PROPERTY_LAYERMODE, + Any(bLayerMode), + Any(mbLayerMode)); + + mbLayerMode = bLayerMode; + } +} + +void DrawController::FireSwitchCurrentPage (SdPage* pNewCurrentPage) noexcept +{ + rtl::Reference<SdrPage> pCurrentPage = mpCurrentPage.get(); + if (pNewCurrentPage == pCurrentPage.get()) + return; + + try + { + Any aNewValue ( + Any(Reference<drawing::XDrawPage>(pNewCurrentPage->getUnoPage(), UNO_QUERY))); + + Any aOldValue; + if (pCurrentPage != nullptr) + { + Reference<drawing::XDrawPage> xOldPage (pCurrentPage->getUnoPage(), UNO_QUERY); + aOldValue <<= xOldPage; + } + + FirePropertyChange(PROPERTY_CURRENTPAGE, aNewValue, aOldValue); + + mpCurrentPage = pNewCurrentPage; + } + catch (const uno::Exception&) + { + TOOLS_WARN_EXCEPTION("sd", "sd::SdUnoDrawView::FireSwitchCurrentPage()"); + } +} + +void DrawController::NotifyAccUpdate() +{ + sal_Int32 nHandle = PROPERTY_UPDATEACC; + Any aNewValue, aOldValue; + fire (&nHandle, &aNewValue, &aOldValue, 1, false); +} + +void DrawController::fireChangeLayer( css::uno::Reference< css::drawing::XLayer>* pCurrentLayer ) noexcept +{ + if( pCurrentLayer != mpCurrentLayer ) + { + sal_Int32 nHandle = PROPERTY_ACTIVE_LAYER; + + Any aNewValue ( *pCurrentLayer); + + Any aOldValue ; + + fire (&nHandle, &aNewValue, &aOldValue, 1, false); + + mpCurrentLayer = pCurrentLayer; + } +} + +// This method is only called in slide show and outline view +//void DrawController::fireSwitchCurrentPage(String pageName ) throw() +void DrawController::fireSwitchCurrentPage(sal_Int32 pageIndex ) noexcept +{ + Any aNewValue; + Any aOldValue; + //OUString aPageName( pageName ); + //aNewValue <<= aPageName ; + aNewValue <<= pageIndex; + + // Use new property to handle page change event + sal_Int32 nHandles = PROPERTY_PAGE_CHANGE; + fire( &nHandles, &aNewValue, &aOldValue, 1, false ); +} + +void DrawController::FirePropertyChange ( + sal_Int32 nHandle, + const Any& rNewValue, + const Any& rOldValue) +{ + try + { + fire (&nHandle, &rNewValue, &rOldValue, 1, false); + } + catch (const RuntimeException&) + { + // Ignore this exception. Exceptions should be handled in the + // fire() function so that all listeners are called. This is + // not the case at the moment, so we simply ignore the + // exception. + } + +} + +void DrawController::BroadcastContextChange() const +{ + std::shared_ptr<ViewShell> pViewShell (mpBase->GetMainViewShell()); + if ( ! pViewShell) + return; + + EnumContext::Context eContext (EnumContext::Context::Unknown); + switch (pViewShell->GetShellType()) + { + case ViewShell::ST_IMPRESS: + case ViewShell::ST_DRAW: + if (mbMasterPageMode) + eContext = EnumContext::Context::MasterPage; + else + eContext = EnumContext::Context::DrawPage; + break; + + case ViewShell::ST_NOTES: + eContext = EnumContext::Context::NotesPage; + break; + + case ViewShell::ST_HANDOUT: + eContext = EnumContext::Context::HandoutPage; + break; + + case ViewShell::ST_OUTLINE: + eContext = EnumContext::Context::OutlineText; + break; + + case ViewShell::ST_SLIDE_SORTER: + eContext = EnumContext::Context::SlidesorterPage; + break; + + case ViewShell::ST_PRESENTATION: + case ViewShell::ST_NONE: + default: + eContext = EnumContext::Context::Empty; + break; + } + + ContextChangeEventMultiplexer::NotifyContextChange(mpBase, eContext); +} + +void DrawController::ReleaseViewShellBase() +{ + DisposeFrameworkControllers(); + mpBase = nullptr; +} + +//===== XControllerManager ============================================================== + +Reference<XConfigurationController> SAL_CALL + DrawController::getConfigurationController() +{ + ThrowIfDisposed(); + + return mxConfigurationController; +} + +Reference<XModuleController> SAL_CALL + DrawController::getModuleController() +{ + ThrowIfDisposed(); + + return mxModuleController; +} + +//===== XUnoTunnel ============================================================ + +const Sequence<sal_Int8>& DrawController::getUnoTunnelId() +{ + static const comphelper::UnoIdInit theDrawControllerUnoTunnelId; + return theDrawControllerUnoTunnelId.getSeq(); +} + +sal_Int64 SAL_CALL DrawController::getSomething (const Sequence<sal_Int8>& rId) +{ + return comphelper::getSomethingImpl(rId, this); +} + +//===== Properties ============================================================ + +void DrawController::FillPropertyTable ( + ::std::vector<beans::Property>& rProperties) +{ + rProperties.emplace_back("VisibleArea", + PROPERTY_WORKAREA, + ::cppu::UnoType< css::awt::Rectangle>::get(), + beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY); + rProperties.emplace_back( + "SubController", + PROPERTY_SUB_CONTROLLER, + cppu::UnoType<drawing::XDrawSubController>::get(), + beans::PropertyAttribute::BOUND); + rProperties.emplace_back( + "CurrentPage", + PROPERTY_CURRENTPAGE, + cppu::UnoType<drawing::XDrawPage>::get(), + beans::PropertyAttribute::BOUND ); + rProperties.emplace_back("IsLayerMode", + PROPERTY_LAYERMODE, + cppu::UnoType<bool>::get(), + beans::PropertyAttribute::BOUND ); + rProperties.emplace_back("IsMasterPageMode", + PROPERTY_MASTERPAGEMODE, + cppu::UnoType<bool>::get(), + beans::PropertyAttribute::BOUND ); + rProperties.emplace_back("ActiveLayer", + PROPERTY_ACTIVE_LAYER, + cppu::UnoType<drawing::XLayer>::get(), + beans::PropertyAttribute::BOUND ); + rProperties.emplace_back("ZoomValue", + PROPERTY_ZOOMVALUE, + ::cppu::UnoType<sal_Int16>::get(), + beans::PropertyAttribute::BOUND ); + rProperties.emplace_back("ZoomType", + PROPERTY_ZOOMTYPE, + ::cppu::UnoType<sal_Int16>::get(), + beans::PropertyAttribute::BOUND ); + rProperties.emplace_back("ViewOffset", + PROPERTY_VIEWOFFSET, + ::cppu::UnoType< css::awt::Point>::get(), + beans::PropertyAttribute::BOUND ); + rProperties.emplace_back("DrawViewMode", + PROPERTY_DRAWVIEWMODE, + ::cppu::UnoType< css::awt::Point>::get(), + beans::PropertyAttribute::BOUND|beans::PropertyAttribute::READONLY|beans::PropertyAttribute::MAYBEVOID ); + // add new property to update current page's acc information + rProperties.emplace_back( "UpdateAcc", + PROPERTY_UPDATEACC, + ::cppu::UnoType<sal_Int16>::get(), + beans::PropertyAttribute::BOUND ); + rProperties.emplace_back( "PageChange", + PROPERTY_PAGE_CHANGE, + ::cppu::UnoType<sal_Int16>::get(), + beans::PropertyAttribute::BOUND ); +} + +IPropertyArrayHelper & DrawController::getInfoHelper() +{ + SolarMutexGuard aGuard; + + if (mpPropertyArrayHelper == nullptr) + { + ::std::vector<beans::Property> aProperties; + FillPropertyTable(aProperties); + mpPropertyArrayHelper.reset(new OPropertyArrayHelper(comphelper::containerToSequence(aProperties), false)); + } + + return *mpPropertyArrayHelper; +} + +Reference < beans::XPropertySetInfo > DrawController::getPropertySetInfo() +{ + SolarMutexGuard aGuard; + + static Reference < beans::XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) ); + return xInfo; +} + +uno::Reference< form::runtime::XFormController > SAL_CALL DrawController::getFormController( const uno::Reference< form::XForm >& Form ) +{ + SolarMutexGuard aGuard; + + FmFormShell* pFormShell = mpBase->GetFormShellManager()->GetFormShell(); + SdrView* pSdrView = mpBase->GetDrawView(); + std::shared_ptr<ViewShell> pViewShell = mpBase->GetMainViewShell(); + ::sd::Window* pWindow = pViewShell ? pViewShell->GetActiveWindow() : nullptr; + + uno::Reference< form::runtime::XFormController > xController; + if ( pFormShell && pSdrView && pWindow ) + xController = FmFormShell::GetFormController( Form, *pSdrView, *pWindow->GetOutDev() ); + return xController; +} + +sal_Bool SAL_CALL DrawController::isFormDesignMode( ) +{ + SolarMutexGuard aGuard; + + bool bIsDesignMode = true; + + FmFormShell* pFormShell = mpBase->GetFormShellManager()->GetFormShell(); + if ( pFormShell ) + bIsDesignMode = pFormShell->IsDesignMode(); + + return bIsDesignMode; +} + +void SAL_CALL DrawController::setFormDesignMode( sal_Bool DesignMode ) +{ + SolarMutexGuard aGuard; + + FmFormShell* pFormShell = mpBase->GetFormShellManager()->GetFormShell(); + if ( pFormShell ) + pFormShell->SetDesignMode( DesignMode ); +} + +uno::Reference< awt::XControl > SAL_CALL DrawController::getControl( const uno::Reference< awt::XControlModel >& xModel ) +{ + SolarMutexGuard aGuard; + + FmFormShell* pFormShell = mpBase->GetFormShellManager()->GetFormShell(); + SdrView* pSdrView = mpBase->GetDrawView(); + std::shared_ptr<ViewShell> pViewShell = mpBase->GetMainViewShell(); + ::sd::Window* pWindow = pViewShell ? pViewShell->GetActiveWindow() : nullptr; + + uno::Reference< awt::XControl > xControl; + if ( pFormShell && pSdrView && pWindow ) + pFormShell->GetFormControl( xModel, *pSdrView, *pWindow->GetOutDev(), xControl ); + return xControl; +} + +sal_Bool DrawController::convertFastPropertyValue ( + Any & rConvertedValue, + Any & rOldValue, + sal_Int32 nHandle, + const Any& rValue) +{ + bool bResult = false; + + if (nHandle == PROPERTY_SUB_CONTROLLER) + { + rOldValue <<= mxSubController; + rConvertedValue <<= Reference<drawing::XDrawSubController>(rValue, UNO_QUERY); + bResult = (rOldValue != rConvertedValue); + } + else if (mxSubController.is()) + { + rConvertedValue = rValue; + try + { + rOldValue = mxSubController->getFastPropertyValue(nHandle); + bResult = (rOldValue != rConvertedValue); + } + catch (const beans::UnknownPropertyException&) + { + // The property is unknown and thus an illegal argument to this method. + throw css::lang::IllegalArgumentException(); + } + } + + return bResult; +} + +void DrawController::setFastPropertyValue_NoBroadcast ( + sal_Int32 nHandle, + const Any& rValue) +{ + SolarMutexGuard aGuard; + if (nHandle == PROPERTY_SUB_CONTROLLER) + SetSubController(Reference<drawing::XDrawSubController>(rValue, UNO_QUERY)); + else if (mxSubController.is()) + mxSubController->setFastPropertyValue(nHandle, rValue); +} + +void DrawController::getFastPropertyValue ( + Any & rRet, + sal_Int32 nHandle ) const +{ + SolarMutexGuard aGuard; + + switch( nHandle ) + { + case PROPERTY_WORKAREA: + rRet <<= awt::Rectangle( + maLastVisArea.Left(), + maLastVisArea.Top(), + maLastVisArea.GetWidth(), + maLastVisArea.GetHeight()); + break; + + case PROPERTY_SUB_CONTROLLER: + rRet <<= mxSubController; + break; + + default: + if (mxSubController.is()) + rRet = mxSubController->getFastPropertyValue(nHandle); + break; + } +} + +void DrawController::ProvideFrameworkControllers() +{ + SolarMutexGuard aGuard; + try + { + Reference<XController> xController (this); + const Reference<XComponentContext> xContext ( + ::comphelper::getProcessComponentContext() ); + mxConfigurationController = ConfigurationController::create( + xContext, + xController); + mxModuleController = ModuleController::create( + xContext, + xController); + } + catch (const RuntimeException&) + { + mxConfigurationController = nullptr; + mxModuleController = nullptr; + } +} + +void DrawController::DisposeFrameworkControllers() +{ + Reference<XComponent> xComponent (mxModuleController, UNO_QUERY); + if (xComponent.is()) + xComponent->dispose(); + + xComponent.set(mxConfigurationController, UNO_QUERY); + if (xComponent.is()) + xComponent->dispose(); +} + +void DrawController::ThrowIfDisposed() const +{ + if (rBHelper.bDisposed || rBHelper.bInDispose || mbDisposing) + { + SAL_WARN("sd", "Calling disposed DrawController object. Throwing exception:"); + throw lang::DisposedException ( + "DrawController object has already been disposed", + const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this))); + } +} + +} // end of namespace sd + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/unoidl/SdUnoDrawView.cxx b/sd/source/ui/unoidl/SdUnoDrawView.cxx new file mode 100644 index 000000000..379a2956f --- /dev/null +++ b/sd/source/ui/unoidl/SdUnoDrawView.cxx @@ -0,0 +1,548 @@ +/* -*- 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 <SdUnoDrawView.hxx> + +#include <DrawController.hxx> +#include <DrawDocShell.hxx> +#include <DrawViewShell.hxx> +#include <drawdoc.hxx> +#include "unolayer.hxx" +#include <unomodel.hxx> +#include <Window.hxx> +#include <pres.hxx> + +#include <comphelper/processfactory.hxx> +#include <cppuhelper/supportsservice.hxx> +#include <sfx2/dispatch.hxx> +#include <sfx2/viewfrm.hxx> +#include <svx/svdpagv.hxx> +#include <svx/unopage.hxx> +#include <sfx2/zoomitem.hxx> +#include <com/sun/star/drawing/DrawViewMode.hpp> +#include <com/sun/star/drawing/ShapeCollection.hpp> +#include <com/sun/star/drawing/XLayerManager.hpp> +#include <com/sun/star/view/DocumentZoomType.hpp> + +#include <vector> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::drawing; + +namespace sd { + +SdUnoDrawView::SdUnoDrawView( + DrawViewShell& rViewShell, + View& rView) noexcept + : DrawSubControllerInterfaceBase(m_aMutex), + mrDrawViewShell(rViewShell), + mrView(rView) +{ +} + +SdUnoDrawView::~SdUnoDrawView() noexcept +{ +} + +bool SdUnoDrawView::getMasterPageMode() const noexcept +{ + return (mrDrawViewShell.GetEditMode() == EditMode::MasterPage); +} + +void SdUnoDrawView::setMasterPageMode (bool bMasterPageMode) noexcept +{ + if ((mrDrawViewShell.GetEditMode() == EditMode::MasterPage) != bMasterPageMode) + { + mrDrawViewShell.ChangeEditMode ( + bMasterPageMode ? EditMode::MasterPage : EditMode::Page, + mrDrawViewShell.IsLayerModeActive()); + } +} + +bool SdUnoDrawView::getLayerMode() const noexcept +{ + return mrDrawViewShell.IsLayerModeActive(); +} + +void SdUnoDrawView::setLayerMode (bool bLayerMode) noexcept +{ + if (mrDrawViewShell.IsLayerModeActive() != bLayerMode) + { + mrDrawViewShell.ChangeEditMode ( + mrDrawViewShell.GetEditMode(), + bLayerMode); + } +} + +Reference<drawing::XLayer> SdUnoDrawView::getActiveLayer() const +{ + Reference<drawing::XLayer> xCurrentLayer; + + do + { + // Retrieve the layer manager from the model. + SdXImpressDocument* pModel = GetModel(); + if (pModel == nullptr) + break; + + SdDrawDocument* pSdModel = pModel->GetDoc(); + if (pSdModel == nullptr) + break; + + // From the model get the current SdrLayer object via the layer admin. + SdrLayerAdmin& rLayerAdmin = pSdModel->GetLayerAdmin (); + SdrLayer* pLayer = rLayerAdmin.GetLayer (mrView.GetActiveLayer()); + if (pLayer == nullptr) + break; + + // Get the corresponding XLayer object from the implementation + // object of the layer manager. + Reference<drawing::XLayerManager> xManager (pModel->getLayerManager(), uno::UNO_QUERY); + SdLayerManager* pManager = comphelper::getFromUnoTunnel<SdLayerManager> (xManager); + if (pManager != nullptr) + xCurrentLayer = pManager->GetLayer (pLayer); + } + while (false); + + return xCurrentLayer; +} + +void SdUnoDrawView::setActiveLayer (const Reference<drawing::XLayer>& rxLayer) +{ + // Get the SdrLayer object corresponding to the given reference. + if ( ! rxLayer.is()) + return; + + SdLayer* pLayer = comphelper::getFromUnoTunnel<SdLayer> (rxLayer); + if (pLayer == nullptr) + return; + + SdrLayer* pSdrLayer = pLayer->GetSdrLayer(); + if (pSdrLayer == nullptr) + return; + + // Set the new active layer and make the change visible. + mrView.SetActiveLayer (pSdrLayer->GetName()); + mrDrawViewShell.ResetActualLayer (); +} + +// XSelectionSupplier + +sal_Bool SAL_CALL SdUnoDrawView::select( const Any& aSelection ) +{ + bool bOk = true; + + ::std::vector<SdrObject*> aObjects; + + SdrPage* pSdrPage = nullptr; + + Reference< drawing::XShape > xShape; + aSelection >>= xShape; + + if(xShape.is()) + { + SdrObject* pObj = SdrObject::getSdrObjectFromXShape( xShape ); + if( pObj ) + { + pSdrPage = pObj->getSdrPageFromSdrObject(); + aObjects.push_back( pObj ); + } + else + { + bOk = false; + } + } + else + { + Reference< drawing::XShapes > xShapes; + aSelection >>= xShapes; + if( xShapes.is() ) + { + const sal_uInt32 nCount = xShapes->getCount(); + for( sal_uInt32 i = 0; i < nCount; i++ ) + { + xShapes->getByIndex(i) >>= xShape; + if( xShape.is() ) + { + SdrObject* pObj = SdrObject::getSdrObjectFromXShape(xShape); + if( !pObj ) + { + bOk = false; + break; + } + + if( pSdrPage == nullptr ) + { + pSdrPage = pObj->getSdrPageFromSdrObject(); + } + else if( pSdrPage != pObj->getSdrPageFromSdrObject() ) + { + bOk = false; + break; + } + + aObjects.push_back( pObj ); + } + } + } + } + + if( bOk ) + { + if( pSdrPage ) + { + setMasterPageMode( pSdrPage->IsMasterPage() ); + mrDrawViewShell.SwitchPage( (pSdrPage->GetPageNum() - 1) >> 1 ); + mrDrawViewShell.WriteFrameViewData(); + } + + SdrPageView *pPV = mrView.GetSdrPageView(); + + if(pPV) + { + // first deselect all + mrView.UnmarkAllObj( pPV ); + + for( SdrObject* pObj : aObjects ) + { + mrView.MarkObj( pObj, pPV ); + } + } + else + { + bOk = false; + } + } + + return bOk; +} + +Any SAL_CALL SdUnoDrawView::getSelection() +{ + Any aAny; + + if( mrView.IsTextEdit() ) + mrView.getTextSelection( aAny ); + + if( !aAny.hasValue() ) + { + const SdrMarkList& rMarkList = mrView.GetMarkedObjectList(); + const size_t nCount = rMarkList.GetMarkCount(); + if( nCount ) + { + Reference< drawing::XShapes > xShapes = drawing::ShapeCollection::create( + comphelper::getProcessComponentContext()); + for( size_t nNum = 0; nNum < nCount; ++nNum) + { + SdrMark *pMark = rMarkList.GetMark(nNum); + if(pMark==nullptr) + continue; + + SdrObject *pObj = pMark->GetMarkedSdrObj(); + if(pObj==nullptr || pObj->getSdrPageFromSdrObject() == nullptr) + continue; + + Reference< drawing::XDrawPage > xPage( pObj->getSdrPageFromSdrObject()->getUnoPage(), UNO_QUERY); + + if(!xPage.is()) + continue; + + SvxDrawPage* pDrawPage = comphelper::getFromUnoTunnel<SvxDrawPage>( xPage ); + + if(pDrawPage==nullptr) + continue; + + Reference< drawing::XShape > xShape( pObj->getUnoShape(), UNO_QUERY ); + + if(xShape.is()) + xShapes->add(xShape); + } + aAny <<= xShapes; + } + } + + return aAny; +} + +void SAL_CALL SdUnoDrawView::addSelectionChangeListener ( + const css::uno::Reference<css::view::XSelectionChangeListener>&) +{} + +void SAL_CALL SdUnoDrawView::removeSelectionChangeListener ( + const css::uno::Reference<css::view::XSelectionChangeListener>&) +{} + +void SdUnoDrawView::setFastPropertyValue ( + sal_Int32 nHandle, + const Any& rValue) +{ + switch( nHandle ) + { + case DrawController::PROPERTY_CURRENTPAGE: + { + Reference< drawing::XDrawPage > xPage; + rValue >>= xPage; + setCurrentPage( xPage ); + } + break; + + case DrawController::PROPERTY_MASTERPAGEMODE: + { + bool bValue = false; + rValue >>= bValue; + setMasterPageMode( bValue ); + } + break; + + case DrawController::PROPERTY_LAYERMODE: + { + bool bValue = false; + rValue >>= bValue; + setLayerMode( bValue ); + } + break; + case DrawController::PROPERTY_ACTIVE_LAYER: + { + Reference<drawing::XLayer> xLayer; + rValue >>= xLayer; + setActiveLayer (xLayer); + } + break; + case DrawController::PROPERTY_ZOOMVALUE: + { + sal_Int16 nZoom = 0; + rValue >>= nZoom; + SetZoom( nZoom ); + } + break; + case DrawController::PROPERTY_ZOOMTYPE: + { + sal_Int16 nType = 0; + rValue >>= nType; + SetZoomType( nType ); + } + break; + case DrawController::PROPERTY_VIEWOFFSET: + { + awt::Point aOffset; + rValue >>= aOffset; + SetViewOffset( aOffset ); + } + break; + default: + throw beans::UnknownPropertyException( OUString::number(nHandle), static_cast<cppu::OWeakObject*>(this)); + } +} + +Any SAL_CALL SdUnoDrawView::getFastPropertyValue ( + sal_Int32 nHandle) +{ + Any aValue; + switch( nHandle ) + { + case DrawController::PROPERTY_CURRENTPAGE: + aValue <<= getCurrentPage(); + break; + + case DrawController::PROPERTY_MASTERPAGEMODE: + aValue <<= getMasterPageMode(); + break; + + case DrawController::PROPERTY_LAYERMODE: + aValue <<= getLayerMode(); + break; + + case DrawController::PROPERTY_ACTIVE_LAYER: + aValue <<= getActiveLayer(); + break; + + case DrawController::PROPERTY_ZOOMVALUE: + aValue <<= GetZoom(); + break; + case DrawController::PROPERTY_ZOOMTYPE: + aValue <<= sal_Int16(css::view::DocumentZoomType::BY_VALUE); + break; + case DrawController::PROPERTY_VIEWOFFSET: + aValue <<= GetViewOffset(); + break; + + case DrawController::PROPERTY_DRAWVIEWMODE: + aValue = getDrawViewMode(); + break; + + default: + throw beans::UnknownPropertyException( OUString::number(nHandle), static_cast<cppu::OWeakObject*>(this)); + } + + return aValue; +} + +// XDrawView + +void SAL_CALL SdUnoDrawView::setCurrentPage ( + const Reference< drawing::XDrawPage >& xPage ) +{ + SvxDrawPage* pDrawPage = comphelper::getFromUnoTunnel<SvxDrawPage>( xPage ); + SdrPage *pSdrPage = pDrawPage ? pDrawPage->GetSdrPage() : nullptr; + + if(pSdrPage) + { + // End editing of text. Otherwise the edited text object would + // still be visible on the new page. + mrDrawViewShell.GetView()->SdrEndTextEdit(); + + setMasterPageMode( pSdrPage->IsMasterPage() ); + mrDrawViewShell.SwitchPage( (pSdrPage->GetPageNum() - 1) >> 1 ); + mrDrawViewShell.WriteFrameViewData(); + } +} + +Reference< drawing::XDrawPage > SAL_CALL SdUnoDrawView::getCurrentPage() +{ + Reference< drawing::XDrawPage > xPage; + + SdrPageView *pPV = mrView.GetSdrPageView(); + SdrPage* pPage = pPV ? pPV->GetPage() : nullptr; + + if(pPage) + xPage.set( pPage->getUnoPage(), UNO_QUERY ); + + return xPage; +} + +sal_Int16 SdUnoDrawView::GetZoom() const +{ + if (mrDrawViewShell.GetActiveWindow() ) + { + return static_cast<sal_Int16>(mrDrawViewShell.GetActiveWindow()->GetZoom()); + } + else + { + return 0; + } +} + +void SdUnoDrawView::SetZoom( sal_Int16 nZoom ) +{ + SvxZoomItem aZoomItem( SvxZoomType::PERCENT, nZoom ); + + SfxViewFrame* pViewFrame = mrDrawViewShell.GetViewFrame(); + if( pViewFrame ) + { + SfxDispatcher* pDispatcher = pViewFrame->GetDispatcher(); + if( pDispatcher ) + { + pDispatcher->ExecuteList(SID_ATTR_ZOOM, SfxCallMode::SYNCHRON, + { &aZoomItem }); + } + } +} + +void SdUnoDrawView::SetViewOffset(const awt::Point& rWinPos ) +{ + Point aWinPos( rWinPos.X, rWinPos.Y ); + aWinPos += mrDrawViewShell.GetViewOrigin(); + mrDrawViewShell.SetWinViewPos( aWinPos ); +} + +awt::Point SdUnoDrawView::GetViewOffset() const +{ + Point aRet = mrDrawViewShell.GetWinViewPos(); + aRet -= mrDrawViewShell.GetViewOrigin(); + + return awt::Point( aRet.X(), aRet.Y() ); +} + +void SdUnoDrawView::SetZoomType ( sal_Int16 nType ) +{ + SfxViewFrame* pViewFrame = mrDrawViewShell.GetViewFrame(); + if( !pViewFrame ) + return; + + SfxDispatcher* pDispatcher = pViewFrame->GetDispatcher(); + if( !pDispatcher ) + return; + + SvxZoomType eZoomType; + switch( nType ) + { + case css::view::DocumentZoomType::OPTIMAL: + eZoomType = SvxZoomType::OPTIMAL; + break; + + case css::view::DocumentZoomType::PAGE_WIDTH: + case css::view::DocumentZoomType::PAGE_WIDTH_EXACT: + eZoomType = SvxZoomType::PAGEWIDTH; + break; + + case css::view::DocumentZoomType::ENTIRE_PAGE: + eZoomType = SvxZoomType::WHOLEPAGE; + break; + + default: + return; + } + SvxZoomItem aZoomItem( eZoomType ); + pDispatcher->ExecuteList(SID_ATTR_ZOOM, SfxCallMode::SYNCHRON, + { &aZoomItem }); +} + +SdXImpressDocument* SdUnoDrawView::GetModel() const noexcept +{ + if (mrView.GetDocSh()!=nullptr) + { + Reference<frame::XModel> xModel (mrView.GetDocSh()->GetModel()); + return comphelper::getFromUnoTunnel<SdXImpressDocument>(xModel); + } + else + return nullptr; +} + +Any SdUnoDrawView::getDrawViewMode() const +{ + Any aRet; + switch( mrDrawViewShell.GetPageKind() ) + { + case PageKind::Notes: aRet <<= DrawViewMode_NOTES; break; + case PageKind::Handout: aRet <<= DrawViewMode_HANDOUT; break; + case PageKind::Standard: aRet <<= DrawViewMode_DRAW; break; + } + return aRet; +} + +// XServiceInfo +OUString SAL_CALL SdUnoDrawView::getImplementationName( ) +{ + return "com.sun.star.comp.sd.SdUnoDrawView" ; +} + +sal_Bool SAL_CALL SdUnoDrawView::supportsService( const OUString& ServiceName ) +{ + return cppu::supportsService( this, ServiceName ); +} + +Sequence< OUString > SAL_CALL SdUnoDrawView::getSupportedServiceNames( ) +{ + return { "com.sun.star.drawing.DrawingDocumentDrawView" }; +} + +} // end of namespace sd + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/unoidl/SdUnoOutlineView.cxx b/sd/source/ui/unoidl/SdUnoOutlineView.cxx new file mode 100644 index 000000000..6b98f2140 --- /dev/null +++ b/sd/source/ui/unoidl/SdUnoOutlineView.cxx @@ -0,0 +1,156 @@ +/* -*- 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 <SdUnoOutlineView.hxx> + +#include <DrawController.hxx> +#include <OutlineViewShell.hxx> +#include <sdpage.hxx> + +#include <cppuhelper/supportsservice.hxx> +#include <svx/unopage.hxx> + +using namespace ::cppu; +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; + +namespace sd { + +SdUnoOutlineView::SdUnoOutlineView( + OutlineViewShell& rViewShell) noexcept + : DrawSubControllerInterfaceBase(m_aMutex), + mrOutlineViewShell(rViewShell) +{ +} + +SdUnoOutlineView::~SdUnoOutlineView() noexcept +{ +} + +void SAL_CALL SdUnoOutlineView::disposing() +{ +} + +//----- XSelectionSupplier ---------------------------------------------------- + +sal_Bool SAL_CALL SdUnoOutlineView::select( const Any& ) +{ + // todo: add selections for text ranges + return false; +} + +Any SAL_CALL SdUnoOutlineView::getSelection() +{ + Any aAny; + return aAny; +} + +void SAL_CALL SdUnoOutlineView::addSelectionChangeListener ( + const css::uno::Reference<css::view::XSelectionChangeListener>&) +{} + +void SAL_CALL SdUnoOutlineView::removeSelectionChangeListener ( + const css::uno::Reference<css::view::XSelectionChangeListener>&) +{} + +//----- XDrawView ------------------------------------------------------------- +void SAL_CALL SdUnoOutlineView::setCurrentPage ( + const Reference< drawing::XDrawPage >& xPage) +{ + SvxDrawPage* pDrawPage = comphelper::getFromUnoTunnel<SvxDrawPage>( xPage ); + SdrPage *pSdrPage = pDrawPage ? pDrawPage->GetSdrPage() : nullptr; + SdPage *pSdPage = dynamic_cast<SdPage*>(pSdrPage); + + if (pSdPage != nullptr) + mrOutlineViewShell.SetCurrentPage(pSdPage); +} + +Reference< drawing::XDrawPage > SAL_CALL SdUnoOutlineView::getCurrentPage() +{ + Reference<drawing::XDrawPage> xPage; + + SdPage* pPage = mrOutlineViewShell.getCurrentPage(); + if (pPage != nullptr) + xPage.set(pPage->getUnoPage(), UNO_QUERY); + + return xPage; +} + +void SdUnoOutlineView::setFastPropertyValue ( + sal_Int32 nHandle, + const Any& rValue) +{ + switch( nHandle ) + { + case DrawController::PROPERTY_CURRENTPAGE: + { + Reference< drawing::XDrawPage > xPage; + rValue >>= xPage; + setCurrentPage( xPage ); + } + break; + + default: + throw beans::UnknownPropertyException( OUString::number(nHandle), static_cast<cppu::OWeakObject*>(this)); + } +} + +Any SAL_CALL SdUnoOutlineView::getFastPropertyValue ( + sal_Int32 nHandle) +{ + Any aValue; + + switch( nHandle ) + { + case DrawController::PROPERTY_CURRENTPAGE: + { + SdPage* pPage = mrOutlineViewShell.GetActualPage(); + if (pPage != nullptr) + aValue <<= pPage->getUnoPage(); + } + break; + case DrawController::PROPERTY_VIEWOFFSET: + break; + + default: + throw beans::UnknownPropertyException( OUString::number(nHandle), static_cast<cppu::OWeakObject*>(this)); + } + + return aValue; +} + +// XServiceInfo +OUString SAL_CALL SdUnoOutlineView::getImplementationName( ) +{ + return "com.sun.star.comp.sd.SdUnoOutlineView"; +} + +sal_Bool SAL_CALL SdUnoOutlineView::supportsService( const OUString& ServiceName ) +{ + return cppu::supportsService( this, ServiceName ); +} + +Sequence< OUString > SAL_CALL SdUnoOutlineView::getSupportedServiceNames( ) +{ + return { "com.sun.star.presentation.OutlineView" }; +} + +} // end of namespace sd + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/unoidl/SdUnoSlideView.cxx b/sd/source/ui/unoidl/SdUnoSlideView.cxx new file mode 100644 index 000000000..c30962ed7 --- /dev/null +++ b/sd/source/ui/unoidl/SdUnoSlideView.cxx @@ -0,0 +1,172 @@ +/* -*- 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 <DrawController.hxx> +#include <SdUnoSlideView.hxx> + +#include <SlideSorter.hxx> +#include <controller/SlideSorterController.hxx> +#include <controller/SlsPageSelector.hxx> +#include <controller/SlsCurrentSlideManager.hxx> +#include <model/SlsPageEnumerationProvider.hxx> +#include <model/SlsPageDescriptor.hxx> +#include <sdpage.hxx> +#include <com/sun/star/beans/XPropertySet.hpp> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; + +namespace sd { + +SdUnoSlideView::SdUnoSlideView ( + slidesorter::SlideSorter& rSlideSorter) noexcept + : DrawSubControllerInterfaceBase(m_aMutex), + mrSlideSorter(rSlideSorter) +{ +} + +SdUnoSlideView::~SdUnoSlideView() noexcept +{ +} + +//----- XSelectionSupplier ---------------------------------------------------- + +sal_Bool SAL_CALL SdUnoSlideView::select (const Any& aSelection) +{ + slidesorter::controller::SlideSorterController& rSlideSorterController + = mrSlideSorter.GetController(); + slidesorter::controller::PageSelector& rSelector (rSlideSorterController.GetPageSelector()); + rSelector.DeselectAllPages(); + Sequence<Reference<drawing::XDrawPage> > xPages; + aSelection >>= xPages; + for (const auto& rPage : std::as_const(xPages)) + { + Reference<beans::XPropertySet> xSet (rPage, UNO_QUERY); + if (xSet.is()) + { + try + { + Any aNumber = xSet->getPropertyValue("Number"); + sal_Int32 nPageNumber = 0; + aNumber >>= nPageNumber; + nPageNumber -=1; // Transform 1-based page numbers to 0-based ones. + rSelector.SelectPage(nPageNumber); + } + catch (const RuntimeException&) + { + } + } + } + + return true; +} + +Any SAL_CALL SdUnoSlideView::getSelection() +{ + Any aResult; + + slidesorter::model::PageEnumeration aSelectedPages ( + slidesorter::model::PageEnumerationProvider::CreateSelectedPagesEnumeration( + mrSlideSorter.GetModel())); + int nSelectedPageCount ( + mrSlideSorter.GetController().GetPageSelector().GetSelectedPageCount()); + + Sequence<Reference<XInterface> > aPages(nSelectedPageCount); + auto aPagesRange = asNonConstRange(aPages); + int nIndex = 0; + while (aSelectedPages.HasMoreElements() && nIndex<nSelectedPageCount) + { + slidesorter::model::SharedPageDescriptor pDescriptor (aSelectedPages.GetNextElement()); + aPagesRange[nIndex++] = pDescriptor->GetPage()->getUnoPage(); + } + aResult <<= aPages; + + return aResult; +} + +void SAL_CALL SdUnoSlideView::addSelectionChangeListener ( + const css::uno::Reference<css::view::XSelectionChangeListener>&) +{} + +void SAL_CALL SdUnoSlideView::removeSelectionChangeListener ( + const css::uno::Reference<css::view::XSelectionChangeListener>&) +{} + +//----- XDrawView ------------------------------------------------------------- + +void SAL_CALL SdUnoSlideView::setCurrentPage ( + const css::uno::Reference<css::drawing::XDrawPage>& rxDrawPage) +{ + Reference<beans::XPropertySet> xProperties (rxDrawPage, UNO_QUERY); + if (xProperties.is()) + { + sal_uInt16 nPageNumber(0); + if (xProperties->getPropertyValue("Number") >>= nPageNumber) + { + mrSlideSorter.GetController().GetCurrentSlideManager()->SwitchCurrentSlide( + nPageNumber-1); + } + } +} + +css::uno::Reference<css::drawing::XDrawPage > SAL_CALL + SdUnoSlideView::getCurrentPage() +{ + return mrSlideSorter.GetController().GetCurrentSlideManager()->GetCurrentSlide()->GetXDrawPage(); +} + +//----- XFastPropertySet ------------------------------------------------------ + +void SdUnoSlideView::setFastPropertyValue ( + sal_Int32 nHandle, + const Any&) +{ + throw beans::UnknownPropertyException( OUString::number(nHandle), static_cast<cppu::OWeakObject*>(this)); +} + +Any SAL_CALL SdUnoSlideView::getFastPropertyValue ( + sal_Int32 nHandle) +{ + if( nHandle != DrawController::PROPERTY_VIEWOFFSET ) + throw beans::UnknownPropertyException( OUString::number(nHandle), static_cast<cppu::OWeakObject*>(this)); + + return Any(); +} + +// XServiceInfo +OUString SAL_CALL SdUnoSlideView::getImplementationName( ) +{ + return "com.sun.star.comp.sd.SdUnoSlideView"; +} + +sal_Bool SAL_CALL SdUnoSlideView::supportsService( const OUString& ServiceName ) +{ + return cppu::supportsService( this, ServiceName ); +} + +Sequence< OUString > SAL_CALL SdUnoSlideView::getSupportedServiceNames( ) +{ + return { "com.sun.star.presentation.SlidesView" }; +} + +} // end of namespace sd + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/unoidl/UnoDocumentSettings.cxx b/sd/source/ui/unoidl/UnoDocumentSettings.cxx new file mode 100644 index 000000000..331f90b53 --- /dev/null +++ b/sd/source/ui/unoidl/UnoDocumentSettings.cxx @@ -0,0 +1,1431 @@ +/* -*- 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 <memory> +#include <utility> +#include <com/sun/star/embed/XStorage.hpp> +#include <com/sun/star/embed/ElementModes.hpp> +#include <com/sun/star/embed/XTransactedObject.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/beans/XMultiPropertySet.hpp> +#include <com/sun/star/i18n/XForbiddenCharacters.hpp> +#include <cppuhelper/implbase.hxx> +#include <cppuhelper/supportsservice.hxx> +#include <comphelper/propertysethelper.hxx> +#include <comphelper/propertysetinfo.hxx> +#include <o3tl/string_view.hxx> +#include <tools/debug.hxx> +#include <tools/urlobj.hxx> +#include <svx/xtable.hxx> +#include <vcl/svapp.hxx> + +#include <drawdoc.hxx> +#include <DrawDocShell.hxx> +#include "UnoDocumentSettings.hxx" +#include <unomodel.hxx> + +#include <optsitem.hxx> +#include <sfx2/printer.hxx> +#include <sfx2/sfxsids.hrc> +#include <sdattr.hrc> +#include <sdmod.hxx> +#include <Outliner.hxx> +#include <xmloff/settingsstore.hxx> +#include <editeng/editstat.hxx> +#include <svx/unoapi.hxx> + +using namespace ::comphelper; +using namespace ::cppu; +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::util; +using namespace ::com::sun::star::container; +using namespace ::com::sun::star::drawing; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::document; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::i18n; + +namespace sd +{ + namespace { + + class DocumentSettings : public WeakImplHelper< XPropertySet, XMultiPropertySet, XServiceInfo >, + public comphelper::PropertySetHelper, + public DocumentSettingsSerializer + { + public: + explicit DocumentSettings( SdXImpressDocument* pModel ); + + // XInterface + virtual Any SAL_CALL queryInterface( const Type& aType ) override; + virtual void SAL_CALL acquire( ) noexcept override; + virtual void SAL_CALL release( ) noexcept override; + + // XPropertySet + 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; + + // XMultiPropertySet + virtual void SAL_CALL setPropertyValues( const css::uno::Sequence< OUString >& aPropertyNames, const css::uno::Sequence< css::uno::Any >& aValues ) override; + virtual css::uno::Sequence< css::uno::Any > SAL_CALL getPropertyValues( const css::uno::Sequence< OUString >& aPropertyNames ) override; + virtual void SAL_CALL addPropertiesChangeListener( const css::uno::Sequence< OUString >& aPropertyNames, const css::uno::Reference< css::beans::XPropertiesChangeListener >& xListener ) override; + virtual void SAL_CALL removePropertiesChangeListener( const css::uno::Reference< css::beans::XPropertiesChangeListener >& xListener ) override; + virtual void SAL_CALL firePropertiesChangeEvent( const css::uno::Sequence< OUString >& aPropertyNames, const css::uno::Reference< css::beans::XPropertiesChangeListener >& xListener ) override; + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName( ) override; + virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override; + virtual Sequence< OUString > SAL_CALL getSupportedServiceNames( ) override; + + // DocumentSettingsSerializer cf. xmloff + virtual uno::Sequence<beans::PropertyValue> + filterStreamsFromStorage(OUString const & referer, + const uno::Reference< embed::XStorage > &xStorage, + const uno::Sequence<beans::PropertyValue>& aConfigProps ) override; + virtual uno::Sequence<beans::PropertyValue> + filterStreamsToStorage(const uno::Reference< embed::XStorage > &xStorage, + const uno::Sequence<beans::PropertyValue>& aConfigProps ) override; + + protected: + virtual void _setPropertyValues( const comphelper::PropertyMapEntry** ppEntries, const css::uno::Any* pValues ) override; + virtual void _getPropertyValues( const comphelper::PropertyMapEntry** ppEntries, css::uno::Any* pValue ) override; + + private: + bool LoadList( XPropertyListType t, const OUString &rPath, + const OUString &rReferer, + const uno::Reference< embed::XStorage > &xStorage ); + void AssignURL( XPropertyListType t, const Any* pValue, bool *pOk, bool *pChanged ); + void ExtractURL( XPropertyListType t, Any* pValue ); + rtl::Reference<SdXImpressDocument> mxModel; + }; + + } + + Reference< XInterface > DocumentSettings_createInstance( SdXImpressDocument* pModel ) + noexcept + { + DBG_ASSERT( pModel, "I need a model for the DocumentSettings!" ); + return static_cast<XWeak*>(new DocumentSettings( pModel )); + } + +namespace { + +enum SdDocumentSettingsPropertyHandles +{ + HANDLE_PRINTDRAWING, HANDLE_PRINTNOTES, HANDLE_PRINTHANDOUT, HANDLE_PRINTOUTLINE, HANDLE_MEASUREUNIT, HANDLE_SCALE_NUM, + HANDLE_SCALE_DOM, HANDLE_TABSTOP, HANDLE_PRINTPAGENAME, HANDLE_PRINTDATE, HANDLE_PRINTTIME, + HANDLE_PRINTHIDDENPAGES, HANDLE_PRINTFITPAGE, HANDLE_PRINTTILEPAGE, HANDLE_PRINTBOOKLET, HANDLE_PRINTBOOKLETFRONT, + HANDLE_PRINTBOOKLETBACK, HANDLE_PRINTQUALITY, HANDLE_COLORTABLEURL, HANDLE_DASHTABLEURL, HANDLE_LINEENDTABLEURL, HANDLE_HATCHTABLEURL, + HANDLE_GRADIENTTABLEURL, HANDLE_BITMAPTABLEURL, HANDLE_FORBIDDENCHARS, HANDLE_APPLYUSERDATA, HANDLE_SAVETHUMBNAIL, HANDLE_PAGENUMFMT, + HANDLE_PRINTERNAME, HANDLE_PRINTERJOB, HANDLE_PRINTERPAPERSIZE, HANDLE_PARAGRAPHSUMMATION, HANDLE_CHARCOMPRESS, HANDLE_ASIANPUNCT, + HANDLE_UPDATEFROMTEMPLATE, HANDLE_PRINTER_INDEPENDENT_LAYOUT + // #i33095# + ,HANDLE_LOAD_READONLY, HANDLE_MODIFY_PASSWD, HANDLE_SAVE_VERSION + ,HANDLE_SLIDESPERHANDOUT, HANDLE_HANDOUTHORIZONTAL, + HANDLE_EMBED_FONTS, HANDLE_EMBED_USED_FONTS, + HANDLE_EMBED_LATIN_SCRIPT_FONTS, HANDLE_EMBED_ASIAN_SCRIPT_FONTS, HANDLE_EMBED_COMPLEX_SCRIPT_FONTS, + HANDLE_IMAGE_PREFERRED_DPI +}; + +} + +#define MID_PRINTER 1 + + static rtl::Reference<PropertySetInfo> createSettingsInfoImpl( bool bIsDraw ) + { + static PropertyMapEntry const aImpressSettingsInfoMap[] = + { + { OUString("IsPrintDrawing"), HANDLE_PRINTDRAWING, cppu::UnoType<bool>::get(), 0, MID_PRINTER }, + { OUString("IsPrintNotes"), HANDLE_PRINTNOTES, cppu::UnoType<bool>::get(), 0, MID_PRINTER }, + { OUString("IsPrintHandout"), HANDLE_PRINTHANDOUT, cppu::UnoType<bool>::get(), 0, MID_PRINTER }, + { OUString("IsPrintOutline"), HANDLE_PRINTOUTLINE, cppu::UnoType<bool>::get(), 0, MID_PRINTER }, + { OUString("SlidesPerHandout"), HANDLE_SLIDESPERHANDOUT, ::cppu::UnoType<sal_Int16>::get(), 0, MID_PRINTER }, + { OUString("HandoutsHorizontal"), HANDLE_HANDOUTHORIZONTAL, cppu::UnoType<bool>::get(), 0, MID_PRINTER }, + }; + + static PropertyMapEntry const aDrawSettingsInfoMap[] = + { + { OUString("MeasureUnit"), HANDLE_MEASUREUNIT, ::cppu::UnoType<sal_Int16>::get(), 0, 0 }, + { OUString("ScaleNumerator"), HANDLE_SCALE_NUM, ::cppu::UnoType<sal_Int32>::get(), 0, 0 }, + { OUString("ScaleDenominator"), HANDLE_SCALE_DOM, ::cppu::UnoType<sal_Int32>::get(), 0, 0 }, + }; + + static PropertyMapEntry const aCommonSettingsInfoMap[] = + { + { OUString("DefaultTabStop"), HANDLE_TABSTOP, ::cppu::UnoType<sal_Int32>::get(), 0, 0 }, + { OUString("PrinterName"), HANDLE_PRINTERNAME, ::cppu::UnoType<OUString>::get(), 0, 0 }, + { OUString("PrinterSetup"), HANDLE_PRINTERJOB, cppu::UnoType<uno::Sequence < sal_Int8 >>::get(), 0, MID_PRINTER }, + { OUString("PrinterPaperFromSetup"), HANDLE_PRINTERPAPERSIZE, cppu::UnoType<bool>::get(), 0, MID_PRINTER }, + + { OUString("IsPrintPageName"), HANDLE_PRINTPAGENAME, cppu::UnoType<bool>::get(), 0, MID_PRINTER }, + { OUString("IsPrintDate"), HANDLE_PRINTDATE, cppu::UnoType<bool>::get(), 0, MID_PRINTER }, + { OUString("IsPrintTime"), HANDLE_PRINTTIME, cppu::UnoType<bool>::get(), 0, MID_PRINTER }, + { OUString("IsPrintHiddenPages"), HANDLE_PRINTHIDDENPAGES, cppu::UnoType<bool>::get(), 0, MID_PRINTER }, + { OUString("IsPrintFitPage"), HANDLE_PRINTFITPAGE, cppu::UnoType<bool>::get(), 0, MID_PRINTER }, + { OUString("IsPrintTilePage"), HANDLE_PRINTTILEPAGE, cppu::UnoType<bool>::get(), 0, MID_PRINTER }, + { OUString("IsPrintBooklet"), HANDLE_PRINTBOOKLET, cppu::UnoType<bool>::get(), 0, MID_PRINTER }, + { OUString("IsPrintBookletFront"), HANDLE_PRINTBOOKLETFRONT, cppu::UnoType<bool>::get(), 0, MID_PRINTER }, + { OUString("IsPrintBookletBack"), HANDLE_PRINTBOOKLETBACK, cppu::UnoType<bool>::get(), 0, MID_PRINTER }, + { OUString("PrintQuality"), HANDLE_PRINTQUALITY, ::cppu::UnoType<sal_Int32>::get(), 0, MID_PRINTER }, + { OUString("ColorTableURL"), HANDLE_COLORTABLEURL, ::cppu::UnoType<OUString>::get(), 0, 0 }, + { OUString("DashTableURL"), HANDLE_DASHTABLEURL, ::cppu::UnoType<OUString>::get(), 0, 0 }, + { OUString("LineEndTableURL"), HANDLE_LINEENDTABLEURL, ::cppu::UnoType<OUString>::get(), 0, 0 }, + { OUString("HatchTableURL"), HANDLE_HATCHTABLEURL, ::cppu::UnoType<OUString>::get(), 0, 0 }, + { OUString("GradientTableURL"), HANDLE_GRADIENTTABLEURL, ::cppu::UnoType<OUString>::get(), 0, 0 }, + { OUString("BitmapTableURL"), HANDLE_BITMAPTABLEURL, ::cppu::UnoType<OUString>::get(), 0, 0 }, + + { OUString("ForbiddenCharacters"), HANDLE_FORBIDDENCHARS, cppu::UnoType<XForbiddenCharacters>::get(), 0, 0 }, + { OUString("ApplyUserData"), HANDLE_APPLYUSERDATA, cppu::UnoType<bool>::get(), 0, 0 }, + { OUString("SaveThumbnail"), HANDLE_SAVETHUMBNAIL, cppu::UnoType<bool>::get(), 0, 0 }, + + { OUString("PageNumberFormat"), HANDLE_PAGENUMFMT, ::cppu::UnoType<sal_Int32>::get(), 0, 0 }, + { OUString("ParagraphSummation"), HANDLE_PARAGRAPHSUMMATION, cppu::UnoType<bool>::get(), 0, 0 }, + { OUString("CharacterCompressionType"),HANDLE_CHARCOMPRESS, ::cppu::UnoType<sal_Int16>::get(), 0, 0 }, + { OUString("IsKernAsianPunctuation"),HANDLE_ASIANPUNCT, cppu::UnoType<bool>::get(), 0, 0 }, + { OUString("UpdateFromTemplate"), HANDLE_UPDATEFROMTEMPLATE, cppu::UnoType<bool>::get(), 0, 0 }, + { OUString("PrinterIndependentLayout"),HANDLE_PRINTER_INDEPENDENT_LAYOUT,::cppu::UnoType<sal_Int16>::get(), 0, 0 }, + // --> #i33095# + { OUString("LoadReadonly"), HANDLE_LOAD_READONLY, cppu::UnoType<bool>::get(), 0, 0 }, + { OUString("ModifyPasswordInfo"), HANDLE_MODIFY_PASSWD, cppu::UnoType<uno::Sequence < beans::PropertyValue >>::get(), 0, 0 }, + { OUString("SaveVersionOnClose"), HANDLE_SAVE_VERSION, cppu::UnoType<bool>::get(), 0, 0 }, + { OUString("EmbedFonts"), HANDLE_EMBED_FONTS, cppu::UnoType<bool>::get(), 0, 0 }, + { OUString("EmbedOnlyUsedFonts"), HANDLE_EMBED_USED_FONTS, cppu::UnoType<bool>::get(), 0, 0 }, + { OUString("EmbedLatinScriptFonts"), HANDLE_EMBED_LATIN_SCRIPT_FONTS, cppu::UnoType<bool>::get(), 0, 0 }, + { OUString("EmbedAsianScriptFonts"), HANDLE_EMBED_ASIAN_SCRIPT_FONTS, cppu::UnoType<bool>::get(), 0, 0 }, + { OUString("EmbedComplexScriptFonts"), HANDLE_EMBED_COMPLEX_SCRIPT_FONTS, cppu::UnoType<bool>::get(), 0, 0 }, + { OUString("ImagePreferredDPI"), HANDLE_IMAGE_PREFERRED_DPI, cppu::UnoType<sal_Int32>::get(), 0, 0 }, + }; + + rtl::Reference<PropertySetInfo> xInfo = new PropertySetInfo( aCommonSettingsInfoMap ); + if (bIsDraw) + xInfo->add( aDrawSettingsInfoMap ); + else + xInfo->add( aImpressSettingsInfoMap ); + + return xInfo; + } +} + +using namespace ::sd; + +DocumentSettings::DocumentSettings( SdXImpressDocument* pModel ) +: PropertySetHelper( createSettingsInfoImpl( !pModel->IsImpressDocument() ) ), + mxModel( pModel ) +{ +} + +bool DocumentSettings::LoadList( XPropertyListType t, const OUString &rInPath, + const OUString &rReferer, + const uno::Reference< embed::XStorage > &xStorage ) +{ + SdDrawDocument* pDoc = mxModel->GetDoc(); + + sal_Int32 nSlash = rInPath.lastIndexOf('/'); + OUString aPath, aName; + if (nSlash < 0) + aName = rInPath; + else { + aName = rInPath.copy( nSlash + 1 ); + aPath = rInPath.copy( 0, nSlash ); + } + + XPropertyListRef pList = XPropertyList::CreatePropertyList( + t, aPath, rReferer ); + pList->SetName( aName ); + + if( pList->LoadFrom( xStorage, rInPath, rReferer ) ) + { + pDoc->SetPropertyList( pList ); + return true; + } + + return false; +} + +void DocumentSettings::AssignURL( XPropertyListType t, const Any* pValue, + bool *pOk, bool *pChanged ) +{ + OUString aURL; + if( !( *pValue >>= aURL ) ) + return; + + if( LoadList( t, aURL, ""/*TODO?*/, uno::Reference< embed::XStorage >() ) ) + *pOk = *pChanged = true; +} + +struct { + const char *pName; + XPropertyListType t; +} const aURLPropertyNames[] = { + { "ColorTableURL", XPropertyListType::Color }, + { "DashTableURL", XPropertyListType::Dash }, + { "LineEndTableURL", XPropertyListType::LineEnd }, + { "HatchTableURL", XPropertyListType::Hatch }, + { "GradientTableURL", XPropertyListType::Gradient }, + { "BitmapTableURL", XPropertyListType::Bitmap } +}; + +static XPropertyListType getTypeOfName( std::u16string_view aName ) +{ + for(const auto & rURLPropertyName : aURLPropertyNames) { + if( o3tl::equalsAscii( aName, rURLPropertyName.pName ) ) + return rURLPropertyName.t; + } + return XPropertyListType::Unknown; +} + +static OUString getNameOfType( XPropertyListType t ) +{ + for(const auto & rURLPropertyName : aURLPropertyNames) { + if( t == rURLPropertyName.t ) + return OUString( rURLPropertyName.pName, + strlen( rURLPropertyName.pName ) - 3, + RTL_TEXTENCODING_ASCII_US ); + } + return OUString(); +} + +uno::Sequence<beans::PropertyValue> + DocumentSettings::filterStreamsFromStorage( + OUString const & referer, + const uno::Reference< embed::XStorage > &xStorage, + const uno::Sequence<beans::PropertyValue>& aConfigProps ) +{ + uno::Sequence<beans::PropertyValue> aRet( aConfigProps.getLength() ); + auto aRetRange = asNonConstRange(aRet); + int nRet = 0; + for( const auto& rConfigProp : aConfigProps ) + { + XPropertyListType t = getTypeOfName( rConfigProp.Name ); + if (t == XPropertyListType::Unknown) + aRetRange[nRet++] = rConfigProp; + else + { + OUString aURL; + rConfigProp.Value >>= aURL; + LoadList( t, aURL, referer, xStorage ); + } + } + aRet.realloc( nRet ); + return aRet; +} + +uno::Sequence<beans::PropertyValue> + DocumentSettings::filterStreamsToStorage( + const uno::Reference< embed::XStorage > &xStorage, + const uno::Sequence<beans::PropertyValue>& aConfigProps ) +{ + uno::Sequence<beans::PropertyValue> aRet( aConfigProps.getLength() ); + + bool bHasEmbed = false; + SdDrawDocument* pDoc = mxModel->GetDoc(); + for( size_t i = 0; i < SAL_N_ELEMENTS( aURLPropertyNames ); i++ ) + { + const XPropertyListRef& pList = pDoc->GetPropertyList( static_cast<XPropertyListType>(i) ); + bHasEmbed = pList.is() && pList->IsEmbedInDocument(); + if( bHasEmbed ) + break; + } + if( !bHasEmbed ) + return aConfigProps; + + try { + // create Settings/ sub storage. + uno::Reference< embed::XStorage > xSubStorage = xStorage->openStorageElement( "Settings" , + embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE ); + if( !xSubStorage.is() ) + return aRet; + + auto aRetRange = asNonConstRange(aRet); + // now populate it + for( sal_Int32 i = 0; i < aConfigProps.getLength(); i++ ) + { + XPropertyListType t = getTypeOfName( aConfigProps[i].Name ); + aRetRange[i] = aConfigProps[i]; + if (t != XPropertyListType::Unknown) { + const XPropertyListRef& pList = pDoc->GetPropertyList( t ); + if( !pList.is() || !pList->IsEmbedInDocument() ) + continue; // no change ... + else + { + // Such specific path construction is grim. + + OUString aName( getNameOfType( t ) ); + OUString aResult; + if( pList->SaveTo( xSubStorage, aName, &aResult ) ) + { + OUString aRealPath = "Settings/" + aResult; + aRetRange[i].Value <<= aRealPath; + } + } + } + } + + // surprisingly difficult to make it really exist + uno::Reference< embed::XTransactedObject > xTrans( xSubStorage, UNO_QUERY ); + if( xTrans.is() ) + xTrans->commit(); + if( xSubStorage.is() ) + xSubStorage->dispose(); + } catch (const uno::Exception &) { +// fprintf (stderr, "saving etc. exception '%s'\n", +// OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8).getStr()); + } + + return aRet; +} + +// Most of the code reading/writing UNO document settings is the same in +// sd, sc and sw and it is mostly copy-pasted back and forth. +// TODO: Move _setPropertyValues and _getPropertyValues to some shared +// place, at least for the settings that are common to sd, sc and sw +void +DocumentSettings::_setPropertyValues(const PropertyMapEntry** ppEntries, + const Any* pValues) +{ + ::SolarMutexGuard aGuard; + + SdDrawDocument* pDoc = mxModel->GetDoc(); + ::sd::DrawDocShell* pDocSh = mxModel->GetDocShell(); + if( nullptr == pDoc || nullptr == pDocSh ) + { + throw RuntimeException("Document or Shell missing", + static_cast<OWeakObject *>(this)); + } + + bool bValue = false; + bool bOk, bChanged = false, bOptionsChanged = false; + + SdOptionsPrintItem aOptionsPrintItem; + + VclPtr<SfxPrinter> pPrinter = pDocSh->GetPrinter( false ); + if( pPrinter ) + { + SdOptionsPrintItem const * pPrinterOptions = pPrinter->GetOptions().GetItemIfSet( ATTR_OPTIONS_PRINT, false ); + if(pPrinterOptions) + aOptionsPrintItem.GetOptionsPrint() = pPrinterOptions->GetOptionsPrint(); + } + else + { + aOptionsPrintItem.SetOptions( SD_MOD()->GetSdOptions(pDoc->GetDocumentType()) ); + } + SdOptionsPrint& aPrintOpts = aOptionsPrintItem.GetOptionsPrint(); + + for( ; *ppEntries; ppEntries++, pValues++ ) + { + bOk = false; + + switch( (*ppEntries)->mnHandle ) + { + case HANDLE_COLORTABLEURL: + AssignURL( XPropertyListType::Color, pValues, &bOk, &bChanged ); + break; + + case HANDLE_DASHTABLEURL: + AssignURL( XPropertyListType::Dash, pValues, &bOk, &bChanged ); + break; + + case HANDLE_LINEENDTABLEURL: + AssignURL( XPropertyListType::LineEnd, pValues, &bOk, &bChanged ); + break; + + case HANDLE_HATCHTABLEURL: + AssignURL( XPropertyListType::Hatch, pValues, &bOk, &bChanged ); + break; + + case HANDLE_GRADIENTTABLEURL: + AssignURL( XPropertyListType::Gradient, pValues, &bOk, &bChanged ); + break; + + case HANDLE_BITMAPTABLEURL: + AssignURL( XPropertyListType::Bitmap, pValues, &bOk, &bChanged ); + break; + + case HANDLE_FORBIDDENCHARS: + bOk = true; + break; + + case HANDLE_APPLYUSERDATA: + { + bool bApplyUserData = false; + if( *pValues >>= bApplyUserData ) + { + bChanged = ( bApplyUserData != pDocSh->IsUseUserData() ); + pDocSh->SetUseUserData( bApplyUserData ); + bOk = true; + } + } + break; + case HANDLE_SAVETHUMBNAIL: + { + bool bSaveThumbnail = false; + if (*pValues >>= bSaveThumbnail) + { + bChanged = (bSaveThumbnail != pDocSh->IsUseThumbnailSave()); + pDocSh->SetUseThumbnailSave(bSaveThumbnail); + bOk = true; + } + } + break; + + case HANDLE_PRINTDRAWING: + if( *pValues >>= bValue ) + { + if( aPrintOpts.IsDraw() != bValue ) + { + aPrintOpts.SetDraw( bValue ); + bOptionsChanged = true; + } + + bOk = true; + } + break; + case HANDLE_PRINTNOTES: + if( *pValues >>= bValue ) + { + if( aPrintOpts.IsNotes() != bValue ) + { + aPrintOpts.SetNotes( bValue ); + bOptionsChanged = true; + } + + bOk = true; + } + break; + case HANDLE_PRINTHANDOUT: + if( *pValues >>= bValue ) + { + if( aPrintOpts.IsHandout() != bValue) + { + aPrintOpts.SetHandout( bValue ); + bOptionsChanged = true; + } + + bOk = true; + } + break; + case HANDLE_PRINTOUTLINE: + if( *pValues >>= bValue ) + { + if( aPrintOpts.IsOutline() != bValue) + { + aPrintOpts.SetOutline( bValue ); + bOptionsChanged = true; + } + bOk = true; + } + break; + case HANDLE_SLIDESPERHANDOUT: + { + sal_Int16 nValue = 0; + if( (*pValues >>= nValue) && (nValue >= 1) && (nValue <= 9) ) + { + if( static_cast<sal_Int16>( aPrintOpts.GetHandoutPages() ) != nValue ) + { + aPrintOpts.SetHandoutPages( static_cast< sal_uInt16 >( nValue ) ); + bOptionsChanged = true; + } + bOk = true; + } + } + break; + case HANDLE_HANDOUTHORIZONTAL: + if( *pValues >>= bValue ) + { + if( aPrintOpts.IsHandoutHorizontal() != bValue ) + { + aPrintOpts.SetHandoutHorizontal( bValue ); + bOptionsChanged = true; + } + bOk = true; + } + break; + + case HANDLE_PRINTPAGENAME: + if( *pValues >>= bValue ) + { + if( aPrintOpts.IsPagename() != bValue) + { + aPrintOpts.SetPagename( bValue ); + bOptionsChanged = true; + } + bOk = true; + } + break; + case HANDLE_PRINTDATE: + if( *pValues >>= bValue ) + { + if( aPrintOpts.IsDate() != bValue) + { + aPrintOpts.SetDate( bValue ); + bOptionsChanged = true; + } + bOk = true; + } + break; + case HANDLE_PRINTTIME: + if( *pValues >>= bValue ) + { + if( aPrintOpts.IsDate() != bValue) + { + aPrintOpts.SetTime( bValue ); + bOptionsChanged = true; + } + bOk = true; + } + break; + case HANDLE_PRINTHIDDENPAGES: + if( *pValues >>= bValue ) + { + if( aPrintOpts.IsHiddenPages() != bValue) + { + aPrintOpts.SetHiddenPages( bValue ); + bOptionsChanged = true; + } + bOk = true; + } + break; + case HANDLE_PRINTFITPAGE: + if( *pValues >>= bValue ) + { + if( aPrintOpts.IsPagesize() != bValue) + { + aPrintOpts.SetPagesize( bValue ); + bOptionsChanged = true; + } + bOk = true; + } + break; + case HANDLE_PRINTTILEPAGE: + if( *pValues >>= bValue ) + { + if( aPrintOpts.IsPagetile() != bValue) + { + aPrintOpts.SetPagetile( bValue ); + bOptionsChanged = true; + } + bOk = true; + } + break; + case HANDLE_PRINTBOOKLET: + if( *pValues >>= bValue ) + { + if( aPrintOpts.IsBooklet() != bValue) + { + aPrintOpts.SetBooklet( bValue ); + bOptionsChanged = true; + } + bOk = true; + } + break; + case HANDLE_PRINTBOOKLETFRONT: + if( *pValues >>= bValue ) + { + if( aPrintOpts.IsFrontPage() != bValue) + { + aPrintOpts.SetFrontPage( bValue ); + bOptionsChanged = true; + } + bOk = true; + } + break; + case HANDLE_PRINTBOOKLETBACK: + if( *pValues >>= bValue ) + { + if( aPrintOpts.IsBackPage() != bValue) + { + aPrintOpts.SetBackPage( bValue ); + bOptionsChanged = true; + } + bOk = true; + } + break; + case HANDLE_PRINTQUALITY: + { + sal_Int32 nValue = 0; + if( *pValues >>= nValue ) + { + if( aPrintOpts.GetOutputQuality() != nValue) + { + aPrintOpts.SetOutputQuality( static_cast<sal_uInt16>(nValue) ); + bOptionsChanged = true; + } + bOk = true; + } + } + break; + case HANDLE_MEASUREUNIT: + { + sal_Int16 nValue = 0; + if( *pValues >>= nValue ) + { + FieldUnit nFieldUnit; + if( SvxMeasureUnitToFieldUnit( nValue, nFieldUnit ) ) + { + pDoc->SetUIUnit( nFieldUnit ); + bOk = true; + } + } + } + break; + case HANDLE_SCALE_NUM: + { + sal_Int32 nValue = 0; + if( *pValues >>= nValue ) + { + Fraction aFract( nValue, pDoc->GetUIScale().GetDenominator() ); + pDoc->SetUIScale( aFract ); + bOk = true; + bChanged = true; + } + } + break; + case HANDLE_SCALE_DOM: + { + sal_Int32 nValue = 0; + if( *pValues >>= nValue ) + { + auto nNumerator = pDoc->GetUIScale().GetNumerator(); + assert(nNumerator != 0); + Fraction aFract(nNumerator, nValue); + pDoc->SetUIScale( aFract ); + bOk = true; + bChanged = true; + } + } + break; + + case HANDLE_TABSTOP: + { + sal_Int32 nValue = 0; + if( (*pValues >>= nValue) && (nValue >= 0) ) + { + pDoc->SetDefaultTabulator(static_cast<sal_uInt16>(nValue)); + bOk = true; + bChanged = true; + } + } + break; + case HANDLE_PAGENUMFMT: + { + sal_Int32 nValue = 0; + if( (*pValues >>= nValue ) && (nValue >= css::style::NumberingType::CHARS_UPPER_LETTER ) && (nValue <= css::style::NumberingType::PAGE_DESCRIPTOR) ) + { + pDoc->SetPageNumType(static_cast<SvxNumType>(nValue)); + bOk = true; + bChanged = true; + } + } + break; + case HANDLE_PRINTERNAME: + { + OUString aPrinterName; + if( *pValues >>= aPrinterName ) + { + bOk = true; + if( !aPrinterName.isEmpty() && pDocSh->GetCreateMode() != SfxObjectCreateMode::EMBEDDED ) + { + SfxPrinter *pTempPrinter = pDocSh->GetPrinter( true ); + if (pTempPrinter) + { + VclPtr<SfxPrinter> pNewPrinter = VclPtr<SfxPrinter>::Create( pTempPrinter->GetOptions().Clone(), aPrinterName ); + pDocSh->SetPrinter( pNewPrinter ); + } + } + } + } + break; + case HANDLE_PRINTERJOB: + { + Sequence < sal_Int8 > aSequence; + if ( *pValues >>= aSequence ) + { + bOk = true; + sal_uInt32 nSize = aSequence.getLength(); + if( nSize ) + { + SvMemoryStream aStream (aSequence.getArray(), nSize, StreamMode::READ ); + aStream.Seek ( STREAM_SEEK_TO_BEGIN ); + std::unique_ptr<SfxItemSet> pItemSet; + + bool bPreferPrinterPapersize = false; + if( pPrinter ) + { + pItemSet = pPrinter->GetOptions().Clone(); + bPreferPrinterPapersize = pPrinter->GetPrinterSettingsPreferred(); + } + else + { + pItemSet = std::make_unique<SfxItemSetFixed + <SID_PRINTER_NOTFOUND_WARN, SID_PRINTER_NOTFOUND_WARN, + SID_PRINTER_CHANGESTODOC, SID_PRINTER_CHANGESTODOC, + ATTR_OPTIONS_PRINT, ATTR_OPTIONS_PRINT>>(pDoc->GetPool()); + } + + pPrinter = SfxPrinter::Create ( aStream, std::move(pItemSet) ); + pPrinter->SetPrinterSettingsPreferred( bPreferPrinterPapersize ); + + MapMode aMM (pPrinter->GetMapMode()); + aMM.SetMapUnit(MapUnit::Map100thMM); + pPrinter->SetMapMode(aMM); + + pDocSh->SetPrinter( pPrinter ); + + pPrinter = nullptr; + } + } + } + break; + + case HANDLE_PRINTERPAPERSIZE: + { + bool bPreferPrinterPapersize; + if( *pValues >>= bPreferPrinterPapersize ) + { + bOk = true; + if( pDocSh->GetCreateMode() != SfxObjectCreateMode::EMBEDDED ) + { + SfxPrinter *pTempPrinter = pDocSh->GetPrinter( true ); + if (pTempPrinter) + pTempPrinter->SetPrinterSettingsPreferred( bPreferPrinterPapersize ); + } + } + } + break; + + case HANDLE_PARAGRAPHSUMMATION : + { + bool bIsSummationOfParagraphs = false; + if ( *pValues >>= bIsSummationOfParagraphs ) + { + bOk = true; + bChanged = true; + if ( pDoc->GetDocumentType() == DocumentType::Impress ) + { + EEControlBits nSum = bIsSummationOfParagraphs ? EEControlBits::ULSPACESUMMATION : EEControlBits::NONE; + EEControlBits nCntrl; + + pDoc->SetSummationOfParagraphs( bIsSummationOfParagraphs ); + SdDrawDocument* pDocument = pDocSh->GetDoc(); + SdrOutliner& rOutl = pDocument->GetDrawOutliner(); + nCntrl = rOutl.GetControlWord() &~ EEControlBits::ULSPACESUMMATION; + rOutl.SetControlWord( nCntrl | nSum ); + SdOutliner* pOutl = pDocument->GetOutliner( false ); + if( pOutl ) + { + nCntrl = pOutl->GetControlWord() &~ EEControlBits::ULSPACESUMMATION; + pOutl->SetControlWord( nCntrl | nSum ); + } + pOutl = pDocument->GetInternalOutliner( false ); + if( pOutl ) + { + nCntrl = pOutl->GetControlWord() &~ EEControlBits::ULSPACESUMMATION; + pOutl->SetControlWord( nCntrl | nSum ); + } + } + } + } + break; + + case HANDLE_CHARCOMPRESS: + { + sal_Int16 nCharCompressType = 0; + if( *pValues >>= nCharCompressType ) + { + bOk = true; + + pDoc->SetCharCompressType( static_cast<CharCompressType>(nCharCompressType) ); + SdDrawDocument* pDocument = pDocSh->GetDoc(); + SdrOutliner& rOutl = pDocument->GetDrawOutliner(); + rOutl.SetAsianCompressionMode( static_cast<CharCompressType>(nCharCompressType) ); + SdOutliner* pOutl = pDocument->GetOutliner( false ); + if( pOutl ) + { + pOutl->SetAsianCompressionMode( static_cast<CharCompressType>(nCharCompressType) ); + } + pOutl = pDocument->GetInternalOutliner( false ); + if( pOutl ) + { + pOutl->SetAsianCompressionMode( static_cast<CharCompressType>(nCharCompressType) ); + } + } + break; + + } + case HANDLE_ASIANPUNCT: + { + bool bAsianPunct = false; + if( *pValues >>= bAsianPunct ) + { + bOk = true; + + pDoc->SetKernAsianPunctuation( bAsianPunct ); + SdDrawDocument* pDocument = pDocSh->GetDoc(); + SdrOutliner& rOutl = pDocument->GetDrawOutliner(); + rOutl.SetKernAsianPunctuation( bAsianPunct ); + SdOutliner* pOutl = pDocument->GetOutliner( false ); + if( pOutl ) + { + pOutl->SetKernAsianPunctuation( bAsianPunct ); + } + pOutl = pDocument->GetInternalOutliner( false ); + if( pOutl ) + { + pOutl->SetKernAsianPunctuation( bAsianPunct ); + } + } + break; + + } + case HANDLE_UPDATEFROMTEMPLATE: + { + bool value = false; + if( *pValues >>= value ) + { + bChanged = ( value != pDocSh->IsQueryLoadTemplate() ); + pDocSh->SetQueryLoadTemplate( value ); + bOk = true; + } + } + break; + + case HANDLE_PRINTER_INDEPENDENT_LAYOUT: + { + // Just propagate the new printer independent layout mode to + // the document and determine it really differs from the old + // one. + sal_Int16 nOldValue = + static_cast<sal_Int16>(pDoc->GetPrinterIndependentLayout ()); + sal_Int16 nValue = 0; + if (*pValues >>= nValue) + { + pDoc->SetPrinterIndependentLayout (nValue); + bChanged = (nValue != nOldValue); + bOk = true; + } + } + break; + + // --> #i33095# + case HANDLE_LOAD_READONLY: + { + bool bNewValue = false; + if ( *pValues >>= bNewValue ) + { + bChanged = ( pDocSh->IsLoadReadonly() != bNewValue ); + pDocSh->SetLoadReadonly( bNewValue ); + bOk = true; + } + } + break; + + case HANDLE_MODIFY_PASSWD: + { + uno::Sequence< beans::PropertyValue > aInfo; + if ( !( *pValues >>= aInfo ) ) + throw lang::IllegalArgumentException( + "Value of type Sequence<PropertyValue> expected!", + uno::Reference< uno::XInterface >(), + 2 ); + + if ( !pDocSh->SetModifyPasswordInfo( aInfo ) ) + throw beans::PropertyVetoException( + "The hash is not allowed to be changed now!" ); + + bOk = true +; + + } + break; + + case HANDLE_SAVE_VERSION: + { + bool bNewValue = false; + if ( *pValues >>= bNewValue ) + { + bChanged = ( pDocSh->IsSaveVersionOnClose() != bNewValue ); + pDocSh->SetSaveVersionOnClose( bNewValue ); + bOk = true; + } + } + break; + + case HANDLE_EMBED_FONTS: + { + if (pValues->has<bool>()) + { + bool bNewValue = pValues->get<bool>(); + bChanged = (pDoc->IsEmbedFonts() != bNewValue); + pDoc->SetEmbedFonts(bNewValue); + bOk = true; + } + } + break; + + case HANDLE_EMBED_USED_FONTS: + { + if (pValues->has<bool>()) + { + bool bNewValue = pValues->get<bool>(); + bChanged = (pDoc->IsEmbedUsedFontsOnly() != bNewValue); + pDoc->SetEmbedUsedFontsOnly(bNewValue); + bOk = true; + } + } + break; + + case HANDLE_EMBED_LATIN_SCRIPT_FONTS: + { + if (pValues->has<bool>()) + { + bool bNewValue = pValues->get<bool>(); + bChanged = (pDoc->IsEmbedFontScriptLatin() != bNewValue); + pDoc->SetEmbedFontScriptLatin(bNewValue); + bOk = true; + } + } + break; + + case HANDLE_EMBED_ASIAN_SCRIPT_FONTS: + { + if (pValues->has<bool>()) + { + bool bNewValue = pValues->get<bool>(); + bChanged = (pDoc->IsEmbedFontScriptAsian() != bNewValue); + pDoc->SetEmbedFontScriptAsian(bNewValue); + bOk = true; + } + } + break; + + case HANDLE_EMBED_COMPLEX_SCRIPT_FONTS: + { + if (pValues->has<bool>()) + { + bool bNewValue = pValues->get<bool>(); + bChanged = (pDoc->IsEmbedFontScriptComplex() != bNewValue); + pDoc->SetEmbedFontScriptComplex(bNewValue); + bOk = true; + } + } + break; + + case HANDLE_IMAGE_PREFERRED_DPI: + { + if (pValues->has<sal_Int32>()) + { + auto nNewValue = pValues->get<sal_Int32>(); + bChanged = (pDoc->getImagePreferredDPI() != nNewValue); + pDoc->setImagePreferredDPI(nNewValue); + bOk = true; + } + } + break; + + default: + throw UnknownPropertyException( OUString::number((*ppEntries)->mnHandle), static_cast<cppu::OWeakObject*>(this)); + } + + if( !bOk ) + throw IllegalArgumentException(); + } + + if( bOptionsChanged ) + { + if( !pPrinter ) + pPrinter = pDocSh->GetPrinter( true ); + SfxItemSet aNewOptions( pPrinter->GetOptions() ); + aNewOptions.Put( aOptionsPrintItem ); + pPrinter->SetOptions( aNewOptions ); + } + + if( bChanged || bOptionsChanged ) + mxModel->SetModified(); +} + +void DocumentSettings::ExtractURL( XPropertyListType t, Any* pValue ) +{ + XPropertyListRef pList = mxModel->GetDoc()->GetPropertyList( t ); + if( !pList.is() ) + return; + + INetURLObject aPathURL( pList->GetPath() ); + aPathURL.insertName( pList->GetName() ); + aPathURL.setExtension( pList->GetDefaultExt() ); + OUString aPath( aPathURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ) ); + *pValue <<= aPath; +} + +void +DocumentSettings::_getPropertyValues( + const PropertyMapEntry** ppEntries, Any* pValue) +{ + ::SolarMutexGuard aGuard; + + SdDrawDocument* pDoc = mxModel->GetDoc(); + ::sd::DrawDocShell* pDocSh = mxModel->GetDocShell(); + if( nullptr == pDoc || nullptr == pDocSh ) + { + throw RuntimeException("Document or Shell missing", + static_cast<OWeakObject *>(this)); + } + + SdOptionsPrintItem aOptionsPrintItem; + + SfxPrinter* pPrinter = pDocSh->GetPrinter( false ); + if( pPrinter ) + { + SdOptionsPrintItem const * pPrinterOptions = pPrinter->GetOptions().GetItemIfSet( ATTR_OPTIONS_PRINT, false ); + if (pPrinterOptions) + aOptionsPrintItem.GetOptionsPrint() = pPrinterOptions->GetOptionsPrint(); + } + else + { + aOptionsPrintItem.SetOptions( SD_MOD()->GetSdOptions(pDoc->GetDocumentType()) ); + } + SdOptionsPrint& aPrintOpts = aOptionsPrintItem.GetOptionsPrint(); + + for( ; *ppEntries; ppEntries++, pValue++ ) + { + switch( (*ppEntries)->mnHandle ) + { + case HANDLE_COLORTABLEURL: + ExtractURL( XPropertyListType::Color, pValue ); + break; + case HANDLE_DASHTABLEURL: + ExtractURL( XPropertyListType::Dash, pValue ); + break; + case HANDLE_LINEENDTABLEURL: + ExtractURL( XPropertyListType::LineEnd, pValue ); + break; + case HANDLE_HATCHTABLEURL: + ExtractURL( XPropertyListType::Hatch, pValue ); + break; + case HANDLE_GRADIENTTABLEURL: + ExtractURL( XPropertyListType::Gradient, pValue ); + break; + case HANDLE_BITMAPTABLEURL: + ExtractURL( XPropertyListType::Bitmap, pValue ); + break; + case HANDLE_FORBIDDENCHARS: + *pValue <<= mxModel->getForbiddenCharsTable(); + break; + case HANDLE_APPLYUSERDATA: + *pValue <<= pDocSh->IsUseUserData(); + break; + case HANDLE_SAVETHUMBNAIL: + *pValue <<= pDocSh->IsUseThumbnailSave(); + break; + case HANDLE_PRINTDRAWING: + *pValue <<= aPrintOpts.IsDraw(); + break; + case HANDLE_PRINTNOTES: + *pValue <<= aPrintOpts.IsNotes(); + break; + case HANDLE_PRINTHANDOUT: + *pValue <<= aPrintOpts.IsHandout(); + break; + case HANDLE_PRINTOUTLINE: + *pValue <<= aPrintOpts.IsOutline(); + break; + case HANDLE_SLIDESPERHANDOUT: + *pValue <<= static_cast<sal_Int16>(aPrintOpts.GetHandoutPages()); + break; + case HANDLE_HANDOUTHORIZONTAL: + *pValue <<= aPrintOpts.IsHandoutHorizontal(); + break; + case HANDLE_PRINTPAGENAME: + *pValue <<= aPrintOpts.IsPagename(); + break; + case HANDLE_PRINTDATE: + *pValue <<= aPrintOpts.IsDate(); + break; + case HANDLE_PRINTTIME: + *pValue <<= aPrintOpts.IsTime(); + break; + case HANDLE_PRINTHIDDENPAGES: + *pValue <<= aPrintOpts.IsHiddenPages(); + break; + case HANDLE_PRINTFITPAGE: + *pValue <<= aPrintOpts.IsPagesize(); + break; + case HANDLE_PRINTTILEPAGE: + *pValue <<= aPrintOpts.IsPagetile(); + break; + case HANDLE_PRINTBOOKLET: + *pValue <<= aPrintOpts.IsBooklet(); + break; + case HANDLE_PRINTBOOKLETFRONT: + *pValue <<= aPrintOpts.IsFrontPage(); + break; + case HANDLE_PRINTBOOKLETBACK: + *pValue <<= aPrintOpts.IsBackPage(); + break; + case HANDLE_PRINTQUALITY: + *pValue <<= static_cast<sal_Int32>(aPrintOpts.GetOutputQuality()); + break; + case HANDLE_MEASUREUNIT: + { + short nMeasure; + SvxFieldUnitToMeasureUnit( pDoc->GetUIUnit(), nMeasure ); + *pValue <<= static_cast<sal_Int16>(nMeasure); + } + break; + case HANDLE_SCALE_NUM: + *pValue <<= pDoc->GetUIScale().GetNumerator(); + break; + case HANDLE_SCALE_DOM: + *pValue <<= pDoc->GetUIScale().GetDenominator(); + break; + case HANDLE_TABSTOP: + *pValue <<= static_cast<sal_Int32>(pDoc->GetDefaultTabulator()); + break; + case HANDLE_PAGENUMFMT: + *pValue <<= static_cast<sal_Int32>(pDoc->GetPageNumType()); + break; + case HANDLE_PRINTERNAME: + { + SfxPrinter *pTempPrinter = pDocSh->GetPrinter( false ); + *pValue <<= pTempPrinter ? pTempPrinter->GetName() : OUString(); + } + break; + case HANDLE_PRINTERJOB: + { + SfxPrinter *pTempPrinter = pDocSh->GetPrinter( false ); + if (pTempPrinter) + { + SvMemoryStream aStream; + pTempPrinter->Store( aStream ); + *pValue <<= Sequence< sal_Int8 >( static_cast< const sal_Int8* >( aStream.GetData() ), + aStream.TellEnd() ); + } + else + { + Sequence < sal_Int8 > aSequence; + *pValue <<= aSequence; + } + } + break; + + case HANDLE_PRINTERPAPERSIZE: + { + SfxPrinter *pTempPrinter = pDocSh->GetPrinter( false ); + *pValue <<= pTempPrinter && pTempPrinter->GetPrinterSettingsPreferred(); + } + break; + + case HANDLE_PARAGRAPHSUMMATION : + { + bool bIsSummationOfParagraphs = pDoc->IsSummationOfParagraphs(); + *pValue <<= bIsSummationOfParagraphs; + } + break; + + case HANDLE_CHARCOMPRESS: + { + *pValue <<= static_cast<sal_Int16>(pDoc->GetCharCompressType()); + break; + } + + case HANDLE_ASIANPUNCT: + { + *pValue <<= pDoc->IsKernAsianPunctuation(); + break; + } + + case HANDLE_UPDATEFROMTEMPLATE: + { + *pValue <<= pDocSh->IsQueryLoadTemplate(); + } + break; + + case HANDLE_PRINTER_INDEPENDENT_LAYOUT: + { + sal_Int16 nPrinterIndependentLayout = + static_cast<sal_Int16>(pDoc->GetPrinterIndependentLayout()); + *pValue <<= nPrinterIndependentLayout; + } + break; + + // --> #i33095# + case HANDLE_LOAD_READONLY: + { + *pValue <<= pDocSh->IsLoadReadonly(); + } + break; + + case HANDLE_MODIFY_PASSWD: + { + *pValue <<= pDocSh->GetModifyPasswordInfo(); + } + break; + + case HANDLE_SAVE_VERSION: + { + *pValue <<= pDocSh->IsSaveVersionOnClose(); + } + break; + + case HANDLE_EMBED_FONTS: + { + *pValue <<= pDoc->IsEmbedFonts(); + } + break; + + case HANDLE_EMBED_USED_FONTS: + { + *pValue <<= pDoc->IsEmbedUsedFontsOnly(); + } + break; + + case HANDLE_EMBED_LATIN_SCRIPT_FONTS: + { + *pValue <<= pDoc->IsEmbedFontScriptLatin(); + } + break; + + case HANDLE_EMBED_ASIAN_SCRIPT_FONTS: + { + *pValue <<= pDoc->IsEmbedFontScriptAsian(); + } + break; + + case HANDLE_EMBED_COMPLEX_SCRIPT_FONTS: + { + *pValue <<= pDoc->IsEmbedFontScriptComplex(); + } + break; + + case HANDLE_IMAGE_PREFERRED_DPI: + { + *pValue <<= pDoc->getImagePreferredDPI(); + } + break; + + default: + throw UnknownPropertyException( OUString::number((*ppEntries)->mnHandle), static_cast<cppu::OWeakObject*>(this)); + } + } +} + +// XInterface +Any SAL_CALL DocumentSettings::queryInterface( const Type& aType ) +{ + return WeakImplHelper< XPropertySet, XMultiPropertySet, XServiceInfo >::queryInterface( aType ); +} + +void SAL_CALL DocumentSettings::acquire( ) noexcept +{ + WeakImplHelper< XPropertySet, XMultiPropertySet, XServiceInfo >::acquire(); +} + +void SAL_CALL DocumentSettings::release( ) noexcept +{ + WeakImplHelper< XPropertySet, XMultiPropertySet, XServiceInfo >::release(); +} + +// XPropertySet +Reference< XPropertySetInfo > SAL_CALL DocumentSettings::getPropertySetInfo( ) +{ + return PropertySetHelper::getPropertySetInfo(); +} + +void SAL_CALL DocumentSettings::setPropertyValue( const OUString& aPropertyName, const Any& aValue ) +{ + PropertySetHelper::setPropertyValue( aPropertyName, aValue ); +} + +Any SAL_CALL DocumentSettings::getPropertyValue( const OUString& PropertyName ) +{ + return PropertySetHelper::getPropertyValue( PropertyName ); +} + +void SAL_CALL DocumentSettings::addPropertyChangeListener( const OUString& aPropertyName, const Reference< XPropertyChangeListener >& xListener ) +{ + PropertySetHelper::addPropertyChangeListener( aPropertyName, xListener ); +} + +void SAL_CALL DocumentSettings::removePropertyChangeListener( const OUString& aPropertyName, const Reference< XPropertyChangeListener >& aListener ) +{ + PropertySetHelper::removePropertyChangeListener( aPropertyName, aListener ); +} + +void SAL_CALL DocumentSettings::addVetoableChangeListener( const OUString& PropertyName, const Reference< XVetoableChangeListener >& aListener ) +{ + PropertySetHelper::addVetoableChangeListener( PropertyName, aListener ); +} + +void SAL_CALL DocumentSettings::removeVetoableChangeListener( const OUString& PropertyName, const Reference< XVetoableChangeListener >& aListener ) +{ + PropertySetHelper::removeVetoableChangeListener( PropertyName, aListener ); +} + +// XMultiPropertySet +void SAL_CALL DocumentSettings::setPropertyValues( const Sequence< OUString >& aPropertyNames, const Sequence< Any >& aValues ) +{ + PropertySetHelper::setPropertyValues( aPropertyNames, aValues ); +} + +Sequence< Any > SAL_CALL DocumentSettings::getPropertyValues( const Sequence< OUString >& aPropertyNames ) +{ + return PropertySetHelper::getPropertyValues( aPropertyNames ); +} + +void SAL_CALL DocumentSettings::addPropertiesChangeListener( const Sequence< OUString >& aPropertyNames, const Reference< XPropertiesChangeListener >& xListener ) +{ + PropertySetHelper::addPropertiesChangeListener( aPropertyNames, xListener ); +} + +void SAL_CALL DocumentSettings::removePropertiesChangeListener( const Reference< XPropertiesChangeListener >& xListener ) +{ + PropertySetHelper::removePropertiesChangeListener( xListener ); +} + +void SAL_CALL DocumentSettings::firePropertiesChangeEvent( const Sequence< OUString >& aPropertyNames, const Reference< XPropertiesChangeListener >& xListener ) +{ + PropertySetHelper::firePropertiesChangeEvent( aPropertyNames, xListener ); +} + +// XServiceInfo +OUString SAL_CALL DocumentSettings::getImplementationName( ) +{ + return "com.sun.star.comp.Draw.DocumentSettings"; +} + +sal_Bool SAL_CALL DocumentSettings::supportsService( const OUString& ServiceName ) +{ + return cppu::supportsService(this, ServiceName); +} + +Sequence< OUString > SAL_CALL DocumentSettings::getSupportedServiceNames( ) +{ + return { "com.sun.star.document.Settings" , + mxModel->IsImpressDocument()?OUString("com.sun.star.presentation.DocumentSettings"):OUString("com.sun.star.drawing.DocumentSettings") }; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/unoidl/UnoDocumentSettings.hxx b/sd/source/ui/unoidl/UnoDocumentSettings.hxx new file mode 100644 index 000000000..bba3c66b1 --- /dev/null +++ b/sd/source/ui/unoidl/UnoDocumentSettings.hxx @@ -0,0 +1,37 @@ +/* -*- 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/uno/Reference.hxx> + +namespace com::sun::star::uno +{ +class XInterface; +} + +class SdXImpressDocument; + +namespace sd +{ +css::uno::Reference<css::uno::XInterface> +DocumentSettings_createInstance(SdXImpressDocument* pDoc) noexcept; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/unoidl/randomnode.cxx b/sd/source/ui/unoidl/randomnode.cxx new file mode 100644 index 000000000..a87ae1783 --- /dev/null +++ b/sd/source/ui/unoidl/randomnode.cxx @@ -0,0 +1,573 @@ +/* -*- 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 <com/sun/star/animations/XTimeContainer.hpp> +#include <com/sun/star/presentation/ParagraphTarget.hpp> +#include <com/sun/star/animations/AnimationFill.hpp> +#include <com/sun/star/animations/AnimationNodeType.hpp> +#include <com/sun/star/animations/XAnimate.hpp> +#include <com/sun/star/animations/AnimationRestart.hpp> +#include <com/sun/star/animations/ParallelTimeContainer.hpp> +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/container/XEnumerationAccess.hpp> +#include <com/sun/star/util/XCloneable.hpp> +#include <comphelper/processfactory.hxx> + +#include <cppuhelper/implbase.hxx> +#include <cppuhelper/supportsservice.hxx> +#include <cppuhelper/weakref.hxx> +#include <osl/mutex.hxx> +#include <CustomAnimationPreset.hxx> +#include <randomnode.hxx> + +using ::osl::Mutex; +using ::osl::Guard; + +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::uno::Any; +using ::com::sun::star::uno::UNO_QUERY; +using ::com::sun::star::uno::XInterface; +using ::com::sun::star::uno::WeakReference; +using ::com::sun::star::beans::NamedValue; +using ::com::sun::star::lang::IllegalArgumentException; +using ::com::sun::star::container::XEnumeration; +using ::com::sun::star::container::XEnumerationAccess; +using ::com::sun::star::util::XCloneable; +using ::com::sun::star::lang::XServiceInfo; +using ::com::sun::star::lang::XInitialization; +using ::com::sun::star::uno::Type; +using ::com::sun::star::uno::XWeak; +using ::com::sun::star::presentation::ParagraphTarget; +using ::com::sun::star::drawing::XShape; + +using namespace ::com::sun::star::animations; + +namespace sd +{ + +typedef ::cppu::WeakImplHelper< XTimeContainer, XEnumerationAccess, XCloneable, XServiceInfo, XInitialization > RandomAnimationNodeBase; + +namespace { + +class RandomAnimationNode : public RandomAnimationNodeBase +{ +public: + RandomAnimationNode( const RandomAnimationNode& rNode ); + explicit RandomAnimationNode( sal_Int16 nPresetClass ); + RandomAnimationNode(); + + void init( sal_Int16 nPresetClass ); + + // XInitialization + void SAL_CALL initialize( const Sequence< Any >& aArguments ) override; + + // XChild + Reference< XInterface > SAL_CALL getParent( ) override; + void SAL_CALL setParent( const Reference< XInterface >& Parent ) override; + + // XCloneable + virtual Reference< XCloneable > SAL_CALL createClone() override; + + // XServiceInfo + OUString SAL_CALL getImplementationName() override; + Sequence< OUString > SAL_CALL getSupportedServiceNames() override; + sal_Bool SAL_CALL supportsService(const OUString& ServiceName) override; + + // XAnimationNode + ::sal_Int16 SAL_CALL getType() override; + Any SAL_CALL getBegin() override; + void SAL_CALL setBegin( const Any& _begin ) override; + Any SAL_CALL getDuration() override; + void SAL_CALL setDuration( const Any& _duration ) override; + Any SAL_CALL getEnd() override; + void SAL_CALL setEnd( const Any& _end ) override; + Any SAL_CALL getEndSync() override; + void SAL_CALL setEndSync( const Any& _endsync ) override; + Any SAL_CALL getRepeatCount() override; + void SAL_CALL setRepeatCount( const Any& _repeatcount ) override; + Any SAL_CALL getRepeatDuration() override; + void SAL_CALL setRepeatDuration( const Any& _repeatduration ) override; + ::sal_Int16 SAL_CALL getFill() override; + void SAL_CALL setFill( ::sal_Int16 _fill ) override; + ::sal_Int16 SAL_CALL getFillDefault() override; + void SAL_CALL setFillDefault( ::sal_Int16 _filldefault ) override; + ::sal_Int16 SAL_CALL getRestart() override; + void SAL_CALL setRestart( ::sal_Int16 _restart ) override; + ::sal_Int16 SAL_CALL getRestartDefault() override; + void SAL_CALL setRestartDefault( ::sal_Int16 _restartdefault ) override; + double SAL_CALL getAcceleration() override; + void SAL_CALL setAcceleration( double _acceleration ) override; + double SAL_CALL getDecelerate() override; + void SAL_CALL setDecelerate( double _decelerate ) override; + sal_Bool SAL_CALL getAutoReverse() override; + void SAL_CALL setAutoReverse( sal_Bool _autoreverse ) override; + Sequence< NamedValue > SAL_CALL getUserData() override; + void SAL_CALL setUserData( const Sequence< NamedValue >& _userdata ) override; + + // XElementAccess + virtual Type SAL_CALL getElementType() override; + virtual sal_Bool SAL_CALL hasElements() override; + + // XEnumerationAccess + virtual Reference< XEnumeration > SAL_CALL createEnumeration() override; + + // XTimeContainer + Reference< XAnimationNode > SAL_CALL insertBefore( const Reference< XAnimationNode >& newChild, const Reference< XAnimationNode >& refChild ) override; + Reference< XAnimationNode > SAL_CALL insertAfter( const Reference< XAnimationNode >& newChild, const Reference< XAnimationNode >& refChild ) override; + Reference< XAnimationNode > SAL_CALL replaceChild( const Reference< XAnimationNode >& newChild, const Reference< XAnimationNode >& oldChild ) override; + Reference< XAnimationNode > SAL_CALL removeChild( const Reference< XAnimationNode >& oldChild ) override; + Reference< XAnimationNode > SAL_CALL appendChild( const Reference< XAnimationNode >& newChild ) override; + +private: + // our first, last and only protection from multi-threads! + Mutex maMutex; + + sal_Int16 mnPresetClass; + WeakReference<XInterface> mxParent; + + Any maBegin, maDuration, maEnd, maEndSync, maRepeatCount, maRepeatDuration, maTarget; + sal_Int16 mnFill, mnFillDefault, mnRestart, mnRestartDefault; + double mfAcceleration, mfDecelerate; + bool mbAutoReverse; + Sequence< NamedValue > maUserData; + + Reference< XAnimate > mxFirstNode; +}; + +} + +Reference< XInterface > RandomAnimationNode_createInstance( sal_Int16 nPresetClass ) +{ + Reference< XInterface > xInt( static_cast<XWeak*>( new RandomAnimationNode( nPresetClass ) ) ); + return xInt; +} + +RandomAnimationNode::RandomAnimationNode( const RandomAnimationNode& rNode ) +: RandomAnimationNodeBase(rNode), + mnPresetClass( rNode.mnPresetClass ), + maBegin( rNode.maBegin ), + maDuration( rNode.maDuration ), + maEnd( rNode.maEnd ), + maEndSync( rNode.maEndSync ), + maRepeatCount( rNode.maRepeatCount ), + maRepeatDuration( rNode.maRepeatDuration ), + maTarget( rNode.maTarget ), + mnFill( rNode.mnFill ), + mnFillDefault( rNode.mnFillDefault ), + mnRestart( rNode.mnRestart ), + mnRestartDefault( rNode.mnRestartDefault ), + mfAcceleration( rNode.mfAcceleration ), + mfDecelerate( rNode.mfDecelerate ), + mbAutoReverse( rNode.mbAutoReverse ), + maUserData( rNode.maUserData ) +{ +} + +RandomAnimationNode::RandomAnimationNode( sal_Int16 nPresetClass ) +{ + init( nPresetClass ); +} + +RandomAnimationNode::RandomAnimationNode() +{ + init( 1 ); +} + +void RandomAnimationNode::init( sal_Int16 nPresetClass ) +{ + mnPresetClass = nPresetClass; + mnFill = AnimationFill::DEFAULT; + mnFillDefault = AnimationFill::INHERIT; + mnRestart = AnimationRestart::DEFAULT; + mnRestartDefault = AnimationRestart::INHERIT; + mfAcceleration = 0.0; + mfDecelerate = 0.0; + mbAutoReverse = false; +} + +// XInitialization +void SAL_CALL RandomAnimationNode::initialize( const Sequence< Any >& aArguments ) +{ + if( aArguments.getLength() != 1 ) + throw IllegalArgumentException(); + + if( aArguments[0].getValueType() == ::cppu::UnoType<sal_Int16>::get() ) + { + aArguments[0] >>= mnPresetClass; + } + else if( aArguments[0].getValueType() != ::cppu::UnoType<ParagraphTarget>::get() ) + { + Reference< XShape > xShape; + aArguments[0] >>= xShape; + if( !xShape.is() ) + throw IllegalArgumentException(); + } + maTarget = aArguments[0]; +} + +// XAnimationNode +sal_Int16 SAL_CALL RandomAnimationNode::getType() +{ + Guard< Mutex > aGuard( maMutex ); + return css::animations::AnimationNodeType::PAR; +} + +// XAnimationNode +Any SAL_CALL RandomAnimationNode::getBegin() +{ + Guard< Mutex > aGuard( maMutex ); + return maBegin; +} + +// XAnimationNode +void SAL_CALL RandomAnimationNode::setBegin( const Any& _begin ) +{ + Guard< Mutex > aGuard( maMutex ); + maBegin = _begin; +} + +// XAnimationNode +Any SAL_CALL RandomAnimationNode::getDuration() +{ + Guard< Mutex > aGuard( maMutex ); + return maDuration; +} + +// XAnimationNode +void SAL_CALL RandomAnimationNode::setDuration( const Any& _duration ) +{ + Guard< Mutex > aGuard( maMutex ); + maDuration = _duration; +} + +// XAnimationNode +Any SAL_CALL RandomAnimationNode::getEnd() +{ + Guard< Mutex > aGuard( maMutex ); + return maEnd; +} + +// XAnimationNode +void SAL_CALL RandomAnimationNode::setEnd( const Any& _end ) +{ + Guard< Mutex > aGuard( maMutex ); + maEnd = _end; +} + +// XAnimationNode +Any SAL_CALL RandomAnimationNode::getEndSync() +{ + Guard< Mutex > aGuard( maMutex ); + return maEndSync; +} + +// XAnimationNode +void SAL_CALL RandomAnimationNode::setEndSync( const Any& _endsync ) +{ + Guard< Mutex > aGuard( maMutex ); + maEndSync = _endsync; +} + +// XAnimationNode +Any SAL_CALL RandomAnimationNode::getRepeatCount() +{ + Guard< Mutex > aGuard( maMutex ); + return maRepeatCount; +} + +// XAnimationNode +void SAL_CALL RandomAnimationNode::setRepeatCount( const Any& _repeatcount ) +{ + Guard< Mutex > aGuard( maMutex ); + maRepeatCount = _repeatcount; +} + +// XAnimationNode +Any SAL_CALL RandomAnimationNode::getRepeatDuration() +{ + Guard< Mutex > aGuard( maMutex ); + return maRepeatDuration; +} + +// XAnimationNode +void SAL_CALL RandomAnimationNode::setRepeatDuration( const Any& _repeatduration ) +{ + Guard< Mutex > aGuard( maMutex ); + maRepeatDuration = _repeatduration; +} + +// XAnimationNode +sal_Int16 SAL_CALL RandomAnimationNode::getFill() +{ + Guard< Mutex > aGuard( maMutex ); + return mnFill; +} + +// XAnimationNode +void SAL_CALL RandomAnimationNode::setFill( sal_Int16 _fill ) +{ + Guard< Mutex > aGuard( maMutex ); + mnFill = _fill; +} + +// XAnimationNode +sal_Int16 SAL_CALL RandomAnimationNode::getFillDefault() +{ + Guard< Mutex > aGuard( maMutex ); + return mnFillDefault; +} + +// XAnimationNode +void SAL_CALL RandomAnimationNode::setFillDefault( sal_Int16 _filldefault ) +{ + Guard< Mutex > aGuard( maMutex ); + mnFillDefault = _filldefault; +} + +// XAnimationNode +sal_Int16 SAL_CALL RandomAnimationNode::getRestart() +{ + Guard< Mutex > aGuard( maMutex ); + return mnRestart; +} + +// XAnimationNode +void SAL_CALL RandomAnimationNode::setRestart( sal_Int16 _restart ) +{ + Guard< Mutex > aGuard( maMutex ); + mnRestart = _restart; +} + +// XAnimationNode +sal_Int16 SAL_CALL RandomAnimationNode::getRestartDefault() +{ + Guard< Mutex > aGuard( maMutex ); + return mnRestartDefault; +} + +// XAnimationNode +void SAL_CALL RandomAnimationNode::setRestartDefault( sal_Int16 _restartdefault ) +{ + Guard< Mutex > aGuard( maMutex ); + mnRestartDefault = _restartdefault; +} + +// XAnimationNode +double SAL_CALL RandomAnimationNode::getAcceleration() +{ + Guard< Mutex > aGuard( maMutex ); + return mfAcceleration; +} + +// XAnimationNode +void SAL_CALL RandomAnimationNode::setAcceleration( double _acceleration ) +{ + Guard< Mutex > aGuard( maMutex ); + mfAcceleration = _acceleration; +} + +// XAnimationNode +double SAL_CALL RandomAnimationNode::getDecelerate() +{ + Guard< Mutex > aGuard( maMutex ); + return mfDecelerate; +} + +// XAnimationNode +void SAL_CALL RandomAnimationNode::setDecelerate( double _decelerate ) +{ + Guard< Mutex > aGuard( maMutex ); + mfDecelerate = _decelerate; +} + +// XAnimationNode +sal_Bool SAL_CALL RandomAnimationNode::getAutoReverse() +{ + Guard< Mutex > aGuard( maMutex ); + return mbAutoReverse; +} + +// XAnimationNode +void SAL_CALL RandomAnimationNode::setAutoReverse( sal_Bool _autoreverse ) +{ + Guard< Mutex > aGuard( maMutex ); + mbAutoReverse = _autoreverse; +} + +Sequence< NamedValue > SAL_CALL RandomAnimationNode::getUserData() +{ + Guard< Mutex > aGuard( maMutex ); + return maUserData; +} + +void SAL_CALL RandomAnimationNode::setUserData( const Sequence< NamedValue >& _userdata ) +{ + Guard< Mutex > aGuard( maMutex ); + maUserData = _userdata; +} + +// XChild +Reference< XInterface > SAL_CALL RandomAnimationNode::getParent() +{ + Guard< Mutex > aGuard( maMutex ); + return mxParent.get(); +} + +// XChild +void SAL_CALL RandomAnimationNode::setParent( const Reference< XInterface >& Parent ) +{ + Guard< Mutex > aGuard( maMutex ); + mxParent = Parent; +} + +// XCloneable +Reference< XCloneable > SAL_CALL RandomAnimationNode::createClone() +{ + Reference< XCloneable > xNewNode( new RandomAnimationNode( *this ) ); + return xNewNode; +} + +// XElementAccess +Type SAL_CALL RandomAnimationNode::getElementType() +{ + return cppu::UnoType<XAnimationNode>::get(); +} + +// XElementAccess +sal_Bool SAL_CALL RandomAnimationNode::hasElements() +{ + return true; +} + +// XEnumerationAccess +Reference< XEnumeration > SAL_CALL RandomAnimationNode::createEnumeration() +{ + Guard< Mutex > aGuard( maMutex ); + + if( !maTarget.hasValue() && mxFirstNode.is() ) + { + Any aTarget( mxFirstNode->getTarget() ); + if( aTarget.hasValue() ) + { + maTarget = aTarget; + mxFirstNode.clear(); + } + } + + Reference< XEnumeration > xEnum; + + Reference< XEnumerationAccess > aEnumAccess( CustomAnimationPresets::getCustomAnimationPresets().getRandomPreset( mnPresetClass ), UNO_QUERY ); + + if( aEnumAccess.is() ) + { + Reference< XEnumeration > xEnumeration = aEnumAccess->createEnumeration(); + if( xEnumeration.is() ) + { + while( xEnumeration->hasMoreElements() ) + { + Reference< XAnimate > xAnimate( xEnumeration->nextElement(), UNO_QUERY ); + if( xAnimate.is() ) + xAnimate->setTarget( maTarget ); + } + } + xEnum = aEnumAccess->createEnumeration(); + } + else + { + // no presets? give empty node! + Reference< XParallelTimeContainer > xTimeContainer = ParallelTimeContainer::create( comphelper::getProcessComponentContext() ); + xEnum = xTimeContainer->createEnumeration(); + } + + return xEnum; +} + +// XTimeContainer +Reference< XAnimationNode > SAL_CALL RandomAnimationNode::insertBefore( const Reference< XAnimationNode >& newChild, const Reference< XAnimationNode >& ) +{ + return appendChild( newChild ); +} + +// XTimeContainer +Reference< XAnimationNode > SAL_CALL RandomAnimationNode::insertAfter( const Reference< XAnimationNode >& newChild, const Reference< XAnimationNode >& ) +{ + return appendChild( newChild ); +} + +// XTimeContainer +Reference< XAnimationNode > SAL_CALL RandomAnimationNode::replaceChild( const Reference< XAnimationNode >& newChild, const Reference< XAnimationNode >& ) +{ + return appendChild( newChild ); +} + +// XTimeContainer +Reference< XAnimationNode > SAL_CALL RandomAnimationNode::removeChild( const Reference< XAnimationNode >& oldChild ) +{ + return oldChild; +} + +// XTimeContainer +Reference< XAnimationNode > SAL_CALL RandomAnimationNode::appendChild( const Reference< XAnimationNode >& newChild ) +{ + Reference< XAnimate > xAnimate( newChild, UNO_QUERY ); + if( xAnimate.is() ) + { + Any aTarget( xAnimate->getTarget() ); + if( aTarget.hasValue() ) + maTarget = aTarget; + } + + if( !maTarget.hasValue() && !mxFirstNode.is() ) + mxFirstNode = xAnimate; + + return newChild; +} + +// XServiceInfo +OUString RandomAnimationNode::getImplementationName() +{ + return "sd::RandomAnimationNode" ; +} + +// XServiceInfo +sal_Bool RandomAnimationNode::supportsService(const OUString& ServiceName) +{ + return cppu::supportsService(this, ServiceName); +} + +// XServiceInfo +Sequence< OUString > RandomAnimationNode::getSupportedServiceNames() +{ + return { "com.sun.star.animations.ParallelTimeContainer", "com.sun.star.comp.sd.RandomAnimationNode" }; +} + +} + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* +RandomAnimationNode_get_implementation(css::uno::XComponentContext*, + css::uno::Sequence<css::uno::Any> const &) +{ + return cppu::acquire(new sd::RandomAnimationNode()); +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/unoidl/sddetect.cxx b/sd/source/ui/unoidl/sddetect.cxx new file mode 100644 index 000000000..cfa50d141 --- /dev/null +++ b/sd/source/ui/unoidl/sddetect.cxx @@ -0,0 +1,160 @@ +/* -*- 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 "sddetect.hxx" + +#include <com/sun/star/beans/PropertyValue.hpp> +#include <cppuhelper/supportsservice.hxx> +#include <com/sun/star/io/XInputStream.hpp> +#include <com/sun/star/ucb/ContentCreationException.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <vcl/graphicfilter.hxx> +#include <sfx2/docfile.hxx> +#include <sfx2/docfilt.hxx> +#include <sfx2/fcontnr.hxx> +#include <vcl/FilterConfigItem.hxx> +#include <sot/storage.hxx> +#include <unotools/mediadescriptor.hxx> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::io; +using namespace ::com::sun::star::task; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::lang; +using utl::MediaDescriptor; + +SdFilterDetect::SdFilterDetect() +{ +} + +SdFilterDetect::~SdFilterDetect() +{ +} + +OUString SAL_CALL SdFilterDetect::detect( Sequence< beans::PropertyValue >& lDescriptor ) +{ + MediaDescriptor aMediaDesc( lDescriptor ); + OUString aTypeName = aMediaDesc.getUnpackedValueOrDefault( MediaDescriptor::PROP_TYPENAME, OUString() ); + uno::Reference< io::XInputStream > xInStream ( aMediaDesc[MediaDescriptor::PROP_INPUTSTREAM], uno::UNO_QUERY ); + if ( !xInStream.is() ) + return OUString(); + + SfxMedium aMedium; + aMedium.UseInteractionHandler( false ); + aMedium.setStreamToLoadFrom( xInStream, true ); + + SvStream *pInStrm = aMedium.GetInStream(); + if ( !pInStrm || pInStrm->GetError() ) + return OUString(); + + if ( aTypeName.startsWith( "impress_MS_PowerPoint_97" ) ) + { + // Do not attempt to create an SotStorage on a + // 0-length stream as that would create the compound + // document header on the stream and effectively write to + // disk! + pInStrm->Seek( STREAM_SEEK_TO_BEGIN ); + if ( pInStrm->remainingSize() == 0 ) + return OUString(); + + try + { + tools::SvRef<SotStorage> aStorage = new SotStorage( pInStrm, false ); + if ( !aStorage->GetError() && aStorage->IsStream( "PowerPoint Document" ) ) + return aTypeName; + } + catch (const css::ucb::ContentCreationException&) + { + } + } + else + { + pInStrm->Seek( STREAM_SEEK_TO_BEGIN ); + + const OUString aFileName( aMediaDesc.getUnpackedValueOrDefault( MediaDescriptor::PROP_URL, OUString() ) ); + GraphicDescriptor aDesc( *pInStrm, &aFileName ); + if( !aDesc.Detect() ) + { + INetURLObject aCheckURL( aFileName ); + if( aCheckURL.getExtension().equalsIgnoreAsciiCase("cgm") ) + { + sal_uInt8 n8; + pInStrm->Seek( STREAM_SEEK_TO_BEGIN ); + pInStrm->ReadUChar( n8 ); + if ( ( n8 & 0xf0 ) == 0 ) + // we are supporting binary cgm format only, so + // this is a small test to exclude cgm text + return "impress_CGM_Computer_Graphics_Metafile"; + } + } + else + { + OUString aShortName( GraphicDescriptor::GetImportFormatShortName( aDesc.GetFileFormat() ) ); + GraphicFilter &rGrfFilter = GraphicFilter::GetGraphicFilter(); + const OUString aName( rGrfFilter.GetImportFormatTypeName( rGrfFilter.GetImportFormatNumberForShortName( aShortName ) ) ); + + if ( aShortName.equalsIgnoreAsciiCase( "PCD" ) ) // there is a multiple pcd selection possible + { + sal_Int32 nBase = 2; // default Base0 + if ( aTypeName == "pcd_Photo_CD_Base4" ) + nBase = 1; + else if ( aTypeName == "pcd_Photo_CD_Base16" ) + nBase = 0; + FilterConfigItem aFilterConfigItem( u"Office.Common/Filter/Graphic/Import/PCD" ); + aFilterConfigItem.WriteInt32( "Resolution" , nBase ); + } + + SfxFilterMatcher aMatch("sdraw"); + std::shared_ptr<const SfxFilter> pFilter = aMatch.GetFilter4FilterName( aName ); + if ( pFilter ) + return pFilter->GetRealTypeName(); + } + } + + return OUString(); +} + +// XServiceInfo +OUString SAL_CALL SdFilterDetect::getImplementationName() +{ + return "com.sun.star.comp.draw.FormatDetector"; +} + +// XServiceInfo +sal_Bool SAL_CALL SdFilterDetect::supportsService( const OUString& sServiceName ) +{ + return cppu::supportsService(this, sServiceName); +} + +// XServiceInfo +Sequence< OUString > SAL_CALL SdFilterDetect::getSupportedServiceNames() +{ + return { "com.sun.star.frame.ExtendedTypeDetection" }; +} + + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* +com_sun_star_comp_draw_FormatDetector_get_implementation(css::uno::XComponentContext*, + css::uno::Sequence<css::uno::Any> const &) +{ + return cppu::acquire(new SdFilterDetect()); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/unoidl/sddetect.hxx b/sd/source/ui/unoidl/sddetect.hxx new file mode 100644 index 000000000..3d22cc12c --- /dev/null +++ b/sd/source/ui/unoidl/sddetect.hxx @@ -0,0 +1,48 @@ +/* -*- 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 <rtl/ustring.hxx> +#include <com/sun/star/document/XExtendedFilterDetection.hpp> +#include <cppuhelper/implbase.hxx> + +#include <com/sun/star/lang/XServiceInfo.hpp> + + +namespace com::sun::star::beans { struct PropertyValue; } + +class SdFilterDetect : public ::cppu::WeakImplHelper< css::document::XExtendedFilterDetection, css::lang::XServiceInfo > +{ +public: + SdFilterDetect(); + virtual ~SdFilterDetect() 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; + + // XExtendedFilterDetect + + virtual OUString SAL_CALL detect( css::uno::Sequence< css::beans::PropertyValue >& lDescriptor ) override; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/unoidl/unocpres.cxx b/sd/source/ui/unoidl/unocpres.cxx new file mode 100644 index 000000000..cc57b1e79 --- /dev/null +++ b/sd/source/ui/unoidl/unocpres.cxx @@ -0,0 +1,450 @@ +/* -*- 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 <algorithm> + +#include <com/sun/star/lang/DisposedException.hpp> +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> +#include <o3tl/safeint.hxx> +#include <vcl/svapp.hxx> +#include <svx/svdpage.hxx> +#include <cppuhelper/supportsservice.hxx> + +#include <createunocustomshow.hxx> +#include <unomodel.hxx> +#include <drawdoc.hxx> +#include "unocpres.hxx" +#include <cusshow.hxx> +#include <unopage.hxx> +#include <customshowlist.hxx> + +using namespace ::com::sun::star; + +uno::Reference< uno::XInterface > createUnoCustomShow( SdCustomShow* pShow ) +{ + return static_cast<cppu::OWeakObject*>(new SdXCustomPresentation( pShow )); +} + +SdXCustomPresentation::SdXCustomPresentation() noexcept +: mpSdCustomShow(nullptr), mpModel(nullptr), + aDisposeListeners( aDisposeContainerMutex ), + bDisposing( false ) +{ +} + +SdXCustomPresentation::SdXCustomPresentation( SdCustomShow* pShow) noexcept +: mpSdCustomShow(pShow), mpModel(nullptr), + aDisposeListeners( aDisposeContainerMutex ), + bDisposing( false ) +{ +} + +SdXCustomPresentation::~SdXCustomPresentation() noexcept +{ +} + +UNO3_GETIMPLEMENTATION_IMPL( SdXCustomPresentation ); + +// XServiceInfo +OUString SAL_CALL SdXCustomPresentation::getImplementationName() +{ + return "SdXCustomPresentation" ; +} + +sal_Bool SAL_CALL SdXCustomPresentation::supportsService( const OUString& ServiceName ) +{ + return cppu::supportsService( this, ServiceName ); +} + +uno::Sequence< OUString > SAL_CALL SdXCustomPresentation::getSupportedServiceNames() +{ + return { "com.sun.star.presentation.CustomPresentation" }; +} + +// XIndexContainer +void SAL_CALL SdXCustomPresentation::insertByIndex( sal_Int32 Index, const uno::Any& Element ) +{ + SolarMutexGuard aGuard; + + if( bDisposing ) + throw lang::DisposedException(); + + if( Index < 0 || o3tl::make_unsigned(Index) > ( mpSdCustomShow ? mpSdCustomShow->PagesVector().size() : 0 ) ) + throw lang::IndexOutOfBoundsException(); + + uno::Reference< drawing::XDrawPage > xPage; + Element >>= xPage; + + if(!xPage.is()) + throw lang::IllegalArgumentException(); + + SdDrawPage* pPage = comphelper::getFromUnoTunnel<SdDrawPage>( xPage ); + + if(pPage) + { + if( nullptr == mpModel ) + mpModel = pPage->GetModel(); + + if( nullptr != mpModel && nullptr == mpSdCustomShow && mpModel->GetDoc() ) + mpSdCustomShow = new SdCustomShow; + + mpSdCustomShow->PagesVector().insert(mpSdCustomShow->PagesVector().begin() + Index, + static_cast<SdPage*>(pPage->GetSdrPage())); + } + + if( mpModel ) + mpModel->SetModified(); +} + +void SAL_CALL SdXCustomPresentation::removeByIndex( sal_Int32 Index ) +{ + SolarMutexGuard aGuard; + + if( bDisposing ) + throw lang::DisposedException(); + + if(mpSdCustomShow) + { + uno::Reference< drawing::XDrawPage > xPage; + getByIndex( Index ) >>= xPage; + + if( xPage.is() ) + { + SvxDrawPage* pPage = comphelper::getFromUnoTunnel<SvxDrawPage>( xPage ); + if(pPage) + { + SdCustomShow::PageVec::iterator it = std::find( + mpSdCustomShow->PagesVector().begin(), + mpSdCustomShow->PagesVector().end(), + pPage->GetSdrPage()); + if (it != mpSdCustomShow->PagesVector().end()) + mpSdCustomShow->PagesVector().erase(it); + } + } + } + + if( mpModel ) + mpModel->SetModified(); +} + +// XIndexReplace +void SAL_CALL SdXCustomPresentation::replaceByIndex( sal_Int32 Index, const uno::Any& Element ) +{ + removeByIndex( Index ); + insertByIndex( Index, Element ); +} + +// XElementAccess +uno::Type SAL_CALL SdXCustomPresentation::getElementType() +{ + return cppu::UnoType<drawing::XDrawPage>::get(); +} + +sal_Bool SAL_CALL SdXCustomPresentation::hasElements() +{ + SolarMutexGuard aGuard; + + if( bDisposing ) + throw lang::DisposedException(); + + return getCount() > 0; +} + +// XIndexAccess +sal_Int32 SAL_CALL SdXCustomPresentation::getCount() +{ + SolarMutexGuard aGuard; + if( bDisposing ) + throw lang::DisposedException(); + + return mpSdCustomShow ? mpSdCustomShow->PagesVector().size() : 0; +} + +uno::Any SAL_CALL SdXCustomPresentation::getByIndex( sal_Int32 Index ) +{ + SolarMutexGuard aGuard; + + if( bDisposing ) + throw lang::DisposedException(); + + if (Index < 0 || !mpSdCustomShow || o3tl::make_unsigned(Index) >= mpSdCustomShow->PagesVector().size()) + throw lang::IndexOutOfBoundsException(); + + uno::Any aAny; + SdrPage * pPage = const_cast<SdPage *>(mpSdCustomShow->PagesVector()[Index]); + + if( pPage ) + { + uno::Reference< drawing::XDrawPage > xRef( pPage->getUnoPage(), uno::UNO_QUERY ); + aAny <<= xRef; + } + + return aAny; +} + +// XNamed +OUString SAL_CALL SdXCustomPresentation::getName() +{ + SolarMutexGuard aGuard; + + if( bDisposing ) + throw lang::DisposedException(); + + if(mpSdCustomShow) + return mpSdCustomShow->GetName(); + + return OUString(); +} + +void SAL_CALL SdXCustomPresentation::setName( const OUString& aName ) +{ + SolarMutexGuard aGuard; + + if( bDisposing ) + throw lang::DisposedException(); + + if(mpSdCustomShow) + mpSdCustomShow->SetName( aName ); +} + +// XComponent +void SAL_CALL SdXCustomPresentation::dispose() +{ + SolarMutexGuard aGuard; + + if( bDisposing ) + return; // caught a recursion + + bDisposing = true; + + uno::Reference< uno::XInterface > xSource( static_cast<cppu::OWeakObject*>(this) ); + + lang::EventObject aEvt; + aEvt.Source = xSource; + aDisposeListeners.disposeAndClear(aEvt); + + mpSdCustomShow = nullptr; +} + +void SAL_CALL SdXCustomPresentation::addEventListener( const uno::Reference< lang::XEventListener >& xListener ) +{ + if( bDisposing ) + throw lang::DisposedException(); + + aDisposeListeners.addInterface(xListener); +} + +void SAL_CALL SdXCustomPresentation::removeEventListener( const uno::Reference< lang::XEventListener >& aListener ) +{ + if( !bDisposing ) + aDisposeListeners.removeInterface(aListener); +} + +/*===========================================================================* + * class SdXCustomPresentationAccess : public XCustomPresentationAccess, * + * public UsrObject * + *===========================================================================*/ + +SdXCustomPresentationAccess::SdXCustomPresentationAccess(SdXImpressDocument& rMyModel) noexcept +: mrModel(rMyModel) +{ +} + +SdXCustomPresentationAccess::~SdXCustomPresentationAccess() noexcept +{ +} + +// XServiceInfo +OUString SAL_CALL SdXCustomPresentationAccess::getImplementationName() +{ + return "SdXCustomPresentationAccess"; +} + +sal_Bool SAL_CALL SdXCustomPresentationAccess::supportsService( const OUString& ServiceName ) +{ + return cppu::supportsService( this, ServiceName ); +} + +uno::Sequence< OUString > SAL_CALL SdXCustomPresentationAccess::getSupportedServiceNames() +{ + return { "com.sun.star.presentation.CustomPresentationAccess" }; +} + +// XSingleServiceFactory +uno::Reference< uno::XInterface > SAL_CALL SdXCustomPresentationAccess::createInstance() +{ + uno::Reference< uno::XInterface > xRef( static_cast<cppu::OWeakObject*>(new SdXCustomPresentation()) ); + return xRef; +} + +uno::Reference< uno::XInterface > SAL_CALL SdXCustomPresentationAccess::createInstanceWithArguments( const uno::Sequence< uno::Any >& ) +{ + return createInstance(); +} + +// XNameContainer +void SAL_CALL SdXCustomPresentationAccess::insertByName( const OUString& aName, const uno::Any& aElement ) +{ + SolarMutexGuard aGuard; + + // get the documents custom show list + SdCustomShowList* pList = nullptr; + if(mrModel.GetDoc()) + pList = mrModel.GetDoc()->GetCustomShowList(true); + + // no list, no cookies + if( nullptr == pList) + throw uno::RuntimeException(); + + // do we have a container::XIndexContainer? + SdXCustomPresentation* pXShow = nullptr; + + uno::Reference< container::XIndexContainer > xContainer; + if( (aElement >>= xContainer) && xContainer.is() ) + pXShow = comphelper::getFromUnoTunnel<SdXCustomPresentation>(xContainer); + + if( nullptr == pXShow ) + throw lang::IllegalArgumentException(); + + // get the internal custom show from the api wrapper + SdCustomShow* pShow = pXShow->GetSdCustomShow(); + if( nullptr == pShow ) + { + pShow = new SdCustomShow( xContainer ); + pXShow->SetSdCustomShow( pShow ); + } + else + { + if( nullptr == pXShow->GetModel() || *pXShow->GetModel() != mrModel ) + throw lang::IllegalArgumentException(); + } + + // give it a name + pShow->SetName( aName); + + // check if this or another customshow with the same name already exists + for( SdCustomShow* pCompare = pList->First(); + pCompare; + pCompare = pList->Next() ) + { + if( pCompare == pShow || pCompare->GetName() == pShow->GetName() ) + throw container::ElementExistException(); + } + + pList->push_back(std::unique_ptr<SdCustomShow>(pShow)); + + mrModel.SetModified(); +} + +void SAL_CALL SdXCustomPresentationAccess::removeByName( const OUString& Name ) +{ + SolarMutexGuard aGuard; + + SdCustomShow* pShow = getSdCustomShow(Name); + + SdCustomShowList* pList = GetCustomShowList(); + if(!pList || !pShow) + throw container::NoSuchElementException(); + + pList->erase( pShow ); + + mrModel.SetModified(); +} + +// XNameReplace +void SAL_CALL SdXCustomPresentationAccess::replaceByName( const OUString& aName, const uno::Any& aElement ) +{ + removeByName( aName ); + insertByName( aName, aElement ); +} + +// XNameAccess +uno::Any SAL_CALL SdXCustomPresentationAccess::getByName( const OUString& aName ) +{ + SolarMutexGuard aGuard; + + SdCustomShow* pShow = getSdCustomShow(aName); + if(!pShow) + { + throw container::NoSuchElementException(); + } + + uno::Reference< container::XIndexContainer > xRef( pShow->getUnoCustomShow(), uno::UNO_QUERY ); + return uno::Any(xRef); +} + +uno::Sequence< OUString > SAL_CALL SdXCustomPresentationAccess::getElementNames() +{ + SolarMutexGuard aGuard; + + SdCustomShowList* pList = GetCustomShowList(); + const sal_uInt32 nCount = pList ? pList->size() : 0; + + uno::Sequence< OUString > aSequence( nCount ); + OUString* pStringList = aSequence.getArray(); + + sal_uInt32 nIdx = 0; + while( nIdx < nCount ) + { + const SdCustomShow* pShow = (*pList)[nIdx].get(); + pStringList[nIdx] = pShow->GetName(); + nIdx++; + } + + return aSequence; +} + +sal_Bool SAL_CALL SdXCustomPresentationAccess::hasByName( const OUString& aName ) +{ + SolarMutexGuard aGuard; + return getSdCustomShow(aName) != nullptr; +} + +// XElementAccess +uno::Type SAL_CALL SdXCustomPresentationAccess::getElementType() +{ + return cppu::UnoType<container::XIndexContainer>::get(); +} + +sal_Bool SAL_CALL SdXCustomPresentationAccess::hasElements() +{ + SolarMutexGuard aGuard; + + SdCustomShowList* pList = GetCustomShowList(); + return pList && !pList->empty(); +} + +SdCustomShow * SdXCustomPresentationAccess::getSdCustomShow( std::u16string_view rName ) const noexcept +{ + sal_uInt32 nIdx = 0; + + SdCustomShowList* pList = GetCustomShowList(); + const sal_uInt32 nCount = pList ? pList->size() : 0; + + while( nIdx < nCount ) + { + SdCustomShow* pShow = (*pList)[nIdx].get(); + if( pShow->GetName() == rName ) + return pShow; + nIdx++; + } + return nullptr; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/unoidl/unocpres.hxx b/sd/source/ui/unoidl/unocpres.hxx new file mode 100644 index 000000000..e32dce956 --- /dev/null +++ b/sd/source/ui/unoidl/unocpres.hxx @@ -0,0 +1,147 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#pragma once + +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/container/XIndexContainer.hpp> +#include <com/sun/star/container/XNamed.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XUnoTunnel.hpp> +#include <comphelper/interfacecontainer3.hxx> +#include <osl/mutex.hxx> + +#include <cppuhelper/implbase.hxx> +#include <comphelper/servicehelper.hxx> +#include <com/sun/star/container/XNameContainer.hpp> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> + +#include <unomodel.hxx> +#include <drawdoc.hxx> + + +class SdCustomShow; + +class SdXCustomPresentation : public ::cppu::WeakImplHelper< css::container::XIndexContainer, + css::container::XNamed, + css::lang::XUnoTunnel, + css::lang::XComponent, + css::lang::XServiceInfo > +{ +private: + SdCustomShow* mpSdCustomShow; + SdXImpressDocument* mpModel; + + // for xComponent + ::osl::Mutex aDisposeContainerMutex; + ::comphelper::OInterfaceContainerHelper3<css::lang::XEventListener> aDisposeListeners; + bool bDisposing; + +public: + SdXCustomPresentation() noexcept; + explicit SdXCustomPresentation( SdCustomShow* mpSdCustomShow ) noexcept; + virtual ~SdXCustomPresentation() noexcept override; + + // internal + SdCustomShow* GetSdCustomShow() const noexcept { return mpSdCustomShow; } + void SetSdCustomShow( SdCustomShow* pShow ) noexcept { mpSdCustomShow = pShow; } + SdXImpressDocument* GetModel() const noexcept { return mpModel; } + + // uno helper + UNO3_GETIMPLEMENTATION_DECL(SdXCustomPresentation) + + // 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; + + // XIndexContainer + virtual void SAL_CALL insertByIndex( sal_Int32 Index, const css::uno::Any& Element ) override; + virtual void SAL_CALL removeByIndex( sal_Int32 Index ) override; + + // XIndexReplace + virtual void SAL_CALL replaceByIndex( sal_Int32 Index, const css::uno::Any& Element ) override; + + // XElementAccess + virtual css::uno::Type SAL_CALL getElementType() override; + virtual sal_Bool SAL_CALL hasElements() override; + + // XIndexAccess + virtual sal_Int32 SAL_CALL getCount() override ; + virtual css::uno::Any SAL_CALL getByIndex( sal_Int32 Index ) override; + + // XNamed + virtual OUString SAL_CALL getName( ) override; + virtual void SAL_CALL setName( const OUString& aName ) 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 >& aListener ) override; +}; + +class SdXCustomPresentationAccess : public ::cppu::WeakImplHelper< css::container::XNameContainer, + css::lang::XSingleServiceFactory, + css::lang::XServiceInfo > +{ +private: + SdXImpressDocument& mrModel; + + // intern + inline SdCustomShowList* GetCustomShowList() const noexcept; + SdCustomShow * getSdCustomShow( std::u16string_view Name ) const noexcept; + +public: + explicit SdXCustomPresentationAccess(SdXImpressDocument& rMyModel) noexcept; + virtual ~SdXCustomPresentationAccess() noexcept 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; + + // XSingleServiceFactory + virtual css::uno::Reference< css::uno::XInterface > SAL_CALL createInstance( ) override; + virtual css::uno::Reference< css::uno::XInterface > SAL_CALL createInstanceWithArguments( const css::uno::Sequence< css::uno::Any >& aArguments ) override; + + // XNameContainer + virtual void SAL_CALL insertByName( const OUString& aName, const css::uno::Any& aElement ) override; + virtual void SAL_CALL removeByName( const OUString& Name ) override; + + // XNameReplace + virtual void SAL_CALL replaceByName( const OUString& aName, const css::uno::Any& aElement ) override; + + // 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; + + // XElementAccess + virtual css::uno::Type SAL_CALL getElementType() override; + virtual sal_Bool SAL_CALL hasElements() override; +}; + +inline SdCustomShowList* SdXCustomPresentationAccess::GetCustomShowList() const noexcept +{ + if(mrModel.GetDoc()) + return mrModel.GetDoc()->GetCustomShowList(); + else + return nullptr; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/unoidl/unodoc.cxx b/sd/source/ui/unoidl/unodoc.cxx new file mode 100644 index 000000000..cfb97c186 --- /dev/null +++ b/sd/source/ui/unoidl/unodoc.cxx @@ -0,0 +1,73 @@ +/* -*- 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 <sfx2/sfxmodelfactory.hxx> +#include <com/sun/star/frame/XModel.hpp> + +#include <sddll.hxx> +#include <DrawDocShell.hxx> +#include <GraphicDocShell.hxx> +#include <vcl/svapp.hxx> + +using namespace ::com::sun::star; + +// com.sun.star.comp.Draw.DrawingDocument + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* +sd_DrawingDocument_get_implementation( + css::uno::XComponentContext* , css::uno::Sequence<css::uno::Any> const& args) +{ + SolarMutexGuard aGuard; + + SdDLL::Init(); + + css::uno::Reference<css::uno::XInterface> xInterface = sfx2::createSfxModelInstance(args, + [](SfxModelFlags _nCreationFlags) + { + SfxObjectShell* pShell = new ::sd::GraphicDocShell( _nCreationFlags ); + return uno::Reference< uno::XInterface >( pShell->GetModel() ); + }); + xInterface->acquire(); + return xInterface.get(); +} + + +// com.sun.star.comp.Draw.PresentationDocument + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* +sd_PresentationDocument_get_implementation( + css::uno::XComponentContext* , css::uno::Sequence<css::uno::Any> const& args) +{ + SolarMutexGuard aGuard; + + SdDLL::Init(); + + css::uno::Reference<css::uno::XInterface> xInterface = sfx2::createSfxModelInstance(args, + [](SfxModelFlags _nCreationFlags) + { + SfxObjectShell* pShell = + new ::sd::DrawDocShell( + _nCreationFlags, false, DocumentType::Impress ); + return pShell->GetModel(); + }); + xInterface->acquire(); + return xInterface.get(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/unoidl/unolayer.cxx b/sd/source/ui/unoidl/unolayer.cxx new file mode 100644 index 000000000..c6bc3cdf3 --- /dev/null +++ b/sd/source/ui/unoidl/unolayer.cxx @@ -0,0 +1,707 @@ +/* -*- 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 <com/sun/star/lang/DisposedException.hpp> +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> + +#include "unolayer.hxx" + +#include <comphelper/extract.hxx> +#include <editeng/unoipset.hxx> +#include <osl/diagnose.h> +#include <svl/itemprop.hxx> +#include <svx/svdpagv.hxx> +#include <svx/svdobj.hxx> +#include <cppuhelper/supportsservice.hxx> + +// following ones for InsertSdPage() +#include <svx/svdlayer.hxx> + +#include <DrawDocShell.hxx> +#include <drawdoc.hxx> +#include <unomodel.hxx> +#include <unoprnms.hxx> +#include <com/sun/star/lang/NoSupportException.hpp> +#include <svx/svdpool.hxx> +#include <FrameView.hxx> +#include <DrawViewShell.hxx> +#include <View.hxx> +#include <ViewShell.hxx> +#include <strings.hrc> +#include <sdresid.hxx> + +#include "unowcntr.hxx" +#include <vcl/svapp.hxx> + +using namespace ::com::sun::star; + +// class SdLayer +#define WID_LAYER_LOCKED 1 +#define WID_LAYER_PRINTABLE 2 +#define WID_LAYER_VISIBLE 3 +#define WID_LAYER_NAME 4 +#define WID_LAYER_TITLE 5 +#define WID_LAYER_DESC 6 + +static const SvxItemPropertySet* ImplGetSdLayerPropertySet() +{ + static const SfxItemPropertyMapEntry aSdLayerPropertyMap_Impl[] = + { + { u"" UNO_NAME_LAYER_LOCKED, WID_LAYER_LOCKED, cppu::UnoType<bool>::get(), 0, 0 }, + { u"" UNO_NAME_LAYER_PRINTABLE, WID_LAYER_PRINTABLE,cppu::UnoType<bool>::get(), 0, 0 }, + { u"" UNO_NAME_LAYER_VISIBLE, WID_LAYER_VISIBLE, cppu::UnoType<bool>::get(), 0, 0 }, + { u"" UNO_NAME_LAYER_NAME, WID_LAYER_NAME, ::cppu::UnoType<OUString>::get(), 0, 0 }, + { u"Title", WID_LAYER_TITLE, ::cppu::UnoType<OUString>::get(), 0, 0 }, + { u"Description", WID_LAYER_DESC, ::cppu::UnoType<OUString>::get(), 0, 0 }, + { u"", 0, css::uno::Type(), 0, 0 } + }; + static SvxItemPropertySet aSDLayerPropertySet_Impl( aSdLayerPropertyMap_Impl, SdrObject::GetGlobalDrawObjectItemPool() ); + return &aSDLayerPropertySet_Impl; +} + +SdLayer::SdLayer(SdLayerManager* pLayerManager_, SdrLayer* pSdrLayer_) +: mxLayerManager(pLayerManager_) +, pLayer(pSdrLayer_) +, pPropSet(ImplGetSdLayerPropertySet()) +{ + // no defaults possible yet, a "set" would overwrite existing information + // in view, which is currently needed for saving, because pLayer is not updated + // from view. +} + +SdLayer::~SdLayer() noexcept +{ +} + +// uno helper +UNO3_GETIMPLEMENTATION_IMPL( SdLayer ); + +// XServiceInfo +OUString SAL_CALL SdLayer::getImplementationName() +{ + return "SdUnoLayer"; +} + +sal_Bool SAL_CALL SdLayer::supportsService( const OUString& ServiceName ) +{ + return cppu::supportsService( this, ServiceName ); +} + +uno::Sequence< OUString > SAL_CALL SdLayer::getSupportedServiceNames() +{ + return { "com.sun.star.drawing.Layer" }; +} + +// beans::XPropertySet +uno::Reference< beans::XPropertySetInfo > SAL_CALL SdLayer::getPropertySetInfo( ) +{ + SolarMutexGuard aGuard; + return pPropSet->getPropertySetInfo(); +} + +void SAL_CALL SdLayer::setPropertyValue( const OUString& aPropertyName, const uno::Any& aValue ) +{ + SolarMutexGuard aGuard; + + if(pLayer == nullptr || mxLayerManager == nullptr) + throw lang::DisposedException(); + + const SfxItemPropertyMapEntry* pEntry = pPropSet->getPropertyMapEntry(aPropertyName); + + switch( pEntry ? pEntry->nWID : -1 ) + { + case WID_LAYER_LOCKED: + { + pLayer->SetLockedODF( cppu::any2bool(aValue) ); + set(LOCKED, cppu::any2bool(aValue)); // changes the View, if any exists + break; + } + case WID_LAYER_PRINTABLE: + { + pLayer->SetPrintableODF( cppu::any2bool(aValue) ); + set(PRINTABLE, cppu::any2bool(aValue)); // changes the View, if any exists + break; + } + case WID_LAYER_VISIBLE: + { + pLayer->SetVisibleODF( cppu::any2bool(aValue) ); + set(VISIBLE, cppu::any2bool(aValue)); // changes the View, if any exists + break; + } + case WID_LAYER_NAME: + { + OUString aName; + if(!(aValue >>= aName)) + throw lang::IllegalArgumentException(); + + pLayer->SetName(aName); + mxLayerManager->UpdateLayerView(); + break; + } + + case WID_LAYER_TITLE: + { + OUString sTitle; + if(!(aValue >>= sTitle)) + throw lang::IllegalArgumentException(); + + pLayer->SetTitle(sTitle); + break; + } + + case WID_LAYER_DESC: + { + OUString sDescription; + if(!(aValue >>= sDescription)) + throw lang::IllegalArgumentException(); + + pLayer->SetDescription(sDescription); + break; + } + + default: + throw beans::UnknownPropertyException( aPropertyName, static_cast<cppu::OWeakObject*>(this)); + } + + if( mxLayerManager->GetDocShell() ) + mxLayerManager->GetDocShell()->SetModified(); +} + +uno::Any SAL_CALL SdLayer::getPropertyValue( const OUString& PropertyName ) +{ + SolarMutexGuard aGuard; + + if(pLayer == nullptr || mxLayerManager == nullptr) + throw lang::DisposedException(); + + const SfxItemPropertyMapEntry* pEntry = pPropSet->getPropertyMapEntry(PropertyName); + + uno::Any aValue; + + switch( pEntry ? pEntry->nWID : -1 ) + { + case WID_LAYER_LOCKED: + aValue <<= get( LOCKED ); + break; + case WID_LAYER_PRINTABLE: + aValue <<= get( PRINTABLE ); + break; + case WID_LAYER_VISIBLE: + aValue <<= get( VISIBLE ); + break; + case WID_LAYER_NAME: + { + OUString aRet(pLayer->GetName()); + aValue <<= aRet; + break; + } + case WID_LAYER_TITLE: + aValue <<= pLayer->GetTitle(); + break; + case WID_LAYER_DESC: + aValue <<= pLayer->GetDescription(); + break; + default: + throw beans::UnknownPropertyException( PropertyName, static_cast<cppu::OWeakObject*>(this)); + } + + return aValue; +} + +void SAL_CALL SdLayer::addPropertyChangeListener( const OUString& , const uno::Reference< beans::XPropertyChangeListener >& ) {} +void SAL_CALL SdLayer::removePropertyChangeListener( const OUString& , const uno::Reference< beans::XPropertyChangeListener >& ) {} +void SAL_CALL SdLayer::addVetoableChangeListener( const OUString& , const uno::Reference< beans::XVetoableChangeListener >& ) {} +void SAL_CALL SdLayer::removeVetoableChangeListener( const OUString& , const uno::Reference< beans::XVetoableChangeListener >& ) {} + +bool SdLayer::get( LayerAttribute what ) noexcept +{ + if(pLayer && mxLayerManager.is()) + { + // Try 1. is an arbitrary page open? + ::sd::View *pView = mxLayerManager->GetView(); + SdrPageView* pSdrPageView = nullptr; + if(pView) + pSdrPageView = pView->GetSdrPageView(); + + if(pSdrPageView) + { + OUString aLayerName = pLayer->GetName(); + switch(what) + { + case VISIBLE: return pSdrPageView->IsLayerVisible(aLayerName); + case PRINTABLE: return pSdrPageView->IsLayerPrintable(aLayerName); + case LOCKED: return pSdrPageView->IsLayerLocked(aLayerName); + } + } + + // Try 2. get info from FrameView + if(mxLayerManager->GetDocShell()) + { + ::sd::FrameView *pFrameView = mxLayerManager->GetDocShell()->GetFrameView(); + if(pFrameView) + switch(what) + { + case VISIBLE: return pFrameView->GetVisibleLayers().IsSet(pLayer->GetID()); + case PRINTABLE: return pFrameView->GetPrintableLayers().IsSet(pLayer->GetID()); + case LOCKED: return pFrameView->GetLockedLayers().IsSet(pLayer->GetID()); + } + } + + // no view at all, e.g. Draw embedded as OLE in text document, ODF default values + switch(what) + { + case VISIBLE: return true; + case PRINTABLE: return true; + case LOCKED: return false; + } + + } + return false; //TODO: uno::Exception? +} + +void SdLayer::set( LayerAttribute what, bool flag ) noexcept +{ + if(!(pLayer && mxLayerManager.is())) + return; + + // Try 1. is an arbitrary page open? + ::sd::View *pView = mxLayerManager->GetView(); + SdrPageView* pSdrPageView = nullptr; + if(pView) + pSdrPageView = pView->GetSdrPageView(); + + if(pSdrPageView) + { + OUString aLayerName(pLayer->GetName()); + switch(what) + { + case VISIBLE: pSdrPageView->SetLayerVisible(aLayerName,flag); + break; + case PRINTABLE: pSdrPageView->SetLayerPrintable(aLayerName,flag); + break; + case LOCKED: pSdrPageView->SetLayerLocked(aLayerName,flag); + break; + } + } + + // Try 2. get info from FrameView + if(!mxLayerManager->GetDocShell()) + return; + + ::sd::FrameView *pFrameView = mxLayerManager->GetDocShell()->GetFrameView(); + + if(!pFrameView) + return; + + SdrLayerIDSet aNewLayers; + switch(what) + { + case VISIBLE: aNewLayers = pFrameView->GetVisibleLayers(); + break; + case PRINTABLE: aNewLayers = pFrameView->GetPrintableLayers(); + break; + case LOCKED: aNewLayers = pFrameView->GetLockedLayers(); + break; + } + + aNewLayers.Set(pLayer->GetID(),flag); + + switch(what) + { + case VISIBLE: pFrameView->SetVisibleLayers(aNewLayers); + break; + case PRINTABLE: pFrameView->SetPrintableLayers(aNewLayers); + break; + case LOCKED: pFrameView->SetLockedLayers(aNewLayers); + break; + } + return; + //TODO: uno::Exception? +} + +// css::container::XChild +uno::Reference<uno::XInterface> SAL_CALL SdLayer::getParent() +{ + SolarMutexGuard aGuard; + + if( !mxLayerManager.is() ) + throw lang::DisposedException(); + + return uno::Reference<uno::XInterface> (static_cast<cppu::OWeakObject*>(mxLayerManager.get()), uno::UNO_QUERY); +} + +void SAL_CALL SdLayer::setParent (const uno::Reference<uno::XInterface >& ) +{ + throw lang::NoSupportException (); +} + +// XComponent +void SAL_CALL SdLayer::dispose( ) +{ + mxLayerManager.clear(); + pLayer = nullptr; +} + +void SAL_CALL SdLayer::addEventListener( const uno::Reference< lang::XEventListener >& ) +{ + OSL_FAIL("not implemented!"); +} + +void SAL_CALL SdLayer::removeEventListener( const uno::Reference< lang::XEventListener >& ) +{ + OSL_FAIL("not implemented!"); +} + +// class SdLayerManager +SdLayerManager::SdLayerManager( SdXImpressDocument& rMyModel ) noexcept +:mpModel( &rMyModel) +{ + mpLayers.reset(new SvUnoWeakContainer); +} + +SdLayerManager::~SdLayerManager() noexcept +{ + dispose(); +} + +// uno helper +UNO3_GETIMPLEMENTATION_IMPL( SdLayerManager ); + +// XComponent +void SAL_CALL SdLayerManager::dispose( ) +{ + mpModel = nullptr; + if( mpLayers ) + { + mpLayers->dispose(); + mpLayers.reset(); + } +} + +void SAL_CALL SdLayerManager::addEventListener( const uno::Reference< lang::XEventListener >& ) +{ + OSL_FAIL("not implemented!"); +} + +void SAL_CALL SdLayerManager::removeEventListener( const uno::Reference< lang::XEventListener >& ) +{ + OSL_FAIL("not implemented!"); +} + +// XServiceInfo +OUString SAL_CALL SdLayerManager::getImplementationName() +{ + return "SdUnoLayerManager"; +} + +sal_Bool SAL_CALL SdLayerManager::supportsService( const OUString& ServiceName ) +{ + return cppu::supportsService( this, ServiceName ); +} + +uno::Sequence< OUString > SAL_CALL SdLayerManager::getSupportedServiceNames() +{ + return {"com.sun.star.drawing.LayerManager"}; +} + +// XLayerManager +uno::Reference< drawing::XLayer > SAL_CALL SdLayerManager::insertNewByIndex( sal_Int32 nIndex ) +{ + SolarMutexGuard aGuard; + + if( mpModel == nullptr ) + throw lang::DisposedException(); + + uno::Reference< drawing::XLayer > xLayer; + + if( mpModel->mpDoc ) + { + SdrLayerAdmin& rLayerAdmin = mpModel->mpDoc->GetLayerAdmin(); + sal_uInt16 nLayerCnt = rLayerAdmin.GetLayerCount(); + sal_Int32 nLayer = nLayerCnt - 2 + 1; + OUString aLayerName; + + // Test for existing names + while( aLayerName.isEmpty() || rLayerAdmin.GetLayer( aLayerName ) ) + { + aLayerName = SdResId(STR_LAYER) + OUString::number(nLayer); + ++nLayer; + } + + SdrLayerAdmin& rLA=mpModel->mpDoc->GetLayerAdmin(); + const sal_Int32 nMax=rLA.GetLayerCount(); + if (nIndex>nMax) nIndex=nMax; + xLayer = GetLayer (rLA.NewLayer(aLayerName,static_cast<sal_uInt16>(nIndex))); + mpModel->SetModified(); + } + return xLayer; +} + +void SAL_CALL SdLayerManager::remove( const uno::Reference< drawing::XLayer >& xLayer ) +{ + SolarMutexGuard aGuard; + + if( mpModel == nullptr ) + throw lang::DisposedException(); + + SdLayer* pSdLayer = comphelper::getFromUnoTunnel<SdLayer>(xLayer); + + if(pSdLayer && GetView()) + { + const SdrLayer* pSdrLayer = pSdLayer->GetSdrLayer(); + GetView()->DeleteLayer( pSdrLayer->GetName() ); + + UpdateLayerView(); + } + + mpModel->SetModified(); +} + +void SAL_CALL SdLayerManager::attachShapeToLayer( const uno::Reference< drawing::XShape >& xShape, const uno::Reference< drawing::XLayer >& xLayer ) +{ + SolarMutexGuard aGuard; + + if( mpModel == nullptr ) + throw lang::DisposedException(); + + SdLayer* pSdLayer = comphelper::getFromUnoTunnel<SdLayer>(xLayer); + SdrLayer* pSdrLayer = pSdLayer?pSdLayer->GetSdrLayer():nullptr; + if(pSdrLayer==nullptr) + return; + + SdrObject* pSdrObject = SdrObject::getSdrObjectFromXShape( xShape ); + + if(pSdrObject) + pSdrObject->SetLayer(pSdrLayer->GetID()); + + mpModel->SetModified(); +} + +uno::Reference< drawing::XLayer > SAL_CALL SdLayerManager::getLayerForShape( const uno::Reference< drawing::XShape >& xShape ) +{ + SolarMutexGuard aGuard; + + if( mpModel == nullptr ) + throw lang::DisposedException(); + + uno::Reference< drawing::XLayer > xLayer; + + if(mpModel->mpDoc) + { + SdrObject* pObj = SdrObject::getSdrObjectFromXShape( xShape ); + if(pObj) + { + SdrLayerID aId = pObj->GetLayer(); + SdrLayerAdmin& rLayerAdmin = mpModel->mpDoc->GetLayerAdmin(); + xLayer = GetLayer (rLayerAdmin.GetLayerPerID(aId)); + } + } + return xLayer; +} + +// XIndexAccess +sal_Int32 SAL_CALL SdLayerManager::getCount() +{ + SolarMutexGuard aGuard; + + if( mpModel == nullptr ) + throw lang::DisposedException(); + + if( mpModel->mpDoc ) + { + SdrLayerAdmin& rLayerAdmin = mpModel->mpDoc->GetLayerAdmin(); + return rLayerAdmin.GetLayerCount(); + } + + return 0; +} + +uno::Any SAL_CALL SdLayerManager::getByIndex( sal_Int32 nLayer ) +{ + SolarMutexGuard aGuard; + + if( mpModel == nullptr ) + throw lang::DisposedException(); + + if( nLayer >= getCount() || nLayer < 0 ) + throw lang::IndexOutOfBoundsException(); + + uno::Any aAny; + + if( mpModel->mpDoc ) + { + SdrLayerAdmin& rLayerAdmin = mpModel->mpDoc->GetLayerAdmin(); + uno::Reference<drawing::XLayer> xLayer (GetLayer (rLayerAdmin.GetLayer(static_cast<sal_uInt16>(nLayer)))); + aAny <<= xLayer; + } + return aAny; +} + +// XNameAccess +uno::Any SAL_CALL SdLayerManager::getByName( const OUString& aName ) +{ + SolarMutexGuard aGuard; + + if( (mpModel == nullptr) || (mpModel->mpDoc == nullptr ) ) + throw lang::DisposedException(); + + SdrLayerAdmin& rLayerAdmin = mpModel->mpDoc->GetLayerAdmin(); + SdrLayer* pLayer = rLayerAdmin.GetLayer(aName); + if( pLayer == nullptr ) + throw container::NoSuchElementException(); + + return uno::Any( GetLayer (pLayer) ); +} + +uno::Sequence< OUString > SAL_CALL SdLayerManager::getElementNames() +{ + SolarMutexGuard aGuard; + + if( mpModel == nullptr ) + throw lang::DisposedException(); + + SdrLayerAdmin& rLayerAdmin = mpModel->mpDoc->GetLayerAdmin(); + const sal_uInt16 nLayerCount = rLayerAdmin.GetLayerCount(); + + uno::Sequence< OUString > aSeq( nLayerCount ); + + OUString* pStrings = aSeq.getArray(); + + for( sal_uInt16 nLayer = 0; nLayer < nLayerCount; nLayer++ ) + { + SdrLayer* pLayer = rLayerAdmin.GetLayer( nLayer ); + if( pLayer ) + *pStrings++ = pLayer->GetName(); + } + + return aSeq; +} + +sal_Bool SAL_CALL SdLayerManager::hasByName( const OUString& aName ) +{ + SolarMutexGuard aGuard; + + if( mpModel == nullptr ) + throw lang::DisposedException(); + + SdrLayerAdmin& rLayerAdmin = mpModel->mpDoc->GetLayerAdmin(); + + return nullptr != rLayerAdmin.GetLayer(aName); +} + +// XElementAccess +uno::Type SAL_CALL SdLayerManager::getElementType() +{ + return cppu::UnoType<drawing::XLayer>::get(); +} + +sal_Bool SAL_CALL SdLayerManager::hasElements() +{ + return getCount() > 0; +} + +/** + * If something was changed at the layers, this methods takes care that the + * changes are made visible in sdbcx::View. + */ +void SdLayerManager::UpdateLayerView() const noexcept +{ + if(!mpModel->mpDocShell) + return; + + ::sd::DrawViewShell* pDrViewSh = dynamic_cast< ::sd::DrawViewShell* >( mpModel->mpDocShell->GetViewShell()); + + if(pDrViewSh) + { + bool bLayerMode = pDrViewSh->IsLayerModeActive(); + pDrViewSh->ChangeEditMode(pDrViewSh->GetEditMode(), !bLayerMode); + pDrViewSh->ChangeEditMode(pDrViewSh->GetEditMode(), bLayerMode); + } + + mpModel->mpDoc->SetChanged(); +} + +/** */ +::sd::View* SdLayerManager::GetView() const noexcept +{ + if( mpModel->mpDocShell ) + { + ::sd::ViewShell* pViewSh = mpModel->mpDocShell->GetViewShell(); + if(pViewSh) + return pViewSh->GetView(); + } + return nullptr; +} + +namespace +{ +/** Compare two pointers to <type>SdrLayer</type> objects. + @param xRef + The implementing SdLayer class provides the first pointer by the + <member>SdLayer::GetSdrLayer</member> method. + @param pSearchData + This void pointer is the second pointer to an <type>SdrLayer</type> + object. + @return + Return </True> if both pointers point to the same object. +*/ +bool compare_layers (const uno::WeakReference<uno::XInterface>& xRef, void const * pSearchData) +{ + uno::Reference<uno::XInterface> xLayer (xRef); + if (xLayer.is()) + { + SdLayer* pSdLayer = comphelper::getFromUnoTunnel<SdLayer> (xRef); + if (pSdLayer != nullptr) + { + SdrLayer* pSdrLayer = pSdLayer->GetSdrLayer (); + if (pSdrLayer == static_cast<SdrLayer const *>(pSearchData)) + return true; + } + } + return false; +} +} + +/** Use the <member>mpLayers</member> container of weak references to either + retrieve and return a previously created <type>XLayer</type> object for + the given <type>SdrLayer</type> object or create and remember a new one. +*/ +uno::Reference<drawing::XLayer> SdLayerManager::GetLayer (SdrLayer* pLayer) +{ + uno::WeakReference<uno::XInterface> xRef; + uno::Reference<drawing::XLayer> xLayer; + + // Search existing xLayer for the given pLayer. + if (mpLayers->findRef (xRef, static_cast<void*>(pLayer), compare_layers)) + xLayer.set(xRef, uno::UNO_QUERY); + + // Create the xLayer if necessary. + if ( ! xLayer.is()) + { + xLayer = new SdLayer (this, pLayer); + + // Remember the new xLayer for future calls. + uno::WeakReference<uno::XInterface> wRef(xLayer); + mpLayers->insert(wRef); + } + + return xLayer; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/unoidl/unolayer.hxx b/sd/source/ui/unoidl/unolayer.hxx new file mode 100644 index 000000000..aa7d4891b --- /dev/null +++ b/sd/source/ui/unoidl/unolayer.hxx @@ -0,0 +1,169 @@ +/* -*- 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/drawing/XLayer.hpp> +#include <com/sun/star/drawing/XLayerManager.hpp> + +#include <cppuhelper/implbase.hxx> +#include <comphelper/servicehelper.hxx> +#include <rtl/ref.hxx> + +#include <unomodel.hxx> + +class SdrLayer; +class SdLayerManager; +class SvUnoWeakContainer; + +namespace sd { +class View; +} +enum LayerAttribute { VISIBLE, PRINTABLE, LOCKED }; + +/*********************************************************************** +* * +***********************************************************************/ +class SdLayer : public ::cppu::WeakImplHelper< css::drawing::XLayer, + css::lang::XServiceInfo, + css::container::XChild, + css::lang::XUnoTunnel, + css::lang::XComponent > +{ +public: + SdLayer(SdLayerManager* pLayerManager_, SdrLayer* pSdrLayer_); + virtual ~SdLayer() noexcept override; + + // intern + SdrLayer* GetSdrLayer() const noexcept { return pLayer; } + + // uno helper + UNO3_GETIMPLEMENTATION_DECL( SdLayer ) + + // 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; + + // css::beans::XPropertySet + 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; + + // css::container::XChild + + /** Returns the layer manager that manages this layer. + */ + virtual css::uno::Reference< css::uno::XInterface > SAL_CALL getParent( ) 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 >& aListener ) override; + + /** Not implemented. Always throws an exception. + @throws NoSupportException. + */ + virtual void SAL_CALL setParent( const css::uno::Reference< css::uno::XInterface >& Parent ) override; + +private: + rtl::Reference<SdLayerManager> mxLayerManager; + SdrLayer* pLayer; + const SvxItemPropertySet* pPropSet; + + bool get( LayerAttribute what ) noexcept; + void set( LayerAttribute what, bool flag ) noexcept; + +}; + +/*********************************************************************** +* * +***********************************************************************/ + +class SdLayerManager : public ::cppu::WeakImplHelper< css::drawing::XLayerManager, + css::container::XNameAccess, + css::lang::XServiceInfo, + css::lang::XUnoTunnel, + css::lang::XComponent > +{ + friend class SdLayer; + +public: + explicit SdLayerManager( SdXImpressDocument& rMyModel ) noexcept; + virtual ~SdLayerManager() noexcept override; + + // uno helper + UNO3_GETIMPLEMENTATION_DECL( SdLayerManager ) + + // 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; + + // XLayerManager + virtual css::uno::Reference< css::drawing::XLayer > SAL_CALL insertNewByIndex( sal_Int32 nIndex ) override; + virtual void SAL_CALL remove( const css::uno::Reference< css::drawing::XLayer >& xLayer ) override; + virtual void SAL_CALL attachShapeToLayer( const css::uno::Reference< css::drawing::XShape >& xShape, const css::uno::Reference< css::drawing::XLayer >& xLayer ) override; + virtual css::uno::Reference< css::drawing::XLayer > SAL_CALL getLayerForShape( const css::uno::Reference< css::drawing::XShape >& xShape ) override; + + // XIndexAccess + virtual sal_Int32 SAL_CALL getCount() override ; + virtual css::uno::Any SAL_CALL getByIndex( sal_Int32 Index ) override; + + // 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; + + // XElementAccess + virtual css::uno::Type SAL_CALL getElementType() override; + virtual sal_Bool SAL_CALL hasElements() override; + + /** Return the <type>XLayer</type> object that is associated with the + given <type>SdrLayer</type> object. If the requested object does + not yet exist it is created. All calls with the same argument + return the same object. + @param pLayer + The <type>SdrLayer</type> object for which to return the + associated <type>XLayer</type> object. + @return + The returned value is the unique <type>XLayer</type> object + associated with the specified argument. If no layer can be + created for the argument than an empty reference is returned. + */ + css::uno::Reference< css::drawing::XLayer> GetLayer (SdrLayer* pLayer); + + // 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 >& aListener ) override; + +private: + SdXImpressDocument* mpModel; + std::unique_ptr<SvUnoWeakContainer> mpLayers; + + ::sd::View* GetView() const noexcept; + ::sd::DrawDocShell* GetDocShell() const noexcept { return mpModel->mpDocShell; } + void UpdateLayerView() const noexcept; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/unoidl/unomodel.cxx b/sd/source/ui/unoidl/unomodel.cxx new file mode 100644 index 000000000..758ce1380 --- /dev/null +++ b/sd/source/ui/unoidl/unomodel.cxx @@ -0,0 +1,3491 @@ +/* -*- 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 <memory> + +#include <com/sun/star/presentation/XPresentation2.hpp> + +#include <com/sun/star/lang/DisposedException.hpp> +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> +#include <com/sun/star/lang/ServiceNotRegisteredException.hpp> +#include <com/sun/star/lang/Locale.hpp> +#include <com/sun/star/awt/XDevice.hpp> +#include <com/sun/star/document/IndexedPropertyValues.hpp> +#include <com/sun/star/beans/PropertyAttribute.hpp> + +#include <com/sun/star/embed/Aspects.hpp> + +#include <officecfg/Office/Common.hxx> +#include <comphelper/indexedpropertyvalues.hxx> +#include <comphelper/lok.hxx> +#include <comphelper/propertyvalue.hxx> +#include <comphelper/sequence.hxx> +#include <comphelper/servicehelper.hxx> +#include <cppuhelper/supportsservice.hxx> +#include <comphelper/processfactory.hxx> +#include <comphelper/profilezone.hxx> + +#include <sal/log.hxx> +#include <editeng/unofield.hxx> +#include <notifydocumentevent.hxx> +#include <tpaction.hxx> +#include <unomodel.hxx> +#include "unopool.hxx" +#include <sfx2/lokhelper.hxx> +#include <sfx2/dispatch.hxx> +#include <vcl/svapp.hxx> +#include <LibreOfficeKit/LibreOfficeKitEnums.h> + +#include <editeng/UnoForbiddenCharsTable.hxx> +#include <svx/svdoutl.hxx> +#include <o3tl/safeint.hxx> +#include <o3tl/string_view.hxx> +#include <o3tl/unit_conversion.hxx> +#include <svx/UnoNamespaceMap.hxx> +#include <svx/svdlayer.hxx> +#include <svx/svdsob.hxx> +#include <svx/svdundo.hxx> +#include <svx/unoapi.hxx> +#include <svx/unofill.hxx> +#include <svx/sdrpagewindow.hxx> +#include <svx/sdrpaintwindow.hxx> +#include <editeng/fontitem.hxx> +#include <toolkit/awt/vclxdevice.hxx> +#include <svx/svdpool.hxx> +#include <svx/svdpagv.hxx> +#include <svtools/unoimap.hxx> +#include <svtools/slidesorterbaropt.hxx> +#include <svx/unoshape.hxx> +#include <editeng/unonrule.hxx> +#include <editeng/eeitem.hxx> +#include <unotools/datetime.hxx> +#include <xmloff/autolayout.hxx> + +// Support creation of GraphicStorageHandler and EmbeddedObjectResolver +#include <svx/xmleohlp.hxx> +#include <svx/xmlgrhlp.hxx> +#include <DrawDocShell.hxx> +#include <ViewShellBase.hxx> +#include "UnoDocumentSettings.hxx" + +#include <Annotation.hxx> +#include <drawdoc.hxx> +#include <sdmod.hxx> +#include <sdresid.hxx> +#include <sdpage.hxx> + +#include <strings.hrc> +#include <strings.hxx> +#include "unolayer.hxx" +#include <unopage.hxx> +#include "unocpres.hxx" +#include "unoobj.hxx" +#include <stlpool.hxx> +#include "unopback.hxx" +#include <unokywds.hxx> + +#include <FrameView.hxx> +#include <ClientView.hxx> +#include <DrawViewShell.hxx> +#include <ViewShell.hxx> +#include <Window.hxx> +#include <optsitem.hxx> + +#include <vcl/pdfextoutdevdata.hxx> +#include <com/sun/star/presentation/AnimationSpeed.hpp> +#include <com/sun/star/presentation/ClickAction.hpp> +#include <svx/sdr/contact/viewobjectcontact.hxx> +#include <svx/sdr/contact/viewcontact.hxx> +#include <svx/sdr/contact/displayinfo.hxx> + +#include <com/sun/star/office/XAnnotation.hpp> +#include <com/sun/star/office/XAnnotationAccess.hpp> +#include <com/sun/star/office/XAnnotationEnumeration.hpp> +#include <com/sun/star/geometry/RealPoint2D.hpp> +#include <com/sun/star/util/DateTime.hpp> + +#include <drawinglayer/primitive2d/structuretagprimitive2d.hxx> + +#include <sfx2/lokcomponenthelpers.hxx> +#include <tools/gen.hxx> +#include <tools/debug.hxx> +#include <tools/diagnose_ex.h> +#include <tools/json_writer.hxx> +#include <tools/UnitConversion.hxx> +#include <svx/ColorSets.hxx> + +#include <app.hrc> + +using namespace ::cppu; +using namespace ::com::sun::star; +using namespace ::sd; + +TranslateId SdTPAction::GetClickActionSdResId( presentation::ClickAction eCA ) +{ + switch( eCA ) + { + case presentation::ClickAction_NONE: return STR_CLICK_ACTION_NONE; + case presentation::ClickAction_PREVPAGE: return STR_CLICK_ACTION_PREVPAGE; + case presentation::ClickAction_NEXTPAGE: return STR_CLICK_ACTION_NEXTPAGE; + case presentation::ClickAction_FIRSTPAGE: return STR_CLICK_ACTION_FIRSTPAGE; + case presentation::ClickAction_LASTPAGE: return STR_CLICK_ACTION_LASTPAGE; + case presentation::ClickAction_BOOKMARK: return STR_CLICK_ACTION_BOOKMARK; + case presentation::ClickAction_DOCUMENT: return STR_CLICK_ACTION_DOCUMENT; + case presentation::ClickAction_PROGRAM: return STR_CLICK_ACTION_PROGRAM; + case presentation::ClickAction_MACRO: return STR_CLICK_ACTION_MACRO; + case presentation::ClickAction_SOUND: return STR_CLICK_ACTION_SOUND; + case presentation::ClickAction_VERB: return STR_CLICK_ACTION_VERB; + case presentation::ClickAction_STOPPRESENTATION: return STR_CLICK_ACTION_STOPPRESENTATION; + default: OSL_FAIL( "No StringResource for ClickAction available!" ); + } + return {}; +} + +namespace { + +class SdUnoForbiddenCharsTable : public SvxUnoForbiddenCharsTable, + public SfxListener +{ +public: + explicit SdUnoForbiddenCharsTable(SdrModel* pModel); + virtual ~SdUnoForbiddenCharsTable() override; + + // SfxListener + virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) noexcept override; +protected: + virtual void onChange() override; + +private: + SdrModel* mpModel; +}; + +} + +SdUnoForbiddenCharsTable::SdUnoForbiddenCharsTable( SdrModel* pModel ) +: SvxUnoForbiddenCharsTable( pModel->GetForbiddenCharsTable() ), mpModel( pModel ) +{ + StartListening( *pModel ); +} + +void SdUnoForbiddenCharsTable::onChange() +{ + if( mpModel ) + { + mpModel->ReformatAllTextObjects(); + } +} + +SdUnoForbiddenCharsTable::~SdUnoForbiddenCharsTable() +{ + SolarMutexGuard g; + + if( mpModel ) + EndListening( *mpModel ); +} + +void SdUnoForbiddenCharsTable::Notify( SfxBroadcaster&, const SfxHint& rHint ) noexcept +{ + if (rHint.GetId() != SfxHintId::ThisIsAnSdrHint) + return; + const SdrHint* pSdrHint = static_cast<const SdrHint*>( &rHint ); + if( SdrHintKind::ModelCleared == pSdrHint->GetKind() ) + { + mpModel = nullptr; + } +} + +const sal_uInt16 WID_MODEL_LANGUAGE = 1; +const sal_uInt16 WID_MODEL_TABSTOP = 2; +const sal_uInt16 WID_MODEL_VISAREA = 3; +const sal_uInt16 WID_MODEL_MAPUNIT = 4; +const sal_uInt16 WID_MODEL_FORBCHARS = 5; +const sal_uInt16 WID_MODEL_CONTFOCUS = 6; +const sal_uInt16 WID_MODEL_DSGNMODE = 7; +const sal_uInt16 WID_MODEL_BASICLIBS = 8; +const sal_uInt16 WID_MODEL_RUNTIMEUID = 9; +const sal_uInt16 WID_MODEL_BUILDID = 10; +const sal_uInt16 WID_MODEL_HASVALIDSIGNATURES = 11; +const sal_uInt16 WID_MODEL_DIALOGLIBS = 12; +const sal_uInt16 WID_MODEL_FONTS = 13; +const sal_uInt16 WID_MODEL_INTEROPGRABBAG = 14; +const sal_uInt16 WID_MODEL_THEME = 15; + +static const SvxItemPropertySet* ImplGetDrawModelPropertySet() +{ + // Attention: the first parameter HAS TO BE sorted!!! + const static SfxItemPropertyMapEntry aDrawModelPropertyMap_Impl[] = + { + { u"BuildId", WID_MODEL_BUILDID, ::cppu::UnoType<OUString>::get(), 0, 0}, + { sUNO_Prop_CharLocale, WID_MODEL_LANGUAGE, ::cppu::UnoType<lang::Locale>::get(), 0, 0}, + { sUNO_Prop_TabStop, WID_MODEL_TABSTOP, ::cppu::UnoType<sal_Int32>::get(), 0, 0}, + { sUNO_Prop_VisibleArea, WID_MODEL_VISAREA, ::cppu::UnoType<awt::Rectangle>::get(), 0, 0}, + { sUNO_Prop_MapUnit, WID_MODEL_MAPUNIT, ::cppu::UnoType<sal_Int16>::get(), beans::PropertyAttribute::READONLY, 0}, + { sUNO_Prop_ForbiddenCharacters, WID_MODEL_FORBCHARS, cppu::UnoType<i18n::XForbiddenCharacters>::get(), beans::PropertyAttribute::READONLY, 0}, + { sUNO_Prop_AutomContFocus, WID_MODEL_CONTFOCUS, cppu::UnoType<bool>::get(), 0, 0}, + { sUNO_Prop_ApplyFrmDsgnMode, WID_MODEL_DSGNMODE, cppu::UnoType<bool>::get(), 0, 0}, + { u"BasicLibraries", WID_MODEL_BASICLIBS, cppu::UnoType<script::XLibraryContainer>::get(), beans::PropertyAttribute::READONLY, 0}, + { u"DialogLibraries", WID_MODEL_DIALOGLIBS, cppu::UnoType<script::XLibraryContainer>::get(), beans::PropertyAttribute::READONLY, 0}, + { sUNO_Prop_RuntimeUID, WID_MODEL_RUNTIMEUID, ::cppu::UnoType<OUString>::get(), beans::PropertyAttribute::READONLY, 0}, + { sUNO_Prop_HasValidSignatures, WID_MODEL_HASVALIDSIGNATURES, ::cppu::UnoType<sal_Bool>::get(), beans::PropertyAttribute::READONLY, 0}, + { u"Fonts", WID_MODEL_FONTS, cppu::UnoType<uno::Sequence<uno::Any>>::get(), beans::PropertyAttribute::READONLY, 0}, + { sUNO_Prop_InteropGrabBag, WID_MODEL_INTEROPGRABBAG, cppu::UnoType<uno::Sequence< beans::PropertyValue >>::get(), 0, 0}, + { sUNO_Prop_Theme, WID_MODEL_THEME, cppu::UnoType<uno::Sequence< beans::PropertyValue >>::get(), 0, 0}, + { u"", 0, css::uno::Type(), 0, 0 } + }; + static SvxItemPropertySet aDrawModelPropertySet_Impl( aDrawModelPropertyMap_Impl, SdrObject::GetGlobalDrawObjectItemPool() ); + return &aDrawModelPropertySet_Impl; +} + +// this ctor is used from the DocShell +SdXImpressDocument::SdXImpressDocument(::sd::DrawDocShell* pShell, bool bClipBoard) +: SfxBaseModel( pShell ), + mpDocShell( pShell ), + mpDoc( pShell ? pShell->GetDoc() : nullptr ), + mbDisposed(false), + mbImpressDoc( pShell && pShell->GetDoc() && pShell->GetDoc()->GetDocumentType() == DocumentType::Impress ), + mbClipBoard( bClipBoard ), + mpPropSet( ImplGetDrawModelPropertySet() ) +{ + if( mpDoc ) + { + StartListening( *mpDoc ); + } + else + { + OSL_FAIL("DocShell is invalid"); + } +} + +SdXImpressDocument::SdXImpressDocument(SdDrawDocument* pDoc, bool bClipBoard) +: SfxBaseModel( nullptr ), + mpDocShell( nullptr ), + mpDoc( pDoc ), + mbDisposed(false), + mbImpressDoc( pDoc && pDoc->GetDocumentType() == DocumentType::Impress ), + mbClipBoard( bClipBoard ), + mpPropSet( ImplGetDrawModelPropertySet() ) +{ + if( mpDoc ) + { + StartListening( *mpDoc ); + } + else + { + OSL_FAIL("SdDrawDocument is invalid"); + } +} + +/*********************************************************************** +* * +***********************************************************************/ +SdXImpressDocument::~SdXImpressDocument() noexcept +{ +} + +// XInterface +uno::Any SAL_CALL SdXImpressDocument::queryInterface( const uno::Type & rType ) +{ + uno::Any aAny; + + if (rType == cppu::UnoType<lang::XServiceInfo>::get()) + aAny <<= uno::Reference<lang::XServiceInfo>(this); + else if (rType == cppu::UnoType<beans::XPropertySet>::get()) + aAny <<= uno::Reference<beans::XPropertySet>(this); + else if (rType == cppu::UnoType<lang::XMultiServiceFactory>::get()) + aAny <<= uno::Reference<lang::XMultiServiceFactory>(this); + else if (rType == cppu::UnoType<drawing::XDrawPageDuplicator>::get()) + aAny <<= uno::Reference<drawing::XDrawPageDuplicator>(this); + else if (rType == cppu::UnoType<drawing::XLayerSupplier>::get()) + aAny <<= uno::Reference<drawing::XLayerSupplier>(this); + else if (rType == cppu::UnoType<drawing::XMasterPagesSupplier>::get()) + aAny <<= uno::Reference<drawing::XMasterPagesSupplier>(this); + else if (rType == cppu::UnoType<drawing::XDrawPagesSupplier>::get()) + aAny <<= uno::Reference<drawing::XDrawPagesSupplier>(this); + else if (rType == cppu::UnoType<presentation::XHandoutMasterSupplier>::get()) + aAny <<= uno::Reference<presentation::XHandoutMasterSupplier>(this); + else if (rType == cppu::UnoType<document::XLinkTargetSupplier>::get()) + aAny <<= uno::Reference<document::XLinkTargetSupplier>(this); + else if (rType == cppu::UnoType<style::XStyleFamiliesSupplier>::get()) + aAny <<= uno::Reference<style::XStyleFamiliesSupplier>(this); + else if (rType == cppu::UnoType<css::ucb::XAnyCompareFactory>::get()) + aAny <<= uno::Reference<css::ucb::XAnyCompareFactory>(this); + else if (rType == cppu::UnoType<view::XRenderable>::get()) + aAny <<= uno::Reference<view::XRenderable>(this); + else if (mbImpressDoc && rType == cppu::UnoType<presentation::XPresentationSupplier>::get()) + aAny <<= uno::Reference< presentation::XPresentationSupplier >(this); + else if (mbImpressDoc && rType == cppu::UnoType<presentation::XCustomPresentationSupplier>::get()) + aAny <<= uno::Reference< presentation::XCustomPresentationSupplier >(this); + else + return SfxBaseModel::queryInterface(rType); + + return aAny; +} + +void SAL_CALL SdXImpressDocument::acquire() noexcept +{ + SfxBaseModel::acquire(); +} + +void SAL_CALL SdXImpressDocument::release() noexcept +{ + if (osl_atomic_decrement( &m_refCount ) != 0) + return; + + // restore reference count: + osl_atomic_increment( &m_refCount ); + if(!mbDisposed) + { + try + { + dispose(); + } + catch (const uno::RuntimeException&) + { + // don't break throw () + TOOLS_WARN_EXCEPTION( "sd", "" ); + } + } + SfxBaseModel::release(); +} + +// XUnoTunnel +const css::uno::Sequence< sal_Int8 > & SdXImpressDocument::getUnoTunnelId() noexcept +{ + static const comphelper::UnoIdInit theSdXImpressDocumentUnoTunnelId; + return theSdXImpressDocumentUnoTunnelId.getSeq(); +} + +sal_Int64 SAL_CALL SdXImpressDocument::getSomething( const css::uno::Sequence< sal_Int8 >& rIdentifier ) +{ + if (comphelper::isUnoTunnelId<SdrModel>(rIdentifier)) + return comphelper::getSomething_cast(mpDoc); + + return comphelper::getSomethingImpl(rIdentifier, this, + comphelper::FallbackToGetSomethingOf<SfxBaseModel>{}); +} + +// XTypeProvider +uno::Sequence< uno::Type > SAL_CALL SdXImpressDocument::getTypes( ) +{ + ::SolarMutexGuard aGuard; + + if( !maTypeSequence.hasElements() ) + { + uno::Sequence< uno::Type > aTypes( SfxBaseModel::getTypes() ); + aTypes = comphelper::concatSequences(aTypes, + uno::Sequence { + cppu::UnoType<beans::XPropertySet>::get(), + cppu::UnoType<lang::XServiceInfo>::get(), + cppu::UnoType<lang::XMultiServiceFactory>::get(), + cppu::UnoType<drawing::XDrawPageDuplicator>::get(), + cppu::UnoType<drawing::XLayerSupplier>::get(), + cppu::UnoType<drawing::XMasterPagesSupplier>::get(), + cppu::UnoType<drawing::XDrawPagesSupplier>::get(), + cppu::UnoType<document::XLinkTargetSupplier>::get(), + cppu::UnoType<style::XStyleFamiliesSupplier>::get(), + cppu::UnoType<css::ucb::XAnyCompareFactory>::get(), + cppu::UnoType<view::XRenderable>::get() }); + if( mbImpressDoc ) + { + aTypes = comphelper::concatSequences(aTypes, + uno::Sequence { + cppu::UnoType<presentation::XPresentationSupplier>::get(), + cppu::UnoType<presentation::XCustomPresentationSupplier>::get(), + cppu::UnoType<presentation::XHandoutMasterSupplier>::get() }); + } + maTypeSequence = aTypes; + } + + return maTypeSequence; +} + +uno::Sequence< sal_Int8 > SAL_CALL SdXImpressDocument::getImplementationId( ) +{ + return css::uno::Sequence<sal_Int8>(); +} + +/*********************************************************************** +* * +***********************************************************************/ +void SdXImpressDocument::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) +{ + if( mpDoc ) + { + if (rHint.GetId() == SfxHintId::ThisIsAnSdrHint) + { + const SdrHint* pSdrHint = static_cast<const SdrHint*>( &rHint ); + if( hasEventListeners() ) + { + document::EventObject aEvent; + if( SvxUnoDrawMSFactory::createEvent( mpDoc, pSdrHint, aEvent ) ) + notifyEvent( aEvent ); + } + + if( pSdrHint->GetKind() == SdrHintKind::ModelCleared ) + { + if( mpDoc ) + EndListening( *mpDoc ); + mpDoc = nullptr; + mpDocShell = nullptr; + } + } + else + { + // did our SdDrawDocument just died? + if(rHint.GetId() == SfxHintId::Dying) + { + // yes, so we ask for a new one + if( mpDocShell ) + { + SdDrawDocument *pNewDoc = mpDocShell->GetDoc(); + + // is there a new one? + if( pNewDoc != mpDoc ) + { + mpDoc = pNewDoc; + if(mpDoc) + StartListening( *mpDoc ); + } + } + } + } + } + SfxBaseModel::Notify( rBC, rHint ); +} + +/****************************************************************************** +* * +******************************************************************************/ +SdPage* SdXImpressDocument::InsertSdPage( sal_uInt16 nPage, bool bDuplicate ) +{ + sal_uInt16 nPageCount = mpDoc->GetSdPageCount( PageKind::Standard ); + SdrLayerAdmin& rLayerAdmin = mpDoc->GetLayerAdmin(); + SdrLayerID aBckgrnd = rLayerAdmin.GetLayerID(sUNO_LayerName_background); + SdrLayerID aBckgrndObj = rLayerAdmin.GetLayerID(sUNO_LayerName_background_objects); + + rtl::Reference<SdPage> pStandardPage; + + if( 0 == nPageCount ) + { + // this is only used for clipboard where we only have one page + pStandardPage = mpDoc->AllocSdPage(false); + + Size aDefSize(21000, 29700); // A4 portrait orientation + pStandardPage->SetSize( aDefSize ); + mpDoc->InsertPage(pStandardPage.get(), 0); + } + else + { + // here we determine the page after which we should insert + SdPage* pPreviousStandardPage = mpDoc->GetSdPage( std::min( static_cast<sal_uInt16>(nPageCount - 1), nPage ), PageKind::Standard ); + SdrLayerIDSet aVisibleLayers = pPreviousStandardPage->TRG_GetMasterPageVisibleLayers(); + bool bIsPageBack = aVisibleLayers.IsSet( aBckgrnd ); + bool bIsPageObj = aVisibleLayers.IsSet( aBckgrndObj ); + + // AutoLayouts must be ready + mpDoc->StopWorkStartupDelay(); + + /* First we create a standard page and then a notes page. It is + guaranteed, that after a standard page the corresponding notes page + follows. */ + + sal_uInt16 nStandardPageNum = pPreviousStandardPage->GetPageNum() + 2; + SdPage* pPreviousNotesPage = static_cast<SdPage*>( mpDoc->GetPage( nStandardPageNum - 1 ) ); + sal_uInt16 nNotesPageNum = nStandardPageNum + 1; + + /************************************************************** + * standard page + **************************************************************/ + if( bDuplicate ) + pStandardPage = static_cast<SdPage*>( pPreviousStandardPage->CloneSdrPage(*mpDoc).get() ); + else + pStandardPage = mpDoc->AllocSdPage(false); + + pStandardPage->SetSize( pPreviousStandardPage->GetSize() ); + pStandardPage->SetBorder( pPreviousStandardPage->GetLeftBorder(), + pPreviousStandardPage->GetUpperBorder(), + pPreviousStandardPage->GetRightBorder(), + pPreviousStandardPage->GetLowerBorder() ); + pStandardPage->SetOrientation( pPreviousStandardPage->GetOrientation() ); + pStandardPage->SetName(OUString()); + + // insert page after current page + mpDoc->InsertPage(pStandardPage.get(), nStandardPageNum); + + if( !bDuplicate ) + { + // use MasterPage of the current page + pStandardPage->TRG_SetMasterPage(pPreviousStandardPage->TRG_GetMasterPage()); + pStandardPage->SetLayoutName( pPreviousStandardPage->GetLayoutName() ); + pStandardPage->SetAutoLayout(AUTOLAYOUT_NONE, true ); + } + + aBckgrnd = rLayerAdmin.GetLayerID(sUNO_LayerName_background); + aBckgrndObj = rLayerAdmin.GetLayerID(sUNO_LayerName_background_objects); + aVisibleLayers.Set(aBckgrnd, bIsPageBack); + aVisibleLayers.Set(aBckgrndObj, bIsPageObj); + pStandardPage->TRG_SetMasterPageVisibleLayers(aVisibleLayers); + + /************************************************************** + * notes page + **************************************************************/ + rtl::Reference<SdPage> pNotesPage; + + if( bDuplicate ) + pNotesPage = static_cast<SdPage*>( pPreviousNotesPage->CloneSdrPage(*mpDoc).get() ); + else + pNotesPage = mpDoc->AllocSdPage(false); + + pNotesPage->SetSize( pPreviousNotesPage->GetSize() ); + pNotesPage->SetBorder( pPreviousNotesPage->GetLeftBorder(), + pPreviousNotesPage->GetUpperBorder(), + pPreviousNotesPage->GetRightBorder(), + pPreviousNotesPage->GetLowerBorder() ); + pNotesPage->SetOrientation( pPreviousNotesPage->GetOrientation() ); + pNotesPage->SetName(OUString()); + pNotesPage->SetPageKind(PageKind::Notes); + + // insert page after current page + mpDoc->InsertPage(pNotesPage.get(), nNotesPageNum); + + if( !bDuplicate ) + { + // use MasterPage of the current page + pNotesPage->TRG_SetMasterPage(pPreviousNotesPage->TRG_GetMasterPage()); + pNotesPage->SetLayoutName( pPreviousNotesPage->GetLayoutName() ); + pNotesPage->SetAutoLayout(AUTOLAYOUT_NOTES, true ); + } + } + + SetModified(); + + return pStandardPage.get(); +} + +void SdXImpressDocument::SetModified() noexcept +{ + if( mpDoc ) + mpDoc->SetChanged(); +} + +// XModel +void SAL_CALL SdXImpressDocument::lockControllers( ) +{ + ::SolarMutexGuard aGuard; + + if( nullptr == mpDoc ) + throw lang::DisposedException(); + + mpDoc->setLock(true); +} + +void SAL_CALL SdXImpressDocument::unlockControllers( ) +{ + ::SolarMutexGuard aGuard; + + if( nullptr == mpDoc ) + throw lang::DisposedException(); + + if( mpDoc->isLocked() ) + { + mpDoc->setLock(false); + } +} + +sal_Bool SAL_CALL SdXImpressDocument::hasControllersLocked( ) +{ + ::SolarMutexGuard aGuard; + + if( nullptr == mpDoc ) + throw lang::DisposedException(); + + return mpDoc->isLocked(); +} + +uno::Reference < container::XIndexAccess > SAL_CALL SdXImpressDocument::getViewData() +{ + ::SolarMutexGuard aGuard; + + if( nullptr == mpDoc ) + throw lang::DisposedException(); + + uno::Reference < container::XIndexAccess > xRet( SfxBaseModel::getViewData() ); + + if( !xRet.is() ) + { + const std::vector<std::unique_ptr<sd::FrameView>> &rList = mpDoc->GetFrameViewList(); + + if( !rList.empty() ) + { + xRet = new comphelper::IndexedPropertyValuesContainer(); + + uno::Reference < container::XIndexContainer > xCont( xRet, uno::UNO_QUERY ); + DBG_ASSERT( xCont.is(), "SdXImpressDocument::getViewData() failed for OLE object" ); + if( xCont.is() ) + { + for( sal_uInt32 i = 0, n = rList.size(); i < n; i++ ) + { + ::sd::FrameView* pFrameView = rList[ i ].get(); + + uno::Sequence< beans::PropertyValue > aSeq; + pFrameView->WriteUserDataSequence( aSeq ); + xCont->insertByIndex( i, uno::Any( aSeq ) ); + } + } + } + } + + return xRet; +} + +void SAL_CALL SdXImpressDocument::setViewData( const uno::Reference < container::XIndexAccess >& xData ) +{ + ::SolarMutexGuard aGuard; + + if( nullptr == mpDoc ) + throw lang::DisposedException(); + + SfxBaseModel::setViewData( xData ); + if( !(mpDocShell && (mpDocShell->GetCreateMode() == SfxObjectCreateMode::EMBEDDED) && xData.is()) ) + return; + + const sal_Int32 nCount = xData->getCount(); + + std::vector<std::unique_ptr<sd::FrameView>> &rViews = mpDoc->GetFrameViewList(); + + rViews.clear(); + + uno::Sequence< beans::PropertyValue > aSeq; + for( sal_Int32 nIndex = 0; nIndex < nCount; nIndex++ ) + { + if( xData->getByIndex( nIndex ) >>= aSeq ) + { + std::unique_ptr<::sd::FrameView> pFrameView(new ::sd::FrameView( mpDoc )); + pFrameView->ReadUserDataSequence( aSeq ); + rViews.push_back( std::move(pFrameView) ); + } + } +} + +// XDrawPageDuplicator +uno::Reference< drawing::XDrawPage > SAL_CALL SdXImpressDocument::duplicate( const uno::Reference< drawing::XDrawPage >& xPage ) +{ + ::SolarMutexGuard aGuard; + + if( nullptr == mpDoc ) + throw lang::DisposedException(); + + // get pPage from xPage and determine the Id (nPos ) afterwards + SvxDrawPage* pSvxPage = comphelper::getFromUnoTunnel<SvxDrawPage>( xPage ); + if( pSvxPage ) + { + SdPage* pPage = static_cast<SdPage*>( pSvxPage->GetSdrPage() ); + sal_uInt16 nPos = pPage->GetPageNum(); + nPos = ( nPos - 1 ) / 2; + pPage = InsertSdPage( nPos, true ); + if( pPage ) + { + uno::Reference< drawing::XDrawPage > xDrawPage( pPage->getUnoPage(), uno::UNO_QUERY ); + return xDrawPage; + } + } + + uno::Reference< drawing::XDrawPage > xDrawPage; + return xDrawPage; +} + +// XDrawPagesSupplier +uno::Reference< drawing::XDrawPages > SAL_CALL SdXImpressDocument::getDrawPages() +{ + ::SolarMutexGuard aGuard; + + if( nullptr == mpDoc ) + throw lang::DisposedException(); + + uno::Reference< drawing::XDrawPages > xDrawPages( mxDrawPagesAccess ); + + if( !xDrawPages.is() ) + { + initializeDocument(); + mxDrawPagesAccess = xDrawPages = new SdDrawPagesAccess(*this); + } + + return xDrawPages; +} + +// XMasterPagesSupplier +uno::Reference< drawing::XDrawPages > SAL_CALL SdXImpressDocument::getMasterPages() +{ + ::SolarMutexGuard aGuard; + + if( nullptr == mpDoc ) + throw lang::DisposedException(); + + uno::Reference< drawing::XDrawPages > xMasterPages( mxMasterPagesAccess ); + + if( !xMasterPages.is() ) + { + if ( !hasControllersLocked() ) + initializeDocument(); + mxMasterPagesAccess = xMasterPages = new SdMasterPagesAccess(*this); + } + + return xMasterPages; +} + +// XLayerManagerSupplier +uno::Reference< container::XNameAccess > SAL_CALL SdXImpressDocument::getLayerManager( ) +{ + ::SolarMutexGuard aGuard; + + if( nullptr == mpDoc ) + throw lang::DisposedException(); + + uno::Reference< container::XNameAccess > xLayerManager( mxLayerManager ); + + if( !xLayerManager.is() ) + mxLayerManager = xLayerManager = new SdLayerManager(*this); + + return xLayerManager; +} + +// XCustomPresentationSupplier +uno::Reference< container::XNameContainer > SAL_CALL SdXImpressDocument::getCustomPresentations() +{ + ::SolarMutexGuard aGuard; + + if( nullptr == mpDoc ) + throw lang::DisposedException(); + + uno::Reference< container::XNameContainer > xCustomPres( mxCustomPresentationAccess ); + + if( !xCustomPres.is() ) + mxCustomPresentationAccess = xCustomPres = new SdXCustomPresentationAccess(*this); + + return xCustomPres; +} + +// XPresentationSupplier +uno::Reference< presentation::XPresentation > SAL_CALL SdXImpressDocument::getPresentation() +{ + ::SolarMutexGuard aGuard; + + if( nullptr == mpDoc ) + throw lang::DisposedException(); + + return mpDoc->getPresentation(); +} + +// XHandoutMasterSupplier +uno::Reference< drawing::XDrawPage > SAL_CALL SdXImpressDocument::getHandoutMasterPage() +{ + ::SolarMutexGuard aGuard; + + if( nullptr == mpDoc ) + throw lang::DisposedException(); + + uno::Reference< drawing::XDrawPage > xPage; + + initializeDocument(); + SdPage* pPage = mpDoc->GetMasterSdPage(0, PageKind::Handout); + if (pPage) + xPage.set(pPage->getUnoPage(), uno::UNO_QUERY); + return xPage; +} + +// XMultiServiceFactory ( SvxFmMSFactory ) + +css::uno::Reference<css::uno::XInterface> SdXImpressDocument::create( + OUString const & aServiceSpecifier, OUString const & referer) +{ + ::SolarMutexGuard aGuard; + + if( nullptr == mpDoc ) + throw lang::DisposedException(); + + if( aServiceSpecifier == "com.sun.star.drawing.DashTable" ) + { + if( !mxDashTable.is() ) + mxDashTable = SvxUnoDashTable_createInstance( mpDoc ); + + return mxDashTable; + } + if( aServiceSpecifier == "com.sun.star.drawing.GradientTable" ) + { + if( !mxGradientTable.is() ) + mxGradientTable = SvxUnoGradientTable_createInstance( mpDoc ); + + return mxGradientTable; + } + if( aServiceSpecifier == "com.sun.star.drawing.HatchTable" ) + { + if( !mxHatchTable.is() ) + mxHatchTable = SvxUnoHatchTable_createInstance( mpDoc ); + + return mxHatchTable; + } + if( aServiceSpecifier == "com.sun.star.drawing.BitmapTable" ) + { + if( !mxBitmapTable.is() ) + mxBitmapTable = SvxUnoBitmapTable_createInstance( mpDoc ); + + return mxBitmapTable; + } + if( aServiceSpecifier == "com.sun.star.drawing.TransparencyGradientTable" ) + { + if( !mxTransGradientTable.is() ) + mxTransGradientTable = SvxUnoTransGradientTable_createInstance( mpDoc ); + + return mxTransGradientTable; + } + if( aServiceSpecifier == "com.sun.star.drawing.MarkerTable" ) + { + if( !mxMarkerTable.is() ) + mxMarkerTable = SvxUnoMarkerTable_createInstance( mpDoc ); + + return mxMarkerTable; + } + if( aServiceSpecifier == "com.sun.star.text.NumberingRules" ) + { + return uno::Reference< uno::XInterface >( SvxCreateNumRule( mpDoc ), uno::UNO_QUERY ); + } + if( aServiceSpecifier == "com.sun.star.drawing.Background" ) + { + return uno::Reference< uno::XInterface >( + static_cast<uno::XWeak*>(new SdUnoPageBackground( mpDoc ))); + } + + if( aServiceSpecifier == "com.sun.star.drawing.Defaults" ) + { + if( !mxDrawingPool.is() ) + mxDrawingPool = SdUnoCreatePool( mpDoc ); + + return mxDrawingPool; + + } + + if ( aServiceSpecifier == sUNO_Service_ImageMapRectangleObject ) + { + return SvUnoImageMapRectangleObject_createInstance( ImplGetSupportedMacroItems() ); + } + + if ( aServiceSpecifier == sUNO_Service_ImageMapCircleObject ) + { + return SvUnoImageMapCircleObject_createInstance( ImplGetSupportedMacroItems() ); + } + + if ( aServiceSpecifier == sUNO_Service_ImageMapPolygonObject ) + { + return SvUnoImageMapPolygonObject_createInstance( ImplGetSupportedMacroItems() ); + } + + if( aServiceSpecifier == "com.sun.star.document.Settings" || + ( !mbImpressDoc && ( aServiceSpecifier == "com.sun.star.drawing.DocumentSettings" ) ) || + ( mbImpressDoc && ( aServiceSpecifier == "com.sun.star.presentation.DocumentSettings" ) ) ) + { + return sd::DocumentSettings_createInstance( this ); + } + + if( aServiceSpecifier == "com.sun.star.text.TextField.DateTime" || + aServiceSpecifier == "com.sun.star.text.textfield.DateTime" ) + { + return static_cast<cppu::OWeakObject *>(new SvxUnoTextField( text::textfield::Type::DATE )); + } + + if( aServiceSpecifier == "com.sun.star.presentation.TextField.Header" || + aServiceSpecifier == "com.sun.star.presentation.textfield.Header" ) + { + return static_cast<cppu::OWeakObject *>(new SvxUnoTextField( text::textfield::Type::PRESENTATION_HEADER )); + } + + if( aServiceSpecifier == "com.sun.star.presentation.TextField.Footer" || + aServiceSpecifier == "com.sun.star.presentation.textfield.Footer" ) + { + return static_cast<cppu::OWeakObject *>(new SvxUnoTextField( text::textfield::Type::PRESENTATION_FOOTER )); + } + + if( aServiceSpecifier == "com.sun.star.presentation.TextField.DateTime" || + aServiceSpecifier == "com.sun.star.presentation.textfield.DateTime" ) + { + return static_cast<cppu::OWeakObject *>(new SvxUnoTextField( text::textfield::Type::PRESENTATION_DATE_TIME )); + } + + if( aServiceSpecifier == "com.sun.star.text.TextField.PageName" || + aServiceSpecifier == "com.sun.star.text.textfield.PageName" ) + { + return static_cast<cppu::OWeakObject *>(new SvxUnoTextField( text::textfield::Type::PAGE_NAME )); + } + + if (aServiceSpecifier == "com.sun.star.text.TextField.DocInfo.Custom" || + aServiceSpecifier == "com.sun.star.text.textfield.DocInfo.Custom") + { + return static_cast<cppu::OWeakObject *>(new SvxUnoTextField(text::textfield::Type::DOCINFO_CUSTOM)); + } + + if( aServiceSpecifier == "com.sun.star.xml.NamespaceMap" ) + { + static sal_uInt16 aWhichIds[] = { SDRATTR_XMLATTRIBUTES, EE_CHAR_XMLATTRIBS, EE_PARA_XMLATTRIBS, 0 }; + + return svx::NamespaceMap_createInstance( aWhichIds, &mpDoc->GetItemPool() ); + } + + // Support creation of GraphicStorageHandler and EmbeddedObjectResolver + if (aServiceSpecifier == "com.sun.star.document.ExportGraphicStorageHandler") + { + return static_cast<cppu::OWeakObject *>(new SvXMLGraphicHelper( SvXMLGraphicHelperMode::Write )); + } + + if (aServiceSpecifier == "com.sun.star.document.ImportGraphicStorageHandler") + { + return static_cast<cppu::OWeakObject *>(new SvXMLGraphicHelper( SvXMLGraphicHelperMode::Read )); + } + + if( aServiceSpecifier == "com.sun.star.document.ExportEmbeddedObjectResolver" ) + { + comphelper::IEmbeddedHelper* pPersist = mpDoc->GetPersist(); + if( nullptr == pPersist ) + throw lang::DisposedException(); + + return static_cast<cppu::OWeakObject *>(new SvXMLEmbeddedObjectHelper( *pPersist, SvXMLEmbeddedObjectHelperMode::Write )); + } + + if( aServiceSpecifier == "com.sun.star.document.ImportEmbeddedObjectResolver" ) + { + comphelper::IEmbeddedHelper* pPersist = mpDoc->GetPersist(); + if( nullptr == pPersist ) + throw lang::DisposedException(); + + return static_cast<cppu::OWeakObject *>(new SvXMLEmbeddedObjectHelper( *pPersist, SvXMLEmbeddedObjectHelperMode::Read )); + } + + uno::Reference< uno::XInterface > xRet; + + if( aServiceSpecifier.startsWith( "com.sun.star.presentation.") ) + { + const std::u16string_view aType( aServiceSpecifier.subView(26) ); + rtl::Reference<SvxShape> pShape; + + SdrObjKind nType = SdrObjKind::Text; + // create a shape wrapper + if( o3tl::starts_with(aType, u"TitleTextShape" ) ) + { + nType = SdrObjKind::Text; + } + else if( o3tl::starts_with(aType, u"OutlinerShape" ) ) + { + nType = SdrObjKind::Text; + } + else if( o3tl::starts_with(aType, u"SubtitleShape" ) ) + { + nType = SdrObjKind::Text; + } + else if( o3tl::starts_with(aType, u"GraphicObjectShape" ) ) + { + nType = SdrObjKind::Graphic; + } + else if( o3tl::starts_with(aType, u"PageShape" ) ) + { + nType = SdrObjKind::Page; + } + else if( o3tl::starts_with(aType, u"OLE2Shape" ) ) + { + nType = SdrObjKind::OLE2; + } + else if( o3tl::starts_with(aType, u"ChartShape" ) ) + { + nType = SdrObjKind::OLE2; + } + else if( o3tl::starts_with(aType, u"CalcShape" ) ) + { + nType = SdrObjKind::OLE2; + } + else if( o3tl::starts_with(aType, u"TableShape" ) ) + { + nType = SdrObjKind::Table; + } + else if( o3tl::starts_with(aType, u"OrgChartShape" ) ) + { + nType = SdrObjKind::OLE2; + } + else if( o3tl::starts_with(aType, u"NotesShape" ) ) + { + nType = SdrObjKind::Text; + } + else if( o3tl::starts_with(aType, u"HandoutShape" ) ) + { + nType = SdrObjKind::Page; + } + else if( o3tl::starts_with(aType, u"FooterShape" ) ) + { + nType = SdrObjKind::Text; + } + else if( o3tl::starts_with(aType, u"HeaderShape" ) ) + { + nType = SdrObjKind::Text; + } + else if( o3tl::starts_with(aType, u"SlideNumberShape" ) ) + { + nType = SdrObjKind::Text; + } + else if( o3tl::starts_with(aType, u"DateTimeShape" ) ) + { + nType = SdrObjKind::Text; + } + else if( o3tl::starts_with(aType, u"MediaShape" ) ) + { + nType = SdrObjKind::Media; + } + else + { + throw lang::ServiceNotRegisteredException(); + } + + // create the API wrapper + pShape = CreateSvxShapeByTypeAndInventor( nType, SdrInventor::Default, referer ); + + // set shape type + if( pShape && !mbClipBoard ) + pShape->SetShapeType(aServiceSpecifier); + + xRet = static_cast<uno::XWeak*>(pShape.get()); + } + else if ( aServiceSpecifier == "com.sun.star.drawing.TableShape" ) + { + rtl::Reference<SvxShape> pShape = CreateSvxShapeByTypeAndInventor( SdrObjKind::Table, SdrInventor::Default, referer ); + if( pShape && !mbClipBoard ) + pShape->SetShapeType(aServiceSpecifier); + + xRet = static_cast<uno::XWeak*>(pShape.get()); + } + else + { + xRet = SvxFmMSFactory::createInstance( aServiceSpecifier ); + } + + uno::Reference< drawing::XShape > xShape( xRet, uno::UNO_QUERY ); + SvxShape* pShape = xShape.is() ? comphelper::getFromUnoTunnel<SvxShape>(xShape) : nullptr; + if (pShape) + { + xRet.clear(); + new SdXShape( pShape, this ); + xRet = xShape; + xShape.clear(); + } + + return xRet; +} + +uno::Reference< uno::XInterface > SAL_CALL SdXImpressDocument::createInstance( const OUString& aServiceSpecifier ) +{ + return create(aServiceSpecifier, ""); +} + +css::uno::Reference<css::uno::XInterface> +SdXImpressDocument::createInstanceWithArguments( + OUString const & ServiceSpecifier, + css::uno::Sequence<css::uno::Any> const & Arguments) +{ + OUString arg; + if ((ServiceSpecifier == "com.sun.star.drawing.GraphicObjectShape" + || ServiceSpecifier == "com.sun.star.drawing.MediaShape" + || ServiceSpecifier == "com.sun.star.presentation.MediaShape") + && Arguments.getLength() == 1 && (Arguments[0] >>= arg)) + { + return create(ServiceSpecifier, arg); + } + return SvxFmMSFactory::createInstanceWithArguments( + ServiceSpecifier, Arguments); +} + +uno::Sequence< OUString > SAL_CALL SdXImpressDocument::getAvailableServiceNames() +{ + ::SolarMutexGuard aGuard; + + if( nullptr == mpDoc ) + throw lang::DisposedException(); + + const uno::Sequence< OUString > aSNS_ORG( SvxFmMSFactory::getAvailableServiceNames() ); + + uno::Sequence< OUString > aSNS_Common{ "com.sun.star.drawing.DashTable", + "com.sun.star.drawing.GradientTable", + "com.sun.star.drawing.HatchTable", + "com.sun.star.drawing.BitmapTable", + "com.sun.star.drawing.TransparencyGradientTable", + "com.sun.star.drawing.MarkerTable", + "com.sun.star.text.NumberingRules", + "com.sun.star.drawing.Background", + "com.sun.star.document.Settings", + sUNO_Service_ImageMapRectangleObject, + sUNO_Service_ImageMapCircleObject, + sUNO_Service_ImageMapPolygonObject, + "com.sun.star.xml.NamespaceMap", + + // Support creation of GraphicStorageHandler and EmbeddedObjectResolver + "com.sun.star.document.ExportGraphicStorageHandler", + "com.sun.star.document.ImportGraphicStorageHandler", + "com.sun.star.document.ExportEmbeddedObjectResolver", + "com.sun.star.document.ImportEmbeddedObjectResolver", + "com.sun.star.drawing.TableShape" }; + + uno::Sequence< OUString > aSNS_Specific; + + if(mbImpressDoc) + aSNS_Specific = { "com.sun.star.presentation.TitleTextShape", + "com.sun.star.presentation.OutlinerShape", + "com.sun.star.presentation.SubtitleShape", + "com.sun.star.presentation.GraphicObjectShape", + "com.sun.star.presentation.ChartShape", + "com.sun.star.presentation.PageShape", + "com.sun.star.presentation.OLE2Shape", + "com.sun.star.presentation.TableShape", + "com.sun.star.presentation.OrgChartShape", + "com.sun.star.presentation.NotesShape", + "com.sun.star.presentation.HandoutShape", + "com.sun.star.presentation.DocumentSettings", + "com.sun.star.presentation.FooterShape", + "com.sun.star.presentation.HeaderShape", + "com.sun.star.presentation.SlideNumberShape", + "com.sun.star.presentation.DateTimeShape", + "com.sun.star.presentation.CalcShape", + "com.sun.star.presentation.MediaShape" }; + else + aSNS_Specific = { "com.sun.star.drawing.DocumentSettings" }; + + return comphelper::concatSequences( aSNS_ORG, aSNS_Common, aSNS_Specific ); +} + +// lang::XServiceInfo +OUString SAL_CALL SdXImpressDocument::getImplementationName() +{ + return "SdXImpressDocument"; + /* // Matching the .component information: + return mbImpressDoc + ? OUString("com.sun.star.comp.Draw.PresentationDocument") + : OUString("com.sun.star.comp.Draw.DrawingDocument"); + */ +} + +sal_Bool SAL_CALL SdXImpressDocument::supportsService( const OUString& ServiceName ) +{ + return cppu::supportsService(this, ServiceName); +} + +uno::Sequence< OUString > SAL_CALL SdXImpressDocument::getSupportedServiceNames() +{ + ::SolarMutexGuard aGuard; + + return { "com.sun.star.document.OfficeDocument", + "com.sun.star.drawing.GenericDrawingDocument", + "com.sun.star.drawing.DrawingDocumentFactory", + mbImpressDoc?OUString("com.sun.star.presentation.PresentationDocument"):OUString("com.sun.star.drawing.DrawingDocument") }; +} + +// XPropertySet +uno::Reference< beans::XPropertySetInfo > SAL_CALL SdXImpressDocument::getPropertySetInfo( ) +{ + ::SolarMutexGuard aGuard; + return mpPropSet->getPropertySetInfo(); +} + +void SAL_CALL SdXImpressDocument::setPropertyValue( const OUString& aPropertyName, const uno::Any& aValue ) +{ + ::SolarMutexGuard aGuard; + + if( nullptr == mpDoc ) + throw lang::DisposedException(); + + const SfxItemPropertyMapEntry* pEntry = mpPropSet->getPropertyMapEntry(aPropertyName); + + switch( pEntry ? pEntry->nWID : -1 ) + { + case WID_MODEL_LANGUAGE: + { + lang::Locale aLocale; + if(!(aValue >>= aLocale)) + throw lang::IllegalArgumentException(); + + mpDoc->SetLanguage( LanguageTag::convertToLanguageType(aLocale), EE_CHAR_LANGUAGE ); + break; + } + case WID_MODEL_TABSTOP: + { + sal_Int32 nValue = 0; + if(!(aValue >>= nValue) || nValue < 0 ) + throw lang::IllegalArgumentException(); + + mpDoc->SetDefaultTabulator(static_cast<sal_uInt16>(nValue)); + break; + } + case WID_MODEL_VISAREA: + { + SfxObjectShell* pEmbeddedObj = mpDoc->GetDocSh(); + if( !pEmbeddedObj ) + break; + + awt::Rectangle aVisArea; + if( !(aValue >>= aVisArea) || (aVisArea.Width < 0) || (aVisArea.Height < 0) ) + throw lang::IllegalArgumentException(); + + sal_Int32 nRight, nTop; + if (o3tl::checked_add(aVisArea.X, aVisArea.Width, nRight) || o3tl::checked_add(aVisArea.Y, aVisArea.Height, nTop)) + throw lang::IllegalArgumentException(); + + pEmbeddedObj->SetVisArea(::tools::Rectangle(aVisArea.X, aVisArea.Y, nRight, nTop)); + } + break; + case WID_MODEL_CONTFOCUS: + { + bool bFocus = false; + if( !(aValue >>= bFocus ) ) + throw lang::IllegalArgumentException(); + mpDoc->SetAutoControlFocus( bFocus ); + } + break; + case WID_MODEL_DSGNMODE: + { + bool bMode = false; + if( !(aValue >>= bMode ) ) + throw lang::IllegalArgumentException(); + mpDoc->SetOpenInDesignMode( bMode ); + } + break; + case WID_MODEL_BUILDID: + aValue >>= maBuildId; + return; + case WID_MODEL_MAPUNIT: + case WID_MODEL_BASICLIBS: + case WID_MODEL_RUNTIMEUID: // is read-only + case WID_MODEL_DIALOGLIBS: + case WID_MODEL_FONTS: + throw beans::PropertyVetoException(); + case WID_MODEL_INTEROPGRABBAG: + setGrabBagItem(aValue); + break; + case WID_MODEL_THEME: + { + SdrModel& rModel = getSdrModelFromUnoModel(); + std::unique_ptr<svx::Theme> pTheme = svx::Theme::FromAny(aValue); + rModel.SetTheme(std::move(pTheme)); + } + break; + default: + throw beans::UnknownPropertyException( aPropertyName, static_cast<cppu::OWeakObject*>(this)); + } + + SetModified(); +} + +uno::Any SAL_CALL SdXImpressDocument::getPropertyValue( const OUString& PropertyName ) +{ + ::SolarMutexGuard aGuard; + + uno::Any aAny; + if( nullptr == mpDoc ) + throw lang::DisposedException(); + + const SfxItemPropertyMapEntry* pEntry = mpPropSet->getPropertyMapEntry(PropertyName); + + switch( pEntry ? pEntry->nWID : -1 ) + { + case WID_MODEL_LANGUAGE: + { + LanguageType eLang = mpDoc->GetLanguage( EE_CHAR_LANGUAGE ); + aAny <<= LanguageTag::convertToLocale( eLang); + break; + } + case WID_MODEL_TABSTOP: + aAny <<= static_cast<sal_Int32>(mpDoc->GetDefaultTabulator()); + break; + case WID_MODEL_VISAREA: + { + SfxObjectShell* pEmbeddedObj = mpDoc->GetDocSh(); + if( !pEmbeddedObj ) + break; + + const ::tools::Rectangle& aRect = pEmbeddedObj->GetVisArea(); + awt::Rectangle aVisArea( aRect.Left(), aRect.Top(), aRect.getWidth(), aRect.getHeight() ); + aAny <<= aVisArea; + } + break; + case WID_MODEL_MAPUNIT: + { + SfxObjectShell* pEmbeddedObj = mpDoc->GetDocSh(); + if( !pEmbeddedObj ) + break; + + sal_Int16 nMeasureUnit = 0; + SvxMapUnitToMeasureUnit( pEmbeddedObj->GetMapUnit(), nMeasureUnit ); + aAny <<= nMeasureUnit; + } + break; + case WID_MODEL_FORBCHARS: + { + aAny <<= getForbiddenCharsTable(); + } + break; + case WID_MODEL_CONTFOCUS: + aAny <<= mpDoc->GetAutoControlFocus(); + break; + case WID_MODEL_DSGNMODE: + aAny <<= mpDoc->GetOpenInDesignMode(); + break; + case WID_MODEL_BASICLIBS: + aAny <<= mpDocShell->GetBasicContainer(); + break; + case WID_MODEL_DIALOGLIBS: + aAny <<= mpDocShell->GetDialogContainer(); + break; + case WID_MODEL_RUNTIMEUID: + aAny <<= getRuntimeUID(); + break; + case WID_MODEL_BUILDID: + return uno::Any( maBuildId ); + case WID_MODEL_HASVALIDSIGNATURES: + aAny <<= hasValidSignatures(); + break; + case WID_MODEL_FONTS: + { + uno::Sequence<uno::Any> aSeq; + int nSeqIndex = 0; + + sal_uInt16 const aWhichIds[] { EE_CHAR_FONTINFO, EE_CHAR_FONTINFO_CJK, + EE_CHAR_FONTINFO_CTL }; + + const SfxItemPool& rPool = mpDoc->GetPool(); + + for(sal_uInt16 nWhichId : aWhichIds) + { + sal_uInt32 nItems = rPool.GetItemCount2( nWhichId ); + + aSeq.realloc( aSeq.getLength() + nItems*5 + 5 ); + auto pSeq = aSeq.getArray(); + + for (const SfxPoolItem* pItem : rPool.GetItemSurrogates(nWhichId)) + { + const SvxFontItem *pFont = static_cast<const SvxFontItem *>(pItem); + + pSeq[nSeqIndex++] <<= pFont->GetFamilyName(); + pSeq[nSeqIndex++] <<= pFont->GetStyleName(); + pSeq[nSeqIndex++] <<= sal_Int16(pFont->GetFamily()); + pSeq[nSeqIndex++] <<= sal_Int16(pFont->GetPitch()); + pSeq[nSeqIndex++] <<= sal_Int16(pFont->GetCharSet()); + } + + const SvxFontItem& rFont = static_cast<const SvxFontItem&>(rPool.GetDefaultItem( nWhichId )); + + pSeq[nSeqIndex++] <<= rFont.GetFamilyName(); + pSeq[nSeqIndex++] <<= rFont.GetStyleName(); + pSeq[nSeqIndex++] <<= sal_Int16(rFont.GetFamily()); + pSeq[nSeqIndex++] <<= sal_Int16(rFont.GetPitch()); + pSeq[nSeqIndex++] <<= sal_Int16(rFont.GetCharSet()); + + } + + aSeq.realloc( nSeqIndex ); + aAny <<= aSeq; + break; + } + case WID_MODEL_INTEROPGRABBAG: + getGrabBagItem(aAny); + break; + case WID_MODEL_THEME: + { + SdrModel& rModel = getSdrModelFromUnoModel(); + svx::Theme* pTheme = rModel.GetTheme(); + if (pTheme) + { + pTheme->ToAny(aAny); + } + else + { + beans::PropertyValues aValues; + aAny <<= aValues; + } + break; + } + default: + throw beans::UnknownPropertyException( PropertyName, static_cast<cppu::OWeakObject*>(this)); + } + + return aAny; +} + +void SAL_CALL SdXImpressDocument::addPropertyChangeListener( const OUString& , const uno::Reference< beans::XPropertyChangeListener >& ) {} +void SAL_CALL SdXImpressDocument::removePropertyChangeListener( const OUString& , const uno::Reference< beans::XPropertyChangeListener >& ) {} +void SAL_CALL SdXImpressDocument::addVetoableChangeListener( const OUString& , const uno::Reference< beans::XVetoableChangeListener >& ) {} +void SAL_CALL SdXImpressDocument::removeVetoableChangeListener( const OUString& , const uno::Reference< beans::XVetoableChangeListener >& ) {} + +// XLinkTargetSupplier +uno::Reference< container::XNameAccess > SAL_CALL SdXImpressDocument::getLinks() +{ + ::SolarMutexGuard aGuard; + + if( nullptr == mpDoc ) + throw lang::DisposedException(); + + uno::Reference< container::XNameAccess > xLinks( mxLinks ); + if( !xLinks.is() ) + mxLinks = xLinks = new SdDocLinkTargets( *this ); + return xLinks; +} + +// XStyleFamiliesSupplier +uno::Reference< container::XNameAccess > SAL_CALL SdXImpressDocument::getStyleFamilies( ) +{ + ::SolarMutexGuard aGuard; + + if( nullptr == mpDoc ) + throw lang::DisposedException(); + + uno::Reference< container::XNameAccess > xStyles( dynamic_cast< container::XNameAccess* >( mpDoc->GetStyleSheetPool()) ); + return xStyles; +} + +// XAnyCompareFactory +uno::Reference< css::ucb::XAnyCompare > SAL_CALL SdXImpressDocument::createAnyCompareByName( const OUString& ) +{ + return SvxCreateNumRuleCompare(); +} + +// XRenderable +sal_Int32 SAL_CALL SdXImpressDocument::getRendererCount( const uno::Any& rSelection, + const uno::Sequence< beans::PropertyValue >& ) +{ + ::SolarMutexGuard aGuard; + sal_Int32 nRet = 0; + + if( nullptr == mpDoc ) + throw lang::DisposedException(); + + if (mpDocShell) + { + uno::Reference< frame::XModel > xModel; + + rSelection >>= xModel; + + if( xModel == mpDocShell->GetModel() ) + nRet = mpDoc->GetSdPageCount( PageKind::Standard ); + else + { + uno::Reference< drawing::XShapes > xShapes; + + rSelection >>= xShapes; + + if( xShapes.is() && xShapes->getCount() ) + nRet = 1; + } + } + return nRet; +} + +uno::Sequence< beans::PropertyValue > SAL_CALL SdXImpressDocument::getRenderer( sal_Int32 , const uno::Any& , + const uno::Sequence< beans::PropertyValue >& rxOptions ) +{ + ::SolarMutexGuard aGuard; + + if( nullptr == mpDoc ) + throw lang::DisposedException(); + + bool bExportNotesPages = false; + for( const auto& rOption : rxOptions ) + { + if ( rOption.Name == "ExportNotesPages" ) + rOption.Value >>= bExportNotesPages; + } + uno::Sequence< beans::PropertyValue > aRenderer; + if (mpDocShell) + { + awt::Size aPageSize; + if ( bExportNotesPages ) + { + Size aNotesPageSize = mpDoc->GetSdPage( 0, PageKind::Notes )->GetSize(); + aPageSize = awt::Size( aNotesPageSize.Width(), aNotesPageSize.Height() ); + } + else + { + const ::tools::Rectangle aVisArea( mpDocShell->GetVisArea( embed::Aspects::MSOLE_DOCPRINT ) ); + aPageSize = awt::Size( aVisArea.GetWidth(), aVisArea.GetHeight() ); + } + aRenderer = { comphelper::makePropertyValue("PageSize", aPageSize) }; + } + return aRenderer; +} + +namespace { + +class ImplRenderPaintProc : public sdr::contact::ViewObjectContactRedirector +{ + const SdrLayerAdmin& rLayerAdmin; + SdrPageView* pSdrPageView; + +public: + bool IsVisible ( const SdrObject* pObj ) const; + bool IsPrintable( const SdrObject* pObj ) const; + + ImplRenderPaintProc(const SdrLayerAdmin& rLA, SdrPageView* pView); + + // all default implementations just call the same methods at the original. To do something + // different, override the method and at least do what the method does. + virtual void createRedirectedPrimitive2DSequence( + const sdr::contact::ViewObjectContact& rOriginal, + const sdr::contact::DisplayInfo& rDisplayInfo, + drawinglayer::primitive2d::Primitive2DDecompositionVisitor& rVisitor) override; +}; + +} + +ImplRenderPaintProc::ImplRenderPaintProc(const SdrLayerAdmin& rLA, SdrPageView *const pView) + : rLayerAdmin(rLA) + , pSdrPageView(pView) +{ +} + +static sal_Int32 ImplPDFGetBookmarkPage( const OUString& rBookmark, SdDrawDocument const & rDoc ) +{ + sal_Int32 nPage = -1; + + OUString aBookmark( rBookmark ); + + if( rBookmark.startsWith("#") ) + aBookmark = rBookmark.copy( 1 ); + + // is the bookmark a page ? + bool bIsMasterPage; + sal_uInt16 nPgNum = rDoc.GetPageByName( aBookmark, bIsMasterPage ); + + if ( nPgNum == SDRPAGE_NOTFOUND ) + { + // is the bookmark an object ? + SdrObject* pObj = rDoc.GetObj( aBookmark ); + if (pObj) + nPgNum = pObj->getSdrPageFromSdrObject()->GetPageNum(); + } + if ( nPgNum != SDRPAGE_NOTFOUND ) + nPage = ( nPgNum - 1 ) / 2; + return nPage; +} + +static void ImplPDFExportComments( const uno::Reference< drawing::XDrawPage >& xPage, vcl::PDFExtOutDevData& rPDFExtOutDevData ) +{ + try + { + uno::Reference< office::XAnnotationAccess > xAnnotationAccess( xPage, uno::UNO_QUERY_THROW ); + uno::Reference< office::XAnnotationEnumeration > xAnnotationEnumeration( xAnnotationAccess->createAnnotationEnumeration() ); + + while( xAnnotationEnumeration->hasMoreElements() ) + { + uno::Reference< office::XAnnotation > xAnnotation( xAnnotationEnumeration->nextElement() ); + + geometry::RealPoint2D aRealPoint2D( xAnnotation->getPosition() ); + uno::Reference< text::XText > xText( xAnnotation->getTextRange() ); + + vcl::PDFNote aNote; + aNote.Title = xAnnotation->getAuthor(); + aNote.Contents = xText->getString(); + aNote.maModificationDate = xAnnotation->getDateTime(); + + rPDFExtOutDevData.CreateNote( ::tools::Rectangle( Point( static_cast< ::tools::Long >( aRealPoint2D.X * 100 ), + static_cast< ::tools::Long >( aRealPoint2D.Y * 100 ) ), Size( 1000, 1000 ) ), aNote ); + } + } + catch (const uno::Exception&) + { + } +} + +static void ImplPDFExportShapeInteraction( const uno::Reference< drawing::XShape >& xShape, SdDrawDocument& rDoc, vcl::PDFExtOutDevData& rPDFExtOutDevData ) +{ + if ( xShape->getShapeType() == "com.sun.star.drawing.GroupShape" ) + { + uno::Reference< container::XIndexAccess > xIndexAccess( xShape, uno::UNO_QUERY ); + if ( xIndexAccess.is() ) + { + sal_Int32 i, nCount = xIndexAccess->getCount(); + for ( i = 0; i < nCount; i++ ) + { + uno::Reference< drawing::XShape > xSubShape( xIndexAccess->getByIndex( i ), uno::UNO_QUERY ); + if ( xSubShape.is() ) + ImplPDFExportShapeInteraction( xSubShape, rDoc, rPDFExtOutDevData ); + } + } + } + else + { + uno::Reference< beans::XPropertySet > xShapePropSet( xShape, uno::UNO_QUERY ); + if( xShapePropSet.is() ) + { + Size aPageSize( rDoc.GetSdPage( 0, PageKind::Standard )->GetSize() ); + Point aPoint( 0, 0 ); + ::tools::Rectangle aPageRect( aPoint, aPageSize ); + + awt::Point aShapePos( xShape->getPosition() ); + awt::Size aShapeSize( xShape->getSize() ); + ::tools::Rectangle aLinkRect( Point( aShapePos.X, aShapePos.Y ), Size( aShapeSize.Width, aShapeSize.Height ) ); + + // Handle linked videos. + if (xShape->getShapeType() == "com.sun.star.drawing.MediaShape" || xShape->getShapeType() == "com.sun.star.presentation.MediaShape") + { + OUString aMediaURL; + xShapePropSet->getPropertyValue("MediaURL") >>= aMediaURL; + if (!aMediaURL.isEmpty()) + { + sal_Int32 nScreenId = rPDFExtOutDevData.CreateScreen(aLinkRect, rPDFExtOutDevData.GetCurrentPageNumber()); + if (aMediaURL.startsWith("vnd.sun.star.Package:")) + { + OUString aTempFileURL; + xShapePropSet->getPropertyValue("PrivateTempFileURL") >>= aTempFileURL; + rPDFExtOutDevData.SetScreenStream(nScreenId, aTempFileURL); + } + else + rPDFExtOutDevData.SetScreenURL(nScreenId, aMediaURL); + } + } + + presentation::ClickAction eCa; + uno::Any aAny( xShapePropSet->getPropertyValue( "OnClick" ) ); + if ( aAny >>= eCa ) + { + OUString const actionName(SdResId(SdTPAction::GetClickActionSdResId(eCa))); + switch ( eCa ) + { + case presentation::ClickAction_LASTPAGE : + { + sal_Int32 nCount = rDoc.GetSdPageCount( PageKind::Standard ); + sal_Int32 nDestId = rPDFExtOutDevData.CreateDest( aPageRect, nCount - 1, vcl::PDFWriter::DestAreaType::FitRectangle ); + sal_Int32 nLinkId = rPDFExtOutDevData.CreateLink(aLinkRect, actionName); + rPDFExtOutDevData.SetLinkDest( nLinkId, nDestId ); + } + break; + case presentation::ClickAction_FIRSTPAGE : + { + sal_Int32 nDestId = rPDFExtOutDevData.CreateDest( aPageRect, 0, vcl::PDFWriter::DestAreaType::FitRectangle ); + sal_Int32 nLinkId = rPDFExtOutDevData.CreateLink(aLinkRect, actionName); + rPDFExtOutDevData.SetLinkDest( nLinkId, nDestId ); + } + break; + case presentation::ClickAction_PREVPAGE : + { + sal_Int32 nDestPage = rPDFExtOutDevData.GetCurrentPageNumber(); + if ( nDestPage ) + nDestPage--; + sal_Int32 nDestId = rPDFExtOutDevData.CreateDest( aPageRect, nDestPage, vcl::PDFWriter::DestAreaType::FitRectangle ); + sal_Int32 nLinkId = rPDFExtOutDevData.CreateLink(aLinkRect, actionName); + rPDFExtOutDevData.SetLinkDest( nLinkId, nDestId ); + } + break; + case presentation::ClickAction_NEXTPAGE : + { + sal_Int32 nDestPage = rPDFExtOutDevData.GetCurrentPageNumber() + 1; + sal_Int32 nLastPage = rDoc.GetSdPageCount( PageKind::Standard ) - 1; + if ( nDestPage > nLastPage ) + nDestPage = nLastPage; + sal_Int32 nDestId = rPDFExtOutDevData.CreateDest( aPageRect, nDestPage, vcl::PDFWriter::DestAreaType::FitRectangle ); + sal_Int32 nLinkId = rPDFExtOutDevData.CreateLink(aLinkRect, actionName); + rPDFExtOutDevData.SetLinkDest( nLinkId, nDestId ); + } + break; + + case presentation::ClickAction_PROGRAM : + case presentation::ClickAction_BOOKMARK : + case presentation::ClickAction_DOCUMENT : + { + OUString aBookmark; + xShapePropSet->getPropertyValue( "Bookmark" ) >>= aBookmark; + if( !aBookmark.isEmpty() ) + { + switch( eCa ) + { + case presentation::ClickAction_DOCUMENT : + case presentation::ClickAction_PROGRAM : + { + sal_Int32 nLinkId = rPDFExtOutDevData.CreateLink(aLinkRect, actionName); + rPDFExtOutDevData.SetLinkURL( nLinkId, aBookmark ); + } + break; + case presentation::ClickAction_BOOKMARK : + { + sal_Int32 nPage = ImplPDFGetBookmarkPage( aBookmark, rDoc ); + if ( nPage != -1 ) + { + sal_Int32 nDestId = rPDFExtOutDevData.CreateDest( aPageRect, nPage, vcl::PDFWriter::DestAreaType::FitRectangle ); + sal_Int32 nLinkId = rPDFExtOutDevData.CreateLink(aLinkRect, actionName); + rPDFExtOutDevData.SetLinkDest( nLinkId, nDestId ); + } + } + break; + default: + break; + } + } + } + break; + + case presentation::ClickAction_STOPPRESENTATION : + case presentation::ClickAction_SOUND : + case presentation::ClickAction_INVISIBLE : + case presentation::ClickAction_VERB : + case presentation::ClickAction_VANISH : + case presentation::ClickAction_MACRO : + default : + break; + } + } + } + } +} + +void ImplRenderPaintProc::createRedirectedPrimitive2DSequence( + const sdr::contact::ViewObjectContact& rOriginal, + const sdr::contact::DisplayInfo& rDisplayInfo, + drawinglayer::primitive2d::Primitive2DDecompositionVisitor& rVisitor) +{ + SdrObject* pObject = rOriginal.GetViewContact().TryToGetSdrObject(); + if(!pObject) + { + // not an object, maybe a page + sdr::contact::ViewObjectContactRedirector::createRedirectedPrimitive2DSequence(rOriginal, rDisplayInfo, rVisitor); + return; + } + SdrPage* pSdrPage(pObject->getSdrPageFromSdrObject()); + if(!pSdrPage) + return; + if(!pSdrPage->checkVisibility(rOriginal, rDisplayInfo, false)) + return; + if(!IsVisible(pObject) || !IsPrintable(pObject)) + return; + + sdr::contact::ViewObjectContactRedirector::createRedirectedPrimitive2DSequence(rOriginal, rDisplayInfo, rVisitor); +} + +bool ImplRenderPaintProc::IsVisible( const SdrObject* pObj ) const +{ + bool bVisible = true; + SdrLayerID nLayerId = pObj->GetLayer(); + if( pSdrPageView ) + { + const SdrLayer* pSdrLayer = rLayerAdmin.GetLayerPerID( nLayerId ); + if ( pSdrLayer ) + { + const OUString& aLayerName = pSdrLayer->GetName(); + bVisible = pSdrPageView->IsLayerVisible( aLayerName ); + } + } + return bVisible; +} +bool ImplRenderPaintProc::IsPrintable( const SdrObject* pObj ) const +{ + bool bPrintable = true; + SdrLayerID nLayerId = pObj->GetLayer(); + if( pSdrPageView ) + { + const SdrLayer* pSdrLayer = rLayerAdmin.GetLayerPerID( nLayerId ); + if ( pSdrLayer ) + { + const OUString& aLayerName = pSdrLayer->GetName(); + bPrintable = pSdrPageView->IsLayerPrintable( aLayerName ); + } + } + return bPrintable; + +} + +namespace +{ + sal_Int16 CalcOutputPageNum(vcl::PDFExtOutDevData const * pPDFExtOutDevData, SdDrawDocument const *pDoc, sal_Int16 nPageNumber) + { + //export all pages, simple one to one case + if (pPDFExtOutDevData && pPDFExtOutDevData->GetIsExportHiddenSlides()) + return nPageNumber-1; + //check all preceding pages, and only count non-hidden ones + sal_Int16 nRet = 0; + for (sal_Int16 i = 0; i < nPageNumber-1; ++i) + { + if (!pDoc->GetSdPage(i, PageKind::Standard)->IsExcluded()) + ++nRet; + } + return nRet; + } +} + +void SAL_CALL SdXImpressDocument::render( sal_Int32 nRenderer, const uno::Any& rSelection, + const uno::Sequence< beans::PropertyValue >& rxOptions ) +{ + ::SolarMutexGuard aGuard; + + if( nullptr == mpDoc ) + throw lang::DisposedException(); + + if (!mpDocShell) + return; + + uno::Reference< awt::XDevice > xRenderDevice; + const sal_Int32 nPageNumber = nRenderer + 1; + PageKind ePageKind = PageKind::Standard; + bool bExportNotesPages = false; + + for( const auto& rOption : rxOptions ) + { + if ( rOption.Name == "RenderDevice" ) + rOption.Value >>= xRenderDevice; + else if ( rOption.Name == "ExportNotesPages" ) + { + rOption.Value >>= bExportNotesPages; + if ( bExportNotesPages ) + ePageKind = PageKind::Notes; + } + } + + if( !(xRenderDevice.is() && nPageNumber && ( nPageNumber <= mpDoc->GetSdPageCount( ePageKind ) )) ) + return; + + VCLXDevice* pDevice = comphelper::getFromUnoTunnel<VCLXDevice>( xRenderDevice ); + VclPtr< OutputDevice> pOut = pDevice ? pDevice->GetOutputDevice() : VclPtr< OutputDevice >(); + + if( !pOut ) + return; + + vcl::PDFExtOutDevData* pPDFExtOutDevData = dynamic_cast<vcl::PDFExtOutDevData* >( pOut->GetExtOutDevData() ); + + if ( mpDoc->GetSdPage(static_cast<sal_Int16>(nPageNumber)-1, PageKind::Standard)->IsExcluded() && + !(pPDFExtOutDevData && pPDFExtOutDevData->GetIsExportHiddenSlides()) ) + return; + + if (pPDFExtOutDevData) + { + css::lang::Locale const docLocale(Application::GetSettings().GetLanguageTag().getLocale()); + pPDFExtOutDevData->SetDocumentLocale(docLocale); + } + + ::sd::ClientView aView( mpDocShell, pOut ); + ::tools::Rectangle aVisArea( Point(), mpDoc->GetSdPage( static_cast<sal_uInt16>(nPageNumber) - 1, ePageKind )->GetSize() ); + vcl::Region aRegion( aVisArea ); + + ::sd::ViewShell* pOldViewSh = mpDocShell->GetViewShell(); + ::sd::View* pOldSdView = pOldViewSh ? pOldViewSh->GetView() : nullptr; + + if ( pOldSdView ) + pOldSdView->SdrEndTextEdit(); + + aView.SetHlplVisible( false ); + aView.SetGridVisible( false ); + aView.SetBordVisible( false ); + aView.SetPageVisible( false ); + aView.SetGlueVisible( false ); + + pOut->SetMapMode(MapMode(MapUnit::Map100thMM)); + pOut->IntersectClipRegion( aVisArea ); + + uno::Reference< frame::XModel > xModel; + rSelection >>= xModel; + + if( xModel == mpDocShell->GetModel() ) + { + aView.ShowSdrPage( mpDoc->GetSdPage( static_cast<sal_uInt16>(nPageNumber) - 1, ePageKind )); + SdrPageView* pPV = aView.GetSdrPageView(); + + if( pOldSdView ) + { + SdrPageView* pOldPV = pOldSdView->GetSdrPageView(); + if( pPV && pOldPV ) + { + pPV->SetVisibleLayers( pOldPV->GetVisibleLayers() ); + pPV->SetPrintableLayers( pOldPV->GetPrintableLayers() ); + } + } + + ImplRenderPaintProc aImplRenderPaintProc( mpDoc->GetLayerAdmin(), + pPV); + + // background color for outliner :o + SdPage* pPage = pPV ? static_cast<SdPage*>(pPV->GetPage()) : nullptr; + if( pPage ) + { + SdrOutliner& rOutl = mpDoc->GetDrawOutliner(); + bool bScreenDisplay(true); + + // #i75566# printing; suppress AutoColor BackgroundColor generation + // for visibility reasons by giving GetPageBackgroundColor() + // the needed hint + // #i75566# PDF export; suppress AutoColor BackgroundColor generation (see printing) + if (pOut && ((OUTDEV_PRINTER == pOut->GetOutDevType()) + || (OUTDEV_PDF == pOut->GetOutDevType()))) + bScreenDisplay = false; + + // #i75566# Name change GetBackgroundColor -> GetPageBackgroundColor and + // hint value if screen display. Only then the AutoColor mechanisms shall be applied + rOutl.SetBackgroundColor( pPage->GetPageBackgroundColor( pPV, bScreenDisplay ) ); + } + aView.SdrPaintView::CompleteRedraw( pOut, aRegion, &aImplRenderPaintProc ); + + if ( pPDFExtOutDevData && pPage ) + { + try + { + uno::Any aAny; + uno::Reference< drawing::XDrawPage > xPage( uno::Reference< drawing::XDrawPage >::query( pPage->getUnoPage() ) ); + if ( xPage.is() ) + { + if ( pPDFExtOutDevData->GetIsExportNotes() ) + ImplPDFExportComments( xPage, *pPDFExtOutDevData ); + uno::Reference< beans::XPropertySet > xPagePropSet( xPage, uno::UNO_QUERY ); + if( xPagePropSet.is() ) + { + // exporting object interactions to pdf + + // if necessary, the master page interactions will be exported first + bool bIsBackgroundObjectsVisible = false; // #i39428# IsBackgroundObjectsVisible not available for Draw + if ( mbImpressDoc && xPagePropSet->getPropertySetInfo()->hasPropertyByName( "IsBackgroundObjectsVisible" ) ) + xPagePropSet->getPropertyValue( "IsBackgroundObjectsVisible" ) >>= bIsBackgroundObjectsVisible; + if ( bIsBackgroundObjectsVisible && !pPDFExtOutDevData->GetIsExportNotesPages() ) + { + uno::Reference< drawing::XMasterPageTarget > xMasterPageTarget( xPage, uno::UNO_QUERY ); + if ( xMasterPageTarget.is() ) + { + uno::Reference< drawing::XDrawPage > xMasterPage = xMasterPageTarget->getMasterPage(); + if ( xMasterPage.is() ) + { + sal_Int32 i, nCount = xMasterPage->getCount(); + for ( i = 0; i < nCount; i++ ) + { + aAny = xMasterPage->getByIndex( i ); + uno::Reference< drawing::XShape > xShape; + if ( aAny >>= xShape ) + ImplPDFExportShapeInteraction( xShape, *mpDoc, *pPDFExtOutDevData ); + } + } + } + } + + // exporting slide page object interactions + sal_Int32 i, nCount = xPage->getCount(); + for ( i = 0; i < nCount; i++ ) + { + aAny = xPage->getByIndex( i ); + uno::Reference< drawing::XShape > xShape; + if ( aAny >>= xShape ) + ImplPDFExportShapeInteraction( xShape, *mpDoc, *pPDFExtOutDevData ); + } + + // exporting transition effects to pdf + if ( mbImpressDoc && !pPDFExtOutDevData->GetIsExportNotesPages() && pPDFExtOutDevData->GetIsExportTransitionEffects() ) + { + static const OUStringLiteral sEffect( u"Effect" ); + static const OUStringLiteral sSpeed ( u"Speed" ); + sal_Int32 nTime = 800; + presentation::AnimationSpeed aAs; + if ( xPagePropSet->getPropertySetInfo( )->hasPropertyByName( sSpeed ) ) + { + aAny = xPagePropSet->getPropertyValue( sSpeed ); + if ( aAny >>= aAs ) + { + switch( aAs ) + { + case presentation::AnimationSpeed_SLOW : nTime = 1500; break; + case presentation::AnimationSpeed_FAST : nTime = 300; break; + default: + case presentation::AnimationSpeed_MEDIUM : nTime = 800; + } + } + } + presentation::FadeEffect eFe; + vcl::PDFWriter::PageTransition eType = vcl::PDFWriter::PageTransition::Regular; + if ( xPagePropSet->getPropertySetInfo( )->hasPropertyByName( sEffect ) ) + { + aAny = xPagePropSet->getPropertyValue( sEffect ); + if ( aAny >>= eFe ) + { + switch( eFe ) + { + case presentation::FadeEffect_HORIZONTAL_LINES : + case presentation::FadeEffect_HORIZONTAL_CHECKERBOARD : + case presentation::FadeEffect_HORIZONTAL_STRIPES : eType = vcl::PDFWriter::PageTransition::BlindsHorizontal; break; + + case presentation::FadeEffect_VERTICAL_LINES : + case presentation::FadeEffect_VERTICAL_CHECKERBOARD : + case presentation::FadeEffect_VERTICAL_STRIPES : eType = vcl::PDFWriter::PageTransition::BlindsVertical; break; + + case presentation::FadeEffect_UNCOVER_TO_RIGHT : + case presentation::FadeEffect_UNCOVER_TO_UPPERRIGHT : + case presentation::FadeEffect_ROLL_FROM_LEFT : + case presentation::FadeEffect_FADE_FROM_UPPERLEFT : + case presentation::FadeEffect_MOVE_FROM_UPPERLEFT : + case presentation::FadeEffect_FADE_FROM_LEFT : + case presentation::FadeEffect_MOVE_FROM_LEFT : eType = vcl::PDFWriter::PageTransition::WipeLeftToRight; break; + + case presentation::FadeEffect_UNCOVER_TO_BOTTOM : + case presentation::FadeEffect_UNCOVER_TO_LOWERRIGHT : + case presentation::FadeEffect_ROLL_FROM_TOP : + case presentation::FadeEffect_FADE_FROM_UPPERRIGHT : + case presentation::FadeEffect_MOVE_FROM_UPPERRIGHT : + case presentation::FadeEffect_FADE_FROM_TOP : + case presentation::FadeEffect_MOVE_FROM_TOP : eType = vcl::PDFWriter::PageTransition::WipeTopToBottom; break; + + case presentation::FadeEffect_UNCOVER_TO_LEFT : + case presentation::FadeEffect_UNCOVER_TO_LOWERLEFT : + case presentation::FadeEffect_ROLL_FROM_RIGHT : + + case presentation::FadeEffect_FADE_FROM_LOWERRIGHT : + case presentation::FadeEffect_MOVE_FROM_LOWERRIGHT : + case presentation::FadeEffect_FADE_FROM_RIGHT : + case presentation::FadeEffect_MOVE_FROM_RIGHT : eType = vcl::PDFWriter::PageTransition::WipeRightToLeft; break; + + case presentation::FadeEffect_UNCOVER_TO_TOP : + case presentation::FadeEffect_UNCOVER_TO_UPPERLEFT : + case presentation::FadeEffect_ROLL_FROM_BOTTOM : + case presentation::FadeEffect_FADE_FROM_LOWERLEFT : + case presentation::FadeEffect_MOVE_FROM_LOWERLEFT : + case presentation::FadeEffect_FADE_FROM_BOTTOM : + case presentation::FadeEffect_MOVE_FROM_BOTTOM : eType = vcl::PDFWriter::PageTransition::WipeBottomToTop; break; + + case presentation::FadeEffect_OPEN_VERTICAL : eType = vcl::PDFWriter::PageTransition::SplitHorizontalInward; break; + case presentation::FadeEffect_CLOSE_HORIZONTAL : eType = vcl::PDFWriter::PageTransition::SplitHorizontalOutward; break; + + case presentation::FadeEffect_OPEN_HORIZONTAL : eType = vcl::PDFWriter::PageTransition::SplitVerticalInward; break; + case presentation::FadeEffect_CLOSE_VERTICAL : eType = vcl::PDFWriter::PageTransition::SplitVerticalOutward; break; + + case presentation::FadeEffect_FADE_TO_CENTER : eType = vcl::PDFWriter::PageTransition::BoxInward; break; + case presentation::FadeEffect_FADE_FROM_CENTER : eType = vcl::PDFWriter::PageTransition::BoxOutward; break; + + case presentation::FadeEffect_NONE : eType = vcl::PDFWriter::PageTransition::Regular; break; + + case presentation::FadeEffect_RANDOM : + case presentation::FadeEffect_DISSOLVE : + default: eType = vcl::PDFWriter::PageTransition::Dissolve; break; + } + } + } + + if ( xPagePropSet->getPropertySetInfo( )->hasPropertyByName( sEffect ) || + xPagePropSet->getPropertySetInfo( )->hasPropertyByName( sSpeed ) ) + { + pPDFExtOutDevData->SetPageTransition( eType, nTime ); + } + } + } + } + + Size aPageSize( mpDoc->GetSdPage( 0, PageKind::Standard )->GetSize() ); + Point aPoint( 0, 0 ); + ::tools::Rectangle aPageRect( aPoint, aPageSize ); + + // resolving links found in this page by the method ImpEditEngine::Paint + std::vector< vcl::PDFExtOutDevBookmarkEntry >& rBookmarks = pPDFExtOutDevData->GetBookmarks(); + for ( const auto& rBookmark : rBookmarks ) + { + sal_Int32 nPage = ImplPDFGetBookmarkPage( rBookmark.aBookmark, *mpDoc ); + if ( nPage != -1 ) + { + if ( rBookmark.nLinkId != -1 ) + pPDFExtOutDevData->SetLinkDest( rBookmark.nLinkId, pPDFExtOutDevData->CreateDest( aPageRect, nPage, vcl::PDFWriter::DestAreaType::FitRectangle ) ); + else + pPDFExtOutDevData->DescribeRegisteredDest( rBookmark.nDestId, aPageRect, nPage, vcl::PDFWriter::DestAreaType::FitRectangle ); + } + else + pPDFExtOutDevData->SetLinkURL( rBookmark.nLinkId, rBookmark.aBookmark ); + } + rBookmarks.clear(); + //---> #i56629, #i40318 + //get the page name, will be used as outline element in PDF bookmark pane + OUString aPageName = mpDoc->GetSdPage( static_cast<sal_uInt16>(nPageNumber) - 1 , PageKind::Standard )->GetName(); + if( !aPageName.isEmpty() ) + { + // Destination PageNum + const sal_Int32 nDestPageNum = CalcOutputPageNum(pPDFExtOutDevData, mpDoc, nPageNumber); + + // insert the bookmark to this page into the NamedDestinations + if( pPDFExtOutDevData->GetIsExportNamedDestinations() ) + pPDFExtOutDevData->CreateNamedDest(aPageName, aPageRect, nDestPageNum); + + // add the name to the outline, (almost) same code as in sc/source/ui/unoobj/docuno.cxx + // issue #i40318. + + if( pPDFExtOutDevData->GetIsExportBookmarks() ) + { + // Destination Export + const sal_Int32 nDestId = + pPDFExtOutDevData->CreateDest(aPageRect , nDestPageNum); + + // Create a new outline item: + pPDFExtOutDevData->CreateOutlineItem( -1 , aPageName, nDestId ); + } + } + //<--- #i56629, #i40318 + } + catch (const uno::Exception&) + { + } + + } + } + else + { + uno::Reference< drawing::XShapes > xShapes; + rSelection >>= xShapes; + + if( xShapes.is() && xShapes->getCount() ) + { + SdrPageView* pPV = nullptr; + + ImplRenderPaintProc aImplRenderPaintProc( mpDoc->GetLayerAdmin(), + pOldSdView ? pOldSdView->GetSdrPageView() : nullptr); + + for( sal_uInt32 i = 0, nCount = xShapes->getCount(); i < nCount; i++ ) + { + uno::Reference< drawing::XShape > xShape; + xShapes->getByIndex( i ) >>= xShape; + + if( xShape.is() ) + { + SdrObject* pObj = SdrObject::getSdrObjectFromXShape( xShape ); + if( pObj && pObj->getSdrPageFromSdrObject() + && aImplRenderPaintProc.IsVisible( pObj ) + && aImplRenderPaintProc.IsPrintable( pObj ) ) + { + if( !pPV ) + pPV = aView.ShowSdrPage( pObj->getSdrPageFromSdrObject() ); + + if( pPV ) + aView.MarkObj( pObj, pPV ); + } + } + } + aView.DrawMarkedObj(*pOut); + } + } +} + +DrawViewShell* SdXImpressDocument::GetViewShell() +{ + DrawViewShell* pViewSh = dynamic_cast<DrawViewShell*>(mpDocShell->GetViewShell()); + if (!pViewSh) + { + SAL_WARN("sd", "DrawViewShell not available!"); + return nullptr; + } + return pViewSh; +} + +void SdXImpressDocument::paintTile( VirtualDevice& rDevice, + int nOutputWidth, int nOutputHeight, + int nTilePosX, int nTilePosY, + ::tools::Long nTileWidth, ::tools::Long nTileHeight ) +{ + DrawViewShell* pViewSh = GetViewShell(); + if (!pViewSh) + return; + + // Setup drawing layer to work properly. Since we use a custom VirtualDevice + // for the drawing, SdrPaintView::BeginCompleteRedraw() will call FindPaintWindow() + // unsuccessfully and use a temporary window that doesn't keep state. So patch + // the existing SdrPageWindow to use a temporary, and this way the state will be kept. + // Well, at least that's how I understand it based on Writer's RenderContextGuard, + // as the drawing layer classes lack documentation. + SdrPageWindow* patchedPageWindow = nullptr; + SdrPaintWindow* previousPaintWindow = nullptr; + std::unique_ptr<SdrPaintWindow> temporaryPaintWindow; + if(SdrView* pDrawView = pViewSh->GetDrawView()) + { + if(SdrPageView* pSdrPageView = pDrawView->GetSdrPageView()) + { + patchedPageWindow = pSdrPageView->FindPageWindow(*getDocWindow()->GetOutDev()); + temporaryPaintWindow.reset(new SdrPaintWindow(*pDrawView, rDevice)); + if (patchedPageWindow) + previousPaintWindow = patchedPageWindow->patchPaintWindow(*temporaryPaintWindow); + } + } + + // Scaling. Must convert from pixels to twips. We know + // that VirtualDevices use a DPI of 96. + // We specifically calculate these scales first as we're still + // in TWIPs, and might as well minimize the number of conversions. + const Fraction scale = conversionFract(o3tl::Length::px, o3tl::Length::twip); + Fraction scaleX = Fraction(nOutputWidth, nTileWidth) * scale; + Fraction scaleY = Fraction(nOutputHeight, nTileHeight) * scale; + + // svx seems to be the only component that works natively in + // 100th mm rather than TWIP. It makes most sense just to + // convert here and in getDocumentSize, and leave the tiled + // rendering API working in TWIPs. + ::tools::Long nTileWidthHMM = convertTwipToMm100( nTileWidth ); + ::tools::Long nTileHeightHMM = convertTwipToMm100( nTileHeight ); + int nTilePosXHMM = convertTwipToMm100( nTilePosX ); + int nTilePosYHMM = convertTwipToMm100( nTilePosY ); + + MapMode aMapMode = rDevice.GetMapMode(); + aMapMode.SetMapUnit( MapUnit::Map100thMM ); + aMapMode.SetOrigin( Point( -nTilePosXHMM, + -nTilePosYHMM) ); + aMapMode.SetScaleX( scaleX ); + aMapMode.SetScaleY( scaleY ); + + rDevice.SetMapMode( aMapMode ); + + rDevice.SetOutputSizePixel( Size(nOutputWidth, nOutputHeight) ); + + Point aPoint(nTilePosXHMM, nTilePosYHMM); + Size aSize(nTileWidthHMM, nTileHeightHMM); + ::tools::Rectangle aRect(aPoint, aSize); + + pViewSh->GetView()->CompleteRedraw(&rDevice, vcl::Region(aRect)); + + LokChartHelper::PaintAllChartsOnTile(rDevice, nOutputWidth, nOutputHeight, + nTilePosX, nTilePosY, nTileWidth, nTileHeight); + + if(patchedPageWindow != nullptr) + patchedPageWindow->unpatchPaintWindow(previousPaintWindow); +} + +void SdXImpressDocument::selectPart(int nPart, int nSelect) +{ + DrawViewShell* pViewSh = GetViewShell(); + if (!pViewSh) + return; + + pViewSh->SelectPage(nPart, nSelect); +} + +void SdXImpressDocument::moveSelectedParts(int nPosition, bool bDuplicate) +{ + // Duplicating is currently unsupported. + if (!bDuplicate) + mpDoc->MovePages(nPosition); +} + +OUString SdXImpressDocument::getPartInfo(int nPart) +{ + DrawViewShell* pViewSh = GetViewShell(); + if (!pViewSh) + return OUString(); + + const bool bIsVisible = pViewSh->IsVisible(nPart); + const bool bIsSelected = pViewSh->IsSelected(nPart); + const sal_Int16 nMasterPageCount= pViewSh->GetDoc()->GetMasterSdPageCount(pViewSh->GetPageKind()); + + OUString aPartInfo = "{ \"visible\": \"" + + OUString::number(static_cast<unsigned int>(bIsVisible)) + + "\", \"selected\": \"" + + OUString::number(static_cast<unsigned int>(bIsSelected)) + + "\", \"masterPageCount\": \"" + + OUString::number(nMasterPageCount) + + "\" }"; + return aPartInfo; +} + +void SdXImpressDocument::setPart( int nPart, bool bAllowChangeFocus ) +{ + DrawViewShell* pViewSh = GetViewShell(); + if (!pViewSh) + return; + + pViewSh->SwitchPage( nPart, bAllowChangeFocus ); +} + +int SdXImpressDocument::getParts() +{ + if (!mpDoc) + return 0; + + if (isMasterViewMode()) + return mpDoc->GetMasterSdPageCount(PageKind::Standard); + + return mpDoc->GetSdPageCount(PageKind::Standard); +} + +int SdXImpressDocument::getPart() +{ + DrawViewShell* pViewSh = GetViewShell(); + if (!pViewSh) + return 0; + + return pViewSh->GetViewShellBase().getPart(); +} + +OUString SdXImpressDocument::getPartName(int nPart) +{ + SdPage* pPage; + if (isMasterViewMode()) + pPage = mpDoc->GetMasterSdPage(nPart, PageKind::Standard); + else + pPage = mpDoc->GetSdPage(nPart, PageKind::Standard); + + if (!pPage) + { + SAL_WARN("sd", "DrawViewShell not available!"); + return OUString(); + } + + return pPage->GetName(); +} + +OUString SdXImpressDocument::getPartHash(int nPart) +{ + SdPage* pPage; + if (isMasterViewMode()) + pPage = mpDoc->GetMasterSdPage(nPart, PageKind::Standard); + else + pPage = mpDoc->GetSdPage(nPart, PageKind::Standard); + + if (!pPage) + { + SAL_WARN("sd", "DrawViewShell not available!"); + return OUString(); + } + + return OUString::number(pPage->GetHashCode()); +} + +bool SdXImpressDocument::isMasterViewMode() +{ + DrawViewShell* pViewSh = GetViewShell(); + if (!pViewSh) + return false; + + if (pViewSh->GetDispatcher()) + { + const SfxBoolItem* isMasterViewMode = nullptr; + pViewSh->GetDispatcher()->QueryState(SID_SLIDE_MASTER_MODE, isMasterViewMode); + if (isMasterViewMode && isMasterViewMode->GetValue()) + return true; + } + return false; +} + +VclPtr<vcl::Window> SdXImpressDocument::getDocWindow() +{ + SolarMutexGuard aGuard; + DrawViewShell* pViewShell = GetViewShell(); + VclPtr<vcl::Window> pWindow; + if (pViewShell) + pWindow = pViewShell->GetActiveWindow(); + + LokChartHelper aChartHelper(pViewShell->GetViewShell()); + VclPtr<vcl::Window> pChartWindow = aChartHelper.GetWindow(); + if (pChartWindow) + pWindow = pChartWindow; + + return pWindow; +} + +void SdXImpressDocument::setPartMode( int nPartMode ) +{ + DrawViewShell* pViewSh = GetViewShell(); + if (!pViewSh) + return; + + PageKind aPageKind( PageKind::Standard ); + switch ( nPartMode ) + { + case LOK_PARTMODE_SLIDES: + break; + case LOK_PARTMODE_NOTES: + aPageKind = PageKind::Notes; + break; + } + pViewSh->SetPageKind( aPageKind ); +} + +Size SdXImpressDocument::getDocumentSize() +{ + DrawViewShell* pViewSh = GetViewShell(); + if (!pViewSh) + return Size(); + + SdrView *pSdrView = pViewSh->GetView(); + if (!pSdrView) + return Size(); + + SdrPageView* pCurPageView = pSdrView->GetSdrPageView(); + if (!pCurPageView) + return Size(); + + Size aSize = pCurPageView->GetPageRect().GetSize(); + // Convert the size in 100th mm to TWIP + // See paintTile above for further info. + return o3tl::convert(aSize, o3tl::Length::mm100, o3tl::Length::twip); +} + +void SdXImpressDocument::getPostIts(::tools::JsonWriter& rJsonWriter) +{ + auto commentsNode = rJsonWriter.startNode("comments"); + // Return annotations on master pages too ? + const sal_uInt16 nMaxPages = mpDoc->GetPageCount(); + SdPage* pPage; + for (sal_uInt16 nPage = 0; nPage < nMaxPages; ++nPage) + { + pPage = static_cast<SdPage*>(mpDoc->GetPage(nPage)); + const sd::AnnotationVector& aPageAnnotations = pPage->getAnnotations(); + + for (const uno::Reference<office::XAnnotation>& xAnnotation : aPageAnnotations) + { + sal_uInt32 nID = sd::getAnnotationId(xAnnotation); + OString nodeName = "comment" + OString::number(nID); + auto commentNode = rJsonWriter.startNode(nodeName.getStr()); + rJsonWriter.put("id", nID); + rJsonWriter.put("author", xAnnotation->getAuthor()); + rJsonWriter.put("dateTime", utl::toISO8601(xAnnotation->getDateTime())); + uno::Reference<text::XText> xText(xAnnotation->getTextRange()); + rJsonWriter.put("text", xText->getString()); + rJsonWriter.put("parthash", pPage->GetHashCode()); + geometry::RealPoint2D const & rPoint = xAnnotation->getPosition(); + geometry::RealSize2D const & rSize = xAnnotation->getSize(); + ::tools::Rectangle aRectangle(Point(rPoint.X * 100.0, rPoint.Y * 100.0), Size(rSize.Width * 100.0, rSize.Height * 100.0)); + aRectangle = o3tl::toTwips(aRectangle, o3tl::Length::mm100); + OString sRectangle = aRectangle.toString(); + rJsonWriter.put("rectangle", sRectangle.getStr()); + } + } +} + +void SdXImpressDocument::initializeForTiledRendering(const css::uno::Sequence<css::beans::PropertyValue>& rArguments) +{ + SolarMutexGuard aGuard; + + if (DrawViewShell* pViewShell = GetViewShell()) + { + DrawView* pDrawView = pViewShell->GetDrawView(); + for (const beans::PropertyValue& rValue : rArguments) + { + if (rValue.Name == ".uno:ShowBorderShadow" && rValue.Value.has<bool>()) + pDrawView->SetPageShadowVisible(rValue.Value.get<bool>()); + else if (rValue.Name == ".uno:Author" && rValue.Value.has<OUString>()) + pDrawView->SetAuthor(rValue.Value.get<OUString>()); + else if (rValue.Name == ".uno:SpellOnline" && rValue.Value.has<bool>()) + mpDoc->SetOnlineSpell(rValue.Value.get<bool>()); + } + + // Disable comments if requested + SdOptions* pOptions = SD_MOD()->GetSdOptions(mpDoc->GetDocumentType()); + pOptions->SetShowComments(comphelper::LibreOfficeKit::isTiledAnnotations()); + + pViewShell->SetRuler(false); + pViewShell->SetScrollBarsVisible(false); + + if (sd::Window* pWindow = pViewShell->GetActiveWindow()) + { + // get the full page size in pixels + pWindow->EnableMapMode(); + Size aSize(pWindow->LogicToPixel(pDrawView->GetSdrPageView()->GetPage()->GetSize())); + // Disable map mode, so that it's possible to send mouse event + // coordinates in logic units + pWindow->EnableMapMode(false); + + // arrange UI elements again with new view size + pViewShell->GetParentWindow()->SetSizePixel(aSize); + pViewShell->Resize(); + } + + // Forces all images to be swapped in synchronously, this + // ensures that images are available when paintTile is called + // (whereas with async loading images start being loaded after + // we have painted the tile, resulting in an invalidate, followed + // by the tile being rerendered - which is wasteful and ugly). + pDrawView->SetSwapAsynchron(false); + } + + // when the "This document may contain formatting or content that cannot + // be saved..." dialog appears, it is auto-cancelled with tiled rendering, + // causing 'Save' being disabled; so let's always save to the original + // format + auto xChanges = comphelper::ConfigurationChanges::create(); + officecfg::Office::Common::Save::Document::WarnAlienFormat::set(false, xChanges); + xChanges->commit(); + + if (!getenv("LO_TESTNAME")) + SvtSlideSorterBarOptions().SetVisibleImpressView(true); +} + +void SdXImpressDocument::postKeyEvent(int nType, int nCharCode, int nKeyCode) +{ + SolarMutexGuard aGuard; + SfxLokHelper::postKeyEventAsync(getDocWindow(), nType, nCharCode, nKeyCode); +} + +void SdXImpressDocument::postMouseEvent(int nType, int nX, int nY, int nCount, int nButtons, int nModifier) +{ + SolarMutexGuard aGuard; + + DrawViewShell* pViewShell = GetViewShell(); + if (!pViewShell) + return; + + constexpr double fScale = o3tl::convert(1.0, o3tl::Length::twip, o3tl::Length::px); + + // check if user hit a chart which is being edited by him + LokChartHelper aChartHelper(pViewShell->GetViewShell()); + if (aChartHelper.postMouseEvent(nType, nX, nY, + nCount, nButtons, nModifier, + fScale, fScale)) + return; + + // check if the user hit a chart which is being edited by someone else + // and, if so, skip current mouse event + if (nType != LOK_MOUSEEVENT_MOUSEMOVE) + { + if (LokChartHelper::HitAny(Point(nX, nY))) + return; + } + + const Point aPos(Point(convertTwipToMm100(nX), convertTwipToMm100(nY))); + LokMouseEventData aMouseEventData(nType, aPos, nCount, MouseEventModifiers::SIMPLECLICK, + nButtons, nModifier); + SfxLokHelper::postMouseEventAsync(pViewShell->GetActiveWindow(), aMouseEventData); +} + +void SdXImpressDocument::setTextSelection(int nType, int nX, int nY) +{ + SolarMutexGuard aGuard; + + DrawViewShell* pViewShell = GetViewShell(); + if (!pViewShell) + return; + + LokChartHelper aChartHelper(pViewShell->GetViewShell()); + if (aChartHelper.setTextSelection(nType, nX, nY)) + return; + + Point aPoint(convertTwipToMm100(nX), convertTwipToMm100(nY)); + switch (nType) + { + case LOK_SETTEXTSELECTION_START: + pViewShell->SetCursorMm100Position(aPoint, /*bPoint=*/false, /*bClearMark=*/false); + break; + case LOK_SETTEXTSELECTION_END: + pViewShell->SetCursorMm100Position(aPoint, /*bPoint=*/true, /*bClearMark=*/false); + break; + case LOK_SETTEXTSELECTION_RESET: + pViewShell->SetCursorMm100Position(aPoint, /*bPoint=*/true, /*bClearMark=*/true); + break; + default: + assert(false); + break; + } +} + +uno::Reference<datatransfer::XTransferable> SdXImpressDocument::getSelection() +{ + SolarMutexGuard aGuard; + + DrawViewShell* pViewShell = GetViewShell(); + if (!pViewShell) + return uno::Reference<datatransfer::XTransferable>(); + + return pViewShell->GetSelectionTransferrable(); +} + +void SdXImpressDocument::setGraphicSelection(int nType, int nX, int nY) +{ + SolarMutexGuard aGuard; + + DrawViewShell* pViewShell = GetViewShell(); + if (!pViewShell) + return; + + constexpr double fScale = o3tl::convert(1.0, o3tl::Length::twip, o3tl::Length::px); + + LokChartHelper aChartHelper(pViewShell->GetViewShell()); + if (aChartHelper.setGraphicSelection(nType, nX, nY, fScale, fScale)) + return; + + Point aPoint(convertTwipToMm100(nX), convertTwipToMm100(nY)); + switch (nType) + { + case LOK_SETGRAPHICSELECTION_START: + pViewShell->SetGraphicMm100Position(/*bStart=*/true, aPoint); + break; + case LOK_SETGRAPHICSELECTION_END: + pViewShell->SetGraphicMm100Position(/*bStart=*/false, aPoint); + break; + default: + assert(false); + break; + } +} + +void SdXImpressDocument::resetSelection() +{ + SolarMutexGuard aGuard; + + DrawViewShell* pViewShell = GetViewShell(); + if (!pViewShell) + return; + + SdrView* pSdrView = pViewShell->GetView(); + if (!pSdrView) + return; + + if (pSdrView->IsTextEdit()) + { + // Reset the editeng selection. + pSdrView->UnmarkAll(); + // Finish editing. + pSdrView->SdrEndTextEdit(); + } + // Reset graphic selection. + pSdrView->UnmarkAll(); +} + +void SdXImpressDocument::setClientVisibleArea(const ::tools::Rectangle& rRectangle) +{ + SolarMutexGuard aGuard; + + DrawViewShell* pViewShell = GetViewShell(); + if (!pViewShell) + return; + + pViewShell->GetViewShellBase().setLOKVisibleArea(rRectangle); +} + +void SdXImpressDocument::setClipboard(const uno::Reference<datatransfer::clipboard::XClipboard>& xClipboard) +{ + SolarMutexGuard aGuard; + + DrawViewShell* pViewShell = GetViewShell(); + if (!pViewShell) + return; + + pViewShell->GetActiveWindow()->SetClipboard(xClipboard); +} + +bool SdXImpressDocument::isMimeTypeSupported() +{ + SolarMutexGuard aGuard; + DrawViewShell* pViewShell = GetViewShell(); + if (!pViewShell) + return false; + + TransferableDataHelper aDataHelper(TransferableDataHelper::CreateFromSystemClipboard(pViewShell->GetActiveWindow())); + return EditEngine::HasValidData(aDataHelper.GetTransferable()); +} + +PointerStyle SdXImpressDocument::getPointer() +{ + SolarMutexGuard aGuard; + DrawViewShell* pViewShell = GetViewShell(); + if (!pViewShell) + return PointerStyle::Arrow; + + Window* pWindow = pViewShell->GetActiveWindow(); + if (!pWindow) + return PointerStyle::Arrow; + + return pWindow->GetPointer(); +} + +uno::Reference< i18n::XForbiddenCharacters > SdXImpressDocument::getForbiddenCharsTable() +{ + uno::Reference< i18n::XForbiddenCharacters > xForb(mxForbiddenCharacters); + + if( !xForb.is() ) + mxForbiddenCharacters = xForb = new SdUnoForbiddenCharsTable( mpDoc ); + + return xForb; +} + +void SdXImpressDocument::initializeDocument() +{ + if( mbClipBoard ) + return; + + switch( mpDoc->GetPageCount() ) + { + case 1: + { + // nasty hack to detect clipboard document + mbClipBoard = true; + break; + } + case 0: + { + mpDoc->CreateFirstPages(); + mpDoc->StopWorkStartupDelay(); + break; + } + } +} + +SdrModel& SdXImpressDocument::getSdrModelFromUnoModel() const +{ + OSL_ENSURE(GetDoc(), "No SdrModel in draw/Impress, should not happen"); + return *GetDoc(); // TTTT should be reference +} + +void SAL_CALL SdXImpressDocument::dispose() +{ + if( mbDisposed ) + return; + + ::SolarMutexGuard aGuard; + + if( mpDoc ) + { + EndListening( *mpDoc ); + mpDoc = nullptr; + } + + // Call the base class dispose() before setting the mbDisposed flag + // to true. The reason for this is that if close() has not yet been + // called this is done in SfxBaseModel::dispose(). At the end of + // that dispose() is called again. It is important to forward this + // second dispose() to the base class, too. + // As a consequence the following code has to be able to be run twice. + SfxBaseModel::dispose(); + mbDisposed = true; + + uno::Reference< container::XNameAccess > xLinks( mxLinks ); + if( xLinks.is() ) + { + uno::Reference< lang::XComponent > xComp( xLinks, uno::UNO_QUERY ); + if( xComp.is() ) + xComp->dispose(); + + xLinks = nullptr; + } + + uno::Reference< drawing::XDrawPages > xDrawPagesAccess( mxDrawPagesAccess ); + if( xDrawPagesAccess.is() ) + { + uno::Reference< lang::XComponent > xComp( xDrawPagesAccess, uno::UNO_QUERY ); + if( xComp.is() ) + xComp->dispose(); + + xDrawPagesAccess = nullptr; + } + + uno::Reference< drawing::XDrawPages > xMasterPagesAccess( mxMasterPagesAccess ); + if( xDrawPagesAccess.is() ) + { + uno::Reference< lang::XComponent > xComp( xMasterPagesAccess, uno::UNO_QUERY ); + if( xComp.is() ) + xComp->dispose(); + + xDrawPagesAccess = nullptr; + } + + uno::Reference< container::XNameAccess > xLayerManager( mxLayerManager ); + if( xLayerManager.is() ) + { + uno::Reference< lang::XComponent > xComp( xLayerManager, uno::UNO_QUERY ); + if( xComp.is() ) + xComp->dispose(); + + xLayerManager = nullptr; + } + + uno::Reference< container::XNameContainer > xCustomPresentationAccess( mxCustomPresentationAccess ); + if( xCustomPresentationAccess.is() ) + { + uno::Reference< lang::XComponent > xComp( xCustomPresentationAccess, uno::UNO_QUERY ); + if( xComp.is() ) + xComp->dispose(); + + xCustomPresentationAccess = nullptr; + } + + mxDashTable = nullptr; + mxGradientTable = nullptr; + mxHatchTable = nullptr; + mxBitmapTable = nullptr; + mxTransGradientTable = nullptr; + mxMarkerTable = nullptr; + mxDrawingPool = nullptr; +} + + +SdDrawPagesAccess::SdDrawPagesAccess( SdXImpressDocument& rMyModel ) noexcept +: mpModel( &rMyModel) +{ +} + +SdDrawPagesAccess::~SdDrawPagesAccess() noexcept +{ +} + +// XIndexAccess +sal_Int32 SAL_CALL SdDrawPagesAccess::getCount() +{ + ::SolarMutexGuard aGuard; + + if( nullptr == mpModel ) + throw lang::DisposedException(); + + return mpModel->mpDoc->GetSdPageCount( PageKind::Standard ); +} + +uno::Any SAL_CALL SdDrawPagesAccess::getByIndex( sal_Int32 Index ) +{ + ::SolarMutexGuard aGuard; + + if( nullptr == mpModel ) + throw lang::DisposedException(); + + uno::Any aAny; + + if( (Index < 0) || (Index >= mpModel->mpDoc->GetSdPageCount( PageKind::Standard ) ) ) + throw lang::IndexOutOfBoundsException(); + + SdPage* pPage = mpModel->mpDoc->GetSdPage( static_cast<sal_uInt16>(Index), PageKind::Standard ); + if( pPage ) + { + uno::Reference< drawing::XDrawPage > xDrawPage( pPage->getUnoPage(), uno::UNO_QUERY ); + aAny <<= xDrawPage; + } + + return aAny; +} + +// XNameAccess +uno::Any SAL_CALL SdDrawPagesAccess::getByName( const OUString& aName ) +{ + ::SolarMutexGuard aGuard; + + if( nullptr == mpModel ) + throw lang::DisposedException(); + + if( !aName.isEmpty() ) + { + const sal_uInt16 nCount = mpModel->mpDoc->GetSdPageCount( PageKind::Standard ); + sal_uInt16 nPage; + for( nPage = 0; nPage < nCount; nPage++ ) + { + SdPage* pPage = mpModel->mpDoc->GetSdPage( nPage, PageKind::Standard ); + if(nullptr == pPage) + continue; + + if( aName == SdDrawPage::getPageApiName( pPage ) ) + { + uno::Any aAny; + uno::Reference< drawing::XDrawPage > xDrawPage( pPage->getUnoPage(), uno::UNO_QUERY ); + aAny <<= xDrawPage; + return aAny; + } + } + } + + throw container::NoSuchElementException(); +} + +uno::Sequence< OUString > SAL_CALL SdDrawPagesAccess::getElementNames() +{ + ::SolarMutexGuard aGuard; + + if( nullptr == mpModel ) + throw lang::DisposedException(); + + const sal_uInt16 nCount = mpModel->mpDoc->GetSdPageCount( PageKind::Standard ); + uno::Sequence< OUString > aNames( nCount ); + OUString* pNames = aNames.getArray(); + + sal_uInt16 nPage; + for( nPage = 0; nPage < nCount; nPage++ ) + { + SdPage* pPage = mpModel->mpDoc->GetSdPage( nPage, PageKind::Standard ); + *pNames++ = SdDrawPage::getPageApiName( pPage ); + } + + return aNames; +} + +sal_Bool SAL_CALL SdDrawPagesAccess::hasByName( const OUString& aName ) +{ + ::SolarMutexGuard aGuard; + + if( nullptr == mpModel ) + throw lang::DisposedException(); + + const sal_uInt16 nCount = mpModel->mpDoc->GetSdPageCount( PageKind::Standard ); + sal_uInt16 nPage; + for( nPage = 0; nPage < nCount; nPage++ ) + { + SdPage* pPage = mpModel->mpDoc->GetSdPage( nPage, PageKind::Standard ); + if(nullptr == pPage) + continue; + + if( aName == SdDrawPage::getPageApiName( pPage ) ) + return true; + } + + return false; +} + +// XElementAccess +uno::Type SAL_CALL SdDrawPagesAccess::getElementType() +{ + return cppu::UnoType<drawing::XDrawPage>::get(); +} + +sal_Bool SAL_CALL SdDrawPagesAccess::hasElements() +{ + return getCount() > 0; +} + +// XDrawPages + +/** + * Creates a new page with model at the specified position. + * @returns corresponding SdDrawPage + */ +uno::Reference< drawing::XDrawPage > SAL_CALL SdDrawPagesAccess::insertNewByIndex( sal_Int32 nIndex ) +{ + ::SolarMutexGuard aGuard; + comphelper::ProfileZone aZone("insertNewByIndex"); + + if( nullptr == mpModel ) + throw lang::DisposedException(); + + if( mpModel->mpDoc ) + { + SdPage* pPage = mpModel->InsertSdPage( static_cast<sal_uInt16>(nIndex), false ); + if( pPage ) + { + uno::Reference< drawing::XDrawPage > xDrawPage( pPage->getUnoPage(), uno::UNO_QUERY ); + return xDrawPage; + } + } + uno::Reference< drawing::XDrawPage > xDrawPage; + return xDrawPage; +} + +/** + * Removes the specified SdDrawPage from the model and the internal list. It + * only works, if there is at least one *normal* page in the model after + * removing this page. + */ +void SAL_CALL SdDrawPagesAccess::remove( const uno::Reference< drawing::XDrawPage >& xPage ) +{ + ::SolarMutexGuard aGuard; + + if( nullptr == mpModel || mpModel->mpDoc == nullptr ) + throw lang::DisposedException(); + + SdDrawDocument& rDoc = *mpModel->mpDoc; + + sal_uInt16 nPageCount = rDoc.GetSdPageCount( PageKind::Standard ); + if( nPageCount > 1 ) + { + // get pPage from xPage and determine the Id (nPos ) afterwards + SdDrawPage* pSvxPage = comphelper::getFromUnoTunnel<SdDrawPage>( xPage ); + if( pSvxPage ) + { + SdPage* pPage = static_cast<SdPage*>(pSvxPage->GetSdrPage()); + if(pPage && ( pPage->GetPageKind() == PageKind::Standard ) ) + { + sal_uInt16 nPage = pPage->GetPageNum(); + + SdPage* pNotesPage = static_cast< SdPage* >( rDoc.GetPage( nPage+1 ) ); + + bool bUndo = rDoc.IsUndoEnabled(); + if( bUndo ) + { + // Add undo actions and delete the pages. The order of adding + // the undo actions is important. + rDoc.BegUndo( SdResId( STR_UNDO_DELETEPAGES ) ); + rDoc.AddUndo(rDoc.GetSdrUndoFactory().CreateUndoDeletePage(*pNotesPage)); + rDoc.AddUndo(rDoc.GetSdrUndoFactory().CreateUndoDeletePage(*pPage)); + } + + rDoc.RemovePage( nPage ); // the page + rDoc.RemovePage( nPage ); // the notes page + + if( bUndo ) + { + rDoc.EndUndo(); + } + } + } + } + + mpModel->SetModified(); +} + +// XServiceInfo + +OUString SAL_CALL SdDrawPagesAccess::getImplementationName( ) +{ + return "SdDrawPagesAccess"; +} + +sal_Bool SAL_CALL SdDrawPagesAccess::supportsService( const OUString& ServiceName ) +{ + return cppu::supportsService(this, ServiceName); +} + +uno::Sequence< OUString > SAL_CALL SdDrawPagesAccess::getSupportedServiceNames( ) +{ + return { "com.sun.star.drawing.DrawPages" }; +} + +// XComponent +void SAL_CALL SdDrawPagesAccess::dispose( ) +{ + mpModel = nullptr; +} + +void SAL_CALL SdDrawPagesAccess::addEventListener( const uno::Reference< lang::XEventListener >& ) +{ + OSL_FAIL( "not implemented!" ); +} + +void SAL_CALL SdDrawPagesAccess::removeEventListener( const uno::Reference< lang::XEventListener >& ) +{ + OSL_FAIL( "not implemented!" ); +} + + +SdMasterPagesAccess::SdMasterPagesAccess( SdXImpressDocument& rMyModel ) noexcept +: mpModel(&rMyModel) +{ +} + +SdMasterPagesAccess::~SdMasterPagesAccess() noexcept +{ +} + +// XComponent +void SAL_CALL SdMasterPagesAccess::dispose( ) +{ + mpModel = nullptr; +} + +void SAL_CALL SdMasterPagesAccess::addEventListener( const uno::Reference< lang::XEventListener >& ) +{ + OSL_FAIL( "not implemented!" ); +} + +void SAL_CALL SdMasterPagesAccess::removeEventListener( const uno::Reference< lang::XEventListener >& ) +{ + OSL_FAIL( "not implemented!" ); +} + +// XIndexAccess +sal_Int32 SAL_CALL SdMasterPagesAccess::getCount() +{ + ::SolarMutexGuard aGuard; + + if( nullptr == mpModel->mpDoc ) + throw lang::DisposedException(); + + return mpModel->mpDoc->GetMasterSdPageCount(PageKind::Standard); +} + +/** + * Provides a drawing::XDrawPage interface for accessing the Masterpage at the + * specified position in the model. + */ +uno::Any SAL_CALL SdMasterPagesAccess::getByIndex( sal_Int32 Index ) +{ + ::SolarMutexGuard aGuard; + comphelper::ProfileZone aZone("SdMasterPagesAccess::getByIndex"); + + if( nullptr == mpModel ) + throw lang::DisposedException(); + + uno::Any aAny; + + if( (Index < 0) || (Index >= mpModel->mpDoc->GetMasterSdPageCount( PageKind::Standard ) ) ) + throw lang::IndexOutOfBoundsException(); + + SdPage* pPage = mpModel->mpDoc->GetMasterSdPage( static_cast<sal_uInt16>(Index), PageKind::Standard ); + if( pPage ) + { + uno::Reference< drawing::XDrawPage > xDrawPage( pPage->getUnoPage(), uno::UNO_QUERY ); + aAny <<= xDrawPage; + } + + return aAny; +} + +// XElementAccess +uno::Type SAL_CALL SdMasterPagesAccess::getElementType() +{ + return cppu::UnoType<drawing::XDrawPage>::get(); +} + +sal_Bool SAL_CALL SdMasterPagesAccess::hasElements() +{ + return getCount() > 0; +} + +// XDrawPages +uno::Reference< drawing::XDrawPage > SAL_CALL SdMasterPagesAccess::insertNewByIndex( sal_Int32 nInsertPos ) +{ + ::SolarMutexGuard aGuard; + + if( nullptr == mpModel ) + throw lang::DisposedException(); + + uno::Reference< drawing::XDrawPage > xDrawPage; + + SdDrawDocument* pDoc = mpModel->mpDoc; + if( pDoc ) + { + // calculate internal index and check for range errors + const sal_Int32 nMPageCount = pDoc->GetMasterPageCount(); + nInsertPos = nInsertPos * 2 + 1; + if( nInsertPos < 0 || nInsertPos > nMPageCount ) + nInsertPos = nMPageCount; + + // now generate a unique name for the new masterpage + const OUString aStdPrefix( SdResId(STR_LAYOUT_DEFAULT_NAME) ); + OUString aPrefix( aStdPrefix ); + + bool bUnique = true; + + std::vector<OUString> aPageNames; + for (sal_Int32 nMaster = 1; nMaster < nMPageCount; ++nMaster) + { + const SdPage* pPage = static_cast<const SdPage*>(pDoc->GetMasterPage(static_cast<sal_uInt16>(nMaster))); + if (!pPage) + continue; + aPageNames.push_back(pPage->GetName()); + if (aPageNames.back() == aPrefix) + bUnique = false; + } + + sal_Int32 i = 0; + while (!bUnique) + { + aPrefix = aStdPrefix + " " + OUString::number(++i); + bUnique = std::find(aPageNames.begin(), aPageNames.end(), aPrefix) == aPageNames.end(); + } + + OUString aLayoutName = aPrefix + SD_LT_SEPARATOR + STR_LAYOUT_OUTLINE; + + // create styles + static_cast<SdStyleSheetPool*>(pDoc->GetStyleSheetPool())->CreateLayoutStyleSheets( aPrefix ); + + // get the first page for initial size and border settings + SdPage* pPage = mpModel->mpDoc->GetSdPage( sal_uInt16(0), PageKind::Standard ); + SdPage* pRefNotesPage = mpModel->mpDoc->GetSdPage( sal_uInt16(0), PageKind::Notes); + + // create and insert new draw masterpage + rtl::Reference<SdPage> pMPage = mpModel->mpDoc->AllocSdPage(true); + pMPage->SetSize( pPage->GetSize() ); + pMPage->SetBorder( pPage->GetLeftBorder(), + pPage->GetUpperBorder(), + pPage->GetRightBorder(), + pPage->GetLowerBorder() ); + pMPage->SetLayoutName( aLayoutName ); + pDoc->InsertMasterPage(pMPage.get(), static_cast<sal_uInt16>(nInsertPos)); + + { + // ensure default MasterPage fill + pMPage->EnsureMasterPageDefaultBackground(); + } + + xDrawPage.set( pMPage->getUnoPage(), uno::UNO_QUERY ); + + // create and insert new notes masterpage + rtl::Reference<SdPage> pMNotesPage = mpModel->mpDoc->AllocSdPage(true); + pMNotesPage->SetSize( pRefNotesPage->GetSize() ); + pMNotesPage->SetPageKind(PageKind::Notes); + pMNotesPage->SetBorder( pRefNotesPage->GetLeftBorder(), + pRefNotesPage->GetUpperBorder(), + pRefNotesPage->GetRightBorder(), + pRefNotesPage->GetLowerBorder() ); + pMNotesPage->SetLayoutName( aLayoutName ); + pDoc->InsertMasterPage(pMNotesPage.get(), static_cast<sal_uInt16>(nInsertPos) + 1); + pMNotesPage->SetAutoLayout(AUTOLAYOUT_NOTES, true, true); + mpModel->SetModified(); + } + + return xDrawPage; +} + +/** + * Removes the specified SdMasterPage from the model and the internal list. It + * only works, if there is no *normal* page using this page as MasterPage in + * the model. + */ +void SAL_CALL SdMasterPagesAccess::remove( const uno::Reference< drawing::XDrawPage >& xPage ) +{ + ::SolarMutexGuard aGuard; + + if( nullptr == mpModel || mpModel->mpDoc == nullptr ) + throw lang::DisposedException(); + + SdMasterPage* pSdPage = comphelper::getFromUnoTunnel<SdMasterPage>( xPage ); + if(pSdPage == nullptr) + return; + + SdPage* pPage = dynamic_cast< SdPage* > (pSdPage->GetSdrPage()); + + DBG_ASSERT( pPage && pPage->IsMasterPage(), "SdMasterPage is not masterpage?"); + + if( !pPage || !pPage->IsMasterPage() || (mpModel->mpDoc->GetMasterPageUserCount(pPage) > 0)) + return; //Todo: this should be excepted + + // only standard pages can be removed directly + if( pPage->GetPageKind() != PageKind::Standard ) + return; + + sal_uInt16 nPage = pPage->GetPageNum(); + + SdDrawDocument& rDoc = *mpModel->mpDoc; + + SdPage* pNotesPage = static_cast< SdPage* >( rDoc.GetMasterPage( nPage+1 ) ); + + bool bUndo = rDoc.IsUndoEnabled(); + if( bUndo ) + { + // Add undo actions and delete the pages. The order of adding + // the undo actions is important. + rDoc.BegUndo( SdResId( STR_UNDO_DELETEPAGES ) ); + rDoc.AddUndo(rDoc.GetSdrUndoFactory().CreateUndoDeletePage(*pNotesPage)); + rDoc.AddUndo(rDoc.GetSdrUndoFactory().CreateUndoDeletePage(*pPage)); + } + + // remove both pages + rDoc.RemoveMasterPage( nPage ); + rDoc.RemoveMasterPage( nPage ); + + if( bUndo ) + { + rDoc.EndUndo(); + } +} + +// XServiceInfo + +OUString SAL_CALL SdMasterPagesAccess::getImplementationName( ) +{ + return "SdMasterPagesAccess"; +} + +sal_Bool SAL_CALL SdMasterPagesAccess::supportsService( const OUString& ServiceName ) +{ + return cppu::supportsService(this, ServiceName); +} + +uno::Sequence< OUString > SAL_CALL SdMasterPagesAccess::getSupportedServiceNames( ) +{ + return { "com.sun.star.drawing.MasterPages" }; +} + + +SdDocLinkTargets::SdDocLinkTargets( SdXImpressDocument& rMyModel ) noexcept +: mpModel( &rMyModel ) +{ +} + +SdDocLinkTargets::~SdDocLinkTargets() noexcept +{ +} + +// XComponent +void SAL_CALL SdDocLinkTargets::dispose( ) +{ + mpModel = nullptr; +} + +void SAL_CALL SdDocLinkTargets::addEventListener( const uno::Reference< lang::XEventListener >& ) +{ + OSL_FAIL( "not implemented!" ); +} + +void SAL_CALL SdDocLinkTargets::removeEventListener( const uno::Reference< lang::XEventListener >& ) +{ + OSL_FAIL( "not implemented!" ); +} + +// XNameAccess +uno::Any SAL_CALL SdDocLinkTargets::getByName( const OUString& aName ) +{ + ::SolarMutexGuard aGuard; + + if( nullptr == mpModel ) + throw lang::DisposedException(); + + SdPage* pPage = FindPage( aName ); + + if( pPage == nullptr ) + throw container::NoSuchElementException(); + + uno::Any aAny; + + uno::Reference< beans::XPropertySet > xProps( pPage->getUnoPage(), uno::UNO_QUERY ); + if( xProps.is() ) + aAny <<= xProps; + + return aAny; +} + +uno::Sequence< OUString > SAL_CALL SdDocLinkTargets::getElementNames() +{ + ::SolarMutexGuard aGuard; + + if( nullptr == mpModel ) + throw lang::DisposedException(); + + SdDrawDocument* pDoc = mpModel->GetDoc(); + if( pDoc == nullptr ) + { + return { }; + } + + if( pDoc->GetDocumentType() == DocumentType::Draw ) + { + const sal_uInt16 nMaxPages = pDoc->GetSdPageCount( PageKind::Standard ); + const sal_uInt16 nMaxMasterPages = pDoc->GetMasterSdPageCount( PageKind::Standard ); + + uno::Sequence< OUString > aSeq( nMaxPages + nMaxMasterPages ); + OUString* pStr = aSeq.getArray(); + + sal_uInt16 nPage; + // standard pages + for( nPage = 0; nPage < nMaxPages; nPage++ ) + *pStr++ = pDoc->GetSdPage( nPage, PageKind::Standard )->GetName(); + + // master pages + for( nPage = 0; nPage < nMaxMasterPages; nPage++ ) + *pStr++ = pDoc->GetMasterSdPage( nPage, PageKind::Standard )->GetName(); + return aSeq; + } + else + { + const sal_uInt16 nMaxPages = pDoc->GetPageCount(); + const sal_uInt16 nMaxMasterPages = pDoc->GetMasterPageCount(); + + uno::Sequence< OUString > aSeq( nMaxPages + nMaxMasterPages ); + OUString* pStr = aSeq.getArray(); + + sal_uInt16 nPage; + // standard pages + for( nPage = 0; nPage < nMaxPages; nPage++ ) + *pStr++ = static_cast<SdPage*>(pDoc->GetPage( nPage ))->GetName(); + + // master pages + for( nPage = 0; nPage < nMaxMasterPages; nPage++ ) + *pStr++ = static_cast<SdPage*>(pDoc->GetMasterPage( nPage ))->GetName(); + return aSeq; + } +} + +sal_Bool SAL_CALL SdDocLinkTargets::hasByName( const OUString& aName ) +{ + ::SolarMutexGuard aGuard; + + if( nullptr == mpModel ) + throw lang::DisposedException(); + + return FindPage( aName ) != nullptr; +} + +// container::XElementAccess +uno::Type SAL_CALL SdDocLinkTargets::getElementType() +{ + return cppu::UnoType<beans::XPropertySet>::get(); +} + +sal_Bool SAL_CALL SdDocLinkTargets::hasElements() +{ + ::SolarMutexGuard aGuard; + + if( nullptr == mpModel ) + throw lang::DisposedException(); + + return mpModel->GetDoc() != nullptr; +} + +SdPage* SdDocLinkTargets::FindPage( std::u16string_view rName ) const +{ + SdDrawDocument* pDoc = mpModel->GetDoc(); + if( pDoc == nullptr ) + return nullptr; + + const sal_uInt16 nMaxPages = pDoc->GetPageCount(); + const sal_uInt16 nMaxMasterPages = pDoc->GetMasterPageCount(); + + sal_uInt16 nPage; + SdPage* pPage; + + const bool bDraw = pDoc->GetDocumentType() == DocumentType::Draw; + + // standard pages + for( nPage = 0; nPage < nMaxPages; nPage++ ) + { + pPage = static_cast<SdPage*>(pDoc->GetPage( nPage )); + if( (pPage->GetName() == rName) && (!bDraw || (pPage->GetPageKind() == PageKind::Standard)) ) + return pPage; + } + + // master pages + for( nPage = 0; nPage < nMaxMasterPages; nPage++ ) + { + pPage = static_cast<SdPage*>(pDoc->GetMasterPage( nPage )); + if( (pPage->GetName() == rName) && (!bDraw || (pPage->GetPageKind() == PageKind::Standard)) ) + return pPage; + } + + return nullptr; +} + +// XServiceInfo +OUString SAL_CALL SdDocLinkTargets::getImplementationName() +{ + return "SdDocLinkTargets"; +} + +sal_Bool SAL_CALL SdDocLinkTargets::supportsService( const OUString& ServiceName ) +{ + return cppu::supportsService( this, ServiceName ); +} + +uno::Sequence< OUString > SAL_CALL SdDocLinkTargets::getSupportedServiceNames() +{ + return { "com.sun.star.document.LinkTargets" }; +} + +rtl::Reference< SdXImpressDocument > SdXImpressDocument::GetModel( SdDrawDocument const & rDocument ) +{ + rtl::Reference< SdXImpressDocument > xRet; + ::sd::DrawDocShell* pDocShell(rDocument.GetDocSh()); + if( pDocShell ) + { + uno::Reference<frame::XModel> xModel(pDocShell->GetModel()); + + xRet.set( dynamic_cast< SdXImpressDocument* >( xModel.get() ) ); + } + + return xRet; +} + +void NotifyDocumentEvent( SdDrawDocument const & rDocument, const OUString& rEventName ) +{ + rtl::Reference< SdXImpressDocument > xModel( SdXImpressDocument::GetModel( rDocument ) ); + + if( xModel.is() ) + { + uno::Reference< uno::XInterface > xSource( static_cast<uno::XWeak*>( xModel.get() ) ); + css::document::EventObject aEvent( xSource, rEventName ); + xModel->notifyEvent(aEvent ); + } +} + +void NotifyDocumentEvent( SdDrawDocument const & rDocument, const OUString& rEventName, const uno::Reference< uno::XInterface >& xSource ) +{ + rtl::Reference< SdXImpressDocument > xModel( SdXImpressDocument::GetModel( rDocument ) ); + + if( xModel.is() ) + { + css::document::EventObject aEvent( xSource, rEventName ); + xModel->notifyEvent(aEvent ); + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/unoidl/unomodule.cxx b/sd/source/ui/unoidl/unomodule.cxx new file mode 100644 index 000000000..d862f7c9d --- /dev/null +++ b/sd/source/ui/unoidl/unomodule.cxx @@ -0,0 +1,132 @@ +/* -*- 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 <com/sun/star/frame/DispatchResultState.hpp> +#include <cppuhelper/supportsservice.hxx> + +#include <sddll.hxx> +#include <sdmod.hxx> +#include "unomodule.hxx" +#include <sfx2/objface.hxx> +#include <sfx2/bindings.hxx> +#include <sfx2/request.hxx> +#include <vcl/svapp.hxx> + +using namespace ::com::sun::star; + + // XNotifyingDispatch +void SAL_CALL SdUnoModule::dispatchWithNotification( const util::URL& aURL, const uno::Sequence< beans::PropertyValue >& aArgs, const uno::Reference< frame::XDispatchResultListener >& xListener ) +{ + // there is no guarantee, that we are holded alive during this method! + // May the outside dispatch container will be updated by a CONTEXT_CHANGED + // asynchronous ... + uno::Reference< uno::XInterface > xThis(static_cast< frame::XNotifyingDispatch* >(this)); + + SolarMutexGuard aGuard; + SdDLL::Init(); + const SfxSlot* pSlot = SD_MOD()->GetInterface()->GetSlot( aURL.Complete ); + + sal_Int16 aState = frame::DispatchResultState::DONTKNOW; + if ( !pSlot ) + aState = frame::DispatchResultState::FAILURE; + else + { + SfxRequest aReq( pSlot, aArgs, SfxCallMode::SYNCHRON, SD_MOD()->GetPool() ); + const SfxPoolItem* pResult = SD_MOD()->ExecuteSlot( aReq ); + if ( pResult ) + aState = frame::DispatchResultState::SUCCESS; + else + aState = frame::DispatchResultState::FAILURE; + } + + if ( xListener.is() ) + { + xListener->dispatchFinished( + frame::DispatchResultEvent( + xThis, aState, uno::Any())); + } +} + // XDispatch +void SAL_CALL SdUnoModule::dispatch( const util::URL& aURL, const uno::Sequence< beans::PropertyValue >& aArgs ) +{ + dispatchWithNotification(aURL, aArgs, uno::Reference< frame::XDispatchResultListener >()); +} + +void SAL_CALL SdUnoModule::addStatusListener(const uno::Reference< frame::XStatusListener > &, const util::URL&) +{ +} + +void SAL_CALL SdUnoModule::removeStatusListener(const uno::Reference< frame::XStatusListener > &, const util::URL&) +{ +} + +uno::Sequence< uno::Reference< frame::XDispatch > > SAL_CALL SdUnoModule::queryDispatches( const uno::Sequence< frame::DispatchDescriptor >& seqDescripts ) +{ + sal_Int32 nCount = seqDescripts.getLength(); + uno::Sequence< uno::Reference< frame::XDispatch > > lDispatcher( nCount ); + + std::transform(seqDescripts.begin(), seqDescripts.end(), lDispatcher.getArray(), + [this](const frame::DispatchDescriptor& rDescr) -> uno::Reference<frame::XDispatch> { + return queryDispatch(rDescr.FeatureURL, rDescr.FrameName, rDescr.SearchFlags); }); + + return lDispatcher; +} + +// XDispatchProvider +uno::Reference< frame::XDispatch > SAL_CALL SdUnoModule::queryDispatch( const util::URL& aURL, const OUString&, sal_Int32 ) +{ + SolarMutexGuard aGuard; + SdDLL::Init(); + const SfxSlot* pSlot = SD_MOD()->GetInterface()->GetSlot( aURL.Complete ); + + uno::Reference< frame::XDispatch > xSlot; + if ( pSlot ) + xSlot = this; + + return xSlot; +} + +// XServiceInfo +OUString SAL_CALL SdUnoModule::getImplementationName( ) +{ + return "com.sun.star.comp.Draw.DrawingModule"; +} + +sal_Bool SAL_CALL SdUnoModule::supportsService( const OUString& sServiceName ) +{ + return cppu::supportsService(this, sServiceName); +} + +uno::Sequence< OUString > SAL_CALL SdUnoModule::getSupportedServiceNames( ) +{ + return { "com.sun.star.drawing.ModuleDispatcher" }; +} + + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* +com_sun_star_comp_Draw_DrawingModule_get_implementation(css::uno::XComponentContext* , + css::uno::Sequence<css::uno::Any> const &) +{ + SolarMutexGuard aGuard; + + return cppu::acquire(new SdUnoModule); +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/unoidl/unomodule.hxx b/sd/source/ui/unoidl/unomodule.hxx new file mode 100644 index 000000000..bc78c6b19 --- /dev/null +++ b/sd/source/ui/unoidl/unomodule.hxx @@ -0,0 +1,57 @@ +/* -*- 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 <rtl/ustring.hxx> +#include <com/sun/star/frame/XDispatchProvider.hpp> +#include <com/sun/star/frame/XNotifyingDispatch.hpp> +#include <com/sun/star/uno/Reference.h> +#include <cppuhelper/implbase.hxx> + +#include <com/sun/star/lang/XServiceInfo.hpp> + +namespace com::sun::star::beans { struct PropertyValue; } +namespace com::sun::star::frame { struct DispatchDescriptor; } + +class SdUnoModule : public ::cppu::WeakImplHelper< css::frame::XDispatchProvider, css::frame::XNotifyingDispatch, css::lang::XServiceInfo > +{ +public: + SdUnoModule() {} + + // XnotifyingDispatch + virtual void SAL_CALL dispatchWithNotification( const css::util::URL& URL, const css::uno::Sequence< css::beans::PropertyValue >& Arguments, const css::uno::Reference< css::frame::XDispatchResultListener >& Listener ) override; + + // XDispatch + virtual void SAL_CALL dispatch( const css::util::URL& aURL, const css::uno::Sequence< css::beans::PropertyValue >& aArgs ) override; + virtual void SAL_CALL addStatusListener(const css::uno::Reference< css::frame::XStatusListener > & xControl, const css::util::URL& aURL) override; + virtual void SAL_CALL removeStatusListener(const css::uno::Reference< css::frame::XStatusListener > & xControl, const css::util::URL& aURL) override; + + // XDispatchProvider + virtual css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > SAL_CALL queryDispatches( const css::uno::Sequence< css::frame::DispatchDescriptor >& seqDescriptor ) override ; + virtual css::uno::Reference< css::frame::XDispatch > SAL_CALL queryDispatch( const css::util::URL & aURL , + const OUString & sTargetFrameName, + sal_Int32 eSearchFlags ) 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; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/unoidl/unoobj.cxx b/sd/source/ui/unoidl/unoobj.cxx new file mode 100644 index 000000000..6ed6729f9 --- /dev/null +++ b/sd/source/ui/unoidl/unoobj.cxx @@ -0,0 +1,1627 @@ +/* -*- 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 <memory> +#include <string_view> +#include <utility> + +#include <com/sun/star/style/XStyle.hpp> +#include <com/sun/star/presentation/ClickAction.hpp> +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <com/sun/star/beans/PropertyState.hpp> +#include <rtl/ustrbuf.hxx> +#include <svl/itemprop.hxx> +#include <svl/style.hxx> +#include <svx/svdpool.hxx> +#include <sfx2/viewfrm.hxx> +#include <sfx2/app.hxx> +#include <svtools/unoimap.hxx> +#include <svtools/unoevent.hxx> +#include <sfx2/bindings.hxx> +#include <sfx2/event.hxx> +#include <sfx2/sfxsids.hrc> +#include <comphelper/extract.hxx> +#include <cppuhelper/implbase.hxx> +#include <cppuhelper/supportsservice.hxx> +#include <svx/unoshape.hxx> +#include <svx/svdotext.hxx> +#include <svx/svdopath.hxx> +#include <svx/svdoole2.hxx> +#include <svx/svdograf.hxx> +#include <svx/ImageMapInfo.hxx> +#include <filter/msfilter/msdffimp.hxx> +#include <svl/instrm.hxx> +#include <editeng/outlobj.hxx> +#include <Outliner.hxx> +#include <comphelper/sequence.hxx> +#include <svx/svdogrp.hxx> +#include <o3tl/typed_flags_set.hxx> +#include <vcl/svapp.hxx> +#include <tools/debug.hxx> + +#include <anminfo.hxx> +#include "unoobj.hxx" +#include <unoprnms.hxx> +#include <unomodel.hxx> +#include <drawdoc.hxx> +#include <sdmod.hxx> +#include <sdpage.hxx> +#include <ViewShell.hxx> +#include <unopage.hxx> +#include <DrawDocShell.hxx> +#include <EffectMigration.hxx> + +using namespace ::sd; +using namespace ::com::sun::star; +using namespace ::com::sun::star::presentation; +using namespace ::com::sun::star::animations; + +using ::com::sun::star::uno::Any; +using ::com::sun::star::drawing::XShape; + +#define WID_EFFECT 1 +#define WID_SPEED 2 +#define WID_TEXTEFFECT 3 +#define WID_BOOKMARK 4 +#define WID_CLICKACTION 5 +#define WID_PLAYFULL 6 +#define WID_SOUNDFILE 7 +#define WID_SOUNDON 8 +#define WID_BLUESCREEN 9 +#define WID_VERB 10 +#define WID_DIMCOLOR 11 +#define WID_DIMHIDE 12 +#define WID_DIMPREV 13 +#define WID_PRESORDER 14 +#define WID_STYLE 15 +#define WID_ANIMPATH 16 +#define WID_IMAGEMAP 17 +#define WID_ISANIMATION 18 +#define WID_THAT_NEED_ANIMINFO 19 + +#define WID_ISEMPTYPRESOBJ 20 +#define WID_ISPRESOBJ 21 +#define WID_MASTERDEPEND 22 + +#define WID_NAVORDER 23 +#define WID_PLACEHOLDERTEXT 24 +#define WID_LEGACYFRAGMENT 25 + +#define IMPRESS_MAP_ENTRIES \ + { u"" UNO_NAME_OBJ_LEGACYFRAGMENT,WID_LEGACYFRAGMENT, cppu::UnoType<drawing::XShape>::get(), 0, 0},\ + { u"" UNO_NAME_OBJ_ANIMATIONPATH, WID_ANIMPATH, cppu::UnoType<drawing::XShape>::get(), 0, 0},\ + { u"" UNO_NAME_OBJ_BOOKMARK, WID_BOOKMARK, cppu::UnoType<OUString>::get(), 0, 0},\ + { u"" UNO_NAME_OBJ_DIMCOLOR, WID_DIMCOLOR, cppu::UnoType<sal_Int32>::get(), 0, 0},\ + { u"" UNO_NAME_OBJ_DIMHIDE, WID_DIMHIDE, cppu::UnoType<bool>::get(), 0, 0},\ + { u"" UNO_NAME_OBJ_DIMPREV, WID_DIMPREV, cppu::UnoType<bool>::get(), 0, 0},\ + { u"" UNO_NAME_OBJ_EFFECT, WID_EFFECT, cppu::UnoType<presentation::AnimationEffect>::get(), 0, 0},\ + { u"" UNO_NAME_OBJ_ISEMPTYPRESOBJ,WID_ISEMPTYPRESOBJ, cppu::UnoType<bool>::get(), 0, 0},\ + { u"" UNO_NAME_OBJ_ISPRESOBJ, WID_ISPRESOBJ, cppu::UnoType<bool>::get(), css::beans::PropertyAttribute::READONLY, 0},\ + { u"" UNO_NAME_OBJ_MASTERDEPENDENT,WID_MASTERDEPEND, cppu::UnoType<bool>::get(), 0, 0},\ + { u"" UNO_NAME_OBJ_CLICKACTION, WID_CLICKACTION, cppu::UnoType<presentation::ClickAction>::get(), 0, 0},\ + { u"" UNO_NAME_OBJ_PLAYFULL, WID_PLAYFULL, cppu::UnoType<bool>::get(), 0, 0},\ + { u"" UNO_NAME_OBJ_PRESORDER, WID_PRESORDER, cppu::UnoType<sal_Int32>::get(), 0, 0},\ + { u"" UNO_NAME_OBJ_STYLE, WID_STYLE, cppu::UnoType<style::XStyle>::get(), css::beans::PropertyAttribute::MAYBEVOID, 0},\ + { u"" UNO_NAME_OBJ_SOUNDFILE, WID_SOUNDFILE, cppu::UnoType<OUString>::get(), 0, 0},\ + { u"" UNO_NAME_OBJ_SOUNDON, WID_SOUNDON, cppu::UnoType<bool>::get(), 0, 0},\ + { u"" UNO_NAME_OBJ_SPEED, WID_SPEED, cppu::UnoType<presentation::AnimationSpeed>::get(), 0, 0},\ + { u"" UNO_NAME_OBJ_TEXTEFFECT, WID_TEXTEFFECT, cppu::UnoType<presentation::AnimationEffect>::get(), 0, 0},\ + { u"" UNO_NAME_OBJ_BLUESCREEN, WID_BLUESCREEN, cppu::UnoType<sal_Int32>::get(), 0, 0},\ + { u"" UNO_NAME_OBJ_VERB, WID_VERB, cppu::UnoType<sal_Int32>::get(), 0, 0},\ + { u"IsAnimation", WID_ISANIMATION, cppu::UnoType<bool>::get(), 0, 0},\ + { u"NavigationOrder", WID_NAVORDER, cppu::UnoType<sal_Int32>::get(), 0, 0},\ + { u"PlaceholderText", WID_PLACEHOLDERTEXT, cppu::UnoType<OUString>::get(), 0, 0},\ + { u"", 0, css::uno::Type(), 0, 0 } + + static const SfxItemPropertyMapEntry* lcl_GetImpress_SdXShapePropertyGraphicMap_Impl() + { + + static const SfxItemPropertyMapEntry aImpress_SdXShapePropertyGraphicMap_Impl[] = + { + { u"ImageMap", WID_IMAGEMAP, cppu::UnoType<container::XIndexContainer>::get(), 0, 0 }, + IMPRESS_MAP_ENTRIES + }; + return aImpress_SdXShapePropertyGraphicMap_Impl; + } + + static const SfxItemPropertyMapEntry* lcl_GetImpress_SdXShapePropertySimpleMap_Impl() + { + + static const SfxItemPropertyMapEntry aImpress_SdXShapePropertySimpleMap_Impl[] = + { + IMPRESS_MAP_ENTRIES + }; + return aImpress_SdXShapePropertySimpleMap_Impl; + } + + #define DRAW_MAP_ENTRIES\ + { u"" UNO_NAME_OBJ_BOOKMARK, WID_BOOKMARK, cppu::UnoType<OUString>::get(), 0, 0},\ + { u"" UNO_NAME_OBJ_CLICKACTION, WID_CLICKACTION, cppu::UnoType<presentation::ClickAction>::get(),0, 0},\ + { u"" UNO_NAME_OBJ_STYLE, WID_STYLE, cppu::UnoType<style::XStyle>::get(), css::beans::PropertyAttribute::MAYBEVOID, 0},\ + { u"NavigationOrder", WID_NAVORDER, cppu::UnoType<sal_Int32>::get(), 0, 0},\ + { u"", 0, css::uno::Type(), 0, 0 } + + static const SfxItemPropertyMapEntry* lcl_GetDraw_SdXShapePropertySimpleMap_Impl() + { + static const SfxItemPropertyMapEntry aDraw_SdXShapePropertyMap_Impl[] = + { + DRAW_MAP_ENTRIES + }; + return aDraw_SdXShapePropertyMap_Impl; + } + static const SfxItemPropertyMapEntry* lcl_GetDraw_SdXShapePropertyGraphicMap_Impl() + { + static const SfxItemPropertyMapEntry aDraw_SdXShapePropertyGraphicMap_Impl[] = + { + { u"ImageMap", WID_IMAGEMAP, cppu::UnoType<container::XIndexContainer>::get(), 0, 0 }, + DRAW_MAP_ENTRIES + }; + return aDraw_SdXShapePropertyGraphicMap_Impl; + } + static const SfxItemPropertyMapEntry* lcl_ImplGetShapePropertyMap( bool bImpress, bool bGraphicObj ) + { + const SfxItemPropertyMapEntry* pRet = nullptr; + if( bImpress ) + { + if( bGraphicObj ) + pRet = lcl_GetImpress_SdXShapePropertyGraphicMap_Impl(); + else + pRet = lcl_GetImpress_SdXShapePropertySimpleMap_Impl(); + } + else + { + if( bGraphicObj ) + pRet = lcl_GetDraw_SdXShapePropertyGraphicMap_Impl(); + else + pRet = lcl_GetDraw_SdXShapePropertySimpleMap_Impl(); + } + return pRet; + + } + static const SvxItemPropertySet* lcl_ImplGetShapePropertySet( bool bImpress, bool bGraphicObj ) + { + const SvxItemPropertySet* pRet = nullptr; + if( bImpress ) + { + if( bGraphicObj ) + { + static SvxItemPropertySet aImpress_SdXShapePropertyGraphicSet_Impl( lcl_GetImpress_SdXShapePropertyGraphicMap_Impl(), SdrObject::GetGlobalDrawObjectItemPool()); + pRet = &aImpress_SdXShapePropertyGraphicSet_Impl; + } + else + { + static SvxItemPropertySet aImpress_SdXShapePropertySet_Impl(lcl_GetImpress_SdXShapePropertySimpleMap_Impl(), SdrObject::GetGlobalDrawObjectItemPool()); + pRet = &aImpress_SdXShapePropertySet_Impl; + } + } + else + { + if( bGraphicObj ) + { + static SvxItemPropertySet aDraw_SdXShapePropertyGraphicSet_Impl(lcl_GetDraw_SdXShapePropertyGraphicMap_Impl(), SdrObject::GetGlobalDrawObjectItemPool()); + pRet = &aDraw_SdXShapePropertyGraphicSet_Impl; + } + else + { + static SvxItemPropertySet aDraw_SdXShapePropertySet_Impl( lcl_GetDraw_SdXShapePropertySimpleMap_Impl(), SdrObject::GetGlobalDrawObjectItemPool()); + pRet = &aDraw_SdXShapePropertySet_Impl; + } + } + return pRet; + } + static const SfxItemPropertyMapEntry* lcl_GetEmpty_SdXShapePropertyMap_Impl() + { + static const SfxItemPropertyMapEntry aEmpty_SdXShapePropertyMap_Impl[] = + { + { u"", 0, css::uno::Type(), 0, 0 } + }; + return aEmpty_SdXShapePropertyMap_Impl; + } + + static const SvxItemPropertySet* lcl_GetEmpty_SdXShapePropertySet_Impl() + { + static SvxItemPropertySet aEmptyPropSet( lcl_GetEmpty_SdXShapePropertyMap_Impl(), SdrObject::GetGlobalDrawObjectItemPool() ); + return &aEmptyPropSet; + } +const SvEventDescription* ImplGetSupportedMacroItems() +{ + static const SvEventDescription aMacroDescriptionsImpl[] = + { + { SvMacroItemId::OnMouseOver, "OnMouseOver" }, + { SvMacroItemId::OnMouseOut, "OnMouseOut" }, + { SvMacroItemId::NONE, nullptr } + }; + + return aMacroDescriptionsImpl; +} + +SdXShape::SdXShape(SvxShape* pShape, SdXImpressDocument* pModel) +: mpShape( pShape ), + mpPropSet( pModel? + lcl_ImplGetShapePropertySet(pModel->IsImpressDocument(), pShape->getShapeKind() == SdrObjKind::Graphic ) + : lcl_GetEmpty_SdXShapePropertySet_Impl() ), + mpMap( pModel? + lcl_ImplGetShapePropertyMap(pModel->IsImpressDocument(), pShape->getShapeKind() == SdrObjKind::Graphic ) + : lcl_GetEmpty_SdXShapePropertyMap_Impl() ), + mpModel(pModel) +{ + + pShape->setMaster( this ); +} + +SdXShape::~SdXShape() noexcept +{ +} + +void SdXShape::dispose() +{ + mpShape->setMaster( nullptr ); + delete this; +} + +uno::Any SAL_CALL SdXShape::queryInterface( const uno::Type & rType ) +{ + return mpShape->queryInterface( rType ); +} + +void SAL_CALL SdXShape::acquire() noexcept +{ + mpShape->acquire(); +} + +void SAL_CALL SdXShape::release() noexcept +{ + mpShape->release(); +} + +bool SdXShape::queryAggregation( const css::uno::Type & rType, css::uno::Any& aAny ) +{ + if( mpModel && mpModel ->IsImpressDocument() ) + { + if( rType == cppu::UnoType<document::XEventsSupplier>::get()) + { + aAny <<= uno::Reference< document::XEventsSupplier >(this); + return true; + } + } + + return false; +} + +uno::Sequence< uno::Type > SAL_CALL SdXShape::getTypes() +{ + if( mpModel && !mpModel->IsImpressDocument() ) + { + return mpShape->_getTypes(); + } + else + { + SdrObjKind nObjId = mpShape->getShapeKind(); + uno::Sequence< uno::Type > aTypes; + SdTypesCache& gImplTypesCache = SD_MOD()->gImplTypesCache; + SdTypesCache::iterator aIter( gImplTypesCache.find( nObjId ) ); + if( aIter == gImplTypesCache.end() ) + { + aTypes = mpShape->_getTypes(); + sal_uInt32 nCount = aTypes.getLength(); + aTypes.realloc( nCount+1 ); + aTypes.getArray()[nCount] = cppu::UnoType<lang::XTypeProvider>::get(); + + gImplTypesCache.insert(std::make_pair(nObjId, aTypes)); + } + else + { + // use the already computed implementation id + aTypes = (*aIter).second; + } + return aTypes; + } +} + +// XPropertyState +beans::PropertyState SAL_CALL SdXShape::getPropertyState( const OUString& PropertyName ) +{ + SolarMutexGuard aGuard; + + if( mpPropSet->getPropertyMapEntry(PropertyName) ) + { + return beans::PropertyState_DIRECT_VALUE; + } + else + { + SdrObject* pObj = mpShape->GetSdrObject(); + if( pObj == nullptr || ( pObj->getSdrPageFromSdrObject()->IsMasterPage() && pObj->IsEmptyPresObj() ) ) + return beans::PropertyState_DEFAULT_VALUE; + + return mpShape->_getPropertyState( PropertyName ); + } +} + +void SAL_CALL SdXShape::setPropertyToDefault( const OUString& PropertyName ) +{ + SolarMutexGuard aGuard; + + if( mpPropSet->getPropertyMapEntry(PropertyName) ) + { + return; + } + else + { + mpShape->_setPropertyToDefault(PropertyName); + } +} + +uno::Any SAL_CALL SdXShape::getPropertyDefault( const OUString& aPropertyName ) +{ + SolarMutexGuard aGuard; + + if( mpPropSet->getPropertyMapEntry(aPropertyName) ) + { + return getPropertyValue( aPropertyName ); + } + else + { + uno::Any aRet( mpShape->_getPropertyDefault(aPropertyName) ); + return aRet; + } +} + +//XPropertySet +css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL SdXShape::getPropertySetInfo() +{ + SfxItemPropertyMapEntry const * nObjId = mpShape->getPropertyMapEntries(); + css::uno::Reference<css::beans::XPropertySetInfo> pInfo; + + SdExtPropertySetInfoCache& rCache = (mpModel && mpModel->IsImpressDocument()) ? + SD_MOD()->gImplImpressPropertySetInfoCache : SD_MOD()->gImplDrawPropertySetInfoCache; + + SdExtPropertySetInfoCache::iterator aIter( rCache.find( nObjId ) ); + if( aIter == rCache.end() ) + { + uno::Reference< beans::XPropertySetInfo > xInfo( mpShape->_getPropertySetInfo() ); + pInfo = new SfxExtItemPropertySetInfo( mpMap, xInfo->getProperties() ); + + rCache.insert(std::make_pair(nObjId, pInfo)); + } + else + { + // use the already computed implementation id + pInfo = (*aIter).second; + } + + return pInfo; +} + +void SAL_CALL SdXShape::setPropertyValue( const OUString& aPropertyName, const css::uno::Any& aValue ) +{ + SolarMutexGuard aGuard; + + const SfxItemPropertyMapEntry* pEntry = mpPropSet->getPropertyMapEntry(aPropertyName); + + if( pEntry ) + { + SdrObject* pObj = mpShape->GetSdrObject(); + if( pObj ) + { + SdAnimationInfo* pInfo = GetAnimationInfo(pEntry->nWID <= WID_THAT_NEED_ANIMINFO); + + switch(pEntry->nWID) + { + case WID_NAVORDER: + { + sal_Int32 nNavOrder = 0; + if(!(aValue >>= nNavOrder)) + throw lang::IllegalArgumentException(); + + SdrObjList* pObjList = pObj->getParentSdrObjListFromSdrObject(); + if( pObjList ) + pObjList->SetObjectNavigationPosition( *pObj, (nNavOrder < 0) ? SAL_MAX_UINT32 : static_cast< sal_uInt32 >( nNavOrder ) ); + break; + } + + case WID_EFFECT: + { + AnimationEffect eEffect; + if(!(aValue >>= eEffect)) + throw lang::IllegalArgumentException(); + + EffectMigration::SetAnimationEffect( mpShape, eEffect ); + break; + } + case WID_TEXTEFFECT: + { + AnimationEffect eEffect; + if(!(aValue >>= eEffect)) + throw lang::IllegalArgumentException(); + + EffectMigration::SetTextAnimationEffect( mpShape, eEffect ); + break; + } + case WID_SPEED: + { + AnimationSpeed eSpeed; + if(!(aValue>>=eSpeed)) + throw lang::IllegalArgumentException(); + + EffectMigration::SetAnimationSpeed( mpShape, eSpeed ); + break; + } + case WID_ISANIMATION: + { + bool bIsAnimation(false); + + if(!(aValue >>= bIsAnimation)) + { + throw lang::IllegalArgumentException(); + } + + if(bIsAnimation) + { + SdrObjGroup* pGroup = dynamic_cast< SdrObjGroup* >(pObj); + SdPage* pPage = pGroup ? dynamic_cast< SdPage* >(pGroup->getSdrPageFromSdrObject()) : nullptr; + + if (pPage) + { + // #i42894# Animated Group object, migrate that effect + EffectMigration::CreateAnimatedGroup(*pGroup, *pPage); + + // #i42894# unfortunately when doing this all group members have to + // be moved to the page as direct members, else the currently + // available forms of animation do not work. If it succeeds, + // the group is empty and can be removed and deleted + if(!pGroup->GetSubList()->GetObjCount()) + { + pPage->NbcRemoveObject(pGroup->GetOrdNum()); + + // always use SdrObject::Free(...) for SdrObjects (!) + SdrObject* pTemp(pGroup); + SdrObject::Free(pTemp); + } + } + } + //pInfo->mbIsMovie = bIsAnimation; + break; + } + case WID_BOOKMARK: + { + OUString aString; + if(!(aValue >>= aString)) + throw lang::IllegalArgumentException(); + + pInfo->SetBookmark( SdDrawPage::getUiNameFromPageApiName( aString ) ); + break; + } + case WID_CLICKACTION: + ::cppu::any2enum< presentation::ClickAction >( pInfo->meClickAction, aValue); + break; + +// TODO: WID_PLAYFULL: + case WID_SOUNDFILE: + { + OUString aString; + if(!(aValue >>= aString)) + throw lang::IllegalArgumentException(); + pInfo->maSoundFile = aString; + EffectMigration::UpdateSoundEffect( mpShape, pInfo ); + break; + } + + case WID_SOUNDON: + { + if( !(aValue >>= pInfo->mbSoundOn) ) + throw lang::IllegalArgumentException(); + EffectMigration::UpdateSoundEffect( mpShape, pInfo ); + break; + } + case WID_VERB: + { + sal_Int32 nVerb = 0; + if(!(aValue >>= nVerb)) + throw lang::IllegalArgumentException(); + + pInfo->mnVerb = static_cast<sal_uInt16>(nVerb); + break; + } + case WID_DIMCOLOR: + { + sal_Int32 nColor = 0; + + if( !(aValue >>= nColor) ) + throw lang::IllegalArgumentException(); + + EffectMigration::SetDimColor( mpShape, nColor ); + break; + } + case WID_DIMHIDE: + { + bool bDimHide = false; + if( !(aValue >>= bDimHide) ) + throw lang::IllegalArgumentException(); + + EffectMigration::SetDimHide( mpShape, bDimHide ); + break; + } + case WID_DIMPREV: + { + bool bDimPrevious = false; + if( !(aValue >>= bDimPrevious) ) + throw lang::IllegalArgumentException(); + + EffectMigration::SetDimPrevious( mpShape, bDimPrevious ); + break; + } + case WID_PRESORDER: + { + sal_Int32 nNewPos = 0; + if( !(aValue >>= nNewPos) ) + throw lang::IllegalArgumentException(); + + EffectMigration::SetPresentationOrder( mpShape, nNewPos ); + break; + } + case WID_STYLE: + SetStyleSheet( aValue ); + break; + case WID_ISEMPTYPRESOBJ: + SetEmptyPresObj( ::cppu::any2bool(aValue) ); + break; + case WID_MASTERDEPEND: + SetMasterDepend( ::cppu::any2bool(aValue) ); + break; + + case WID_LEGACYFRAGMENT: + { + uno::Reference< io::XInputStream > xInputStream; + aValue >>= xInputStream; + if( xInputStream.is() ) + { + SvInputStream aStream( xInputStream ); + SdrObject* pObject = mpShape->GetSdrObject(); + SvxMSDffManager::ReadObjText( aStream, pObject ); + } + } + break; + + case WID_ANIMPATH: + { + uno::Reference< drawing::XShape > xShape( aValue, uno::UNO_QUERY ); + SdrPathObj* pObj2 = xShape.is() ? dynamic_cast<SdrPathObj*>(SdrObject::getSdrObjectFromXShape(xShape)) : nullptr; + + if( pObj2 == nullptr ) + throw lang::IllegalArgumentException(); + + EffectMigration::SetAnimationPath( mpShape, pObj2 ); + break; + } + case WID_IMAGEMAP: + { + SdDrawDocument* pDoc = mpModel?mpModel->GetDoc():nullptr; + if( pDoc ) + { + ImageMap aImageMap; + uno::Reference< uno::XInterface > xImageMap; + aValue >>= xImageMap; + + if( !xImageMap.is() || !SvUnoImageMap_fillImageMap( xImageMap, aImageMap ) ) + throw lang::IllegalArgumentException(); + + SvxIMapInfo* pIMapInfo = SvxIMapInfo::GetIMapInfo(pObj); + if( pIMapInfo ) + { + // replace existing image map + pIMapInfo->SetImageMap( aImageMap ); + } + else + { + // insert new user data with image map + pObj->AppendUserData(std::unique_ptr<SdrObjUserData>(new SvxIMapInfo(aImageMap) )); + } + } + } + break; + } + } + } + else + { + mpShape->_setPropertyValue(aPropertyName, aValue); + } + + if( mpModel ) + mpModel->SetModified(); +} + +css::uno::Any SAL_CALL SdXShape::getPropertyValue( const OUString& PropertyName ) +{ + SolarMutexGuard aGuard; + + uno::Any aRet; + + const SfxItemPropertyMapEntry* pEntry = mpPropSet->getPropertyMapEntry(PropertyName); + + if( pEntry && mpShape->GetSdrObject() ) + { + SdAnimationInfo* pInfo = GetAnimationInfo(); + + switch(pEntry->nWID) + { + case WID_NAVORDER: + { + const sal_uInt32 nNavOrder = mpShape->GetSdrObject()->GetNavigationPosition(); + aRet <<= nNavOrder == SAL_MAX_UINT32 ? static_cast<sal_Int32>(-1) : static_cast< sal_Int32 >(nNavOrder); + } + break; + case WID_EFFECT: + aRet <<= EffectMigration::GetAnimationEffect( mpShape ); + break; + case WID_TEXTEFFECT: + aRet <<= EffectMigration::GetTextAnimationEffect( mpShape ); + break; + case WID_ISPRESOBJ: + aRet <<= IsPresObj(); + break; + case WID_ISEMPTYPRESOBJ: + aRet <<= IsEmptyPresObj(); + break; + case WID_MASTERDEPEND: + aRet <<= IsMasterDepend(); + break; + case WID_SPEED: + aRet <<= EffectMigration::GetAnimationSpeed( mpShape ); + break; + case WID_ISANIMATION: + aRet <<= (pInfo && pInfo->mbIsMovie); + break; + case WID_PLACEHOLDERTEXT: + aRet <<= GetPlaceholderText(); + break; + case WID_BOOKMARK: + { + OUString aString; + SdDrawDocument* pDoc = mpModel ? mpModel->GetDoc() : nullptr; + if (pInfo && pDoc) + { + // is the bookmark a page? + bool bIsMasterPage; + if(pDoc->GetPageByName( pInfo->GetBookmark(), bIsMasterPage ) != SDRPAGE_NOTFOUND) + { + aString = SdDrawPage::getPageApiNameFromUiName( pInfo->GetBookmark() ); + } + else + { + aString = pInfo->GetBookmark() ; + sal_Int32 nPos = aString.lastIndexOf( '#' ); + if( nPos >= 0 ) + { + OUString aURL( aString.copy( 0, nPos+1 ) ); + OUString aName( aString.copy( nPos+1 ) ); + if(pDoc->GetPageByName( aName, bIsMasterPage ) != SDRPAGE_NOTFOUND) + { + aURL += SdDrawPage::getPageApiNameFromUiName( aName ); + aString = aURL; + } + } + } + } + + aRet <<= aString; + break; + } + case WID_CLICKACTION: + aRet <<= ( pInfo?pInfo->meClickAction:presentation::ClickAction_NONE ); + break; + case WID_PLAYFULL: + aRet <<= ( pInfo && pInfo->mbPlayFull ); + break; + case WID_SOUNDFILE: + aRet <<= EffectMigration::GetSoundFile( mpShape ); + break; + case WID_SOUNDON: + aRet <<= EffectMigration::GetSoundOn( mpShape ); + break; + case WID_BLUESCREEN: + aRet <<= pInfo ? pInfo->maBlueScreen : Color(0x00ffffff); + break; + case WID_VERB: + aRet <<= static_cast<sal_Int32>( pInfo?pInfo->mnVerb:0 ); + break; + case WID_DIMCOLOR: + aRet <<= EffectMigration::GetDimColor( mpShape ); + break; + case WID_DIMHIDE: + aRet <<= EffectMigration::GetDimHide( mpShape ); + break; + case WID_DIMPREV: + aRet <<= EffectMigration::GetDimPrevious( mpShape ); + break; + case WID_PRESORDER: + aRet <<= EffectMigration::GetPresentationOrder( mpShape ); + break; + case WID_STYLE: + aRet = GetStyleSheet(); + break; + case WID_IMAGEMAP: + { + uno::Reference< uno::XInterface > xImageMap; + + SdDrawDocument* pDoc = mpModel?mpModel->GetDoc():nullptr; + if( pDoc ) + { + + SvxIMapInfo* pIMapInfo = SvxIMapInfo::GetIMapInfo(mpShape->GetSdrObject()); + if( pIMapInfo ) + { + const ImageMap& rIMap = pIMapInfo->GetImageMap(); + xImageMap = SvUnoImageMap_createInstance( rIMap, ImplGetSupportedMacroItems() ); + } + else + { + xImageMap = SvUnoImageMap_createInstance(); + } + } + + aRet <<= uno::Reference< container::XIndexContainer >::query( xImageMap ); + break; + } + } + } + else + { + aRet = mpShape->_getPropertyValue(PropertyName); + } + + return aRet; +} + +/** */ +SdAnimationInfo* SdXShape::GetAnimationInfo( bool bCreate ) const +{ + SdAnimationInfo* pInfo = nullptr; + + SdrObject* pObj = mpShape->GetSdrObject(); + if(pObj) + pInfo = SdDrawDocument::GetShapeUserData(*pObj, bCreate); + + return pInfo; +} + +uno::Sequence< OUString > SAL_CALL SdXShape::getSupportedServiceNames() +{ + std::vector<std::u16string_view> aAdd{ u"com.sun.star.presentation.Shape", + u"com.sun.star.document.LinkTarget" }; + + SdrObject* pObj = mpShape->GetSdrObject(); + if(pObj && pObj->GetObjInventor() == SdrInventor::Default ) + { + SdrObjKind nInventor = pObj->GetObjIdentifier(); + switch( nInventor ) + { + case SdrObjKind::TitleText: + aAdd.emplace_back(u"com.sun.star.presentation.TitleTextShape"); + break; + case SdrObjKind::OutlineText: + aAdd.emplace_back(u"com.sun.star.presentation.OutlinerShape"); + break; + default: ; + } + } + return comphelper::concatSequences(mpShape->_getSupportedServiceNames(), aAdd); +} + +/** checks if this is a presentation object + */ +bool SdXShape::IsPresObj() const +{ + SdrObject* pObj = mpShape->GetSdrObject(); + if(pObj) + { + SdPage* pPage = dynamic_cast<SdPage* >(pObj->getSdrPageFromSdrObject()); + if(pPage) + return pPage->GetPresObjKind(pObj) != PresObjKind::NONE; + } + return false; +} + +/** checks if this presentation object is empty + */ +bool SdXShape::IsEmptyPresObj() const +{ + SdrObject* pObj = mpShape->GetSdrObject(); + if( (pObj != nullptr) && pObj->IsEmptyPresObj() ) + { + // check if the object is in edit, then if it's temporarily not empty + SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >( pObj ); + if( pTextObj == nullptr ) + return true; + + return !pTextObj->CanCreateEditOutlinerParaObject(); + } + + return false; +} + +OUString SdXShape::GetPlaceholderText() const +{ + // only possible if this actually *is* a presentation object + if( !IsPresObj() ) + return OUString(); + + SdrObject* pObj = mpShape->GetSdrObject(); + if( pObj == nullptr ) + return OUString(); + + SdPage* pPage = dynamic_cast< SdPage* >(pObj->getSdrPageFromSdrObject()); + DBG_ASSERT( pPage, "no page?" ); + if( pPage == nullptr ) + return OUString(); + + return pPage->GetPresObjText( pPage->GetPresObjKind(pObj) ); +} + +/** sets/reset the empty status of a presentation object +*/ +void SdXShape::SetEmptyPresObj(bool bEmpty) +{ + // only possible if this actually *is* a presentation object + if( !IsPresObj() ) + return; + + SdrObject* pObj = mpShape->GetSdrObject(); + if( pObj == nullptr ) + return; + + if( pObj->IsEmptyPresObj() == bEmpty ) + return; + + if(!bEmpty) + { + OutlinerParaObject* pOutlinerParaObject = pObj->GetOutlinerParaObject(); + const bool bVertical = pOutlinerParaObject && pOutlinerParaObject->IsEffectivelyVertical(); + + // really delete SdrOutlinerObj at pObj + pObj->NbcSetOutlinerParaObject(std::nullopt); + if( bVertical ) + if (auto pTextObj = dynamic_cast<SdrTextObj*>( pObj ) ) + pTextObj->SetVerticalWriting( true ); + + SdrGrafObj* pGraphicObj = dynamic_cast<SdrGrafObj*>( pObj ); + if( pGraphicObj ) + { + Graphic aEmpty; + pGraphicObj->SetGraphic(aEmpty); + } + else + { + SdrOle2Obj* pOleObj = dynamic_cast< SdrOle2Obj* >( pObj ); + if( pOleObj ) + { + pOleObj->ClearGraphic(); + } + } + } + else + { + // now set an empty OutlinerParaObject at pObj without + // any content but with the style of the old OutlinerParaObjects + // first paragraph + do + { + SdDrawDocument* pDoc = mpModel?mpModel->GetDoc():nullptr; + DBG_ASSERT( pDoc, "no document?" ); + if( pDoc == nullptr) + break; + + SdOutliner* pOutliner = pDoc->GetInternalOutliner(); + DBG_ASSERT( pOutliner, "no outliner?" ); + if( pOutliner == nullptr ) + break; + + SdPage* pPage = dynamic_cast< SdPage* >(pObj->getSdrPageFromSdrObject()); + DBG_ASSERT( pPage, "no page?" ); + if( pPage == nullptr ) + break; + + OutlinerParaObject* pOutlinerParaObject = pObj->GetOutlinerParaObject(); + pOutliner->SetText( *pOutlinerParaObject ); + const bool bVertical = pOutliner->IsVertical(); + + pOutliner->Clear(); + pOutliner->SetVertical( bVertical ); + pOutliner->SetStyleSheetPool( static_cast<SfxStyleSheetPool*>(pDoc->GetStyleSheetPool()) ); + pOutliner->SetStyleSheet( 0, pPage->GetTextStyleSheetForObject( pObj ) ); + pOutliner->Insert( pPage->GetPresObjText( pPage->GetPresObjKind(pObj) ) ); + pObj->SetOutlinerParaObject( pOutliner->CreateParaObject() ); + pOutliner->Clear(); + } + while(false); + } + + pObj->SetEmptyPresObj(bEmpty); +} + +bool SdXShape::IsMasterDepend() const noexcept +{ + SdrObject* pObj = mpShape->GetSdrObject(); + return pObj && pObj->GetUserCall() != nullptr; +} + +void SdXShape::SetMasterDepend( bool bDepend ) noexcept +{ + if( IsMasterDepend() == bDepend ) + return; + + SdrObject* pObj = mpShape->GetSdrObject(); + if( pObj ) + { + if( bDepend ) + { + SdPage* pPage = dynamic_cast< SdPage* >(pObj->getSdrPageFromSdrObject()); + pObj->SetUserCall( pPage ); + } + else + { + pObj->SetUserCall( nullptr ); + } + } +} + +void SdXShape::SetStyleSheet( const uno::Any& rAny ) +{ + SdrObject* pObj = mpShape->GetSdrObject(); + if( pObj == nullptr ) + throw beans::UnknownPropertyException(); + + uno::Reference< style::XStyle > xStyle( rAny, uno::UNO_QUERY ); + SfxStyleSheet* pStyleSheet = SfxUnoStyleSheet::getUnoStyleSheet( xStyle ); + + const SfxStyleSheet* pOldStyleSheet = pObj->GetStyleSheet(); + if( pOldStyleSheet == pStyleSheet ) + return; + + if( pStyleSheet == nullptr || (pStyleSheet->GetFamily() != SfxStyleFamily::Para && pStyleSheet->GetFamily() != SfxStyleFamily::Page) ) + throw lang::IllegalArgumentException(); + + pObj->SetStyleSheet( pStyleSheet, false ); + + SdDrawDocument* pDoc = mpModel? mpModel->GetDoc() : nullptr; + if( pDoc ) + { + ::sd::DrawDocShell* pDocSh = pDoc->GetDocSh(); + ::sd::ViewShell* pViewSh = pDocSh ? pDocSh->GetViewShell() : nullptr; + + if( pViewSh ) + pViewSh->GetViewFrame()->GetBindings().Invalidate( SID_STYLE_FAMILY2 ); + } +} + +uno::Any SdXShape::GetStyleSheet() const +{ + SdrObject* pObj = mpShape->GetSdrObject(); + if( pObj == nullptr ) + throw beans::UnknownPropertyException(); + + SfxStyleSheet* pStyleSheet = pObj->GetStyleSheet(); + // it is possible for shapes inside a draw to have a presentation style + // but we don't want this for the api + if( (pStyleSheet == nullptr) || ((pStyleSheet->GetFamily() != SfxStyleFamily::Para) && !mpModel->IsImpressDocument()) ) + return Any(); + + return Any( uno::Reference< style::XStyle >( dynamic_cast< SfxUnoStyleSheet* >( pStyleSheet ) ) ); +} + +class SdUnoEventsAccess : public cppu::WeakImplHelper< css::container::XNameReplace, css::lang::XServiceInfo > +{ +private: + SdXShape* mpShape; + +public: + explicit SdUnoEventsAccess(SdXShape* pShape) noexcept; + + // XNameReplace + virtual void SAL_CALL replaceByName( const OUString& aName, const css::uno::Any& aElement ) override; + + // 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; + + // XElementAccess + virtual css::uno::Type SAL_CALL getElementType( ) override; + virtual sal_Bool SAL_CALL hasElements( ) 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; +}; + +// XEventsSupplier +uno::Reference< container::XNameReplace > SAL_CALL SdXShape::getEvents( ) +{ + return new SdUnoEventsAccess( this ); +} + +constexpr OUStringLiteral gaStrOnClick( u"OnClick" ); +constexpr OUStringLiteral gaStrServiceName( u"com.sun.star.documents.Events" ); +constexpr OUStringLiteral gaStrEventType( u"EventType" ); +constexpr OUStringLiteral gaStrPresentation( u"Presentation" ); +constexpr OUStringLiteral gaStrLibrary(u"Library"); +constexpr OUStringLiteral gaStrMacroName(u"MacroName"); +constexpr OUStringLiteral gaStrClickAction( u"ClickAction" ); +constexpr OUStringLiteral gaStrBookmark( u"Bookmark" ); +constexpr OUStringLiteral gaStrEffect( u"Effect" ); +constexpr OUStringLiteral gaStrPlayFull( u"PlayFull" ); +constexpr OUStringLiteral gaStrVerb( u"Verb" ); +constexpr OUStringLiteral gaStrSoundURL( u"SoundURL" ); +constexpr OUStringLiteral gaStrSpeed( u"Speed" ); +constexpr OUStringLiteral gaStrStarBasic( u"StarBasic" ); +constexpr OUStringLiteral gaStrScript( u"Script" ); + +SdUnoEventsAccess::SdUnoEventsAccess( SdXShape* pShape ) noexcept + : mpShape( pShape ) +{ +} + +namespace { + +enum class FoundFlags { + NONE = 0x0000, + ClickAction = 0x0001, + Bookmark = 0x0002, + Effect = 0x0004, + PlayFull = 0x0008, + Verb = 0x0010, + SoundUrl = 0x0020, + Speed = 0x0040, + EventType = 0x0080, + Macro = 0x0100, + Library = 0x0200, +}; + +} + +namespace o3tl { + template<> struct typed_flags<FoundFlags> : is_typed_flags<FoundFlags, 0x03ff> {}; +} + +static void clearEventsInAnimationInfo( SdAnimationInfo* pInfo ) +{ + pInfo->SetBookmark( "" ); + pInfo->mbSecondSoundOn = false; + pInfo->mbSecondPlayFull = false; + pInfo->meClickAction = presentation::ClickAction_NONE; + pInfo->meSecondEffect = presentation::AnimationEffect_NONE; + pInfo->meSecondSpeed = presentation::AnimationSpeed_MEDIUM; + pInfo->mnVerb = 0; +} + +// XNameReplace +void SAL_CALL SdUnoEventsAccess::replaceByName( const OUString& aName, const uno::Any& aElement ) +{ + if( mpShape == nullptr || aName != gaStrOnClick ) + throw container::NoSuchElementException(); + + uno::Sequence< beans::PropertyValue > aProperties; + if( !aElement.hasValue() || aElement.getValueType() != getElementType() || !(aElement >>= aProperties) ) + throw lang::IllegalArgumentException(); + + FoundFlags nFound = FoundFlags::NONE; + + OUString aStrEventType; + presentation::ClickAction eClickAction = presentation::ClickAction_NONE; + presentation::AnimationEffect eEffect = presentation::AnimationEffect_NONE; + presentation::AnimationSpeed eSpeed = presentation::AnimationSpeed_MEDIUM; + OUString aStrSoundURL; + bool bPlayFull = false; + sal_Int32 nVerb = 0; + OUString aStrMacro; + OUString aStrLibrary; + OUString aStrBookmark; + + for( const beans::PropertyValue& rProperty : std::as_const(aProperties) ) + { + if( !( nFound & FoundFlags::EventType ) && rProperty.Name == gaStrEventType ) + { + if( rProperty.Value >>= aStrEventType ) + { + nFound |= FoundFlags::EventType; + continue; + } + } + else if( !( nFound & FoundFlags::ClickAction ) && rProperty.Name == gaStrClickAction ) + { + if( rProperty.Value >>= eClickAction ) + { + nFound |= FoundFlags::ClickAction; + continue; + } + } + else if( !( nFound & FoundFlags::Macro ) && ( rProperty.Name == gaStrMacroName || rProperty.Name == gaStrScript ) ) + { + if( rProperty.Value >>= aStrMacro ) + { + nFound |= FoundFlags::Macro; + continue; + } + } + else if( !( nFound & FoundFlags::Library ) && rProperty.Name == gaStrLibrary ) + { + if( rProperty.Value >>= aStrLibrary ) + { + nFound |= FoundFlags::Library; + continue; + } + } + else if( !( nFound & FoundFlags::Effect ) && rProperty.Name == gaStrEffect ) + { + if( rProperty.Value >>= eEffect ) + { + nFound |= FoundFlags::Effect; + continue; + } + } + else if( !( nFound & FoundFlags::Bookmark ) && rProperty.Name == gaStrBookmark ) + { + if( rProperty.Value >>= aStrBookmark ) + { + nFound |= FoundFlags::Bookmark; + continue; + } + } + else if( !( nFound & FoundFlags::Speed ) && rProperty.Name == gaStrSpeed ) + { + if( rProperty.Value >>= eSpeed ) + { + nFound |= FoundFlags::Speed; + continue; + } + } + else if( !( nFound & FoundFlags::SoundUrl ) && rProperty.Name == gaStrSoundURL ) + { + if( rProperty.Value >>= aStrSoundURL ) + { + nFound |= FoundFlags::SoundUrl; + continue; + } + } + else if( !( nFound & FoundFlags::PlayFull ) && rProperty.Name == gaStrPlayFull ) + { + if( rProperty.Value >>= bPlayFull ) + { + nFound |= FoundFlags::PlayFull; + continue; + } + } + else if( !( nFound & FoundFlags::Verb ) && rProperty.Name == gaStrVerb ) + { + if( rProperty.Value >>= nVerb ) + { + nFound |= FoundFlags::Verb; + continue; + } + } + + throw lang::IllegalArgumentException(); + } + + bool bOk = false; + do + { + if( !( nFound & FoundFlags::EventType ) ) + break; + + if( aStrEventType == gaStrPresentation ) + { + if( !( nFound & FoundFlags::ClickAction ) ) + break; + + SdAnimationInfo* pInfo = mpShape->GetAnimationInfo(); + if( presentation::ClickAction_NONE == eClickAction && nullptr == pInfo ) + { + bOk = true; + break; + } + + if( nullptr == pInfo ) + pInfo = mpShape->GetAnimationInfo( true ); + + DBG_ASSERT( pInfo, "shape animation info could not be created!" ); + if( nullptr == pInfo ) + break; + + clearEventsInAnimationInfo( pInfo ); + pInfo->meClickAction = eClickAction; + + switch( eClickAction ) + { + case presentation::ClickAction_NONE: + case presentation::ClickAction_PREVPAGE: + case presentation::ClickAction_NEXTPAGE: + case presentation::ClickAction_FIRSTPAGE: + case presentation::ClickAction_LASTPAGE: + case presentation::ClickAction_INVISIBLE: + case presentation::ClickAction_STOPPRESENTATION: + { + bOk = true; + } + break; + + case presentation::ClickAction_PROGRAM: + case presentation::ClickAction_BOOKMARK: + case presentation::ClickAction_DOCUMENT: + if( nFound & FoundFlags::Bookmark ) + { + if( eClickAction == presentation::ClickAction_BOOKMARK ) + { + aStrBookmark = getUiNameFromPageApiNameImpl( aStrBookmark ); + } + else if( eClickAction == presentation::ClickAction_DOCUMENT ) + { + sal_Int32 nPos = aStrBookmark.lastIndexOf( '#' ); + if( nPos >= 0 ) + { + OUString aURL = aStrBookmark.subView( 0, nPos+1 ) + + getUiNameFromPageApiNameImpl( aStrBookmark.copy( nPos+1 ) ); + aStrBookmark = aURL; + } + } + + pInfo->SetBookmark( aStrBookmark ); + bOk = true; + } + break; + + case presentation::ClickAction_MACRO: + if( nFound & FoundFlags::Macro ) + { + pInfo->SetBookmark( aStrMacro ); + bOk = true; + } + break; + + case presentation::ClickAction_VERB: + if( nFound & FoundFlags::Verb ) + { + pInfo->mnVerb = static_cast<sal_uInt16>(nVerb); + bOk = true; + } + break; + + case presentation::ClickAction_VANISH: + if( !( nFound & FoundFlags::Effect ) ) + break; + + pInfo->meSecondEffect = eEffect; + pInfo->meSecondSpeed = nFound & FoundFlags::Speed ? eSpeed : presentation::AnimationSpeed_MEDIUM; + + bOk = true; + + [[fallthrough]]; + + case presentation::ClickAction_SOUND: + if( nFound & FoundFlags::SoundUrl ) + { + pInfo->SetBookmark( aStrSoundURL ); + if( eClickAction != presentation::ClickAction_SOUND ) + pInfo->mbSecondSoundOn = !aStrSoundURL.isEmpty(); + pInfo->mbSecondPlayFull = (nFound & FoundFlags::PlayFull) && bPlayFull; + + bOk = true; + } + break; + default: + break; + } + } + else + { + SdAnimationInfo* pInfo = mpShape->GetAnimationInfo( true ); + + DBG_ASSERT( pInfo, "shape animation info could not be created!" ); + if( nullptr == pInfo ) + break; + + clearEventsInAnimationInfo( pInfo ); + pInfo->meClickAction = presentation::ClickAction_MACRO; + + if ( SfxApplication::IsXScriptURL( aStrMacro ) ) + { + pInfo->SetBookmark( aStrMacro ); + } + else + { + sal_Int32 nIdx{ 0 }; + const std::u16string_view aLibName = o3tl::getToken(aStrMacro, 0, '.', nIdx); + const std::u16string_view aModulName = o3tl::getToken(aStrMacro, 0, '.', nIdx); + const std::u16string_view aMacroName = o3tl::getToken(aStrMacro, 0, '.', nIdx); + + OUStringBuffer sBuffer( + OUString::Concat(aMacroName) + OUStringChar('.') + aModulName + OUStringChar('.') + aLibName + OUStringChar('.') ); + + if ( aStrLibrary == "StarOffice" ) + { + sBuffer.append( "BASIC" ); + } + else + { + sBuffer.append( aStrLibrary ); + } + + pInfo->SetBookmark( sBuffer.makeStringAndClear() ); + } + bOk = true; + } + } + while(false); + + if( !bOk ) + throw lang::IllegalArgumentException(); +} + +// XNameAccess +uno::Any SAL_CALL SdUnoEventsAccess::getByName( const OUString& aName ) +{ + if( mpShape == nullptr || aName != gaStrOnClick ) + throw container::NoSuchElementException(); + + SdAnimationInfo* pInfo = mpShape->GetAnimationInfo(); + + presentation::ClickAction eClickAction = presentation::ClickAction_NONE; + if( pInfo ) + eClickAction = pInfo->meClickAction; + + sal_Int32 nPropertyCount = 2; + switch( eClickAction ) + { + case presentation::ClickAction_NONE: + case presentation::ClickAction_PREVPAGE: + case presentation::ClickAction_NEXTPAGE: + case presentation::ClickAction_FIRSTPAGE: + case presentation::ClickAction_LASTPAGE: + case presentation::ClickAction_INVISIBLE: + case presentation::ClickAction_STOPPRESENTATION: + break; + case presentation::ClickAction_PROGRAM: + case presentation::ClickAction_VERB: + case presentation::ClickAction_BOOKMARK: + case presentation::ClickAction_DOCUMENT: + case presentation::ClickAction_MACRO: + if ( !SfxApplication::IsXScriptURL( pInfo->GetBookmark() ) ) + nPropertyCount += 1; + break; + + case presentation::ClickAction_SOUND: + nPropertyCount += 2; + break; + + case presentation::ClickAction_VANISH: + nPropertyCount += 4; + break; + default: + break; + } + + uno::Sequence< beans::PropertyValue > aProperties( nPropertyCount ); + beans::PropertyValue* pProperties = aProperties.getArray(); + + uno::Any aAny; + + if( eClickAction == presentation::ClickAction_MACRO ) + { + if ( SfxApplication::IsXScriptURL( pInfo->GetBookmark() ) ) + { + // Scripting Framework URL + aAny <<= OUString(gaStrScript); + pProperties->Name = gaStrEventType; + pProperties->Handle = -1; + pProperties->Value = aAny; + pProperties->State = beans::PropertyState_DIRECT_VALUE; + pProperties++; + + aAny <<= pInfo->GetBookmark(); + pProperties->Name = gaStrScript; + pProperties->Handle = -1; + pProperties->Value = aAny; + pProperties->State = beans::PropertyState_DIRECT_VALUE; + pProperties++; + } + else + { + // Old Basic macro URL + aAny <<= OUString(gaStrStarBasic); + pProperties->Name = gaStrEventType; + pProperties->Handle = -1; + pProperties->Value = aAny; + pProperties->State = beans::PropertyState_DIRECT_VALUE; + pProperties++; + + OUString aMacro = pInfo->GetBookmark(); + + // aMacro has got following format: + // "Macroname.Modulname.Libname.Documentname" or + // "Macroname.Modulname.Libname.Applicationname" + sal_Int32 nIdx{ 0 }; + const std::u16string_view aMacroName = o3tl::getToken(aMacro, 0, '.', nIdx); + const std::u16string_view aModulName = o3tl::getToken(aMacro, 0, '.', nIdx); + const std::u16string_view aLibName = o3tl::getToken(aMacro, 0, '.', nIdx); + + OUString sBuffer = OUString::Concat(aLibName) + + "." + + aModulName + + "." + + aMacroName; + + aAny <<= sBuffer; + pProperties->Name = gaStrMacroName; + pProperties->Handle = -1; + pProperties->Value = aAny; + pProperties->State = beans::PropertyState_DIRECT_VALUE; + pProperties++; + + aAny <<= OUString( "StarOffice" ); + pProperties->Name = gaStrLibrary; + pProperties->Handle = -1; + pProperties->Value = aAny; + pProperties->State = beans::PropertyState_DIRECT_VALUE; + } + } + else + { + aAny <<= OUString(gaStrPresentation); + pProperties->Name = gaStrEventType; + pProperties->Handle = -1; + pProperties->Value = aAny; + pProperties->State = beans::PropertyState_DIRECT_VALUE; + pProperties++; + + aAny <<= eClickAction; + pProperties->Name = gaStrClickAction; + pProperties->Handle = -1; + pProperties->Value = aAny; + pProperties->State = beans::PropertyState_DIRECT_VALUE; + pProperties++; + + switch( eClickAction ) + { + case presentation::ClickAction_NONE: + case presentation::ClickAction_PREVPAGE: + case presentation::ClickAction_NEXTPAGE: + case presentation::ClickAction_FIRSTPAGE: + case presentation::ClickAction_LASTPAGE: + case presentation::ClickAction_INVISIBLE: + case presentation::ClickAction_STOPPRESENTATION: + break; + case presentation::ClickAction_BOOKMARK: + { + const OUString aStrBookmark( getPageApiNameFromUiName( pInfo->GetBookmark()) ); + pProperties->Name = gaStrBookmark; + pProperties->Handle = -1; + pProperties->Value <<= aStrBookmark; + pProperties->State = beans::PropertyState_DIRECT_VALUE; + } + break; + + case presentation::ClickAction_DOCUMENT: + case presentation::ClickAction_PROGRAM: + { + OUString aString( pInfo->GetBookmark()); + sal_Int32 nPos = aString.lastIndexOf( '#' ); + if( nPos >= 0 ) + { + OUString aURL = aString.subView( 0, nPos+1 ) + + getPageApiNameFromUiName( aString.copy( nPos+1 ) ); + aString = aURL; + } + pProperties->Name = gaStrBookmark; + pProperties->Handle = -1; + pProperties->Value <<= aString; + pProperties->State = beans::PropertyState_DIRECT_VALUE; + } + break; + + case presentation::ClickAction_VANISH: + aAny <<= pInfo->meSecondEffect; + pProperties->Name = gaStrEffect; + pProperties->Handle = -1; + pProperties->Value = aAny; + pProperties->State = beans::PropertyState_DIRECT_VALUE; + pProperties++; + + aAny <<= pInfo->meSecondSpeed; + pProperties->Name = gaStrSpeed; + pProperties->Handle = -1; + pProperties->Value = aAny; + pProperties->State = beans::PropertyState_DIRECT_VALUE; + pProperties++; + + [[fallthrough]]; + + case presentation::ClickAction_SOUND: + if( eClickAction == presentation::ClickAction_SOUND || pInfo->mbSecondSoundOn ) + { + aAny <<= pInfo->GetBookmark(); + pProperties->Name = gaStrSoundURL; + pProperties->Handle = -1; + pProperties->Value = aAny; + pProperties->State = beans::PropertyState_DIRECT_VALUE; + pProperties++; + + pProperties->Name = gaStrPlayFull; + pProperties->Handle = -1; + pProperties->Value <<= pInfo->mbSecondPlayFull; + pProperties->State = beans::PropertyState_DIRECT_VALUE; + } + break; + + case presentation::ClickAction_VERB: + aAny <<= static_cast<sal_Int32>(pInfo->mnVerb); + pProperties->Name = gaStrVerb; + pProperties->Handle = -1; + pProperties->Value = aAny; + pProperties->State = beans::PropertyState_DIRECT_VALUE; + break; + default: + break; + } + } + + aAny <<= aProperties; + return aAny; +} + +uno::Sequence< OUString > SAL_CALL SdUnoEventsAccess::getElementNames( ) +{ + return { gaStrOnClick }; +} + +sal_Bool SAL_CALL SdUnoEventsAccess::hasByName( const OUString& aName ) +{ + return aName == gaStrOnClick; +} + +// XElementAccess +uno::Type SAL_CALL SdUnoEventsAccess::getElementType( ) +{ + return cppu::UnoType<uno::Sequence< beans::PropertyValue >>::get(); +} + +sal_Bool SAL_CALL SdUnoEventsAccess::hasElements( ) +{ + return true; +} + +// XServiceInfo +OUString SAL_CALL SdUnoEventsAccess::getImplementationName( ) +{ + return "SdUnoEventsAccess"; +} + +sal_Bool SAL_CALL SdUnoEventsAccess::supportsService( const OUString& ServiceName ) +{ + return cppu::supportsService(this, ServiceName); +} + +uno::Sequence< OUString > SAL_CALL SdUnoEventsAccess::getSupportedServiceNames( ) +{ + return { gaStrServiceName }; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/unoidl/unoobj.hxx b/sd/source/ui/unoidl/unoobj.hxx new file mode 100644 index 000000000..3f01cbed1 --- /dev/null +++ b/sd/source/ui/unoidl/unoobj.hxx @@ -0,0 +1,100 @@ +/* -*- 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/beans/PropertyState.hpp> +#include <com/sun/star/document/XEventsSupplier.hpp> +#include <svx/unomaster.hxx> + +namespace com::sun::star::beans { class XPropertySetInfo; } + +class SdXImpressDocument; +class SdAnimationInfo; +class SvxItemPropertySet; +class SvxShape; +struct SfxItemPropertyMapEntry; + +class SdXShape : public SvxShapeMaster, + public css::document::XEventsSupplier +{ + friend class SdUnoEventsAccess; + +private: + SvxShape* mpShape; + const SvxItemPropertySet* mpPropSet; + const SfxItemPropertyMapEntry* mpMap; + SdXImpressDocument* mpModel; + + /// @throws css::lang::IllegalArgumentException + /// @throws css::beans::UnknownPropertyException + /// @throws css::uno::RuntimeException + void SetStyleSheet( const css::uno::Any& rAny ); + /// @throws css::beans::UnknownPropertyException + css::uno::Any GetStyleSheet() const; + + // Intern + /// @throws std::exception + SdAnimationInfo* GetAnimationInfo( bool bCreate = false ) const; + /// @throws std::exception + bool IsPresObj() const; + + bool IsEmptyPresObj() const; + void SetEmptyPresObj(bool bEmpty); + + bool IsMasterDepend() const noexcept; + void SetMasterDepend( bool bDepend ) noexcept; + + OUString GetPlaceholderText() const; + +public: + SdXShape(SvxShape* pShape, SdXImpressDocument* pModel); + virtual ~SdXShape() noexcept; + + virtual bool queryAggregation( const css::uno::Type & rType, css::uno::Any& aAny ) override; + virtual void dispose() override; + + // XInterface + virtual css::uno::Any SAL_CALL queryInterface( const css::uno::Type & rType ) override; + virtual void SAL_CALL acquire() noexcept override; + virtual void SAL_CALL release() noexcept override; + + // XServiceInfo + virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override; + + //XPropertySet + 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; + + //XPropertyState + virtual css::beans::PropertyState SAL_CALL getPropertyState( const OUString& PropertyName ) override; + virtual void SAL_CALL setPropertyToDefault( const OUString& PropertyName ) override; + virtual css::uno::Any SAL_CALL getPropertyDefault( const OUString& aPropertyName ) override; + + // XTypeProvider + virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes( ) override; + + // XEventsSupplier + virtual css::uno::Reference< css::container::XNameReplace > SAL_CALL getEvents( ) override; +}; + +struct SvEventDescription; +const SvEventDescription* ImplGetSupportedMacroItems(); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/unoidl/unopage.cxx b/sd/source/ui/unoidl/unopage.cxx new file mode 100644 index 000000000..8a9549c51 --- /dev/null +++ b/sd/source/ui/unoidl/unopage.cxx @@ -0,0 +1,3056 @@ +/* -*- 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 <initializer_list> +#include <string_view> + +#include <com/sun/star/awt/XBitmap.hpp> +#include <com/sun/star/lang/DisposedException.hpp> +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> +#include <com/sun/star/presentation/FadeEffect.hpp> +#include <com/sun/star/presentation/AnimationSpeed.hpp> +#include <com/sun/star/view/PaperOrientation.hpp> +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <cppuhelper/implbase.hxx> +#include <comphelper/profilezone.hxx> +#include <comphelper/servicehelper.hxx> +#include <cppuhelper/supportsservice.hxx> +#include <rtl/ustrbuf.hxx> +#include <vcl/bitmapex.hxx> +#include <vcl/filter/SvmWriter.hxx> +#include <vcl/metaact.hxx> +#include <toolkit/helper/vclunohelper.hxx> +#include <tools/diagnose_ex.h> +#include <vcl/svapp.hxx> +#include <AnnotationEnumeration.hxx> +#include <createunopageimpl.hxx> +#include <unomodel.hxx> +#include <unopage.hxx> +#include <svl/itemset.hxx> +#include <svx/svdmodel.hxx> +#include <sdresid.hxx> +#include <strings.hrc> +#include <sdpage.hxx> +#include <unoprnms.hxx> +#include <drawdoc.hxx> +#include <svx/unoshape.hxx> +#include <svl/style.hxx> +#include <comphelper/extract.hxx> +#include <comphelper/sequence.hxx> +#include <svx/svditer.hxx> +#include <vcl/wmf.hxx> +#include <svx/svdoole2.hxx> +#include <svx/svdpool.hxx> +#include <svx/svdview.hxx> +#include <svx/xfillit0.hxx> +#include <DrawDocShell.hxx> +#include <ViewShell.hxx> +#include <DrawViewShell.hxx> +#include <editeng/unoprnms.hxx> +#include "unoobj.hxx" + +#include <strings.hxx> +#include <bitmaps.hlst> +#include <unokywds.hxx> +#include "unopback.hxx" +#include <vcl/dibtools.hxx> +#include <tools/debug.hxx> +#include <tools/stream.hxx> +#include <o3tl/string_view.hxx> + +using ::com::sun::star::animations::XAnimationNode; +using ::com::sun::star::animations::XAnimationNodeSupplier; + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::container; +using namespace ::com::sun::star::drawing; +using namespace ::com::sun::star::office; + +namespace { + +// this are the ids for page properties +enum WID_PAGE +{ + WID_PAGE_LEFT, WID_PAGE_RIGHT, WID_PAGE_TOP, WID_PAGE_BOTTOM, WID_PAGE_WIDTH, + WID_PAGE_HEIGHT, WID_PAGE_EFFECT, WID_PAGE_CHANGE, WID_PAGE_SPEED, WID_PAGE_NUMBER, + WID_PAGE_ORIENT, WID_PAGE_LAYOUT, WID_PAGE_DURATION, WID_PAGE_HIGHRESDURATION, WID_PAGE_LDNAME, WID_PAGE_LDBITMAP, + WID_PAGE_BACK, WID_PAGE_PREVIEW, WID_PAGE_PREVIEWBITMAP, WID_PAGE_VISIBLE, WID_PAGE_SOUNDFILE, WID_PAGE_BACKFULL, + WID_PAGE_BACKVIS, WID_PAGE_BACKOBJVIS, WID_PAGE_USERATTRIBS, WID_PAGE_BOOKMARK, WID_PAGE_ISDARK, + WID_PAGE_HEADERVISIBLE, WID_PAGE_HEADERTEXT, WID_PAGE_FOOTERVISIBLE, WID_PAGE_FOOTERTEXT, + WID_PAGE_PAGENUMBERVISIBLE, WID_PAGE_DATETIMEVISIBLE, WID_PAGE_DATETIMEFIXED, + WID_PAGE_DATETIMETEXT, WID_PAGE_DATETIMEFORMAT, WID_TRANSITION_TYPE, WID_TRANSITION_SUBTYPE, + WID_TRANSITION_DIRECTION, WID_TRANSITION_FADE_COLOR, WID_TRANSITION_DURATION, WID_LOOP_SOUND, + WID_NAVORDER, WID_PAGE_PREVIEWMETAFILE, WID_PAGE_THEME +}; + +} + +constexpr OUStringLiteral sEmptyPageName = u"page"; + +// this function stores the property maps for draw pages in impress and draw +static const SvxItemPropertySet* ImplGetDrawPagePropertySet( bool bImpress, PageKind ePageKind ) +{ + static const SfxItemPropertyMapEntry aDrawPagePropertyMap_Impl[] = + { + { u"" UNO_NAME_PAGE_BACKGROUND, WID_PAGE_BACK, cppu::UnoType<beans::XPropertySet>::get(), beans::PropertyAttribute::MAYBEVOID,0}, + { u"" UNO_NAME_PAGE_BOTTOM, WID_PAGE_BOTTOM, ::cppu::UnoType<sal_Int32>::get(), 0, 0}, + { u"" UNO_NAME_PAGE_LEFT, WID_PAGE_LEFT, ::cppu::UnoType<sal_Int32>::get(), 0, 0}, + { u"" UNO_NAME_PAGE_RIGHT, WID_PAGE_RIGHT, ::cppu::UnoType<sal_Int32>::get(), 0, 0}, + { u"" UNO_NAME_PAGE_TOP, WID_PAGE_TOP, ::cppu::UnoType<sal_Int32>::get(), 0, 0}, + { u"" UNO_NAME_PAGE_CHANGE, WID_PAGE_CHANGE, ::cppu::UnoType<sal_Int32>::get(), 0, 0}, + { u"" UNO_NAME_PAGE_DURATION, WID_PAGE_DURATION, ::cppu::UnoType<sal_Int32>::get(), 0, 0}, + { u"" UNO_NAME_PAGE_EFFECT, WID_PAGE_EFFECT, ::cppu::UnoType<presentation::FadeEffect>::get(), 0, 0}, + { u"" UNO_NAME_PAGE_HEIGHT, WID_PAGE_HEIGHT, ::cppu::UnoType<sal_Int32>::get(), 0, 0}, + { u"" UNO_NAME_PAGE_LAYOUT, WID_PAGE_LAYOUT, ::cppu::UnoType<sal_Int16>::get(), 0, 0}, + { UNO_NAME_LINKDISPLAYBITMAP, WID_PAGE_LDBITMAP, cppu::UnoType<awt::XBitmap>::get(), beans::PropertyAttribute::READONLY, 0}, + { UNO_NAME_LINKDISPLAYNAME, WID_PAGE_LDNAME, ::cppu::UnoType<OUString>::get(), beans::PropertyAttribute::READONLY, 0}, + { u"" UNO_NAME_PAGE_NUMBER, WID_PAGE_NUMBER, ::cppu::UnoType<sal_Int16>::get(), beans::PropertyAttribute::READONLY, 0}, + { u"" UNO_NAME_PAGE_ORIENTATION, WID_PAGE_ORIENT, ::cppu::UnoType<view::PaperOrientation>::get(),0, 0}, + { u"" UNO_NAME_PAGE_SPEED, WID_PAGE_SPEED, ::cppu::UnoType<presentation::AnimationSpeed>::get(), 0, 0}, + { u"" UNO_NAME_PAGE_WIDTH, WID_PAGE_WIDTH, ::cppu::UnoType<sal_Int32>::get(), 0, 0}, + { u"" UNO_NAME_PAGE_PREVIEW, WID_PAGE_PREVIEW, cppu::UnoType<css::uno::Sequence<sal_Int8>>::get(), css::beans::PropertyAttribute::READONLY, 0}, + { u"" UNO_NAME_PAGE_PREVIEWBITMAP, WID_PAGE_PREVIEWBITMAP, cppu::UnoType<css::uno::Sequence<sal_Int8>>::get(), css::beans::PropertyAttribute::READONLY, 0}, + { u"" UNO_NAME_PAGE_PREVIEWMETAFILE, WID_PAGE_PREVIEWMETAFILE, cppu::UnoType<css::uno::Sequence<sal_Int8>>::get(), css::beans::PropertyAttribute::READONLY, 0}, + { u"" UNO_NAME_PAGE_VISIBLE, WID_PAGE_VISIBLE, cppu::UnoType<bool>::get(), 0, 0}, + { u"" UNO_NAME_OBJ_SOUNDFILE, WID_PAGE_SOUNDFILE, cppu::UnoType<Any>::get(), 0, 0}, + { sUNO_Prop_IsBackgroundVisible, WID_PAGE_BACKVIS, cppu::UnoType<bool>::get(), 0, 0}, + { sUNO_Prop_IsBackgroundObjectsVisible, WID_PAGE_BACKOBJVIS, cppu::UnoType<bool>::get(), 0, 0}, + { sUNO_Prop_UserDefinedAttributes,WID_PAGE_USERATTRIBS, cppu::UnoType<css::container::XNameContainer>::get(), 0, 0}, + { sUNO_Prop_BookmarkURL, WID_PAGE_BOOKMARK, ::cppu::UnoType<OUString>::get(), 0, 0}, + { u"HighResDuration", WID_PAGE_HIGHRESDURATION, ::cppu::UnoType<double>::get(), 0, 0}, + { u"IsBackgroundDark" , WID_PAGE_ISDARK, cppu::UnoType<bool>::get(), beans::PropertyAttribute::READONLY, 0}, + { u"IsFooterVisible", WID_PAGE_FOOTERVISIBLE, cppu::UnoType<bool>::get(), 0, 0}, + { u"FooterText", WID_PAGE_FOOTERTEXT, ::cppu::UnoType<OUString>::get(), 0, 0}, + { u"IsPageNumberVisible", WID_PAGE_PAGENUMBERVISIBLE, cppu::UnoType<bool>::get(), 0, 0}, + { u"IsDateTimeVisible", WID_PAGE_DATETIMEVISIBLE, cppu::UnoType<bool>::get(), 0, 0}, + { u"IsDateTimeFixed", WID_PAGE_DATETIMEFIXED, cppu::UnoType<bool>::get(), 0, 0}, + { u"DateTimeText", WID_PAGE_DATETIMETEXT, ::cppu::UnoType<OUString>::get(), 0, 0}, + { u"DateTimeFormat", WID_PAGE_DATETIMEFORMAT, ::cppu::UnoType<sal_Int32>::get(), 0, 0}, + { u"TransitionType", WID_TRANSITION_TYPE, ::cppu::UnoType<sal_Int16>::get(), 0, 0}, + { u"TransitionSubtype", WID_TRANSITION_SUBTYPE, ::cppu::UnoType<sal_Int16>::get(), 0, 0}, + { u"TransitionDirection", WID_TRANSITION_DIRECTION, ::cppu::UnoType<sal_Bool>::get(), 0, 0}, + { u"TransitionFadeColor", WID_TRANSITION_FADE_COLOR, ::cppu::UnoType<sal_Int32>::get(), 0, 0}, + { u"" UNO_NAME_PAGE_TRANSITION_DURATION, WID_TRANSITION_DURATION, ::cppu::UnoType<double>::get(), 0, 0}, + { u"LoopSound", WID_LOOP_SOUND, cppu::UnoType<bool>::get(), 0, 0}, + { u"NavigationOrder", WID_NAVORDER, cppu::UnoType<css::container::XIndexAccess>::get(),0, 0}, + { u"", 0, css::uno::Type(), 0, 0 } + }; + +#define DRAW_PAGE_NOTES_PROPERTIES \ + { u"" UNO_NAME_PAGE_BOTTOM, WID_PAGE_BOTTOM, ::cppu::UnoType<sal_Int32>::get(), 0, 0}, \ + { u"" UNO_NAME_PAGE_LEFT, WID_PAGE_LEFT, ::cppu::UnoType<sal_Int32>::get(), 0, 0}, \ + { u"" UNO_NAME_PAGE_RIGHT, WID_PAGE_RIGHT, ::cppu::UnoType<sal_Int32>::get(), 0, 0}, \ + { u"" UNO_NAME_PAGE_TOP, WID_PAGE_TOP, ::cppu::UnoType<sal_Int32>::get(), 0, 0}, \ + { u"" UNO_NAME_PAGE_HEIGHT, WID_PAGE_HEIGHT, ::cppu::UnoType<sal_Int32>::get(), 0, 0}, \ + { u"" UNO_NAME_PAGE_LAYOUT, WID_PAGE_LAYOUT, ::cppu::UnoType<sal_Int16>::get(), 0, 0}, \ + { UNO_NAME_LINKDISPLAYBITMAP, WID_PAGE_LDBITMAP, cppu::UnoType<awt::XBitmap>::get(), beans::PropertyAttribute::READONLY, 0}, \ + { UNO_NAME_LINKDISPLAYNAME, WID_PAGE_LDNAME, ::cppu::UnoType<OUString>::get(), beans::PropertyAttribute::READONLY, 0}, \ + { u"" UNO_NAME_PAGE_NUMBER, WID_PAGE_NUMBER, ::cppu::UnoType<sal_Int16>::get(), beans::PropertyAttribute::READONLY, 0}, \ + { u"" UNO_NAME_PAGE_ORIENTATION, WID_PAGE_ORIENT, ::cppu::UnoType<view::PaperOrientation>::get(),0, 0}, \ + { u"" UNO_NAME_PAGE_WIDTH, WID_PAGE_WIDTH, ::cppu::UnoType<sal_Int32>::get(), 0, 0}, \ + { sUNO_Prop_UserDefinedAttributes,WID_PAGE_USERATTRIBS, cppu::UnoType<css::container::XNameContainer>::get(), 0, 0},\ + { u"IsHeaderVisible", WID_PAGE_HEADERVISIBLE, cppu::UnoType<bool>::get(), 0, 0}, \ + { u"HeaderText", WID_PAGE_HEADERTEXT, ::cppu::UnoType<OUString>::get(), 0, 0}, \ + { u"IsBackgroundDark", WID_PAGE_ISDARK, cppu::UnoType<bool>::get(), beans::PropertyAttribute::READONLY, 0}, \ + { u"IsFooterVisible", WID_PAGE_FOOTERVISIBLE, cppu::UnoType<bool>::get(), 0, 0}, \ + { u"FooterText", WID_PAGE_FOOTERTEXT, ::cppu::UnoType<OUString>::get(), 0, 0}, \ + { u"IsPageNumberVisible", WID_PAGE_PAGENUMBERVISIBLE, cppu::UnoType<bool>::get(), 0, 0}, \ + { u"IsDateTimeVisible", WID_PAGE_DATETIMEVISIBLE, cppu::UnoType<bool>::get(), 0, 0}, \ + { u"IsDateTimeFixed", WID_PAGE_DATETIMEFIXED, cppu::UnoType<bool>::get(), 0, 0}, \ + { u"DateTimeText", WID_PAGE_DATETIMETEXT, ::cppu::UnoType<OUString>::get(), 0, 0}, \ + { u"DateTimeFormat", WID_PAGE_DATETIMEFORMAT, ::cppu::UnoType<sal_Int32>::get(), 0, 0}, \ + { u"NavigationOrder", WID_NAVORDER, cppu::UnoType<css::container::XIndexAccess>::get(),0, 0}, \ + { u"", 0, css::uno::Type(), 0, 0 } + + static const SfxItemPropertyMapEntry aDrawPageNotesHandoutPropertyMap_Impl[] = + { + // this must be the first two entries so they can be excluded for PageKind::Standard + { u"" UNO_NAME_PAGE_BACKGROUND, WID_PAGE_BACK, cppu::UnoType<beans::XPropertySet>::get(), beans::PropertyAttribute::MAYBEVOID,0}, + DRAW_PAGE_NOTES_PROPERTIES + }; + static const SfxItemPropertyMapEntry aDrawPageNotesHandoutPropertyNoBackMap_Impl[] = + { + DRAW_PAGE_NOTES_PROPERTIES + }; + +#define GRAPHIC_PAGE_PROPERTIES \ + { u"" UNO_NAME_PAGE_BOTTOM, WID_PAGE_BOTTOM, ::cppu::UnoType<sal_Int32>::get(), 0, 0}, \ + { u"" UNO_NAME_PAGE_LEFT, WID_PAGE_LEFT, ::cppu::UnoType<sal_Int32>::get(), 0, 0}, \ + { u"" UNO_NAME_PAGE_RIGHT, WID_PAGE_RIGHT, ::cppu::UnoType<sal_Int32>::get(), 0, 0}, \ + { u"" UNO_NAME_PAGE_TOP, WID_PAGE_TOP, ::cppu::UnoType<sal_Int32>::get(), 0, 0}, \ + { u"" UNO_NAME_PAGE_HEIGHT, WID_PAGE_HEIGHT, ::cppu::UnoType<sal_Int32>::get(), 0, 0}, \ + { UNO_NAME_LINKDISPLAYBITMAP, WID_PAGE_LDBITMAP, cppu::UnoType<awt::XBitmap>::get(), beans::PropertyAttribute::READONLY, 0}, \ + { UNO_NAME_LINKDISPLAYNAME, WID_PAGE_LDNAME, ::cppu::UnoType<OUString>::get(), beans::PropertyAttribute::READONLY, 0}, \ + { u"" UNO_NAME_PAGE_NUMBER, WID_PAGE_NUMBER, ::cppu::UnoType<sal_Int16>::get(), beans::PropertyAttribute::READONLY, 0}, \ + { u"" UNO_NAME_PAGE_ORIENTATION, WID_PAGE_ORIENT, ::cppu::UnoType<view::PaperOrientation>::get(),0, 0}, \ + { u"" UNO_NAME_PAGE_WIDTH, WID_PAGE_WIDTH, ::cppu::UnoType<sal_Int32>::get(), 0, 0}, \ + { u"" UNO_NAME_PAGE_PREVIEW, WID_PAGE_PREVIEW, cppu::UnoType<css::uno::Sequence<sal_Int8>>::get(), css::beans::PropertyAttribute::READONLY, 0}, \ + { u"" UNO_NAME_PAGE_PREVIEWBITMAP, WID_PAGE_PREVIEWBITMAP, cppu::UnoType<css::uno::Sequence<sal_Int8>>::get(), css::beans::PropertyAttribute::READONLY, 0},\ + { u"" UNO_NAME_PAGE_PREVIEWMETAFILE, WID_PAGE_PREVIEWMETAFILE, cppu::UnoType<css::uno::Sequence<sal_Int8>>::get(), css::beans::PropertyAttribute::READONLY, 0},\ + { sUNO_Prop_UserDefinedAttributes,WID_PAGE_USERATTRIBS, cppu::UnoType<css::container::XNameContainer>::get(), 0, 0}, \ + { sUNO_Prop_BookmarkURL, WID_PAGE_BOOKMARK, ::cppu::UnoType<OUString>::get(), 0, 0}, \ + { u"IsBackgroundDark", WID_PAGE_ISDARK, cppu::UnoType<bool>::get(), beans::PropertyAttribute::READONLY, 0}, \ + { u"NavigationOrder", WID_NAVORDER, cppu::UnoType<css::container::XIndexAccess>::get(),0, 0}, \ + { u"", 0, css::uno::Type(), 0, 0 } + + static const SfxItemPropertyMapEntry aGraphicPagePropertyMap_Impl[] = + { + { u"" UNO_NAME_PAGE_BACKGROUND, WID_PAGE_BACK, cppu::UnoType<beans::XPropertySet>::get(), beans::PropertyAttribute::MAYBEVOID,0}, + GRAPHIC_PAGE_PROPERTIES + }; + static const SfxItemPropertyMapEntry aGraphicPagePropertyNoBackMap_Impl[] = + { + GRAPHIC_PAGE_PROPERTIES + }; + + bool bWithoutBackground = ePageKind != PageKind::Standard && ePageKind != PageKind::Handout; + const SvxItemPropertySet* pRet = nullptr; + if( bImpress ) + { + if( ePageKind == PageKind::Standard ) + { + //PageKind::Standard always has a background property + static SvxItemPropertySet aDrawPagePropertySet_Impl( aDrawPagePropertyMap_Impl, SdrObject::GetGlobalDrawObjectItemPool() ); + pRet = &aDrawPagePropertySet_Impl; + } + else + { + if(bWithoutBackground) + { + static SvxItemPropertySet aDrawPageNotesHandoutPropertyNoBackSet_Impl( aDrawPageNotesHandoutPropertyNoBackMap_Impl, SdrObject::GetGlobalDrawObjectItemPool() ); + pRet = &aDrawPageNotesHandoutPropertyNoBackSet_Impl; + } + else + { + static SvxItemPropertySet aDrawPageNotesHandoutPropertySet_Impl( aDrawPageNotesHandoutPropertyMap_Impl, SdrObject::GetGlobalDrawObjectItemPool() ); + pRet = &aDrawPageNotesHandoutPropertySet_Impl; + } + } + } + else + { + if(bWithoutBackground) + { + static SvxItemPropertySet aGraphicPagePropertyNoBackSet_Impl( aGraphicPagePropertyNoBackMap_Impl, SdrObject::GetGlobalDrawObjectItemPool() ); + pRet = &aGraphicPagePropertyNoBackSet_Impl; + } + else + { + static SvxItemPropertySet aGraphicPagePropertySet_Impl( aGraphicPagePropertyMap_Impl, SdrObject::GetGlobalDrawObjectItemPool() ); + pRet = &aGraphicPagePropertySet_Impl; + } + } + return pRet; +} + +/** this function stores the property map for master pages in impress and draw */ +static const SvxItemPropertySet* ImplGetMasterPagePropertySet( PageKind ePageKind ) +{ + static const SfxItemPropertyMapEntry aMasterPagePropertyMap_Impl[] = + { + { u"" UNO_NAME_PAGE_BACKGROUND, WID_PAGE_BACK, cppu::UnoType<beans::XPropertySet>::get(), 0, 0}, + { u"" UNO_NAME_PAGE_BOTTOM, WID_PAGE_BOTTOM, ::cppu::UnoType<sal_Int32>::get(), 0, 0}, + { u"" UNO_NAME_PAGE_LEFT, WID_PAGE_LEFT, ::cppu::UnoType<sal_Int32>::get(), 0, 0}, + { u"" UNO_NAME_PAGE_RIGHT, WID_PAGE_RIGHT, ::cppu::UnoType<sal_Int32>::get(), 0, 0}, + { u"" UNO_NAME_PAGE_TOP, WID_PAGE_TOP, ::cppu::UnoType<sal_Int32>::get(), 0, 0}, + { u"" UNO_NAME_PAGE_HEIGHT, WID_PAGE_HEIGHT, ::cppu::UnoType<sal_Int32>::get(), 0, 0}, + { UNO_NAME_LINKDISPLAYBITMAP, WID_PAGE_LDBITMAP, cppu::UnoType<awt::XBitmap>::get(), beans::PropertyAttribute::READONLY, 0}, + { UNO_NAME_LINKDISPLAYNAME, WID_PAGE_LDNAME, ::cppu::UnoType<OUString>::get(), beans::PropertyAttribute::READONLY, 0}, + { u"" UNO_NAME_PAGE_NUMBER, WID_PAGE_NUMBER, ::cppu::UnoType<sal_Int16>::get(), beans::PropertyAttribute::READONLY, 0}, + { u"" UNO_NAME_PAGE_ORIENTATION, WID_PAGE_ORIENT, ::cppu::UnoType<view::PaperOrientation>::get(),0, 0}, + { u"" UNO_NAME_PAGE_WIDTH, WID_PAGE_WIDTH, ::cppu::UnoType<sal_Int32>::get(), 0, 0}, + { u"BackgroundFullSize", WID_PAGE_BACKFULL, cppu::UnoType<bool>::get(), 0, 0}, + { sUNO_Prop_UserDefinedAttributes,WID_PAGE_USERATTRIBS, cppu::UnoType<css::container::XNameContainer>::get(), 0, 0}, + { u"IsBackgroundDark", WID_PAGE_ISDARK, cppu::UnoType<bool>::get(), beans::PropertyAttribute::READONLY, 0}, + { u"Theme", WID_PAGE_THEME, cppu::UnoType<uno::Sequence< beans::PropertyValue >>::get(), 0, 0}, + { u"", 0, css::uno::Type(), 0, 0 } + }; + + static const SfxItemPropertyMapEntry aHandoutMasterPagePropertyMap_Impl[] = + { + { u"" UNO_NAME_PAGE_BOTTOM, WID_PAGE_BOTTOM, ::cppu::UnoType<sal_Int32>::get(), 0, 0}, + { u"" UNO_NAME_PAGE_LEFT, WID_PAGE_LEFT, ::cppu::UnoType<sal_Int32>::get(), 0, 0}, + { u"" UNO_NAME_PAGE_RIGHT, WID_PAGE_RIGHT, ::cppu::UnoType<sal_Int32>::get(), 0, 0}, + { u"" UNO_NAME_PAGE_TOP, WID_PAGE_TOP, ::cppu::UnoType<sal_Int32>::get(), 0, 0}, + { u"" UNO_NAME_PAGE_HEIGHT, WID_PAGE_HEIGHT, ::cppu::UnoType<sal_Int32>::get(), 0, 0}, + { u"" UNO_NAME_PAGE_ORIENTATION, WID_PAGE_ORIENT, ::cppu::UnoType<view::PaperOrientation>::get(),0, 0}, + { u"" UNO_NAME_PAGE_NUMBER, WID_PAGE_NUMBER, ::cppu::UnoType<sal_Int16>::get(), beans::PropertyAttribute::READONLY, 0}, + { u"" UNO_NAME_PAGE_WIDTH, WID_PAGE_WIDTH, ::cppu::UnoType<sal_Int32>::get(), 0, 0}, + { u"" UNO_NAME_PAGE_LAYOUT, WID_PAGE_LAYOUT, ::cppu::UnoType<sal_Int16>::get(), 0, 0}, + { sUNO_Prop_UserDefinedAttributes,WID_PAGE_USERATTRIBS, cppu::UnoType<css::container::XNameContainer>::get(), 0, 0}, + { u"IsBackgroundDark", WID_PAGE_ISDARK, cppu::UnoType<bool>::get(), beans::PropertyAttribute::READONLY, 0}, + { u"IsHeaderVisible", WID_PAGE_HEADERVISIBLE, cppu::UnoType<bool>::get(), 0, 0}, + { u"HeaderText", WID_PAGE_HEADERTEXT, ::cppu::UnoType<OUString>::get(), 0, 0}, + { u"IsFooterVisible", WID_PAGE_FOOTERVISIBLE, cppu::UnoType<bool>::get(), 0, 0}, + { u"FooterText", WID_PAGE_FOOTERTEXT, ::cppu::UnoType<OUString>::get(), 0, 0}, + { u"IsPageNumberVisible", WID_PAGE_PAGENUMBERVISIBLE, cppu::UnoType<bool>::get(), 0, 0}, + { u"IsDateTimeVisible", WID_PAGE_DATETIMEVISIBLE, cppu::UnoType<bool>::get(), 0, 0}, + { u"IsDateTimeFixed", WID_PAGE_DATETIMEFIXED, cppu::UnoType<bool>::get(), 0, 0}, + { u"DateTimeText", WID_PAGE_DATETIMETEXT, ::cppu::UnoType<OUString>::get(), 0, 0}, + { u"DateTimeFormat", WID_PAGE_DATETIMEFORMAT, ::cppu::UnoType<sal_Int32>::get(), 0, 0}, + { u"", 0, css::uno::Type(), 0, 0 } + }; + + const SvxItemPropertySet* pRet = nullptr; + if( ePageKind == PageKind::Handout ) + { + static SvxItemPropertySet aHandoutMasterPagePropertySet_Impl( aHandoutMasterPagePropertyMap_Impl, SdrObject::GetGlobalDrawObjectItemPool() ); + pRet = &aHandoutMasterPagePropertySet_Impl; + } + else + { + static SvxItemPropertySet aMasterPagePropertySet_Impl( aMasterPagePropertyMap_Impl, SdrObject::GetGlobalDrawObjectItemPool() ); + pRet = &aMasterPagePropertySet_Impl; + } + return pRet; +} + +const css::uno::Sequence< sal_Int8 > & SdGenericDrawPage::getUnoTunnelId() noexcept +{ + static const comphelper::UnoIdInit theSdGenericDrawPageUnoTunnelId; + return theSdGenericDrawPageUnoTunnelId.getSeq(); +} + +sal_Int64 SAL_CALL SdGenericDrawPage::getSomething( const css::uno::Sequence< sal_Int8 >& rId ) +{ + return comphelper::getSomethingImpl(rId, this, + comphelper::FallbackToGetSomethingOf<SvxFmDrawPage>{}); +} + +SdGenericDrawPage::SdGenericDrawPage(SdXImpressDocument* _pModel, SdPage* pInPage, const SvxItemPropertySet* _pSet) +: SvxFmDrawPage( static_cast<SdrPage*>(pInPage) ), + SdUnoSearchReplaceShape(this), + mpDocModel( _pModel ), + mpSdrModel(nullptr), + mbIsImpressDocument(false), + mnTempPageNumber(0), + mpPropSet ( _pSet ) +{ + mpSdrModel = SvxFmDrawPage::mpModel; + if( mpDocModel ) + mbIsImpressDocument = mpDocModel->IsImpressDocument(); + +} + +SdGenericDrawPage::~SdGenericDrawPage() noexcept +{ +} + +void SdGenericDrawPage::throwIfDisposed() const +{ + if( (SvxFmDrawPage::mpModel == nullptr) || (mpDocModel == nullptr) || (SvxFmDrawPage::mpPage == nullptr) ) + throw lang::DisposedException(); +} + +SdXImpressDocument* SdGenericDrawPage::GetModel() const +{ + if( mpSdrModel != SvxFmDrawPage::mpModel ) + const_cast<SdGenericDrawPage*>(this)->UpdateModel(); + return mpDocModel; +} + +bool SdGenericDrawPage::IsImpressDocument() const +{ + if( mpSdrModel != SvxFmDrawPage::mpModel ) + const_cast<SdGenericDrawPage*>(this)->UpdateModel(); + return mbIsImpressDocument; +} + + +void SdGenericDrawPage::UpdateModel() +{ + mpSdrModel = SvxFmDrawPage::mpModel; + if( mpSdrModel ) + { + uno::Reference< uno::XInterface > xModel( SvxFmDrawPage::mpModel->getUnoModel() ); + mpDocModel = comphelper::getFromUnoTunnel<SdXImpressDocument>( xModel ); + } + else + { + mpDocModel = nullptr; + } + mbIsImpressDocument = mpDocModel && mpDocModel->IsImpressDocument(); +} + +// this is called whenever a SdrObject must be created for an empty api shape wrapper +SdrObject * SdGenericDrawPage::CreateSdrObject_( const Reference< drawing::XShape >& xShape ) +{ + if( nullptr == SvxFmDrawPage::mpPage || !xShape.is() ) + return nullptr; + + OUString aType( xShape->getShapeType() ); + static const OUStringLiteral aPrefix( u"com.sun.star.presentation." ); + if( !aType.startsWith( aPrefix ) ) + { + SdrObject* pObj = SvxFmDrawPage::CreateSdrObject_( xShape ); + return pObj; + } + + aType = aType.copy( aPrefix.getLength() ); + + PresObjKind eObjKind = PresObjKind::NONE; + + if( aType == "TitleTextShape" ) + { + eObjKind = PresObjKind::Title; + } + else if( aType == "OutlinerShape" ) + { + eObjKind = PresObjKind::Outline; + } + else if( aType == "SubtitleShape" ) + { + eObjKind = PresObjKind::Text; + } + else if( aType == "OLE2Shape" ) + { + eObjKind = PresObjKind::Object; + } + else if( aType == "ChartShape" ) + { + eObjKind = PresObjKind::Chart; + } + else if( aType == "CalcShape" ) + { + eObjKind = PresObjKind::Calc; + } + else if( aType == "TableShape" ) + { + eObjKind = PresObjKind::Table; + } + else if( aType == "GraphicObjectShape" ) + { + eObjKind = PresObjKind::Graphic; + } + else if( aType == "OrgChartShape" ) + { + eObjKind = PresObjKind::OrgChart; + } + else if( aType == "PageShape" ) + { + if( GetPage()->GetPageKind() == PageKind::Notes && GetPage()->IsMasterPage() ) + eObjKind = PresObjKind::Title; + else + eObjKind = PresObjKind::Page; + } + else if( aType == "NotesShape" ) + { + eObjKind = PresObjKind::Notes; + } + else if( aType == "HandoutShape" ) + { + eObjKind = PresObjKind::Handout; + } + else if( aType == "FooterShape" ) + { + eObjKind = PresObjKind::Footer; + } + else if( aType == "HeaderShape" ) + { + eObjKind = PresObjKind::Header; + } + else if( aType == "SlideNumberShape" ) + { + eObjKind = PresObjKind::SlideNumber; + } + else if( aType == "DateTimeShape" ) + { + eObjKind = PresObjKind::DateTime; + } + else if( aType == "MediaShape" ) + { + eObjKind = PresObjKind::Media; + } + + ::tools::Rectangle aRect( eObjKind == PresObjKind::Title ? GetPage()->GetTitleRect() : GetPage()->GetLayoutRect() ); + + const awt::Point aPos( aRect.Left(), aRect.Top() ); + xShape->setPosition( aPos ); + + const awt::Size aSize( aRect.GetWidth(), aRect.GetHeight() ); + xShape->setSize( aSize ); + + SdrObject *pPresObj = nullptr; + if( (eObjKind == PresObjKind::Table) || (eObjKind == PresObjKind::Media) ) + { + pPresObj = SvxFmDrawPage::CreateSdrObject_( xShape ); + if( pPresObj ) + { + SdDrawDocument& rDoc(static_cast< SdDrawDocument& >(GetPage()->getSdrModelFromSdrPage())); + pPresObj->NbcSetStyleSheet(rDoc.GetDefaultStyleSheet(), true); + GetPage()->InsertPresObj( pPresObj, eObjKind ); + } + } + else + { + pPresObj = GetPage()->CreatePresObj( eObjKind, false, aRect ); + } + + if( pPresObj ) + pPresObj->SetUserCall( GetPage() ); + + return pPresObj; +} + +// XInterface +Any SAL_CALL SdGenericDrawPage::queryInterface( const uno::Type & rType ) +{ + Any aAny; + + if (rType == cppu::UnoType<beans::XPropertySet>::get()) + { + aAny <<= Reference<beans::XPropertySet>(this); + } + else if (rType == cppu::UnoType<container::XNamed>::get()) + { + aAny <<= Reference<container::XNamed>(this); + } + else if (rType == cppu::UnoType<util::XReplaceable>::get()) + { + aAny <<= Reference<util::XReplaceable>(this); + } + else if (rType == cppu::UnoType<util::XSearchable>::get()) + { + aAny <<= Reference<util::XSearchable>(this); + } + else if (rType == cppu::UnoType<document::XLinkTargetSupplier>::get()) + { + aAny <<= Reference<document::XLinkTargetSupplier>(this); + } + else if (rType == cppu::UnoType<drawing::XShapeCombiner>::get()) + { + aAny <<= Reference<drawing::XShapeCombiner>(this); + } + else if (rType == cppu::UnoType<drawing::XShapeBinder>::get()) + { + aAny <<= Reference<drawing::XShapeBinder>(this); + } + else if (rType == cppu::UnoType<beans::XMultiPropertySet>::get()) + { + aAny <<= Reference<beans::XMultiPropertySet>(this); + } + else if (rType == cppu::UnoType<office::XAnnotationAccess>::get()) + { + aAny <<= Reference<office::XAnnotationAccess>(this); + } + else if (IsImpressDocument() && rType == cppu::UnoType<XAnimationNodeSupplier>::get()) + { + const PageKind ePageKind = GetPage() ? GetPage()->GetPageKind() : PageKind::Standard; + + if( ePageKind == PageKind::Standard ) + return Any( Reference< XAnimationNodeSupplier >( this ) ); + } + else + return SvxDrawPage::queryInterface( rType ); + + return aAny; +} + +// XPropertySet +Reference< beans::XPropertySetInfo > SAL_CALL SdGenericDrawPage::getPropertySetInfo() +{ + ::SolarMutexGuard aGuard; + throwIfDisposed(); + return mpPropSet->getPropertySetInfo(); +} + +void SAL_CALL SdGenericDrawPage::setPropertyValue( const OUString& aPropertyName, const Any& aValue ) +{ + ::SolarMutexGuard aGuard; + + throwIfDisposed(); + + const SfxItemPropertyMapEntry* pEntry = mpPropSet->getPropertyMapEntry(aPropertyName); + + switch( pEntry ? pEntry->nWID : -1 ) + { + case WID_NAVORDER: + setNavigationOrder( aValue ); + break; + case WID_PAGE_LEFT: + case WID_PAGE_RIGHT: + case WID_PAGE_TOP: + case WID_PAGE_BOTTOM: + case WID_PAGE_LAYOUT: + case WID_PAGE_DURATION: + case WID_PAGE_CHANGE: + { + sal_Int32 nValue = 0; + if(!(aValue >>= nValue)) + throw lang::IllegalArgumentException(); + + switch( pEntry->nWID ) + { + case WID_PAGE_LEFT: + SetLeftBorder(nValue); + break; + case WID_PAGE_RIGHT: + SetRightBorder( nValue ); + break; + case WID_PAGE_TOP: + SetUpperBorder( nValue ); + break; + case WID_PAGE_BOTTOM: + SetLowerBorder( nValue ); + break; + case WID_PAGE_CHANGE: + GetPage()->SetPresChange( static_cast<PresChange>(nValue) ); + break; + case WID_PAGE_LAYOUT: + GetPage()->SetAutoLayout( static_cast<AutoLayout>(nValue), true ); + break; + case WID_PAGE_DURATION: + GetPage()->SetTime(nValue); + break; + } + break; + } + case WID_PAGE_HIGHRESDURATION: + { + double fValue = 0; + if(!(aValue >>= fValue)) + throw lang::IllegalArgumentException(); + + GetPage()->SetTime(fValue); + break; + } + case WID_PAGE_WIDTH: + { + sal_Int32 nWidth = 0; + if(!(aValue >>= nWidth)) + throw lang::IllegalArgumentException(); + + SetWidth( nWidth ); + break; + } + case WID_PAGE_HEIGHT: + { + sal_Int32 nHeight = 0; + if(!(aValue >>= nHeight)) + throw lang::IllegalArgumentException(); + + SetHeight( nHeight ); + break; + } + case WID_PAGE_ORIENT: + { + sal_Int32 nEnum = 0; + if(!::cppu::enum2int( nEnum, aValue )) + throw lang::IllegalArgumentException(); + + Orientation eOri = (static_cast<view::PaperOrientation>(nEnum) == view::PaperOrientation_PORTRAIT)?Orientation::Portrait:Orientation::Landscape; + + if( eOri != GetPage()->GetOrientation() ) + { + SdDrawDocument& rDoc(static_cast< SdDrawDocument& >(GetPage()->getSdrModelFromSdrPage())); + const PageKind ePageKind = GetPage()->GetPageKind(); + + sal_uInt16 i, nPageCnt = rDoc.GetMasterSdPageCount(ePageKind); + for (i = 0; i < nPageCnt; i++) + { + SdPage* pPage = rDoc.GetMasterSdPage(i, ePageKind); + pPage->SetOrientation( eOri ); + } + + nPageCnt = rDoc.GetSdPageCount(ePageKind); + + for (i = 0; i < nPageCnt; i++) + { + SdPage* pPage = rDoc.GetSdPage(i, ePageKind); + pPage->SetOrientation( eOri ); + } + } + break; + } + case WID_PAGE_EFFECT: + { + sal_Int32 nEnum = 0; + if(!::cppu::enum2int( nEnum, aValue )) + throw lang::IllegalArgumentException(); + + GetPage()->SetFadeEffect( static_cast<presentation::FadeEffect>(nEnum) ); + break; + } + case WID_PAGE_BACK: + setBackground( aValue ); + break; + case WID_PAGE_SPEED: + { + sal_Int32 nEnum = 0; + if(!::cppu::enum2int( nEnum, aValue )) + throw lang::IllegalArgumentException(); + + GetPage()->setTransitionDuration( nEnum == 0 ? 3.0 : (nEnum == 1 ? 2.0 : 1.0 ) ); + break; + } + case WID_PAGE_VISIBLE : + { + bool bVisible = false; + if( ! ( aValue >>= bVisible ) ) + throw lang::IllegalArgumentException(); + GetPage()->SetExcluded( !bVisible ); + break; + } + case WID_PAGE_SOUNDFILE : + { + OUString aURL; + if( aValue >>= aURL ) + { + GetPage()->SetSoundFile( aURL ); + GetPage()->SetSound( !aURL.isEmpty() ); + break; + } + else + { + bool bStopSound = false; + if( aValue >>= bStopSound ) + { + GetPage()->SetStopSound( bStopSound ); + break; + } + } + + throw lang::IllegalArgumentException(); + } + case WID_LOOP_SOUND: + { + bool bLoop = false; + if( ! (aValue >>= bLoop) ) + throw lang::IllegalArgumentException(); + + GetPage()->SetLoopSound( bLoop ); + break; + } + case WID_PAGE_BACKFULL: + { + bool bFullSize = false; + if( ! ( aValue >>= bFullSize ) ) + throw lang::IllegalArgumentException(); + GetPage()->SetBackgroundFullSize( bFullSize ); + break; + } + case WID_PAGE_BACKVIS: + { + bool bVisible = false; + if( ! ( aValue >>= bVisible ) ) + throw lang::IllegalArgumentException(); + + SdrPage* pPage = GetPage(); + if( pPage ) + { + SdDrawDocument& rDoc(static_cast< SdDrawDocument& >(pPage->getSdrModelFromSdrPage())); + if( rDoc.GetMasterPageCount() ) + { + SdrLayerAdmin& rLayerAdmin = rDoc.GetLayerAdmin(); + SdrLayerIDSet aVisibleLayers = pPage->TRG_GetMasterPageVisibleLayers(); + aVisibleLayers.Set(rLayerAdmin.GetLayerID(sUNO_LayerName_background), bVisible); + pPage->TRG_SetMasterPageVisibleLayers(aVisibleLayers); + } + } + break; + } + case WID_PAGE_BACKOBJVIS: + { + bool bVisible = false; + if( ! ( aValue >>= bVisible ) ) + throw lang::IllegalArgumentException(); + + SdrPage* pPage = GetPage(); + if( pPage ) + { + SdDrawDocument& rDoc(static_cast< SdDrawDocument& >(pPage->getSdrModelFromSdrPage())); + if( rDoc.GetMasterPageCount() ) + { + SdrLayerAdmin& rLayerAdmin = rDoc.GetLayerAdmin(); + SdrLayerIDSet aVisibleLayers = pPage->TRG_GetMasterPageVisibleLayers(); + aVisibleLayers.Set(rLayerAdmin.GetLayerID(sUNO_LayerName_background_objects), bVisible); + pPage->TRG_SetMasterPageVisibleLayers(aVisibleLayers); + } + } + + break; + } + case WID_PAGE_USERATTRIBS: + { + if( !GetPage()->setAlienAttributes( aValue ) ) + throw lang::IllegalArgumentException(); + break; + } + case WID_PAGE_BOOKMARK: + { + OUString aBookmarkURL; + if( ! ( aValue >>= aBookmarkURL ) ) + throw lang::IllegalArgumentException(); + + setBookmarkURL( aBookmarkURL ); + break; + } + + case WID_PAGE_HEADERVISIBLE: + case WID_PAGE_HEADERTEXT: + case WID_PAGE_FOOTERVISIBLE: + case WID_PAGE_FOOTERTEXT: + case WID_PAGE_PAGENUMBERVISIBLE: + case WID_PAGE_DATETIMEVISIBLE: + case WID_PAGE_DATETIMEFIXED: + case WID_PAGE_DATETIMETEXT: + case WID_PAGE_DATETIMEFORMAT: + { + sd::HeaderFooterSettings aHeaderFooterSettings( GetPage()->getHeaderFooterSettings() ); + + switch( pEntry->nWID ) + { + case WID_PAGE_HEADERVISIBLE: + { + bool bVisible = false; + if( ! ( aValue >>= bVisible ) ) + throw lang::IllegalArgumentException(); + + aHeaderFooterSettings.mbHeaderVisible = bVisible; + break; + } + case WID_PAGE_HEADERTEXT: + { + OUString aText; + if( ! ( aValue >>= aText ) ) + throw lang::IllegalArgumentException(); + + aHeaderFooterSettings.maHeaderText = aText; + break; + } + case WID_PAGE_FOOTERVISIBLE: + { + bool bVisible = false; + if( ! ( aValue >>= bVisible ) ) + throw lang::IllegalArgumentException(); + + aHeaderFooterSettings.mbFooterVisible = bVisible; + break; + } + case WID_PAGE_FOOTERTEXT: + { + OUString aText; + if( ! ( aValue >>= aText ) ) + throw lang::IllegalArgumentException(); + + aHeaderFooterSettings.maFooterText = aText; + break; + } + case WID_PAGE_PAGENUMBERVISIBLE: + { + bool bVisible = false; + if( ! ( aValue >>= bVisible ) ) + throw lang::IllegalArgumentException(); + + aHeaderFooterSettings.mbSlideNumberVisible = bVisible; + break; + } + case WID_PAGE_DATETIMEVISIBLE: + { + bool bVisible = false; + if( ! ( aValue >>= bVisible ) ) + throw lang::IllegalArgumentException(); + + aHeaderFooterSettings.mbDateTimeVisible = bVisible; + break; + } + case WID_PAGE_DATETIMEFIXED: + { + bool bVisible = false; + if( ! ( aValue >>= bVisible ) ) + throw lang::IllegalArgumentException(); + + aHeaderFooterSettings.mbDateTimeIsFixed = bVisible; + break; + } + case WID_PAGE_DATETIMETEXT: + { + OUString aText; + if( ! ( aValue >>= aText ) ) + throw lang::IllegalArgumentException(); + + aHeaderFooterSettings.maDateTimeText = aText; + break; + } + case WID_PAGE_DATETIMEFORMAT: + { + sal_Int32 nValue = 0; + if( ! ( aValue >>= nValue ) ) + throw lang::IllegalArgumentException(); + + aHeaderFooterSettings.meDateFormat = static_cast<SvxDateFormat>(nValue & 0x0f); + aHeaderFooterSettings.meTimeFormat = static_cast<SvxTimeFormat>((nValue >> 4) & 0x0f); + break; + } + } + + if( !(aHeaderFooterSettings == GetPage()->getHeaderFooterSettings()) ) + GetPage()->setHeaderFooterSettings( aHeaderFooterSettings ); + + break; + } + + case WID_PAGE_NUMBER: + if( (GetPage()->GetPageKind() == PageKind::Handout) && !GetPage()->IsMasterPage() ) + { + if( !(aValue >>= mnTempPageNumber) ) + throw lang::IllegalArgumentException(); + + break; + } + throw beans::PropertyVetoException(); + + case WID_PAGE_LDBITMAP: + case WID_PAGE_LDNAME: + case WID_PAGE_ISDARK: + throw beans::PropertyVetoException(); + + case WID_TRANSITION_TYPE: + { + sal_Int16 nValue = 0; + if( ! ( aValue >>= nValue ) ) + throw lang::IllegalArgumentException(); + + GetPage()->setTransitionType( nValue ); + break; + } + + case WID_TRANSITION_SUBTYPE: + { + sal_Int16 nValue = 0; + if( ! ( aValue >>= nValue ) ) + throw lang::IllegalArgumentException(); + + GetPage()->setTransitionSubtype( nValue ); + break; + } + + case WID_TRANSITION_DIRECTION: + { + bool bValue = false; + if( ! ( aValue >>= bValue ) ) + throw lang::IllegalArgumentException(); + + GetPage()->setTransitionDirection( bValue ); + break; + } + + case WID_TRANSITION_FADE_COLOR: + { + sal_Int32 nValue = 0; + if( ! ( aValue >>= nValue ) ) + throw lang::IllegalArgumentException(); + + GetPage()->setTransitionFadeColor( nValue ); + break; + } + + case WID_TRANSITION_DURATION: + { + double fValue = 0.0; + if( ! ( aValue >>= fValue ) ) + throw lang::IllegalArgumentException(); + + GetPage()->setTransitionDuration( fValue ); + break; + } + + case WID_PAGE_THEME: + { + SdrPage* pPage = GetPage(); + std::unique_ptr<svx::Theme> pTheme = svx::Theme::FromAny(aValue); + pPage->getSdrPageProperties().SetTheme(std::move(pTheme)); + break; + } + + default: + throw beans::UnknownPropertyException( aPropertyName, static_cast<cppu::OWeakObject*>(this)); + } + + GetModel()->SetModified(); +} + +Any SAL_CALL SdGenericDrawPage::getPropertyValue( const OUString& PropertyName ) +{ + ::SolarMutexGuard aGuard; + + throwIfDisposed(); + + uno::Any aAny; + + const SfxItemPropertyMapEntry* pEntry = mpPropSet->getPropertyMapEntry(PropertyName); + + sal_Int16 nEntry = pEntry ? pEntry->nWID : -1; + switch (nEntry) + { + case WID_NAVORDER: + aAny = getNavigationOrder(); + break; + case WID_PAGE_LEFT: + aAny <<= GetPage()->GetLeftBorder(); + break; + case WID_PAGE_RIGHT: + aAny <<= GetPage()->GetRightBorder(); + break; + case WID_PAGE_TOP: + aAny <<= GetPage()->GetUpperBorder(); + break; + case WID_PAGE_BOTTOM: + aAny <<= GetPage()->GetLowerBorder(); + break; + case WID_PAGE_WIDTH: + aAny <<= static_cast<sal_Int32>( GetPage()->GetSize().getWidth() ); + break; + case WID_PAGE_HEIGHT: + aAny <<= static_cast<sal_Int32>( GetPage()->GetSize().getHeight() ); + break; + case WID_PAGE_ORIENT: + aAny <<= + GetPage()->GetOrientation() == Orientation::Portrait + ? view::PaperOrientation_PORTRAIT + : view::PaperOrientation_LANDSCAPE; + break; + case WID_PAGE_EFFECT: + aAny <<= GetPage()->GetFadeEffect(); + break; + case WID_PAGE_CHANGE: + aAny <<= static_cast<sal_Int32>( GetPage()->GetPresChange() ); + break; + case WID_PAGE_SPEED: + { + const double fDuration = GetPage()->getTransitionDuration(); + aAny <<= presentation::AnimationSpeed( + fDuration < 2.0 ? 2 : fDuration > 2.0 ? 0 : 1); + } + break; + case WID_PAGE_LAYOUT: + aAny <<= static_cast<sal_Int16>( GetPage()->GetAutoLayout() ); + break; + case WID_PAGE_NUMBER: + { + const sal_uInt16 nPageNumber(GetPage()->GetPageNum()); + + if(nPageNumber > 0) + { + // for all other pages calculate the number + aAny <<= static_cast<sal_Int16>(static_cast<sal_uInt16>((nPageNumber-1)>>1) + 1); + } + else + { + aAny <<= mnTempPageNumber; + } + } + break; + case WID_PAGE_DURATION: + aAny <<= static_cast<sal_Int32>( GetPage()->GetTime() + .5 ); + break; + case WID_PAGE_HIGHRESDURATION: + aAny <<= GetPage()->GetTime(); + break; + case WID_PAGE_LDNAME: + { + const OUString aName( GetPage()->GetName() ); + aAny <<= aName; + break; + } + case WID_PAGE_LDBITMAP: + { + Reference< awt::XBitmap > xBitmap(VCLUnoHelper::CreateBitmap(BitmapEx(BMP_PAGE))); + aAny <<= xBitmap; + } + break; + case WID_PAGE_BACK: + getBackground( aAny ); + break; + case WID_PAGE_PREVIEW : + case WID_PAGE_PREVIEWMETAFILE : + { + SdDrawDocument& rDoc(static_cast< SdDrawDocument& >(GetPage()->getSdrModelFromSdrPage())); + ::sd::DrawDocShell* pDocShell = rDoc.GetDocSh(); + if ( pDocShell ) + { + sal_uInt16 nPgNum = 0; + sal_uInt16 nPageCount = rDoc.GetSdPageCount( PageKind::Standard ); + sal_uInt16 nPageNumber = static_cast<sal_uInt16>( ( GetPage()->GetPageNum() - 1 ) >> 1 ); + while( nPgNum < nPageCount ) + { + rDoc.SetSelected( rDoc.GetSdPage( nPgNum, PageKind::Standard ), nPgNum == nPageNumber ); + nPgNum++; + } + std::shared_ptr<GDIMetaFile> xMetaFile = pDocShell->GetPreviewMetaFile(); + if (xMetaFile) + { + Size aSize( GetPage()->GetSize() ); + xMetaFile->AddAction( new MetaFillColorAction( COL_WHITE, true ), 0 ); + xMetaFile->AddAction( new MetaRectAction( ::tools::Rectangle( Point(), aSize ) ), 1 ); + xMetaFile->SetPrefMapMode(MapMode(MapUnit::Map100thMM)); + xMetaFile->SetPrefSize( aSize ); + + SvMemoryStream aDestStrm( 65535, 65535 ); + if (nEntry == WID_PAGE_PREVIEW) + // Preview: WMF format. + ConvertGDIMetaFileToWMF(*xMetaFile, aDestStrm, nullptr, false); + else + { + // PreviewMetafile: SVM format. + SvmWriter aWriter(aDestStrm); + aWriter.Write(*xMetaFile); + } + Sequence<sal_Int8> aSeq( static_cast<sal_Int8 const *>(aDestStrm.GetData()), aDestStrm.Tell() ); + aAny <<= aSeq; + } + } + } + break; + + case WID_PAGE_PREVIEWBITMAP : + { + SdDrawDocument& rDoc(static_cast< SdDrawDocument& >(GetPage()->getSdrModelFromSdrPage())); + ::sd::DrawDocShell* pDocShell = rDoc.GetDocSh(); + if ( pDocShell ) + { + sal_uInt16 nPgNum = 0; + sal_uInt16 nPageCount = rDoc.GetSdPageCount( PageKind::Standard ); + sal_uInt16 nPageNumber = static_cast<sal_uInt16>( ( GetPage()->GetPageNum() - 1 ) >> 1 ); + while( nPgNum < nPageCount ) + { + rDoc.SetSelected( rDoc.GetSdPage( nPgNum, PageKind::Standard ), nPgNum == nPageNumber ); + nPgNum++; + } + std::shared_ptr<GDIMetaFile> xMetaFile = pDocShell->GetPreviewMetaFile(); + BitmapEx aBitmap; + if (xMetaFile && xMetaFile->CreateThumbnail(aBitmap)) + { + SvMemoryStream aMemStream; + WriteDIB(aBitmap.GetBitmap(), aMemStream, false, false); + uno::Sequence<sal_Int8> aSeq( static_cast<sal_Int8 const *>(aMemStream.GetData()), aMemStream.Tell() ); + aAny <<= aSeq; + } + } + } + break; + + case WID_PAGE_VISIBLE : + { + bool bVisible = !GetPage()->IsExcluded(); + aAny <<= bVisible; + break; + } + + case WID_PAGE_SOUNDFILE : + { + if( GetPage()->IsStopSound() ) + { + aAny <<= true; + } + else + { + OUString aURL; + if( GetPage()->IsSoundOn() ) + aURL = GetPage()->GetSoundFile(); + aAny <<= aURL; + } + break; + } + case WID_LOOP_SOUND: + { + aAny <<= GetPage()->IsLoopSound(); + break; + } + case WID_PAGE_BACKFULL: + { + bool bFullSize = GetPage()->IsBackgroundFullSize(); + aAny <<= bFullSize; + break; + } + case WID_PAGE_BACKVIS: + { + SdrPage* pPage = GetPage(); + if( pPage ) + { + SdDrawDocument& rDoc(static_cast< SdDrawDocument& >(pPage->getSdrModelFromSdrPage())); + if( rDoc.GetMasterPageCount() ) + { + SdrLayerAdmin& rLayerAdmin = rDoc.GetLayerAdmin(); + SdrLayerIDSet aVisibleLayers = pPage->TRG_GetMasterPageVisibleLayers(); + aAny <<= aVisibleLayers.IsSet(rLayerAdmin.GetLayerID(sUNO_LayerName_background)); + } + else + { + aAny <<= false; + } + } + break; + } + case WID_PAGE_BACKOBJVIS: + { + SdrPage* pPage = GetPage(); + if( pPage ) + { + SdDrawDocument& rDoc(static_cast< SdDrawDocument& >(pPage->getSdrModelFromSdrPage())); + if( rDoc.GetMasterPageCount() ) + { + SdrLayerAdmin& rLayerAdmin = rDoc.GetLayerAdmin(); + SdrLayerIDSet aVisibleLayers = pPage->TRG_GetMasterPageVisibleLayers(); + aAny <<= aVisibleLayers.IsSet(rLayerAdmin.GetLayerID(sUNO_LayerName_background_objects)); + } + else + { + aAny <<= false; + } + } + break; + } + case WID_PAGE_USERATTRIBS: + { + GetPage()->getAlienAttributes( aAny ); + break; + } + case WID_PAGE_BOOKMARK: + { + aAny <<= getBookmarkURL(); + break; + } + case WID_PAGE_ISDARK: + { + aAny <<= GetPage()->GetPageBackgroundColor().IsDark(); + break; + } + case WID_PAGE_HEADERVISIBLE: + aAny <<= GetPage()->getHeaderFooterSettings().mbHeaderVisible; + break; + case WID_PAGE_HEADERTEXT: + { + const OUString aText( GetPage()->getHeaderFooterSettings().maHeaderText ); + aAny <<= aText; + } + break; + case WID_PAGE_FOOTERVISIBLE: + aAny <<= GetPage()->getHeaderFooterSettings().mbFooterVisible; + break; + case WID_PAGE_FOOTERTEXT: + { + const OUString aText( GetPage()->getHeaderFooterSettings().maFooterText ); + aAny <<= aText; + } + break; + case WID_PAGE_PAGENUMBERVISIBLE: + aAny <<= GetPage()->getHeaderFooterSettings().mbSlideNumberVisible; + break; + case WID_PAGE_DATETIMEVISIBLE: + aAny <<= GetPage()->getHeaderFooterSettings().mbDateTimeVisible; + break; + case WID_PAGE_DATETIMEFIXED: + aAny <<= GetPage()->getHeaderFooterSettings().mbDateTimeIsFixed; + break; + case WID_PAGE_DATETIMETEXT: + { + const OUString aText( GetPage()->getHeaderFooterSettings().maDateTimeText ); + aAny <<= aText; + } + break; + case WID_PAGE_DATETIMEFORMAT: + { + auto const & rSettings = GetPage()->getHeaderFooterSettings(); + sal_Int32 x = static_cast<sal_Int32>(rSettings.meDateFormat) | (static_cast<sal_Int32>(rSettings.meTimeFormat) << 4); + aAny <<= x; + } + break; + + case WID_TRANSITION_TYPE: + aAny <<= GetPage()->getTransitionType(); + break; + + case WID_TRANSITION_SUBTYPE: + aAny <<= GetPage()->getTransitionSubtype(); + break; + + case WID_TRANSITION_DIRECTION: + aAny <<= GetPage()->getTransitionDirection(); + break; + + case WID_TRANSITION_FADE_COLOR: + aAny <<= GetPage()->getTransitionFadeColor(); + break; + + case WID_TRANSITION_DURATION: + aAny <<= GetPage()->getTransitionDuration(); + break; + + case WID_PAGE_THEME: + { + SdrPage* pPage = GetPage(); + svx::Theme* pTheme = pPage->getSdrPageProperties().GetTheme(); + if (pTheme) + { + pTheme->ToAny(aAny); + } + else + { + beans::PropertyValues aValues; + aAny <<= aValues; + } + break; + } + + default: + throw beans::UnknownPropertyException( PropertyName, static_cast<cppu::OWeakObject*>(this)); + } + return aAny; +} + +void SAL_CALL SdGenericDrawPage::addPropertyChangeListener( const OUString& , const Reference< beans::XPropertyChangeListener >& ) {} +void SAL_CALL SdGenericDrawPage::removePropertyChangeListener( const OUString& , const Reference< beans::XPropertyChangeListener >& ) {} +void SAL_CALL SdGenericDrawPage::addVetoableChangeListener( const OUString& , const Reference< beans::XVetoableChangeListener >& ) {} +void SAL_CALL SdGenericDrawPage::removeVetoableChangeListener( const OUString& , const Reference< beans::XVetoableChangeListener >& ) {} + +// XMultiPropertySet +void SAL_CALL SdGenericDrawPage::setPropertyValues( const Sequence< OUString >& aPropertyNames, const Sequence< Any >& aValues ) +{ + if( aPropertyNames.getLength() != aValues.getLength() ) + throw lang::IllegalArgumentException(); + + const OUString* pNames = aPropertyNames.getConstArray(); + const Any* pValues = aValues.getConstArray(); + sal_uInt32 nCount = aValues.getLength(); + while( nCount-- ) + { + try + { + setPropertyValue( *pNames++, *pValues++ ); + } + catch( beans::UnknownPropertyException& ) + { + // ignore for multi property set + // todo: optimize this! + } + } +} + +Sequence< Any > SAL_CALL SdGenericDrawPage::getPropertyValues( const Sequence< OUString >& aPropertyNames ) +{ + sal_Int32 nCount = aPropertyNames.getLength(); + Sequence< Any > aValues( nCount ); + std::transform(aPropertyNames.begin(), aPropertyNames.end(), aValues.getArray(), + [this](const OUString& rName) -> Any { + Any aValue; + try + { + aValue = getPropertyValue(rName); + } + catch( beans::UnknownPropertyException& ) + { + // ignore for multi property set + // todo: optimize this! + } + return aValue; + }); + return aValues; +} + +void SAL_CALL SdGenericDrawPage::addPropertiesChangeListener( const Sequence< OUString >& , const Reference< beans::XPropertiesChangeListener >& ) +{ +} + +void SAL_CALL SdGenericDrawPage::removePropertiesChangeListener( const Reference< beans::XPropertiesChangeListener >& ) +{ +} + +void SAL_CALL SdGenericDrawPage::firePropertiesChangeEvent( const Sequence< OUString >& , const Reference< beans::XPropertiesChangeListener >& ) +{ +} + +Reference< drawing::XShape > SdGenericDrawPage::CreateShape(SdrObject *pObj) const +{ + DBG_ASSERT( GetPage(), "SdGenericDrawPage::CreateShape(), can't create shape for disposed page!" ); + DBG_ASSERT( pObj, "SdGenericDrawPage::CreateShape(), invalid call with pObj == 0!" ); + + if (!pObj) + return Reference< drawing::XShape >(); + + if (GetPage()) + { + PresObjKind eKind = GetPage()->GetPresObjKind(pObj); + + rtl::Reference<SvxShape> pShape; + + if(pObj->GetObjInventor() == SdrInventor::Default) + { + SdrObjKind nInventor = pObj->GetObjIdentifier(); + switch( nInventor ) + { + case SdrObjKind::TitleText: + pShape = new SvxShapeText( pObj ); + if( GetPage()->GetPageKind() == PageKind::Notes && GetPage()->IsMasterPage() ) + { + // fake an empty PageShape if it's a title shape on the master page + pShape->SetShapeType("com.sun.star.presentation.PageShape"); + } + else + { + pShape->SetShapeType("com.sun.star.presentation.TitleTextShape"); + } + eKind = PresObjKind::NONE; + break; + case SdrObjKind::OutlineText: + pShape = new SvxShapeText( pObj ); + pShape->SetShapeType("com.sun.star.presentation.OutlinerShape"); + eKind = PresObjKind::NONE; + break; + default: ; + } + } + + Reference< drawing::XShape > xShape( pShape ); + + if(!xShape.is()) + xShape = SvxFmDrawPage::CreateShape( pObj ); + + if( eKind != PresObjKind::NONE ) + { + OUString aShapeType("com.sun.star.presentation."); + + switch( eKind ) + { + case PresObjKind::Title: + aShapeType += "TitleTextShape"; + break; + case PresObjKind::Outline: + aShapeType += "OutlinerShape"; + break; + case PresObjKind::Text: + aShapeType += "SubtitleShape"; + break; + case PresObjKind::Graphic: + aShapeType += "GraphicObjectShape"; + break; + case PresObjKind::Object: + aShapeType += "OLE2Shape"; + break; + case PresObjKind::Chart: + aShapeType += "ChartShape"; + break; + case PresObjKind::OrgChart: + aShapeType += "OrgChartShape"; + break; + case PresObjKind::Calc: + aShapeType += "CalcShape"; + break; + case PresObjKind::Table: + aShapeType += "TableShape"; + break; + case PresObjKind::Media: + aShapeType += "MediaShape"; + break; + case PresObjKind::Page: + aShapeType += "PageShape"; + break; + case PresObjKind::Handout: + aShapeType += "HandoutShape"; + break; + case PresObjKind::Notes: + aShapeType += "NotesShape"; + break; + case PresObjKind::Footer: + aShapeType += "FooterShape"; + break; + case PresObjKind::Header: + aShapeType += "HeaderShape"; + break; + case PresObjKind::SlideNumber: + aShapeType += "SlideNumberShape"; + break; + case PresObjKind::DateTime: + aShapeType += "DateTimeShape"; + break; + // coverity[dead_error_begin] - following conditions exist to avoid compiler warning + case PresObjKind::NONE: + break; + } + + if( !pShape ) + pShape = comphelper::getFromUnoTunnel<SvxShape>( xShape ); + + if( pShape ) + pShape->SetShapeType( aShapeType ); + } + + SvxShape *pSdShape = comphelper::getFromUnoTunnel<SvxShape>(xShape); + if (pSdShape) + { + // SdXShape aggregates SvxShape + new SdXShape(pSdShape, GetModel()); + } + return xShape; + } + else + { + return SvxFmDrawPage::CreateShape( pObj ); + } + +} + +// XServiceInfo +Sequence< OUString > SAL_CALL SdGenericDrawPage::getSupportedServiceNames() +{ + return comphelper::concatSequences( + SvxFmDrawPage::getSupportedServiceNames(), + std::initializer_list<std::u16string_view>{ u"com.sun.star.drawing.GenericDrawPage", + u"com.sun.star.document.LinkTarget", + u"com.sun.star.document.LinkTargetSupplier" }); +} + +// XLinkTargetSupplier +Reference< container::XNameAccess > SAL_CALL SdGenericDrawPage::getLinks( ) +{ + return new SdPageLinkTargets( this ); +} + +void SdGenericDrawPage::setBackground( const Any& ) +{ + OSL_FAIL( "Don't call me, I'm useless!" ); +} + +void SdGenericDrawPage::getBackground( Any& ) +{ + OSL_FAIL( "Don't call me, I'm useless!" ); +} + +OUString SdGenericDrawPage::getBookmarkURL() const +{ + OUStringBuffer aRet; + if( SvxFmDrawPage::mpPage ) + { + OUString aFileName( static_cast<SdPage*>(SvxFmDrawPage::mpPage)->GetFileName() ); + if( !aFileName.isEmpty() ) + { + const OUString aBookmarkName( SdDrawPage::getPageApiNameFromUiName( static_cast<SdPage*>(SvxFmDrawPage::mpPage)->GetBookmarkName() ) ); + aRet.append( aFileName ); + aRet.append( '#' ); + aRet.append( aBookmarkName ); + } + } + + return aRet.makeStringAndClear(); +} + +void SdGenericDrawPage::setBookmarkURL( std::u16string_view rURL ) +{ + if( !SvxFmDrawPage::mpPage ) + return; + + size_t nIndex = rURL.find( '#' ); + if( nIndex == std::u16string_view::npos ) + return; + + const OUString aFileName( rURL.substr( 0, nIndex ) ); + const OUString aBookmarkName( SdDrawPage::getUiNameFromPageApiName( OUString(rURL.substr( nIndex+1 )) ) ); + + if( !aFileName.isEmpty() && !aBookmarkName.isEmpty() ) + { + static_cast<SdPage*>(SvxFmDrawPage::mpPage)->DisconnectLink(); + static_cast<SdPage*>(SvxFmDrawPage::mpPage)->SetFileName( aFileName ); + static_cast<SdPage*>(SvxFmDrawPage::mpPage)->SetBookmarkName( aBookmarkName ); + static_cast<SdPage*>(SvxFmDrawPage::mpPage)->ConnectLink(); + } +} + +Reference< drawing::XShape > SAL_CALL SdGenericDrawPage::combine( const Reference< drawing::XShapes >& xShapes ) +{ + ::SolarMutexGuard aGuard; + + throwIfDisposed(); + + DBG_ASSERT(SvxFmDrawPage::mpPage,"SdrPage is NULL! [CL]"); + DBG_ASSERT(mpView, "SdrView is NULL! [CL]"); + + Reference< drawing::XShape > xShape; + if(mpView==nullptr||!xShapes.is()||GetPage()==nullptr) + return xShape; + + SdrPageView* pPageView = mpView->ShowSdrPage( GetPage() ); + + SelectObjectsInView( xShapes, pPageView ); + + mpView->CombineMarkedObjects( false ); + + mpView->AdjustMarkHdl(); + const SdrMarkList& rMarkList = mpView->GetMarkedObjectList(); + if( rMarkList.GetMarkCount() == 1 ) + { + SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj(); + if( pObj ) + xShape.set( pObj->getUnoShape(), UNO_QUERY ); + } + + mpView->HideSdrPage(); + + GetModel()->SetModified(); + + return xShape; +} + +void SAL_CALL SdGenericDrawPage::split( const Reference< drawing::XShape >& xGroup ) +{ + ::SolarMutexGuard aGuard; + + throwIfDisposed(); + + if(mpView==nullptr||!xGroup.is()||GetPage()==nullptr) + return; + + SdrPageView* pPageView = mpView->ShowSdrPage( GetPage() ); + SelectObjectInView( xGroup, pPageView ); + mpView->DismantleMarkedObjects(); + mpView->HideSdrPage(); + + GetModel()->SetModified(); +} + +Reference< drawing::XShape > SAL_CALL SdGenericDrawPage::bind( const Reference< drawing::XShapes >& xShapes ) +{ + ::SolarMutexGuard aGuard; + + throwIfDisposed(); + + uno::Reference< drawing::XShape > xShape; + if(mpView==nullptr||!xShapes.is()||GetPage()==nullptr) + return xShape; + + SdrPageView* pPageView = mpView->ShowSdrPage( GetPage() ); + + SelectObjectsInView( xShapes, pPageView ); + + mpView->CombineMarkedObjects(); + + mpView->AdjustMarkHdl(); + const SdrMarkList& rMarkList = mpView->GetMarkedObjectList(); + if( rMarkList.GetMarkCount() == 1 ) + { + SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj(); + if( pObj ) + xShape.set( pObj->getUnoShape(), UNO_QUERY ); + } + + mpView->HideSdrPage(); + + GetModel()->SetModified(); + + return xShape; +} + +void SAL_CALL SdGenericDrawPage::unbind( const Reference< drawing::XShape >& xShape ) +{ + ::SolarMutexGuard aGuard; + + throwIfDisposed(); + + if(mpView==nullptr||!xShape.is()||GetPage()==nullptr) + return; + + SdrPageView* pPageView = mpView->ShowSdrPage( GetPage() ); + SelectObjectInView( xShape, pPageView ); + mpView->DismantleMarkedObjects( true ); + mpView->HideSdrPage(); + + GetModel()->SetModified(); +} + +void SdGenericDrawPage::SetLeftBorder( sal_Int32 nValue ) +{ + if( nValue == GetPage()->GetLeftBorder() ) + return; + + SdDrawDocument& rDoc(static_cast< SdDrawDocument& >(GetPage()->getSdrModelFromSdrPage())); + const PageKind ePageKind = GetPage()->GetPageKind(); + + sal_uInt16 i, nPageCnt = rDoc.GetMasterSdPageCount(ePageKind); + for (i = 0; i < nPageCnt; i++) + { + SdPage* pPage = rDoc.GetMasterSdPage(i, ePageKind); + pPage->SetLeftBorder( nValue ); + } + + nPageCnt = rDoc.GetSdPageCount(ePageKind); + + for (i = 0; i < nPageCnt; i++) + { + SdPage* pPage = rDoc.GetSdPage(i, ePageKind); + pPage->SetLeftBorder( nValue ); + } +} + +void SdGenericDrawPage::SetRightBorder( sal_Int32 nValue ) +{ + if( nValue == GetPage()->GetRightBorder() ) + return; + + SdDrawDocument& rDoc(static_cast< SdDrawDocument& >(GetPage()->getSdrModelFromSdrPage())); + const PageKind ePageKind = GetPage()->GetPageKind(); + + sal_uInt16 i, nPageCnt = rDoc.GetMasterSdPageCount(ePageKind); + for (i = 0; i < nPageCnt; i++) + { + SdPage* pPage = rDoc.GetMasterSdPage(i, ePageKind); + pPage->SetRightBorder( nValue ); + } + + nPageCnt = rDoc.GetSdPageCount(ePageKind); + + for (i = 0; i < nPageCnt; i++) + { + SdPage* pPage = rDoc.GetSdPage(i, ePageKind); + pPage->SetRightBorder( nValue ); + } +} + +void SdGenericDrawPage::SetUpperBorder( sal_Int32 nValue ) +{ + if( nValue == GetPage()->GetUpperBorder() ) + return; + + SdDrawDocument& rDoc(static_cast< SdDrawDocument& >(GetPage()->getSdrModelFromSdrPage())); + const PageKind ePageKind = GetPage()->GetPageKind(); + + sal_uInt16 i, nPageCnt = rDoc.GetMasterSdPageCount(ePageKind); + for (i = 0; i < nPageCnt; i++) + { + SdPage* pPage = rDoc.GetMasterSdPage(i, ePageKind); + pPage->SetUpperBorder( nValue ); + } + + nPageCnt = rDoc.GetSdPageCount(ePageKind); + + for (i = 0; i < nPageCnt; i++) + { + SdPage* pPage = rDoc.GetSdPage(i, ePageKind); + pPage->SetUpperBorder( nValue ); + } +} + +void SdGenericDrawPage::SetLowerBorder( sal_Int32 nValue ) +{ + if( nValue == GetPage()->GetLowerBorder() ) + return; + + SdDrawDocument& rDoc(static_cast< SdDrawDocument& >(GetPage()->getSdrModelFromSdrPage())); + const PageKind ePageKind = GetPage()->GetPageKind(); + + sal_uInt16 i, nPageCnt = rDoc.GetMasterSdPageCount(ePageKind); + for (i = 0; i < nPageCnt; i++) + { + SdPage* pPage = rDoc.GetMasterSdPage(i, ePageKind); + pPage->SetLowerBorder( nValue ); + } + + nPageCnt = rDoc.GetSdPageCount(ePageKind); + + for (i = 0; i < nPageCnt; i++) + { + SdPage* pPage = rDoc.GetSdPage(i, ePageKind); + pPage->SetLowerBorder( nValue ); + } +} + +static void refreshpage( SdDrawDocument* pDoc, const PageKind ePageKind ) +{ + ::sd::DrawDocShell* pDocShell = pDoc->GetDocSh(); + if ( !pDocShell ) + return; + + ::sd::ViewShell* pViewSh = pDocShell->GetViewShell(); + + if( !pViewSh ) + return; + + if( auto pDrawViewShell = dynamic_cast<::sd::DrawViewShell* >(pViewSh) ) + pDrawViewShell->ResetActualPage(); + + Size aPageSize = pDoc->GetSdPage(0, ePageKind)->GetSize(); + const tools::Long nWidth = aPageSize.Width(); + const tools::Long nHeight = aPageSize.Height(); + + Point aPageOrg(nWidth, nHeight / 2); + Size aViewSize(nWidth * 3, nHeight * 2); + + pDoc->SetMaxObjSize(aViewSize); + + pViewSh->InitWindows(aPageOrg, aViewSize, Point(-1, -1), true); + + pViewSh->UpdateScrollBars(); +} + +void SdGenericDrawPage::SetWidth( sal_Int32 nWidth ) +{ + Size aSize( GetPage()->GetSize() ); + if( aSize.getWidth() == nWidth ) + return; + + aSize.setWidth( nWidth ); + + SdDrawDocument& rDoc(static_cast< SdDrawDocument& >(GetPage()->getSdrModelFromSdrPage())); + const PageKind ePageKind = GetPage()->GetPageKind(); + + sal_uInt16 i, nPageCnt = rDoc.GetMasterSdPageCount(ePageKind); + for (i = 0; i < nPageCnt; i++) + { + SdPage* pPage = rDoc.GetMasterSdPage(i, ePageKind); + pPage->SetSize(aSize); + } + + nPageCnt = rDoc.GetSdPageCount(ePageKind); + + for (i = 0; i < nPageCnt; i++) + { + SdPage* pPage = rDoc.GetSdPage(i, ePageKind); + pPage->SetSize(aSize); + } + + refreshpage( &rDoc, ePageKind ); +} + +void SdGenericDrawPage::SetHeight( sal_Int32 nHeight ) +{ + Size aSize( GetPage()->GetSize() ); + if( aSize.getHeight() == nHeight ) + return; + + aSize.setHeight( nHeight ); + + SdDrawDocument& rDoc(static_cast< SdDrawDocument& >(GetPage()->getSdrModelFromSdrPage())); + const PageKind ePageKind = GetPage()->GetPageKind(); + + sal_uInt16 i, nPageCnt = rDoc.GetMasterSdPageCount(ePageKind); + for (i = 0; i < nPageCnt; i++) + { + SdPage* pPage = rDoc.GetMasterSdPage(i, ePageKind); + pPage->SetSize(aSize); + } + + nPageCnt = rDoc.GetSdPageCount(ePageKind); + + for (i = 0; i < nPageCnt; i++) + { + SdPage* pPage = rDoc.GetSdPage(i, ePageKind); + pPage->SetSize(aSize); + } + + refreshpage( &rDoc, ePageKind ); +} + +// XInterface +void SdGenericDrawPage::release() noexcept +{ + + OWeakAggObject::release(); +} + +// XComponent +void SdGenericDrawPage::disposing() noexcept +{ + mpDocModel = nullptr; + SvxFmDrawPage::disposing(); +} + +// XAnimationNodeSupplier +Reference< XAnimationNode > SAL_CALL SdGenericDrawPage::getAnimationNode() +{ + ::SolarMutexGuard aGuard; + + throwIfDisposed(); + + SdPage *pSdPage = static_cast<SdPage*>(SvxFmDrawPage::mpPage); + + return pSdPage->getAnimationNode(); +} + +// SdPageLinkTargets +SdPageLinkTargets::SdPageLinkTargets( SdGenericDrawPage* pUnoPage ) noexcept +{ + mxPage = pUnoPage; + mpUnoPage = pUnoPage; +} + +SdPageLinkTargets::~SdPageLinkTargets() noexcept +{ +} + +// XElementAccess +uno::Type SAL_CALL SdPageLinkTargets::getElementType() +{ + return cppu::UnoType<beans::XPropertySet>::get(); +} + +sal_Bool SAL_CALL SdPageLinkTargets::hasElements() +{ + ::SolarMutexGuard aGuard; + + SdPage* pPage = mpUnoPage->GetPage(); + if( pPage != nullptr ) + { + SdrObjListIter aIter( pPage, SdrIterMode::DeepWithGroups ); + + while( aIter.IsMore() ) + { + SdrObject* pObj = aIter.Next(); + OUString aStr( pObj->GetName() ); + if( aStr.isEmpty() ) + if (auto pOleObj = dynamic_cast< const SdrOle2Obj *>( pObj )) + aStr = pOleObj->GetPersistName(); + if( !aStr.isEmpty() ) + return true; + } + } + + return false; +} + +// container::XNameAccess + +// XNameAccess +Any SAL_CALL SdPageLinkTargets::getByName( const OUString& aName ) +{ + ::SolarMutexGuard aGuard; + + SdPage* pPage = mpUnoPage->GetPage(); + if( pPage != nullptr ) + { + SdrObject* pObj = FindObject( aName ); + if( pObj ) + { + Reference< beans::XPropertySet > aRef( pObj->getUnoShape(), uno::UNO_QUERY ); + return Any( aRef ); + } + } + + throw container::NoSuchElementException(); +} + +Sequence< OUString > SAL_CALL SdPageLinkTargets::getElementNames() +{ + ::SolarMutexGuard aGuard; + + sal_uInt32 nObjCount = 0; + + SdPage* pPage = mpUnoPage->GetPage(); + if( pPage != nullptr ) + { + SdrObjListIter aIter( pPage, SdrIterMode::DeepWithGroups ); + while( aIter.IsMore() ) + { + SdrObject* pObj = aIter.Next(); + OUString aStr( pObj->GetName() ); + if( aStr.isEmpty() ) + if (auto pOleObj = dynamic_cast< const SdrOle2Obj *>( pObj )) + aStr = pOleObj->GetPersistName(); + if( !aStr.isEmpty() ) + nObjCount++; + } + } + + Sequence< OUString > aSeq( nObjCount ); + if( nObjCount > 0 ) + { + OUString* pStr = aSeq.getArray(); + + SdrObjListIter aIter( pPage, SdrIterMode::DeepWithGroups ); + while( aIter.IsMore() ) + { + SdrObject* pObj = aIter.Next(); + OUString aStr( pObj->GetName() ); + if( aStr.isEmpty() ) + if (auto pOleObj = dynamic_cast< const SdrOle2Obj *>( pObj )) + aStr = pOleObj->GetPersistName(); + if( !aStr.isEmpty() ) + *pStr++ = aStr; + } + } + + return aSeq; +} + +sal_Bool SAL_CALL SdPageLinkTargets::hasByName( const OUString& aName ) +{ + ::SolarMutexGuard aGuard; + + return FindObject( aName ) != nullptr; +} + +SdrObject* SdPageLinkTargets::FindObject( std::u16string_view rName ) const noexcept +{ + SdPage* pPage = mpUnoPage->GetPage(); + if( pPage == nullptr ) + return nullptr; + + SdrObjListIter aIter( pPage, SdrIterMode::DeepWithGroups ); + + while( aIter.IsMore() ) + { + SdrObject* pObj = aIter.Next(); + OUString aStr( pObj->GetName() ); + if( aStr.isEmpty() ) + if (auto pOleObj = dynamic_cast< const SdrOle2Obj *>( pObj )) + aStr = pOleObj->GetPersistName(); + if( !aStr.isEmpty() && (aStr == rName) ) + return pObj; + } + + return nullptr; +} + +// XServiceInfo +OUString SAL_CALL SdPageLinkTargets::getImplementationName() +{ + return "SdPageLinkTargets"; +} + +sal_Bool SAL_CALL SdPageLinkTargets::supportsService( const OUString& ServiceName ) +{ + return cppu::supportsService( this, ServiceName ); +} + +Sequence< OUString > SAL_CALL SdPageLinkTargets::getSupportedServiceNames() +{ + return { "com.sun.star.document.LinkTargets" }; +} + +// SdDrawPage +SdDrawPage::SdDrawPage(SdXImpressDocument* pModel, SdPage* pPage) + : SdGenericDrawPage( pModel, pPage, ImplGetDrawPagePropertySet( pModel->IsImpressDocument(), pPage->GetPageKind() ) ) +{ +} + +SdDrawPage::~SdDrawPage() noexcept +{ +} + +// XInterface +Any SAL_CALL SdDrawPage::queryInterface( const uno::Type & rType ) +{ + if( rType == cppu::UnoType<drawing::XMasterPageTarget>::get() ) + { + return Any( Reference< drawing::XMasterPageTarget >( this ) ); + } + else if( IsImpressDocument() + && rType == cppu::UnoType<presentation::XPresentationPage>::get() ) + { + SdPage * p = dynamic_cast<SdPage *>(SvxDrawPage::mpPage); + if( p == nullptr || p->GetPageKind() != PageKind::Handout ) + { + return Any( Reference< presentation::XPresentationPage >( this ) ); + } + } + + return SdGenericDrawPage::queryInterface( rType ); +} + +void SAL_CALL SdDrawPage::acquire() noexcept +{ + SvxDrawPage::acquire(); +} + +void SAL_CALL SdDrawPage::release() noexcept +{ + SvxDrawPage::release(); +} + +UNO3_GETIMPLEMENTATION2_IMPL( SdDrawPage, SdGenericDrawPage ); + +// XTypeProvider +Sequence< uno::Type > SAL_CALL SdDrawPage::getTypes() +{ + ::SolarMutexGuard aGuard; + + throwIfDisposed(); + + if( !maTypeSequence.hasElements() ) + { + const PageKind ePageKind = GetPage() ? GetPage()->GetPageKind() : PageKind::Standard; + bool bPresPage = IsImpressDocument() && ePageKind != PageKind::Handout; + + // Collect the types of this class. + ::std::vector<uno::Type> aTypes; + aTypes.reserve(13); + aTypes.push_back(cppu::UnoType<drawing::XDrawPage>::get()); + aTypes.push_back(cppu::UnoType<beans::XPropertySet>::get()); + aTypes.push_back(cppu::UnoType<container::XNamed>::get()); + aTypes.push_back(cppu::UnoType<drawing::XMasterPageTarget>::get()); + aTypes.push_back(cppu::UnoType<lang::XServiceInfo>::get()); + aTypes.push_back(cppu::UnoType<util::XReplaceable>::get()); + aTypes.push_back(cppu::UnoType<document::XLinkTargetSupplier>::get()); + aTypes.push_back(cppu::UnoType<drawing::XShapeCombiner>::get()); + aTypes.push_back(cppu::UnoType<drawing::XShapeBinder>::get()); + aTypes.push_back(cppu::UnoType<office::XAnnotationAccess>::get()); + aTypes.push_back(cppu::UnoType<beans::XMultiPropertySet>::get()); + if( bPresPage ) + aTypes.push_back(cppu::UnoType<presentation::XPresentationPage>::get()); + if( bPresPage && ePageKind == PageKind::Standard ) + aTypes.push_back(cppu::UnoType<XAnimationNodeSupplier>::get()); + + // Get types of base class. + // Join those types in a sequence. + return comphelper::concatSequences( + comphelper::containerToSequence(aTypes), + SdGenericDrawPage::getTypes() ); + } + + return maTypeSequence; +} + +Sequence< sal_Int8 > SAL_CALL SdDrawPage::getImplementationId() +{ + return css::uno::Sequence<sal_Int8>(); +} + +OUString SdDrawPage::getPageApiName( SdPage const * pPage ) +{ + return ::getPageApiName( pPage ); +} + +OUString getPageApiName( SdPage const * pPage ) +{ + OUString aPageName; + + if(pPage) + { + aPageName = pPage->GetRealName(); + + if( aPageName.isEmpty() ) + { + const sal_Int32 nPageNum = ( ( pPage->GetPageNum() - 1 ) >> 1 ) + 1; + aPageName = sEmptyPageName + OUString::number( nPageNum ); + } + } + + return aPageName; +} + +OUString getPageApiNameFromUiName( const OUString& rUIName ) +{ + OUString aApiName; + + OUString aDefPageName(SdResId(STR_PAGE) + " "); + + if( rUIName.startsWith( aDefPageName ) ) + { + aApiName = OUString::Concat(sEmptyPageName) + rUIName.subView( aDefPageName.getLength() ); + } + else + { + aApiName = rUIName; + } + + return aApiName; +} + +OUString SdDrawPage::getPageApiNameFromUiName( const OUString& rUIName ) +{ + return ::getPageApiNameFromUiName( rUIName ); +} + +OUString getUiNameFromPageApiNameImpl( const OUString& rApiName ) +{ + const OUString aDefPageName( sEmptyPageName ); + if( rApiName.startsWith( aDefPageName ) ) + { + std::u16string_view aNumber( rApiName.subView( aDefPageName.getLength() ) ); + + // create the page number + sal_Int32 nPageNumber = o3tl::toInt32(aNumber); + + // check if there are non number characters in the number part + const size_t nChars = aNumber.size(); + const sal_Unicode* pString = aNumber.data(); + for( size_t nChar = 0; nChar < nChars; nChar++, pString++ ) + { + if((*pString < '0') || (*pString > '9')) + { + // found a non number character, so this is not the default + // name for this page + nPageNumber = -1; + break; + } + } + + if( nPageNumber != -1) + { + return SdResId(STR_PAGE) + " " + aNumber; + } + } + + return rApiName; +} + +OUString SdDrawPage::getUiNameFromPageApiName( const OUString& rApiName ) +{ + return getUiNameFromPageApiNameImpl( rApiName ); +} + +// XServiceInfo +OUString SAL_CALL SdDrawPage::getImplementationName() +{ + return "SdDrawPage"; +} + +Sequence< OUString > SAL_CALL SdDrawPage::getSupportedServiceNames() +{ + ::SolarMutexGuard aGuard; + + throwIfDisposed(); + + std::vector<std::u16string_view> aAdd{ u"com.sun.star.drawing.DrawPage" }; + + if( IsImpressDocument() ) + aAdd.emplace_back(u"com.sun.star.presentation.DrawPage"); + + return comphelper::concatSequences(SdGenericDrawPage::getSupportedServiceNames(), aAdd); +} + +sal_Bool SAL_CALL SdDrawPage::supportsService( const OUString& ServiceName ) +{ + return cppu::supportsService( this, ServiceName ); +} + +// XNamed +void SAL_CALL SdDrawPage::setName( const OUString& rName ) +{ + ::SolarMutexGuard aGuard; + + throwIfDisposed(); + + DBG_ASSERT( GetPage() && !GetPage()->IsMasterPage(), "Don't call base implementation for masterpages!" ); + + OUString aName( rName ); + + if(!(GetPage() && GetPage()->GetPageKind() != PageKind::Notes)) + return; + + // check if this is the default 'page1234' name + OUString aNumber; + if(aName.startsWith( sEmptyPageName, &aNumber )) + { + // ok, it maybe is, aNumber is the number part after 'page' + + // create the page number + sal_Int32 nPageNumber = aNumber.toInt32(); + + // check if there are non number characters in the number part + const sal_Int32 nChars = aNumber.getLength(); + const sal_Unicode* pString = aNumber.getStr(); + sal_Int32 nChar; + for( nChar = 0; nChar < nChars; nChar++, pString++ ) + { + if((*pString < '0') || (*pString > '9')) + { + // found a non number character, so this is not the default + // name for this page + nPageNumber = -1; + break; + } + } + + if( nPageNumber == ( ( GetPage()->GetPageNum() - 1 ) >> 1 ) + 1 ) + aName.clear(); + } + else + { + OUString aDefaultPageName( SdResId(STR_PAGE) + " " ); + if( aName.startsWith( aDefaultPageName ) ) + aName.clear(); + } + + GetPage()->SetName( aName ); + + sal_uInt16 nNotesPageNum = (GetPage()->GetPageNum()-1)>>1; + if( GetModel()->GetDoc()->GetSdPageCount( PageKind::Notes ) > nNotesPageNum ) + { + SdPage* pNotesPage = GetModel()->GetDoc()->GetSdPage( nNotesPageNum, PageKind::Notes ); + if( pNotesPage ) + pNotesPage->SetName(aName); + } + + // fake a mode change to repaint the page tab bar + ::sd::DrawDocShell* pDocSh = GetModel()->GetDocShell(); + ::sd::ViewShell* pViewSh = pDocSh ? pDocSh->GetViewShell() : nullptr; + if( auto pDrawViewSh = dynamic_cast<::sd::DrawViewShell* >(pViewSh) ) + { + EditMode eMode = pDrawViewSh->GetEditMode(); + if( eMode == EditMode::Page ) + { + bool bLayer = pDrawViewSh->IsLayerModeActive(); + + pDrawViewSh->ChangeEditMode( eMode, !bLayer ); + pDrawViewSh->ChangeEditMode( eMode, bLayer ); + } + } + + GetModel()->SetModified(); +} + +OUString SAL_CALL SdDrawPage::getName() +{ + ::SolarMutexGuard aGuard; + + throwIfDisposed(); + + return getPageApiName( GetPage() ); +} + +// XMasterPageTarget +Reference< drawing::XDrawPage > SAL_CALL SdDrawPage::getMasterPage( ) +{ + ::SolarMutexGuard aGuard; + + throwIfDisposed(); + + if(GetPage()) + { + Reference< drawing::XDrawPage > xPage; + + if(SvxFmDrawPage::mpPage->TRG_HasMasterPage()) + { + SdrPage& rMasterPage = SvxFmDrawPage::mpPage->TRG_GetMasterPage(); + xPage.set( rMasterPage.getUnoPage(), uno::UNO_QUERY ); + } + + return xPage; + } + return nullptr; +} + +void SAL_CALL SdDrawPage::setMasterPage( const Reference< drawing::XDrawPage >& xMasterPage ) +{ + ::SolarMutexGuard aGuard; + comphelper::ProfileZone aZone("setMasterPage"); + + throwIfDisposed(); + + if(!SvxFmDrawPage::mpPage) + return; + + SdMasterPage* pMasterPage = comphelper::getFromUnoTunnel<SdMasterPage>( xMasterPage ); + if( !(pMasterPage && pMasterPage->isValid()) ) + return; + + SvxFmDrawPage::mpPage->TRG_ClearMasterPage(); + + SdPage* pSdPage = static_cast<SdPage*>(pMasterPage->GetSdrPage()); + SvxFmDrawPage::mpPage->TRG_SetMasterPage(*pSdPage); + + SvxFmDrawPage::mpPage->SetBorder(pSdPage->GetLeftBorder(),pSdPage->GetUpperBorder(), + pSdPage->GetRightBorder(),pSdPage->GetLowerBorder() ); + + SvxFmDrawPage::mpPage->SetSize( pSdPage->GetSize() ); + SvxFmDrawPage::mpPage->SetOrientation( pSdPage->GetOrientation() ); + static_cast<SdPage*>(SvxFmDrawPage::mpPage)->SetLayoutName( pSdPage->GetLayoutName() ); + + // set notes master also + SdPage* pNotesPage = GetModel()->GetDoc()->GetSdPage( (SvxFmDrawPage::mpPage->GetPageNum()-1)>>1, PageKind::Notes ); + + pNotesPage->TRG_ClearMasterPage(); + sal_uInt16 nNum = SvxFmDrawPage::mpPage->TRG_GetMasterPage().GetPageNum() + 1; + pNotesPage->TRG_SetMasterPage(*SvxFmDrawPage::mpPage->getSdrModelFromSdrPage().GetMasterPage(nNum)); + pNotesPage->SetLayoutName( pSdPage->GetLayoutName() ); + + GetModel()->SetModified(); +} + +// XPresentationPage +Reference< drawing::XDrawPage > SAL_CALL SdDrawPage::getNotesPage() +{ + ::SolarMutexGuard aGuard; + + throwIfDisposed(); + + if(SvxFmDrawPage::mpPage && GetModel()->GetDoc() && SvxFmDrawPage::mpPage->GetPageNum() ) + { + SdPage* pNotesPage = GetModel()->GetDoc()->GetSdPage( (SvxFmDrawPage::mpPage->GetPageNum()-1)>>1, PageKind::Notes ); + if( pNotesPage ) + { + Reference< drawing::XDrawPage > xPage( pNotesPage->getUnoPage(), uno::UNO_QUERY ); + return xPage; + } + } + return nullptr; +} + +// XIndexAccess +sal_Int32 SAL_CALL SdDrawPage::getCount() +{ + return SdGenericDrawPage::getCount(); +} + +Any SAL_CALL SdDrawPage::getByIndex( sal_Int32 Index ) +{ + return SdGenericDrawPage::getByIndex( Index ); +} + +// XElementAccess +uno::Type SAL_CALL SdDrawPage::getElementType() +{ + return SdGenericDrawPage::getElementType(); +} + +sal_Bool SAL_CALL SdDrawPage::hasElements() +{ + return SdGenericDrawPage::hasElements(); +} + +// XShapes +void SAL_CALL SdDrawPage::add( const Reference< drawing::XShape >& xShape ) +{ + SdGenericDrawPage::add( xShape ); +} + +void SAL_CALL SdDrawPage::remove( const Reference< drawing::XShape >& xShape ) +{ + ::SolarMutexGuard aGuard; + + throwIfDisposed(); + + SdrObject* pObj = SdrObject::getSdrObjectFromXShape( xShape ); + if( pObj ) + { + GetPage()->RemovePresObj(pObj); + pObj->SetUserCall(nullptr); + } + + SdGenericDrawPage::remove( xShape ); +} + +void SdDrawPage::setBackground( const Any& rValue ) +{ + Reference< beans::XPropertySet > xSet; + + if( !(rValue >>= xSet) && !rValue.hasValue() ) + throw lang::IllegalArgumentException(); + + if( !xSet.is() ) + { + // the easy case, no background set. Set drawing::FillStyle_NONE to represent this + GetPage()->getSdrPageProperties().PutItem(XFillStyleItem(drawing::FillStyle_NONE)); + return; + } + + // is it our own implementation? + SdUnoPageBackground* pBack = comphelper::getFromUnoTunnel<SdUnoPageBackground>( xSet ); + + SfxItemSetFixed<XATTR_FILL_FIRST, XATTR_FILL_LAST> aSet( GetModel()->GetDoc()->GetPool() ); + + if( pBack ) + { + pBack->fillItemSet( static_cast<SdDrawDocument*>(&GetPage()->getSdrModelFromSdrPage()), aSet ); + } + else + { + rtl::Reference<SdUnoPageBackground> pBackground = new SdUnoPageBackground(); + + Reference< beans::XPropertySetInfo > xSetInfo( xSet->getPropertySetInfo() ); + Reference< beans::XPropertySetInfo > xDestSetInfo( pBackground->getPropertySetInfo() ); + + const Sequence< beans::Property > aProperties( xDestSetInfo->getProperties() ); + + for( const beans::Property& rProp : aProperties ) + { + const OUString aPropName( rProp.Name ); + if( xSetInfo->hasPropertyByName( aPropName ) ) + pBackground->setPropertyValue( aPropName, + xSet->getPropertyValue( aPropName ) ); + } + + pBackground->fillItemSet( static_cast<SdDrawDocument*>(&GetPage()->getSdrModelFromSdrPage()), aSet ); + } + + if( aSet.Count() == 0 ) + { + // no background fill, represent by setting drawing::FillStyle_NONE + GetPage()->getSdrPageProperties().PutItem(XFillStyleItem(drawing::FillStyle_NONE)); + } + else + { + // background fill, set at page (not sure if ClearItem is needed) + GetPage()->getSdrPageProperties().ClearItem(); + GetPage()->getSdrPageProperties().PutItemSet(aSet); + } + + // repaint only + SvxFmDrawPage::mpPage->ActionChanged(); +} + +// XAnnotationAccess: +Reference< XAnnotation > SAL_CALL SdGenericDrawPage::createAndInsertAnnotation() +{ + if( !GetPage() ) + throw DisposedException(); + + Reference< XAnnotation > xRet; + GetPage()->createAnnotation(xRet); + return xRet; +} + +void SAL_CALL SdGenericDrawPage::removeAnnotation(const Reference< XAnnotation > & annotation) +{ + GetPage()->removeAnnotation(annotation); +} + +Reference< XAnnotationEnumeration > SAL_CALL SdGenericDrawPage::createAnnotationEnumeration() +{ + return ::sd::createAnnotationEnumeration( std::vector(GetPage()->getAnnotations()) ); +} + +void SdDrawPage::getBackground(Any& rValue) +{ + const SfxItemSet& rFillAttributes = GetPage()->getSdrPageProperties().GetItemSet(); + + if(drawing::FillStyle_NONE == rFillAttributes.Get(XATTR_FILLSTYLE).GetValue()) + { + // no fill set (switched off by drawing::FillStyle_NONE), clear rValue to represent this + rValue.clear(); + } + else + { + // there is a fill set, export to rValue + Reference< beans::XPropertySet > xSet(new SdUnoPageBackground( + GetModel()->GetDoc(), + &GetPage()->getSdrPageProperties().GetItemSet())); + rValue <<= xSet; + } +} + +void SdGenericDrawPage::setNavigationOrder( const Any& rValue ) +{ + Reference< XIndexAccess > xIA( rValue, UNO_QUERY ); + if( xIA.is() ) + { + if( dynamic_cast< SdDrawPage* >( xIA.get() ) == this ) + { + if( GetPage()->HasObjectNavigationOrder() ) + GetPage()->ClearObjectNavigationOrder(); + + return; + } + else if( static_cast<size_t>(xIA->getCount()) == GetPage()->GetObjCount() ) + { + GetPage()->SetNavigationOrder(xIA); + return; + } + } + throw IllegalArgumentException(); +} + +namespace { + +class SdNavigationOrderAccess : public ::cppu::WeakImplHelper< XIndexAccess > +{ +public: + explicit SdNavigationOrderAccess(SdrPage const * pPage); + + // XIndexAccess + virtual sal_Int32 SAL_CALL getCount( ) override; + virtual Any SAL_CALL getByIndex( sal_Int32 Index ) override; + + // XElementAccess + virtual Type SAL_CALL getElementType( ) override; + virtual sal_Bool SAL_CALL hasElements( ) override; + +private: + std::vector< Reference< XShape > > maShapes; +}; + +} + +SdNavigationOrderAccess::SdNavigationOrderAccess( SdrPage const * pPage ) +: maShapes( pPage ? pPage->GetObjCount() : 0 ) +{ + if( pPage ) + { + const size_t nCount = pPage->GetObjCount(); + for( size_t nIndex = 0; nIndex < nCount; ++nIndex ) + { + SdrObject* pObj = pPage->GetObj( nIndex ); + sal_uInt32 nNavPos = pObj->GetNavigationPosition(); + DBG_ASSERT( !maShapes[nNavPos].is(), "sd::SdNavigationOrderAccess::SdNavigationOrderAccess(), duplicate navigation positions from core!" ); + maShapes[nNavPos].set( pObj->getUnoShape(), UNO_QUERY ); + } + } +} + +// XIndexAccess +sal_Int32 SAL_CALL SdNavigationOrderAccess::getCount( ) +{ + return static_cast< sal_Int32 >( maShapes.size() ); +} + +Any SAL_CALL SdNavigationOrderAccess::getByIndex( sal_Int32 Index ) +{ + if( (Index < 0) || (Index > getCount()) ) + throw IndexOutOfBoundsException(); + + return Any( maShapes[Index] ); +} + +// XElementAccess +Type SAL_CALL SdNavigationOrderAccess::getElementType( ) +{ + return cppu::UnoType<XShape>::get(); +} + +sal_Bool SAL_CALL SdNavigationOrderAccess::hasElements( ) +{ + return !maShapes.empty(); +} + +Any SdGenericDrawPage::getNavigationOrder() +{ + if( GetPage()->HasObjectNavigationOrder() ) + { + return Any( Reference< XIndexAccess >( new SdNavigationOrderAccess( GetPage() ) ) ); + } + else + { + return Any( Reference< XIndexAccess >( this ) ); + } +} + +SdMasterPage::SdMasterPage(SdXImpressDocument* pModel, SdPage* pPage) + : SdGenericDrawPage(pModel, pPage, ImplGetMasterPagePropertySet(pPage->GetPageKind())) +{ +} + +SdMasterPage::~SdMasterPage() noexcept +{ +} + +// XInterface +Any SAL_CALL SdMasterPage::queryInterface( const uno::Type & rType ) +{ + ::SolarMutexGuard aGuard; + + throwIfDisposed(); + + uno::Any aAny; + + if( rType == cppu::UnoType<container::XIndexAccess>::get() ) + aAny <<= Reference< container::XIndexAccess >(static_cast<presentation::XPresentationPage*>(this)); + else if( rType == cppu::UnoType<container::XElementAccess>::get() ) + aAny <<= Reference< container::XElementAccess >(static_cast<presentation::XPresentationPage*>(this)); + else if( rType == cppu::UnoType<container::XNamed>::get() ) + aAny <<= Reference< container::XNamed >(this); + else if( rType == cppu::UnoType<presentation::XPresentationPage>::get() && + ( IsImpressDocument() && + GetPage() && GetPage()->GetPageKind() != PageKind::Handout) ) + aAny <<= Reference< presentation::XPresentationPage >( this ); + else + return SdGenericDrawPage::queryInterface( rType ); + + return aAny; +} + +void SAL_CALL SdMasterPage::acquire() noexcept +{ + SvxDrawPage::acquire(); +} + +void SAL_CALL SdMasterPage::release() noexcept +{ + SvxDrawPage::release(); +} + +UNO3_GETIMPLEMENTATION2_IMPL( SdMasterPage, SdGenericDrawPage ); + +// XTypeProvider +Sequence< uno::Type > SAL_CALL SdMasterPage::getTypes() +{ + ::SolarMutexGuard aGuard; + + throwIfDisposed(); + + if( !maTypeSequence.hasElements() ) + { + const PageKind ePageKind = GetPage() ? GetPage()->GetPageKind() : PageKind::Standard; + bool bPresPage = IsImpressDocument() && SvxFmDrawPage::mpPage && ePageKind != PageKind::Handout; + + // Collect the types of this class. + ::std::vector<uno::Type> aTypes; + aTypes.reserve(12); + aTypes.push_back(cppu::UnoType<drawing::XDrawPage>::get()); + aTypes.push_back(cppu::UnoType<beans::XPropertySet>::get()); + aTypes.push_back(cppu::UnoType<container::XNamed>::get()); + aTypes.push_back(cppu::UnoType<lang::XServiceInfo>::get()); + aTypes.push_back(cppu::UnoType<util::XReplaceable>::get()); + aTypes.push_back(cppu::UnoType<document::XLinkTargetSupplier>::get()); + aTypes.push_back(cppu::UnoType<drawing::XShapeCombiner>::get()); + aTypes.push_back(cppu::UnoType<drawing::XShapeBinder>::get()); + aTypes.push_back(cppu::UnoType<office::XAnnotationAccess>::get()); + aTypes.push_back(cppu::UnoType<beans::XMultiPropertySet>::get()); + if( bPresPage ) + aTypes.push_back(cppu::UnoType<presentation::XPresentationPage>::get()); + if( bPresPage && ePageKind == PageKind::Standard ) + aTypes.push_back(cppu::UnoType<XAnimationNodeSupplier>::get()); + + // Get types of base class. + // Join those types in a sequence. + return comphelper::concatSequences( + comphelper::containerToSequence(aTypes), + SdGenericDrawPage::getTypes() ); + } + + return maTypeSequence; +} + +Sequence< sal_Int8 > SAL_CALL SdMasterPage::getImplementationId() +{ + return css::uno::Sequence<sal_Int8>(); +} + +// XServiceInfo +OUString SAL_CALL SdMasterPage::getImplementationName() +{ + return "SdMasterPage"; +} + +Sequence< OUString > SAL_CALL SdMasterPage::getSupportedServiceNames() +{ + ::SolarMutexGuard aGuard; + + throwIfDisposed(); + + std::vector<std::u16string_view> aAdd{ u"com.sun.star.drawing.MasterPage" }; + + if( SvxFmDrawPage::mpPage && static_cast<SdPage*>(SvxFmDrawPage::mpPage)->GetPageKind() == PageKind::Handout ) + aAdd.emplace_back(u"com.sun.star.presentation.HandoutMasterPage"); + + return comphelper::concatSequences(SdGenericDrawPage::getSupportedServiceNames(), aAdd); +} + +sal_Bool SAL_CALL SdMasterPage::supportsService( const OUString& ServiceName ) +{ + return cppu::supportsService( this, ServiceName ); +} + +// XElementAccess +sal_Bool SAL_CALL SdMasterPage::hasElements() +{ + ::SolarMutexGuard aGuard; + + throwIfDisposed(); + + if( SvxFmDrawPage::mpPage == nullptr ) + return false; + + return SvxFmDrawPage::mpPage->GetObjCount() > 0; +} + +uno::Type SAL_CALL SdMasterPage::getElementType() +{ + return SdGenericDrawPage::getElementType(); +} + +// XIndexAccess +sal_Int32 SAL_CALL SdMasterPage::getCount() +{ + ::SolarMutexGuard aGuard; + + throwIfDisposed(); + + return SdGenericDrawPage::getCount(); +} + +Any SAL_CALL SdMasterPage::getByIndex( sal_Int32 Index ) +{ + ::SolarMutexGuard aGuard; + + throwIfDisposed(); + + return SdGenericDrawPage::getByIndex(Index); +} + +// intern +void SdMasterPage::setBackground( const Any& rValue ) +{ + // we need at least a beans::XPropertySet + Reference< beans::XPropertySet > xInputSet( rValue, UNO_QUERY ); + if( !xInputSet.is() ) + throw lang::IllegalArgumentException(); + + try + { + if( GetModel() && IsImpressDocument() ) + { + Reference< container::XNameAccess > xFamilies( GetModel()->getStyleFamilies(), UNO_SET_THROW ); + Reference< container::XNameAccess > xFamily( xFamilies->getByName( getName() ), UNO_QUERY_THROW ) ; + + Reference< beans::XPropertySet > xStyleSet( xFamily->getByName( sUNO_PseudoSheet_Background ), UNO_QUERY_THROW ); + + Reference< beans::XPropertySetInfo > xSetInfo( xInputSet->getPropertySetInfo(), UNO_SET_THROW ); + Reference< beans::XPropertyState > xSetStates( xInputSet, UNO_QUERY ); + + for( const auto pProp : ImplGetPageBackgroundPropertySet()->getPropertyMap().getPropertyEntries() ) + { + const OUString& rPropName = pProp->aName; + if( xSetInfo->hasPropertyByName( rPropName ) ) + { + if( !xSetStates.is() || xSetStates->getPropertyState( rPropName ) == beans::PropertyState_DIRECT_VALUE ) + xStyleSet->setPropertyValue( rPropName, xInputSet->getPropertyValue( rPropName ) ); + else + xSetStates->setPropertyToDefault( rPropName ); + } + } + } + else + { + // first fill an item set + // is it our own implementation? + SdUnoPageBackground* pBack = comphelper::getFromUnoTunnel<SdUnoPageBackground>( xInputSet ); + + SfxItemSetFixed<XATTR_FILL_FIRST, XATTR_FILL_LAST> aSet( GetModel()->GetDoc()->GetPool() ); + + if( pBack ) + { + pBack->fillItemSet( static_cast<SdDrawDocument*>(&GetPage()->getSdrModelFromSdrPage()), aSet ); + } + else + { + rtl::Reference<SdUnoPageBackground> pBackground = new SdUnoPageBackground(); + + Reference< beans::XPropertySetInfo > xInputSetInfo( xInputSet->getPropertySetInfo(), UNO_SET_THROW ); + Reference< beans::XPropertySetInfo > xDestSetInfo( pBackground->getPropertySetInfo(), UNO_SET_THROW ); + + const uno::Sequence< beans::Property> aProperties( xDestSetInfo->getProperties() ); + + for( const beans::Property& rProp : aProperties ) + { + const OUString aPropName( rProp.Name ); + if( xInputSetInfo->hasPropertyByName( aPropName ) ) + pBackground->setPropertyValue( aPropName, xInputSet->getPropertyValue( aPropName ) ); + } + + pBackground->fillItemSet( static_cast<SdDrawDocument*>(&SvxFmDrawPage::mpPage->getSdrModelFromSdrPage()), aSet ); + } + + // if we find the background style, copy the set to the background + SdDrawDocument* pDoc = static_cast<SdDrawDocument*>(&SvxFmDrawPage::mpPage->getSdrModelFromSdrPage()); + SfxStyleSheetBasePool* pSSPool = pDoc->GetStyleSheetPool(); + if(pSSPool) + { + OUString aLayoutName( static_cast< SdPage* >( SvxFmDrawPage::mpPage )->GetLayoutName() ); + aLayoutName = OUString::Concat(aLayoutName.subView(0, aLayoutName.indexOf(SD_LT_SEPARATOR)+4)) + + STR_LAYOUT_BACKGROUND; + SfxStyleSheetBase* pStyleSheet = pSSPool->Find( aLayoutName, SfxStyleFamily::Page ); + + if( pStyleSheet ) + { + pStyleSheet->GetItemSet().Put( aSet ); + + // repaint only + SvxFmDrawPage::mpPage->ActionChanged(); + return; + } + } + + // if no background style is available, set at page directly. This + // is an error and should NOT happen (and will be asserted from the SdrPage) + GetPage()->getSdrPageProperties().PutItemSet(aSet); + } + } + catch( Exception& ) + { + TOOLS_WARN_EXCEPTION( "sd", "sd::SdMasterPage::setBackground()"); + } +} + +void SdMasterPage::getBackground( Any& rValue ) +{ + if( !GetModel() ) + return; + + try + { + if( IsImpressDocument() ) + { + Reference< container::XNameAccess > xFamilies( GetModel()->getStyleFamilies(), UNO_SET_THROW ); + Reference< container::XNameAccess > xFamily( xFamilies->getByName( getName() ), UNO_QUERY_THROW ); + + rValue <<= Reference< beans::XPropertySet >( xFamily->getByName( sUNO_PseudoSheet_Background ), UNO_QUERY_THROW ); + } + else + { + SdDrawDocument* pDoc = static_cast<SdDrawDocument*>(&SvxFmDrawPage::mpPage->getSdrModelFromSdrPage()); + SfxStyleSheetBasePool* pSSPool = pDoc->GetStyleSheetPool(); + if(pSSPool) + { + OUString aLayoutName( static_cast< SdPage* >(SvxFmDrawPage::mpPage)->GetLayoutName() ); + aLayoutName = OUString::Concat(aLayoutName.subView(0, aLayoutName.indexOf(SD_LT_SEPARATOR)+4)) + + STR_LAYOUT_BACKGROUND; + SfxStyleSheetBase* pStyleSheet = pSSPool->Find( aLayoutName, SfxStyleFamily::Page ); + + if( pStyleSheet ) + { + SfxItemSet aStyleSet( pStyleSheet->GetItemSet()); + if( aStyleSet.Count() ) + { + rValue <<= Reference< beans::XPropertySet >( new SdUnoPageBackground( pDoc, &aStyleSet ) ); + return; + } + } + } + + // No style found, use fill attributes from page background. This + // should NOT happen and is an error + const SfxItemSet& rFallbackItemSet(SvxFmDrawPage::mpPage->getSdrPageProperties().GetItemSet()); + + if(drawing::FillStyle_NONE == rFallbackItemSet.Get(XATTR_FILLSTYLE).GetValue()) + { + rValue <<= Reference< beans::XPropertySet >( + new SdUnoPageBackground(GetModel()->GetDoc(), &rFallbackItemSet)); + } + else + { + rValue.clear(); + } + } + } + catch( Exception& ) + { + TOOLS_WARN_EXCEPTION( "sd", "sd::SdMasterPage::getBackground()"); + rValue.clear(); + } +} + +// XNamed +void SAL_CALL SdMasterPage::setName( const OUString& rName ) +{ + ::SolarMutexGuard aGuard; + + throwIfDisposed(); + + if(!(SvxFmDrawPage::mpPage && GetPage()->GetPageKind() != PageKind::Notes)) + return; + + SdDrawDocument* pDoc = GetModel()->GetDoc(); + bool bOutDummy; + + // Slide Name has to be unique + if( pDoc && pDoc->GetPageByName( rName, bOutDummy ) != SDRPAGE_NOTFOUND ) + return; // throw Exception ? + + GetPage()->SetName( rName ); + + if( pDoc ) + pDoc->RenameLayoutTemplate( GetPage()->GetLayoutName(), rName ); + + // fake a mode change to repaint the page tab bar + ::sd::DrawDocShell* pDocSh = GetModel()->GetDocShell(); + ::sd::ViewShell* pViewSh = pDocSh ? pDocSh->GetViewShell() : nullptr; + if( auto pDrawViewSh = dynamic_cast< ::sd::DrawViewShell* >(pViewSh) ) + { + EditMode eMode = pDrawViewSh->GetEditMode(); + if( eMode == EditMode::MasterPage ) + { + bool bLayer = pDrawViewSh->IsLayerModeActive(); + + pDrawViewSh->ChangeEditMode( eMode, !bLayer ); + pDrawViewSh->ChangeEditMode( eMode, bLayer ); + } + } + + GetModel()->SetModified(); +} + +OUString SAL_CALL SdMasterPage::getName( ) +{ + ::SolarMutexGuard aGuard; + + throwIfDisposed(); + + if(SvxFmDrawPage::mpPage) + { + OUString aLayoutName( GetPage()->GetLayoutName() ); + return aLayoutName.copy(0, aLayoutName.indexOf(SD_LT_SEPARATOR)); + } + + return OUString(); +} + +// XPresentationPage +Reference< drawing::XDrawPage > SAL_CALL SdMasterPage::getNotesPage() +{ + ::SolarMutexGuard aGuard; + + throwIfDisposed(); + + if(SvxFmDrawPage::mpPage && GetModel()->GetDoc() ) + { + SdPage* pNotesPage = GetModel()->GetDoc()->GetMasterSdPage( (SvxFmDrawPage::mpPage->GetPageNum()-1)>>1, PageKind::Notes ); + if( pNotesPage ) + { + Reference< drawing::XDrawPage > xPage( pNotesPage->getUnoPage(), uno::UNO_QUERY ); + return xPage; + } + } + return nullptr; +} + +// XShapes +void SAL_CALL SdMasterPage::add( const Reference< drawing::XShape >& xShape ) +{ + SdGenericDrawPage::add( xShape ); +} + +void SAL_CALL SdMasterPage::remove( const Reference< drawing::XShape >& xShape ) +{ + ::SolarMutexGuard aGuard; + + throwIfDisposed(); + + SdrObject* pObj = SdrObject::getSdrObjectFromXShape( xShape ); + if( pObj && GetPage()->IsPresObj( pObj ) ) + GetPage()->RemovePresObj(pObj); + + SdGenericDrawPage::remove( xShape ); +} + +Reference< uno::XInterface > createUnoPageImpl( SdPage* pPage ) +{ + Reference< uno::XInterface > xPage; + + if( pPage ) + { + SdXImpressDocument* pModel = comphelper::getFromUnoTunnel<SdXImpressDocument>( pPage->getSdrModelFromSdrPage().getUnoModel() ); + if( pModel ) + { + if( pPage->IsMasterPage() ) + { + xPage = static_cast<cppu::OWeakObject*>(new SdMasterPage( pModel, pPage )); + } + else + { + xPage = static_cast<cppu::OWeakObject*>(new SdDrawPage( pModel, pPage )); + } + } + } + + return xPage; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/unoidl/unopback.cxx b/sd/source/ui/unoidl/unopback.cxx new file mode 100644 index 000000000..508b1f866 --- /dev/null +++ b/sd/source/ui/unoidl/unopback.cxx @@ -0,0 +1,410 @@ +/* -*- 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 <com/sun/star/drawing/BitmapMode.hpp> +#include <vcl/svapp.hxx> +#include <svl/itemset.hxx> +#include <svx/svdpool.hxx> +#include <cppuhelper/supportsservice.hxx> +#include <svx/xflbstit.hxx> +#include <svx/xflbmtit.hxx> +#include <svx/svdobj.hxx> +#include <svx/unoshape.hxx> +#include <svx/unoshprp.hxx> + +#include "unopback.hxx" +#include <drawdoc.hxx> +#include <unokywds.hxx> + +using namespace ::com::sun::star; + +const SvxItemPropertySet* ImplGetPageBackgroundPropertySet() +{ + static const SfxItemPropertyMapEntry aPageBackgroundPropertyMap_Impl[] = + { + FILL_PROPERTIES + { u"", 0, css::uno::Type(), 0, 0 } + }; + + static SvxItemPropertySet aPageBackgroundPropertySet_Impl( aPageBackgroundPropertyMap_Impl, SdrObject::GetGlobalDrawObjectItemPool() ); + return &aPageBackgroundPropertySet_Impl; +} + +UNO3_GETIMPLEMENTATION_IMPL( SdUnoPageBackground ); + +SdUnoPageBackground::SdUnoPageBackground( + SdDrawDocument* pDoc /* = NULL */, + const SfxItemSet* pSet /* = NULL */) +: mpPropSet(ImplGetPageBackgroundPropertySet()), + mpDoc(pDoc) +{ + if( pDoc ) + { + StartListening( *pDoc ); + mpSet = std::make_unique<SfxItemSetFixed<XATTR_FILL_FIRST, XATTR_FILL_LAST>>( pDoc->GetPool() ); + + if( pSet ) + mpSet->Put(*pSet); + } +} + +SdUnoPageBackground::~SdUnoPageBackground() noexcept +{ + SolarMutexGuard g; + + if( mpDoc ) + EndListening( *mpDoc ); +} + +void SdUnoPageBackground::Notify( SfxBroadcaster&, const SfxHint& rHint ) +{ + if (rHint.GetId() != SfxHintId::ThisIsAnSdrHint) + return; + const SdrHint* pSdrHint = static_cast<const SdrHint*>( &rHint ); + + // delete item set if document is dying because then the pool + // will also die + if( pSdrHint->GetKind() == SdrHintKind::ModelCleared ) + { + mpSet.reset(); + mpDoc = nullptr; + } +} + +void SdUnoPageBackground::fillItemSet( SdDrawDocument* pDoc, SfxItemSet& rSet ) +{ + rSet.ClearItem(); + + if( mpSet == nullptr ) + { + StartListening( *pDoc ); + mpDoc = pDoc; + + mpSet = std::make_unique<SfxItemSetFixed<XATTR_FILL_FIRST, XATTR_FILL_LAST>>( *rSet.GetPool() ); + + if( maUsrAnys.AreThereOwnUsrAnys() ) + { + for( const auto pProp : mpPropSet->getPropertyMap().getPropertyEntries() ) + { + uno::Any* pAny = maUsrAnys.GetUsrAnyForID( *pProp ); + if( pAny ) + { + const OUString & aPropertyName = pProp->aName; + switch( pProp->nWID ) + { + case XATTR_FILLFLOATTRANSPARENCE : + case XATTR_FILLGRADIENT : + { + if ( ( pAny->getValueType() == ::cppu::UnoType< css::awt::Gradient>::get() ) + && ( pProp->nMemberId == MID_FILLGRADIENT ) ) + { + setPropertyValue( aPropertyName, *pAny ); + } + else if ( ( pAny->getValueType() == ::cppu::UnoType<OUString>::get() ) && + ( pProp->nMemberId == MID_NAME ) ) + { + setPropertyValue( aPropertyName, *pAny ); + } + } + break; + case XATTR_FILLHATCH : + { + if ( ( pAny->getValueType() == ::cppu::UnoType< css::drawing::Hatch>::get() ) + && ( pProp->nMemberId == MID_FILLHATCH ) ) + { + setPropertyValue( aPropertyName, *pAny ); + } + else if ( ( pAny->getValueType() == ::cppu::UnoType<OUString>::get() ) && + ( pProp->nMemberId == MID_NAME ) ) + { + setPropertyValue( aPropertyName, *pAny ); + } + } + break; + case XATTR_FILLBITMAP : + { + if (pProp->nMemberId == MID_BITMAP && + (pAny->getValueType() == cppu::UnoType<css::awt::XBitmap>::get() || + pAny->getValueType() == cppu::UnoType<css::graphic::XGraphic>::get())) + { + setPropertyValue( aPropertyName, *pAny ); + } + else if (pAny->getValueType() == ::cppu::UnoType<OUString>::get() && pProp->nMemberId == MID_NAME) + { + setPropertyValue( aPropertyName, *pAny ); + } + } + break; + + default: + setPropertyValue( aPropertyName, *pAny ); + } + } + } + } + } + + rSet.Put( *mpSet ); +} + +// XServiceInfo +OUString SAL_CALL SdUnoPageBackground::getImplementationName() +{ + return "SdUnoPageBackground"; +} + +sal_Bool SAL_CALL SdUnoPageBackground::supportsService( const OUString& ServiceName ) +{ + return cppu::supportsService( this, ServiceName ); +} + +uno::Sequence< OUString > SAL_CALL SdUnoPageBackground::getSupportedServiceNames() +{ + return { sUNO_Service_PageBackground, sUNO_Service_FillProperties }; +} + +// XPropertySet +uno::Reference< beans::XPropertySetInfo > SAL_CALL SdUnoPageBackground::getPropertySetInfo() +{ + return mpPropSet->getPropertySetInfo(); +} + +void SAL_CALL SdUnoPageBackground::setPropertyValue( const OUString& aPropertyName, const uno::Any& aValue ) +{ + SolarMutexGuard aGuard; + + const SfxItemPropertyMapEntry* pEntry = getPropertyMapEntry( aPropertyName ); + + if( pEntry == nullptr ) + { + throw beans::UnknownPropertyException( aPropertyName, static_cast<cppu::OWeakObject*>(this)); + } + + if( mpSet ) + { + if( pEntry->nWID == OWN_ATTR_FILLBMP_MODE ) + { + drawing::BitmapMode eMode; + if( aValue >>= eMode ) + { + mpSet->Put( XFillBmpStretchItem( eMode == drawing::BitmapMode_STRETCH ) ); + mpSet->Put( XFillBmpTileItem( eMode == drawing::BitmapMode_REPEAT ) ); + return; + } + throw lang::IllegalArgumentException(); + } + + SfxItemPool& rPool = *mpSet->GetPool(); + SfxItemSet aSet( rPool, pEntry->nWID, pEntry->nWID); + aSet.Put( *mpSet ); + + if( !aSet.Count() ) + aSet.Put( rPool.GetDefaultItem( pEntry->nWID ) ); + + if( pEntry->nMemberId == MID_NAME && ( pEntry->nWID == XATTR_FILLBITMAP || pEntry->nWID == XATTR_FILLGRADIENT || pEntry->nWID == XATTR_FILLHATCH || pEntry->nWID == XATTR_FILLFLOATTRANSPARENCE ) ) + { + OUString aName; + if(!(aValue >>= aName )) + throw lang::IllegalArgumentException(); + + SvxShape::SetFillAttribute( pEntry->nWID, aName, aSet ); + } + else + { + SvxItemPropertySet_setPropertyValue( pEntry, aValue, aSet ); + } + + mpSet->Put( aSet ); + } + else + { + if(pEntry->nWID) + SvxItemPropertySet::setPropertyValue( pEntry, aValue, maUsrAnys ); + } +} + +uno::Any SAL_CALL SdUnoPageBackground::getPropertyValue( const OUString& PropertyName ) +{ + SolarMutexGuard aGuard; + + uno::Any aAny; + const SfxItemPropertyMapEntry* pEntry = getPropertyMapEntry(PropertyName); + + if( pEntry == nullptr ) + { + throw beans::UnknownPropertyException( PropertyName, static_cast<cppu::OWeakObject*>(this)); + } + + if( mpSet ) + { + if( pEntry->nWID == OWN_ATTR_FILLBMP_MODE ) + { + const XFillBmpStretchItem* pStretchItem = mpSet->GetItem<XFillBmpStretchItem>(XATTR_FILLBMP_STRETCH); + const XFillBmpTileItem* pTileItem = mpSet->GetItem<XFillBmpTileItem>(XATTR_FILLBMP_TILE); + + if( pStretchItem && pTileItem ) + { + if( pTileItem->GetValue() ) + aAny <<= drawing::BitmapMode_REPEAT; + else if( pStretchItem->GetValue() ) + aAny <<= drawing::BitmapMode_STRETCH; + else + aAny <<= drawing::BitmapMode_NO_REPEAT; + } + } + else + { + SfxItemPool& rPool = *mpSet->GetPool(); + SfxItemSet aSet( rPool, pEntry->nWID, pEntry->nWID); + aSet.Put( *mpSet ); + + if( !aSet.Count() ) + aSet.Put( rPool.GetDefaultItem( pEntry->nWID ) ); + + // get value from ItemSet + aAny = SvxItemPropertySet_getPropertyValue( pEntry, aSet ); + } + } + else + { + if(pEntry->nWID) + aAny = mpPropSet->getPropertyValue( pEntry, maUsrAnys ); + } + return aAny; +} + +void SAL_CALL SdUnoPageBackground::addPropertyChangeListener( const OUString& , const uno::Reference< beans::XPropertyChangeListener >& ) {} +void SAL_CALL SdUnoPageBackground::removePropertyChangeListener( const OUString& , const uno::Reference< beans::XPropertyChangeListener >& ) {} +void SAL_CALL SdUnoPageBackground::addVetoableChangeListener( const OUString& , const uno::Reference< beans::XVetoableChangeListener >& ) {} +void SAL_CALL SdUnoPageBackground::removeVetoableChangeListener( const OUString& , const uno::Reference< beans::XVetoableChangeListener >& ) {} + +// XPropertyState +beans::PropertyState SAL_CALL SdUnoPageBackground::getPropertyState( const OUString& PropertyName ) +{ + SolarMutexGuard aGuard; + + const SfxItemPropertyMapEntry* pEntry = getPropertyMapEntry(PropertyName); + + if( pEntry == nullptr ) + throw beans::UnknownPropertyException( PropertyName, static_cast<cppu::OWeakObject*>(this)); + + if( mpSet ) + { + if( pEntry->nWID == OWN_ATTR_FILLBMP_MODE ) + { + if( mpSet->GetItemState( XATTR_FILLBMP_STRETCH, false ) == SfxItemState::SET || + mpSet->GetItemState( XATTR_FILLBMP_TILE, false ) == SfxItemState::SET ) + { + return beans::PropertyState_DIRECT_VALUE; + } + else + { + return beans::PropertyState_AMBIGUOUS_VALUE; + } + } + + switch( mpSet->GetItemState( pEntry->nWID, false ) ) + { + case SfxItemState::SET: + return beans::PropertyState_DIRECT_VALUE; + case SfxItemState::DEFAULT: + return beans::PropertyState_DEFAULT_VALUE; + default: +// case SfxItemState::DONTCARE: +// case SfxItemState::DISABLED: + return beans::PropertyState_AMBIGUOUS_VALUE; + } + } + else + { + if( nullptr == maUsrAnys.GetUsrAnyForID(*pEntry) ) + return beans::PropertyState_DEFAULT_VALUE; + else + return beans::PropertyState_DIRECT_VALUE; + } +} + +uno::Sequence< beans::PropertyState > SAL_CALL SdUnoPageBackground::getPropertyStates( const uno::Sequence< OUString >& aPropertyName ) +{ + SolarMutexGuard aGuard; + + sal_Int32 nCount = aPropertyName.getLength(); + + uno::Sequence< beans::PropertyState > aPropertyStateSequence( nCount ); + + std::transform(aPropertyName.begin(), aPropertyName.end(), aPropertyStateSequence.getArray(), + [this](const OUString& rName) -> beans::PropertyState { return getPropertyState(rName); }); + + return aPropertyStateSequence; +} + +void SAL_CALL SdUnoPageBackground::setPropertyToDefault( const OUString& PropertyName ) +{ + SolarMutexGuard aGuard; + + const SfxItemPropertyMapEntry* pEntry = getPropertyMapEntry(PropertyName); + + if( pEntry == nullptr ) + throw beans::UnknownPropertyException( PropertyName, static_cast<cppu::OWeakObject*>(this)); + + if( mpSet ) + { + if( pEntry->nWID == OWN_ATTR_FILLBMP_MODE ) + { + mpSet->ClearItem( XATTR_FILLBMP_STRETCH ); + mpSet->ClearItem( XATTR_FILLBMP_TILE ); + } + else + { + mpSet->ClearItem( pEntry->nWID ); + } + } +} + +uno::Any SAL_CALL SdUnoPageBackground::getPropertyDefault( const OUString& aPropertyName ) +{ + SolarMutexGuard aGuard; + + const SfxItemPropertyMapEntry* pEntry = getPropertyMapEntry(aPropertyName); + if( pEntry == nullptr || mpSet == nullptr ) + throw beans::UnknownPropertyException( aPropertyName, static_cast<cppu::OWeakObject*>(this)); + + uno::Any aAny; + if (pEntry->nWID == OWN_ATTR_FILLBMP_MODE) + { + aAny <<= drawing::BitmapMode_REPEAT; + } + else + { + SfxItemPool& rPool = *mpSet->GetPool(); + SfxItemSet aSet(rPool, pEntry->nWID, pEntry->nWID); + aSet.Put(rPool.GetDefaultItem(pEntry->nWID)); + + aAny = SvxItemPropertySet_getPropertyValue(pEntry, aSet); + } + return aAny; +} + +/** this is used because our property map is not sorted yet */ +const SfxItemPropertyMapEntry* SdUnoPageBackground::getPropertyMapEntry( std::u16string_view rPropertyName ) const noexcept +{ + return mpPropSet->getPropertyMap().getByName(rPropertyName); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/unoidl/unopback.hxx b/sd/source/ui/unoidl/unopback.hxx new file mode 100644 index 000000000..c70cc2fea --- /dev/null +++ b/sd/source/ui/unoidl/unopback.hxx @@ -0,0 +1,89 @@ +/* -*- 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 <memory> + +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/beans/XPropertyState.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XUnoTunnel.hpp> + +#include <svl/lstner.hxx> +#include <comphelper/servicehelper.hxx> + +#include <cppuhelper/implbase.hxx> +#include <editeng/unoipset.hxx> + +class SdDrawDocument; +class SdrModel; +class SfxItemSet; +class SvxItemPropertySet; +struct SfxItemPropertyMapEntry; + +const SvxItemPropertySet* ImplGetPageBackgroundPropertySet(); + +class SdUnoPageBackground final : public ::cppu::WeakImplHelper< + css::beans::XPropertySet, + css::lang::XServiceInfo, + css::beans::XPropertyState, + css::lang::XUnoTunnel>, + public SfxListener +{ + const SvxItemPropertySet* mpPropSet; + SvxItemPropertySetUsrAnys maUsrAnys; + std::unique_ptr<SfxItemSet> mpSet; + SdrModel* mpDoc; + + const SfxItemPropertyMapEntry* getPropertyMapEntry( std::u16string_view rPropertyName ) const noexcept; +public: + SdUnoPageBackground( SdDrawDocument* pDoc = nullptr, const SfxItemSet* pSet = nullptr); + virtual ~SdUnoPageBackground() noexcept override; + + // internal + void fillItemSet( SdDrawDocument* pDoc, SfxItemSet& rSet ); + virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) override; + + // uno helper + UNO3_GETIMPLEMENTATION_DECL( SdUnoPageBackground ) + + // 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; + + // XPropertySet + 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; + + // XPropertyState + virtual css::beans::PropertyState SAL_CALL getPropertyState( const OUString& PropertyName ) override; + virtual css::uno::Sequence< css::beans::PropertyState > SAL_CALL getPropertyStates( const css::uno::Sequence< OUString >& aPropertyName ) override; + virtual void SAL_CALL setPropertyToDefault( const OUString& PropertyName ) override; + virtual css::uno::Any SAL_CALL getPropertyDefault( const OUString& aPropertyName ) override; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/unoidl/unopool.cxx b/sd/source/ui/unoidl/unopool.cxx new file mode 100644 index 000000000..7345dc45d --- /dev/null +++ b/sd/source/ui/unoidl/unopool.cxx @@ -0,0 +1,89 @@ +/* -*- 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 <i18nlangtag/languagetag.hxx> +#include <comphelper/propertysetinfo.hxx> +#include <editeng/eeitem.hxx> +#include <svx/unopool.hxx> + +#include <drawdoc.hxx> +#include "unopool.hxx" + +using namespace ::com::sun::star; +using namespace ::cppu; +using namespace ::comphelper; + +static LanguageType SdUnoGetLanguage( const lang::Locale& rLocale ) +{ + // empty language -> LANGUAGE_SYSTEM + if ( rLocale.Language.getLength() == 0 ) + return LANGUAGE_SYSTEM; + + LanguageType eRet = LanguageTag::convertToLanguageType( rLocale, false); + if ( eRet == LANGUAGE_NONE ) + eRet = LANGUAGE_SYSTEM; //! or throw an exception? + + return eRet; +} + +namespace { + +class SdUnoDrawPool : public SvxUnoDrawPool +{ +public: + explicit SdUnoDrawPool(SdDrawDocument* pModel); + +protected: + virtual void putAny( SfxItemPool* pPool, const PropertyMapEntry* pEntry, const uno::Any& rValue ) override; + +private: + SdDrawDocument* mpDrawModel; +}; + +} + +SdUnoDrawPool::SdUnoDrawPool(SdDrawDocument* pModel) +: SvxUnoDrawPool( pModel ), mpDrawModel( pModel ) +{ +} + +void SdUnoDrawPool::putAny( SfxItemPool* pPool, const comphelper::PropertyMapEntry* pEntry, const uno::Any& rValue ) +{ + switch( pEntry->mnHandle ) + { + case EE_CHAR_LANGUAGE: + case EE_CHAR_LANGUAGE_CJK: + case EE_CHAR_LANGUAGE_CTL: + { + lang::Locale aLocale; + if( rValue >>= aLocale ) + mpDrawModel->SetLanguage( + SdUnoGetLanguage( aLocale ), + static_cast<sal_uInt16>(pEntry->mnHandle) ); + } + } + SvxUnoDrawPool::putAny( pPool, pEntry, rValue ); +} + +uno::Reference< uno::XInterface > SdUnoCreatePool( SdDrawDocument* pDrawModel ) +{ + return static_cast<uno::XAggregation*>(new SdUnoDrawPool( pDrawModel )); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/unoidl/unopool.hxx b/sd/source/ui/unoidl/unopool.hxx new file mode 100644 index 000000000..4188e80a9 --- /dev/null +++ b/sd/source/ui/unoidl/unopool.hxx @@ -0,0 +1,29 @@ +/* -*- 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 <com/sun/star/uno/Reference.hxx> +#include <drawdoc.hxx> + +css::uno::Reference<css::uno::XInterface> SdUnoCreatePool(SdDrawDocument* pDrawModel); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/unoidl/unosrch.cxx b/sd/source/ui/unoidl/unosrch.cxx new file mode 100644 index 000000000..f1005819d --- /dev/null +++ b/sd/source/ui/unoidl/unosrch.cxx @@ -0,0 +1,778 @@ +/* -*- 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 <memory> +#include <sal/config.h> + +#include <com/sun/star/drawing/XShapes.hpp> +#include <com/sun/star/drawing/XDrawPage.hpp> +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> +#include <vcl/svapp.hxx> + +#include <svx/svdobj.hxx> +#include <svx/svdpool.hxx> +#include <editeng/unoipset.hxx> +#include <editeng/unotext.hxx> +#include <tools/debug.hxx> + +#include <unoprnms.hxx> +#include <unosrch.hxx> + +using namespace ::com::sun::star; + +#define WID_SEARCH_BACKWARDS 0 +#define WID_SEARCH_CASE 1 +#define WID_SEARCH_WORDS 2 + +static const SfxItemPropertyMapEntry* ImplGetSearchPropertyMap() +{ + static const SfxItemPropertyMapEntry aSearchPropertyMap_Impl[] = + { + { u"" UNO_NAME_SEARCH_BACKWARDS, WID_SEARCH_BACKWARDS, cppu::UnoType<bool>::get(), 0, 0 }, + { u"" UNO_NAME_SEARCH_CASE, WID_SEARCH_CASE, cppu::UnoType<bool>::get(), 0, 0 }, + { u"" UNO_NAME_SEARCH_WORDS, WID_SEARCH_WORDS, cppu::UnoType<bool>::get(), 0, 0 }, + { u"", 0, css::uno::Type(), 0, 0 } + }; + + return aSearchPropertyMap_Impl; +} + +namespace { + +class SearchContext_impl +{ + uno::Reference< drawing::XShapes > mxShapes; + sal_Int32 mnIndex; + +public: + SearchContext_impl(uno::Reference<drawing::XShapes> const& xShapes) + : mxShapes( xShapes ), mnIndex( -1 ) {} + + uno::Reference< drawing::XShape > firstShape() + { + mnIndex = -1; + return nextShape(); + } + + uno::Reference< drawing::XShape > nextShape() + { + uno::Reference< drawing::XShape > xShape; + mnIndex++; + if( mxShapes.is() && mxShapes->getCount() > mnIndex ) + { + mxShapes->getByIndex( mnIndex ) >>= xShape; + } + return xShape; + } +}; + +} + +/* ================================================================= */ +/** this class implements a search or replace operation on a given + page or a given sdrobj + */ + +SdUnoSearchReplaceShape::SdUnoSearchReplaceShape( drawing::XDrawPage* pPage ) noexcept + : mpPage(pPage) +{ +} + +SdUnoSearchReplaceShape::~SdUnoSearchReplaceShape() noexcept +{ +} + +// util::XReplaceable +uno::Reference< util::XReplaceDescriptor > SAL_CALL SdUnoSearchReplaceShape::createReplaceDescriptor() +{ + return new SdUnoSearchReplaceDescriptor; +} + +sal_Int32 SAL_CALL SdUnoSearchReplaceShape::replaceAll( const uno::Reference< util::XSearchDescriptor >& xDesc ) +{ + SdUnoSearchReplaceDescriptor* pDescr = comphelper::getFromUnoTunnel<SdUnoSearchReplaceDescriptor>( xDesc ); + if( pDescr == nullptr ) + return 0; + + sal_Int32 nFound = 0; + + uno::Reference< drawing::XShapes > xShapes; + uno::Reference< drawing::XShape > xShape; + + std::vector<SearchContext_impl> aContexts; + if(mpPage) + { + xShapes = mpPage; + + if( xShapes->getCount() ) + { + aContexts.push_back(SearchContext_impl(xShapes)); + xShape = aContexts.back().firstShape(); + } + else + { + xShapes = nullptr; + } + } + + while( xShape.is() ) + { + // replace in xShape + uno::Reference< text::XText > xText(xShape, uno::UNO_QUERY); + uno::Reference< text::XTextRange > xRange = xText; + uno::Reference< text::XTextRange > xFound; + + while( xRange.is() ) + { + xFound = Search( xRange, pDescr ); + if( !xFound.is() ) + break; + + xFound->setString( pDescr->getReplaceString() ); + xRange = xFound->getEnd(); + nFound++; + } + // done with xShape -> get next shape + + // test if it's a group + uno::Reference< drawing::XShapes > xGroupShape( xShape, uno::UNO_QUERY ); + if( xGroupShape.is() && ( xGroupShape->getCount() > 0 ) ) + { + aContexts.push_back(SearchContext_impl(xGroupShape)); + xShape = aContexts.back().firstShape(); + } + else + { + if (!aContexts.empty()) + xShape = aContexts.back().nextShape(); + else + xShape = nullptr; + } + + // test parent contexts for next shape if none + // is found in the current context + while (!aContexts.empty() && !xShape.is()) + { + aContexts.pop_back(); + if (!aContexts.empty()) + xShape = aContexts.back().nextShape(); + } + } + + return nFound; +} + +// XSearchable +uno::Reference< css::util::XSearchDescriptor > SAL_CALL SdUnoSearchReplaceShape::createSearchDescriptor( ) +{ + return new SdUnoSearchReplaceDescriptor; +} + +uno::Reference< css::container::XIndexAccess > SAL_CALL SdUnoSearchReplaceShape::findAll( const css::uno::Reference< css::util::XSearchDescriptor >& xDesc ) +{ + SdUnoSearchReplaceDescriptor* pDescr = comphelper::getFromUnoTunnel<SdUnoSearchReplaceDescriptor>( xDesc ); + if( pDescr == nullptr ) + return uno::Reference< container::XIndexAccess > (); + + sal_Int32 nSequence = 32; + sal_Int32 nFound = 0; + + uno::Sequence < uno::Reference< uno::XInterface > > aSeq( nSequence ); + + uno::Reference< uno::XInterface > * pArray = aSeq.getArray(); + + uno::Reference< drawing::XShapes > xShapes; + uno::Reference< drawing::XShape > xShape; + + std::vector<SearchContext_impl> aContexts; + if(mpPage) + { + xShapes = mpPage; + + if( xShapes->getCount() > 0 ) + { + aContexts.push_back(SearchContext_impl(xShapes)); + xShape = aContexts.back().firstShape(); + } + else + { + xShapes = nullptr; + } + } + + while( xShape.is() ) + { + // find in xShape + uno::Reference< text::XText > xText(xShape, uno::UNO_QUERY); + uno::Reference< text::XTextRange > xRange = xText; + uno::Reference< text::XTextRange > xFound; + + while( xRange.is() ) + { + xFound = Search( xRange, pDescr ); + if( !xFound.is() ) + break; + + if( nFound >= nSequence ) + { + nSequence += 32; + aSeq.realloc( nSequence ); + pArray = aSeq.getArray(); + } + + pArray[nFound++] = xFound; + + xRange = xFound->getEnd(); + } + // done with shape -> get next shape + + // test if it's a group + uno::Reference< drawing::XShapes > xGroupShape; + xGroupShape.set( xShape, uno::UNO_QUERY ); + + if( xGroupShape.is() && xGroupShape->getCount() > 0 ) + { + aContexts.push_back(SearchContext_impl(xGroupShape)); + xShape = aContexts.back().firstShape(); + } + else + { + if (!aContexts.empty()) + xShape = aContexts.back().nextShape(); + else + xShape = nullptr; + } + + // test parent contexts for next shape if none + // is found in the current context + while (!aContexts.empty() && !xShape.is()) + { + aContexts.pop_back(); + if (!aContexts.empty()) + xShape = aContexts.back().nextShape(); + } + } + + if( nFound != nSequence ) + aSeq.realloc( nFound ); + + uno::Reference<css::container::XIndexAccess> xRet(new SdUnoFindAllAccess(aSeq)); + return xRet; +} + +uno::Reference< css::uno::XInterface > SAL_CALL SdUnoSearchReplaceShape::findFirst( const css::uno::Reference< css::util::XSearchDescriptor >& xDesc ) +{ + uno::Reference< text::XTextRange > xRange( GetCurrentShape(), uno::UNO_QUERY ); + if( xRange.is() ) + return findNext( xRange, xDesc ); + + return uno::Reference< uno::XInterface > (); +} + +uno::Reference< drawing::XShape > SdUnoSearchReplaceShape::GetCurrentShape() const noexcept +{ + uno::Reference< drawing::XShape > xShape; + + if( mpPage && mpPage->getCount() > 0) + mpPage->getByIndex(0) >>= xShape; + + return xShape; + +} + +uno::Reference< css::uno::XInterface > SAL_CALL SdUnoSearchReplaceShape::findNext( const css::uno::Reference< css::uno::XInterface >& xStartAt, const css::uno::Reference< css::util::XSearchDescriptor >& xDesc ) +{ + SdUnoSearchReplaceDescriptor* pDescr = comphelper::getFromUnoTunnel<SdUnoSearchReplaceDescriptor>( xDesc ); + + uno::Reference< uno::XInterface > xFound; + + uno::Reference< text::XTextRange > xRange( xStartAt, uno::UNO_QUERY ); + if(pDescr && xRange.is() ) + { + + uno::Reference< text::XTextRange > xCurrentRange( xStartAt, uno::UNO_QUERY ); + + uno::Reference< drawing::XShape > xCurrentShape( GetShape( xCurrentRange ) ); + + while(!xFound.is() && xRange.is()) + { + xFound = Search( xRange, pDescr ); + if(!xFound.is()) + { + // we need a new starting range now + xRange = nullptr; + + if(mpPage) + { + // we do a page wide search, so skip to the next shape here + // get next shape on our page + uno::Reference< drawing::XShape > xFound2( GetNextShape( mpPage, xCurrentShape ) ); + if( xFound2.is() && (xFound2.get() != xCurrentShape.get()) ) + xCurrentShape = xFound2; + else + xCurrentShape = nullptr; + + xRange.set( xCurrentShape, uno::UNO_QUERY ); + if(!(xCurrentShape.is() && (xRange.is()))) + xRange = nullptr; + } + else + { + // we search only in this shape, so end search if we have + // not found anything + } + } + } + } + return xFound; +} + +/** this method returns the shape that follows xCurrentShape in the shape collection xShapes. + It steps recursive into groupshapes and returns the xCurrentShape if it is the last + shape in this collection */ +uno::Reference< drawing::XShape > SdUnoSearchReplaceShape::GetNextShape( const uno::Reference< container::XIndexAccess >& xShapes, const uno::Reference< drawing::XShape >& xCurrentShape ) noexcept +{ + uno::Reference< drawing::XShape > xFound; + + if(xShapes.is() && xCurrentShape.is()) + { + const sal_Int32 nCount = xShapes->getCount(); + for( sal_Int32 i = 0; i < nCount; i++ ) + { + uno::Reference< drawing::XShape > xSearchShape; + xShapes->getByIndex(i) >>= xSearchShape; + + if( xSearchShape.is() ) + { + uno::Reference< container::XIndexAccess > xGroup( xSearchShape, uno::UNO_QUERY ); + + if( xCurrentShape.get() == xSearchShape.get() ) + { + if( xGroup.is() && xGroup->getCount() > 0 ) + { + xGroup->getByIndex( 0 ) >>= xFound; + } + else + { + i++; + if( i < nCount ) + xShapes->getByIndex( i ) >>= xFound; + else + xFound = xCurrentShape; + } + + break; + } + else if( xGroup.is() ) + { + xFound = GetNextShape( xGroup, xCurrentShape ); + if( xFound.is() ) + { + if( xFound.get() == xCurrentShape.get() ) + { + // the current shape was found at the end of the group + i++; + if( i < nCount ) + { + xShapes->getByIndex(i) >>= xFound; + } + } + break; + } + } + } + } + } + + return xFound; +} + +uno::Reference< text::XTextRange > SdUnoSearchReplaceShape::Search( const uno::Reference< text::XTextRange >& xText, SdUnoSearchReplaceDescriptor* pDescr ) +{ + if(!xText.is()) + return uno::Reference< text::XTextRange > (); + + uno::Reference< text::XText > xParent( xText->getText() ); + + if( !xParent.is() ) + { + xParent.set( xText, uno::UNO_QUERY ); + } + + const OUString aText( xParent->getString() ); + + const sal_Int32 nTextLen = aText.getLength(); + + std::unique_ptr<sal_Int32[]> pConvertPos( new sal_Int32[nTextLen+2] ); + std::unique_ptr<sal_Int32[]> pConvertPara( new sal_Int32[nTextLen+2] ); + + sal_Int32* pPos = pConvertPos.get(); + sal_Int32* pPara = pConvertPara.get(); + + sal_Int32 nLastPos = 0, nLastPara = 0; + + uno::Reference< container::XEnumerationAccess > xEnumAccess( xParent, uno::UNO_QUERY ); + + // first we fill the arrays with the position and paragraph for every character + // inside the text + if( xEnumAccess.is() ) + { + uno::Reference< container::XEnumeration > xParaEnum( xEnumAccess->createEnumeration() ); + + while(xParaEnum->hasMoreElements()) + { + int ndbg = 0; + uno::Reference< text::XTextContent > xParagraph( xParaEnum->nextElement(), uno::UNO_QUERY ); + if( xParagraph.is() ) + xEnumAccess.set(xParagraph, css::uno::UNO_QUERY); + else + xEnumAccess.clear(); + + if( xEnumAccess.is() ) + { + uno::Reference< container::XEnumeration > xPortionEnum( xEnumAccess->createEnumeration() ); + if( xPortionEnum.is() ) + { + while(xPortionEnum->hasMoreElements()) + { + uno::Reference< text::XTextRange > xPortion( xPortionEnum->nextElement(), uno::UNO_QUERY ); + if( xPortion.is() ) + { + const OUString aPortion( xPortion->getString() ); + const sal_Int32 nLen = aPortion.getLength(); + + ESelection aStartSel( GetSelection( xPortion->getStart() ) ); + ESelection aEndSel( GetSelection( xPortion->getEnd() ) ); + + // special case for empty portions with content or length one portions with content (fields) + if( (aStartSel.nStartPos == aEndSel.nStartPos) || ( (aStartSel.nStartPos == (aEndSel.nStartPos - 1)) && (nLen > 1) ) ) + { + for( sal_Int32 i = 0; i < nLen; i++ ) + { + if( ndbg < (nTextLen+2) ) + { + *pPos++ = aStartSel.nStartPos; + *pPara++ = aStartSel.nStartPara; + + ndbg += 1; + } + else + { + OSL_FAIL( "array overflow while searching" ); + } + } + + nLastPos = aStartSel.nStartPos; + } + // normal case + else + { + for( sal_Int32 i = 0; i < nLen; i++ ) + { + if( ndbg < (nTextLen+2) ) + { + *pPos++ = aStartSel.nStartPos++; + *pPara++ = aStartSel.nStartPara; + + ndbg += 1; + } + else + { + OSL_FAIL( "array overflow while searching" ); + } + } + + nLastPos = aStartSel.nStartPos - 1; + DBG_ASSERT( aEndSel.nStartPos == aStartSel.nStartPos, "Search is not working" ); + } + nLastPara = aStartSel.nStartPara; + } + } + } + } + + if( ndbg < (nTextLen+2) ) + { + *pPos++ = nLastPos + 1; + *pPara++ = nLastPara; + } + else + { + OSL_FAIL( "array overflow while searching" ); + } + } + } + + uno::Reference< text::XTextRange > xFound; + ESelection aSel; + + if( xText.is() ) + aSel = GetSelection( xText ); + + sal_Int32 nStartPos; + sal_Int32 nEndPos = 0; + for( nStartPos = 0; nStartPos < nTextLen; nStartPos++ ) + { + if( pConvertPara[nStartPos] == aSel.nStartPara && pConvertPos[nStartPos] == aSel.nStartPos ) + break; + } + + if( Search( aText, nStartPos, nEndPos, pDescr ) ) + { + if( nStartPos <= nTextLen && nEndPos <= nTextLen ) + { + ESelection aSelection( pConvertPara[nStartPos], pConvertPos[nStartPos], + pConvertPara[nEndPos], pConvertPos[nEndPos] ); + + SvxUnoTextBase* pParent = comphelper::getFromUnoTunnel<SvxUnoTextBase>( xParent ); + + if(pParent) + { + rtl::Reference<SvxUnoTextRange> pRange = new SvxUnoTextRange( *pParent ); + xFound = pRange; + pRange->SetSelection(aSelection); + } + } + else + { + OSL_FAIL("Array overflow while searching!"); + } + } + + return xFound; +} + +bool SdUnoSearchReplaceShape::Search( const OUString& rText, sal_Int32& nStartPos, sal_Int32& nEndPos, SdUnoSearchReplaceDescriptor* pDescr ) noexcept +{ + OUString aSearchStr( pDescr->getSearchString() ); + OUString aText( rText ); + + if( !pDescr->IsCaseSensitive() ) + { + aText = aText.toAsciiLowerCase(); + aSearchStr = aSearchStr.toAsciiLowerCase(); + } + + sal_Int32 nFound = aText.indexOf( aSearchStr, nStartPos ); + if( nFound != -1 ) + { + nStartPos = nFound; + nEndPos = nFound + aSearchStr.getLength(); + + if(pDescr->IsWords()) + { + if( (nStartPos > 0 && aText[nStartPos-1] > ' ') || + (nEndPos < aText.getLength() && aText[nEndPos] > ' ') ) + { + nStartPos++; + return Search( aText, nStartPos, nEndPos, pDescr ); + } + } + + return true; + } + else + return false; +} + +ESelection SdUnoSearchReplaceShape::GetSelection( const uno::Reference< text::XTextRange >& xTextRange ) noexcept +{ + ESelection aSel; + SvxUnoTextRangeBase* pRange = comphelper::getFromUnoTunnel<SvxUnoTextRangeBase>( xTextRange ); + + if(pRange) + aSel = pRange->GetSelection(); + + return aSel; +} + +uno::Reference< drawing::XShape > SdUnoSearchReplaceShape::GetShape( const uno::Reference< text::XTextRange >& xTextRange ) noexcept +{ + uno::Reference< drawing::XShape > xShape; + + if(xTextRange.is()) + { + uno::Reference< text::XText > xText( xTextRange->getText() ); + + if(xText.is()) + { + do + { + xShape.set( xText, uno::UNO_QUERY ); + if(!xShape.is()) + { + uno::Reference< text::XText > xParent( xText->getText() ); + if(!xParent.is() || xText.get() == xParent.get()) + return xShape; + + xText = xParent; + } + } while( !xShape.is() ); + } + } + + return xShape; +} + +/* ================================================================= */ +/** this class holds the parameters and status of a search or replace + operation performed by class SdUnoSearchReplaceShape + */ + +UNO3_GETIMPLEMENTATION_IMPL( SdUnoSearchReplaceDescriptor ); + +SdUnoSearchReplaceDescriptor::SdUnoSearchReplaceDescriptor() +{ + mpPropSet.reset( new SvxItemPropertySet(ImplGetSearchPropertyMap(), SdrObject::GetGlobalDrawObjectItemPool()) ); + + mbBackwards = false; + mbCaseSensitive = false; + mbWords = false; +} + +SdUnoSearchReplaceDescriptor::~SdUnoSearchReplaceDescriptor() noexcept +{ +} + +// XSearchDescriptor +OUString SAL_CALL SdUnoSearchReplaceDescriptor::getSearchString() +{ + return maSearchStr; +} + +void SAL_CALL SdUnoSearchReplaceDescriptor::setSearchString( const OUString& aString ) +{ + maSearchStr = aString; +} + +// XReplaceDescriptor +OUString SAL_CALL SdUnoSearchReplaceDescriptor::getReplaceString() +{ + return maReplaceStr; +} + +void SAL_CALL SdUnoSearchReplaceDescriptor::setReplaceString( const OUString& aReplaceString ) +{ + maReplaceStr = aReplaceString; +} + +// XPropertySet +uno::Reference< css::beans::XPropertySetInfo > SAL_CALL SdUnoSearchReplaceDescriptor::getPropertySetInfo() +{ + SolarMutexGuard aGuard; + return mpPropSet->getPropertySetInfo(); +} + +void SAL_CALL SdUnoSearchReplaceDescriptor::setPropertyValue( const OUString& aPropertyName, const css::uno::Any& aValue ) +{ + SolarMutexGuard aGuard; + + const SfxItemPropertyMapEntry* pEntry = mpPropSet->getPropertyMapEntry(aPropertyName); + + bool bOk = false; + + switch( pEntry ? pEntry->nWID : -1 ) + { + case WID_SEARCH_BACKWARDS: + bOk = (aValue >>= mbBackwards); + break; + case WID_SEARCH_CASE: + bOk = (aValue >>= mbCaseSensitive); + break; + case WID_SEARCH_WORDS: + bOk = (aValue >>= mbWords); + break; + default: + throw beans::UnknownPropertyException( aPropertyName, static_cast<cppu::OWeakObject*>(this)); + } + + if( !bOk ) + throw lang::IllegalArgumentException(); +} + +uno::Any SAL_CALL SdUnoSearchReplaceDescriptor::getPropertyValue( const OUString& PropertyName ) +{ + SolarMutexGuard aGuard; + + uno::Any aAny; + + const SfxItemPropertyMapEntry* pEntry = mpPropSet->getPropertyMapEntry(PropertyName); + + switch( pEntry ? pEntry->nWID : -1 ) + { + case WID_SEARCH_BACKWARDS: + aAny <<= mbBackwards; + break; + case WID_SEARCH_CASE: + aAny <<= mbCaseSensitive; + break; + case WID_SEARCH_WORDS: + aAny <<= mbWords; + break; + default: + throw beans::UnknownPropertyException( PropertyName, static_cast<cppu::OWeakObject*>(this)); + } + + return aAny; +} + +void SAL_CALL SdUnoSearchReplaceDescriptor::addPropertyChangeListener( const OUString& , const css::uno::Reference< css::beans::XPropertyChangeListener >& ) {} +void SAL_CALL SdUnoSearchReplaceDescriptor::removePropertyChangeListener( const OUString& , const css::uno::Reference< css::beans::XPropertyChangeListener >& ) {} +void SAL_CALL SdUnoSearchReplaceDescriptor::addVetoableChangeListener( const OUString& , const css::uno::Reference< css::beans::XVetoableChangeListener >& ) {} +void SAL_CALL SdUnoSearchReplaceDescriptor::removeVetoableChangeListener( const OUString& , const css::uno::Reference< css::beans::XVetoableChangeListener >& ) {} + +/* ================================================================= */ + +SdUnoFindAllAccess::SdUnoFindAllAccess( uno::Sequence< uno::Reference< uno::XInterface > > const & rSequence ) noexcept +:maSequence( rSequence ) +{ +} + +SdUnoFindAllAccess::~SdUnoFindAllAccess() noexcept +{ +} + +// XElementAccess +uno::Type SAL_CALL SdUnoFindAllAccess::getElementType() +{ + return cppu::UnoType<text::XTextRange>::get(); +} + +sal_Bool SAL_CALL SdUnoFindAllAccess::hasElements() +{ + return maSequence.hasElements(); +} + +// XIndexAccess +sal_Int32 SAL_CALL SdUnoFindAllAccess::getCount() +{ + return maSequence.getLength(); +} + +uno::Any SAL_CALL SdUnoFindAllAccess::getByIndex( sal_Int32 Index ) +{ + if( Index < 0 || Index >= getCount() ) + throw lang::IndexOutOfBoundsException(); + + uno::Any aAny; + aAny <<= maSequence[Index]; + return aAny; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/unoidl/unowcntr.cxx b/sd/source/ui/unoidl/unowcntr.cxx new file mode 100644 index 000000000..1079477ef --- /dev/null +++ b/sd/source/ui/unoidl/unowcntr.cxx @@ -0,0 +1,99 @@ +/* -*- 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 <com/sun/star/lang/XComponent.hpp> + +#include "unowcntr.hxx" + +using namespace ::com::sun::star; + +SvUnoWeakContainer::SvUnoWeakContainer() noexcept +{ +} + +SvUnoWeakContainer::~SvUnoWeakContainer() noexcept +{ +} + +/** inserts the given ref into this container */ +void SvUnoWeakContainer::insert( const uno::WeakReference< uno::XInterface >& xRef ) noexcept +{ + for ( auto it = maVector.begin(); it != maVector.end(); ) + { + uno::WeakReference< uno::XInterface > & rWeakRef = *it; + uno::Reference< uno::XInterface > xTestRef( rWeakRef ); + if ( !xTestRef.is() ) + { + it = maVector.erase( it ); + } + else + { + if ( rWeakRef == xRef ) + return; + ++it; + } + } + maVector.emplace_back( xRef ); +} + +/** searches the container for a ref that returns true on the given + search function +*/ +bool SvUnoWeakContainer::findRef( + uno::WeakReference< uno::XInterface >& rRef, + void const * pSearchData, + weakref_searchfunc pSearchFunc +) +{ + for ( auto it = maVector.begin(); it != maVector.end(); ) + { + uno::WeakReference< uno::XInterface > & itRef = *it; + uno::Reference< uno::XInterface > xTestRef( itRef ); + if ( !xTestRef.is() ) + { + it = maVector.erase( it ); + } + else + { + if( (*pSearchFunc)( itRef, pSearchData ) ) + { + rRef = itRef; + return true; + } + ++it; + } + } + return false; +} + +void SvUnoWeakContainer::dispose() +{ + for (auto const& elem : maVector) + { + uno::Reference< uno::XInterface > xTestRef( elem ); + if ( xTestRef.is() ) + { + uno::Reference< lang::XComponent > xComp( xTestRef, uno::UNO_QUERY ); + if( xComp.is() ) + xComp->dispose(); + } + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/unoidl/unowcntr.hxx b/sd/source/ui/unoidl/unowcntr.hxx new file mode 100644 index 000000000..a863f0929 --- /dev/null +++ b/sd/source/ui/unoidl/unowcntr.hxx @@ -0,0 +1,47 @@ +/* -*- 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 <cppuhelper/weakref.hxx> +#include <vector> + +typedef bool (*weakref_searchfunc)( const css::uno::WeakReference< css::uno::XInterface >& xRef, void const * pSearchData ); + +class SvUnoWeakContainer +{ +private: + std::vector< css::uno::WeakReference< css::uno::XInterface > > maVector; + +public: + SvUnoWeakContainer() noexcept; + ~SvUnoWeakContainer() noexcept; + + /** inserts the given ref into this container */ + void insert( const css::uno::WeakReference< css::uno::XInterface >& xRef ) noexcept; + + /** searches the container for a ref that returns true on the given + search function + */ + bool findRef( css::uno::WeakReference< css::uno::XInterface >& rRef, void const * pSearchData, weakref_searchfunc pSearchFunc ); + + void dispose(); +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |